← Documentation home
Build · Reference

Errors

Custom errors thrown by the metavault, with payload and when each fires.

Values for the named bounds (BPS, MAX_PERFORMANCE_FEE_BPS, MAX_CORRELATED_SENIOR_LEVERAGE_BPS, etc.) live in the Constants table on the metavault page. This page describes the errors themselves; the cap values are not repeated here so the two sources can't drift.

Validation

ErrorWhen it fires
InvalidAmount()A numeric input is zero (zero deposit, zero shares, zero notice).
InvalidAddress()Required address argument is address(0) (constructor vault, receiver, etc.).
InvalidRate()A premium-rate argument exceeds BPS.
InvalidFeeRate()A performance-fee-rate argument exceeds MAX_PERFORMANCE_FEE_BPS.
InsufficientAssetReceived(uint256 expected, uint256 received)transferFrom delivered less than asked; fee-on-transfer or rebasing assets are unsupported.

Pause

ErrorWhen it fires
DepositsPaused()Either depositSenior or depositJunior while depositsPaused is true. Single global flag; there is no senior-only pause mode.

Solvency / capacity

ErrorWhen it fires
ProtectionTooThin(uint256 seniorAssets, uint256 juniorAssets, uint256 requiredJuniorAssets)A senior deposit (or junior withdrawal) would push senior NAV past the senior-leverage cap (MAX_CORRELATED_SENIOR_LEVERAGE_BPS).
InsufficientJuniorProtection(uint256 requestedAssets, uint256 maxAssets)A junior withdrawal would breach the senior protection floor (i.e. exceed maxJuniorWithdrawAssets).
InsufficientVaultLiquidity(uint256 requestedShares, uint256 availableShares)The wrapped ERC4626 cannot satisfy the requested redemption right now (gates closed, queue full, etc., transient).
TrancheWiped(uint8 trancheId)New deposits into a tranche whose NAV has reached zero while shares are still outstanding. The wiped side is terminal until a new series is deployed; new capital cannot resurrect the zero unit price.

Withdrawal notice flow

Symmetric for senior and junior, indexed by holder address.

ErrorWhen it fires
WithdrawalNoticePending(uint256 executableAt)withdrawSenior / withdrawJunior called before the notice has matured.
WithdrawalNoticeTooSmall(uint256 requestedShares, uint256 noticedShares)Execution requested more shares than the notice covers.
WithdrawalNoticeExpired()Execution attempted with no active notice on file.

Underlying integrity

These guard the boundary between the metavault and the wrapped ERC4626. They should not fire against a well-behaved 4626; they exist to detect non-conforming integrations. The factory's approvedUnderlyings allowlist is the deploy-time gate; these errors are the runtime backstop.

ErrorWhen it fires
InvalidUnderlyingWithdrawal(uint256 expectedShares, uint256 burnedShares)The underlying vault burned a different number of shares than the metavault expected during a redemption.
UnderlyingValueLoss(uint256 minAssets, uint256 actualAssets)The underlying vault delivered fewer assets than the minimum the metavault computed (modulo one unit of rounding). Approved underlyings are expected to be no-fee/no-slippage, so this catches misbehaving integrations before the loss is socialised across tranches.

Access control

ErrorWhen it fires
AccessControlUnauthorizedAccount(address account, bytes32 neededRole)Caller lacks the role gating a privileged setter. OPERATOR_ROLE gates setProtectionPremiumRate + setDepositsPaused; PROTOCOL_ROLE gates setPerformanceFeeRate + setFeeRecipient. Inherited from OpenZeppelin's AccessControl.

Need the 4-byte selector for a revert? Compute bytes4(keccak256(errorSig)). The reference frontend's decodeContractError helper does this lookup automatically.