System architecture
In one paragraph. Trion V2 is a hybrid exchange: an off-chain, single-writer matching engine decides order (who traded with whom, in what sequence), and a set of non-upgradeable contracts decide money (custody, margin, funding, liquidation). Nothing the matcher says becomes true until a signed batch is accepted by the PerpetualV2 contract on chain. Prices come from a separate oracle path that the matcher cannot override.
The six moving parts
| Part | What it does | Where it lives |
|---|---|---|
| Wallet / browser | Signs EIP-712 orders and strategy policies; sends deposits, withdrawals and hard revocations directly to the contracts. | overdrive/exchange/web/src/wallet.ts |
| Matcher (EngineV2) | One writer per market. Verifies signatures in a worker pool, reserves margin, matches against an in-memory FIFO book, and proposes fill batches. | overdrive/exchange/matcher/src/v2-engine/engine.ts |
| Binary WAL | Every command and external fact (order, cancel, price, receipt, reorg…) is appended and fsynced before it is acknowledged, so a restart replays to the same state. | overdrive/exchange/matcher/src/v2-engine/wal.ts, replay.ts |
| Settlement relay | Takes durable batches, checks the matcher signature, simulates settleBatch with eth_call, enforces a gas budget, sends the transaction and reconciles the receipt. | overdrive/exchange/matcher/src/v2-relay/relay.ts, reconciliation.ts |
| Contracts | Registry, price verifier, funding, risk, orders, perpetual, closeout/backstop/ADL/slow-mode, strategy policy. Custody never leaves them. | overdrive/perps/src/v2/*.sol, overdrive/shared/v2/IV2.sol |
| Oracle / price feed | Collects source prices and hashes evidence; in V2, a keyless publisher coordinates three independent one-key signer services to deliver threshold-signed PricePayloads, FundingPayloads and FixingPayloads to TrionPriceVerifierV2 and FundingEpochsV2. | overdrive/exchange/oracle/src/publisher.ts, signer.ts, publication-evidence.ts; overdrive/exchange/matcher/src/index-feed.ts |
Life of an order
- Sign. The browser builds a 14-field
Order, signs it under theTrionOrdersv2 EIP-712 domain bound to the market'sOrdersV2address, andPOSTs{order, signature}to the matcher. See Signed orders. - Admit.
EngineV2.submitOrderrecovers the signer off the hot thread, refreshes the trader's on-chainAccountView/RiskView, and checks collateral reservations. A failure returns a structuredFault(BAD_SIGNATURE,MARGIN, …), never a silently reordered acceptance. - Persist, then match. The order is written to the WAL (
SUBMITframe) and only then matched. GTC remainders rest; IOC remainders are dropped; FOK is all-or-nothing. - Propose. Fills accumulate into a packed batch (target 50, cap 100, 100 ms flush timer) that the matcher key signs under the
TrionPerpetualdomain. The batch is itself a WAL frame (BATCH_PROPOSED). - Settle. The relay simulates, submits
PerpetualV2.settleBatch(packed, matcherSig)and waits for the receipt. The contract re-validates every signature, epoch, tick, price band, fee cap and margin rule; it also pins the batch to the latest accepted oraclepriceSequence. - Confirm. Only receipt-confirmed fills become the tape (
L) and are pushed to WebSocket subscribers. Until then the API reports the order asmatched, neverconfirmed.
Deposits, withdrawals, hard revocation (OrdersV2.advanceAccountEpoch) and direct OrdersV2.cancel go straight from the wallet to the chain; the matcher learns about them by polling PerpetualV2 events (ChainIngester, 500 ms) and re-checking account state on every submission.
Price path
The design separates four prices: I (independent index), M (bounded mark, ±0.5 % of I), E (actual fill) and L (last confirmed fill). Risk uses M; funding notional uses I; the tape uses L. The matcher samples its own book into an EMA mark (mark-sampler.ts) and serves an authenticated snapshot of its depth to the oracle (/v2/mark-evidence), but it cannot push a price on chain: only a payload two of the three committee signers independently reproduced and signed is accepted. Details and current limits are in Data & methodology.
What is implemented versus what is designed
The normative design is docs/spec/V2_ARCHITECTURE.md. The code above implements its main shapes (single-writer engine, binary WAL, packed settleBatch, threshold verifier, epoch revocation, independent signer services). It is deployed and verified on Robinhood Chain (4663) with USDG collateral: the shared stack (MarketRegistryV2, TrionPriceVerifierV2, FundingEpochsV2, RiskV2, FixingCouncilV2) and the CMPT perp modules are in overdrive/deployments/v2/4663.json; the CMPT option stack activates at the time listed on the status page and is recorded in the verified 4663.options.json written by the finalizer. The CMPT perpetual is deployed but not listed, so the live product is CMPT capped options only. GRID, DRAM, NAND, HASH and DPIN have no contracts on 4663, and TOKN derivatives are disabled by construction in the deploy scripts. The 4663.*.dryrun.json files are pre-cutover simulations kept as history; they are not consumed by any loader. Local development uses a throwaway chain 31337 with a valueless test token (see Local development).
Guards that the code now enforces
- Canonical deployment only.
loadV2DeploymentsFromDisk(core/src/deployments.ts) accepts a manifest only whendeploymentStatusisverifiedand it carriesverifiedChainId,verifiedGenesisHash,verifiedAtBlockandverifiedBlockHash. Those fields are written solely by the read-only finalizers (core/scripts/finalize-perps-v2.ts,finalize-options-v2.ts) after a fresh RPC check; the deploy scripts themselves write*.pending.json. The matcher (config.tsvalidateV2Bindings) and the oracle (v2-runtime.ts) re-verify genesis and anchor block against the RPC at startup, so a manifest cannot be pointed at a different chain or fork. - Registry-gated matching. Every
EngineV2is constructed with amarketStateLoader(main.ts) that re-readsMarketRegistryV2.getMarketat the latest block, recomputes the market id from the registered identity and re-checks the block hash. Admission, policy triggers and batch proposal refresh that state; if the market is disabled, unavailable or mismatched, the affected unproposed intents are durably cancelled and no batch is emitted. Cancellation, account intake, receipts, reorgs and recovery are never gated. - No silent chain fallback in the browser.
getV2PerpsDeployment(chainId)andgetV2OptionsDeployment(chainId)inoverdrive/exchange/web/src/v2-config.tsaccept only 31337 (local) and 4663, and on 4663 they throw unless both the perps and options manifests carrydeploymentStatus: "verified". Before signing or sending any V2 transaction,wallet.tsalso re-reads the matcher's configured chain, the wallet's account state and a fresheth_chainId, and refuses on mismatch rather than switching networks for you. - No placeholder prices.
/v1/markets,/v1/accountand thetickerstream serve only the snapshot accepted byTrionPriceVerifierV2and answer503/UNAVAILABLEwhen it is missing, expired or malformed. There is no seed, store or V1 substitute on the V2 path (see API). - Soft cancel reaches the V2 book.
DELETE /v1/orders/:hashauthenticates against the resting order's actual trader and removes it withEngineV2.cancelOrder. It is local only; hard revocation on chain remains the authoritative exit. - No self-refreshed prices. The matcher never re-signs an ageing V2 snapshot. Snapshots come only from the oracle publisher's 2-of-3 signer committee; when the last accepted snapshot expires the API reports the price as unavailable until a new signed snapshot lands.
- Options wired to series. The Options and Liquidity pages read
OptionEngineV2,OptionDlmmV2andWriterSleeveV2through the V2 ABIs, resolve a series byseriesIdfrom the options manifest and the matcher config, and verify pool/token/sleeve bindings on chain before acting. The live series list is whatever the verified4663.options.jsonrecords; an empty manifest yields an empty list, never invented instruments. - Options V3 is a separate exchange.
OptionsExchangeV3(overdrive/src/v3/OptionsExchangeV3.sol, interfaceoverdrive/shared/v3/IOptionsExchangeV3.sol) holds trader cash, positions and per-series collateral locks and settles operator-matched fills (settleFills) against EIP-712 orders under the domainTrionOptionsv3. The book service (overdrive/exchange/options-book) matches in a single-writer engine, simulates each batch witheth_call, relays at most 40 fills per transaction, and keeps orders, fills and batches in SQLite; the desk, the market maker and the service all compute payoff, fee, fill projection and reservations fromoverdrive/exchange/core/src/v3.ts, never from private copies. It loads only a verifiedoverdrive/deployments/v3/<chain>.options-v3.json, and it settles against the sameTrionPriceVerifierV2fixing as V2; the oracle publisher adds V3 expiries to the CMPT fixing schedule from that manifest (oracle/src/v2-runtime.ts). See Options and the Options order-book API. - Public API host. The matcher at
https://api.trion.marketserves the desk and proxies the index oracle read-only under/v1/oracle/*, so the browser talks to one public host (see API).
Known limits at launch
- Perp funding view. The matcher reports perp funding fields as
UNAVAILABLE; it does not readFundingEpochsV2. Options pay no funding, and no perpetual is listed, so this is not user-visible today. - Mark while perps are unlisted. With no qualified perp book, accepted snapshots carry the CMPT index as their mark (
M = I); option premiums are quoted from that mark. - Governance and council. Governance is a single address and all five fixing-council seats are Trion-held at launch; see Risks and security.
- No independent audit. The internal review register in
docs/RELEASE_V2.md§6 has no third-pass closure review.
Source trail: docs/spec/V2_ARCHITECTURE.md §§1, 3.5, 4; overdrive/deployments/v2/4663.json, 4663.perps.json; overdrive/deployments/v2/reviewed/4663.cmpt-options-approval.md (markSource: "index"); overdrive/exchange/matcher/src/main.ts (marketStateLoader), server.ts (/v2/mark-evidence, /v1/oracle/*), config.ts, canonical-prices.ts, index-feed.ts, mark-evidence.ts; overdrive/exchange/core/src/deployments.ts (parseVerification, loadV2DeploymentsFromDisk), v2-bindings.ts; overdrive/exchange/core/scripts/finalize-perps-v2.ts, finalize-options-v2.ts; overdrive/exchange/oracle/src/publisher.ts, signer.ts, v2-runtime.ts; overdrive/exchange/web/src/v2-config.ts, wallet.ts, pages/options.ts, pages/liquidity.ts; overdrive/deployments/v2/README.md.
Repository-owned documentation · September 2026 · Educational material, not investment advice and not an audit.
Documentation
V2 · Live on Robinhood Chain