Backpack Exchange Trading System - Technical Overview
TL;DR
Margin & Leverage:
- MF (Margin Fraction) = Your equity / Your exposure (your current health)
- MMF (Maintenance Margin Fraction) = Minimum MF before liquidation
- IMF (Initial Margin Fraction) = Minimum MF to open a position (IMF > MMF always)
- Margin requirements scale with position size via sqrt function (bigger position = more margin required)
Liquidation Flow:
- MF drops below MMF → On-book liquidation (IOC orders, 10% of position per loop, 50% probability throttle)
- MF drops below
mf_auto_close→ Backstop liquidation (forced fills against designated LPs) - Backstop capacity exhausted → ADL (Auto-Deleverage against profitable traders with opposing positions)
Key Insight: Even winning trades can be forcefully closed via ADL in extreme conditions. Lower leverage = selected last for ADL.
Table of Contents
- Margin System
- Liquidation System
- Backstop & ADL
- Collateral Conversion
- SystemOrderTypes
- Trading Concepts
- Backpack vs Other Exchanges
1. Margin System
Core Formulas
Leverage = Position Notional / Equity
MF (Margin Fraction) = Equity / ExposureThe Three Key Fractions
| Term | Full Name | Purpose | Typical Range |
|---|---|---|---|
| MF | Margin Fraction | Your current health | Varies |
| MMF | Maintenance Margin Fraction | Liquidation threshold | 1-10% |
| IMF | Initial Margin Fraction | Minimum to open position | 2-20% |
Memory trick:
- MF = "My Funds" - where am I now?
- MMF = "Minimum to Maintain" - when do I get liquidated?
- IMF = "Initial to Make (a trade)" - can I open this?
Dynamic Margin (Sqrt Scaling)
Margin requirements are NOT fixed - they scale with position size:
MMF = max(base, factor × sqrt(notional))
IMF = max(base, factor × sqrt(notional))Example (SOL market with base=1%, factor=0.0001):
| Position Size | MMF | Max Leverage |
|---|---|---|
| $1,000 | 1% | 100x |
| $100,000 | 10% | 10x |
| $1,000,000 | 31% | ~3x |
Key files:
/core/types/src/math/position_imf.rs- Sqrt function implementation/engine/src/models/account/mod.rs- Margin calculations
2. Liquidation System
Trigger Condition
Liquidation starts when: MF <= MMFLiquidation Architecture
┌─────────────────────────────────────────────────────────────┐
│ Liquidator │
├──────────────┬──────────────┬──────────────┬────────────────┤
│ Trigger │ Executor │ Resolver │ Aggregator │
│ (detect) │ (liquidate) │ (exit mode) │ (data) │
└──────────────┴──────────────┴──────────────┴────────────────┘Components:
- LiquidationTrigger - Monitors accounts every 1 second, flags those with MF <= MMF
- LiquidationExecutor - Processes liquidations (on-book, backstop, ADL)
- LiquidationResolver - Transitions accounts out of liquidation mode
- LiquidationDataAggregator - Central data source for all decisions
On-Book Liquidation (Primary Method)
When MF drops below MMF but above mf_auto_close:
Throttling mechanism:
- Loop runs every 1 second
- 50% probability per loop (coin flip whether to execute)
- Maximum 10% of position liquidated per execution
- Expected full liquidation time: ~20 seconds
Why throttle?
- Prevents market disruption from large dumps
- Gives order book time to absorb
- Reduces cascade liquidation risk
Order type: IOC (Immediate-Or-Cancel) limit orders that cross the spread
Key files:
/liquidator/src/tasks/liquidation/trigger.rs/liquidator/src/tasks/liquidation/executor.rs/liquidator/src/context/book/positions.rs
Tiered Exit Thresholds
To exit liquidation mode, accounts need MORE margin than to enter (prevents oscillation):
| Account Net Equity | Exit Requirement |
|---|---|
| < $10k | MMF × 1.01 (1% buffer) |
| $10k - $250k | MMF × 1.0075 (0.75% buffer) |
| $250k - $1M | MMF × 1.005 (0.5% buffer) |
| > $1M | MMF × 1.0025 (0.25% buffer) |
Key file: /liquidator/src/aggregator.rs
3. Backstop & ADL
When Each Method Triggers
MF Level:
─────────────────────────────────────────
100% Normal trading
↓
MMF ON-BOOK liquidation starts
↓
mf_auto_close = max(MMF/2, MMF-6%)
↓
BACKSTOP liquidation
↓
ADL (if backstop exhausted)
↓
0% Account wipedBackstop Liquidity Providers (BLPs)
What they are: Designated market makers who are contractually obligated to absorb liquidating positions when order book liquidity is insufficient.
How they work:
- Register for specific markets with capacity limits
- Capacity refreshes hourly/minutely
- When triggered, they MUST take the other side of the liquidation
- Compensated with favorable fill price (2/3 of the spread)
Price distribution on backstop liquidation:
Mark Price ($100)
│
│ ← 2/3 of spread → Backstop LP (profit)
│
Maker Price ($93.33)
│
│ ← 1/3 of spread → Liquidity Fund
│
Zero Price ($90) ← Where liquidated account's equity = $0Liquidated user gets: ~$0 (their remaining equity is distributed)
Key files:
/engine/src/models/backstop_liquidity.rs/engine/src/engine/liquidation/mod.rs
ADL (Auto-Deleveraging)
What it is: Last resort - forces profitable traders to close their positions to absorb liquidations.
When it triggers:
- On-book liquidity exhausted
- Backstop LP capacity exhausted
- Still need to close liquidating positions
Who gets ADL'd:
- Traders with opposing positions (your SHORT absorbs their LONG liquidation)
- Sorted by margin fraction ascending (lowest MF = selected first)
- Two-phase selection:
- Delta-reducing only (reduces your position, doesn't flip it)
- If insufficient, removes delta constraint
What you lose:
- NOT money directly (you still profit)
- Opportunity - forced to close, can't ride the trade further
Example:
You: SHORT SOL at $100, price drops to $80
Unrealized profit: $20/SOL
ADL forces you to close at $82 (maker price)
Realized profit: $18/SOL
Price later drops to $50...
You missed: $32/SOL additional profitHow to minimize ADL risk:
- Use lower leverage (higher MF = selected last)
- Take profits earlier
- Trade liquid markets
Key file: /liquidator/src/context/backstop/positions.rs
4. Collateral Conversion
What it is: Automatic process that sells non-USDC collateral to cover unsettled debt.
When it happens:
- Account has unsettled debt (negative
unsettled_equity) - Direct settlement fails (not enough USDC balance/lend/borrow capacity)
- System sells other collateral to cover
Process:
- CollateralReconciler runs every 10 seconds
- Identifies accounts with negative equity
- Tries settling with USDC first
- If debt remains, identifies largest collateral assets
- Sells via IOC orders (or RFQ)
- Settles remaining debt with proceeds
Key file: /liquidator/src/tasks/collateral_reconciler.rs
5. SystemOrderTypes
Orders created by the system (not users) are tagged with a type:
| Type | Purpose | On-Book? |
|---|---|---|
LiquidatePositionOnBook | Regular order book liquidation | Yes |
LiquidatePositionOnBackstop | Backstop LP liquidation | No |
LiquidatePositionOnAdl | Auto-deleverage liquidation | No |
CollateralConversion | Selling collateral to settle debt | Yes |
FutureExpiry | Closing positions at futures expiration | No |
OrderBookClosed | Closing positions when market removed | No |
Helper methods:
is_liquidation() → true for all 3 liquidation types
is_backstop_liquidation() → true for Backstop and ADLKey file: /core/types/src/models/orders.rs
6. Trading Concepts
Maker vs Taker
Simple definition:
| Role | What You Do | Fee |
|---|---|---|
| Maker | Place order that sits on book waiting (adds liquidity) | Lower (often 0.02% or rebate) |
| Taker | Place order that fills immediately (removes liquidity) | Higher (often 0.05-0.10%) |
Example:
Order Book:
ASKS (sellers)
$101 - 5 SOL
$100 - 10 SOL ← Best ask
─────────────
$99 - 8 SOL ← Best bid
BIDS (buyers)| Your Action | Role | Why |
|---|---|---|
| Limit buy at $98 | Maker | Order sits on book, waiting |
| Limit buy at $100 | Taker | Fills immediately against $100 ask |
| Market buy | Taker | Fills at best available ($100) |
Liquidation orders are takers (IOC orders crossing the spread, ~1% fee).
Post-Only Orders
What it does: Order is rejected if it would execute immediately (be a taker).
| Your Order | Regular Limit | Post-Only |
|---|---|---|
| Buy at $100 (best ask) | Fills immediately (taker) | REJECTED |
| Buy at $99.99 | Sits on book (maker) | Sits on book (maker) |
Tradeoff:
- Pro: Guaranteed maker fee (lower/rebate)
- Con: Might miss trades, must set "worse" price
Who uses it: Market makers who always want maker fees. Regular traders usually don't need it.
Price Types (How Backpack Calculates Them)
| Price | Definition | Update Frequency |
|---|---|---|
| Last Price | Most recent trade on Backpack | On every fill |
| Index Price | Aggregated from external exchanges | Every 2-5 seconds |
| Mark Price | Fair price for margin/liquidation | Every 1 second |
Last Price
- Simply the price of the most recent trade
- Updated whenever a fill occurs
- Considered "stale" if no trades for 60 seconds
Index Price
Aggregated from 15+ external exchanges:
- Binance, Coinbase, Kraken, OKX, Bybit, Bitfinex, Kucoin, etc.
- Also uses Pyth oracle
Calculation:
- Fetch bid/ask/last from each exchange
- Calculate median(bid, ask, last) per exchange
- Cap outliers (>1% from median of all sources)
- Average remaining prices
Why multiple sources: Prevents manipulation. One exchange can't spike your liquidation.
Mark Price
Used for all margin calculations, PnL, and liquidations.
Calculation (in order of preference):
index_price + moving_average(mid_price - index_price)over 60 seconds- Fallback: Just index price
- Fallback: Median(best_bid, best_ask, last_price)
- Fallback: Mid price
- Fallback: Last traded price
Why this approach: Smooths out short-term manipulation while tracking real market.
Key file: /price-oracle/src/mark_price/price_state.rs
Order Types
| Type | Behavior |
|---|---|
| Market | Fill immediately at best price |
| Limit | Fill at specified price or better |
| IOC | Immediate-Or-Cancel: fill what you can now, cancel rest |
| FOK | Fill-Or-Kill: fill entire order or cancel everything |
| GTC | Good-Till-Cancelled: stays on book until filled/cancelled |
| Post-Only | Maker only; rejected if would take |
| Reduce-Only | Can only reduce position, not increase or flip |
Funding Rate (Perpetuals)
Keeps perp price aligned with spot index:
- Perp > Index → Longs pay Shorts (positive funding)
- Perp < Index → Shorts pay Longs (negative funding)
Paid periodically (typically every 8 hours).
Collateral Haircuts (ELI5)
What is a haircut?
A haircut is a "discount" applied to your collateral for safety.
Why? When you get liquidated, the exchange must SELL your collateral to cover debt. But:
- Price might drop while selling
- Large orders have slippage
- Markets can be volatile
The haircut is a safety buffer so the exchange doesn't get stuck with bad debt.
Example:
You deposit 1 BTC worth $100,000
Exchange says: "We'll count this as $95,000 for margin"
That 5% reduction = the haircutIn practice:
| You Have | Market Value | Haircut | Counts As (for margin) |
|---|---|---|---|
| $100 USDC | $100 | 0% | $100 |
| 1 BTC ($100k) | $100,000 | ~5% | $95,000 |
| 100 SOL ($10k) | $10,000 | ~10% | $9,000 |
| Altcoins | $1,000 | ~20-30% | $700-800 |
Rule of thumb: The riskier/less liquid the asset, the bigger the haircut.
7. Backpack vs Other Exchanges
Based on analysis of the bpx-backend code, here are Backpack's distinctive features:
Margin System
| Feature | Backpack | Typical Exchange |
|---|---|---|
| Margin scaling | Sqrt function (continuous) | Fixed tiers (discrete jumps) |
| Position-specific margin | Each position stores its own MMF at open time | Global market MMF applies to all |
| Exit threshold | Tiered by account equity size | Usually fixed multiplier |
Backpack advantage: Sqrt scaling is smoother - no sudden margin requirement jumps at tier boundaries. Position-specific MMF means market-wide changes don't retroactively affect your existing positions.
Liquidation System
| Feature | Backpack | Typical Exchange |
|---|---|---|
| Liquidation throttle | 50% probability × 10% per loop (~20s full liquidation) | Often immediate or faster |
| Price protection | 2% from index price bound | Varies |
| Three-tier system | On-book → Backstop → ADL | Usually On-book → ADL |
Backpack advantage: The probabilistic throttling reduces market impact during liquidations. The backstop LP layer provides a buffer before ADL kicks in.
Backstop System
| Feature | Backpack | Typical Exchange |
|---|---|---|
| Dedicated backstop LPs | Yes - registered market makers with capacity | No - goes straight to ADL |
| Capacity refresh | Hourly/minutely auto-refresh | N/A |
| Price mechanism | 2/3 to maker, 1/3 to liquidity fund | Varies |
Backpack advantage: Dedicated backstop layer means ADL is truly last resort. Most exchanges go directly from order book to ADL.
ADL System
| Feature | Backpack | Typical Exchange |
|---|---|---|
| Selection criteria | Margin fraction (ascending) | Often PnL-based (highest profit first) |
| Delta-reducing priority | Yes - tries to reduce without flipping first | Usually no |
| Distribution method | Sequential then pro-rata | Varies |
Backpack advantage: Selecting by margin fraction (not profit) means conservative traders are protected. Delta-reducing priority means your position is reduced, not flipped to the opposite side.
Collateral Management
| Feature | Backpack | Typical Exchange |
|---|---|---|
| Auto collateral conversion | Yes - sells assets to settle debt | Often manual or partial |
| Settlement frequency | Every 10 seconds | Varies |
| RFQ integration | Can use RFQ for conversions | Usually order book only |
Backpack advantage: Automatic collateral conversion prevents debt accumulation. RFQ option may provide better prices for larger conversions.
Summary: What Makes Backpack Different
- Smoother margin curves - Sqrt scaling instead of tier cliffs
- Gentler liquidations - Probabilistic throttling reduces market impact
- Extra safety layer - Backstop LPs before ADL
- Fairer ADL selection - By margin fraction, not profit
- Position isolation - MMF locked at position open time
- Tiered exit requirements - Account size-aware liquidation exit
- Automatic debt settlement - CollateralConversion handles unsettled equity
Key File Reference
| Component | Location |
|---|---|
| Margin calculations | /engine/src/models/account/mod.rs |
| IMF/MMF sqrt function | /core/types/src/math/position_imf.rs |
| Liquidation trigger | /liquidator/src/tasks/liquidation/trigger.rs |
| Liquidation executor | /liquidator/src/tasks/liquidation/executor.rs |
| On-book liquidation | /liquidator/src/context/book/positions.rs |
| Backstop/ADL logic | /liquidator/src/context/backstop/positions.rs |
| Backstop price calculation | /engine/src/engine/liquidation/mod.rs |
| Collateral conversion | /liquidator/src/tasks/collateral_reconciler.rs |
| SystemOrderTypes | /core/types/src/models/orders.rs |
| Control panel defaults | /engine/src/engine/control_panel.rs |
| Price oracle (mark price) | /price-oracle/src/mark_price/price_state.rs |
| Price oracle (index price) | /price-oracle/src/index_price/index.rs |