Document GP-DOC-18: Fairness & Chain
Provably Fair
GENOPOOL's fairness claim is not a promise; it is a verification procedure. Every race outcome is a pure, replayable function of a published seed, a public genome, and a recorded input trace. Anyone can re-run that function with the open-source engine and check the result against on-chain commitments. Nobody needs to trust the operator.
One bit-deterministic engine
The entire physics simulation is written once, in TypeScript, and runs identically in the browser (the game) and in headless Node (the balancing harness and the server validator). There is no simplified side model: one engine, one source of truth. The rules that make it bit-exact:
| Rule | Implementation |
|---|---|
| Deterministic physics | Rapier compiled with the enhanced-determinism flag |
| Fixed timestep | 60 Hz with an accumulator, never variable delta-time in the simulation path |
| No ambient randomness | zero Math.random in the sim; all randomness comes from a seeded mulberry32 PRNG, seed passed explicitly |
| Ordered iteration | no unordered Set/Map iteration anywhere in the sim path |
Determinism is the foundation everything else stands on. Given the same seed, genome and inputs, any machine reproduces the same race, tick for tick, bit for bit.
The proof chain: published seeds, derived rolls
Every hour, the map seed is published on-chain via Switchboard On-Demand verifiable randomness: the operator cannot choose it, predict it, or replace it. All in-game randomness for that hour is then derived from the published seed through a labeled, domain-separated function:
roll = mulberry32(deriveSeed(hourSeed, "<domain>:<params>"))
domains:
spawn:<zone>:<slot> // wild specimen genomes (shared world slots)
drop:<raceId>:<position> // post-race drop rolls
Because the hour seed is public and the derivation labels are deterministic, every roll in the game is publicly recomputable: anyone can confirm that the spawn a player scanned, or the drop a race awarded, is exactly what the published seed dictates, with no hidden reroll, no operator thumb on the scale. See Wild spawns and Race rewards.
Replays are input traces, not videos
A replay is the timestamped list of pilot inputs: a few kilobytes, with effort quantized to 4 bits per tick at recording time. The full race is reconstructed by feeding that trace back into the engine. Three consequences come free:
- Ghosts cost nothing: rendering a rival's trace alongside your run is just running the sim twice.
- Anti-cheat is re-simulation: the server replays the submitted trace from the published seed and compares the resulting time to the claimed time. A cumulative state hash is folded every 60 ticks, so a divergence is caught at the first faulty checkpoint, not just at the finish line.
- Public commitment: replay hashes are accumulated and committed on-chain as a Merkle root, once per hour. A settled result can be contested by anyone who re-runs the trace.
How to verify a race
- Download the race bundle: the input traces, the creature genomes (readable from the assets' on-chain attributes), and the race metadata. The trace embeds the map seed; replaying without the published seed is impossible by construction.
- Re-simulate with the open-source engine from the published hour seed. The engine is the same code the game ran.
- Compare the resulting times and finishing order to the settled result.
- Check inclusion: verify the replay hash's Merkle proof against the hourly root committed on-chain.
If steps 3 and 4 pass, the result is honest. If either fails, you hold a portable, cryptographic proof of it.
The on-chain programs
Two Anchor programs anchor the money side. Both are deliberately small and hold no discretionary power.
genopool_wager: non-custodial ticket escrow
Stakes for a match live in the token account of a per-match PDA (seed b"match"). The
operator's backend is only the oracle: it signs the final ranking, and holds no
authority to withdraw or redirect funds.
| Constant | Value | Meaning |
|---|---|---|
MAX_PARTICIPANTS | 5 | one race, five lanes |
MAX_PAYOUTS | 3 | podium places paid, at most |
MAX_FEE_BPS | 1 500 | rake hard-capped on-chain at 15 %; the highest official tier uses 12 % |
official payout_bps | [6500, 2500, 1000] | 65 / 25 / 10 % of the net pot |
The lifecycle is create_match → deposit → settle (or refund):
create_matchfreezes the participants,payout_bpsandfee_bpsforever (no instruction can rewrite them) and validatesΣ payout_bps ≤ 10 000.depositis signed by each participant; a bitmap prevents double deposits.settleis oracle-signed and distributespot_net × payout_bps[i]per rank, writes the winningreplay_hashon-chain (making the settlement contestable by re-simulation), and sweeps rake plus integer rounding dust to the treasury.refundis permissionless: past the settlement deadline, anyone can return every deposit to its depositor. If the operator disappears, no funds are stranded.
The poker-room invariant of the economy,
Σ payouts ≤ Σ tickets - rake, is therefore structural in the escrow, not an operator
policy: the program cannot pay out more than the pot it holds, and prizes come from
tickets alone.
genopool_market: royalty-enforcing trades
The marketplace program computes the creator royalty on-chain
(ROYALTY_BPS = 500, 5 %, floor-rounded) and splits every sale atomically, aligned with
the Metaplex Core Royalties plugin carried by each asset. See
Marketplace & registry.
State and proofs on-chain, verifiable compute off-chain
No blockchain runs rigid-body physics at 60 Hz, and GENOPOOL does not pretend otherwise. The division of labor is explicit:
| Layer | Where | Guarantee |
|---|---|---|
| Creature genomes | on-chain (Metaplex Core attributes) | public, readable by anyone |
| Hourly seeds, wild genomes | on-chain (Switchboard) | operator cannot choose outcomes |
| Race proofs | on-chain (hourly Merkle root, replay_hash) | results are committed and contestable |
| Ticket escrow, royalties | on-chain programs | funds and fees follow frozen rules |
| Physics simulation | off-chain, open-source, deterministic | replayable by anyone, bit-for-bit |
The state is public, and the computation over that state is open and reproducible. A skeptical player can independently confirm that the map was not chosen against them (Race format), that the field was settled by the recorded inputs and nothing else (Competition), and that the same engine being verified is the one that was balanced in the open (Balancing). Trust is optional; verification is not gated.