Stock Roast protocol documentation.
This document describes the full product and protocol design. Live deployment details will be published at launch.
Introduction
Stock Roast is an on-chain protocol where players lock a stake each round and pick a heat level - the minimum round multiplier they need to win. After the stake window closes, a single round multiplier (the heat point) is drawn from verified public randomness. If it reaches your heat, you COOKED (win). If not, you BURNED (lose).
Tokenised stock certificates heat up during the reveal - dramatizing a result already fixed on-chain before the animation starts. Wins settle as tokenized stock on Robinhood Chain - swapped via Uniswap, not paid as plain ETH.
Verifiable randomness, stock settlement, and a distinct reveal spectacle - together. We are trying to push on-chain culture forward.
Built for Robinhood Chain, Stock Roast keeps the timed-round loop familiar to players of other games - one shared outcome, instant resolution - while replacing opaque server rolls with verifiable public randomness and routing wins through a themed stock settlement layer.
| Other games | Stock Roast |
|---|---|
| Server picks multiplier in secret | Multiplier from drand after stakes close |
| Cash out mid-round | Pick heat upfront; one shared round multiplier |
| ETH in / ETH out | Wins settle as tokenized stock via Uniswap (ETH fallback) |
| Trust the operator | Verify beacon + formula on-chain |
Design principles
- Outcome before animation. The multiplier exists on-chain before the reveal. The UI never shows live odds.
- Untrusted operators. Anyone can relay randomness; contracts verify signatures.
- Player funds first. Withdrawals remain available even when the game is paused.
- Win-only fees. Protocol fees apply to gross winnings - never to losses or refunds.
The game
In Stock Roast, you commit upfront to a heat level (2× through 10×). One shared round multiplier is drawn for everyone - you do not cash out mid-round.
| Concept | Meaning |
|---|---|
| Round | Fixed time window on a global grid. One stake per player per round. |
| Stake | Native ETH locked from your in-game balance. |
| Heat level | Win threshold (2-10×). Round multiplier must reach this. |
| Round multiplier | The drawn heat point - same for all players. |
| COOKED | Win - round multiplier ≥ your heat. |
| BURNED | Loss - round multiplier below your heat. |
Win: reveal crosses your heat with green. Loss: chart peaks below heat and crushes. Payout size comes from a fixed table by heat - not stake × heat.
Round lifecycle
Rounds run on an absolute time grid. Each round id is derived from timestamp - no off-chain scheduler.
During the stake window you never see a rising multiplier - the randomness input does not exist yet.
Timing model
Round ids are timestamp ÷ roundDuration. All phase boundaries derive from
block.timestamp - no off-chain scheduler decides when a round starts or ends.
| Parameter | Role |
|---|---|
| Round duration | Fixed grid length (e.g. 75s). New round id every interval. |
| Stake window | First portion of the round - only time you can lock a stake. |
| Drand buffer | Gap after stake close before the eligible beacon round - ensures randomness does not exist while the stake window is open. |
| Refund timeout | If no valid beacon is relayed within the limit, anyone can refund all stakes for that round. |
Absolute grid - players worldwide share the same round id at the same moment.
| Phase | On-chain | Player can |
|---|---|---|
| Open | Accepting stakes | Deposit (if unpaused), lock stake |
| Sealed | Multiplier unknown | Wait |
| Settled | Multiplier stored | Watch reveal, claim when ready |
| Refunded | Beacon timeout | Claim full stake return |
Player journey
| Balance | Location | Purpose |
|---|---|---|
| Wallet | Your address | Source for deposits; destination for withdrawals |
| In-game | Game contract | Only balance you can stake from |
- Connect a wallet on desktop (extension or WalletConnect).
- Deposit native ETH in Robinhood Chain into in-game balance.
- Lock stake during the stake window - pick heat 2-10.
- Watch reveal - certificates heat toward the on-chain heat point.
- Claim tokenized stock on win, or refund when applicable.
- Withdraw in-game ETH anytime - even if paused.
Deposit creates in-game balance; only that balance can be staked.
Rules
- One stake per wallet per round.
- Claim unclaimed prior rounds before a new stake.
- Deposits require unpaused game; withdrawals do not.
- Stale chain data disables staking until refreshed.
Heat levels & payouts
Higher heat needs a higher round multiplier to win - but pays more gross if you COOKED. Higher risk, higher reward.
| Heat | Win if ≥ | Payout mult | Win fee | Gross (0.002 ETH stake) |
|---|---|---|---|---|
| 2 | 2.00× | 1.079× | 1.00% | 0.00216 ETH |
| 3 | 3.00× | 1.274× | 1.05% | 0.00255 ETH |
| 4 | 4.00× | 1.440× | 1.10% | 0.00288 ETH |
| 5 | 5.00× | 1.659× | 1.22% | 0.00332 ETH |
| 6 | 6.00× | 1.962× | 1.35% | 0.00392 ETH |
| 7 | 7.00× | 2.368× | 1.50% | 0.00474 ETH |
| 8 | 8.00× | 3.035× | 1.70% | 0.00607 ETH |
| 9 | 9.00× | 4.300× | 2.20% | 0.00860 ETH |
| 10 | 10.00× | 7.000× | 3.00% | 0.01400 ETH |
Payout multiplier is fixed per heat in the on-chain table (StockRoastMath). Win fee
scales linearly from 1% at heat 2 to 3% at heat 10 based on the payout tier - never taken from
your stake on a loss.
edgeBps), not as an upfront cut when you lock a stake.
Gross payout comes from a fixed on-chain table, not stake × heat. House edge is baked into the multiplier curve - not an upfront cut from your stake.
Win-only service fee (1-3% of gross, gradated by heat). No fee on loss or refund.
Randomness & provably fair
The round multiplier is not chosen by Stock Roast. It comes from drand - a public beacon published on a fixed schedule after stakes close.
- Stakes close. Multiplier does not exist.
- Beacon published on drand schedule.
- Anyone relays on-chain. Verifier checks BLS signature - relayer untrusted.
- Multiplier computed from hashed beacon via deterministic on-chain formula.
- Reveal animates the stored value.
Drand quicknet
Stock Roast uses drand quicknet - a public randomness beacon with ~3 second cadence and BLS signatures verifiable on-chain via EIP-2537 precompiles. The eligible drand round number is derived from stake-close time plus the on-chain buffer.
Beacon round is computed from chain time - not chosen by operators.
System architecture
The web app is static - it reads chain state and submits user-signed transactions. Settlement assistance runs off-chain but cannot forge outcomes.
Game logic, payout conversion, and client presentation are separate layers.
| Component | Role |
|---|---|
| Game engine | Balances, stakes, rounds, settlement, claims, bankroll, pause |
| Math module | Multiplier curve, payout table, win-fee gradation |
| Drand verifier | Validates beacon before settlement |
| Stock router | Swaps net win ETH into tokenized stock via Uniswap |
| Fee contract | Separate on-chain contract that receives collected win fees |
| Wrapped native | Wrapped ETH paired against tokenized stocks in Uniswap pools |
| Uniswap pool | WNATIVE / tokenized-stock liquidity per ticker |
| Tokenized stock | On-chain ERC-20 representing a listed equity on Robinhood Chain |
| Keeper | Relays beacons, batch payouts, stale refunds |
Stock settlement
Wins route through a stock payout layer into tokenized stocks on Robinhood Chain - on-chain ERC-20s backed by real listed equities. Each round is assigned one ticker from a static list of top-traded tokenized stocks on Robinhood Chain. The certificate theme matches that ticker; settlement is always the same tokenized asset for every player in the round.
- Round opens with an assigned stock ticker.
- On COOKED → gross payout from the heat table; win fee deducted.
- Net ETH is sent to the stock router, wrapped, and swapped on Uniswap.
- Claim delivers tokenized stock to your wallet.
If the Uniswap swap fails or liquidity is insufficient, net ETH is credited in-game - you are not left empty-handed.
Uniswap swap path
The game engine resolves wins in ETH terms (gross table minus win fee). Conversion into stock happens in a separate payout module so round logic stays independent of AMM pricing:
- Game contract sends net ETH to the stock payout router (only the game can call it).
- Router wraps native ETH into wrapped native currency (WNATIVE).
- Router swaps WNATIVE → tokenized stock through the configured Uniswap V2-style pool for that ticker.
- Tokenized stock is delivered to your wallet on claim.
Each ticker has its own WNATIVE / tokenized-stock pool on Uniswap. The router quotes expected output, applies an on-chain slippage limit, and reverts if the pool cannot fill at that bound. Pool liquidity and market price determine how many stock tokens you receive for a given win - the game table fixes your gross ETH payout; the swap rate is live AMM math.
Payout mode is frozen per round at creation. Refunds always return full stake in ETH.
Supported stocks
Stock Roast uses a fixed whitelist - the most actively traded tokenized stocks on Robinhood Chain. The list is set at deployment and does not change round to round; only which name is picked varies.
One ticker is assigned per round. Selection is deterministic from the round id (hash modulo list length), so the payout stock is fixed before anyone stakes and every player sees the same certificate theme for that round. The exact tickers and list size will be published at launch.
Each whitelisted ticker must have a wired Uniswap pool and sufficient liquidity before it can appear in rotation. Adding or removing names requires a contract configuration update - not a live UI toggle.
Fees & bankroll
Service fees apply only on wins - a gradated 1-3% of gross payout by heat level. Losses and refunds pay no fee. Your full stake is always at risk on a loss; the fee is never taken upfront when you lock a stake.
Same model as the in-app Stats diagram - public steps only; downstream fee utility is not published yet.
| Path | Source | Destination |
|---|---|---|
| Loss stake | Player stake on BURNED | Game bankroll - backs future winner payouts |
| Win fee | 1-3% of gross payout | Accrued in the game contract, then collected to a separate fee contract |
| Win principal | Net after fee | Stock router (or ETH fallback) |
| Refund | Full stake | Returned to in-game balance - no fee |
Proof of bankroll
The bankroll is the ETH inside the game contract that backs winner payouts, separate from player in-game balances and reserved payouts. Losses and external funding grow it; stock swaps draw from it. The Stats view highlights bankroll size, fees collected, and stocks purchased - the same public metrics shown in the money-flow diagram.
Fee collection
Win fees accrue inside the game contract as rounds settle. They are kept separate from the bankroll and player balances. When enough has accumulated, anyone can trigger a withdrawal that sends the batch to a dedicated fee contract - a separate on-chain address from the game engine. At that point fees do not leave the protocol - they sit in the fee contract and will play an important role in the broader protocol economy. How that works is not public yet; details will be unveiled step by step.
Verification
Anyone can audit a settled round without trusting operators.
- Read the round record on-chain - multiplier and drand reference.
- Fetch the same drand beacon from the public network.
- Hash the signature with the contract's algorithm.
- Recompute the multiplier from the published formula.
- Compare to on-chain value - must match.
| Provably fair panel | Shows |
|---|---|
| Round / status | Previous round id and settlement state |
| Stake closes | When the stake window ended |
| Heat point | Round multiplier drawn |
| Drand round | Beacon reference for lookup |
| Stock | Round payout ticker |
Security
Trust model
- Randomness: drand + on-chain verification - operators cannot pick multipliers.
- Relayers: Anyone can submit beacons; invalid signatures revert.
- UI: Read-only sync - cannot alter stored multipliers.
Pause & upgrades
Administrative pause disables deposits and new stakes. Withdrawals always work. Logic upgrades use a timelocked proxy - players can withdraw during the wait.
Refund & exposure
If no beacon arrives within a timeout, anyone can trigger full stake refunds. Each round caps payout exposure as a fraction of bankroll (maxRoundExposureBps) so a single round cannot drain the entire bank.
Idempotency
Settlement, payout processing, and claims are designed so duplicate calls cannot double-pay or corrupt round state. Failed stock swaps fall back to ETH credit rather than leaving payouts stuck.
Upgrade safety
Logic lives behind a UUPS proxy with a timelocked upgrade path. Storage layout is append-only between versions. Players retain withdraw access throughout any upgrade delay.
Multiplier mathematics
The round multiplier is a deterministic function of verified drand randomness. The same beacon input always yields the same multiplier - on-chain and off-chain recomputation must agree.
- Hash the beacon.
randomness = sha256(drand signature) - Derive a tick.
tick = keccak256(randomness) mod 1_000_000 - Map tick to multiplier. Piecewise linear bands from 1.00× upward.
- Compare to heat. Win when
roundMultiplier ≥ heat × 100(basis points).
Lower multipliers occupy more tick space - higher heat wins are rarer. Curve cap is configured at deployment.
Some rounds resolve at exactly 1.00× - a valid outcome where every heat level above 2 BURNED. The curve is public; only the drand input is unknown until after the stake window.
UI & reveal experience
The web client is static - it reads chain state over RPC and submits wallet-signed transactions. It cannot influence the stored multiplier; the reveal is pure presentation.
Client-side phases
On-chain settlement can finish before the stage moves to reveal. The UI deliberately holds "stakes closed" until a dramatization window elapses, then plays certificate heat animation, then the stock pick sequence. These timings are client-only - the outcome is already fixed.
Reduced-motion mode skips animation; on-chain result unchanged.
Platform notes
- Desktop: Full wallet connect (browser extension or WalletConnect), deposit, stake, claim, withdraw.
- Mobile: Blocked for now - desktop with a wallet extension is required to play.
- Stale RPC: Staking disabled until fresh chain poll - prevents acting on outdated round phase.
- Skipped round: Connected but no stake → stage shows "No stake locked" during reveal.
Stage vocabulary
| Label | Meaning |
|---|---|
| COOKED | You won - round multiplier reached your heat |
| BURNED | You lost - multiplier below your heat |
| Heat point | The drawn round multiplier on the certificate trail |
| Win column | Fixed gross payout for your heat if COOKED |
Player operations
Every player action is a wallet-signed transaction to the game contract. No custodial backend holds funds.
| Action | Effect | When allowed |
|---|---|---|
deposit() | Move ETH from wallet → in-game balance | Game unpaused |
withdraw(amount) | Move in-game ETH → wallet | Always |
stake(roundId, amount, heat) | Lock stake for current round | Stake window open, one per wallet |
claim(roundId) | Receive stock tokens (or ETH fallback) for a win; or refund | After round settled/refunded |
Anyone can call settle(roundId, signature) with a valid drand beacon - the relayer
is not trusted. A keeper process typically batches settlement, payout processing, and stale
refunds, but players are never required to wait for it to claim.
Glossary
| Term | Definition |
|---|---|
| Bankroll | ETH backing winner payouts inside the game contract |
| BURNED | Loss - multiplier below your heat |
| COOKED | Win - multiplier at or above your heat |
| Heat level | Win threshold 2-10× and payout tier |
| Heat point | Round multiplier drawn for the round |
| In-game balance | ETH credited inside the game contract |
| Keeper | Off-chain process relaying beacons and batch ops |
| Stake | ETH locked for a round |
| Tokenized stock | On-chain ERC-20 equity token received on win via Uniswap |
| Stock whitelist | Static list of top-traded tokenized stocks on Robinhood Chain |
| Uniswap pool | WNATIVE / tokenized-stock pair used by the payout router |
| Win fee | Gradated fee on gross payout - wins only |
| Drand buffer | On-chain delay ensuring beacon eligibility after stake close |
| Edge bps | House edge parameter baked into multiplier distribution |
| Payout mode | ETH or STOCK - frozen per round at creation |
| Round id | timestamp / roundDuration - global grid identifier |
| WNATIVE | Wrapped native currency used as pool base asset |
| Provably fair panel | In-app readout of previous round audit fields |
Disclaimer
The Stock Roast web app is a visualization and interface for an autonomous on-chain protocol. Rounds, stakes, settlement, and payouts are enforced by smart contracts on Robinhood Chain - not by the website operator.
The app and this documentation are provided as is, without warranties of any kind. Displayed amounts, timings, animations, and copy may lag, simplify, or omit on-chain detail. Do not rely on the UI alone when deciding to stake or claim.
You are responsible for verifying everything yourself: contract addresses, transaction calldata, round state, multiplier derivation, fee math, and payout delivery. Use the chain explorer, contract source, and the verification steps in this documentation before trusting any outcome or balance shown in the app.