Skip to main content
The liquidation module provides functions for calculating liquidation prices, unrealized PnL, margin requirements, and collateral information.

Types

LiquidationAndPnlInfo

Combined liquidation price and unrealized PnL information.
pub struct LiquidationAndPnlInfo {
    pub liquidation_price: i64,  // PRICE_PRECISION
    pub unrealized_pnl: i128,    // QUOTE_PRECISION
    pub oracle_price: i64,       // PRICE_PRECISION
}

MarginRequirementInfo

Margin requirement information for a user.
pub struct MarginRequirementInfo {
    pub initial: u128,      // QUOTE_PRECISION
    pub maintenance: u128,  // QUOTE_PRECISION
}

CollateralInfo

Collateral information for a user.
pub struct CollateralInfo {
    pub total: i128,  // QUOTE_PRECISION
    pub free: i128,   // QUOTE_PRECISION
}

Liquidation Price Functions

calculate_liquidation_price_and_unrealized_pnl

Calculate both liquidation price and unrealized PnL for a perp position.
pub async fn calculate_liquidation_price_and_unrealized_pnl(
    client: &DriftClient,
    user: &User,
    market_index: u16,
) -> SdkResult<LiquidationAndPnlInfo>
Parameters:
  • client - Reference to the DriftClient
  • user - The user account
  • market_index - The perp market index
Returns: Combined liquidation and PnL information Example:
let info = calculate_liquidation_price_and_unrealized_pnl(
    &drift_client,
    &user_account,
    0, // SOL-PERP
).await?;

println!("Liquidation price: ${}", info.liquidation_price as f64 / 1_000_000.0);
println!("Unrealized PnL: ${}", info.unrealized_pnl as f64 / 1_000_000.0);

calculate_liquidation_price

Calculate the liquidation price for a perp position.
pub async fn calculate_liquidation_price(
    client: &DriftClient,
    user: &User,
    market_index: u16,
) -> SdkResult<i64>
Parameters:
  • client - Reference to the DriftClient
  • user - The user account
  • market_index - The perp market index
Returns: Liquidation price in PRICE_PRECISION (1e6)
  • Returns -1 if position cannot be liquidated
Notes:
  • Takes into account all user positions across markets
  • Considers matching spot positions (e.g., SOL-PERP + SOL spot)
  • Price at which free collateral becomes zero

calculate_liquidation_price_inner

Internal function to calculate liquidation price with full control.
pub fn calculate_liquidation_price_inner(
    user: &User,
    perp_market: &PerpMarket,
    spot_market: Option<&SpotMarket>,
    oracle_price: i64,
    accounts: &mut AccountsList,
) -> SdkResult<i64>
Parameters:
  • user - The user account
  • perp_market - The perp market configuration
  • spot_market - Optional matching spot market (for hedging)
  • oracle_price - Current oracle price
  • accounts - All necessary account data
Returns: Liquidation price or -1 if not applicable

Unrealized PnL Functions

calculate_unrealized_pnl

Calculate unrealized PnL for a perp position.
pub async fn calculate_unrealized_pnl(
    client: &DriftClient,
    user: &User,
    market_index: u16,
) -> SdkResult<i128>
Parameters:
  • client - Reference to the DriftClient
  • user - The user account
  • market_index - The perp market index
Returns: Unrealized PnL in QUOTE_PRECISION
  • Positive values indicate profit
  • Negative values indicate loss

calculate_unrealized_pnl_inner

Calculate unrealized PnL given position and oracle price.
pub fn calculate_unrealized_pnl_inner(
    position: &PerpPosition,
    oracle_price: i64,
) -> SdkResult<i128>
Formula:
unrealized_pnl = (base_asset_amount * oracle_price) / AMM_RESERVE_PRECISION
               + quote_entry_amount

Margin Requirement Functions

calculate_margin_requirements

Calculate both initial and maintenance margin requirements.
pub fn calculate_margin_requirements(
    client: &DriftClient,
    user: &User,
) -> SdkResult<MarginRequirementInfo>
Parameters:
  • client - Reference to the DriftClient
  • user - The user account
Returns: Initial and maintenance margin requirements Example:
let margin_req = calculate_margin_requirements(&drift_client, &user_account)?;

println!("Initial margin: ${}", margin_req.initial as f64 / 1_000_000.0);
println!("Maintenance margin: ${}", margin_req.maintenance as f64 / 1_000_000.0);

Collateral Functions

calculate_collateral

Calculate total and free collateral for a user.
pub fn calculate_collateral(
    client: &DriftClient,
    user: &User,
    margin_requirement_type: MarginRequirementType,
) -> SdkResult<CollateralInfo>
Parameters:
  • client - Reference to the DriftClient
  • user - The user account
  • margin_requirement_type - Initial or Maintenance
Returns: Total and free collateral information Example:
use drift_rs::MarginRequirementType;

let collateral = calculate_collateral(
    &drift_client,
    &user_account,
    MarginRequirementType::Maintenance,
)?;

println!("Total collateral: ${}", collateral.total as f64 / 1_000_000.0);
println!("Free collateral: ${}", collateral.free as f64 / 1_000_000.0);

Helper Functions

calculate_perp_free_collateral_delta

Calculate how perp position free collateral changes with price.
pub fn calculate_perp_free_collateral_delta(
    position: &PerpPosition,
    market: &PerpMarket,
    oracle_price: i64,
    margin_mode: MarginMode,
) -> i64
Returns: Rate of change of free collateral per unit price change

calculate_spot_free_collateral_delta

Calculate how spot position free collateral changes with price.
pub fn calculate_spot_free_collateral_delta(
    position: &SpotPosition,
    market: &SpotMarket
) -> i64

calculate_max_pct_to_liquidate

Calculate the maximum percentage of a position that can be liquidated.
pub fn calculate_max_pct_to_liquidate(
    user: &User,
    margin_shortage: u128,
    slot: u64,
    initial_pct_to_liquidate: u128,
    liquidation_duration: u128,
) -> SdkResult<u128>
Parameters:
  • user - The user account
  • margin_shortage - Current margin shortage amount
  • slot - Current blockchain slot
  • initial_pct_to_liquidate - Initial liquidation percentage allowed
  • liquidation_duration - Number of slots over which to scale up liquidation
Returns: Maximum percentage that can be liquidated (LIQUIDATION_PCT_PRECISION) Notes:
  • Percentage increases linearly over time since user’s last activity
  • Allows for graceful liquidations that scale with severity
  • Small margin shortages (< $50) are liquidated immediately

Build docs developers (and LLMs) love