Skip to main content

Errors

This page lists every code the market contract can raise, the condition behind it, and the entries that raise it. It also lists the traps that carry no MarketError code.

MarketError is a #[contracterror] enum with a u32 representation. A rejection inside the market traps with one of its codes. The trap rolls back every effect of that market call, so no partial effect survives it. A caller that invokes the market through a fallible path catches the trap and continues. The router batching page gives those paths.

Code bands​

Each band groups the codes of one concern. A gap inside a band is a code no variant uses.

CodesConcern
600The shared admin code. It carries the same meaning on every upgradeable contract in the protocol.
700 to 706Config, status, and retirement.
710The general guard on a negative number.
711 to 716Position size, margin, and capacity limits. Utilization is 714, open interest is 715, and a size that rounds to zero is 716.
720 to 723The position lifecycle.
730 to 734Orders.
740 to 742The fill price.
750 to 754Vault orders and vault fills. The band leaves 752 unassigned.
755Vault solvency. A settlement raises it on the order, liquidation, and auto-deleveraging (ADL) paths.
760The claimable credit.
770 to 772ADL.

Error codes​

Every row names the entries that raise the code. Token amounts are in token-dec, the decimals of the settlement token. Prices are in feed precision, and a ratio is in SCALAR_18.

CodeVariantConditionRaised by
600UpgradeNotOwneroperator is not the stored ownerupgrade
700InvalidConfigRules 2 to 20 of Config::check_valid fail, or feed_id does not start with 0x00 0x03__constructor, set_config
701InvalidPriceThe flat settlement price is not strictly positiveset_terminal_price
702InvalidStatusset_status receives an unknown discriminant, a same-status set, or a move out of Retired. It also rejects a move to Active or OnIce once the delist grace window (DELIST_GRACE, 86,400 seconds) has passed. set_terminal_price runs while the status is not Delisted or the grace window is open. create_vault_order receives a deposit on a Retired market.set_status, set_terminal_price, create_vault_order
703MarketNotAccruedA borrowing or funding rate parameter changes while the status is not Frozen, and MarketData.accrued_at is not the current ledger timestampset_config
704MarketFrozenThe status is Frozen, or the status is Retired and the entry is one that retirement closes. The status gate below lists both groups.create_order, cancel_order, create_vault_order, cancel_vault_order, claim_credit, every price-bearing entry
705IncreaseHaltedAn increase with positive notional runs while the status is not Active, or while the target side carries an ADL flagexecute_order
706MarketNotClearedA retirement runs while a notional, tokens, or margin total is nonzeroset_status
710NegativeValueNotAllowedA value that must be non-negative is negative. Rule 1 of Config::check_valid raises it on the owner paths. Order::require_valid and VaultOrder::require_valid raise it on the trader paths.__constructor, set_config, create_order, create_vault_order
711NotionalBelowMinimumThe resulting position notional is below min_position_notional. An ADL close cannot raise it, because the full-close clamp absorbs a small remainder.execute_order
712NotionalAboveMaximumAn increase order's own notional, the position notional after a fill, or the remainder of a partial ADL close is above max_position_notionalcreate_order, execute_order, execute_adl
713InsufficientMarginThe position margin is below the initial-margin requirement, which is init_margin times the notional rounded up. An ADL close skips the check.execute_order
714UtilizationExceededAfter an increase fill that adds notional, the increased side's reserved value is above max_util_open of half the settled vault balance. After a redeem fill, either side's reserved value is above max_util_withdraw of it.execute_order, execute_vault_order
715OpenInterestExceededAn increase with positive notional leaves a side's open interest above max_open_interestexecute_order
716SizeRoundsToZeroAn increase with positive notional buys no base size at the entry price. Only a long can raise it, because a short rounds its size up. A margin-only increase, with notional 0, passes.execute_order
720PositionNotFoundThe position notional is 0. get_position never raises it.execute_order, execute_liquidation, execute_adl
721NotionalLockedThe close reaches notional that is still under the decrease lockexecute_order, execute_adl
722NotLiquidatableThe settled equity is at or above the maintenance requirement, and the market is not both Delisted and past DELIST_DEADLINEexecute_liquidation
723PositionLiquidatableThe settled equity is below the maintenance requirement, either before a decrease or ADL close, or after an increase or a partial closeexecute_order, execute_adl
730OrderNotFoundNo Order(user, id) row exists. On a full close, the sweep of the listed decrease orders raises it when a listed row is missing.get_order, cancel_order, execute_order, execute_liquidation, execute_adl
731OrderExpiredexpiration is behind the current ledger sequencecreate_order, execute_order
732InvalidOrderThe request fails a dust floor or a no-op check, a trigger kind carries a zero trigger_price, or the escrow sum overflows. execute_adl raises it when amount is below min_order_notional.create_order, create_vault_order, execute_adl
733TooManyOrdersThe side already lists MAX_ORDERS_PER_SIDE (8) pending decrease orderscreate_order
734UnknownKindThe kind discriminant is not a known variant. A stored row always holds a known kind, so a fill or a cancel never raises it.create_order, create_vault_order
740StalePriceThe effective price predates the position's priced_at or the order's created_at. A vault fill in its order's creation ledger also raises it. A market order filled in its creation ledger skips the created_at check only.execute_order, execute_liquidation, execute_adl, execute_vault_order
741PriceBoundExceededThe order's price_bound is nonzero, and the fill price is worse than itexecute_order
742TriggerNotMetThe order is a trigger kind, and its trigger_price is not crossed at the fill priceexecute_order
750VaultOrderNotFoundNo VaultOrder(user, id) row existsget_vault_order, cancel_vault_order, execute_vault_order
751VaultOrderLockedA redeem fill runs before redeem_lock seconds have passed since created_atexecute_vault_order
753VaultBalanceExceededA deposit fill leaves the settled vault balance above max_vault_balanceexecute_vault_order
754PendingPnlExceededA redeem fill leaves a side's pending profit and loss (PnL) above max_pnl_withdraw of half the settled vault balanceexecute_vault_order
755VaultInsolventThe vault leg of a settlement is negative and larger than the tracked vault balance. Only a decrease fill can raise it on execute_order.execute_order, execute_liquidation, execute_adl
760NothingToClaimThe claimable amount, capped by the credit pool, is not positiveclaim_credit
770AdlNotTriggeredThe side carries no ADL flag, or its pending PnL is at or below adl_clear_target of half the vault balanceexecute_adl
771AdlOvershootThe close leaves the side's pending PnL under adl_clear_target of half the vault balance, re-measured after settlementexecute_adl
772AdlNotEligibleThe close does not reduce the side's pending PnLexecute_adl

