🚧 SportsPerp is currently live on devnet. Mainnet target: before Jun 12, 2026 (World Cup kickoff).
TradingLiquidations

Liquidations

SportsPerp uses a three-layer liquidation cascade designed around a single invariant: the protocol never accrues bad debt. Every position that becomes insolvent is unwound through one of three mechanisms before the global liquidity pool is exposed.

This page is the high-level overview. The detailed layer-by-layer mechanics live in Three-Layer Cascade and Auto-Deleveraging.

The three layers

                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚   margin_ratio = equity / size       β”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                        β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚                             β”‚                             β”‚
  ratio > 20%                 20% β‰₯ ratio > 13.33%               ratio ≀ 13.33%
  [healthy]                   [LAYER 1: Partial]                        β”‚
                                                             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                                             β”‚                     β”‚
                                              insurance can absorb?           no insurance left
                                                             β”‚                     β”‚
                                                    [LAYER 2: Backstop]    [LAYER 3: ADL]
LayerTriggerActionLiquidator reward
1. Partialmargin ≀ 20%, > 13.33%Close 20% of the position at mark price; 30s cooldown5% of closed collateral
2. Backstopmargin ≀ 13.33%, insurance healthyInsurance fund absorbs the full position at mark; fund unwinds 10% per call3% per unwind chunk
3. ADLmargin ≀ 13.33%, insurance depletedForce-close opposing profitable positions, ranked by PnL Γ— leverage(none β€” protocol-driven)

Why three layers

A single-shot liquidation (the dominant crypto-perp model) is fragile:

  • Insufficient fill. If the book is thin, the liquidator can’t close the full position and the protocol eats the residual loss.
  • Liquidation cascades. One liquidation’s price impact triggers the next; socialized losses follow.
  • Bad-debt socialization. When things fail, everyone on the winning side gets haircut.

SportsPerp’s cascade avoids all three:

  • Layer 1 repairs gently. Closing 20% at a time lets a recovering market bring the position back above the maintenance threshold without a full wipeout. The 30-second cooldown prevents stacked partials on the same position.
  • Layer 2 socializes to a dedicated pool, not to other traders. The insurance fund exists to absorb these losses; it is funded by 50% of every Layer 1 liquidation’s proceeds, so the system is self-capitalizing in normal operation.
  • Layer 3 is the nuclear option. Only when insurance is depleted does ADL fire. By that point, the protocol’s losses are being absorbed by opposing profitable positions β€” the participants best able to afford it, because they’ve already captured the gain.

Anti-manipulation protection

A critical subtlety: profitable positions cannot be liquidated unless they have materially lost value vs their most recent margin transfer.

The check, enforced in partial_liquidate.rs:

liquidation allowed only if:
    pnl_vs_entry < 0                                   // position currently losing vs entry
    OR
    (last_margin_transfer_collateral - effective_collateral) / last_margin_transfer_collateral
        β‰₯ 18.3%                                        // lost β‰₯ 18.3% since last margin ops

In plain English: a trader who is ahead on the trade and has not topped up collateral cannot be liquidated. Only when they’re down on the trade or down β‰₯ 18.3% from their last margin baseline does the cascade become eligible to fire.

This protects against a specific attack: an adversary could grief a healthy position by briefly manipulating the oracle to trigger a margin-ratio check failure. The 18.3% floor makes that economically pointless β€” the attacker would need to sustain a major dislocation, not a one-block flash.

Margin baseline resets on every add_collateral and withdraw_collateral call (collateral.rs:30,96). So if a trader actively manages their position, their anti-manipulation baseline stays fresh.

Mark price is the liquidation reference

Liquidations execute against the EMA-smoothed composite mark price, not the raw oracle. This means:

  • A single oracle push cannot trigger mass liquidations on its own β€” the 150-second EMA dampens the impact.
  • A single vAMM squeeze cannot trigger liquidations either β€” the composite weighting pulls toward the oracle.
  • Liquidations are well-defined. Every participant and keeper observes the same on-chain mark_price_ema field and computes identical eligibility.

See Mark Price for the full composite calculation.

Permissionless execution

All three layers are permissionless: any Solana account can invoke partial_liquidate, backstop_liquidate, unwind_backstop, or auto_deleverage. This means:

  • Liquidator incentives align without centralized operators. A 5% reward on Layer 1 and 3% on Layer 2 is enough to fund at least one competitive keeper. In practice, multiple keepers compete for the reward.
  • No SPoF in liquidation. If SportsPerp’s liquidator bot (keeper/liquidator.mjs) goes down, third parties can still clear underwater positions.
  • The math is on-chain. A liquidator doesn’t need to trust any off-chain data feed; the program itself determines eligibility.

Zero-bad-debt guarantee

Across the three layers, the protocol maintains the following invariant:

No close of any single position can result in negative collateral settlement against the global liquidity pool.

Layer 1 enforces this by closing only 20% at a time β€” if the partial close would leave remaining collateral negative, the position is escalated to Layer 2. Layer 2 lets the insurance fund absorb the negative slice. Layer 3 engages when insurance can’t cover β€” at which point opposing profitable positions absorb the loss via ADL.

There is no configuration under which the pool can hold a negative balance. The 50%-of-effective_oi single-position cap (tier 5), the 20% maintenance margin, the 18.3% anti-manipulation floor, and the 50K max backstop exposure collectively ensure that the liquidation math always closes. The full pool-solvency invariant pool_token.amount β‰₯ Ξ£ obligations is monitored continuously off-chain by scripts/probe-solvency.ts.

Further reading