Skip to content

Research notes

Morpho Vault V2 forceDeallocate: Penalty vs Net Assets

Reconcile a constrained Vault V2 exit into gross position debit, net assets received and penalty shares burned, then check the exit helper’s per-leg rounding.

Ivory paper tiles pass through a ceramic gate into a tray while one lime tile stays on the ledge
Illustration for research notes; examples in this article are educational.

Morpho Vault V2 forceDeallocate moves assets from a selected adapter into the vault’s idle balance; it does not pay the caller. A configured penalty burns shares from onBehalf while the penalty assets stay in the vault. A later withdrawal pays the user, so distinguish the position’s gross debit, net assets received and penalty share burn, and use ordinary withdrawal liquidity first.

Start with the withdrawal that needs no forced deallocation

A vault can hold an asset claim in a market that a normal withdrawal does not reach. In Vault V2, ordinary exits use idle underlying tokens first, followed by the configured liquidityAdapter and liquidityData position. Other positions can have available liquidity without being part of that route. Morpho’s force-deallocation tutorial describes this gap for a vault using one MorphoMarketV1AdapterV2 adapter.

Measure the normally available amount before sizing a forced exit. If that amount serves the intended withdrawal, use the ordinary path. Its liquidity retrieval does not invoke the forced-deallocation penalty. The liquidity adapter versus other allocations guide follows which positions this route reaches.

This article checks the mechanics on 29 October 2026 against Vault V2 core commit 07698890 and exit-helper commit 35047bcd. Match a real vault and helper to their chain addresses and deployed code before applying these snapshots. The helper examined here requires exactly one adapter, the named Blue-market adapter; core forceDeallocate supports a broader adapter interface.

How forceDeallocate computes the penalty and share burn

For one forced deallocation, let D be the raw underlying amount moved into idle and p be forceDeallocatePenalty(adapter), scaled by 10^18. The core computes:

P = ceil(D × p / 10^18).

The pinned integer math library rounds this multiplication and division upward.

P is an asset quantity. The core next calls its own withdraw with P assets, the vault itself as receiver and the supplied onBehalf account as share owner. The returned value is the penalty’s vault shares burned, not D or P. These steps appear together in the pinned forceDeallocate implementation.

At that withdrawal state, let A be accrued recorded assets, S the share supply including applicable accrued fee shares, and V the vault’s virtual shares. The share burn is:

Q = ceil(P × (S + V) / (A + 1)).

The extra asset is one raw base unit. V depends on the underlying token’s decimals. This is the vault’s conversion; the direct Morpho Blue supply-share calculation belongs to the underlying market and uses its own virtual quantities. Keep those two share ledgers separate.

The curator configures p per adapter, subject to the applicable timelock, which can be zero. The allowed ceiling is 2%, while an actual adapter can have a lower rate or zero. Read its current value rather than assuming the ceiling applies. Morpho’s adapter configuration guide documents the setting and its 10^18 scale.

Permissionless initiation still checks canSendShares(onBehalf). The penalty receiver is the vault itself, which always passes the receive-assets gate. A later payout to a user or helper must satisfy the gate for that receiver. If the caller differs from onBehalf, the withdrawal checks vault-share allowance for the penalty burn. A zero penalty burns zero shares, while the share-sending gate still applies. The contract reference makes the caller, owner and return-value distinction explicit.

Follow a 10,080 U position through a constrained exit

This is a hypothetical integer example using fictional token U, not a dollar value or live vault quote. U and the vault shares both have 18 decimals. Opening recorded assets and share supply are each 1,000,000 whole units. The vault therefore has one raw virtual share unit. In raw-unit arithmetic, (S + 1) / (A + 1) is exactly one throughout the modeled transaction.

Alice owns 10,080 shares. The vault has 2,000 U idle, its liquidity market can supply nothing further, and a different market held through the same adapter can release at least 8,000 U. That adapter’s penalty is 1%. All transfers are exact; gates, balances and permissions are satisfied. Vault fees and the helper’s referral fee are zero. There is no additional interest, loss or liquidity change during execution. Both illustrative fixtures use unexpired deadlines and a zero minSharePriceE27, isolating the penalty and share calculations.

Alice requests a penalty-inclusive position debit of 10,080 U. With 2,000 U available normally, the remaining gross amount is 8,080 U. For the pinned helper, the forced amount is:

D = floor(8,080 / 1.01) = 8,000 U.

The penalty is P = ceil(8,000 × 0.01) = 80 U. At the stipulated conversion, Q is exactly 80 whole vault shares. Calculations use the underlying 18-decimal integers; these whole-unit expressions have no discarded remainder.

