Skip to content

Research notes

Yearn V3 maxLoss vs Swap Slippage

A 48 U shortfall on a 10,000 U Yearn V3 withdrawal shows how maxLoss, owner limits and a later DEX minimum output apply to different amounts.

An ivory paper ribbon passes through two ceramic gates with separate lime stops, with a curled shaving beside the first.
Illustration for research notes; examples in this article are educational.

Yearn V3 maxLoss caps the asset shortfall accepted during a vault withdrawal or redemption, in basis points of the operation's starting asset amount. An exact-input DEX swap enforces a separate minimum output in the acquired token. Check each bound separately, along with the owner's exit limit: passing maxLoss does not establish the amount a later swap will deliver.

Identify the vault and the asset being returned

Yearn's V3 architecture separates an allocator vault, its strategies and optional periphery such as an accountant. A tokenized strategy can also accept direct deposits. The official V3 overview explains these layers; their exit implementations require separate checks.

This article follows allocator VaultV3 API 3.1.1, pinned to commit 89ab996. The official reference links to that implementation. Match the deployed vault's version and configuration before applying the example. KLINEO's coverage here is educational and does not establish a Yearn integration or expected yield.

First identify the vault's underlying token through asset(). The holder owns vault shares; an exit returns units of that underlying. A subsequent swap exchanges those units for another token. The ERC-4626 shares-versus-assets guide explains why these quantities need separate labels. Its OpenZeppelin numerical example uses another implementation's conversion rules.

Read maxLoss in basis points and check the defaults

One basis point is 0.01%; 100 basis points is 1%. Yearn's maxLoss, spelled max_loss in the Vyper source, accepts values up to 10,000. The integration guide documents an important difference between the two exit methods.

Exit methodQuantity specifiedDefault maxLossReturn value
withdrawUnderlying asset amount0 bpsShares burned
redeemVault share amount10,000 bpsAssets actually withdrawn

A three-argument redeem therefore permits a loss as large as the entire starting asset equivalent. An integration wanting a narrower bound must pass one explicitly. The VaultV3 API reference lists the extended signatures and their return types.

For the pinned allocator, let A be the asset amount entering the internal exit and P the amount ultimately transferred. A is the specified asset amount for withdraw, or the initial rounded-down asset conversion for redeem. When a loss occurs and maxLoss is below 10,000, the final check is:

A − P ≤ floor(A × maxLoss / 10,000)

The right side is calculated in raw underlying-token units. Equality passes. A positive loss at maxLoss zero fails. With maxLoss 10,000 the final loss assertion is skipped, while the other exit conditions still apply. This follows the pinned internal redemption logic.

The bound judges losses encountered during this operation. It does not cap the holder's lifetime loss, repair an earlier decrease in share value or guarantee the underlying's market price.

For redeem, the starting asset conversion is computed when the call executes. If a report lowers share value after an earlier quote, an explicit maxLoss of zero can still permit a smaller receipt than that old quote, provided this exit encounters no additional loss. A wrapper needing to enforce the earlier quoted output must check an asset minimum separately.

Follow a 48-basis-point withdrawal shortfall

Consider this hypothetical vault using ordinary token U with six decimals. Shares also have six decimals. Opening managed assets are 100,000 U: 2,000 U idle and 98,000 U of allocated strategy debt. Effective share supply is 100,000, with no locked-profit shares. Alice owns 15,000 shares and calls directly as owner.

Assume the vault is unpaused, has no withdrawal hook, and its effective queue contains one active strategy. The strategy's conversion values the vault's position at its full 98,000 U debt, and its advertised redemption capacity covers the amounts considered. Exclude vault fees, profit-unlock changes and unrelated transactions. The modeled shortfall appears only when the strategy unwinds the requested slice.

Alice specifies a 10,000 U withdrawal with maxLoss 50, or 0.50%. The opening conversion gives one U per share, so previewWithdraw gives 10,000 shares. Under the stipulated liquidity and conversion views, maxWithdraw(Alice, 50, queue) returns 15,000 U. Her request is within that nominal owner limit.

The vault already has 2,000 U. It therefore requests another 8,000 U from the strategy. The unwind delivers 7,952 U, measured from the vault's actual underlying balance increase. The difference is 48 U. The exit reduces the amount payable to Alice to 2,000 + 7,952 = 9,952 U.

The loss test compares 48 U with a bound based on the original 10,000 U:

10,000 × 50 / 10,000 = 50 U allowed

48 / 10,000 = 0.48%, or 48 bps

Dividing by the 8,000 U strategy request gives 0.60%. That describes the strategy slice's shortfall, but it is the wrong denominator for the allocator's final user-exit bound. Idle assets covered part of Alice's original request.

