perps-math (perps engine)
and kimia-math (everything else). Both use 9-decimal fixed-point internally
and always round down.
Constants
| Constant | Value | Meaning |
|---|---|---|
PRICE_PRECISION | 1_000_000 | 6-decimal prices |
BASE_PRECISION | 1_000_000_000 | 9-decimal base (SOL lamports) |
QUOTE_PRECISION | 1_000_000 | 6-decimal quote (USDC) |
FUNDING_PRECISION | 1_000_000_000 | 9-decimal funding |
MARGIN_PRECISION | 10_000 | 100% |
BPS_PRECISION | 10_000 | 100% |
FUNDING_PERIOD_SECONDS | 3600 | 1h |
PERIODS_PER_DAY | 24 | |
FUNDING_RATE_OFFSET_DENOMINATOR | 5000 | 0.02%/period carry cost |
FUNDING_RATE_MAX_DENOMINATOR | 33 | ±3.03% clamp |
LIQUIDATION_FEE_BPS | 500 | 5% |
DEFAULT_TAKER_FEE_BPS | 10 | 0.1% |
DEFAULT_MAKER_FEE_BPS | 5 | 0.05% |
ORACLE_STALENESS_THRESHOLD | 60 | seconds |
ORACLE_CONFIDENCE_MAX_BPS | 250 | 2.5% |
perps-math
funding
calculate_funding_rate(mark_twap, oracle_twap, oracle_price) → i128calculate_funding_payment(base, funding_delta) → i64update_twap(twap, price, elapsed, period) → u64
margin
calculate_margin_requirement(base, price, margin_ratio) → u64calculate_health(collateral, pnl, maint_req) → i64has_sufficient_initial_margin(...)max_position_size(collateral, price, initial_margin_ratio) → u64calculate_liquidation_price(base, entry, collateral, maint_margin_ratio) → u64
pnl
calculate_unrealized_pnl(base, mark, quote_entry) → i64settle_close(base, quote_entry, close_amount, close_price) → (realized_pnl, new_base, new_quote)
safe_math
All returningOption<T>, no panics:
mul_div_down / mul_div_upapply_bps_down / apply_bps_upbase_to_quote(base, price)normalize_pyth_price(pyth_price, pyth_expo, target_expo)
kimia-math
Fixed-point
mul_fp(a, b) = a · b / ONE, u128 intermediatediv_fp(a, b) = a · ONE / bONE = 1_000_000_000signed_delta(new, old), for yield deltas (negative means no yield)
exp / ln (exp_ln.rs)
ln_fp(x), range-reduced to[0.5, 2.0)via Taylor onz = (x-1)/(x+1)exp_fp(x), range-reduced via powers of 2pow_frac(base, exponent),exp(exponent · ln(base))forexponent ∈ [0, ONE]
insurance
process_positive_funding(funding, skim_bps) → (insurance_skim, vault_yield)process_negative_funding(fund_balance, loss) → (new_balance, uncovered_loss)

