PropStock

PropStock / working paper

v1 · 2026-09-01 · Robinhood Chain 4663

A prop desk exam, paid in Bitcoin

Satoshi built the cash. We built the exam.

01The claim

PropStock is a prop-trading challenge on Robinhood Chain. You buy a challenge account NFT in $ECS, trade a virtual $5,000 account against Chainlink stock feeds under rules calibrated to kill roughly nine accounts in ten, and if you graduate you split a cbBTC prize pool funded entirely by the coin's trading fees. Ticket money never funds payouts; the pool contract cannot pay out more than it holds and has no owner withdrawal for its Bitcoin.

02The account

A challenge account is an ERC-721 ticket. Minting pulls the price in $ECS straight to the treasury; the contract itself never holds ticket money. Every token starts Fresh at tier 1: a virtual $5,000 account tracked in USD fixed point (1e8) by the rule engine. The money is not real. The cbBTC you claim if you graduate is.

Locking 2 to 5 Fresh tier-1 tokens burns them and mints one merged token of tier N, an N x $5,000 account. Only never-traded tokens can merge, and the hard cap is tier 5: a $25,000 account. The cap is arithmetic, not policy. Each account's total weekly payout is capped at 10% of the epoch pool, so the expected value of size beyond tier 5 is exactly zero.

The lifecycle is a one-way street: Fresh to Active at the first accepted order, then Active to exactly one of Graduated, Dead or Expired. All three are terminal. The referee is the only address that can write these transitions on-chain.

03The rulebook

The constants were not designed on a whiteboard. They were calibrated by Monte Carlo on real 5-minute NVDA, TSLA and SPY bars: 12,000 simulated accounts trading under candidate rule sets until the pass rate landed at roughly 11%. Then the constants were locked. We own that number instead of hiding it; the landing page runs the same calibration live, in public, until an account dies.

RuleValue
AccountVirtual $5,000 per tier (USD 1e8 fixed point)
Phase 1+10% of the phase base
Phase 2+5% of the new base
Max drawdownTrailing 8% below the equity high-water mark; the floor never rises above the phase base
Daily loss-5% vs day-start equity: positions closed, locked until the next UTC day
Taker fee2.5 bps (0.025%) of notional, per side
Max leverage100x
Expiry30 calendar days from account start
Trading windowOnly while the oracle is fresh and the market is open; fills at the next oracle tick

The fee is the quiet killer. At 100x, a round trip costs 5 bps of $500,000 notional: $250, five percent of the whole account. That is deliberate. Fees paid feed the leaderboard weight, and reckless churn feeds the floor.

04The money loop

Two streams of money exist and they never touch.

Stream one: tickets. Mint payments in $ECS go straight from the buyer to the treasury. They fund operations. They never enter the prize pool, and no code path exists that could move them there.

Stream two: fees. $ECS trades on its own pool, and the coin's creator fees accrue in ETH at the Pons fee escrow. The splitter claims them on a cooldown and cuts the flow in half: 50% is swapped to cbBTC on the canonical pool and transferred to the PrizePool contract; the remainder buys $ECS on the coin's own pool and sends it to the dead address. Both destinations are immutable constructor parameters. The operator can pull the trigger; nobody can redirect the barrel.

The consequence is the sentence we repeat everywhere: payouts come only from the fee pool, tickets never fund payouts, and the pool can never owe more than it holds. There is no yield promise, no PnL owed, no bank run to have.

05Settlement

Time is cut into weekly epochs. When an epoch closes, the engine collects every account that graduated during it and splits that week's pool:

  • 60% equally among all graduates of the epoch.
  • 40% by leaderboard weight w = sqrt(profit x feesPaid), both in USD 1e8. Profit alone is not enough; you must have actually traded.
  • Each account's combined payout is capped at 10% of the whole epoch pool. Overflow and rounding dust roll to the next epoch. A lone graduate receives exactly pool/10.

The result is encoded as an OpenZeppelin standard merkle tree over (epochId, claimant, amount) and the root is posted on-chain with the epoch total, which must fit inside the pool's free balance. One root per epoch, immutable once posted. Winners claim directly from the contract with their proof, once per epoch per address. The per-epoch trade log that produced the result is published alongside the claim file, so anyone can recompute the tree from the raw fills.

06The machine

One server process is the sole writer of account state. Inside it, the roles are strict:

HarvesterClaims creator fees from the escrow, swaps and splits them: cbBTC to the pool, $ECS to the burn. Cooldown and per-harvest caps bound every run.
BookkeeperPolls each Chainlink aggregator and applies every tick to every account with a position or a pending order, then persists. Restarts lose nothing.
WatchmanFollows ChallengeNFT transfer logs to keep token ownership current, and gates trading on oracle freshness and NYSE regular hours.
RefereeThe engine's on-chain identity. Activates accounts at their first order and writes Graduated, Dead or Expired back to the NFT.
SettlerCloses each epoch: settlement math, merkle tree, root and total posted to the PrizePool.

Orders are signed messages, not transactions: no gas, but the server verifies the signature recovers the NFT owner. Every order fills at the next oracle tick after placement, never the tick you can see. Front-running the feed therefore earns nothing: by the time you observe a price, the earliest fill you can get is the one after it, and the oracle gate rejects orders whenever the feed is stale or the market is closed.

07Risks

The engine is centralized. So is every prop firm that has ever existed. The difference here is verifiability: the trade log is published per epoch, the claim tree can be recomputed from it, and the claims themselves are trustless against an immutable root. You still trust the engine to run the rules honestly between settlements.

The pool breathes with the coin. The pot accrues from $ECS trading fees and is held in cbBTC. Thin volume means a thin pool; a falling Bitcoin price shrinks the dollar value of winnings. Nothing is owed, so nothing can default, but nothing is guaranteed either.

Oracles freeze. Chainlink feeds go stale outside market hours and can hiccup inside them. The engine fails closed: stale feed, no fills. Your 30-day clock keeps running through weekends and freezes alike. That is a real cost and it is priced into the calibration.

08Addresses

Everything below is on Robinhood Chain, chainId 4663. This paper describes only what exists; anything not yet deployed is marked as such and this table is updated at launch.

ContractAddress
cbBTC0xCEC185eB182c47d1bA1EFc84e6959e18cd620Be4
Pons V2FeeEscrow0xd3AFEB2a57f70eF218Aa82451c51B2fb0416Ac9e
Pons LaunchFactory0x7eD598BcEf8bd9Edd8C97A195C6d13f40801EC7e
UniversalRouter0x8876789976dEcBfCbBbe364623C63652db8C0904
v4 PoolManager0x8366a39CC670B4001A1121B8F6A443A643e40951
Permit20x000000000022D473030F116dDEE9F6B43aC78BA3
$ECSNot yet deployed
ChallengeNFTNot yet deployed
PrizePoolNot yet deployed
PrizeSplitterNot yet deployed

Rulebook constants and the payout formula locked 2026-09-01.

Take the challenge