Skip to main content

What counts as collateral

USDC
V1: USDC only. A single 6-decimal SPL token.
Multi-collateral margining is on the V2 roadmap. The engine already supports per-market collateral mints, we just haven’t shipped non-USDC markets yet.

Where your collateral lives

Deposited USDC goes to market.collateral_vault, a token account owned by the market PDA. It is never rehypothecated; the vault only transfers out on:
  • withdraw_collateral (authority only)
  • place_order matching (transfers fees to fee_vault)
  • liquidate (transfers fee split + bad-debt cover)
Your balance on the market is tracked in UserAccount.collateral. The on-chain token balance in the vault equals the sum of all user collateral plus any outstanding fees not yet swept.

Deposits

getDepositCollateralInstruction({
  signer: wallet,             // or delegate
  userAccount,                 // PDA ["user", authority]
  market,
  userTokenAccount,
  collateralVault: market.collateralVault,
  amount: 1_000_000_000n,      // 1,000 USDC (6-decimal)
});
Any signer listed on user_account.delegate can deposit, useful for keeper bots that top up accounts automatically.

Withdrawals

getWithdrawCollateralInstruction({
  authority: wallet,           // authority ONLY, delegates cannot withdraw
  userAccount,
  market,
  collateralVault,
  amount: ...,
});
Post-withdraw, the instruction re-runs the initial margin check, not maintenance. This is stricter than the liquidation threshold and prevents deposit → open max position → withdraw games.

Reserved margin

Resting orders lock margin at placement, not fill. Your accessible collateral is:
free_collateral = collateral − total_reserved_margin
Position health uses free_collateral + unrealized_pnl, not raw collateral. This is deliberate, without it, spamming a hundred limit orders could all simultaneously satisfy their individual margin checks but share the same USDC.

Precision

FieldDecimalsExample
collateral (USDC)61,000.000000 USDC = 1_000_000_000
base_amount (SOL)91.5 SOL = 1_500_000_000
price6$130.00 = 130_000_000
Margin ratiosBPS10% = 1000; denominator 10_000
All conversions are handled in perps-math::safe_math.

Delegate trading

You can set a delegate via set_delegate(delegate: Pubkey):
  • Delegate can: deposit_collateral, place_order, cancel_order, cancel_all_orders.
  • Delegate cannot: withdraw_collateral, set_delegate, liquidate (except against others, liquidation doesn’t require delegation), delete the user account.
This is how the delta-vault manages its perp position: the vault PDA is the delegate for its own UserAccount inside kimia-perp.