Skip to main content
Kimia’s perpetual futures engine (kimia-perp) is an on-chain orderbook-based derivatives exchange. It supports long and short positions on SOL-PERP (V1) with USDC as the single collateral type.

What makes it distinct

  • On-chain FIFO orderbook, up to 32 bids and 32 asks per market, matched in price-then-time priority. Up to 4 fills per transaction to stay inside compute limits.
  • Single-position-per-market (V1), one user account holds one directional position per market; switching direction requires closing first.
  • Reserved margin for resting orders, margin locks at placement, not fill, preventing order-book spam from over-leveraging the account.
  • Permissionless funding + liquidation, any keeper can crank.
  • Pyth Hermes Pull Oracles, prices are posted and consumed in the same tx.

Precision

QuantityDecimalsPrecision
Base (SOL)91_000_000_000
Quote / collateral (USDC)61_000_000
Price61_000_000
Funding rate91_000_000_000
Margin ratio / BPS410_000

Position math

A position has a signed base_amount (positive = long, negative = short) and a quote_entry accumulator. unrealizedPnL=base×mark109+quoteEntry\text{unrealizedPnL} = \frac{\text{base} \times \text{mark}}{10^9} + \text{quoteEntry} For a long at entry EE with mark MM: pnl = base·M - base·E = base·(M-E) For a short at entry EE with mark MM: pnl = -base·M + base·E = base·(E-M)

Margin model

CheckFormulaWhen
Initial marginnotional × initialMarginRatio / 10_000Opening / increasing a position
Maintenance marginnotional × maintenanceMarginRatio / 10_000Every mark / oracle update
HealthfreeCollateral + unrealizedPnL - maintReqOn liquidation check
Liquidation triggerhealth ≤ 0
With a 10% initial and 5% maintenance ratio, a 1 SOL long at 130needs130 needs 13 to open and stays safe until health reaches 0 (roughly 116.5with116.5 with 20 collateral).

Mark price

Mark price is derived from the last trade, clamped to the oracle within ±10%. This prevents a single manipulated fill from cascading through liquidations.
// Pseudocode
mark = clamp(last_trade_price, oracle * 0.9, oracle * 1.1)

What a trade touches

1

Oracle post (prepended instruction)

Off-chain you fetch a signed update from Hermes and post it via @pythnetwork/pyth-solana-receiver. This creates a PriceUpdateV2 account usable for one tx.
2

Reserve margin + match

place_order locks notional × initialMargin out of free collateral and then walks the book up to 4 fills, emitting OrderFilled events and adjusting both sides’ positions.
3

Settle funding (lazy)

The taker’s funding is settled in-line with the trade. Resting makers settle on their next interaction, or when a keeper calls settle_funding.

Fees

FeeDefaultSink
Taker10 bpsfee_vault
Maker5 bpsfee_vault
Liquidation500 bps of notional closedsplit 50/50 between liquidator and insurance

Funding rate

The Drift-style dynamic funding formula Kimia uses.

Oracles

How Pyth Hermes Pull Oracles are validated.

kimia-perp reference

Full list of instructions, accounts, and error codes.

Trade a perpetual

End-to-end walkthrough.