The Orders page, the Vault orders page, and the Auto-deleveraging page own the mechanism behind these conditions. Every utilization check rounds toward rejection. The cap rounds down and a long side's reserve rounds up.

The status gate of MarketFrozen​

Market::load raises MarketFrozen (704) before it prices anything, so every price-bearing entry traps on a Frozen or Retired market. Those entries are execute_order, execute_liquidation, execute_adl, execute_vault_order, update_adl_state, and accrue. create_order traps on the same two statuses.

cancel_order, cancel_vault_order, claim_credit, and create_vault_order trap on Frozen alone. A Retired market therefore keeps cancels, funding claims, and a redeem through create_vault_order open.

Status::from_u32 decodes every status discriminant and raises InvalidStatus (702) on an unknown one. set_status is the only entry that takes the discriminant from a caller.

Failures without a MarketError​

Seven other sources of a trap reach a caller of the market. None of them is a MarketError.

SourceCodesReached through
OwnershipOwnableError (2100 to 2102) and RoleTransferError (2200 to 2203), both from stellar-accessset_config, set_status, set_terminal_price, upgrade, transfer_ownership, accept_ownership, renounce_ownership
OracleThe oracle's codes, or the report verifier's own errorverify_price, which Market::load calls once per price-bearing entry
TreasuryNone, because get_rate declares no error. A trap on the call is a host error.get_rate on the treasury contract
Settlement tokenThe token contract's codesEscrow, the cancel refund, the claim_credit payout, the retirement surplus sweep in set_status, and the vault, keeper, and treasury legs of every settlement
Strategy vaultThe vault's codesstrategy_deposit, strategy_redeem, strategy_withdraw, transfer on the share token, and preview_deposit and preview_redeem when the order's min_out is positive
AuthorizationNone, because host authorization carries no contract error coderequire_auth on user in create_order, cancel_order, create_vault_order, cancel_vault_order, and claim_credit. The escrow transfer from user in create_order and create_vault_order. The stored owner in the owner-only entries.
ArithmeticNone, because a host arithmetic trap carries no contract error codeThe fixed-point and index math of the market, including MarketData::side_reserved and MarketData::accrue_borrowing, which declare no MarketError

After a renounce, every owner-only entry traps with OwnerNotSet (2100). The Ownable codes table below gives the condition for each library code.

Market::load skips the oracle call while a terminal price is stored. The price verification page gives the report checks and the two staleness windows.

Every settlement reads the protocol fee rate. Settlement::fee_split reads it on an increase, a decrease, and a liquidation. Settlement::compute_vault_order reads it on a deposit fill, a redeem fill, and a vault-order rejection. A rejection pays only the keeper's exec_fee, and the vault fee is zero. The fee rate page gives the treasury's surface.

The trader leg of a settlement is the exception to the token row. pay_trader uses a fallible transfer, and it parks the amount as a claimable credit when the transfer fails.

Market::load reads the vault's total_assets on every price-bearing entry. create_vault_order and cancel_vault_order move shares, and on a Retired market create_vault_order runs the redeem outright. execute_vault_order runs a deposit or a redeem, and quotes it through the preview calls when min_out is positive. A settlement with a negative vault leg calls strategy_withdraw. The share pricing page gives the codes for the deposit, the redeem, and both previews. The share token page gives them for transfer, and the strategy withdraw page gives them for strategy_withdraw.

Ownable codes​

Codes 2100 to 2102 are OwnableError and codes 2200 to 2203 are RoleTransferError, both from stellar-access 0.7.2. The codes are the same on the oracle, factory, treasury, and governance contracts.

CodeNameRaised byCondition
2100OwnerNotSetEvery owner-only entry, transfer_ownership, renounce_ownershipThe owner key is absent
2101TransferInProgressrenounce_ownershipAn unexpired pending transfer exists
2102OwnerAlreadySetConstructorThe owner key exists, which a constructor on a fresh instance never meets
2200NoPendingTransfertransfer_ownership with 0, accept_ownershipNo pending entry exists
2201InvalidLiveUntilLedgertransfer_ownership with a value above 0live_until_ledger is below the current ledger sequence or above the highest sequence an entry can live to
2202InvalidPendingAccounttransfer_ownership with 0new_owner differs from the pending address
2203TransferExpiredaccept_ownershipThe current ledger sequence is above the pending live_until_ledger

The check order lives on the mechanism pages​

This page gives the condition for a code, not the sequence an entry runs. The Orders page gives the numbered gate list for create_order and execute_order. The Vault orders page gives the lists for create_vault_order and for the deposit and redeem fills. The Liquidation page and the Auto-deleveraging page give the lists for execute_liquidation and execute_adl. The Config page numbers the Config::check_valid rules behind InvalidConfig (700). The Market status page gives the transition matrix behind InvalidStatus (702).