Margin & Leverage
Margin requirements in Bazaar are dynamic: they respond to realized volatility, realized liquidation quality, and insurance-fund health, rather than being set per-market by governance.
Initial margin (IMR)
Recomputed at most once per minute:
IMR = 3% base
× volatility multiplier (1× → 3× as annualized vol goes ~14% → ~100%)
× liquidation-gap multiplier (1× → 3× as realized gap EMA goes 0 → 3%)
× insurance multiplier (1× → 3× as the fund goes target → empty)
× 1.5 if not continuously traded (stocks, FX)
clamped to [4%, 80%] (25× down to 1.25× max leverage)
- Volatility is an EMA of annualized squared returns (τ = 5 days).
- Liquidation gap is a size-weighted, time-decayed EMA (τ = 3 days) of how far liquidation fills landed from bankruptcy prices — a market that liquidates badly gets more conservative automatically.
- Insurance health compares the fund to its target ratio.
Warmup: a new market's IMR is floored at 20% (5× leverage; 30% for non-continuously traded pairs) until it is 5 days old and has seen 50,000 price updates. Thin, young books don't get 25× leverage.
IMR is what's checked at order creation and collateral withdrawal — always against worst-case exposure: current position plus resting orders in the worse direction, including the flip case. Under a stale oracle, requirements double.
Maintenance margin (MMR) and the 24-hour grace
MMR = IMR / 2, always. A position is liquidatable when equity < MMR × notional (see Liquidations).
Because IMR is dynamic, a volatility spike could raise MMR and instantly liquidate positions that were healthy a minute ago. Bazaar prevents this with a lagged MMR: the pair samples MMR hourly into a 25-slot ring buffer, and existing positions are judged against
effectiveMMR = min(reference, current)
reference = the newest sample ≥ 24 h old (if the position is ≥ 24 h old)
= the position's entry MMR (otherwise)
A rising requirement cannot liquidate you for 24 hours; a falling one helps you immediately. The grace re-anchors every time you increase risk (open, add, flip), and a closed position forfeits it entirely.
Solvency math
All solvency questions go through one function — BucketLib.calculateState:
unrealizedPnl = ±(currentNotional − entryValue)
fundingPnl = ∓(currentFundingIndex − entryFundingIndex) × size / 1e18
equity = collateral + unrealizedPnl + fundingPnl
isSolvent = max(0, equity) ≥ effectiveMMR × currentNotional AND equity > 0
Matching, withdrawals, liquidations, and ADL all call the same math with the same lagged-MMR inputs, so a position cannot be simultaneously "healthy" to one subsystem and "liquidatable" to another.