


Win the entire SOL pot.
Funded by creator fees.
90% of our received creator fees goes to the pot.
per spin1 in 100
SOLSLOT


Funded by creator fees.
90% of our received creator fees goes to the pot.






Your full entry, saved to claim.
No entry tokens burn on a match.
79% chance of no match — no reward; 50,000 tokens burned.Same odds on every spin.

Opening the playground…
Pull down & release to spin
One approval per pack · About 0.00185 SOL in randomness and network costs, for 1, 5 or 10 spins.
One approval per pack. Confirmed results play back to back.
Entry is held until settlement. Matching results return the full entry without burning tokens; jackpot and no-match results burn 50,000.
The jackpot grows from creator fees we collect. Entries wait until the pot has SOL.
90% of creator fees we actually collect from this pump.fun coin and its canonical PumpSwap pool fund the jackpot; 10% goes to treasury. Pump sets the fee schedule, which can change. Unrelated pools do not fund this game.
of our received creator fees goes to the jackpot.The remaining 10% funds the treasury and operating costs.
| Spin | Result | Draw number | Tokens burned | Rewards earned | Jackpot paid |
|---|---|---|---|---|---|
| Your first spin is waiting. Every result will appear here. | |||||
Claim your earned tokens and SOL. Unused prepaid credits can be returned from Play.
Any other triple returns your full entry.

