What the program can and cannot do.
Not deployed, not audited, never executed on a validator. This page states what was revoked by design, where the trust lies, and what remains unverified.
Where it stands.
The source of every figure on this site, and what is built, tested and deployed today, as of 23 Oct 2026.
- program
- cargo check + 21 host tests · not compiled for SBF · not deployedthe program's README
- tests
- property test, 10,000 rounds, passing · Anchor suite not runthe property test
- audit
- noneSECURITY.md
- deployment
- noneSECURITY.md
- legal
- openRISKS.md
What nobody can do.
By construction, checked by tests/idl-authority.ts. The instruction set is closed: 14 instructions, nothing else, everything but the user-signed money paths permissionless.
Update authority: to revoke after audit, or a 72 h timelock · SECURITY.md
- Move an entry.
- Cancel after seal.
- Change the law, the cap or the fees.
- Pause claim, sell back or refund.
- Choose the seed.
- Choose between draw and refund after seeing the value.
- Mint more tokens.
A round opens
Anyone pays in; entries land live, each one capped at a share of the round.
92 slots ≈ 20 s, same price for everyoneOne seed arrives
At the last slot the round closes and asks the oracle for one seed.
seed in 4 s (median), 113 s at the 99th percentileThe shares are computed
The seed lands; every roll is derived from it, the owner and the entry index.
Σ shares = tokens sold, exactlySell back, or keep
The total buys tokens on the curve once; the shares are tallied and settled, page by page.
sell back at the curve price, zero fee
Randomness: where the trust is
ORAO VRF. The seed is fixed at seal from sealed data; every roll is derived from it, the owner and the entry index, recomputable by anyone.
If the oracle has not answered after 900 slots (about 3.3 min), anyone can trigger a refund. Every entry gets its stake back in full, and no fee is taken.
vrf_seed = sha256("pulled:vrf:v1" ‖ window ‖ close_slot ‖ entry_count ‖ entries_commitment)
roll_i = sha256(seed ‖ owner_i ‖ index_i) → floor(10001 · u³)| attacker | what they control | why it fails |
|---|---|---|
| Participant | when and how much to enter, how many entries, their own pubkey | the seed does not exist before close, and the entries commitment includes every entry, so grinding a pubkey changes the seed for everyone, unpredictably; entries after close are rejected; there is no cancel |
| Round or market creator | market parameters at creation, nothing afterwards | no parameter touches the seed; the creator cannot enter after close, cannot request before seal, cannot refund before timeout |
| Keeper or request payer | when to call seal, request, fulfill, tally, settle, refund | all permissionless, so withholding only delays until someone else calls; the value cannot be dodged; the keeper cannot pick the seed and cannot re-request |
| Slot leader | transaction ordering within a slot, the slot hash | the program never reads slot hashes, block hashes, timestamps or any chain entropy; ordering entries changes the commitment but the leader cannot predict the oracle's signatures |
| ORAO fulfilment authorities | their signing keys | this is the residual trust: a colluding quorum could compute the outcome once the seed is fixed, not before the last entry; they could withhold fulfilment and force a timeout refund (a denial of service; nobody gains from it) |
We accept this trust because every on-chain alternative is worse (leader-influenceable). Switchboard's randomness was deprecated in September 2026; ORAO is the only viable VRF on Solana today.
Accounting invariants
Proven at the base unit by tests/props on 10,000 adversarial rounds, with the reference TypeScript law, a line-by-line twin of the program's.
- Σ shares = tokens out for every round; each share within 1 unit of its exact value; the remainder spread by cumulative quota rounding, never dropped.
- Σ stakes = to curve + platform + bounty + host on settlement; Σ stakes = Σ refunds on refund.
- Curve rounding is always against the trader: selling back an entire round returns at most what the curve received.
- Settlement is paginated with a strict cursor: no entry skipped or double-counted, replays are no-ops.
- roll_sum and tokens_out are frozen at finalize; the curve executes once per round, in round order.
- create_market rejects any quote mint with a freeze authority, and any Token-2022 mint carrying a transfer fee, a transfer hook or a permanent delegate: each would break the exact accounting or let a third party block the escrow.
Two fees, written in the program
100 basis points (1.00 %) platform fee on the round total. 0 on sell back, claim and refund. Hosts may add at most 300 basis points, fixed at integration creation.
The seven checks
Each one is a research report with a verdict and a dated figure. One is still open, and it says so.
- Pass
Prior art
No live product draws the size of the fill at a fixed price with the sum conserved.
research/G1.md - Pass, design changed
Randomness
ORAO VRF, latency measured on 314 mainnet requests: median 4 s, p90 72 s, p99 113 s. The sequential 20 s loop is dead; rounds are pipelined. Switchboard is deprecated.
data/orao-summary.json - Pass after redesign
Fairness
The multiplicative law favoured small stakes by 7% to 266%; the linear law is exact to ±0.5% per decile over 10,000,000 rounds.
research/G3.md - Pass
Concentration
Cap of 20% per entry; the biggest entry explains at most 3.6% of a small player's variance.
data/G4-results.json - Pass (reference)
Accounting
10,000 adversarial rounds, invariant to the lamport; program not run on a validator.
props/run.ts - Pass
Time
1 slot = 217 ms (measured 10 Oct 2026 to 23 Oct 2026); 92 slots ≈ 20 s.
data/G6-slot-samples-summary.json - Unverified
The loop
Nobody measures re-entry after a bad draw; the protocol is written, the measurement is not done.
research/G7.md
The risks, plainly
Read this before paying in. Last reviewed 23 Oct 2026.
- The legal question is not resolved. Until a written professional answer exists, nothing goes to mainnet.
- About six entries in ten end below their pro-rata share (62 % measured). A bad draw is a bounded, known, immediate loss.
- The fees are a certain loss: 1.00 % on entry, before the curve buy. The draw redistributes expectation, it does not create it.
- You receive tokens, not money. Their sell-back price is the curve's at that instant; nothing else.
- One randomness provider. If it stops, every round is refunded and none can be drawn.
- The category is shrinking: −17.5 % month over month in July 2026, and 78 % of measured players lose money.
The architecture, in five blocks
Anchor program
14 instructions, none of them administrative. The law lives on-chain, mirrored in the sdk.
ORAO VRF
One seed per round, requested at seal, fulfilled with a public proof.
Permissionless keeper
Anyone can seal, request, tally and settle. Bounty: 10 % of the fee.
SDK + embeddable component
One component or one iframe; a host fee of at most 300 bps, written once.
Indexer
AMM-grade indexing of rounds, entries and settlements, for the verification pages.
Known limitations, and what is not verified
As written in SECURITY.md. What is unverified stays marked unverified.
- No SBF build, no validator run, no devnet test on the machine where this was written. cargo check, clippy and 21 host tests pass; the Anchor suite is written and has not been run.
- No audit.
- Compute budgets of tally_page and settle_page (48 entries per page) are estimated, not measured.
- Placeholder program id and platform treasury must be replaced before deployment.
- Single randomness provider. If ORAO stops, every pending round refunds in full after 900 slots and no new round can be drawn. Measured latency: median 4 s, p90 72 s, p99 113 s.
- A dead keeper only delays (everything is permissionless); a round stuck in Sealed with no request ever sent refunds only after the timeout counted from the sealed slot.