Completed stepU paid to AlicePenalty in UShares burnedAlice’s shares left
Ordinary withdrawal2,00002,0008,080
Force-deallocate 8,000 U080808,000
Withdraw the returned idle8,00008,0000
Total10,0008010,0800

The forced amount becomes idle before the final withdrawal. The penalty’s transfer to the vault itself leaves that idle token balance unchanged: Alice gives up 80 U of share value, and the vault retains the assets. Her net receipt is 2,000 + 8,000 = 10,000 U; her gross debit is 10,000 + 80 = 10,080 U.

The 1% setting applies to the 8,000 U forced amount. Relative to the whole position debit, the effective penalty is 80 / 10,080 × 100 ≈ 0.793651%. The normally available 2,000 U attracts no forced-deallocation penalty.

Reconcile retained tokens with recorded assets

After execution, idle tokens plus the stipulated adapter position values total 1,000,000 − 10,000 = 990,000 U. Idle is zero; the remaining adapter positions are valued at 990,000 U. Recorded _totalAssets and share supply each end at 1,000,000 − 10,080 = 989,920 whole units. The difference is the retained 80 U penalty.

The core treats the penalty as a withdrawal for accounting purposes, reducing recorded assets and supply even though the token transfer returns to itself. Interest accounting runs only once per transaction. Later recognition of the retained value is constrained by maxRate; the example does not assume an immediate 80 U share-price increase. Those details are documented in the core accounting and accrual code.

The Yearn idle-versus-debt ledger also separates asset location from accounting value, but its stored fields and report mechanism differ. Here, retain the penalty-specific 80 U reconciliation. Performance and management fees have a separate Vault V2 fee-share ledger; setting them to zero isolates this exit.

Check the helper’s rounding separately from the core

The core accepts D directly and calculates P for that call. It does not interpret D as a requested net wallet receipt or a penalty-inclusive exit budget.

The pinned VaultExitBundlesV1 helper instead accepts exitAssets. It first withdraws the available ordinary portion L, then calculates:

D = floor((exitAssets − L) × 10^18 / (10^18 + p)).

It walks the adapter’s prefetched market list, taking at most each market’s available capacity until D is covered. Each nonzero leg calls core forceDeallocate separately. It then withdraws D and forwards the proceeds. Reproduce this helper’s market-list order and rounding when modeling its transaction.

That distinction matters at integer boundaries. Consider a separate illustrative fixture with the same exact one-to-one vault conversion and 1% penalty. All amounts in this fixture are raw base units, deliberately tiny. Normal liquidity is zero, exitAssets is 101, and the helper encounters two positions that can release 50 each. Its aggregate forced amount is floor(101 / 1.01) = 100.

Each 50-unit leg incurs ceil(50 × 0.01) = 1 penalty unit. The two penalties total 2, whereas one 100-unit leg would incur 1. The two-leg execution pays 100 asset units and burns 102 share units. A nominal input of 101 therefore does not establish an exact 101-unit gross burn. If Alice has only 101 share units, the final burn fails and the atomic transaction reverts its preceding movements.

Use the actual number of legs and each rounded burn when checking the share balance and allowance. The helper’s minSharePriceE27 compares withdrawn assets per share burned, scaled by 10^27. For the tiny fixture, that rounded result is 980392156862745098039215686; a higher minimum also makes the helper revert. Its separate referral fee is deducted afterward, so the final wallet receipt also needs that deduction. A fee-recipient caller has an additional documented share-count caveat when fee shares accrue during the exit. The examples exclude both effects.

Validate the exit at one fresh state

For an underlying-asset exit, the useful decision sequence is:

  1. Identify the chain, vault, helper, underlying decimals and exact adapter markets. Read the user’s vault shares, current penalty, liquidity route, applicable gates and required share allowance together.
  2. Calculate L from idle and available liquidity through the configured liquidity position. Vault V2’s ERC-4626 maxWithdraw getter always returns zero; use a supported capacity calculation and simulation, as the contract reference explains.
  3. Use an ordinary withdrawal when L covers the request. Otherwise, calculate candidate capacities from the adapter’s position and each market’s liquidity, then reproduce the selected route’s actual leg order, rounding and share burns.
  4. Disclose the gross position debit, penalty assets and net wallet receipt. Apply the route’s deadline and price bounds, including referral deductions where present, and simulate the whole transaction immediately before signing.
  5. After confirmation, reconcile each deallocation and penalty burn with the owner’s share decrease and the receiver’s underlying-token increase. Preserve raw integers alongside formatted values.

Fresh liquidity can change the path between a preview and execution. Where the underlying markets cannot release the required tokens, force-deallocation alone cannot manufacture cash. A partial exit or an appropriately supported in-kind route needs its own capacity and transaction checks. A completed ledger should show what left the user’s position, what arrived in the wallet and what value stayed in the vault.

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.