Architecture
perp.com is an off-chain trading core anchored to on-chain custody and settlement. Hot paths — matching, margin, risk — run in memory for latency; durable state and value transfer live on HyperEVM contracts.
System diagram
Clients reach a single gateway. Orders flow down the green path through matching and position management into settlement. Probability flows in from Polymarket on the right, is guarded and smoothed into a mark, and is published on-chain. Risk, funding, and liquidation read that mark. The indexer bridges chain events back into the event bus.
Design principles
- On-chain custody, off-chain speed. USDC never leaves the vault except through contract-defined paths. The operator holds a margin-engine role bounded by on-chain checks and a withdrawal delay that acts as the user's safety net.
- Event-driven core. Services communicate over an event stream bus — order.created, stream-{m}-response, mark_price.event, settlement.event — not synchronous RPC, so each stage scales and recovers independently.
- Per-market isolation. Each market gets its own matching engine instance and its own risk configuration tier, so a thin event market can't destabilize a deep one.
- Deterministic settlement. Every fill resolves to an on-chain executeTrade, and settlement is atomic — a batch either lands in full or leaves no partial state behind.
Layers
| Layer | Responsibility | Key components |
|---|---|---|
| Edge | Auth, rate limiting, REST + WebSocket fan-out | API / Gateway, Order Controller |
| Order & matching | Margin lock, order book, fills, open interest | Order Svc, Matching Engine, Position Svc, Market Data Svc |
| Risk & pricing | Mark price, funding, margin math, liquidation | Mark Price Svc, Funding Engine, Risk Svc, Liquidation Engine, ADL Engine |
| Settlement | Batch, sign, submit, reconcile on-chain | Settlement Pipeline, Indexer |
| State | Hot atomic state and durable ledger | HotCache, Ledger |
| On-chain | Custody, market lifecycle, risk anchor, positions | CollateralVault, MarketRegistry, MarketRiskRegistry, PositionManager, OracleRegistry, Insurance Fund |
Components
API / Gateway
The single entry point for all client traffic. Validates SIWE sessions, rate-limits, and routes REST calls to internal services. Over WebSocket it subscribes to the event bus and pushes user-scoped updates — order state, fills, balance, liquidations — and public market data: order book deltas, trade prints, mark price, and funding.
Order Service
Accepts orders, computes the effective initial margin against current open interest, locks margin atomically in HotCache, persists to the ledger, and streams the order to the matching engine. Initial margin is dynamic: the requirement scales with a market's open interest between a lower and upper cap, so positions cost more to open as a market gets crowded.
Matching Engine
One in-memory instance per market. Maintains the order book, matches orders, and emits results on stream-{m}-response along with order book deltas, trade prints, and the impact-bid/ask samples the funding engine needs. The book is snapshotted for crash recovery.
Position Service
Owns position lifecycle. Applies fills, moves margin from locked_for_orders to locked_for_positions, maintains per-market open interest, and enqueues settlement batches. Position status moves through OPEN → LIQUIDATING → CLOSED with a parallel settlement status of PENDING_SETTLE → SYNCHRONIZED.
Mark Price Service
Takes the raw oracle probability and applies guards — deviation clamp, smoothing, staleness check, probability bounds — to produce the mark used for risk and the index used for funding. Caches per market and publishes mark_price.event, then pushes snapshots on-chain to the risk registry. Full detail on the Oracle page.
Funding Engine
Runs a three-stage pipeline: per-block premium samples from the impact-mid versus index, a per-minute median to reject book gaps, and a per-period average over the funding interval. Pushes the cumulative funding index delta on-chain; positions accrue funding lazily on their next touch. Detail on the Trading page.
Risk Service
The home for margin math. Computes equity, unrealized PnL, maintenance margin, and the open-interest-scaled initial margin. Asserts pre-trade margin for the Order Service and computes bankruptcy and fillable prices for the Liquidation Engine.
Liquidation & ADL Engines
The Liquidation Engine scans positions, triggers when equity falls to the maintenance margin, and closes at a fillable price with per-block and per-account caps. The ADL Engine and Insurance Fund handle residual bad debt. Full detail on the Liquidation & ADL page.
Settlement Pipeline
Groups pending fills into gas-budgeted batches and submits them on-chain as executeTrade calls, sized for HyperEVM's block constraints. Settlement is atomic and self-reconciling: a batch either applies in full or leaves position state untouched, with automatic recovery on failure.
Indexer
Watches HyperEVM for contract events and publishes them to the event bus — vault.event, market.event, settlement.event, funding.event — alongside the bridged Polymarket probability. It is the chain-to-backend bridge in both directions, with delivery guaranteed even across restarts.
State stores
HotCache is the low-latency layer for hot balance state, atomic margin operations, the mark price cache, and stream cursors. Ledger is the durable, append-only event log and queryable state of record: transactions, orders, fills, positions, and settlement batches.
On-chain contracts (HyperEVM)
Draft → Active → Resolving → Resolved → Settled.executeTrade, liquidate, settlePosition with lazy funding accrual.Key data flows
Order to settlement
client → gateway → Order Svc (lock margin) → Matching Engine → Position Svc (apply fill) → Settlement Pipeline → chain → Indexer → client
Price to risk
Polymarket → Oracle Keeper → Mark Price Svc (guard + smooth) → mark_price.event → Risk / Funding / Liquidation, and on-chain via pushSnapshot.
Funding
Matching Engine impact samples + index → Funding Engine → applyFundingIndex(delta) on-chain; positions apply on next touch.