Skip to content

Research notes

Yearn V3 Profit Locking and Share Price

Follow a Yearn V3 report through locked shares, time-adjusted supply and a checked four-day conversion timeline, then separate that value from withdrawal liquidity.

Warm ivory paper shutters fan open around a lime ceramic core on a near-black surface
Illustration for research notes; examples in this article are educational.

With profit locking enabled, Yearn V3 allocator vaults use vault-held shares to delay a reported gain's effect on share price. Unlocked shares are progressively excluded from conversion supply. A holder can keep the same shares while their asset conversion rises, but that conversion does not establish immediate withdrawal liquidity.

Identify the allocator before following its profit

Yearn V3 has several accounting layers. An allocator vault accepts deposits and allocates the underlying asset across strategies. A TokenizedStrategy can itself be a separate vault, and an accountant supplies fee and refund amounts. The official V3 overview distinguishes these contracts.

This walkthrough follows the allocator VaultV3 API 3.1.1, pinned to commit 89ab996. Its relevant transaction is process_report(strategy). A strategy's own report and profit-unlock clock belong to that strategy's implementation; they should not be substituted for the allocator's state.

For the allocator, reported strategy value comes from converting the strategy shares it owns into assets. Comparing that value with the strategy's recorded debt produces a gain or loss. Consequently, yield a strategy has not yet exposed through its conversion need not already appear as allocator profit. Yearn's vault-management guide describes this reporting boundary.

The ERC-4626 shares-versus-assets guide explains the basic token units and operation previews. Here the additional task is to reconstruct Yearn's time-adjusted denominator. The lending receipt-token guide provides the broader reconciliation between a fixed share quantity and a changing underlying claim.

Read the two supply records separately

Call the vault's stored minted supply M, its stored balance of its own shares B, and the amount currently unlocked X. The public views apply these relationships:

totalSupply() = M − X

balanceOf(vault) = B − X

An ordinary holder's balanceOf returns that holder's stored shares directly. The adjustment applies to the vault's own balance. These details are explicit in the pinned balance and supply getters.

Before the full unlock date, X is calculated from the share-unlocking rate multiplied by elapsed seconds. The product is divided by its 10¹² scale and rounded down. At or after a nonzero full unlock date, X becomes the entire stored vault balance. The unlock and conversion functions then use adjusted supply to price shares against accounted assets.

Time can therefore change public supply without writing storage or emitting a Transfer event. An indexer that reconstructs only mints minus burns can retain a different figure from totalSupply(). Both records have a use, provided they are named correctly.

The public supply has already excluded X. Subtracting unlockedShares() from that result again would overstate the asset value per share.

Process a hypothetical 100 U gain

Use a fictional ordinary underlying token U with six decimals. Vault shares also have six decimals. Start with 1,000 U of accounted assets and 1,000 shares: 100 U idle in the allocator and 900 U recorded as strategy debt. One holder owns 100 shares. The vault holds none of its own shares.

For this illustration, the allocator has no accountant, so fees and refunds are zero. Set profitMaxUnlockTime to four days, or 345,600 seconds. This is a chosen teaching input, not a protocol-wide default or an observed vault setting. Assume no deposits, withdrawals, transfers, additional reports or losses during the four days.

At time t₀, the allocator's strategy holding converts to 1,000 U. Against recorded debt of 900 U, that produces a 100 U gain. At the pre-report rate of one U per share, the allocator calculates 100 shares to lock. It issues those shares to itself and increases accounted strategy debt by 100 U.

After the report, assets are 1,100 U and minted supply is 1,100 shares. The holder still owns 100 shares, initially converting to 100 U. The simultaneous increases in assets and supply preserve the starting conversion. Yearn's official no-fee profit test checks this preservation followed by appreciation as the buffer unlocks.

The stored unlocking rate is 289,351,851,851,851. It measures share base units per second on a 10¹² scale, calculated by integer division of 100,000,000 × 10¹² by 345,600. It is not a U-denominated payment rate. The full unlock date is t₀ plus 345,600 seconds.

The following results reproduce the contract's integer divisions. Every displayed share or U quantity has six decimal places; “day” means exactly 86,400 seconds after t₀. The last column is convertToAssets for the holder's unchanged 100 shares.

Time after reportUnlocked shares XPublic totalSupplyHolder conversion, U
Immediately0.0000001,100.000000100.000000
One day24.9999991,075.000001102.325581
Two days49.9999991,050.000001104.761904
Three days74.9999991,025.000001107.317073
Four days100.0000001,000.000000110.000000

