Liquidation Overview
Liquidations occur when a user’s margin requirement exceeds their total collateral. The protocol relies on permissionless liquidators (keepers) to identify and liquidate underwater positions.
Liquidation Trigger
A user can be liquidated when:
totalCollateral < maintenanceMarginRequirement
Where:
totalCollateral = value of all deposits and positive PnL (with haircuts)
maintenanceMarginRequirement = required margin to maintain positions
User Status During Liquidation
export enum UserStatus {
BeingLiquidated = 1 ,
Bankrupt = 2 ,
ReduceOnly = 4 ,
AdvancedLp = 8 ,
ProtectedMaker = 16 ,
}
When liquidation starts, user is marked with BeingLiquidated status.
Liquidation Types
Drift supports multiple liquidation types depending on the user’s state:
export class LiquidationType {
static readonly LIQUIDATE_PERP = { liquidatePerp: {} };
static readonly LIQUIDATE_SPOT = { liquidateSpot: {} };
static readonly LIQUIDATE_BORROW_FOR_PERP_PNL = { liquidateBorrowForPerpPnl: {} };
static readonly LIQUIDATE_PERP_PNL_FOR_DEPOSIT = { liquidatePerpPnlForDeposit: {} };
static readonly PERP_BANKRUPTCY = { perpBankruptcy: {} };
static readonly SPOT_BANKRUPTCY = { spotBankruptcy: {} };
}
Liquidate Perp
Reduces perp positions to improve margin health:
export type LiquidatePerpRecord = {
marketIndex : number ;
oraclePrice : BN ;
baseAssetAmount : BN ; // Amount liquidated
quoteAssetAmount : BN ; // Quote from liquidation
lpShares : BN ; // LP shares liquidated
userOrderId : BN ;
liquidatorOrderId : BN ;
fillRecordId : BN ;
liquidatorFee : BN ; // Fee to liquidator
ifFee : BN ; // Fee to insurance fund
};
Process:
Calculate margin shortage
Determine max position size to liquidate
Transfer position to liquidator at oracle price
Apply liquidation fees
Update user margin
Liquidate Spot
Reduces spot borrows or converts deposits:
export type LiquidateSpotRecord = {
assetMarketIndex : number ;
assetPrice : BN ;
assetTransfer : BN ; // Asset given to liquidator
liabilityMarketIndex : number ;
liabilityPrice : BN ;
liabilityTransfer : BN ; // Liability taken from user
ifFee : BN ; // Fee to insurance fund
};
Process:
Liquidator selects asset and liability markets
Calculate transfer amounts with liquidation multiplier
Transfer liability from user to liquidator
Transfer asset from user to liquidator
Apply insurance fund fee
Liquidate Borrow for Perp PnL
Uses positive perp PnL to repay spot borrows:
export type LiquidateBorrowForPerpPnlRecord = {
perpMarketIndex : number ;
marketOraclePrice : BN ;
pnlTransfer : BN ; // PnL used to repay
liabilityMarketIndex : number ;
liabilityPrice : BN ;
liabilityTransfer : BN ; // Borrow amount repaid
};
This settles unrealized perp profits to reduce spot liability.
Liquidate Perp PnL for Deposit
Takes user’s deposits to cover negative perp PnL:
export type LiquidatePerpPnlForDepositRecord = {
perpMarketIndex : number ;
marketOraclePrice : BN ;
pnlTransfer : BN ; // Negative PnL covered
assetMarketIndex : number ;
assetPrice : BN ;
assetTransfer : BN ; // Deposit used to cover
};
This uses deposits to cover unrealized perp losses.
Liquidation Fees
Liquidators receive fees as incentive:
Perp Liquidation Fees
// From PerpMarketAccount
liquidatorFee : number ; // e.g., 500 = 0.5%
ifLiquidationFee : number ; // e.g., 100 = 0.1%
Total fee = liquidatorFee + ifLiquidationFee
Example: Liquidating 1000 p o s i t i o n w i t h 0.5 1000 position with 0.5% + 0.1% = 1000 p os i t i o n w i t h 0.5 6 total fee
Liquidator receives: $5
Insurance fund receives: $1
Spot Liquidation Multipliers
Spot liquidations use liability/asset multipliers:
liabilityLiquidationMultiplier = 1.0 ; // Liquidator takes full liability
assetLiquidationMultiplier = 0.95 ; // Liquidator pays 95% of asset value
The 5% difference is split between liquidator profit and IF fee.
Liquidation Amount Limits
Liquidations happen progressively, not all at once:
Max Percentage to Liquidate
sdk/src/math/liquidation.ts
export function calculateMaxPctToLiquidate (
userLastActiveSlot : BN ,
userLiquidationMarginFreed : BN ,
marginShortage : BN ,
slot : BN ,
initialPctToLiquidate : BN ,
liquidationDuration : BN
) : BN
Formula:
m a x P c t = min ( s l o t s E l a p s e d l i q u i d a t i o n D u r a t i o n + i n i t i a l P c t , 100 % ) maxPct = \min\left(\frac{slotsElapsed}{liquidationDuration} + initialPct, 100\%\right) ma x P c t = min ( l i q u i d a t i o n D u r a t i o n s l o t s El a p se d + ini t ia lP c t , 100% )
This ramps up from initialPctToLiquidate (e.g., 10%) to 100% over liquidationDuration slots (e.g., 150 slots = ~1 minute).
Progressive liquidation gives users time to add margin and prevents excessive position closure during brief volatility.
Base Asset Amount to Cover Shortage
sdk/src/math/liquidation.ts
export function calculateBaseAssetAmountToCoverMarginShortage (
marginShortage : BN ,
marginRatio : number ,
liquidationFee : number ,
ifLiquidationFee : number ,
oraclePrice : BN ,
quoteOraclePrice : BN
) : BN | undefined
Calculates the minimum position size to liquidate to cover the margin shortage:
b a s e A m o u n t = m a r g i n S h o r t a g e o r a c l e P r i c e × ( m a r g i n R a t i o − l i q u i d a t i o n F e e − i f F e e ) baseAmount = \frac{marginShortage}{oraclePrice \times (marginRatio - liquidationFee - ifFee)} ba se A m o u n t = or a c l e P r i ce × ( ma r g in R a t i o − l i q u i d a t i o n F ee − i f F ee ) ma r g in S h or t a g e
If this exceeds the position size, returns undefined (liquidate all).
Bankruptcy
When a user’s collateral is insufficient even after full liquidation, bankruptcy procedures activate.
Perp Bankruptcy
export type PerpBankruptcyRecord = {
marketIndex : number ;
pnl : BN ; // Outstanding negative PnL
ifPayment : BN ; // Insurance fund covers
clawbackUser : PublicKey | null ;
clawbackUserPayment : BN | null ;
cumulativeFundingRateDelta : BN ; // Socialized loss
};
Process:
Calculate remaining negative PnL
Insurance fund covers what it can
Remaining loss is socialized via funding rate adjustment
If applicable, clawback from recent profitable traders
Spot Bankruptcy
export type SpotBankruptcyRecord = {
marketIndex : number ;
borrowAmount : BN ; // Outstanding borrow
cumulativeDepositInterestDelta : BN ; // Socialized loss
ifPayment : BN ; // Insurance fund covers
};
Process:
Calculate remaining borrow after liquidating all deposits
Insurance fund covers what it can
Remaining loss is socialized to depositors via cumulative deposit interest adjustment
Socialized losses are rare but can occur during extreme market conditions. They are distributed proportionally to all depositors in the affected spot market.
Liquidation Record
Each liquidation emits a comprehensive record:
export type LiquidationRecord = {
ts : BN ;
user : PublicKey ;
liquidator : PublicKey ;
liquidationType : LiquidationType ;
marginRequirement : BN ;
totalCollateral : BN ;
marginFreed : BN ;
liquidationId : number ;
bankrupt : boolean ;
canceledOrderIds : BN [];
liquidatePerp : LiquidatePerpRecord ;
liquidateSpot : LiquidateSpotRecord ;
liquidateBorrowForPerpPnl : LiquidateBorrowForPerpPnlRecord ;
liquidatePerpPnlForDeposit : LiquidatePerpPnlForDepositRecord ;
perpBankruptcy : PerpBankruptcyRecord ;
spotBankruptcy : SpotBankruptcyRecord ;
};
Liquidation Margin Freed
Tracks how much margin has been freed through liquidations:
// From User account
liquidationMarginFreed : BN ; // Cumulative margin freed
lastActiveSlot : BN ; // Last user activity
This determines the liquidation speed ramp:
If liquidationMarginFreed > 0, liquidation is in progress
Slots since lastActiveSlot determine current max liquidation percentage
Resets to 0 when user is healthy again
Order Cancellation During Liquidation
When liquidation begins:
All risk-increasing orders are cancelled
Reduce-only orders may remain
Order IDs are recorded in canceledOrderIds
Users cannot place new risk-increasing orders
Isolated Position Liquidation
Isolated positions are liquidated independently:
isolatedCollateral = getTokenAmount (
position . isolatedPositionScaledBalance ,
quoteSpotMarket
);
isolatedMarginReq =
positionSize * price * marginRatio ;
if ( isolatedCollateral < isolatedMarginReq ) {
// Liquidate isolated position only
// Other positions unaffected
}
Isolated Liquidation Process:
Check isolated position margin independently
Liquidate only the isolated position if underwater
Use only isolated collateral
Cross-margin positions remain unaffected
If isolated collateral insufficient, bankruptcy on isolated position only
Isolated positions protect your main account from high-risk trades. Only the isolated collateral is at risk.
Liquidation Bit Flags
export class LiquidationBitFlag {
static readonly IsolatedPosition = 1 ;
}
Flags indicate special liquidation circumstances like isolated positions.
Insurance Fund
The insurance fund backs the protocol against insolvency:
Receives portion of liquidation fees
Covers bankruptcy losses before socialization
Per-market insurance funds for spot markets
Shared perp insurance fund
Insurance Fund Structure
// From SpotMarketAccount.insuranceFund
insuranceFund : {
vault : PublicKey ;
totalShares : BN ;
userShares : BN ;
sharesBase : BN ;
unstakingPeriod : BN ;
lastRevenueSettleTs : BN ;
revenueSettlePeriod : BN ;
totalFactor : number ;
userFactor : number ;
}
Users can stake to the insurance fund and earn a portion of protocol revenue.
Liquidator Incentives
Liquidators are incentivized through:
Liquidation fees : Direct fee on liquidated amount
Price improvement : Acquire positions below market price
Insurance fund fees : Additional fee to IF
Example:
User has 10 SOL short at 100 , u n d e r w a t e r b y 100, underwater by 100 , u n d er w a t er b y 50
Liquidator takes over the short position
Liquidator pays: 10 * 100 ∗ ( 1 − 0.5 100 * (1 - 0.5% liquidatorFee - 0.1% ifFee) = 100 ∗ ( 1 − 0.5 994
User receives: 994 f o r 994 for 994 f or 1000 position
Liquidator profit: $6 (plus any favorable position movement)
IF receives: $1
Preventing Liquidation
Users can avoid liquidation by:
Adding collateral : Deposit more funds
Reducing positions : Close or reduce losing positions
Settling PnL : Settle positive unrealized PnL
Repaying borrows : Reduce spot liabilities
Cancelling orders : Free up margin from open orders
Monitor your margin ratio regularly. Set up alerts when approaching maintenance margin threshold.
Next Steps
Margin System Understand margin requirements in detail
Positions Learn about position management
Markets Review market-specific liquidation parameters
Keeper Bots Build a liquidator bot