Windfall Lotto Documentation
Windfall Lotto is a weekly, token-denominated lottery protocol centered on transferable ticket NFTs, deterministic jackpot accounting, public draw progression, and a donor-powered fee-sharing layer. The verified deployed contract keeps gameplay logic in the core lottery contract while delegating ticket rendering, archival draw NFTs, and shareholder accounting to dedicated companion contracts.
1e18 token units, a 10% host fee, a 10% transferred-winner royalty to the original minter,
and a normal jackpot distribution ladder of 80% / 20% / 5% for tiers 5 / 4 / 3.
Deployment Reference
Reference metadata for the verified contract instance this docs page is aligned to.
Decentralization Concept
Windfall Lotto is not ownerless, but the operational path for each draw is intentionally public.
What is permissionless
- Anyone can close a finished draw and request randomness through the next valid source.
- Anyone can push the fallback chain forward when a randomness source times out.
- Anyone can process ticket batches and anyone can finalize the active winning tier.
- Winners claim directly from the contract without host mediation.
- Anyone can open the next draw once the current one is in
COUNTING_DONE.
What remains host-controlled
- Deployment, initial dependency wiring, and the choice of immutable external addresses.
- Bounded tuning of callback gas and confirmation parameters, restricted to the host treasury.
- The child contracts are linked once through
setLotto(address)by the host treasury. - The host treasury remains the permanent fee-share beneficiary and receives archival draw NFTs.
Protocol Architecture
The deployed system separates state, collectibles, fee sharing, and rendering into dedicated contracts.
WindfallLotto
Core draw state machine, jackpot accounting, randomness routing, batch counting, finalization, claims, and next-draw opening.
WindfallTicket
ERC721Enumerable ticket NFTs storing draw linkage, end time, original minter, packed numbers, and processed tier state.
WindfallDrawNFT
Archival draw-result NFTs minted in pairs: one to the host treasury and one to the lotto contract itself.
WindfallFeeShare
Tracks donor qualification, active shareholder expiry, host-fee claimable balances, and pruning of stale inactive entries.
WindfallSVG
Provides on-chain SVG generation used by NFT metadata layers.
Immutable wiring
The core contract stores immutable references to the payment token, ticket NFT, draw NFT, fee-share contract, Chainlink config, and Supra router wallet pair.
Tickets and Matching Logic
The deployed version uses order-sensitive, consecutive streak matching.
Ticket model
- Each ticket contains five
uint8values packed into abytes32. - Every value must stay in the 0–99 range.
- Duplicates are allowed; there is no uniqueness rule across the five positions.
- Position matters. This is not an unordered matching system.
- The ticket also records its draw id, end timestamp, and original minter.
How _matchTier() works
The algorithm scans left to right and returns the longest exact-position consecutive streak.
| Longest streak | Tier result |
|---|---|
| 5 consecutive exact matches | Tier 5 |
| 4 consecutive exact matches | Tier 4 |
| 3 consecutive exact matches | Tier 3 |
| 0, 1, or 2 matches as max streak | Non-winner |
Draw Lifecycle
The contract is designed so a draw can keep moving even if the host is offline.
Open
A new draw opens with its end time set to the next Friday at 23:00 UTC. Any remainder from the previous draw seeds the new jackpot.
Sales
Users buy one ticket or up to 50 in a batch. Ticket purchases mint ERC-721 tickets and split value between jackpot and host fee.
Donations
Users may donate directly to the jackpot. Donations do not pay a fee, but qualifying donations are forwarded to the fee-share logic for shareholder tracking.
Close and request randomness
After endTime, anyone can close the sale and request randomness through the current valid path.
Reveal
The draw stores a five-number winning array, records the randomness source used, and moves to REVEALED.
Count
Anyone can process tickets in batches of up to 500, increment tier counters, and push processed ticket metadata to the ticket NFT contract.
Finalize
Once all tickets are processed, anyone can lock the active tier, winner count, payout-per-winner, and remainder that will roll forward.
Claim
Winning owners claim individually. If a ticket was transferred, 10% of the claim routes to the original minter and 90% to the current owner.
Open next draw
The standard path mints draw NFTs and distributes stored host fees. An emergency light path exists that skips those side effects to prioritize liveness.
Randomness Pipeline
The deployed contract hardcodes a staged fallback model to reduce the chance of a stuck draw.
Stage 1 — Chainlink VRF v2.5
Primary source. A draw first moves from OPEN to CHAINLINK_REQUESTED and waits for the VRF callback.
Stage 2 — Supra
If Chainlink exceeds the configured timeout, the same public function can escalate the draw to SUPRA_REQUESTED.
Stage 3 — Blockhash
If Supra also times out, the contract arms a blockhash fallback with a target block delayed by seven blocks, then later reveals from that block hash.
Timeout and fallback notes
CHAINLINK_TIMEOUT = 1 hoursSUPRA_TIMEOUT = 2 hoursBLOCKHASH_DELAY = 7blocks after arming- The draw state machine is
OPEN → CHAINLINK_REQUESTED → SUPRA_REQUESTED → BLOCKHASH_PENDING → REVEALED → COUNTING_DONE. RandomnessUsedemits the selected source and random word for auditability.
Jackpot, Tier Selection, and Windfall
The deployed version pays only one active tier per draw, with a special windfall override once the jackpot becomes very large.
| Condition | Tier 5 winners exist | Tier 4 winners exist | Tier 3 winners exist | Active winning tier | Distributable share |
|---|---|---|---|---|---|
| Below windfall trigger | Yes | Irrelevant | Irrelevant | Tier 5 only | 80% |
| Below windfall trigger | No | Yes | Irrelevant | Tier 4 only | 20% |
| Below windfall trigger | No | No | Yes | Tier 3 only | 5% |
| Below windfall trigger | No | No | No | No winning tier | 0%, full rollover |
| At or above windfall trigger | Yes | Any | Any | Tier 5 only | 80% |
| At or above windfall trigger | No | Yes | Any | Tier 4 only | 80% |
| At or above windfall trigger | No | No | Yes | Tier 3 only | 80% |
jackpot >= WINDFALL_TRIGGER, the contract still selects the highest available tier in the normal 5 → 4 → 3 order,
but the distributable jackpot share becomes 80% even when the active winning tier is only tier 4 or tier 3.
Payout locking and rollover
payoutPerWinneris locked at finalization time.- Any undistributed dust from integer division stays in
remainder. - If no winning tier exists, the whole jackpot rolls to the next draw as remainder.
- The normal ticket purchase split is 90% to the jackpot and 10% to host-fee accounting.
NFT Layer
Windfall Lotto uses NFTs both as player assets and as protocol memory.
Ticket NFTs
WindfallTicketisERC721Enumerableand supports on-chain portfolio lookup.- Metadata is on-chain and includes SVG rendering.
- Processed tier state is reflected in ticket appearance after counting.
- Winning tier visuals are color-coded for tiers 5, 4, and 3.
Draw-result NFTs
- The standard settlement path mints two draw NFTs per completed draw.
- One result NFT goes to the host treasury and one to the lotto contract.
- Each stores draw id, reveal timestamp, jackpot snapshot, packed winning numbers, active tier, and winner count.
- The emergency light path skips draw-NFT minting.
Trust Model and Risks
The protocol narrows operational dependence, but still has bounded trust assumptions.
- Users still trust the original deployment, immutable addresses, and correct one-time linking of helper contracts.
- The host treasury can tune confirmation and callback parameters within bounded ranges, which can affect UX and liveness quality.
openNextDrawLight()preserves liveness but deliberately skips fee distribution and result-NFT minting for that transition.- The blockhash fallback improves recovery from oracle failure, but it is still a weaker fallback than the oracle paths.
Key Constants Snapshot
A compact reference for the deployed mainnet rules.
| Constant / rule | Value | Meaning |
|---|---|---|
| Ticket price | 1e18 base units | One whole token assuming 18 decimals |
| Max tickets per buy | 50 | Upper bound in buyTickets() |
| Max process batch | 500 | Upper bound for one counting call |
| Host fee on buys | 10% | Accumulated and later distributed through WindfallFeeShare |
| Jackpot contribution on buys | 90% | Added immediately to the current draw jackpot |
| Tier 5 share | 80% | Normal distributable share when tier 5 is active |
| Tier 4 share | 20% | Normal distributable share when tier 4 is active |
| Tier 3 share | 5% | Normal distributable share when tier 3 is active |
| Windfall trigger | 1e27 base units | 1,000,000,000 whole tokens |
| Windfall payout share | 80% | Applied to whichever tier becomes active once trigger is reached |
| Transferred winner royalty | 10% | Redirected to the original minter when the winning ticket changed hands |
| Schedule | Weekly | Draw end targets next Friday at 23:00 UTC |
| Shareholder base minimum | 1000e18 | Base unit used by the fee-share qualification ladder |
| Shareholder duration | 365 days | Base active duration once threshold is reached |
| Max shareholders stored | 200 | Registry cap before pruning is attempted |