Skip to content

Research notes

Yearn V3 Withdrawal Queue vs Debt Allocation

Follow a checked three-strategy exit to see why allocated debt, withdrawal order and immediately redeemable assets produce different answers.

Three ivory ceramic reservoirs with open and closed outlets above a lime stream flowing into one basin.
Illustration for research notes; examples in this article are educational.

In Yearn V3, debt allocation records the assets attributed to each strategy, while the withdrawal queue selects the order in which strategies are asked to fund an exit. The vault uses idle assets first, then respects each selected strategy's current redeemable limit. A custom queue applies only when the vault allows it; sufficient total debt alone does not establish sufficient exit liquidity.

Pin the allocator before reading its queue

This walkthrough uses Yearn's allocator vault API 3.1.1, pinned to commit 89ab996. The official release tags date that release to August 10, 2026. The sources were checked on October 28, 2026; the example below is invented, rather than a snapshot of a deployed vault.

An allocator accepts one underlying asset and holds shares in strategies using that asset. A TokenizedStrategy implementation, the strategy's external investment logic, an accountant and optional vault hooks are separate layers. Yearn's V3 overview describes that architecture. A contract labeled V3 still needs its own version and configuration check.

If share quantities are unfamiliar, start with ERC-4626 shares versus assets. Here the additional question is which underlying assets an allocator can recover from its strategies during one exit.

Allocation and queue order change different things

A strategy's current_debt is its recorded allocation in underlying units, updated by allocations, withdrawals and reports. Its max_debt is an allocation ceiling. The ceiling does not establish cash available for withdrawal, and changing it does not itself transfer tokens.

A permitted debt manager uses update_debt to move funds toward a target, subject to the vault's constraints and the strategy's limits. The management guide describes this distinction. Raising a cap, funding a strategy and receiving assets back are separate actions.

The queue is an ordered list of potential withdrawal sources. It is not a list of waiting depositors. A funded, active strategy can be absent from the default queue: the strategy-addition API allows adding it without queue insertion. Reordering the list alone changes no existing strategy debt. A later withdrawal can change the allocation because earlier strategies may be drawn down before later ones are touched.

There is also a deposit-side connection: if auto_allocate is enabled, a deposit or mint triggers an attempt to allocate available idle assets to the first strategy in the default queue. Allocation constraints still apply. The pinned specification's auto-allocation section explains this behavior. Queue position can therefore affect future deposits as well as exits.

Read the strategy limit from the vault's address

For each strategy, the allocator calls maxRedeem with the allocator vault as owner, then passes that share amount to the strategy's convertToAssets. This produces the asset-denominated ceiling used by the pinned withdrawal implementation. The depositor's wallet address would answer a different ownership question.

In the no-loss case, the pull is bounded by the remaining shortfall, the strategy's recorded debt and that converted ceiling. The allocator then redeems strategy shares and measures the actual underlying-token balance increase. A displayed strategy balance cannot substitute for those checks.

For a strategy using Yearn's TokenizedStrategy pattern, custom availableWithdrawLimit logic can reflect locked positions, loose assets or restrictions in the underlying protocol. The strategy-writing guide explains why that function may need customization. The allocator reads the resulting ERC-4626 redemption interface; it does not directly call every strategy's custom liquidity function.

Zero available liquidity can coexist with positive recorded debt. That alone says nothing about whether a loss has occurred. Conversely, a nonzero limit is not a promise that the external redemption cannot fail.

Follow a 350 U exit across three strategies

This hypothetical example uses underlying token U with six decimals. Both the vault and strategy shares convert at exactly one U per share, with matching decimals. All strategies are active. There are no fees, losses, locked-profit shares, hooks, rounding residuals or intervening transactions. The vault is unpaused, and the withdrawing owner calls directly.

The vault starts with 100 U idle and the following positions. The last column is already the asset equivalent of each strategy's maxRedeem(vault) result.

SourceRecorded debtCurrently redeemable by vault
Strategy A400 U120 U
Strategy B300 U200 U
Strategy C200 U0 U

Recorded strategy debt totals 900 U. Adding 100 U idle gives 1,000 U of vault assets. Outstanding supply is 1,000 shares, of which the owner holds 500. Strategy C's full accounting value still equals its debt; its zero limit represents temporary unavailability in this fixture.

