Seesaw Solana On-Chain Program Improvement Roadmap#
Date: 2026-07-11
Scope: The Rust/Pinocchio program in src/, its protocol specifications, program-facing tests, formal-verification surface, and the operational controls that determine whether the program can be launched safely.
Status: Read-only assessment and recommendation set. This is not a security audit and does not claim that every instruction path was manually re-audited.
Executive summary#
Seesaw is already much stronger than a typical prelaunch Solana program. It has explicit owner/signer/PDA checks, checked arithmetic, SPL Token v1-only validation, a bounded deep red-black-tree orderbook, trader-ledger accounting, runtime solvency and book-consistency tripwires, Kani/Lean/proptest/fuzz/Miri surfaces, a pauser role, authority rotation, fee-recipient sharding, immutable oracle snapshots, and a serious release-evidence framework.
I would not rewrite it in Anchor, replace the CLOB, add leverage, or introduce broad new configurability. The best improvements now are to close a small set of concrete prelaunch gaps, make the existing assurance machinery truthful and continuously executable, reduce hand-maintained ABI/validation drift, and defer economically ambitious changes to a versioned v-next.
The highest-priority work is:
- Enforce the implicit six-decimal settlement-mint invariant on chain, or make share-mint decimals derive from the settlement mint.
- Repair and calibrate the compute-unit regression harness, benchmark every supported orderbook tier, and enforce a measured maximum launch tier.
- Resolve the currently failing event-parity and Kani-inventory gates and make them part of the non-bypassable release gate.
- Complete an independent human audit, production multisig/key ceremony, release-commit fuzz/mutation/Kani evidence, and incident drills before public mainnet use.
- Eliminate operational and ABI drift: the live source has public discriminants through
0x37, while some guidance still stops at0x35; mint-rotation runbooks conflict with the on-chain rejection; the unsafe inventory and a feature-gated hot-path test are stale. - Move toward one machine-readable protocol manifest that generates or validates instruction codecs, account metas, event tags, error codes, IDL, SDK constants, and documentation tables.
- Add a composed, stateful lifecycle model that proves or stress-tests vault, share, fee, referral, and trader-ledger conservation across instruction sequences rather than only within individual transitions.
How to read this document#
Priority means:
- P0: Complete before a public mainnet launch or before claiming release readiness.
- P1: High-value hardening for the first audited production release.
- P2: Versioned v-next improvement; do not destabilize launch code to rush it in.
- P3: Maintenance, clarity, or research work.
Evidence labels mean:
- Confirmed gap: Directly observed in the current checkout.
- Existing roadmap gap: Already acknowledged by repository documentation but still open.
- Design recommendation: A proposed improvement, not a claim of a current vulnerability.
Current strengths to preserve#
These are good architectural decisions. Improvements should build on them instead of churning them:
- Pinocchio is appropriate for the program's compute-sensitive paths. Manual validation is costly to maintain, but the performance/control tradeoff is justified.
overflow-checks = trueis enabled in the release profile, and core financial math uses checked or deliberately bounded operations.- SPL Token v1 is explicitly required. Token-2022 extensions are excluded because transfer fees, hooks, confidential transfers, and variable layouts would invalidate current accounting assumptions.
- Program-owned accounts use discriminators, exact layouts, owner checks, PDA checks, and stored bumps.
- The live orderbook has bounded capacity tiers and avoids reallocating in the order-placement hot path.
- Maker-owned accounts were removed from the place-order hot path in favor of the market-owned trader ledger.
- Runtime tripwires cover solvency, orderbook count/cache coherence, and crossed-book rejection without scanning every slot on every mutation.
- Oracle snapshots bind feed identity, owner, discriminator, verification level, timestamps, predecessor timestamps, exponent bounds, confidence, and market boundaries.
- Authority rotation is two-step and time-delayed; a separate escalation-only pauser exists.
- Fee conservation, referral liabilities, creator fees, and treasury-shard selection have extensive targeted tests.
- Account-layout goldens, constants-to-spec pins, Kani inventories, differential fuzz targets, mutation tooling, and Miri paths are the right assurance layers.
- The production-readiness docs correctly distinguish local evidence from external signoff.
Prioritized recommendation matrix#
| ID | Priority | Recommendation | Type |
|---|---|---|---|
| COR-01 | P0 | Enforce settlement/share decimal compatibility | Confirmed gap |
| PERF-01 | P0 | Repair CU goldens and benchmark T64-T4096 × match limit | Confirmed and existing roadmap gap |
| VER-01 | P0 | Fix the currently failing event-parity and Kani drift gates | Confirmed gap |
| SEC-01 | P0 | Commission an independent human audit against the claimed invariants | Existing roadmap gap |
| GOV-01 | P0 | Put upgrade/config authority behind verified production multisigs | Existing roadmap gap |
| VER-02 | P0 | Produce release-commit fuzz, mutation, Kani, SBF, and build evidence | Existing roadmap gap |
| DRIFT-01 | P0 | Reconcile ABI counts and generate the public instruction inventory | Confirmed gap |
| OPS-01 | P0 | Remove the false settlement-mint-rotation recovery procedure | Confirmed gap |
| DRIFT-02 | P0 | Repair or delete the stale Wave-2 lockdown feature/test | Confirmed gap |
| DRIFT-03 | P0 | Generate the unsafe inventory and align it with the no-Actions reality | Confirmed gap |
| EVENT-01 | P0/P1 | Complete binary-event parser parity or explicitly disable the recorder surface for launch | Confirmed gap |
| GOV-02 | P1 | Add proposal/apply delays for high-impact configuration changes | Design recommendation |
| ARCH-01 | P1 | Introduce a canonical protocol manifest and generated parity artifacts | Design recommendation |
| VAL-01 | P1 | Make instruction account contracts declarative and mechanically complete | Design recommendation |
| VER-03 | P1 | Add one composed lifecycle conservation model | Existing roadmap gap |
| VER-04 | P1 | Differentially execute pure transitions and compiled SBF paths | Design recommendation |
| ORC-01 | P1 | Version and fixture-test the manual Pyth account codec | Design recommendation |
| MINT-01 | P1 | Add an explicit settlement-asset risk policy/registry | Existing roadmap gap |
| PERF-02 | P1 | Add per-instruction stack, heap, account, data, and CU envelopes | Design recommendation |
| ECON-01 | P1/P2 | Design maker incentives without enabling wash-fee extraction | Design recommendation |
| STATE-01 | P1/P2 | Formalize versioned state transitions and migration/drain rules in code | Design recommendation |
| ORC-02 | P2 | Add an optional multi-source resolution policy for new market versions | Design recommendation |
| ORC-03 | P2 | Measure equality frequency and consider a flat/refund outcome | Design recommendation |
| PERF-03 | P2 | Add bounded continuation for matches that exceed one transaction | Design recommendation |
| FEE-01 | P2 | Evaluate deferred fee sweeping to simplify the trade hot path | Design recommendation |
| EVENT-02 | P2 | Make event completeness independently reconstructable | Design recommendation |
| MAINT-01 | P2 | Retire or quarantine legacy orderbook/runtime surfaces | Design recommendation |
| MAINT-02 | P2 | Consolidate duplicate execution models around one transition plan | Design recommendation |
| RISK-01 | P2 | Add opt-in market risk profiles and verified-market metadata | Design recommendation |
| DOC-01 | P1 | Replace aspirational/stale assurance claims with generated current state | Confirmed gap |
1. Immediate correctness and safety work#
COR-01 — Enforce settlement/share decimal compatibility#
Priority: P0
Evidence: Confirmed gap
InitializeConfig validates that the configured settlement mint is a valid, initialized SPL Token v1 mint, but it does not require a particular decimal count. CreateMarket always initializes YES and NO mints with 6 decimals. Accounting treats one share base unit as one settlement-token base unit.
That is safe for the intended six-decimal stablecoin, but the invariant is implicit. A valid SPL mint with another decimal count could be installed during initialization, producing economically confusing displayed units even though raw base-unit conservation still holds.
Recommended launch fix:
- Read the settlement mint's decimals in
InitializeConfig. - Require exactly six decimals.
- Pin the rule in
spec/IX.md,spec/ACCOUNTS.md, SDK initialization builders, and a negative SBF test. - Record the configured decimal count in release evidence.
Recommended v-next alternative:
- Store
settlement_decimalsin config/market state. - Initialize YES/NO mints with the settlement mint's decimals.
- Make all amount-formatting and codec surfaces derive from that field.
Do not support arbitrary decimals merely by changing UI formatting. The mint, share, ledger, order quantity, minimum notional, market cap, and fee paths must all share one base-unit contract.
Acceptance criteria:
- A non-six-decimal mint fails
InitializeConfigbefore any state is committed. - Six-decimal mint initialization succeeds in native and compiled-SBF tests.
- Cross-language SDK vectors identify all quantities as base units of the configured six-decimal mint.
PERF-01 — Repair the CU harness and enforce a measured launch tier#
Priority: P0
Evidence: Confirmed gap and existing roadmap gap
cu-benches/golden.toml says the regression gate is non-functional because its LiteSVM harness fails before instruction execution. Several entries are placeholders with wide tolerances, and one entry still names the retired redeem_eviction_claim surface. The deep orderbook supports T64 through T4096, but the current golden file does not provide a real worst-case matrix for every tier.
Recommended work:
- Fix the pre-execution
0x5001fixture failure. - Delete retired scenarios and require every golden label to map to a live public instruction.
- Measure, at minimum:
- empty-book post;
- one-maker full fill;
- multi-maker partial and full fills;
- self-trade cancellation branches;
- referral/no-referral and treasury indices
0/7; - eviction, expiration, cancel, reduce, and forced cancel;
- T64, T128, T256, T512, T1024, T2048, and T4096;
- representative
match_limitvalues through the protocol maximum.
- Capture p50/p95/max across repeated deterministic runs, not a single measurement.
- Set a launch maximum tier from evidence. Supporting T4096 in the ABI does not require first-party clients to create T4096 launch markets.
- Fail the release gate if a placeholder, skipped measurement, retired label, or tolerance above the approved ceiling remains.
Acceptance criteria:
cargo test --test cu_regression --release --features test-sbfconsumes a compiled SBF artifact and compares real measurements.- No golden value is described as a placeholder.
- Every launch-enabled capacity tier has worst-case measurements and at least 20% headroom below the applicable transaction limit under the approved client compute budget.
- The selected maximum launch tier is enforced in first-party builders and release policy, while the protocol ABI remains forward-compatible.
VER-01 — Restore the failing assurance gates#
Priority: P0
Evidence: Confirmed gap
The required command
cargo test --test category_coverage_matrix --features testable-logic
currently fails in this checkout because:
- the event-parser parity manifest is missing
REFERRAL_FEE_DEFERRED,REFERRAL_ROLLUP_COMPLETED,REFERRER_TREASURY_SHARD_INITIALIZED, andREFERRAL_PENDING_FORFEITED; and docs/kani-inventory.yamlhas drifted from the source-generated rendering.
These failures are valuable: the gate is detecting exactly the drift it was designed to detect. They should be fixed before any readiness claim, and the release process should make it impossible to ship while this command is red.
Acceptance criteria:
- The category matrix passes on the release commit without regeneration side effects.
- Every active binary event tag has a parser-parity row and cross-language vector.
- The Kani inventory is regenerated from source, reviewed, and clean on a second run.
DRIFT-01 — Generate the instruction inventory from source#
Priority: P0
Evidence: Confirmed gap
The live src/instruction.rs::discriminator defines public instructions 0x00 through 0x37 (56 public instructions) plus internal LOG = 0xFF. Some repository guidance still states 0x00 through 0x35 (54 public instructions). This is a protocol-adjacent documentation failure because agents and integrators are explicitly told to treat that guidance as authoritative.
Recommended work:
- Define one canonical instruction manifest containing discriminant, name, argument codec, account contract, event kinds, and lifecycle classification.
- Generate or mechanically validate:
spec/IX.mdinventory;AGENTS.mdcount/range sentence;- IDL entries;
- TypeScript/Rust/Python discriminant tables;
- CLI builders;
- parser routing tests;
- documentation tables.
- Add a test that scans every location containing the count/range and fails if any differs from source.
The manifest must not change existing bytes. It should describe the ABI already implemented.
OPS-01 — Correct the settlement-mint recovery story#
Priority: P0
Evidence: Confirmed gap
process_update_market_defaults requires settlement_mint == [0; 32]; nonzero mint rotation is disabled because the default mint is coupled to treasury recipients and referrer treasury shards. However, several operational documents tell operators to rotate the default settlement mint for new markets with UpdateMarketDefaults (0x32) after an issuer-freeze event.
That procedure cannot work on chain. In an incident, a false recovery step is worse than an incomplete runbook.
Recommended launch fix:
- Remove rotation claims from the threat model, incident response, market-integrity, and production-readiness docs.
- State the actual response: pause or restrict affected markets, preserve unaffected markets, coordinate issuer unfreeze, and deploy an audited program/config migration if a future default mint must change.
- Add a docs drift test that asserts
0x32is fee-only while the processor rejects nonzero mint input.
Recommended v-next fix is described under MINT-01.
DRIFT-02 — Reconcile the Wave-2 hot-path lockdown suite#
Priority: P0
Evidence: Confirmed gap
The wave2-hotpath-lockdown Cargo feature says the suite intentionally fails until rollout completion, while the test file says the surface has shipped. Running it currently produces one failure: the test expects REFERRAL_BINDING_SLOTS == 3, while the live constant is 1 after referral state moved into the position cache.
Recommended work:
- Decide whether the suite is an active regression gate or archival acceptance history.
- If active, update it to assert the current one-account binding/cache surface and enable it in the appropriate default or release matrix.
- If archival, move the historical assertions under
docs/internaland remove the production Cargo feature. - Remove the contradictory Cargo comments either way.
No release feature should be both “shipped” and “expected to fail.”
DRIFT-03 — Generate the unsafe inventory#
Priority: P0
Evidence: Confirmed gap
spec/UNSAFE_INVENTORY.md no longer matches current source locations and does not enumerate all current test/runtime-shim unsafe blocks. It also says a GitHub Actions Miri job runs on every PR, while repository policy says Actions are disabled and local gates are authoritative.
Recommended work:
- Generate the unsafe occurrence list from the Rust syntax tree, not line-number prose.
- Require each occurrence to declare one of:
- production exception with a documented safety invariant;
- test/runtime shim;
- dependency-internal unsafe reached by a safe wrapper.
- Require a named Miri or SBF test owner for every occurrence.
- Fail if the generated inventory changes without an accompanying classification/test change.
- Describe the actual local/cron execution cadence rather than dormant workflow intent.
EVENT-01 — Decide the launch event contract#
Priority: P0 for decision, P1 for full binary adoption
Evidence: Confirmed gap
The beta observability path still relies on textual SEESAW_EVENT:* logs, while the internal binary recorder is not yet a complete downstream contract. The failing parity manifest proves newly active referral events are not fully represented in the event-parser parity inventory.
Choose one explicit launch posture:
- Text authoritative for beta: Disable or clearly label the binary recorder as non-authoritative, test every textual event against truncation/format vectors, and avoid readiness claims based on binary replay.
- Binary authoritative: Complete TS/Rust/Python decoders, add golden byte vectors for every active tag, verify self-CPI feature availability and CU/depth cost, and make the indexer consume/reconcile it.
The ambiguous middle state should not ship. Event completeness affects accounting reconciliation, governance audit trails, referral liabilities, and incident response.
2. Governance, authority, and upgrade safety#
SEC-01 — Independent human audit focused on falsification#
Priority: P0
Evidence: Existing roadmap gap
The embedded security metadata states that no human third-party audit has been completed. The internal verification corpus is extensive, but it is not an independent review.
Audit scope should prioritize:
- Deep RBT/tree storage, matching, price-time priority, eviction, and bounded execution.
- Trader-ledger accounting across fill, cancel, reduce, withdraw, redeem, force-close, and close-market paths.
- Vault/share/fee/referral conservation, including rounding and deferred liability forfeiture.
- Pyth Push/Pull ownership, fixed-offset codec, Rule-A firstness, late capture, expiration, and timestamp edge cases.
- Account substitution, duplicate mutable accounts, CPI targets, PDA seeds/bumps, closure/revival, and realloc paths.
- Admin, pauser, emergency status, rate limits, authority rotation, and upgrade assumptions.
- Compute-exhaustion and account-lock denial of service at every launch-enabled capacity tier.
Give auditors the invariant catalog and proof inventory as claims to attack, not as proof that review is unnecessary.
GOV-01 — Complete and verify the production key ceremony#
Priority: P0
Evidence: Existing roadmap gap
Before public mainnet use:
- Upgrade authority must be a production multisig or intentionally revoked.
- Config authority must be a distinct, appropriately thresholded multisig.
- Pauser should be a lower-latency but escalation-only role.
- Treasury ownership should not collapse into the same single key as upgrade/config authority.
- ProgramData, program hash, authority addresses, quorum, signer set, proposal links, and finalized execution slots must be recorded.
- A compromised pauser drill must prove that the pauser cannot unpause, lower emergency severity, rotate itself, or change economic parameters.
GOV-02 — Timelock high-impact configuration actions, not only authority rotation#
Priority: P1
Evidence: Design recommendation
The program rate-limits several parameter changes, but a cooldown after an update is not the same as notice before the first harmful update. A compromised config authority can still apply an immediately effective allowed value, then the cooldown merely prevents another change.
For high-impact settings, consider a generic proposal/apply mechanism:
- hash the full candidate config delta;
- store proposer, proposal time, eligible time, and expiry;
- emit the complete before/proposed values;
- allow cancellation by current authority and emergency escalation by pauser only where safe;
- apply only the exact stored delta after the delay.
Candidate delayed fields:
- fee curve and fee split;
- treasury recipients;
- max price staleness and expiration window;
- maximum order size;
- settlement-asset registry changes;
- maker-band and referral-duration changes if they become configurable.
Keep Pause and severity-increasing market emergency actions immediate. Recovery actions and economic changes should require the stronger path.
GOV-03 — Make roles and capabilities machine-readable#
Priority: P1
Evidence: Design recommendation
Define a generated capability matrix for current authority, pending authority, pauser, market creator, trader, referrer, and permissionless caller. Validate that code, spec/IX.md, security docs, CLI help, and governance runbooks all agree.
This would catch ambiguities such as documentation implying that the pauser can perform the force-cancel operation itself when the processor may require the config authority for the actual unwind.
STATE-01 — Turn the drain-by-cadence policy into executable version handling#
Priority: P1/P2
Evidence: Design recommendation
The documented strategy—new market layouts apply only to new markets while old markets drain—is sound. Strengthen it with code-level rules:
- Every long-lived account loader must dispatch explicitly on a supported version.
- Unknown future versions fail closed with a dedicated error.
- Old versions are either read-only/drain-only or have a named migration instruction.
- A migration must prove owner, discriminator, old version, canonical PDA, rent delta, idempotency, and post-layout invariants.
- Market creation records a protocol feature/version set, not just a generic program version.
- SDKs expose versioned decoders without “try any layout” behavior on live surfaces.
3. Settlement asset and token architecture#
MINT-01 — Add an explicit settlement-asset policy#
Priority: P1
Evidence: Existing roadmap gap and design recommendation
The current immutable default mint and Tokenkeg-only policy are simple and safe, but issuer freeze/blacklist risk is operationally significant and cannot be fixed with the currently disabled 0x32 mint argument.
A v-next asset registry could store, per approved settlement mint:
- mint address and decimals;
- Token program ID (initially Tokenkeg only);
- enabled/disabled-for-new-markets state;
- risk class and display metadata hash;
- associated treasury recipient set or treasury-shard namespace;
- activation time and governance proposal reference;
- whether mint/freeze authorities are present, as observed at registration;
- optional maximum market liability for that asset.
Existing markets must continue to bind their original mint. Disabling an asset should stop new markets but must not block cancel, withdraw, redeem, settle, force-close, or claim paths for existing markets.
Do not add generic Token-2022 support until every accepted extension has an explicit accounting policy. A deny-by-default extension allowlist would be required.
FEE-01 — Evaluate deferred protocol-fee sweeping#
Priority: P2
Evidence: Design recommendation
Today, the protocol fee portion is transferred to one of eight external treasury recipients during fills, while creator/referral portions may remain as market liabilities. A future market version could instead accrue all fee classes in program-accounted liabilities and sweep them in bounded, permissionless batches.
Potential benefits:
- fewer treasury-recipient concerns on the trade hot path;
- easier per-market fee reconciliation;
- a longer recovery window before funds leave market custody;
- reduced frozen-recipient disruption during fills;
- simpler attribution of rounding dust.
Risks:
- higher vault liabilities and more complex solvency checks;
- sweep liveness and keeper incentives;
- additional state/versioning;
- possibly no meaningful CU win if token movement remains dominated by other CPIs.
Do not implement this without measured CU data and a new composed conservation proof.
4. Oracle and resolution hardening#
ORC-01 — Version the manual Pyth codec and bind it to upstream fixtures#
Priority: P1
Evidence: Design recommendation
src/oracle/pyth.rs manually parses PriceUpdateV2 at fixed offsets. It has good size, discriminator, owner, verification-level, exponent, feed, timestamp, and predecessor checks. The remaining risk is schema drift in the upstream account layout.
Recommended work:
- Define a small internal codec type with an explicit version and all offset assertions in one module.
- Import canonical serialized fixtures from a pinned upstream revision and record the revision/digest.
- Differentially decode those fixtures with the official SDK off chain and the minimal on-chain codec.
- Add mutation cases around enum encoding, truncated data, appended data, verification-level variants, negative/large exponent, and predecessor ordering.
- Treat a new discriminator/version as unsupported until a program upgrade adds and audits a new codec branch.
Avoid pulling a large Anchor receiver SDK into the SBF binary solely for decoding unless CU/binary measurements justify it.
ORC-02 — Optional multi-source resolution for a new market version#
Priority: P2
Evidence: Design recommendation
Single-oracle dependence is a known liveness and integrity concentration. A v-next oracle policy could support:
- Pyth primary plus a second independent source;
- a maximum normalized divergence;
- deterministic median/quorum logic;
- a fail-safe path to delayed resolution or expiry when sources disagree;
- per-asset approved source sets from an asset registry.
This must be a new market version. Retrofitting it into existing markets would change the resolution contract after users trade.
Multi-oracle is not automatically safer: different update cadence, decimals, outage modes, and governance can create more ambiguous states. Model liveness and adversarial disagreement before implementation.
ORC-03 — Quantify equality bias and consider a flat outcome#
Priority: P2
Evidence: Design recommendation
The current deterministic rule treats end >= start as UP, so exact equality resolves UP. That is a valid “non-decrease” market definition, but short-duration or coarsely quantized feeds may produce equality often enough to create a structural side bias.
Before changing anything:
- measure equality frequency per feed/duration from historical Pyth updates;
- publish the observed rate;
- ensure UI wording says “same or higher” if the rule remains;
- consider a new
Flat/Refundoutcome only for a new market version if the economic bias is material.
Any new outcome requires new share/payout proofs, event/schema changes, SDK changes, and close-market handling.
ORC-04 — Centralize lifecycle timing predicates#
Priority: P1
Evidence: Existing future-hardening note
Implement a single pure can_transition(state, now, oracle_state, config) policy used by snapshot, resolve, expire, force-close, and close-market wrappers. This reduces duplicated inclusive-boundary and grace-window logic and makes exhaustive state-machine tests practical.
The function should return a typed transition reason, not only a boolean, so error behavior remains deterministic and testable.
5. Orderbook, execution, and compute#
PERF-02 — Define resource envelopes per instruction#
Priority: P1
Evidence: Design recommendation
For every public instruction, track:
- fixed and optional account counts;
- writable and signer counts;
- instruction-data bytes;
- account-data bytes read and written;
- maximum realloc delta;
- stack-frame and heap high-water marks;
- CPI count and maximum CPI depth;
- measured CU by representative branch;
- transaction packet/ALT assumptions.
Generate a compact resource table and fail when a change exceeds its approved envelope. This makes denial-of-service review concrete and prevents “small” event or validation changes from consuming the last headroom on place/match/settle paths.
PERF-03 — Add bounded match continuation#
Priority: P2
Evidence: Design recommendation
The match limit correctly bounds a single instruction, but very deep liquidity can require multiple transactions to execute a large aggressive order. Consider a versioned continuation design:
- the taker commits limit price, side, remaining quantity, minimum fill, expiry, and a unique nonce;
- each permissionless continuation consumes at most
Nmakers; - state records the exact remaining quantity and prevents parameter substitution;
- the user can cancel remaining quantity after an explicit rule;
- fees and self-trade behavior remain identical across chunks;
- partial progress is never economically worse than the committed constraints.
This is only worthwhile if measured launch markets actually hit match-limit truncation. Do not add it speculatively before CU/volume telemetry exists.
PERF-04 — Benchmark selective reads and writes#
Priority: P1/P2
Evidence: Design recommendation
The deep orderbook and trader ledger are large. Continue moving hot paths toward:
- header-only reads when only counts/best prices are required;
- side-selective traversal;
- mutation of the smallest touched byte ranges;
- no full-account copies or heap materialization;
- measured break-even points for tree traversal versus cached metadata.
Add tests proving selective loaders and full decoders return identical logical state for randomized valid accounts.
MAINT-01 — Quarantine legacy orderbook code#
Priority: P2
Evidence: Design recommendation
The live off-chain contract is deep-orderbook-only, but legacy sorted-array types remain in the on-chain source tree. If they are still needed for tests or conversion, isolate them under a clearly named legacy/test module. Otherwise remove them after proving no public ABI or fixture depends on them.
Add a compile-time/source inventory gate so new production code cannot import a legacy orderbook module accidentally.
6. Economic and market-design improvements#
ECON-01 — Add maker incentives cautiously#
Priority: P1 design, P2 implementation
Evidence: Design recommendation
A pure CLOB needs reliable passive liquidity. The current zero-maker-fee model avoids charging makers but does not fund rebates.
Options, in recommended order:
- Launch with contracted first-party/external market making and off-chain, transparent performance incentives.
- Measure spread, depth, uptime, adverse selection, self-trade, and volume quality.
- Design an on-chain maker rebate only after real data exists.
An on-chain rebate must:
- be funded entirely from collected taker fees or a capped subsidy pool;
- never make total allocations exceed collected fees plus an explicit budget;
- exclude or neutralize self-trades and related-party wash loops;
- use program-derived fill data, never caller-provided maker volume;
- cap per-market/per-epoch payout;
- support independent reconciliation;
- preserve protocol solvency under rounding.
ECON-02 — Make keeper rewards adaptive but bounded#
Priority: P2
Evidence: Design recommendation
The current fixed closer reward and top-up instruction are simple. If telemetry shows missed lifecycle deadlines or fee overpayment, introduce bounded reward classes based on operation and urgency:
- snapshot/resolve reward;
- expiration/force-close reward;
- order-reclaim reward;
- close-market/rent-recovery reward.
Rates should be market-snapshotted at creation or governed through delayed changes, with per-market prepaid budgets and rent floors. Avoid live config changes retroactively altering already-funded market obligations unless top-up sufficiency is proven.
ECON-03 — Keep permissionless markets, add verified-market metadata#
Priority: P2
Evidence: Design recommendation
Permissionless market creation is a core property, but multiple creators can fragment liquidity across equivalent feed/duration windows. Do not force global uniqueness at the protocol level without strong evidence. Instead, add an optional registry/catalog that marks markets as verified under a published risk profile.
The registry should not grant settlement authority or change payouts. It should only attest to feed, duration, settlement asset, oracle mode, capacity tier, and creator identity so first-party clients can curate without making unverified markets invalid.
RISK-01 — Market risk profiles#
Priority: P2
Evidence: Design recommendation
Bundle compatible parameters into named profiles rather than exposing many independent knobs:
- max market liability;
- max per-order size;
- confidence threshold;
- max oracle jump;
- allowed duration range;
- capacity tier ceiling;
- minimum resting notional;
- keeper budget class.
Profiles reduce dangerous combinations and simplify audits. Permissionless custom markets can remain possible but should be visibly distinct from verified profiles.
7. Architecture and maintainability#
ARCH-01 — One canonical protocol manifest#
Priority: P1
Evidence: Design recommendation
The largest structural risk is hand-propagation across the on-chain parser, processors, IDL, three native/trustless SDK families, CLI, indexer, event decoders, error mirrors, and documentation.
Create a machine-readable manifest that describes:
- instruction discriminant and stability status;
- argument fields, sizes, endianness, sentinels, and bounds;
- exact base and optional account groups;
- signer/writable/owner/PDA/mint relationships;
- emitted text and binary event tags;
- error codes;
- account layouts, versions, field offsets, and reserved regions;
- PDA seed formulas;
- feature/retirement status.
Use it initially for validation and generated docs/tests, not to rewrite the program. After confidence grows, generate low-risk surfaces such as constants, codecs, IDL, and tables. Keep processor business logic handwritten.
Acceptance criteria:
- Adding an instruction in Rust without a manifest entry fails.
- Adding a manifest entry without Rust dispatch/codec/account coverage fails.
- Every SDK consumes golden vectors derived from the manifest/source pair.
- Retired/internal instructions cannot accidentally appear as public builders.
VAL-01 — Declarative instruction account contracts#
Priority: P1
Evidence: Design recommendation
Pinocchio requires explicit checks, and the current code has strong central helpers. The next step is completeness, not abstraction for its own sake.
For each instruction, define a typed account contract that can mechanically assert:
- exact legal account counts and optional-tail shapes;
- required signer/writable flags;
- expected owners/program IDs;
- discriminator and size;
- PDA address and stored bump;
- pairwise distinctness groups;
- token mint/authority/state relationships;
- config/market/position/ledger relational bindings.
Generate the instruction-validation matrix from these contracts. Add a source lint that flags direct state deserialization in processors outside approved loaders.
Do not hide business-policy checks inside a giant generic framework. The goal is to make missing validation visible and enumerable.
MAINT-02 — One transition plan, one runtime adapter#
Priority: P2
Evidence: Design recommendation
Trait-based pure implementations, native mocks, and direct Pinocchio wrappers are useful, but duplicate semantics can drift. Standardize each complex instruction around:
- typed validated input;
- pure transition planner returning state deltas, transfers, events, and invariant obligations;
- Pinocchio adapter that executes CPIs and commits the exact plan;
- post-CPI balance/state checks;
- identical native and SBF tests over the plan.
Do this incrementally on the highest-risk flows: place order, cancel/reduce, redeem, force-close, referral rollup, and close market.
MAINT-03 — Keep units at boundaries, not throughout the hot path#
Priority: P2/P3
Evidence: Design recommendation
The code already uses useful types such as price-bps/rate distinctions and dimensional comments. Continue that pattern at instruction, config, and planner boundaries. Avoid a repo-wide newtype migration through the matching hot path unless benchmarks and proof ergonomics justify it.
High-value boundary types include:
- settlement base units;
- share base units;
- lamports;
- price bps versus fee-share bps;
- Unix seconds versus slots;
- count/capacity versus byte size.
MAINT-04 — Split lint policy between production and tests#
Priority: P2
Evidence: Design recommendation
The root lint configuration permits unwrap, expect, and panic because the test corpus intentionally uses them. Keep tests ergonomic, but add a production-only source/Clippy gate over non-test src/ code that rejects panicking operations, unchecked indexing where user-controlled, and undocumented saturating arithmetic.
The existing deny(unsafe_code) production posture and forbid_panic tooling are good foundations; make the distinction explicit and release-gated.
8. Verification and testing#
VER-02 — Release-commit evidence, not historical capability#
Priority: P0
Evidence: Existing roadmap gap
Before launch, run and archive on the exact release commit:
cargo test --lib;- category coverage matrix;
- compiled-SBF integration/security suite;
- real CU regression suite;
- Kani inventory and approved proof set;
- Miri unsafe paths;
- long-running fuzz campaign with seeds, duration, target, failures, and triage;
- refreshed mutation baseline on matching, deep tree/orderbook, oracle, settlement, referral, and closure code;
- reproducible SBF build and on-chain hash verification;
- dependency, secret, and container scans;
- staging incident drills.
The evidence bundle should be immutable, commit-bound, timestamped, and reviewed by someone other than the operator who produced it.
VER-03 — Composed lifecycle conservation model#
Priority: P1
Evidence: Existing roadmap gap
Individual arithmetic and transition proofs are strong, but the most valuable missing proof/test is a composed sequence model tying together:
- vault token balance;
- total YES/NO supply and escrow balances;
- market totals;
- trader-ledger free/locked quote/YES/NO buckets;
- user-position mirrors/caches;
- creator fees;
- pending referral fees and referrer treasury/earnings;
- protocol-fee transfers;
- settled/closed counters and rent-safe lamports.
Generate adversarial sequences containing mint, deposit, place, match, self-trade, cancel, reduce, withdraw, snapshot, resolve, rollup, claim, redeem, mark-settled, force-close, and close. Assert conservation after every successful step and atomic identity after every rejected step.
Start with a small bounded model (two users, one market, small book) suitable for exhaustive exploration, then run larger stateful proptest/fuzz sequences.
VER-04 — Differential pure/SBF execution#
Priority: P1
Evidence: Design recommendation
For every instruction with a pure planner or mock path:
- create the same initial account bytes;
- execute the pure model;
- execute the compiled SBF instruction in LiteSVM/Mollusk/Surfpool;
- canonicalize and compare all changed accounts, token balances, lamports, events, and errors.
This detects wrapper-only validation, CPI ordering, serialization, and recorder drift that pure logic tests cannot see.
VER-05 — Seed and sustain the fuzz corpus#
Priority: P1
Evidence: Existing roadmap gap
The number of fuzz targets is impressive, but target count is less important than sustained execution and corpus quality.
For each critical target:
- check in minimal seeds for every instruction variant and account version;
- seed known historical regressions;
- preserve minimized crashers permanently;
- report edge coverage and corpus growth;
- run alternating arithmetic, loader, orderbook, oracle, settlement, referral, and interleaving campaigns;
- bound cold-start hangs and distinguish harness failure from program failure.
VER-06 — Refresh mutation testing#
Priority: P1
Evidence: Existing roadmap gap
Run mutation campaigns after the deep-orderbook and referral changes. Prioritize mutations that:
- remove owner/signer/writable/distinctness checks;
- change PDA seeds or stored-bump comparisons;
- alter rounding direction;
- change
>=/>timing boundaries; - skip fee/referral liability updates;
- reorder state writes and CPIs;
- turn checked/saturating operations into wrapping operations;
- skip post-CPI balance checks;
- change event tags or sequence increments.
Every surviving high-risk mutant should produce either a new test or a documented proof of semantic equivalence.
VER-07 — Make Kani inventory truth executable#
Priority: P1
Evidence: Confirmed drift plus design recommendation
Beyond regenerating the YAML:
- record which proofs actually ran on the release commit;
- distinguish full-type, protocol-bounded, representative, and smoke domains in release summaries;
- require non-vacuity witnesses;
- track timeouts separately from passes;
- ensure source changes to audited functions invalidate or re-review relevant proof rows;
- add a small mandatory proof subset to every pre-merge assurance run and the complete approved set to release cadence.
VER-08 — Expand qedsvm/compiled replay only where it adds unique evidence#
Priority: P2
Evidence: Existing scoped limitation
The qedsvm lane currently does not prove full terminal-instruction replay with clock/sysvar and SPL Token CPI behavior. Either implement complete fixtures for redeem/mark-settled/force-close/close-market, or keep its scope explicitly limited. Do not count an early-reject smoke test as terminal lifecycle evidence.
VER-09 — Test behavior coverage, not only declaration counts#
Priority: P1/P2
Evidence: Design recommendation
The repository has 569 top-level Rust test files and thousands of declarations. Add reports for:
- production branch/condition coverage;
- error-code reachability;
- instruction × account-mutation × CPI outcome coverage;
- invariants asserted after success and after failure;
- ignored/feature-gated test ownership;
- duplicated fixtures and tests that only assert symbols/constants.
Consolidate campaign-style tests into reusable scenario DSLs where that reduces fixture drift without weakening adversarial independence.
9. Events, reconciliation, and runtime observability#
EVENT-02 — Independently reconstructable accounting#
Priority: P2
Evidence: Design recommendation
For every value-moving instruction, ensure an indexer can reconstruct the transition from finalized account state plus events:
- market and position/ledger identifiers;
- gross amount/notional;
- fee total and each allocation;
- effective treasury shard;
- creator/referrer liability before/after where needed;
- payout/claim amount;
- market event sequence;
- instruction schema/version.
Add a reconciliation test that replays a randomized lifecycle using only emitted canonical events and compares the reconstructed totals with final on-chain accounts. Where events are intentionally insufficient, document which accounts must be read.
EVENT-03 — Global and market-local sequence integrity#
Priority: P2
Evidence: Design recommendation
Market event sequences are valuable. Extend gap detection to config/governance and global fee/treasury events with a config-level sequence or a deterministic transaction/instruction identity contract. Alert on duplicate, regressed, or missing sequences after finalized ingestion.
OPS-02 — On-chain balance watchdog#
Priority: P0/P1 operationally
Evidence: Existing roadmap gap
The current production-readiness docs correctly distinguish indexed projections from true token balances. Implement an independent watchdog that reads finalized on-chain accounts and verifies:
- vault token balance versus market liabilities;
- share mint supply versus market totals and escrow/ledger holdings;
- creator/referral pending liabilities;
- referrer treasury shard balances versus credited earnings;
- rent-safe lamport floors and closer budgets;
- frozen token accounts;
- event-sequence/indexer lag.
Run it from infrastructure independent of the main indexer and page on stale heartbeat as well as invariant failure.
10. Documentation and source-of-truth hygiene#
DOC-01 — Replace stale assurance prose with generated state#
Priority: P1
Evidence: Confirmed gap
Examples observed in this checkout:
- instruction guidance stopping at
0x35while source reaches0x37; - stale mint-rotation incident guidance even though
0x32rejects rotation; - stale Wave-2 feature comments/tests;
- unsafe inventory line numbers and CI claims that no longer match reality;
spec/SECURITY.mdstill listing K Framework/Certora targets while the live formal stack is Kani/Lean;- CU documentation retaining placeholder/retired scenarios;
security_txt!identifying no external audit and using a source-code URL that should be verified against the actual canonical repository.
Recommended hierarchy:
- Rust source and generated protocol manifest.
- Generated ABI/layout/event/error/resource artifacts.
- Reviewed narrative specifications that link to generated facts.
- Historical plans clearly labeled archival and excluded from readiness claims.
Expand docs-check to cover these facts. The current docs drift check passed even while the contradictions above remain, so its coverage is too narrow for protocol readiness.
11. Changes I would explicitly avoid before launch#
- Do not rewrite the program in Anchor.
- Do not replace the deep RBT orderbook after its recent migration; measure and harden it.
- Do not add margin, leverage, liquidation, or cross-margining.
- Do not retrofit native multi-outcome markets into the binary-share invariant model.
- Do not accept Token-2022 generically.
- Do not make every constant configurable.
- Do not add a dispute committee to existing markets after users have traded.
- Do not weaken full Pyth verification or firstness checks for liveness.
- Do not remove checked arithmetic or post-CPI balance checks for CU savings without an equivalent proof and measured need.
- Do not treat test count, proof inventory size, historical fuzz logs, or generated docs as release evidence unless they pass on the exact release commit.
- Do not revoke upgrade authority before the audited operational model and emergency recovery posture are mature; conversely, do not call the system immutable while an upgrade key exists.
12. Proposed delivery sequence#
Phase 0 — Current checkout cleanup (days 1-3)#
- Fix event parser parity and regenerate/review the Kani inventory.
- Reconcile
0x36/0x37across authoritative guidance. - Correct settlement-mint incident runbooks.
- Repair or retire the Wave-2 feature gate.
- Regenerate the unsafe inventory and current execution cadence.
- Verify
security_txtrepository/contact metadata.
Phase 1 — Prelaunch correctness and measurement (week 1-2)#
- Enforce six-decimal settlement mint compatibility.
- Repair the CU harness and measure all tiers/branches.
- Set the launch tier ceiling and client policy.
- Run the full local release gates on a clean release candidate.
- Build the independent on-chain invariant watchdog.
- Complete production key ceremony and authority verification.
Phase 2 — Independent assurance (weeks 2-8)#
- Send the curated invariant/proof/code package to external auditors.
- Run release-scale fuzz, mutation, Kani, Miri, SBF, and incident-drill campaigns.
- Fix findings with new regression tests and re-run the full package.
- Establish clear public security reporting and response ownership.
Phase 3 — First audited release architecture (weeks 4-12)#
- Introduce the protocol manifest in validation-only mode.
- Generate ABI/docs/SDK parity artifacts.
- Add declarative account contracts for the highest-risk instructions.
- Add composed lifecycle conservation and pure/SBF differential tests.
- Version the Pyth codec fixtures.
- Add delayed governance for high-impact config mutations if audit scope permits.
Phase 4 — Data-driven v-next (post-launch)#
- Settlement-asset registry and safe new-market mint rotation.
- Optional multi-source oracle policy.
- Maker rebates or other liquidity incentives.
- Match continuation for proven demand.
- Deferred fee sweeping if measurements justify it.
- Verified-market/risk-profile registry.
- Flat/refund outcome only if equality data shows material bias.
13. Release acceptance checklist derived from this review#
A public-mainnet readiness claim should require all of the following:
- Settlement/share decimal invariant is enforced and cross-language tested.
- Public instruction range/count matches
src/instruction.rseverywhere. - Category coverage matrix passes, including event parity and Kani inventory.
- Wave-2 lockdown status is unambiguous and its active test passes.
- Unsafe inventory is generated, reviewed, and exercised under the documented local cadence.
- CU regression uses real compiled-SBF measurements with no placeholders.
- Every launch-enabled deep-orderbook tier has worst-case CU/account/packet evidence.
- Production launch tier ceiling is documented and enforced by first-party builders.
-
cargo test --lib, compiled-SBF integration/security tests, and deep-orderbook audit pass. - Long fuzz and refreshed mutation campaigns are attached to the exact release commit.
- Kani/Miri runs are attached with scope, assumptions, timeouts, and non-vacuity status.
- Independent audit is complete and critical/high findings are closed or explicitly accepted by accountable owners.
- Upgrade/config/pauser/treasury authorities are verified on chain against intended multisigs.
- Reproducible program binary and deployed ProgramData hash match.
- Settlement-mint freeze response reflects what the program can actually do.
- Binary versus textual event authority is explicitly decided and tested.
- Independent on-chain balance watchdog and dead-man heartbeat are live.
- Oracle outage, vault/freeze, keeper stall, governance compromise, market emergency, and indexer outage drills are complete.
- Release evidence is immutable, finalized/rooted where relevant, and reviewed by a second person.
14. Evidence from this assessment#
Commands run against the current checkout:
| Command | Result |
|---|---|
pnpm test:inventory | Passed; reported 569 top-level Rust test files, 37 fuzz targets, and 7,208 Rust test/property/fuzz declarations |
pnpm audit:deep-orderbook | Passed |
cargo test --lib | Passed: 1,885 tests |
cargo test --features wave2-hotpath-lockdown --test wave2_hotpath_lockdown | Failed: 4 passed, 1 stale referral-slot assertion failed |
cargo test --test category_coverage_matrix --features testable-logic | Failed: event parser parity missing four active tags; Kani inventory drift |
make docs-check | Passed, demonstrating that current docs checks do not cover all protocol contradictions identified here |
Key source observations:
src/instruction.rsdefines public discriminants through0x37and internal0xFF.src/processor/initialize_config.rsvalidates mint initialization but does not enforce six decimals.src/processor/create_market.rsinitializes YES and NO mints with six decimals.src/processor/admin.rs::process_update_market_defaultsrejects nonzero settlement-mint input.cu-benches/golden.tomlexplicitly marks its core CU gate as non-functional/placeholding.spec/UNSAFE_INVENTORY.mdand Wave-2 feature comments have drifted from current source/tests.- The embedded security metadata says no human third-party audit has been completed.
Final recommendation#
Treat the current program as a strong release candidate whose main risk has shifted from obvious arithmetic/account-validation mistakes to assurance drift, resource uncertainty, operational authority, and cross-surface consistency. Close the P0 items without adding new economic features, complete an independent audit and measured launch envelope, then make the protocol manifest and composed lifecycle model the foundation for future changes.