Fairness

Commit, freeze, reveal, recompute

The scheme is called tgrgb-v1. It is three hashes and a sampler, and you can check all of it without our software.

Before entries open

A SHA-256 commitment is published on the post. It binds the server seed and the parameters named in it — the code, the declared closing time, the price and the seat count — so those cannot be quietly changed afterwards.

When entries close

The eligible list is frozen and its canonical hash is published, so the exact set of entries the draw will use is visible before the seed is revealed. This is a second, separate publication — not part of the commitment.

At the draw

The seed is revealed, the pick-by-pick log is published, and every winner index can be recomputed from the hash — with or without our software.

The steps, in order

What is published when, and what it makes impossible
StepPublishedWhat it prevents
1. Commit SHA-256 of tgrgb-v1|code|ends_at|price|seats|server_seed, on the post before entries open Re-picking the seed afterwards, and moving the closing time or the price after seeing who entered
2. Freeze SHA-256 of the canonical entry list — every entry id, ticket number, user id, contribution and weight Adding or removing an entrant after the list closes
3. Client seed SHA-256 of the entrant contributions in snapshot order The host computing the outcome before the list is final
4. Reveal The server seed and draw_seed = HMAC(seed, code|snapshot|client_seed|ends_at) Nothing new — this is what makes step 1 checkable
5. Select The pick log: for each nonce, the raw 32-bit word, the pool size and the entry it landed on A winner list that does not follow from the seed, because index = word % pool_size is arithmetic you can redo

Selection uses rejection sampling: a word is kept only if it is below floor(2³² / n) × n. That makes the choice exactly uniform for any pool size rather than approximately uniform for plausible ones — and it is honest to say the difference would never be visible in a real raffle. The reason it is here is that the claim is provably uniform or it is not a claim worth printing.

What this does not prove

  • The commitment binds the seed and the deadline printed on the post. The moment the pool is frozen is a separate published hash, not part of the commitment.
  • A commitment cannot stop a host from closing early or cancelling before the reveal. What constrains that is automatic closing at the published time, the visible snapshot hash, an early close that demands a recorded reason, and a re-draw that is always a new record.
  • Entrant contributions are assigned by the bot at entry time, not typed by the entrant.
  • Re-running a draw creates a second draw row. The old winner list is never edited, so “why was my number taken” has an answer with a timestamp.
  • Payment review on Venmo, Cash App, PayPal and Zelle is a human decision, because those rails expose no API to check a payment against. We do not call that automated.
  • Nothing here stops a host from choosing a seed they like before publishing — which is why the commitment is published on the group post, where everyone saw it before they paid.

The mitigations that do address the remaining powers are automatic closing at the published time, anchoring the commitment in a public ledger, and keeping a re-draw as a new record.

Check one yourself

The verification page recomputes winners rather than displaying them, and prints the openssl commands to repeat it. Worked example →

Run the demo verification

The rest of the product

One banner post, then the bot does the rest

Publish a raffle from the bot's admin menu in your group. The card carries the prize tiers, the closing time, the seat count and the commitment hash. The entry button lives on the post, so nobody has to scroll for a link.

Seats are held while payment clears

Number 042 is reserved for the person choosing it, for as long as the hold you configured lasts. If the payment never arrives the number goes back on sale by itself, and two people cannot end up on the same ticket.

Take Venmo, Cash App, PayPal, Zelle or stablecoins

Each payment profile is a bundle of the rails your members actually use, with the handle, the deep link and the reference code they must quote. USDC on Solana or Ethereum and USDT on Tron get a QR code of the receiving address generated on our server, not by a third-party QR site.

Prize tiers that match what you are giving away

First, second, third, or eleven identical prizes. The draw goes tier by tier and one account can win at most one tier per raffle, so a three-tier prize pool cannot be swept by a single person.

A draw anyone in the group can check

We publish the commitment before entries open, the entry-list hash when they close, and the seed when the draw runs. The verification page recomputes the winners instead of displaying ours, and gives you the commands to reproduce it with openssl.

Payments stay between you and the entrant

Entrants pay you in a DM to the bot. Handles, transaction references and screenshots never appear in the group, and the counters members see are counts, not names.

Admin menus other members cannot see

The controls live in the bot's private menu and in the operator dashboard, so a raffle cannot be cancelled by whoever noticed the button. Staff rights are per-group and separate from being a Telegram admin.

Giveaways, for the free ones

No seats, no money, no price. Free entry lists with optional caps, the same commitment and the same verifiable draw.