Every conversation about provable fairness starts at the same moment: the block where the random number lands. That is the moment the proof covers, and it is genuinely the good part. Verify the VRF request, verify the fulfilment, check that the contract used the value it was given, and the question “was this draw manipulated” is closed forever. No support ticket, no appeal, no trust required.
It is also, in a well built raffle, the least interesting moment in the whole process. By the time the callback fires, every decision that could have gone against you has already been made. So here is a question almost nobody asks a gaming platform before depositing: what happens to a raffle that does not fill?
TL;DR
- A Chainlink VRF proof certifies that one draw was honest. It says nothing about whether that draw should have run at all.
- An underfilled raffle (500 tickets listed, 12 sold) can be resolved with a mathematically perfect proof and still be a bad deal for everyone in it.
- Operators resolve underfilled draws three ways: run it anyway, extend the clock, or cancel and refund. All three are decisions, and none of them are covered by any randomness proof.
- Extending the entry window is the most invisible: it changes the odds you paid for, after you paid, without a single line of code misbehaving.
- The fix is not a better proof. It is putting the threshold, the close block, the escrowed prize and a permissionless refund path in the contract before tickets go on sale.
The failure path nobody markets
Picture a raffle listed at 500 tickets. The entry window closes and 12 are sold. Nothing has gone wrong technically. The randomness source is healthy, the subscription is funded, the callback will land on time. Draw the winner and the proof will verify for anyone who cares to check, tonight or in four years.
The problem is that the draw was priced against an assumption that did not hold. A raffle is a bundle of two things: a random selection, and a set of conditions the selection runs under. The prize, the number of entrants, the close time, the price per ticket. Verification in this industry has become extremely good at the first thing and has essentially nothing to say about the second.
Three ways to resolve a draw that did not fill
Run it anyway. Twelve tickets, one winner, prize paid out. The odds turned out far better than the entrants expected, which sounds like a gift until you ask who funded the gap between 12 tickets of revenue and a prize sized for 500. Either the operator ate it, in which case they will not do that many times before something changes quietly, or the prize scaled down against a formula you may not have read, or the prize was never fully backed to begin with.
Extend the clock. Push the close time out and let more tickets sell. This is the one that should bother you most, because it is the one that leaves no trace. Your ticket was bought against a stated close time and an implied ceiling on how many people you were competing with. Move the deadline and both change, after your money is committed, with no admin key touched, no contract upgraded and no randomness influenced. The VRF proof at the end will verify perfectly. It is proving something narrower than you think it is.
Cancel and refund. The clean-looking option, and the one worth interrogating hardest. Who is allowed to call the cancel? Under what condition? If the answer is an onlyOwner function triggered at the operator’s discretion, then the platform holds a switch that lets a human look at a live game and decide it should not resolve. That capability does not come with a direction attached. Whatever justifies voiding a draw that embarrassed the treasury will also justify voiding one that emptied it.
A proof of the draw is not a proof of the game
This is the structural point, and it generalises well beyond raffles. Fairness is a property of a sequence: entry window, minimum threshold, prize funding, cancellation authority, resolution, payout. Cryptographic verification currently covers one link in that chain with total rigour and leaves the rest to be governed by whatever the operator wrote in a help article.
“Provably fair” has been doing load-bearing work it was never built for. It is a claim about one component being sold as a claim about a product. The honest version is narrower: verifiable randomness eliminates exactly one dispute class, the one where you suspect the house picked the winner. That happens to be the dispute class that dominates complaints about centralised gaming, which is why it matters. It is not the same as saying every way you can be treated badly has been engineered out.
Where does the prize actually live?
An underfilled draw is precisely the scenario that tests whether a prize is escrowed or promised, which is why it is worth checking before you find out. If the prize sits in the contract from the moment the raffle is created, an undersold draw is an accounting problem for the operator and nothing more, because the money is already out of their hands. If the prize is a promise the operator intends to keep at settlement, then every ticket you hold is partly an unsecured claim on their solvency, and the draw least likely to be honoured is the one where they are underwater on it.
You cannot see the difference from the front end. Both render as a number on a card with a countdown under it. You can see it on a block explorer in about thirty seconds.
The shape we think is correct
Satoshie’s position is that every one of these decisions belongs in the contract before a single ticket sells, not in an inbox afterwards. Concretely: the close is a block height enforced by the contract rather than a timestamp rendered by an interface. Any minimum threshold is in code and published before sale, so “does this resolve at 12 tickets” has an answer you can read rather than an answer you receive. The prize is escrowed at creation. And where a game can fail to resolve, the recovery path is permissionless and time-bounded, meaning that after a deadline written into the contract, anybody at all can trigger it and the outcome is fixed in code. Not the operator. Anybody.
That last property is the one that does the work. A recovery path controlled by the house is an admin key wearing a helpful expression.
The honest half
Escrowing a prize at creation locks capital that would otherwise be earning, and that cost is exactly why promise-based prize pools remain popular. It is a real trade-off and we pay it rather than pretend it does not exist.
A refund is also not quite the clean reversal it sounds like. Getting your stake back on-chain still costs you gas, so “you get everything back” is approximately true rather than exactly true. A permissionless timeout bounds your exposure, it does not delete it, and the window where your funds sit committed is real.
And there is a cost to coding the rules this rigidly that nobody mentions: a contract cannot be kind to you. If a draw resolves at 12 tickets because 12 cleared the published threshold, there is no one to appeal to and nobody who can make an exception because the outcome felt rough. That is the same absence of discretion that stops anyone voiding your win. You do not get to keep only the half you like.
Three things to check before you enter anything
- Is there a minimum, and is it in the contract or in the marketing copy? One of those is a rule and the other is a mood.
- Can the close time move after I have paid, and who is able to move it? If the answer is the operator, the odds you agreed to are provisional.
- Is the prize in the contract right now? Open the explorer and look at the balance. If it is not there yet, you are not playing a game, you are extending credit.
A perfect proof of the draw tells you the coin was honest. It does not tell you the game was. Ask about the failure path, because it is the only part of a gaming platform that nobody bothers to make look good.
📷 Photo by Veronica Campoverde on Unsplash