×3 = 50,000 backBoth token and SOL rewards stay reserved until claimed.
Confirmed total burned by the deployed game.
The odds, the costs, and the code behind each result.
THE POSSIBILITIES
Match three SolSlot logos to win the reserved pot.
Match three Pepe, Doge, Bitcoin or pump.fun symbols. Each match has a 5% chance.
Different symbols mean no reward for this spin.
The same odds apply to every played spin. Previous results do not improve the next spin’s odds. Consolation matches return the full entry with no token burn. SOL transaction and randomness costs are separate from token rewards.
FROM CLICK TO CONFETTI
Your entries are reserved when the transaction confirms. Results are not known when you approve.
The program uses one oracle result to calculate the pack’s draws and save its rewards.
Animations show the settled results. Refreshing skips playback and restores your on-chain rewards.
WHERE THE VALUE GOES
This split applies to creator fees we actually collect from this pump.fun coin and its canonical PumpSwap pool. Pump sets the fee schedule. Protocol fees, LP fees and trades through unrelated pools are not our revenue.
The jackpot must be funded before entries open. Creator fees arriving after a pack is accepted fund later play.
Pump fee documentation ↗About 0.00185 SOL extra per pack for randomness and network costs, whether you choose 1, 5 or 10 spins.
ORAO charges 0.0005 SOL per pack. Its 0.0013462 SOL retained request-account deposit cannot be recovered. A further 0.00310896 SOL temporary deposit returns to your wallet when randomness is fulfilled.
Network fees and any first-time player account deposit are additional. The estimate can change with network fees. Returning your token entry does not refund these SOL costs.
LOOK UNDER THE HOOD
ORAO supplies verifiable randomness on Solana. The game checks the fulfilled request on chain, then turns that result into a number from 1 to 400. The reels display the result; they do not choose it.
The program checks that the fulfilled request is the one reserved for the accepted pack. A known result cannot be used to buy a new entry.
Rejection sampling skips the tiny remainder that would give some numbers extra chances. It reads more bytes from the same result, never a new oracle draw.
For a pack, the program hashes the oracle result with the game address, pack nonce, seed slot and spin index. Outcomes use the fixed ranges shown above.
Checks the oracle owner, account format, player and request address. All 64 bytes of the fulfilled result are hashed into the game’s randomness input.
pub fn read_result(account:&AccountInfo,client:&Pubkey,fulfilled:bool)->Result<([u8;32],Option<[u8;32]>),ProgramError>{
require(account.owner==&ID)?;let d=account.try_borrow_data()?;
require(d.len()>=73 && d[..8]==RESULT_DISC && d[8]<=1 && d[9..41]==client.to_bytes())?;
let seed:[u8;32]=d[41..73].try_into().unwrap();require(account.key==&request_address(&seed))?;
if fulfilled {
require(d[8]==1 && d.len()==137)?;
// Hash all 64 quorum bytes into the game's fixed 32-byte randomness input.
Ok((seed,Some(solana_program::hash::hashv(&[b"solpot:orao:v1",&d[73..137]]).to_bytes())))
}else{
require(d[8]==0 && d.len()>=77)?;
let count=u32::from_le_bytes(d[73..77].try_into().unwrap()) as usize;
require(count==0 && d.len()==749)?;Ok((seed,None))
}
}Read source file ↗The largest multiple of 400 below 2³² is 4,294,967,200. The remaining 96 values are skipped, avoiding modulo bias.
pub fn draw_from_word(word: u32) -> Option<u16> {
const LIMIT: u64 = (1u64 << 32) / 400 * 400;
if u64::from(word) >= LIMIT { None } else { Some((word % 400 + 1) as u16) }
}Read source file ↗One-spin entries read the authenticated bytes directly. Multi-spin packs use a separate hash for each spin; retry counters only reuse the same oracle result.
fn batch_draws(bytes:&[u8;32],game:&Pubkey,nonce:u64,seed_slot:u64,count:u8)->Result<[u16;10],ProgramError>{
require((1..=10).contains(&count))?;
let mut draws=[0u16;10];
for index in 0..count {
if count==1 { draws[0]=bytes.chunks_exact(4).find_map(|b|draw_from_word(u32::from_le_bytes(b.try_into().unwrap()))).ok_or(ProgramError::InvalidAccountData)?; break; }
let mut draw=None;
for counter in 0..16u8 {
let digest=solana_program::hash::hashv(&[b"solpot:batch:v1",bytes,game.as_ref(),&nonce.to_le_bytes(),&seed_slot.to_le_bytes(),&[index,counter]]).to_bytes();
draw=digest.chunks_exact(4).find_map(|b|draw_from_word(u32::from_le_bytes(b.try_into().unwrap())));
if draw.is_some(){break;}
}
draws[usize::from(index)]=draw.ok_or(ProgramError::InvalidAccountData)?;
}
Ok(draws)
}Read source file ↗Numbers 1–4 win the reserved SOL pot. Numbers 5–84 return tokens. The program records rewards, burns and any unused pack credits together.
pub fn settle_batch_verified(&mut self, player: &mut Player, nonce: u64, request: [u8;32], numbers: &[u16]) -> Result<(Settlement,u8)> {
let spin = self.matching_spin(player, nonce, request)?;
let count = self.pending_count();
if numbers.len()!=usize::from(count) || numbers.iter().any(|n| !(1..=400).contains(n)) { return Err(Error::InvalidDraw); }
let mut tokens=0; let mut sol=0; let mut burned=0; let mut played=0u8;
for number in numbers {
let reward=if (5..=84).contains(number) { self.consolation() } else { 0 };
tokens=add(tokens,reward)?; burned=add(burned,self.entry-reward)?; played+=1;
if *number<=4 { sol=spin.locked_pot; break; }
}
let unused=self.entry.checked_mul(u64::from(count-played)).ok_or(Error::Overflow)?;
let new_pot=add(self.pot,if sol==0 {spin.locked_pot} else {0})?;
let new_tokens=add(player.token_rewards,tokens)?; let new_sol=add(player.sol_rewards,sol)?;
let token_liability=add(self.token_liability,tokens)?; let sol_liability=add(self.sol_liability,sol)?;
let total_burned=add(self.burned,burned)?; let prepaid=add(player.prepaid,unused)?;
let prepaid_liability=add(self.prepaid_liability,unused)?;
self.pot=new_pot; player.token_rewards=new_tokens; player.sol_rewards=new_sol; player.prepaid=prepaid;
self.token_liability=token_liability; self.sol_liability=sol_liability; self.prepaid_liability=prepaid_liability;
self.burned=total_burned; self.pending=None; self.pending_count=0;
Ok((Settlement{burned,tokens,sol},played))
}Read source file ↗The code above is extracted directly from this release’s Rust source. ORAO’s program verifies its oracle responses; SolSlot checks the returned account and calculates payouts. Source files and hashes support inspection, but are not an independent audit or reproducible-build proof.
90583a2f57289428c628d390652007ed97699c2d97f6cd613483a07ea6793a2dmainnet-orao