V1 — Provably fair, backend-authoritative
LiveThe marketplace, commit-reveal fairness, the Floor + Dynamic Ceiling payout math, real on-chain payouts, and buyback + burn are live today. Every outcome is verifiable on the Provably Fair page.
V2 — Fully on-chain smart contract
In progressThe entire settlement engine moves into a Solana program, so the rules are enforced by code on-chain — no server trust at all. In development and pending audit (see below).
Referral rewards + community
PlannedOn-chain referrals paying a permanent 3% of every box your invitees open, a HODLER tier for $LOOTBOX holders, and more — shipping alongside V2.
The whole engine, enforced by a Solana smart contract
In V2, opening a box is a program instruction, not a server call. The same commit-reveal fairness and the same Floor + Dynamic Ceiling math you can already verify today become rules the chain enforces. The reserve lives in a program-owned vault (a PDA), so a payout can never exceed what the pool holds — insolvency becomes impossible at the protocol level, not just by policy.
How an open works on-chain
- 1. Commit. The program stores a hash of a secret seed for the open, before anyone pays.
- 2. Pay.The player pays the box price into the pool's reserve vault; the recent slot hash is captured as extra, unpredictable entropy.
- 3. Reveal & settle. The seed is revealed; the program checks it matches the commit, derives the outcome from keccak(seed ‖ payer ‖ slot_hash), enforces the floor and solvency, pays the player their memecoin, and accrues the buyback + burn and referral shares — all atomically.
A trimmed draft of the Anchor program (Rust). This is a work in progress published for transparency and review — it is not yet deployed:
use anchor_lang::prelude::*;
use anchor_lang::solana_program::keccak;
use anchor_spl::token_interface::{self, Mint, TokenAccount, TokenInterface, TransferChecked};
declare_id!("Lootbox1111111111111111111111111111111111");
// Fixed, published economics — mirrors the audited off-chain model.
const FLOOR_BPS: u16 = 4_000; // 40% floor (you never receive less)
const RTP_MIN_BPS: u16 = 8_200; // 82% \
const RTP_MAX_BPS: u16 = 9_000; // 90% > return-to-player band
const RTP_CAP_BPS: u16 = 9_300; // 93% / hard cap, never exceeded
const P_JACKPOT_BPS: u16 = 120; // 1.2% jackpot probability
const REFERRAL_BPS: u16 = 300; // 3% permanent referral fee
const TARGET_BUFFER: u64 = 5 * LAMPORTS_PER_SOL;
#[program]
pub mod lootify {
use super::*;
/// Per-open, before payment: the pool authority commits to a seed hash.
pub fn commit_open(ctx: Context<CommitOpen>, commit: [u8; 32]) -> Result<()> {
let t = &mut ctx.accounts.ticket;
t.pool = ctx.accounts.pool.key();
t.payer = ctx.accounts.payer.key();
t.commit = commit;
t.status = Status::Committed;
Ok(())
}
/// Player pays the box price into the reserve vault; capture slot entropy.
pub fn pay_open(ctx: Context<PayOpen>, price: u64) -> Result<()> {
let t = &mut ctx.accounts.ticket;
require!(t.status == Status::Committed, LootErr::BadState);
require!(price >= ctx.accounts.pool.min_price, LootErr::PriceTooLow);
// Move SOL: player -> reserve vault (a program-owned PDA).
anchor_lang::system_program::transfer(
ctx.accounts.transfer_ctx(), price,
)?;
t.price = price;
t.slot_hash = ctx.accounts.recent_slothashes.data()[0..32].try_into().unwrap();
t.status = Status::Paid;
Ok(())
}
/// Reveal the seed and settle atomically: verify, roll, enforce floor +
/// solvency, pay out, accrue buyback/burn + referral.
pub fn reveal_and_settle(ctx: Context<RevealAndSettle>, seed: [u8; 32]) -> Result<()> {
let t = &mut ctx.accounts.ticket;
require!(t.status == Status::Paid, LootErr::BadState);
require!(keccak::hash(&seed).0 == t.commit, LootErr::BadReveal); // commit-reveal
// Deterministic, reproducible draw stream.
let mut rng = Rng::new(&seed, &t.payer, &t.slot_hash);
let reserve = ctx.accounts.reserve.lamports();
let target = TARGET_BUFFER;
// Dynamic RTP target from reserve health, capped.
let health = (reserve.min(target) * 10_000 / target) as u16;
let rtp = (RTP_MIN_BPS + (RTP_MAX_BPS - RTP_MIN_BPS) * health / 10_000)
.min(RTP_CAP_BPS);
// Draw the multiplier (jackpot vs. floor-anchored exponential).
let mult_bps = draw_multiplier(&mut rng, rtp);
// Floor + solvency: never below 40%, never more than the reserve holds.
let mut payout = (t.price as u128 * mult_bps as u128 / 10_000) as u64;
payout = payout.max(t.price * FLOOR_BPS as u64 / 10_000);
payout = payout.min(reserve);
// Pay the player their memecoin from the reserve, via CPI.
token_interface::transfer_checked(ctx.accounts.payout_ctx(), payout, ctx.accounts.mint.decimals)?;
// On a loss, accrue the buyback+burn split and the referral 3%.
if payout < t.price {
let loss = t.price - payout;
ctx.accounts.pool.accrue_burn(loss * (10_000 - REFERRAL_BPS) as u64 / 10_000);
if let Some(r) = t.referrer { credit_referral(r, loss * REFERRAL_BPS as u64 / 10_000)?; }
}
t.payout = payout;
t.status = Status::Settled;
emit!(BoxOpened { pool: t.pool, payer: t.payer, price: t.price, payout });
Ok(())
}
}
#[account]
pub struct Ticket {
pub pool: Pubkey,
pub payer: Pubkey,
pub referrer: Option<Pubkey>,
pub commit: [u8; 32],
pub slot_hash: [u8; 32],
pub price: u64,
pub payout: u64,
pub status: Status,
}
#[error_code]
pub enum LootErr {
#[msg("reveal does not match the commit")] BadReveal,
#[msg("ticket is in the wrong state")] BadState,
#[msg("price below the pool minimum")] PriceTooLow,
}The full program adds pool creation, the reserve vault PDA, the buyback/burn keeper, and the referral ledger. The randomness and payout math are byte-for-byte the model you can already verify on the Provably Fair page — V2 simply moves the referee on-chain.
On-chain money code must be audited first
A smart contract that holds reserves and pays out is irreversible: a single bug can drain a pool with no way to claw it back. That is why we are not rushing it on-chain. Two things gate the launch:
- A professional security audit. Independent auditors need time to review every instruction, and a serious audit is a real, upfront cost.
- Funding. We need to fund that audit and seed the on-chain reserves. Until then, the current V1 engine is already provably fair, lets us build a public track record, and moves real payouts and burns today.
We would rather ship a slower, safe V2 than a fast, unaudited one.
Are you a developer? Help us ship it and get rewarded
To support the audit and harden the program before launch, we run an open bounty. If you know Rust, Anchor, or Solana security: review the draft above, find issues, stress the economics, or propose improvements. Valid findings and meaningful contributions are rewarded. Every extra pair of expert eyes gets V2 to a safe launch sooner.
Referral rewards — earn 3% forever
V2 introduces an on-chain referral system. Invite others with your link, and you earn a permanent 3% fee from every box they ever open — paid out automatically by the program, for as long as they keep playing. No caps, no expiry. The more you grow the ecosystem, the more you earn.
$LOOTBOX holders get first access to referrals — see the HODLER tier