A risk protocol for NFTs on Robinhood Chain.
Retail produces order flow. Market Makers take a rebate on it.
On a trading floor in the metaverse, a crowd of Retail traders park their capital and produce a healthy supply of $FLOW. They sit together on The Exchange and are settled regularly by their owners to farm the $FLOW. With more $FLOW, the traders can open more positions. But on the other side of every order lurks something Retail would rather not think about — the Makers.
The Makers are hunting for Retail and their precious $FLOW. They will take it by any means the rulebook permits: internalizing an order before it ever reaches the book, or catching a trader on the way out and taking the whole position in slippage. So the brokerage struck a deal with the Makers — they pay a rebate on all $FLOW production. In return, the Makers do not touch Retail while it sits quietly on The Exchange.
But when Retail withdraws, or when a new order is routed, the Makers do not hold back.
The setting is not decoration. Robinhood earns real money selling its users' orders to the firms on the other side of them. That is the same structure as "prey pays predator a tax for not being eaten", and this game runs on Robinhood's own chain.
Order Flow is a fork of Wolf Game (Ethereum, November 2021), retargeted to Robinhood Chain.
This is a fork in the literal sense, not a re-implementation. The source was pulled from the verified mainnet contracts — 0xEB834ae7… (Woolf), 0x29205f25… (Barn), 0x8355DBE8… (WOOL),
0xae05B31E… (Traits) — and edited in place. After the rename to this setting, **87.2% of their
996 lines are byte-identical to what is deployed on Ethereum.** Every deviation carries a // FORK: comment naming what changed and why.
The rarity and alias tables are transcribed verbatim: all 36 rows, verified byte-for-byte against the original. The intended rarity curve is theirs.
What is not theirs: the randomness. That could not survive the move, and section 6 explains why.
| Token IDs | Cost | Paid in |
|---|---|---|
| 1 – 10,000 (Gen 0) | set at deploy | native ETH |
| 10,001 – 20,000 | 20,000 $FLOW | burned |
| 20,001 – 40,000 | 40,000 $FLOW | burned |
| 40,001 – 50,000 | 80,000 $FLOW | burned |
50,000 tokens, ever. Minting every Gen 1 token burns 1,800,000,000 $FLOW.
Each mint is 90% Retail, 10% Maker — exactly, as clean basis points. Batches are capped at ten per transaction.
The original whitepaper states this total as "1,800,000 $WOOL". Its own price tiers give 1,800,000,000. The document is off by three orders of magnitude; the contract is right.
| Action | Notes | Risk |
|---|---|---|
| Join The Exchange | Accrues $FLOW continuously, prorated to the second. | None. |
| Claim | Receive 80% of accrued $FLOW. Position stays open. | Makers take a fixed 20% rebate, split across staked Makers in proportion to Alpha. One transaction, no roll. |
| Exit | Position closes, all $FLOW settles, token returns. Requires T+2 since staking. | 50% chance the Makers take everything accrued. Two transactions with a roll in between. The token comes home either way. |
T+2 is the settlement cycle the US equity market ran on for a decade. In the original this was
an arbitrary "two days worth of $WOOL to keep it warm"; here it is the real thing.
Claiming resets the T+2 clock. Claim-then-exit means waiting another full two days. Inherited behaviour, undocumented in the original, stated here because it surprises people.
You have a 10% chance of minting a Maker, each with an Alpha of 5 to 8. Higher Alpha means a larger share of the rebate and a better chance of internalizing a new mint. Only staked Makers earn or steal anything.
| Action | Notes | Risk |
|---|---|---|
| Enter the Dark Pool | Earn a share of the 20% rebate on all $FLOW produced. | None. |
| Collect | Receive all rebate accrued against your Alpha. | None. |
| Leave | Receive all rebate accrued, and exit. | None. |
Alpha is steeply skewed, and not uniformly across four tiers as people assume. Enumerated over all 65,536 seeds of the original's table:
| Alpha | Title | Probability |
|---|---|---|
| 8 | Tier-1 Internalizer | 0.78% |
| 7 | HFT Desk | 15.63% |
| 6 | Quant Fund | 31.35% |
| 5 | Prop Shop | 52.25% |
A top-Alpha Maker is roughly 1 in 128 Makers, not 1 in 4.
Internalization. A newly minted Gen 1 token has a 10% chance of being routed to a random staked
Maker instead of the buyer who paid for it, weighted by Alpha. Gen 0 is exempt. If no Maker is staked, the minter keeps it.
This is the part that could not be forked, and the reason the game plays differently.
The original resolved every roll inside the transaction that paid for it, from
keccak256(tx.origin, blockhash(block.number-1), block.timestamp, seed). On Ethereum that was
already weak. On Robinhood Chain it is not randomness at all:
| Source | What it actually does here |
|---|---|
blockhash(block.number-1) | Frozen across ~150 consecutive blocks — about 15 seconds — byte-identical for every transaction in the window |
block.prevrandao | The literal constant 1 |
block.timestamp | Ten blocks share each value: roughly four bits |
eth_call with state overrides | Enabled, so any outcome computable in the paying transaction is computable for free beforehand |
Every one of the sixteen canonical VRF coordinator addresses is codeless on this chain.
So minting and exiting are two phases. You pay and reserve ids in one block; the outcome resolves in a later one against a beacon whose entropy did not exist when you paid.
A bonded reverse hash chain — the construction Pyth Entropy uses. The operator picks x[N] at random, computes x[i] = keccak256(x[i+1]) down to x[0], and publishes only x[0]. Revealing a link proves it was fixed before any request existed, because keccak256 does not run backwards.
A word is keccak256(preimage, keccak256(requestId, blockhash(seedBlock)), requestId).
| Party | Why it cannot choose the outcome |
|---|---|
| Player | The preimage is secret and the seed block does not exist at commit time |
| Sequencer | It produces the seed block but does not know the preimage |
| Operator | Its preimage was fixed by an earlier commitment; the seed block's hash was unknown then |
Nobody can bias a draw. The operator's only residual power is refusing to serve — and after roughly thirteen minutes anyone can settle a stuck roll from the block hash alone and take a slice of the operator's bond.
The beacon records two seed blocks and settles against whichever is available.
| Track | Available after | Readable for |
|---|---|---|
L2 (arbBlockHash) | ~0.4 s | ~26 s |
L1 (blockhash) | ~40 s | ~52 minutes |
Both were unknown when the player paid, so the security argument is identical. L1 is not a weaker fallback — it is the same construction on a slower clock with a longer memory, and it is the only reason a stalled operator cannot strand a paid mint.
Measured end to end, a mint settles in about 7 seconds.
If nobody settles within the L1 window, the request expires. The only remaining path is
settleExpired, which mints the floor outcome — plain Retail, null traits — and **refunds
nothing**.
This is deliberate and it is the sharpest edge in the game. A refundable expiry would make abandoning an unfavourable roll free, which is precisely the attack the two-phase split exists to prevent. It also means keeper liveness is a gameplay parameter, not merely an operational one.
Maximum supply 5,000,000,000, enforced inside the token. The staking faucet stops at
2,400,000,000.
$WOOL advertised the same 5B ceiling and never had one in code. Its supply today is 2,806,443,923 — 16.9% above the number it published — and 96.6% of that was minted after the game was already dead, including a single transaction that raised supply 60% in one block. A cap that lives only in a document is not a cap.
The original paid 10,000 $WOOL per staked token per day against a 20,000 first-tier mint. Payback was therefore exactly 2.0 days — the same number as its minimum staking period. Emission bought the thing that produced emission:
dS/dt = (p · R / C) · S p = 0.9, R = 10,000, C = 20,000
growth = 0.45/day → doubling every 1.54 days
Designed economy lifetime: 7.94 days. In the 3.82 days its staking contract actually ran, daily emission was 123.9% of the entire token supply, every day, against a sink that absorbed 22.98% and was one-time-only.
Only the ratio R/C matters, so starting supply cancels: a bigger Gen 0 does not help, and the price tiers buy a 1.85× extension at best. Correcting it means either cutting the rate ~50× or raising the Gen 1 tiers ~50×.
This is the one parameter still open at the time of writing. The testnet build carries the
original rate, which is deliberate: it makes the mechanics visible in minutes rather than months.
Seven defects were inherited from the original and corrected. Each is a // FORK: comment and each has a test whose only job is to fail if it comes back.
| Defect in the original | Consequence there |
|---|---|
Uniqueness key omitted the nose trait | Tokens differing only in that trait were duplicates; the key space was 2^72 and enumerable off-chain |
Bucket drawn as uint8(seed) % length | Biased on ten of eighteen tables — the published rarity percentages were never what the tables encoded |
| Steal roll consumed 11 bits, not 10 | 10.0098% instead of 10% |
uint80 held a wei-denominated accumulator snapshot | Truncates above ~1.2e24, silently voiding a Maker's entire claim basis |
packIndices stored a raw index | Position 0 indistinguishable from never-staked |
| Alpha lookup on a nonexistent token | Returned the best possible score, 8 |
$WOOL had no supply cap in code | See section 7 |
The uint80 fix costs about 20,000 gas per stake, because a packed struct became two slots. On a chain where a transaction costs a fraction of a cent, that is the correct trade against silent fund loss.
Stated plainly, because a game about predators should not be coy about who holds what.
Cannot be biased by anyone. The outcome of any normal draw. Not by the player, not by the
sequencer, not by the operator.
Permissionless. Settlement. revealMint, settleExit and settleStalled are callable by
anyone, so a player who dislikes a result cannot suppress it, and a stalled operator cannot strand one.
What the operator holds. The hash-chain seed, and therefore the ability to stall. Bounded by a
slashable bond and by settleStalled.
What the owner holds, that the original's owner did not. The ability to point the game at a
different beacon. That power is real and it is the sharpest one here — a beacon that returns chosen words defeats everything above. It is therefore behind a 48-hour timelock: proposing a swap is public, and anyone watching can exit before it takes effect. The timelock does not remove the power. It makes using it observable.
What the owner holds, inherited. Re-uploading trait art, and adding $FLOW controllers. Both
existed in the original.
Not audited. No part of this has had a security review.
Robinhood Chain testnet, chain 46630.
| Contract | Address |
|---|---|
| OrderFlow (NFT) | 0x2AaA7b1044433430Fa443562594157420bD0d368 |
| Exchange (staking) | 0x959E8569442Ab7e019602165822b1e0Fd66D997a |
| FlowToken ($FLOW) | 0xC978ef948602566252dfa649A1db2cEfa826DeFF |
| Traits (on-chain art) | 0xFb741d20d231caA32d94B6e2D2aa802fdEB36a31 |
| RandomnessBeacon | 0x786d7Aa6Ccb335Ac97Ad21B3B4a11179138F186c |
All metadata and art are generated and stored on-chain. No IPFS, no API — the same claim the original made, and one this fork still satisfies.
Nothing here is deployed to mainnet. The tokens are worthless. This is not financial advice or an offer to sell anything, and it is not affiliated with Robinhood Markets, Inc., with any market maker, or with the original Wolf Game.