Skip to Content

Liquidation engine

Why Liquidation Design Matters

Every liquidation engine has to make a tradeoff: liquidate quickly enough to protect solvency, while keeping guardrails against oracle misprints, or extremely short lived price spikes.

In a volatile market, bad oracle data or sudden price wicks can create sudden crises. A DEX that instantly liquidates based on a single bad price tick can wipe out healthy traders. Furthermore, liquidating at extreme temporary price can create bad debt, which can be dangerous for the protocol itself.

By design, Velocity’s liquidation engine revolves around 3 key areas:

  • Partial liquidation

    To limit risk and reduce the severity of liquidation events, Velocity uses partial liquidation for cross-margin positions. Instead of closing an entire position at once, the system liquidates portions over time, throttled across multiple slots. This gives the account a chance to recover as new oracle prices arrive, while ensuring the system remains solvent.

    The buffer system ensures that users aren’t liquidated right back at maintenance margin. Instead, Velocity places liquidated accounts slightly behind a safe margin buffer, far enough to reduce immediate risk but close enough to stay competitive for traders using leverage.

This gradual, throttled unwind applies to cross-margin positions only.

  • Speed

    Velocity’s liquidation engine liquidates progressively, adjusting speed based on how “unhealthy” the user’s account is and how the price evolves after the liquidation starts.

    When a liquidation begins, Velocity records how much margin has already been freed. From that point:

    • If the price keeps moving against the user, the system accelerates liquidation.
    • If the price moves in favor of the user, liquidation slows down, since the position is recovering naturally.

    This happens over a wall-clock window that is admin-configurable (State.liquidation_duration, stored in legacy 400ms units and converted to slots at the live slot duration), so the ramp stays constant in seconds even as Solana’s slot time changes.

    From empirical data, even a few slots of delay can prevent unnecessary liquidations during a temporary wick. The goal isn’t to pause liquidation, but to make it responsive, reacting quickly when needed and backing off when conditions improve.

  • Price

    Liquidations on Velocity aren’t triggered directly by the mark price, instead, the engine references the oracle price for liquidation thresholds. The engine compares the current oracle price with the five-minute average oracle price(TWAP) to detect outliers.

    If the oracle price deviates 50% or more from the 5min TWAP, liquidations are temporarily blocked. This gives time for additional oracle updates to confirm whether the move is real. Once the deviation narrows, normal liquidation resumes, following the same pacing described above.

Insurance Fund as a safety net

Even with all these protections, extreme events can still create negative balances. Velocity pays down a bankruptcy in order, tranche by tranche, before any loss is socialized. For a spot bankruptcy, the market’s own revenue pool is drawn first, then the shared Insurance Fund vault. For a perp bankruptcy, the market’s own pending insurance fee is drawn first, then the Insurance Fund vault, then a clawback of the AMM’s fee provision, with any remainder handled by socialized loss. See Bankruptcy Resolution for the full tranche order, the standing first-loss floor, and the claim freeze, and Insurance Fund for the coverage rules and funding sources.

Liquidators

Liquidations act as position transfers between accounts. Liquidator accounts thus need to be collateralised in order to satisfy the transfer’s initial margin requirements.

The core instructions pertaining to liquidations are:

InstructionDetails
liquidate_perpLiquidator takes over user perpetual positions at a discount.
liquidate_perp_with_fillSame as liquidate_perp, but fills the taken-over position against a maker in the same instruction.
liquidate_spotLiquidator takes over borrow at a discount to the deposit value.
liquidate_spot_with_swap_begin / _endLiquidator takes over a borrow via an atomic swap (e.g. against Jupiter) rather than direct token transfer.
liquidate_borrow_for_perp_pnlLiquidator takes over borrow for discounted P&L.
liquidate_perp_pnl_for_depositLiquidator takes over negative P&L for discounted deposit.

Liquidators are open-sourced and can be triggered by anybody running a liquidator bot. Liquidators, also known as Keepers, will have their collateral reward credited to their Velocity account. Every liquidation fee is split three ways (liquidator_fee / if_liquidation_fee / protocol_liquidation_fee) to reward them. See Liquidations for the split logic.

Bankruptcy (see Insurance Fund) is possible if a liquidated user still has outstanding liabilities and no further assets. See Bankruptcy and Solvency Status.

If you would like to run a liquidator bot, see Tutorial: Liquidation Bot.

Last updated on