Overview
Every coin launched on Lottopad has a jar. The coin's pump.fun creator fee goes to the jar (the creator of every coin is a program address, ["jar", mint]); 20 % of each collected fee goes to the pad, the rest stays in the jar.
When a jar holds at least the threshold, the keeper takes it to Base once per Megapot drawing: it bridges the SOL to USDC and buys real Megapot tickets (each a $1 NFT on Base). Megapot draws every day at 17:00 UTC with Pyth randomness. Lottopad has no randomness of its own.
Whatever comes back (winnings plus our own referral cashback, since the pad is its own referrer) is bridged back to SOL and buys this coin on its curve or pool. The bought tokens go to the coin's holders pro rata to a snapshot at the drawing; each holder claims with a merkle proof.
Lifecycle of a round
| status | what it means | who moves it on |
|---|---|---|
| open | SOL moved from the jar to the keeper for one drawing | keeper: bridge |
| bridging | USDC arrived on Base (fill tx recorded) | keeper: buy tickets |
| tickets | ticket ids + numbers stored on Solana, NFTs on Base | Megapot draws; keeper posts the result |
| settled | winnings back in the round vault; buying this coin in chunks; holder root posted; veto window; claims | anyone: buy chunks, claims |
| closed | claim window over; unclaimed tokens carry into the coin's next paying round | anyone |
| no win | less than the minimum payout came back: it goes to the jar, nothing to buy | - |
| refunded | no tickets could be bought: SOL back to the jar | keeper |
| defaulted | the keeper missed a deadline; anyone marks it publicly and no new round of any coin opens until it is resolved | anyone / keeper / admin write-off |
The transactions, with an example
- Launch (you):
launch(name, ticker, uri, dev_buy)creates the pump.fun coin with the jar as creator and your optional first buy. Launch fee: 2.5 % of the dev buy (a launch without a dev buy is free). - Collect (anyone): pump creator fees into the jar; pad share booked.
- Open round (keeper): when the jar holds the threshold, up to 1 SOL goes to the keeper for the next drawing.
- Bridge + tickets (keeper, Base): SOL → USDC (Relay or Mayan), then
Jackpot.buyTicketswith us as referrer and the coin's mint assource.attest_bridgeandpost_ticketsrecord both chains' hashes and every ticket id. - Draw (Megapot): 17:00 UTC, Pyth randomness.
post_drawrecords the numbers, the Pyth random number and the Base tx. - Settle (keeper):
claimWinnings+claimReferralFeeson Base, bridge back, thensettlepulls exactly the SOL that came back into the round vault. - Buy back:
buy_chunkbuys this coin with the vault's SOL, at most 2 % of the curve's SOL per chunk. Only the keeper sends chunks in the first 12 h after a settle (sandwich protection); anyone may after. - Claim (anyone, for a holder): after the guardian veto window,
claim(index, weight, proof)pays the holder's share to the holder's token account.
Example. A jar holds 0.10 SOL. At $120/SOL the bridge delivers about 12 USDC, the keeper buys 12 tickets. Megapot pays 3 of them (about 1 in 4 wins something) for $7.20 gross; Megapot keeps 10 % of each prize as the referrer's share, which comes back to us as referral cashback together with 10 % of the $12 spent: $6.48 won + $1.92 referral = $8.40 → about 0.07 SOL → bought back and paid to the holders.
How ticket numbers are made
The keeper cannot choose numbers. The program computes them in post_tickets and stores them with each ticket id:
seed_sig = the coin's last pump / PumpSwap buy in a slot strictly before the round's open slot
h = sha256("lottopad:numbers:v1" || seed_sig[64] || mint[32] || u64le(draw_id) || u32le(ticket_index))
read h as u16 little-endian words (h = sha256(h) when used up)
normals: v = 1 + word % ball_max, keep if new, until 5 picked, sorted ascending
bonus: 1 + next word % bonus_max (ball_max / bonus_max: Megapot's, per drawing)
Every round page has a Check it yourself button that recomputes every ticket in your browser and compares it with the chain. The numbers do not change the odds: the drawing happens later, on Megapot.
Trust points
2. Keeper attestations. Bridge fills, ticket ids, the drawing's numbers, winnings and the SOL that came back are not verifiable on Solana. Each carries its Base tx hash in events and in the keeper log (the tape). The program checks what it can: numbers are derived on chain, USDC spent never exceeds USDC received, the drawing matches the round, exactly the attested SOL is pulled.
3. The holder table. Keeper-posted merkle root, bound to the round, published as JSON and rebuildable by anyone; the guardian can veto it during the veto window; excluded accounts are refused on chain too.
4. The guardian can only delay (veto a root). 5. The admin sets bounded parameters, pauses new launches and rounds, changes the keeper / guardian with a delay, and can write off a defaulted round (moves nothing).
Parameters (read from the program now)
Reading the config…
Program reference
Program id LoTYmdHDiNwZH8RYDjo1vzBzjB6nUnJhSxx46qoKJNJ. IDL: /idl/lotto.json.
| account | seeds | holds |
|---|---|---|
| Config | ["config"] | admin, treasury, keeper, guardian, params, exposure |
| Coin | ["coin", mint] | jar balance, pad share (fixed at launch), totals |
| Jar | ["jar", mint] | system account, the coin's pump creator |
| Round | ["round", mint, u64le(draw_id)] | one per coin per Megapot drawing: every step's record |
| Vault | ["vault", round] | SOL that came back; buys the coin; holds bought tokens |
| TicketBatch | ["tix", round, u16le(batch)] | one Megapot buy tx: ≤ 10 ticket ids + numbers |
| Draw | ["draw", u64le(draw_id)] | one Megapot drawing: numbers, Pyth random, Base tx, snapshot slot |
Errors
Verify on chain
- Tickets: every ticket links to its NFT on Basescan (
JackpotTicketNFT0x48Ff…66e4); the buy tx carries the coin's mint assource. - Draws:
Jackpot.getDrawingState(id)on 0x3bAe…42a2; the draw studio compares the posted numbers with Base live. - Numbers: the round page recomputes every ticket in your browser.
- Holders: the table JSON of each round, rebuildable from Solana balances at the snapshot slot.
- The keeper log: download the JSON.
What the admin can and cannot do
| can | cannot |
|---|---|
| change parameters inside fixed bounds (pad share only for future coins) | move SOL or tokens from any jar, vault or holder |
| pause new launches and new rounds | stop settles, buybacks or claims |
| propose a new keeper / guardian (live after 48 h) | change a round's rules after it opened |
| write off a round defaulted for 7 days (moves nothing) | choose ticket numbers or drawing results |
Risks
- Keeper custody while bridging and on Base (trust point 1), capped as above.
- Bridge risk (Relay / Mayan) and price moves between the round and the settle.
- Most tickets lose. Expect about 1 in 4 to win a small prize; the jackpot is Megapot's and very unlikely.
- Megapot's terms: prizes over $500 need identity checks in Megapot's app; the contract itself pays the NFT owner.
- Buy chunks: keeper-only for 12 h after a settle, then permissionless; each is capped at 2 % of the venue's SOL to limit sandwiching.
- If Megapot enters emergency mode, a drawing is recorded as "no drawing" and its tickets are refunded on Base.
FAQ
Do I have to do anything as a holder?
Hold through the drawing. After a paying round, connect a wallet: the Mine panel shows what you can claim.
Who picks the numbers?
Nobody. They come from the coin's last buy signature; the program computes them.
Can the keeper keep winnings?
It attests what came back, and every Base tx is public. A missed deadline makes the round defaulted in public and freezes new rounds.
What if a round wins nothing?
The referral cashback still comes back. Below the minimum payout it goes to the jar for the next round.
About this preview
This preview runs on a local Solana validator with a copy of pump.fun. The Base side runs on an anvil fork of Base mainnet with the real Megapot contract; the fork settles each drawing with Megapot's real Pyth random number read from Base mainnet, so winning numbers match the real draw. Fork transaction hashes and some older seeded ticket ids (from the localnet mock) do not exist on Base mainnet, so their Basescan links do not resolve; they are marked preview. A trade simulator on the box trades the example coins so jars fill. The local test wallet in the wallet picker is funded with test SOL.