fix(blue-sdk): throw UnknownMarketAllocation on stale withdrawQueue#548
fix(blue-sdk): throw UnknownMarketAllocation on stale withdrawQueue#548Kubudak90 wants to merge 1 commit into
Conversation
|
@prd-carapulse[bot] review this PR |
|
Reviewed. Changes requested: #548 (review) Blocking:
Verified:
Track: https://carapulse.morpho.dev/dashboard/runs?run_id=gw_run_ab632b458a06 |
There was a problem hiding this comment.
Blocking issue found. @morpho-org/blue-sdk build fails, and the new regression test does not exercise the stale-withdrawQueue path because AccrualVault rebuilds withdrawQueue from the allocations argument.
Verification:
pnpm exec vitest --project blue-sdk --run packages/blue-sdk/test/unit/Vault.test.ts✅pnpm --filter @morpho-org/blue-sdk run build❌TS2353: 'withdrawQueue' does not exist in type 'Omit<IVault, "totalAssets" | "withdrawQueue">'
Rubilmax
left a comment
There was a problem hiding this comment.
This PR is worth implementing! We just have a different POV regarding missing allocations: we'd prefer loudly failing instead of silently ignoring missing markets
| this.withdrawQueue | ||
| .map((marketId) => { | ||
| const allocation = this.allocations.get(marketId); | ||
| if (!allocation) return null; |
There was a problem hiding this comment.
IMO we should throw a custom error UnknownMarketAllocation here instead of silently not accruing so we ensure the returned vault is 100% accurate
Replace the non-null assertion `this.allocations.get(marketId)!` in `AccrualVault.accrueInterest()` with an explicit throw. When the withdraw queue is mutated after construction to reference a market that is not present in `allocations`, the previous code crashed with an opaque "Cannot destructure property 'config' of 'undefined'" at the destructuring site instead of surfacing a typed error. `UnknownMarketAllocation` extends `UnknownDataError`, consistent with the other unknown-data error classes in this package. Callers that want to tolerate stale entries can opt in via `_try(() => vault.accrueInterest(), UnknownDataError)`. Fixes morpho-org#527
f8f6056 to
0535a24
Compare
|
Switched to the fail-loud approach per @Rubilmax's feedback. The non-null assertion now becomes an explicit Summary of changes (single commit, rebased onto current
Addresses both review comments:
Local verification:
Ready for re-review. |
| // Mutate the public `withdrawQueue` after construction so it references a | ||
| // market that has no corresponding entry in `allocations`. Without this | ||
| // mutation the bug cannot be reached, because the AccrualVault constructor | ||
| // rebuilds `withdrawQueue` from the allocations argument. |
There was a problem hiding this comment.
This alone makes the bug unreachable with standard behavior so in the end is it worth it? Sorry for the back-and-forth
WDYT @Foulks-Plb ?
Problem
The
AccrualVault.accrueInterest()method uses a non-null assertion (!) when looking up allocations by market ID from the withdrawQueue:This is unsafe because the
withdrawQueuemay contain market IDs that are not present inallocations. For example, after a market is removed from a vault's allocations but is still referenced in the withdraw queue, this would cause a runtime crash.Solution
Replace the non-null assertion with a safe lookup and filter out any missing allocations:
This preserves the withdraw queue order while gracefully handling missing markets.
Changes
packages/blue-sdk/src/vault/Vault.ts: Safe allocation lookup with null filterpackages/blue-sdk/test/unit/Vault.test.ts: Regression test for missing allocation in withdrawQueueTesting
All tests pass (2/2).