Accounted assets remain 1,100 U throughout. Stored minted supply remains 1,100 shares, and the vault's stored balance remains 100 shares. At two days, its public balanceOf(vault) is only 50.000001 shares because the view excludes 49.999999 unlocked shares.

The extra 0.000001 share in the intermediate supply rows comes from truncating the stored rate. At the full unlock date, the endpoint branch excludes the whole buffer, including that remainder. These tiny differences matter when reconciling raw integers even if a dashboard hides them.

Linear share unlocking produces a curved conversion

Halfway through the interval, roughly half the buffer shares have been excluded. The holder's conversion is 104.761904 U, rather than the 105 U obtained by distributing the eventual ten-U increase evenly over time.

The numerator stays at 1,100 U while the denominator shrinks. Dividing by that changing denominator produces the curve. A linear share-unlock schedule should therefore not be modeled as a fixed number of asset tokens paid to each holder every second.

Use the contract's full-quantity conversion when checking a position. At two days, pricePerShare() displays 1.047619 U after six-decimal rounding. Multiplying that helper value by 100 gives 104.761900 U, four asset base units below the direct conversion. Yearn's integration guidance specifically calls out precision loss in the price-per-share helper.

Now suppose a flat strategy report occurs exactly at day four: reported strategy value still equals recorded debt, with no fees or refunds. Report accounting burns the 100 shares still present in the vault's stored balance. Stored supply becomes 1,000 and unlockedShares() becomes zero. Public supply remains 1,000, and the holder's conversion remains 110 U.

That burn transaction records an adjustment already reflected in the earlier view. Counting another gain when the burn event arrives would duplicate the same profit.

A new report can change the remaining path

The four-day table has one gain and an otherwise unchanged state. With overlapping profitable reports, the allocator combines remaining old locked shares with newly locked shares and computes a weighted remaining period. The old portion contributes its remaining time; the new portion contributes the configured maximum time. The pinned reporting logic performs this calculation in shares with integer rounding.

A new report consequently does not simply restart every existing share at a fresh four days. Re-read the rate, update timestamp and full unlock date after it.

Losses can also consume the buffer. Consider a separate branch from the two-day snapshot: the strategy reports a 55 U loss, with fees and refunds still zero. The loss converts, rounding up, to 52.500001 offset shares. Together with the already unlocked 49.999999 shares, report accounting would need to burn 102.5 stored shares. The vault owns only 100, so the burn stops there.

Assets fall to 1,045 U, public supply becomes 1,000 shares, and the holder's 100 shares convert to 104.5 U. That is below the preceding 104.761904 U quote. The buffer's exhaustion permits the loss to reduce share price, as the official insufficient-buffer loss test demonstrates.

Configuration changes matter too. Changing the maximum to another nonzero period leaves the current schedule running until the next report recalculates it. Setting it to zero instead burns the vault-held shares and clears the schedule immediately. Check the actual period setter before projecting an existing clock forward.

Keep the conversion separate from exit liquidity

Return to the original no-loss timeline. At day four, 100 holder shares convert to 110 U, but the allocator still has only 100 U idle. Completing that entire redemption requires recovering another ten U from strategies.

If every strategy currently exposes zero redeemable shares, with no pause or withdrawal hook, the default maxWithdraw calculation limits this holder to 100 U. The 110 U accounting conversion can coexist with that lower limit. This is a separate liquidity scenario; no redemption occurred in the table.

Follow totalIdle versus totalDebt to reconcile where the underlying sits. Then use the withdrawal queue versus debt allocation walkthrough to determine which strategies an exit can actually reach. An unlock date releases share-price buffering; it does not replenish idle tokens.

Validate one timestamp before projecting another

Read the following fields at the same block and preserve its timestamp. Use the actual deployment's implementation and parameters rather than applying the example's four-day configuration.

EvidenceCheck
Vault, asset, API version and decimalsConfirm the allocator and the units being converted.
Unlock rate, last update and full unlock dateReconstruct elapsed unlocks with integer rounding and the endpoint branch.
totalSupply, unlockedShares and balanceOf(vault)Keep adjusted views separate from stored supply and stored vault shares.
totalAssets, totalIdle and totalDebtExplain the asset numerator and available idle tokens separately.
Holder shares, conversion, matching preview and owner limitCompare the position value with the intended exit size, queue and loss tolerance.

For an interval containing no mint, burn or report, public supply plus unlocked shares should reproduce the same stored supply. After a report, reconcile both sides again: a lower unlocked-shares value can accompany a stored burn without changing the holder's conversion. Record which transition occurred before assigning the change to new earnings or an executed withdrawal.

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.