Provably Fair
How Ticket Clash is Fair
Every raffle result on Ticket Clash is determined by a seeded pseudo-random number generator. The seed is recorded on-chain at lock time, and every shuffle and match can be independently reproduced by anyone with the seed โ including you.
Step-by-step: how a raffle resolves
- 01
Registration closes
When the countdown hits zero, registration is locked. No new tickets can enter. The final list of ticket IDs is frozen.
- 02
Seed is generated
A seed is derived from the current Unix timestamp at the moment of execution. This value is immediately written to the database โ it cannot be changed after the fact.
- 03
Tickets are shuffled
The full list of ticket IDs is shuffled using Fisher-Yates with the seeded RNG. This determines the bracket order.
- 04
Bracket rounds run
Shuffled tickets are paired up. Each pair has a winner selected by the RNG. Unpaired tickets (odd counts) get a free bye to the next round. This repeats until one ticket remains.
- 05
Results are stored
Every round, every match, and every outcome is stored immutably in the database. The winner, 2nd and 3rd place are recorded.
The RNG algorithm
We use Mulberry32, a well-known, fast, and statistically high-quality 32-bit seeded PRNG. Given the same seed, it always produces the exact same sequence of numbers โ making every shuffle and match outcome fully reproducible.
function seedRng(seed: number) {
let s = seed;
return () => {
s |= 0;
s = (s + 0x6d2b79f5) | 0;
let t = Math.imul(s ^ (s >>> 15), 1 | s);
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}The Fisher-Yates shuffle ensures every permutation of tickets is equally likely:
function shuffle(arr, rng) {
const a = [...arr];
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(rng() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}Verify any result yourself
Every finished raffle exposes its seed in the results page. You can copy the seed and the list of ticket IDs, then run the same Mulberry32 + Fisher-Yates shuffle locally to confirm the bracket matches what we recorded. No trust required.
What you need to reproduce a result:
- The raffle's seed (shown on each finished raffle)
- The ordered list of ticket IDs as stored at lock time
- The Mulberry32 + Fisher-Yates code above (copy-paste into any JS console)