MOO Reference Manual
Market On Open. Operator's guide, first edition. Everything below is checkable on chain.
A new stock token on Robinhood Chain exists before its Chainlink feed has ever published a price. In that gap the stock cannot be traded honestly anywhere: an AMM would need someone to invent a starting price, and an order book has nothing to quote against.
MOO is a pool for that gap. Buyers commit USDG. Sellers commit stock. Nobody names a price, because no price exists. When the feed publishes its first round, both sides cross at that number. You cannot front-run a number that has not happened.
The name is a real order type. On the NYSE, a Market On Open order fills at the opening auction price, whatever it turns out to be. This is that order, on chain.
| t | event | effect |
|---|---|---|
| T+0 | POOL DEPLOYED | the feed's current round id is recorded. The window is open. |
| window | SUBSCRIBE / UNDERWRITE | USDG and stock commit in. No cancels, no price named by anyone. |
| first print | WINDOW SHUT | the number is public now. Any further commitment reverts with WindowClosed. |
| after print | SETTLE, by anyone | both sides cross at the print. Smaller side fills whole, larger side pro-rata. |
| settled | CLAIM | subscribers take stock plus unspent USDG. Underwriters take USDG plus unsold stock. |
| deadline, no print | WITHDRAW | every deposit returns exactly. No fee, no partial fill. |
The window closes at the print, not at settle. The moment a newer round exists the number is public, so commitments stop. An auction does not take orders after the open.
- Connect a wallet on Robinhood Chain (the site adds the network for you).
- Press S and enter a USDG amount. It transfers into the pool.
- Wait. The feed prints, someone settles, and your fill price is that print.
- Press C to claim: stock at the print price, plus any USDG that did not fill.
Deposits cannot be cancelled, on purpose. An order you could pull while waiting is a free option on the print: you would watch the number arrive and back out if you disliked it. Commitment is what makes the fill honest for everyone in the pool.
If more USDG subscribed than there is stock to buy, the fill is shared out by the rule in 0x03 and the unspent remainder comes back with the claim.
A book that is oversubscribed cannot fill everyone, so somebody has to be served first. Every real offering answers that question, usually behind a closed door. Here the answer is in the contract and you can read it before you commit a dollar.
The book has two tranches. A subscription from a wallet holding at least 1,000,000 MOO goes into the first one. Everything else goes into the open one. At settlement the fill is poured into the first tranche until it is satisfied, and only what is left over reaches the open tranche. Inside a tranche it is pro-rata, so holding more MOO than the line does not buy a bigger slice.
| the book | stock offered | first tranche | open tranche |
|---|---|---|---|
| $100 held, $100 open | $200 worth | filled $100 | filled $100 |
| $100 held, $100 open | $100 worth | filled $100 | refunded $100 |
| $200 held, $100 open | $100 worth | filled $50 each | refunded $100 |
Qualification is judged the moment the money arrives. Selling the token afterwards cannot take back an allocation already earned, and buying it afterwards only counts toward the next subscription. The token address and the one million line are fixed in the factory at deploy, so no one can move the line later.
Whoever holds inventory of a fresh listing has the day-one problem in mirror image: sell into a thin pool and pay slippage, or quote into a bot swarm and get picked off. Committing stock to a MOO pool is a guaranteed exit at the open, at the one number nobody saw in advance. Real IPOs have underwriters for the same reason this pool does.
- Press U. If you hold the stock it goes straight in. If you hold only USDG, the site buys the shares for you at the deepest venue on the chain and underwrites them in the same press.
- At settle your stock is sold at the print plus the pool's premium, pro-rata with other underwriters.
- Claim returns USDG for what sold and stock for what did not.
The premium is what makes the trip worth taking. A pool paying 2% against a venue that charges 0.05% to buy the shares leaves the difference with whoever showed up before the number existed. What you carry in exchange is the price moving while the window is open, so shorter windows cost you less to underwrite.
P = first print after deploy (Chainlink answer, scaled to 1e18)
m = underwriter premium (bps) set when the pool opens, 0 to 10%
P' = P * (10000 + m) / 10000 the crossing price the buy side pays
U = total USDG subscribed S = total stock underwritten
demanded = U / P' stock the buy side wants
filled = min(demanded, S) stock that actually crosses
spent = filled * P' USDG that actually crosses, premium included,
and every cent of it goes to the sell side
subscriber with u USDG:
gets (u / U) * filled shares
back u - (u / U) * spent USDG
underwriter with s shares:
gets (s / S) * spent USDG
back s - (s / S) * filled shares
Worked example, using the first mainnet pool's real commitments. 24 USDG subscribed, 0.0138 SNDK underwritten. Suppose the print lands at $1,780.00.
| quantity | value | note |
|---|---|---|
| demanded | 24 / 1780 = 0.013483 shares | buy side is the smaller side |
| filled | 0.013483 shares | buy side fills completely |
| spent | 24.00 USDG | every subscribed dollar crosses |
| subscriber claims | 0.013483 SNDK | bought exactly at the print |
| underwriter claims | 24.00 USDG + 0.000317 SNDK | sold at the print, unsold stock returns |
No fee is taken anywhere in this flow. What goes in comes out as stock, settlement money, or refund.
| if | then |
|---|---|
| the feed never prints before the deadline | withdraw() returns every deposit exactly. No fee, no partial fill. |
| a print arrives while you are about to commit | your transaction reverts with WindowClosed. Late money cannot act on a seen price. |
| the pool is oversubscribed | pro-rata fill, automatic refund of the remainder. No queue, no priority. |
| nobody calls settle | anyone can. The function is permissionless and the price it reads is fixed by the feed, not the caller. |
| you are both subscriber and underwriter | one claim() pays both sides at once. |
There is no owner, no admin key, no upgrade path, and no pause switch in the pool contract. Once deployed, the rules above are the only rules.
| what | address |
|---|---|
| MOO factory (open your own pool) | 0x0784cAFFfE3660ddB24A8DF0cBf03641cB473206 |
| MOO pool (SNDK, first pool) | 0x7518251fb11D62f6A5a208Bf40C80b739D1397E1 |
| $MOO token (allocation) | 0xc103ac00a25173870c909223c5676d50bf5728b2 |
| USDG (settlement) | 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168 |
| SNDK stock token | 0xB90A19fF0Af67f7779afF50A882A9CfF42446400 |
| SNDK Chainlink feed | 0xfb133Fa4B7b385802B693a293606682Df47109A3 |
| RPC | https://rpc.mainnet.chain.robinhood.com |
- Ask the factory for its own list:
allPools(). A pool on that list was built by the factory itself, from one source, with the allocation rule burned in at deploy. Nothing on the list can have been hand-assembled with different rules inside. - Read that source: MOO.sol and MOOFactory.sol, served straight out of the tree they are built from.
- Find
_requireWindowOpen(). It reverts commitments the moment the feed has a newer round than deploy. That is the no-front-running rule, in seven lines. - Find
settle(). It only accepts a round strictly newer than deploy, and reads the price from the feed, not from the caller. - Find
withdraw(). If nothing settled by the deadline, it hands back exactly what each address deposited. - Check the live pool state with any RPC tool:
totalUsdg(),totalStock(),settled(),deadline().
Every number the site shows is read from the chain in your own browser. The server serves files; it holds no state and signs nothing.