Skip to content

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:

  1. MF drops below MMF → On-book liquidation (IOC orders, 10% of position per loop, 50% probability throttle)
  2. MF drops below mf_auto_closeBackstop liquidation (forced fills against designated LPs)
  3. 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

  1. Margin System
  2. Liquidation System
  3. Backstop & ADL
  4. Collateral Conversion
  5. SystemOrderTypes
  6. Trading Concepts
  7. Backpack vs Other Exchanges

1. Margin System

Core Formulas

Leverage = Position Notional / Equity
MF (Margin Fraction) = Equity / Exposure

The Three Key Fractions

TermFull NamePurposeTypical Range
MFMargin FractionYour current healthVaries
MMFMaintenance Margin FractionLiquidation threshold1-10%
IMFInitial Margin FractionMinimum to open position2-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 SizeMMFMax Leverage
$1,0001%100x
$100,00010%10x
$1,000,00031%~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 <= MMF

Liquidation 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 EquityExit Requirement
< $10kMMF × 1.01 (1% buffer)
$10k - $250kMMF × 1.0075 (0.75% buffer)
$250k - $1MMMF × 1.005 (0.5% buffer)
> $1MMMF × 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 wiped

Backstop 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 = $0

Liquidated 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:

  1. On-book liquidity exhausted
  2. Backstop LP capacity exhausted
  3. 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:
    1. Delta-reducing only (reduces your position, doesn't flip it)
    2. 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 profit

How 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:

  1. Account has unsettled debt (negative unsettled_equity)
  2. Direct settlement fails (not enough USDC balance/lend/borrow capacity)
  3. System sells other collateral to cover

Process:

  1. CollateralReconciler runs every 10 seconds
  2. Identifies accounts with negative equity
  3. Tries settling with USDC first
  4. If debt remains, identifies largest collateral assets
  5. Sells via IOC orders (or RFQ)
  6. 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:

TypePurposeOn-Book?
LiquidatePositionOnBookRegular order book liquidationYes
LiquidatePositionOnBackstopBackstop LP liquidationNo
LiquidatePositionOnAdlAuto-deleverage liquidationNo
CollateralConversionSelling collateral to settle debtYes
FutureExpiryClosing positions at futures expirationNo
OrderBookClosedClosing positions when market removedNo

Helper methods:

rust
is_liquidation() → true for all 3 liquidation types
is_backstop_liquidation() → true for Backstop and ADL

Key file: /core/types/src/models/orders.rs


6. Trading Concepts

Maker vs Taker

Simple definition:

RoleWhat You DoFee
MakerPlace order that sits on book waiting (adds liquidity)Lower (often 0.02% or rebate)
TakerPlace 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 ActionRoleWhy
Limit buy at $98MakerOrder sits on book, waiting
Limit buy at $100TakerFills immediately against $100 ask
Market buyTakerFills 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 OrderRegular LimitPost-Only
Buy at $100 (best ask)Fills immediately (taker)REJECTED
Buy at $99.99Sits 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)

PriceDefinitionUpdate Frequency
Last PriceMost recent trade on BackpackOn every fill
Index PriceAggregated from external exchangesEvery 2-5 seconds
Mark PriceFair price for margin/liquidationEvery 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:

  1. Fetch bid/ask/last from each exchange
  2. Calculate median(bid, ask, last) per exchange
  3. Cap outliers (>1% from median of all sources)
  4. 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):

  1. index_price + moving_average(mid_price - index_price) over 60 seconds
  2. Fallback: Just index price
  3. Fallback: Median(best_bid, best_ask, last_price)
  4. Fallback: Mid price
  5. 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

TypeBehavior
MarketFill immediately at best price
LimitFill at specified price or better
IOCImmediate-Or-Cancel: fill what you can now, cancel rest
FOKFill-Or-Kill: fill entire order or cancel everything
GTCGood-Till-Cancelled: stays on book until filled/cancelled
Post-OnlyMaker only; rejected if would take
Reduce-OnlyCan 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 haircut

In practice:

You HaveMarket ValueHaircutCounts As (for margin)
$100 USDC$1000%$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

FeatureBackpackTypical Exchange
Margin scalingSqrt function (continuous)Fixed tiers (discrete jumps)
Position-specific marginEach position stores its own MMF at open timeGlobal market MMF applies to all
Exit thresholdTiered by account equity sizeUsually 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

FeatureBackpackTypical Exchange
Liquidation throttle50% probability × 10% per loop (~20s full liquidation)Often immediate or faster
Price protection2% from index price boundVaries
Three-tier systemOn-book → Backstop → ADLUsually 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

FeatureBackpackTypical Exchange
Dedicated backstop LPsYes - registered market makers with capacityNo - goes straight to ADL
Capacity refreshHourly/minutely auto-refreshN/A
Price mechanism2/3 to maker, 1/3 to liquidity fundVaries

Backpack advantage: Dedicated backstop layer means ADL is truly last resort. Most exchanges go directly from order book to ADL.

ADL System

FeatureBackpackTypical Exchange
Selection criteriaMargin fraction (ascending)Often PnL-based (highest profit first)
Delta-reducing priorityYes - tries to reduce without flipping firstUsually no
Distribution methodSequential then pro-rataVaries

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

FeatureBackpackTypical Exchange
Auto collateral conversionYes - sells assets to settle debtOften manual or partial
Settlement frequencyEvery 10 secondsVaries
RFQ integrationCan use RFQ for conversionsUsually 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

  1. Smoother margin curves - Sqrt scaling instead of tier cliffs
  2. Gentler liquidations - Probabilistic throttling reduces market impact
  3. Extra safety layer - Backstop LPs before ADL
  4. Fairer ADL selection - By margin fraction, not profit
  5. Position isolation - MMF locked at position open time
  6. Tiered exit requirements - Account size-aware liquidation exit
  7. Automatic debt settlement - CollateralConversion handles unsettled equity

Key File Reference

ComponentLocation
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