The Codebase
Is this real?
Yes it does.
Fee → server roll → stored ticket → winner launches → Match Engine buys. That architecture runs on useslot.fun today. Reels on the client only animate the server result.
FAQ
Is this real?
Yes it does.
Conceptually and in production: a paid SOL fee is verified on-chain, the server rolls published odds, the ticket is persisted, losses fund the treasury, and wins build a Pump.fun create with Slot matching an equal SOL purchase after launch confirms. The Match Engine’s private signer stays sealed — the public path above is what you can audit here.
- ✓Server-authoritative RNG (randomInt, no modulo bias)
- ✓Payment signature consumed once (replay lock)
- ✓Fee payer must sign; treasury must receive ≥ fee
- ✓Match size capped in lamports at ticket time (≤ 1 SOL)
- ✓Match runs once per ticket (status → MATCHED)
- ✓Demo reels ≠ live odds (show ~1/3 · live ~10%)
1) Published odds
Live jackpot = WIN_RATE_BPS / 10_000. Default 1000 → exactly 10%. Uses crypto.randomInt so the selection is uniform.
// src/services/spin.ts — uniform jackpot odds
import { randomInt } from "node:crypto";
export function rollSpinOutcome() {
const n = randomInt(10_000); // [0, 10000)
const win = n < winRateBps(); // 1000 bps = exactly 10%
if (win) {
return { win: true, reels: ["🚀", "🚀", "🚀"] as const };
}
let reels: [string, string, string];
do {
reels = [
SYMBOLS[randomInt(SYMBOLS.length)]!,
SYMBOLS[randomInt(SYMBOLS.length)]!,
SYMBOLS[randomInt(SYMBOLS.length)]!,
];
} while (reels.every((s) => s === "🚀"));
return { win: false, reels };
}2) Fee → ticket
Payment signature is claimed once, then verified on-chain. Opening buy is clamped to lamports and stored on the ticket before any match can run.
// POST /api/spin/play — fee → roll → immutable ticket
const spinId = newSpinId();
const openingBuyLamports = clampOpeningBuyLamports(body.openingBuySol); // ≤ 1 SOL
const claimed = await markPaymentUsed(paymentSignature); // replay lock
if (!claimed) throw new Error("payment already used");
await verifyFeePayment({
signature: paymentSignature,
fromWallet: wallet, // must be a signer
feeWallet: quote.feeWallet, // treasury destination
minLamports: launchFeeLamports(),
});
const { win, reels } = rollSpinOutcome();
await saveTicket({
id: spinId,
wallet,
paymentSignature,
win,
reels,
openingBuyLamports,
maxMatchLamports: openingBuyLamports,
status: win ? "PAID_WIN" : "PAID_LOSS",
...
});
return { spinId, win, reels };// Fee verification checklist (server)
✓ tx found + meta.err === null (confirmed)
✓ fromWallet is a required signer
✓ feeWallet balance increased ≥ launchFeeLamports
✓ payer funded the transfer (sent ≥ fee)
✓ SystemProgram transfer when decodable
✓ payment age ≤ 30 minutes
✓ paymentSignature unique (KV spinpay:{sig} once)3) Launch + equal SOL match
Slot matches your opening buy with an equal SOL purchase after launch confirms. The second buy hits a later point on the curve — we never claim “double the tokens.” Match is one-shot per ticket.
// Match Engine — equal SOL after create confirms (sealed)
// Spends ticket.maxMatchLamports only — never client “100 SOL” claims.
if (ticket.matchSignature || ticket.status === "MATCHED") {
throw new Error("already matched"); // replay lock
}
await assertCreateConfirmed(createSignature);
assertMintMatchesTicket(mint, ticket.mint);
const lamportsIn = min(ticket.maxMatchLamports, MAX_OPENING_BUY_LAMPORTS);
const result = await MatchEngine.execute({
mint,
lamportsIn, // equal SOL purchase
venue: "pump.fun",
});
ticket.status = "MATCHED";
ticket.matchSignature = result.signature;
await saveTicket(ticket);
// Wording: Slot matches your opening buy with an equal SOL purchase
// after your launch confirms — not “double the tokens on the curve.”Yes it does — spin when you’re ready.
Live launchpad: 10% after the 0.05 SOL treasury fee. Demo on Home is show-only.
← Back to How It Works