Verifiable exchange with replayable execution
A Rust limit-order engine publishes enough evidence for an outsider to replay its history and check its state from public data.
01Context
Problem
An exchange screen cannot show whether its operator omitted an order, invented a fill, or replaced an earlier database. The project asks what an outside observer can verify from public data.
Constraints
- The demo had to remain auditable through public endpoints without database access or an operator account.
- Exact message bytes, integer price grids, and matching rules had to replay identically across implementations.
- The system uses synthetic markets. It does not hold funds, settle trades, replace a stopped sequencer, or prevent censorship.
02System
Architecture
Browser-signed orders
Sequencer ordering and exact-byte storage
Hash-chain and RFC 9162 Merkle commitments
Deterministic price-time-priority matcher
Separately implemented validator replay
Signed state claims
Periodic Base Sepolia roots
My role
Designed the protocol and built the services with AI assistance under direct review, including the Rust processes, browser flows, Go anchor sender, tests, and deployment controls.
Decisions
- Separated message ordering from execution so the sequencer cannot decide how a submitted order fills.
- Signed and stored exact bytes instead of reconstructing equivalent JSON, and kept prices and quantities on integer grids.
- Kept execution off-chain and anchored checked roots, because executing every toy order on-chain would answer a different question.
03Validation
What failed
- Unused-account trade and profit-and-loss queries scanned durable history. Bounded read paths and rate limits removed that cheap denial-of-service path.
- Passive visits persisted raw demo keys and the page could be framed. Key persistence became explicit and the deployment added browser security policies.
- Chart reads rebuilt candles and stale symbol responses could replace newer data. Bounded projections, cancellation, caching, and generation guards fixed both paths.
- Market partial fills and post-only or fill-or-kill refusals were correct but poorly explained. The ticket now states the price bound, slippage, fill, and cancelled remainder.
Tests and checks
- The public audit command is designed to download signed claims and messages, replay the history, and compare the resulting roots and trade counts. A full-history replay was not completed in the review because of memory limits.
- An architecture test keeps the validator implementation separate from the matcher it checks.
- Regression tests cover recovery, signatures, replay defense, order semantics, proofs, expensive empty-account queries, and browser security behavior.
- The public release uses one parentless commit whose files, Git objects, and container inputs were scanned before publication.
04Outcome
Result
The live synthetic exchange exposes a signed history, state claims, validator agreement, and testnet anchors. The public release is a reviewed one-commit snapshot with the source, tests, protocol notes, and local demo.
Limits
The project has no real custody or settlement. The validators run inside the same reviewed system, sequencer liveness and censorship remain unsolved, and a deliberately remembered demo seed remains readable to same-origin script.
What I would change today
Add protocol-level key rotation and separately operated validators before experimenting with anything beyond synthetic markets.