How It Works
Boom Doom runs a continuous sequence of 30-second prediction rounds on-chain. Each round has a fixed open window, a locked price snapshot, and a final close price that determines winners.
Game Mechanics
At its core, Boom Doom is a binary prediction market: you pick a direction (BOOM for up, DOOM for down), stake SOL, and find out the result 30 seconds later.
Unlike pool-based prediction markets where winnings depend on how many others picked the losing side, Boom Doom uses a fixed payout model. Every winner receives exactly 1.9× their stake — regardless of how many others bet, or which direction they chose. Payouts are backed by the house liquidity in HouseVault (provided by the team).
DOOM = Doom = Down. A DOOM bet wins if the BTC/USD close price is strictly less than the lock price.
If close price equals lock price, bets are refunded.
Round Lifecycle
Every round progresses through four phases, each triggered by the
Keeper Bot calling executeRound() on-chain.
Phase 1 — Open (LIVE)
A new round starts with an open betting window. Players can submit
betMoon(epoch) or betDoom(epoch) transactions via the UserVault. The round
remains open until the keeper calls executeRound() for the first time in
that epoch.
Phase 2 — Lock
When the keeper calls executeRound(), the current round is locked. The
contract fetches the current BTC/USD price from the Pyth oracle and records it as
the lockPrice. No new bets are accepted after this point.
Simultaneously, the previous round is ended and settled.
Phase 3 — End & Settle
On the next executeRound() call (~30 seconds later), the contract records
the current price as the closePrice for the locked round. It compares
closePrice vs lockPrice and sets the round outcome:
| Condition | Outcome | Winners |
|---|---|---|
closePrice > lockPrice |
BOOM wins | All Moon bettors receive 1.9× stake |
closePrice < lockPrice |
DOOM wins | All Doom bettors receive 1.9× stake |
closePrice == lockPrice |
PUSH | All bettors receive their stake back (refund) |
Genesis Rounds
When the game first starts (or restarts after being paused), the keeper must call two special functions before the main loop begins:
genesisStartRound()— opens the very first roundgenesisLockRound(priceUpdate)— locks the first round with a seed price
After that, the regular executeRound() loop takes over indefinitely.
Price Oracle
Ticker Tok uses the Pyth Network BTC/USD price feed as its on-chain oracle. Pyth provides a pull-based model: rather than the oracle pushing prices on-chain continuously, the caller provides a signed price update (a price attestation) in the transaction itself.
The keeper bot fetches these attestations from the Pyth Hermes WebSocket service
and passes them as bytes[] calldata priceUpdate to every
executeRound() call. The contract verifies the attestation on-chain
before accepting the price.
| Parameter | Value |
|---|---|
| Feed | BTC/USD (Pyth Insights) |
| Feed ID | 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43 |
| Max staleness | 60 seconds |
| Hermes endpoint | wss://hermes.pyth.network/ws |
| Update frequency | Up to 20 Hz |
Frontend Price Feed
The frontend independently streams prices for the live chart using a three-tier fallback strategy:
- Pyth Hermes WebSocket — real-time feed at up to 20 Hz with EMA smoothing for chart rendering
- Pyth REST polling — falls back to polling every 1 second if WebSocket drops
- Simulation — synthetic price walk if both feeds are unavailable (useful in dev/Sim Mode)
Payouts & Winnings
Fixed Multiplier Model
Ticker Tok uses a fixed 1.9× multiplier (also written as 19000 basis points in the contract). This differs from pool-based designs where payout depends on how much is on the losing side.
Vault-Backed Payouts
When a player wins and calls claim(epoch), the game program
sends the payout (stake × 1.9 SOL) to the player's UserVault. When a player loses,
their stake is sent to the house vault as house profit.
Player Wins
The player is entitled to stake × 1.9 SOL. The game program sends it to their UserVault when they call claim(epoch); until then the amount stays in the contract.
Player Loses
Player's stake (minus fees) is routed to the house vault as house profit.
Push (Tie)
Player's stake is returned in full. No profit or loss to the vault.
Claiming
Winners must call claim(epoch) to receive their payout. Unclaimed winnings remain in the contract indefinitely.
Betting Limits & Fees
| Limit | Value | Notes |
|---|---|---|
| Minimum bet | 0.001 SOL | Bet amount only, does not include fees |
| Maximum bet | Dynamic | No fixed cap. Limit is set by House Vault balance — the more SOL in the vault, the higher the allowed max. The app shows the current max bet (e.g. in the betting card). |
| Keeper fee | 0.0005 SOL | Paid at bet time, goes to keeper bot |
| Treasury fee | 0.001 SOL | Paid at bet time, goes to platform |
| Total fees per bet | 0.0015 SOL | Added on top of bet amount |
| One bet per round | Yes | One address can only bet once per epoch |
| Direction change | No | Once placed, a bet cannot be changed or cancelled |