Explicit maxLossAllowed loss on 10,000 UResult for the same 48 U shortfall
0 bps0 UReverts
47 bps47 UReverts
48 bps48 UPasses at equality
50 bps50 UPasses with 2 U of headroom

These are alternative executions from the same opening state. A rejected call leaves no completed share burn or token withdrawal; any network cost belongs in a separate record.

In the accepted case, Alice burns the precomputed 10,000 shares and receives 9,952 U. The withdraw return value is 10,000 shares, so treating that return as assets received would overstate her receipt by 48 U. A redemption of 10,000 shares at this opening state reaches the same asset calculation, but redeem returns the actual 9,952 U.

The ledger closes with 90,000 U strategy debt, zero idle assets and 90,000 effective shares. Alice retains 5,000 shares. Starting assets reconcile as 100,000 − 9,952 − 48 = 90,000 U. The withdrawing holder bears this particular exit shortfall; the conversion of one U per share stays unchanged under these assumptions.

This case isolates a cost realized while unwinding. If a strategy's conversion already shows a loss relative to allocated debt, the allocator also assesses an unrealized-loss share before pulling funds. That path has its own integer rounding and liquidity adjustments in the same pinned implementation. The receipt-token accounting guide explains why an accounting claim and available cash can differ.

Apply the owner's limit before accepting a loss

Now change one assumption: configure a hypothetical withdrawal hook that returns a fixed 9,975 U limit for Alice and the effective queue at both maxLoss 50 and 10,000. Her shares still convert to 15,000 U. The pinned hook branch gives an extended maxWithdraw result of min(15,000, 9,975) = 9,975 U.

A 10,000 U request fails that hook check before strategy funds are pulled. Raising maxLoss to 10,000 cannot fix this fixed limit. Although the modeled 9,952 U receipt would fit below the cap, the precheck compares the original 10,000 U request with 9,975 U. Other hooks can use maxLoss when calculating their limit, so repeat the limit read with the actual arguments.

Use matching owner, maxLoss and queue arguments when checking limits. A preview only performs the share conversion. A maximum read uses configured restrictions and the information available to its view calls; it cannot execute the later unwind to discover every execution cost. With a hook configured, its limit also does not establish that strategies will release the necessary cash.

Queue order and a forced default affect which strategies actually supply an exit. The withdrawal-queue versus debt-allocation guide follows those choices. For a caller acting for Alice, verify share allowance as well. Holder authorization is separate from the allocation and reporting permissions explained in Yearn's role-manager versus report-keeper guide.

Give a later DEX swap its own output floor

Suppose Alice exchanges the accepted 9,952 U for token V. For this second hypothetical step, both tokens have six decimals and the route quotes 9,952 V for that exact input. The constructed quote already includes its route fees and price impact. It is an assumed one-to-one quote, with no dollar valuation or peg guarantee.

A 0.50% tolerance against this quote produces:

minimum V = 9,952 × 0.995 = 9,902.24 V

For a concrete DEX implementation, Uniswap's v3-periphery v1.3.0 SwapRouter requires returned output to meet amountOutMinimum. Its interface expresses that floor as an amount of the output token. Here the submitted floor would be 9,902,240,000 raw V units. An output of 9,902.23 V fails; 9,902.24 V meets it.

Yearn's 50-bps bound was applied to a 10,000 U claim. The swap's 50-bps tolerance is applied to a 9,952 V quote. Under this deliberately aligned quote, the final floor sits 97.76 V, or 0.9776%, below 10,000 V. The vault shortfall and the permitted quote deterioration accumulate across the route. One 0.50% setting does not describe that combined outcome.

An actual quote can have a different exchange rate, token decimals and input amount. Preserve those terms when calculating its floor. Uniswap's single-swap guide warns against leaving minimum output at zero. The separate minimum-output versus price-limit guide covers a further distinction inside the swap itself.

Validate the complete exit before submitting it

Keep the vault and swap evidence attached to their own units and state references.

CheckEvidence to retain
Contract identityChain, vault, asset, API version, implementation and any wrapper
Owner eligibilityShare balance, caller allowance, matching maximum and hook restriction
Funding pathEffective queue, strategy capacity and loss assessments at one block
Vault acceptanceStarting asset amount, explicit maxLoss and permitted raw-unit loss
Swap acceptanceActual intended input, quote state, output token and submitted minimum
Completed resultShares burned, underlying transferred, swap output and separate network costs

Simulate the exact caller and full route, including the failing boundary. Check whether a wrapper propagates or catches a swap failure and where any retained underlying would sit. A confirmed withdrawal followed by a separately submitted swap needs two transaction records.

For this example, retain 10,000 shares burned, 9,952 U received and a separately calculated 9,902.24 V swap floor. Those three amounts make each acceptance rule and the combined minimum outcome reproducible.

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.