Verifiable Fairness
Round outcomes are computed from on-chain state and deterministic program logic, not from opaque server-side decisions.
Whitepaper
A detailed technical and product specification for the onefor49 commit-reveal lottery protocol, including architecture, economics, security model, and operational boundaries.
Document Status
Version 1.0 • Drafted for current frontend + program architecture • Date: 2026-03-21
Abstract
onefor49 is a non-custodial, stage-based lottery protocol on Solana that combines a commit-reveal flow with deterministic settlement logic and transparent vault accounting. Players place picks, reveal them in a bounded period, and claim rewards after settlement. The protocol is designed for verifiability, explicit stage reasoning, and practical UX reliability through local-first state persistence and transaction-intent journaling.
Motivation and Goals
Round outcomes are computed from on-chain state and deterministic program logic, not from opaque server-side decisions.
Users only follow one clear lifecycle: Place Picks -> Reveal Picks -> Claim Reward.
Frontend preserves intent and round context with local-first storage so page reloads do not erase action continuity.
Wallet signatures remain user controlled, with no private key custody by the application.
System Model
| Actor | Role |
|---|---|
| Player | Places picks, reveals picks, and claims rewards through signed wallet transactions. |
| Root Authority | Operational authority for protocol-level setup, including protocol mint administration flows. |
| Revenue Authority | Operational receiver for revenue-side token accounts and accounting surfaces. |
| Program | On-chain source of truth enforcing round timing, entry constraints, reveal validation, and settlement eligibility. |
| Frontend / Indexer | Read/UX layer that presents state and submits transactions; does not override program finality. |
| On-chain Object | Purpose |
|---|---|
| Protocol Config | Global authorities and protocol mint references. Anchors protocol namespace for all games. |
| Game Config | Per-game parameters: token mint, candidate count, round timing periods, vault accounts, and title metadata. |
| Entry | Per player/game lifecycle state for current participation path in one-entry mode. |
| Game Stats | Aggregates for round and historical computation, including revealed and winner amount sums plus rolling snapshots. |
| Snapshot History | Rolling history record set for recent rounds (fixed-size period) used for transparency and UX summaries. |
Lifecycle and State Machine
Each round executes through strict stage periods driven by game timing parameters: place picks period, reveal period, and claim period. Stage eligibility and UI action enablement must match resolver output to avoid stale submits.
| Stage | Objective | User Requirement | Failure Mode |
|---|---|---|---|
| Place Picks | Collect committed entries for the active round. | Submit a valid pick payload and token amount. | If period closes before submit, player must wait for next round. |
| Reveal Picks | Reveal committed picks for settlement eligibility. | Provide valid reveal data matching prior commitment. | Missed reveal can forfeit reward path in one-entry mode. |
| Claim Reward | Allow eligible players to claim finalized rewards. | Submit claim for settled and eligible round state. | Missed claim period can permanently lose that round reward path. |
Commit-Reveal Construction
Players first submit a commitment derived from pick data and salt. During reveal, the program validates consistency between reveal payload and prior commitment.
Canonical form:
commit_hash = H(namespace || game_id || round_id || wallet || pick_payload || salt_32) where: - H is the deterministic hash function used by current implementation - pick_payload is canonicalized before hashing - salt_32 is a 32-byte value generated from user-provided text or random source
The frontend stores reveal helper material in scoped local storage (Dexie/IndexedDB). This improves UX continuity but creates a user responsibility: if local secret data is removed before reveal, reveal may fail and reward eligibility can be forfeited.
Settlement Mathematics
| Symbol | Meaning |
|---|---|
| N | Candidate count for a game (numbers 1..N). |
| r | Round identifier. |
| A_i(r) | Total revealed amount for option i in round r. |
| W(r) | Winning Number index for round r. |
| P_user(r) | Player payout for round r after settlement. |
| M(r) | Reward rate implied by settled round accounting. |
Round-level aggregates
For option i in [1..N]: A_i(r) = sum of revealed amounts assigned to i in round r Winner selection: W(r) = argmin_i A_i(r) over configured candidate range Payout: P_user(r) = user_winner_amount(r) * M(r) where M(r) is implied by settled reward accounting and pool constraints
Economics and Incentives
Each game binds to a configured token mint. Amounts in UX are presented as token amounts (not base-unit language) for user clarity.
Settlement and claims reference game vault state. Transparency pages expose balances, addresses, and explorer links for independent verification.
One-entry mode simplifies strategic state while forcing timely reveal/claim behavior. Inactivity or missed periods carries explicit opportunity cost.
Protocol-level mint exists for bootstrap and operational distribution flows under root authority controls and destination validation logic.
Security Model
| Threat | Impact | Mitigation |
|---|---|---|
| Stage timing confusion | User submits valid action in wrong stage and fails. | Stage resolver + countdown UI + disabled action reasons + timeline surfaces. |
| Local reveal helper loss | User cannot reveal despite prior commit. | Device-local warnings, backup/export flows, and explicit one-entry forfeiture messaging. |
| RPC/index lag | UI shows stale state around boundary transitions. | Local-first cache with background refresh, tx intents, and explicit refresh controls. |
| Social engineering via fake support | Wallet compromise and asset loss. | Hard policy: never request seed/private key; repeated UI security reminders. |
| Program/account mismatch | Transactions target wrong namespace. | Cluster + program namespace indicators and compatibility checks before submit. |
Client Architecture
| Client Layer | Behavior |
|---|---|
| IndexedDB (Dexie) onefor49 scope | Stores round tickets, commit secrets, tx intents, and query cache for resilient user experience. |
| Tx Intent Journal | Tracks pending/confirmed/failed actions so refresh/reopen does not lose workflow visibility. |
| Scoped Namespace | Cluster + program scoped keys reduce cross-network data confusion. |
| Legacy Secret Migration | Legacy commit-secret rows are lazily migrated into current scoped storage on read. |
Read path preference:Dexie -> query cache -> RPC refresh -> realtime updates
Transaction continuity:pending / confirmed / failedintents persist across refresh and browser reopen.
Operations
| Operation | Description |
|---|---|
| Initialize Protocol | Creates protocol root state and initializes protocol mint references for bootstrap operations. |
| Airdrop Protocol Mint | Root authority can distribute protocol mint tokens to valid destination accounts in supported flows. |
| Create Game | Deploys per-game config with candidate count, token mint, title, and timing periods. |
| Round Progression | Round stage transitions are time-parameter-driven and interpreted by the stage resolver. |
| Ecosystem Revenue Feed | Protocol-side treasury allocation can be surfaced for routing toward the eeteel ecosystem distribution layer. |
Limitations and Future Work
Glossary
| Term | Definition |
|---|---|
| Place Picks | Player submits entry payload for active round. |
| Reveal Picks | Player discloses previously committed pick data for eligibility. |
| Claim Reward | Eligible player receives settled payout in the configured token. |
| One-entry mode | Per wallet/game, one active participation path per round lifecycle. |
| Forfeiture | Loss of reward path due to missed required stage period. |