The default queue is [A, B, C]. The owner requests 350 U with zero accepted loss. Idle cash covers 100 U of that amount, leaving 250 U to recover. The vault's minimum_total_idle setting guides debt allocation; it does not reserve that idle cash against depositor exits. The pinned specification makes that distinction explicit. A can supply only 120 U despite its 400 U debt. After A, the remaining shortfall is 130 U, which B supplies within its 200 U limit. The loop stops before C.

Stage inside the transactionCash held for exitA debtB debtC debt
Opening state100 U400 U300 U200 U
A returns 120 U220 U280 U300 U200 U
B returns 130 U350 U280 U170 U200 U
Owner receives 350 U0 U280 U170 U200 U

The intermediate rows describe progress within one atomic transaction. The receiver gets one payment after enough assets have been recovered. Each row helps explain that single completed exit.

The final cash check is 100 + 120 + 130 − 350 = 0 U. Strategy debt becomes 280 + 170 + 200 = 650 U. Vault assets also equal 650 U. Burning 350 vault shares leaves total supply of 650 shares and the owner with 150 shares. The owner received 350 U and retains a 150 U accounting claim under the example's unchanged conversion.

The strategy redemptions are internal funding movements. They must not be added to the owner's 350 U receipt as extra proceeds. The broader lending receipt-token accounting guide explains the same need to reconcile claims and cash flows separately.

Reverse the order from the same opening state

Now reset every balance and limit to the opening snapshot. Suppose the owner passes [B, A, C] and use_default_queue is false. B supplies 200 U first, then A supplies the remaining 50 U after idle cash. The completed exit leaves A with 350 U debt, B with 100 U and C with 200 U.

The receiver still gets 350 U, and total remaining debt is still 650 U. The residual allocation differs because the funding order differs. Neither route automatically restores the previous strategy weights after paying the owner.

Check which queue the call actually selects

Yearn's integration guide documents the optional ordered strategy array, with at most ten entries. An empty caller array selects the default list. It does not ask the vault to restrict the exit to idle assets.

A nonempty custom array replaces the default list when use_default_queue is false. The default list is not appended as a fallback. If the flag is true, the caller's list is ignored and the default list is used. Match that selection when reading limits and constructing the transaction.

From the same opening snapshot, the owner has a 500 U accounting claim but only 420 U available through the full queue: 100 idle plus 120 from A plus 200 from B. The no-loss maxWithdraw result is therefore 420 U under these assumptions.

Caller list and policyEffective queueExit ceilingResult for 350 U
Empty listA, B, C420 USuccess
B, A, C; custom allowedB, A, C420 USuccess; different residual debt
C, A; custom allowedC, A220 URevert
C, A; default forcedA, B, C420 USuccess using default order

The short list can recover only 120 U from A beyond the 100 U idle. It never reaches B because B was omitted. Queue exhaustion causes a revert, as described in the withdrawal specification. The attempted strategy movements roll back: idle remains 100 U, debts remain 400/300/200 U, shares remain unchanged and the receiver gets zero U. Network costs are separate.

A strategy call that itself reverts also aborts this path. The loop does not catch that error and try the next strategy.

Validate an exit against one consistent state

Read the vault's version, underlying asset, pause status, owner balance, idle assets, strategy debts, full default queue and use_default_queue at one block. Preserve the intended caller, receiver, explicit loss bound and custom array with that snapshot. If the caller differs from the share owner, check share-spending authorization too.

Then inspect the selected strategies' redemption limits for the vault's address. Compare the intended size with maxWithdraw or maxRedeem using the same optional parameters. A conversion or preview alone does not establish exit capacity.

There are two configuration traps. First, the API reference warns that the default-queue setter checks active status but permits duplicates, which can make maximum-limit views inaccurate. Validate unique addresses rather than summing repeated entries.

Second, in API 3.1.1 a configured withdrawal hook replaces the built-in liquidity calculation used by the maximum view. The hook receives the effective queue; the exit still has to recover assets and satisfy the hook's checks. Inspect that hook branch before applying the example's simple ceiling calculation.

Losses also require their own treatment. Use Yearn V3 maxLoss versus swap slippage for exit-loss bounds and profit locking and share price for changing share conversions. The no-loss arithmetic here does not model either mechanism.

Finally, simulate the exact transaction against the intended state, then reconcile confirmed strategy debt updates, shares burned and underlying received. For the default worked exit, the record should close at zero idle, 650 U debt, 350 shares burned and 350 U paid. Any discrepancy calls for checking actual transfers, rounding, losses and configuration before accepting the exit ledger.

Keep the context with the example.

Each worked example is illustrative, with its sources and assumptions in the article. Read our editorial standards for authorship, verification and corrections.