Margin Modes
Drift Protocol supports two margin modes:
export class MarginMode {
static readonly DEFAULT = { default: {} }; // Cross-margin
static readonly HIGH_LEVERAGE = { highLeverage: {} }; // High leverage cross-margin
static readonly HIGH_LEVERAGE_MAINTENANCE = { highLeverageMaintenance: {} };
}
Cross-Margin (Default)
Cross-margin mode pools all collateral across positions:
All deposits act as collateral for all positions
Unrealized PnL contributes to margin (with haircuts)
Most capital efficient for diversified portfolios
Default mode for all users
Isolated Margin
Isolated margin uses dedicated collateral per position:
Only available for ISOLATED tier markets
Separate collateral pool per isolated position
No cross-contamination of risk
Introduced in v2.154.0
Isolated positions cannot share margin with cross-margin positions. Each isolated position is liquidated independently.
Margin Calculation
Margin health is determined by comparing total collateral to margin requirements.
Total Collateral
Total collateral is the sum of:
Spot Deposits (weighted by asset weight)
Unrealized Perp PnL (positive, with haircuts)
Unsettled Perp PnL (positive, settled but not withdrawn)
Formula:
t o t a l C o l l a t e r a l = ∑ d e p o s i t s ( t o k e n A m o u n t × p r i c e × a s s e t W e i g h t ) + ∑ p e r p P n L > 0 ( p n l × p n l A s s e t W e i g h t ) totalCollateral = \sum_{deposits} (tokenAmount \times price \times assetWeight) + \sum_{perpPnL > 0} (pnl \times pnlAssetWeight) t o t a lC o ll a t er a l = d e p os i t s ∑ ( t o k e n A m o u n t × p r i ce × a sse t W e i g h t ) + p er pP n L > 0 ∑ ( p n l × p n l A sse t W e i g h t )
Margin Requirement
Margin requirement is the sum of:
Perp Position Margin (based on position size and market tier)
Spot Borrows (weighted by liability weight)
Open Order Margins (reserved margin for open orders)
Unrealized Perp PnL (negative, with liability weights)
Formula:
m a r g i n R e q u i r e m e n t = ∑ p e r p P o s i t i o n s ( s i z e × p r i c e × m a r g i n R a t i o ) + ∑ b o r r o w s ( t o k e n A m o u n t × p r i c e × l i a b i l i t y W e i g h t ) marginRequirement = \sum_{perpPositions} (size \times price \times marginRatio) + \sum_{borrows} (tokenAmount \times price \times liabilityWeight) ma r g in R e q u i re m e n t = p er pP os i t i o n s ∑ ( s i ze × p r i ce × ma r g in R a t i o ) + b orro w s ∑ ( t o k e n A m o u n t × p r i ce × l iabi l i t y W e i g h t )
Margin Ratio Types
Initial Margin : Required to open new positions
type MarginRequirementType = 'Initial' | 'Maintenance' ;
Initial : Higher requirement, used when opening/increasing positions
Maintenance : Lower requirement, determines liquidation threshold
Health Check
if ( totalCollateral < marginRequirement ) {
// User can be liquidated (maintenance)
// or cannot open new positions (initial)
}
Size-Based Margin Scaling
Both perp and spot positions have size-based margin scaling using the IMF (Initial Margin Fraction) factor:
Perp Position Margin
export function calculateSizePremiumLiabilityWeight (
size : BN ,
imfFactor : BN ,
liabilityWeight : BN ,
precision : BN ,
isBounded = true
) : BN
Formula:
m a r g i n R a t i o = b a s e M a r g i n R a t i o + i m f F a c t o r × s i z e × 10 marginRatio = baseMarginRatio + imfFactor \times \sqrt{size \times 10} ma r g in R a t i o = ba se M a r g in R a t i o + im f F a c t or × s i ze × 10
Larger positions require proportionally more margin.
Spot Liability Weight
Borrows also scale with size:
l i a b i l i t y W e i g h t e f f e c t i v e = l i a b i l i t y W e i g h t + i m f F a c t o r × b o r r o w S i z e × 10 liabilityWeight_{effective} = liabilityWeight + imfFactor \times \sqrt{borrowSize \times 10} l iabi l i t y W e i g h t e ff ec t i v e = l iabi l i t y W e i g h t + im f F a c t or × b orro wS i ze × 10
Spot Asset Weight Discount
Large deposits receive a discounted asset weight:
export function calculateSizeDiscountAssetWeight (
size : BN ,
imfFactor : BN ,
assetWeight : BN
) : BN
a s s e t W e i g h t e f f e c t i v e = 1.1 × a s s e t W e i g h t 1 + i m f F a c t o r × s i z e × 10 assetWeight_{effective} = \frac{1.1 \times assetWeight}{1 + imfFactor \times \sqrt{size \times 10}} a sse t W e i g h t e ff ec t i v e = 1 + im f F a c t or × s i ze × 10 1.1 × a sse t W e i g h t
This prevents excessive concentration in a single asset.
Perp Margin Components
Base Margin Requirements
Each perp market defines base margin ratios:
// From PerpMarketAccount
marginRatioInitial : number ; // e.g., 500 = 5% = 20x max leverage
marginRatioMaintenance : number ; // e.g., 250 = 2.5% = 40x maintenance
imfFactor : number ; // Size scaling factor
Oracle Price for Margin
Perp positions are valued with a conservative oracle price:
export function calculateOraclePriceForPerpMargin (
perpPosition : PerpPosition ,
market : PerpMarketAccount ,
oraclePriceData : OraclePriceData
) : BN
For Long Positions:
m a r g i n P r i c e = o r a c l e P r i c e − p r i c e O f f s e t marginPrice = oraclePrice - priceOffset ma r g in P r i ce = or a c l e P r i ce − p r i ce O ff se t
For Short Positions:
m a r g i n P r i c e = o r a c l e P r i c e + p r i c e O f f s e t marginPrice = oraclePrice + priceOffset ma r g in P r i ce = or a c l e P r i ce + p r i ce O ff se t
Where:
p r i c e O f f s e t = min ( m a x S p r e a d × o r a c l e P r i c e , c o n f i d e n c e + b a s e S p r e a d × o r a c l e P r i c e ) priceOffset = \min(maxSpread \times oraclePrice, confidence + baseSpread \times oraclePrice) p r i ce O ff se t = min ( ma x Sp re a d × or a c l e P r i ce , co n f i d e n ce + ba se Sp re a d × or a c l e P r i ce )
This provides a buffer against adverse price movements.
Worst-Case Position Size
Open orders are considered in margin calculations:
export function calculateWorstCaseBaseAssetAmount (
perpPosition : PerpPosition ,
perpMarket : PerpMarketAccount ,
oraclePrice : BN
) : BN
Considers:
Current position
All open bids (could increase position)
All open asks (could decrease position)
Returns the scenario with maximum liability value.
Unrealized PnL Weights
Unrealized perp PnL contributes to margin with haircuts:
Positive PnL (Asset):
// From PerpMarketAccount
unrealizedPnlInitialAssetWeight : number ; // e.g., 8000 = 80%
unrealizedPnlMaintenanceAssetWeight : number ; // e.g., 9000 = 90%
Negative PnL (Liability):
Counted at full value (100% liability weight) or with IMF scaling:
l i a b i l i t y W e i g h t = 1.0 + u n r e a l i z e d P n l I m f F a c t o r × ∣ p n l ∣ × 10 liabilityWeight = 1.0 + unrealizedPnlImfFactor \times \sqrt{|pnl| \times 10} l iabi l i t y W e i g h t = 1.0 + u n re a l i ze d P n l I m f F a c t or × ∣ p n l ∣ × 10
This prevents users from over-leveraging based on unrealized gains.
PnL Pool Limits
Positive unrealized PnL is capped by available PnL pool:
const maxPnlAsset = min (
unrealizedPnl ,
pnlPool . balance + settleablePnl
);
This ensures PnL can actually be settled.
Spot Margin Components
Asset Weights
Each spot market has asset weights for deposits:
// From SpotMarketAccount
initialAssetWeight : number ; // e.g., 8000 = 80%
maintenanceAssetWeight : number ; // e.g., 9000 = 90%
Example: 100 o f S O L w i t h 80 100 of SOL with 80% initial weight = 100 o f SO L w i t h 80 80 of buying power.
Liability Weights
Borrows have liability weights:
// From SpotMarketAccount
initialLiabilityWeight : number ; // e.g., 12000 = 120%
maintenanceLiabilityWeight : number ; // e.g., 11000 = 110%
Example: 100 b o r r o w e d r e q u i r e s 100 borrowed requires 100 b orro w e d re q u i res 120 of initial margin.
Strict Oracle Prices
Spot margin uses strict oracle prices with confidence intervals:
// For assets (deposits)
strictPrice = oraclePrice - confidence
// For liabilities (borrows)
strictPrice = oraclePrice + confidence
This provides additional safety margins.
Isolated Position Margin
Isolated positions have separate margin calculations:
// From PerpPosition
isolatedPositionScaledBalance : BN ; // Dedicated collateral (scaled)
positionFlag : number ; // Has IsolatedPosition flag
Isolated Margin Calculation
isolatedCollateral = getTokenAmount (
isolatedPositionScaledBalance ,
quoteSpotMarket
);
isolatedMarginRequirement =
positionSize * oraclePrice * marginRatio ;
if ( isolatedCollateral < isolatedMarginRequirement ) {
// Isolated position can be liquidated
}
Isolated positions:
Use only their dedicated collateral
Don’t affect cross-margin positions
Are liquidated independently
Cannot cross-collateralize
Isolated positions are ideal for high-risk trades where you want to limit downside to the allocated collateral.
Open Order Margin
Open orders reserve margin:
openOrderMargin =
openBids * price * marginRatio +
openAsks * price * marginRatio ;
This ensures margin is available if orders fill.
Open Order Treatment
Reduce-only orders : Don’t require additional margin
Risk-increasing orders : Require margin for worst-case scenario
Trigger orders : Require margin as if already filled
High Leverage Mode
Users can enable high leverage mode for lower margin requirements:
export type HighLeverageModeConfig = {
maxUsers : number ; // Cap on users in HLM
currentUsers : number ; // Current users in HLM
reduceOnly : boolean ; // Whether HLM is reduce-only
};
In high leverage mode:
Lower initial and maintenance margin ratios
Limited to specific markets
May have user caps
Higher risk of liquidation
High leverage mode is risky and can lead to rapid liquidation in volatile markets. Use with caution.
Margin Trading Toggle
Users can disable margin trading:
// From User account
isMarginTradingEnabled : boolean ;
When disabled:
Cannot open leveraged positions
Cannot borrow from spot markets
Can only trade with existing deposits
Useful for preventing accidental leverage
Custom Margin Ratios
Users can set custom max margin ratios:
// From User account
maxMarginRatio : number ; // Custom cap on leverage
// From PerpPosition
maxMarginRatio : number ; // Per-position override
Allows users to voluntarily limit leverage below market maximums.
Margin Calculation Example
Let’s calculate margin for a user with:
1000 USDC deposited (initial asset weight: 100%)
Long 10 SOL-PERP at $100 (initial margin: 10%, maintenance: 5%)
500 USDC borrowed (initial liability weight: 105%)
Total Collateral (Initial):
c o l l a t e r a l = 1000 × 1.0 = $ 1000 collateral = 1000 \times 1.0 = \$1000 co ll a t er a l = 1000 × 1.0 = $1000
Margin Requirement (Initial):
p e r p = 10 × 100 × 0.10 = $ 100 perp = 10 \times 100 \times 0.10 = \$100 p er p = 10 × 100 × 0.10 = $100
b o r r o w = 500 × 1.05 = $ 525 borrow = 500 \times 1.05 = \$525 b orro w = 500 × 1.05 = $525
t o t a l = 100 + 525 = $ 625 total = 100 + 525 = \$625 t o t a l = 100 + 525 = $625
Free Collateral:
f r e e = 1000 − 625 = $ 375 free = 1000 - 625 = \$375 f ree = 1000 − 625 = $375
The user can open additional positions worth ~$375 in margin requirement.
Liquidation Threshold (Maintenance):
m a i n t = ( 10 × 100 × 0.05 ) + ( 500 × 1.025 ) = 50 + 512.5 = $ 562.5 maint = (10 \times 100 \times 0.05) + (500 \times 1.025) = 50 + 512.5 = \$562.5 main t = ( 10 × 100 × 0.05 ) + ( 500 × 1.025 ) = 50 + 512.5 = $562.5
If total collateral falls below $562.5, the user can be liquidated.
Next Steps
Liquidations Understand the liquidation process
Positions Learn about position management
Markets Review margin requirements per market
SDK Guide Calculate margin in your application