Bankruptcy Resolution
A bankruptcy is what is left when liquidation runs out of assets: the account still owes a debt and holds nothing that can pay it. Someone has to absorb that debt. This page sets out exactly who, and in what order.
Resolution is permissionless. Anyone can call resolve_perp_bankruptcy or resolve_spot_bankruptcy on a latched account, and both are gated by State.solvencyStatus rather than the general withdraw-pause flags.
Every tranche below is drawn in order, and each one only sees the loss the tranches above it could not cover. Nothing is socialized until every tranche is exhausted.
Step 0: the estate pays first
Before any shared money moves, the resolver empties the bankrupt account itself:
- Recover perp claims. Positive claims the account holds against perp PnL pools are pulled in, capped at the debt being resolved.
- Set off the account’s own quote deposit. For a perp bankruptcy, any quote deposit the account still holds is transferred into the market’s PnL pool and credited against the debt. This is exactly the
settle_pnlthe bankrupt account is barred from making itself. - Forfeit unfundable claims. Positive perp claims the protocol cannot fund are extinguished, capped at the loss other people are about to cover. An estate cannot keep a claim after someone else’s money paid its debt.
If a realizable asset turns up after this step (a non-quote deposit, a keeper reward, a swept revenue share), the latch’s premise is stale. The resolver clears the bankruptcy flag and returns without drawing anything. Ordinary liquidation then seizes the asset and re-latches for whatever residual is real.
If the setoff clears the debt entirely, resolution ends there: no tranche is touched and the flag clears unless another market still holds a bankrupting liability.
Perp bankruptcy waterfall
Tranche 1: the market’s in-transit insurance fee
The market’s own not-yet-swept pending_if_fee is consumed first. This is a counter-only draw: the pending fee claim and the forgiven loss are both claims on future PnL-pool inflows, so cancelling one against the other moves no tokens. The value that would have swept to the revenue pool stays in the PnL pool, backing the counterparties this spares from socialization.
Tranche 2: the shared Insurance Fund vault
The quote market’s Insurance Fund vault covers the remainder, bounded by the market’s own insurance claim cap (quote_max_insurance minus quote_settled_insurance) and by the vault balance minus 1 token, which always stays behind. A market whose contract tier caps insurance at zero draws nothing here.
Tranche 3: the AMM fee-provision clawback
The market claws back the fee provision the AMM has been granted, capped at amm_protocol_fees_received (the cumulative provision, net of prior clawbacks). The untokenized portion goes first, as another counter-only draw, then tokens move from the AMM fee pool into the PnL pool. The AMM’s own trading and spread capital beyond that provision is never touched, and neither is the external LP pool.
Socialized loss
Anything still outstanding is socialized across surviving open interest in that market, through an asymmetric bump to both cumulative funding rates, so longs and shorts both pay. See Socialised Loss.
Spot bankruptcy waterfall
Tranche 1: the market’s revenue pool
The bad-debt market’s own revenue_pool is first-loss capital. It is consumed before the staker-owned Insurance Fund vault and before any socialization. Like the perp in-transit fee, this is counter-only: the pool’s tokens already sit in the spot vault, so cancelling its deposit claim against the forgiven borrow moves nothing. Unlike the periodic revenue settlement, this draw is neither timer-gated nor capped by staker APR.
Tranche 2: the Insurance Fund vault
That market’s Insurance Fund vault covers the rest of the borrow, again leaving at least 1 token in the vault.
Socialized loss
The residual is socialized across that market’s depositors by lowering cumulative_deposit_interest, so every lender in the market takes a pro-rata haircut.
Perp bankruptcies must be resolved before spot bankruptcies. Both resolvers draw on the same quote Insurance Fund vault, so allowing a caller to choose the order would let them shift loss between perp and spot stakeholders. resolve_spot_bankruptcy rejects with PerpBankruptcyMustPrecedeSpot while the account still has an unresolved cross-margin perp bankruptcy.
The standing first-loss tranche
Tranche 1 of a perp bankruptcy is only useful if there is something in it when the bankruptcy happens, and the fee sweep is permissionless. So the sweep is not allowed to drain pending_if_fee to zero: each perp market holds a standing floor behind.
- The floor is
bankruptcy_if_floor_pctof the market’s open-interest notional, priced at the market’s own oracle TWAP rather than a live print, so a manipulated spot price cannot crush it. 0resolves to the default of 10 bps (0.1%) of open-interest notional, so every market carries the tranche without an admin call.BANKRUPTCY_IF_FLOOR_DISABLEDturns the standing floor off. The value is set byupdate_perp_market_bankruptcy_if_floor_pctand must be at or below 100%, or exactly the disable sentinel.
The sweep’s Insurance Fund drain therefore leaves at least this much behind on every call, permissionless sweeps and the inline sweep on any PnL settle included.
The claim freeze
The standing floor is sized off market risk, which is only a proxy for a loss and can be smaller than one. So the moment a bankruptcy is actually latched against a market, the market stops relying on the proxy:
- Latching a bankrupt perp debt increments
PerpMarket.pendingBankruptcyClaims. - While that count is above zero, the fee sweep withholds the whole
pending_if_fee, not just the floor. Without this, a permissionless sweep could drain the first-loss tranche between the latch and the resolution and push the loss onto the shared Insurance Fund or into socialization. - The freeze is independent of open interest and of
bankruptcy_if_floor_pct. Both can be zero exactly when a bankruptcy is pending, and turning the floor off does not expose a latched claim. - The count is decremented when the claim is discharged: either
resolve_perp_bankruptcyabsorbs the debt through the waterfall, orsettle_pnlreleases the claim once the position’s quote reaches zero. Neither needs the admin.
Delisting is blocked while a claim is open. settle_expired_market_pools_to_revenue_pool rejects while pendingBankruptcyClaims is above zero, because that instruction’s final sweep reserves nothing and would drain the tranche backing the open debt. The market stays in Settlement while the two permissionless paths above clear the count. See Delisting Process.
What this means for you
- Insurance Fund stakers. Two tranches stand between a perp bad debt and the vault you are staked in: the market’s in-transit insurance fee (with its standing floor) and, for spot, the market’s own revenue pool. A third, the AMM fee-provision clawback, sits after the vault, so it does not protect you. Markets on the riskiest contract tiers cannot draw on the vault at all.
- Market makers and keepers. If an Insurance Fund fee sweep returns less than you expect, or a delisting is refused, check the market’s
pendingBankruptcyClaims. A non-zero count freezes both. - Traders. Socialized loss is the last tranche, never the first. On a perp market it arrives as a funding-rate bump paid by every surviving position; on a spot market it arrives as a lower deposit-interest index paid by every lender.