Docs
Mechanics, the evidence behind the three gates, the randomness scheme and its weaknesses, the security argument, the risks, and how to deploy.
Evidence
Everything below was measured on 2026-09-24 against Robinhood Chain mainnet (chain 4663) through the public RPC https://rpc.mainnet.chain.robinhood.com, unless a source is named. Block heights at the time of the probes ran from 71 273 196 (11:41 UTC) to about 71 530 000 (19:00 UTC). Raw material is kept in .research/ (JSON dumps, logs) and reproduced by scripts/discover-assets.ts, scripts/measure-depth.ts, contracts/script/MeasureDepth.s.sol and contracts/script/MeasureMultipliers.s.sol.
Chain facts
| Fact | Evidence |
|---|---|
| Chain IDs | eth_chainId → 0x1237 (4663) on mainnet, 0xb626 (46630) on testnet |
| Architecture | Arbitrum Orbit (Robinhood docs "Chain overview"); FCFS sequencing, no fee-based reordering |
| Block cadence | L2 blocks 71 273 056 … 71 273 196 carry timestamps 1 790 243 152 … 1 790 243 166: 140 blocks in 14 s, ~10 L2 blocks/s |
block.number semantics | The same blocks report l1BlockNumber 26 046 513 → 26 046 514: block.number is the L1 estimate and advances every ~12 s (Robinhood docs "Differences from Ethereum" confirm; block.prevrandao is constant) |
| ArbSys | 0x64.arbBlockNumber() → 71 274 643 (true L2 height) |
| Multicall3 | code present at 0xcA11bde05977b3631167028862bE2a173976CA11 (7 619 hex chars) |
| Code-size limit | 96 KB per Robinhood docs; Scrip compiles to 29.8 KB |
| USDG | 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168, symbol() "USDG", decimals() 6, totalSupply() 695 338 558 806 407 (≈ 695 M USDG) |
| WETH | 0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73 (Robinhood docs "Contracts") |
| Uniswap | From Uniswap/contracts deployments/json/4663.json: v2 factory 0x8bcEaA40B9AcdfAedF85AdF4FF01F5Ad6517937f, v2 router 0x89e5DB8B5aA49aA85AC63f691524311AEB649eba, v3 factory 0x1f7d7550B1b028f7571E69A784071F0205FD2EfA, QuoterV2 0x33e885eD0Ec9bF04EcfB19341582aADCb4c8A9E7, SwapRouter02 0xCaf681a66D020601342297493863E78C959E5cb2, v4 PoolManager 0x8366a39CC670B4001A1121B8F6A443A643e40951, V4Quoter 0x8dc178efb8111bb0973dd9d722ebeff267c98f94, StateView 0xf3334192d15450cdd385c8b70e03f9a6bd9e673b, UniversalRouter v2.1.2 0x204FAca1764B154221e35c0d20aBb3c525710498, Permit2 canonical. No 46630.json exists: Uniswap is not deployed on the testnet. |
| Explorer API | robinhoodchain.blockscout.com/api/v2 answers 403 (Cloudflare challenge) to non-browser clients; verification uses --verifier blockscout --verifier-url https://robinhoodchain.blockscout.com/api/ per Robinhood's Foundry guide |
Stock Token surface (verified on the CRM token)
CRM = 0xd95B44124e475743a7589e68F3D74008A5536D44, "Salesforce • Robinhood Token", decimals() 18, totalSupply() 267.48 tokens, uiMultiplier() 1 001 148 322 800 714 293 (1.001148), newUIMultiplier() identical, effectiveAt() 1 789 650 372, oraclePaused() false, paused() false.
The token is a 285-byte beacon proxy (_update reads the implementation from beacon 0xe10b6f6b275de231345c20d14ab812db62151b00, whose implementation() is 0xb35490d6f9163DE4F80d88dc75c3516eb64C5aE2, 11.6 KB). Selector scan of that implementation: present — uiMultiplier(), oraclePaused(), newUIMultiplier(), effectiveAt(), balanceOfUI(address), totalSupplyUI(), paused(), pause(), isBlocked(address), mint(address,uint256), hasRole(bytes32,address). So the issuer can pause transfers, block addresses, mint, and update the multiplier, and can upgrade the logic through the beacon. SCRIP documents all of this in RISK.md and adds no control of its own.
The Robinhood asset API (GET https://api.robinhood.com/rhj/assets) returned 195 assets, all ASSET_STATUS_ACTIVE, all deployed on chain 4663 only. It is the source of packages/config/assets.4663.json.
Gate 1 — randomness: no Chainlink VRF on Robinhood Chain
| Check | Result |
|---|---|
docs.chain.link/vrf/v2-5/supported-networks | Lists nine mainnets (Arbitrum, Avalanche, Base, BNB, Ethereum, OP, Polygon, Ronin, Soneium) and their testnets. Robinhood Chain does not appear. |
docs.chain.link/vrf | No mention of Robinhood Chain; no newer VRF product listed for it. |
chainlinkecosystem.com/chain/robinhood-chain | Only Data Streams is named as live on Robinhood Chain (via the Metric DEX). Data Feeds are live (feed registry below). VRF is not listed. |
| Robinhood "Oracles & price feeds" page | Names Chainlink for price data only. |
| Chainlink L2 sequencer uptime feeds | No feed listed for Robinhood Chain. |
| Robinhood "Differences from Ethereum" | block.prevrandao / block.difficulty return constants; blockhash reliable only for recent blocks; the page itself recommends an oracle such as VRF, which is not available here. |
Decision: commit–reveal (BlockhashRandomness), designed and attacked in RANDOMNESS.md: target block.number + 1 (an L1 estimate that has not ticked yet), a mandatory L2 delay of 4 blocks via ArbSys, seed = keccak(salt, blockhash(target), target), retarget to a future block when the 256-block window lapses, no cancellation path. VrfRandomness implements the same interface so the core contract can switch the day a coordinator exists. The gate does not fail: the scheme has no user-side influence, and its weaknesses (sequencer bias, a lapsed window giving a fresh unknown draw) are disclosed rather than hidden.
Gate 2 — liquidity
Method
scripts/measure-depth.ts, run against the public RPC at block 71 521 452 (unix 1 790 268 173):
- For each of the 195 tokens, discover every Uniswap pool quoted in USDG or WETH: v3 via
getPoolat the four fee tiers, v2 viagetPair, v4 viaInitializeevents on the PoolManager filtered by(currency0, currency1). - Reference price: the Chainlink Total Return Value feed where one exists (35 tokens), otherwise the Robinhood REST
tokenBid/tokenAskmid (already multiplier-adjusted; for AAPL the REST ask 335.99 × multiplier 1.000566 = 336.18, matching thetokenAskfield). - Quote an exact-input USDG purchase at 10 USDG through every pool (v3
QuoterV2.quoteExactInputSingle, v2getAmountsOut, v4V4Quoter.quoteExactInputSingle; WETH-quoted pools go through the USDG/WETH 0.05 % v3 pool first), then ladder 2, 50, 100, 250, 500, 1 000, 2 500, 5 000 USDG on every v2/v3 pool and on the six best v4 pools. - Report execution slippage versus the reference in bps (fee included), and depth@200: the largest ladder size whose execution stays within
MAX_DEVIATION_BPS = 200of the reference, computed both over all venues and over routable venues (v2, v3, and hook-free v4).
The public RPC caps eth_getLogs at 10 000 logs per query and rate-limits above ~6 concurrent calls; the script runs at concurrency 2 with retries and checkpoints, and completes in roughly an hour. The full per-token ranking is DEPTH.md; the machine-readable result is .research/depth.json.
Findings
- Chainlink feeds exist for 35 of the 195 tokens (Chainlink reference-data-directory
feeds-robinhood-mainnet.json: 58 feeds, 35 equities + 23 crypto/stablecoin; the Chainlink docs page lists 33 under "Tokenized Equity" with SGOV and EWY categorised separately). All equity feeds: 8 decimals, heartbeat 86 400 s, deviation threshold 0.5 %, market hoursus_equities_24/5. Feed proxies, e.g. AAPL0x6B22A786bAa607d76728168703a39Ea9C99f2cD0, are inpackages/config/assets.4663.json. The other 160 tokens cannot enter a series whatever their liquidity, becauseAssetRegistryrequires a feed. - Uniswap v4 dominates pool count, not usable depth. NVDA has 502 pools (492 on v4), AAPL 130, TSLA 103; most are hook pools (fee flag
8388608= dynamic fee, hook contracts such as0x64E9ae1066c47Ac4a3cc0a5bd7B135908590e088). Several hook pools quote better than Chainlink at small size. SCRIP does not route through hook pools: a third-party hook between a buyer's USDG and their stock is exactly the kind of dependency the product promises not to have. Hook-free v4 pools exist (e.g. NVDA at fee 375) but the swap path needs the PoolManager unlock callback; v3 and v2 cover the eligible tokens, so SwapLib routes v3 (SwapRouter02) and v2 (Router02) only, and v4 is measured but not routed. - The deep tokens are deep. Real v3 USDG pools at the 0.05 % tier: AAPL
0xAae0d815EE56e4092a5E5C2911E676Fea50B2d6Dholds 185 773 USDG and fills 5 000 USDG within 2 bps of Chainlink; TSLA0xc4f0172D6ac8DD294Dd1137D047d5E1893760236holds 16 032 USDG and fills 1 000 USDG within 11 bps and 5 000 within 76 bps. The mainnet fork test bought five slips of AAPL/NVDA/TSLA through these pools at 3, 17, 4, 3 and 3 bps from Chainlink (test_fork_realTokensFeedsAndPools_commitRevealRedeem,forge test --match-path test/fork/* --fork-url robinhood). - The thin tokens are thin. CRM's only v3 pool is the 1 % tier (
0xda68FBa2d1bCA00e3754937b5608bA61Aee6e827) and quotes 135 bps at slip size; AEHR 431 bps, CBRS 368 bps, ONTO 870 bps at 2 USDG; JBL 453 bps. None of these has a feed either. - Chainlink versus REST mid at measurement time: AAPL −2 bps, TSLA +11 bps, NVDA +19 bps (feed ages 5 900 s … 50 800 s within the 24 h heartbeat, a weekday).
Result of the full run (block 71 521 452, all 195 tokens)
- 33 of the 35 feed-backed tokens reach depth@200 of at least 10 USDG on some hook-free venue, and 32 reach 100 USDG or more. 30 reach the top of the ladder (5 000 USDG). The two that fall short are IONQ, at 10 USDG, and one token with no hook-free depth at all.
- 26 of them are eligible for the launch series. Each has a direct USDG pool on v3 that holds at least the 1 000 USDG floor, and each fills 5 000 USDG within 200 bps. Slippage at slip size (2 USDG) ranges from −6 bps (TSM) to 92 bps (SNDK), and most sit between 13 and 40 bps.
pnpm build:serieswrote them topackages/config/series.4663.jsonwith caps weighted by depth: 26 companies, 990 slips, 198 packs. - Six deep, feed-backed tokens are left out because their depth sits only on venues SwapLib does not route. NBIS, CRWV, ORCL, RKLB and EWY hold their liquidity in hook-free v4 pools, and their v2 and v3 USDG pools are empty. COIN's depth is in a WETH-quoted v3 pool. Adding v4 routing to SwapLib (the PoolManager unlock callback) would bring five of them in.
- The "Routable" columns in DEPTH.md count hook-free v4 pools as well. The launch-series criterion is stricter: only v2 and v3 pools quoted directly in USDG.
- The top of DEPTH.md is full of tokens without a feed, such as RUN, UPS, NNE and AMC. Their reference is the REST mid, and several v4 pools quote below it. They are ranked but can never enter a series.
Deployment constant
AssetRegistry.depthFloorUsdg is immutable and set at deploy to 1 000 USDG (DEPTH_FLOOR_USDG=1000000000): the route's pool must hold at least 1 000 USDG for the token to be registered, to enter a series, and at every reveal. Derivation: a pack is 10 USDG and a slip 2 USDG; a constant-product pool holding 1 000 USDG moves 0.2 % for a 2 USDG buy, well inside the 200 bps guard even for a v3 pool with concentrated liquidity partially out of range; a pool below that could fail the guard on the second slip of the same company in one block. Every token in the launch series must clear it and have depth@200 of at least 100 USDG on a hook-free venue in DEPTH.md, i.e. ten packs' worth of one company without touching the guard.
Gate 3 — the multiplier rises on dividends (measured, not asserted)
UIMultiplierUpdated(uint256 oldMultiplier, uint256 newMultiplier, uint256 effectiveAtTimestamp) (topic 0x2205df4534432b2f60654a3fdb48737ffdaf3e9edb1a498bd985bc026b15b055), read with eth_getLogs from genesis on mainnet:
| Token | Contract | Block | Old | New | Effective at | Tx |
|---|---|---|---|---|---|---|
| CRWD | 0xea72Ecca2d0f6bFA1394DBBCff85b52CD4233931 | 978630 | 1.0 | 4.0 | 1782999000 | 0x07884f2f2440316a996ab3a9c0f8bce962ec872af6924745f5a04a9e9ac1d31f |
| CRWD | 0xea72Ecca2d0f6bFA1394DBBCff85b52CD4233931 | 1231096 | 1.0 | 4.0 | 1782999000 | 0x5dbbb9524fc402fea6786eb5a5dd40205ce8c6e848fb313eecedf7e9395f5bf0 |
| AVGO | 0x156E175DD063a8cE274C50654eF40e0032b3fbcF | 68357872 | 1.0 | 1.0012573186622782 | 1789950036 | 0x4f48d60ed90f20583ba87a441e10983c1beb0bf067a85124849d49396fbefdc8 |
| SPY | 0x117cc2133c37B721F49dE2A7a74833232B3B4C0C | 65779981 | 1.0 | 1.001717991187472 | 1789690233 | 0x2fe45ab24d1b3fa87883f8b08daf29dae969c5b43d0afe9ccca299c11a641025 |
| CCL | 0x9651342CeA770aE9a2969Ba2A52611523146aef9 | 50955407 | 1.0 | 1.0214864448552063 | 1788189026 | 0x391030f47dae3d1ac98f9f4384c31186fad48fae6d62d1b3fae5e1449e2fdd02 |
| QQQ | 0xD5f3879160bc7c32ebb4dC785F8a4F505888de68 | 69210998 | 1.0 | 1.0007007912414054 | 1790035834 | 0x6331915e6ddac124b1ea59b0db720892615fbd8ffbbea59cc9772147e326bba6 |
| TSM | 0x58FfE4a942d3885bAa22D7520691F611EF09e7AA | 64062939 | 1.0 | 1.0014630241596905 | 1789517433 | 0x53888b0500828784f8eb5e98b22e2becf1e5d9b00d4e48c26d0b440e08f34037 |
| MSFT | 0xe93237C50D904957Cf27E7B1133b510C669c2e74 | 60346891 | 1.0 | 1.000412952576206 | 1789139430 | 0x4df2fb31b1e2a4804e73bc8121b0186f3d56d642980de79f77c6fb55c8c82800 |
| META | 0xc0D6457C16Cc70d6790Dd43521C899C87ce02f35 | 68357919 | 1.0 | 1.0005414598794518 | 1789950036 | 0x8928618da3daf1cc5a9e9f7a0e76d7bc28df824fea7d6838434a9c085c6b0b5e |
| GOOGL | 0x2e0847E8910a9732eB3fb1bb4b70a580ADAD4FE3 | 63746832 | 1.0 | 1.0001939244141127 | 1789485027 | 0x8b9babad437e92388a66f13a03db0ee998a96831c244d1620d88115810b65c51 |
| SGOV | 0x92FD66527192E3e61d4DDd13322Aa222DE86F9B5 | 4629631 | 1.0 | 1.0009575198909908 | 1783541672 | 0x79292bc8af671bd6fc4ebc8f5e7a27c814d87988e175cbfab2ab1db1df0efbfb |
| SGOV | 0x92FD66527192E3e61d4DDd13322Aa222DE86F9B5 | 30302195 | 1.0009575198909908 | 1.0029815193467666 | 1786115424 | 0x94aaa4c5c537412b8a5ed4a1933cc8ee7cb3c5bc903a741e11d4aada5dc02ebd |
| SGOV | 0x92FD66527192E3e61d4DDd13322Aa222DE86F9B5 | 51269236 | 1.0029815193467666 | 1.005101770003215 | 1788220826 | 0xf33317c324c4d1d53278dd5c0fcb6ca3afeea41ccf39441ecada548148f5f4e7 |
| NVDA | 0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC | 58952659 | 1.0 | 1.0007751591646306 | 1788998430 | 0x4ac23f2e58e2c4962dcd701c2beff581e87f3995152a29d527c07a3afd67d956 |
| XOM | 0xf9B46d3D1B22199D4D1025a9cEDB540A33F1a2d5 | 60346845 | 1.0 | 1.0010395637646619 | 1789139430 | 0x2cd7aa15b670f84e1302097b2bc3e07282c6cef0148b70b7bc3b0f920a49cdbd |
| JNJ | 0x03DfbBE0AC4E7bCDaFd08eD41A400326B77D8c80 | 58637294 | 1.0 | 1.000021490286702 | 1788966626 | 0x64c7bfc1e54fe6ca6fb7cbda1b5d8d934f8fb0968c74704684c5e85ef6a5f831 |
| ORCL | 0xb0992820E760d836549ba69BC7598b4af75dEE03 | 20823272 | 1.0 | 1.0022109149710134 | 1785165023 | 0xdb44087be277205a6819d8656cdd87e1c0a061822798c735f3efdf94bbfc9bd7 |
| AAPL | 0xaF3D76f1834A1d425780943C99Ea8A608f8a93f9 | 36345344 | 1.0 | 1.0005660800610925 | 1786720366 | 0x6d72ca599d812b9eb483fa82ba204e6d079e981b675669c9b659b7fac8adff35 |
| COST | 0x4EA005168D7F09a7A0Ba9D1DEf21a479950E44C2 | 32889913 | 1.0 | 1.0006120402962597 | 1786374624 | 0x728a9545a0d36b55ef5b4c12a9b9a3565e22167abe78f4453efb78d1292fcf62 |
| CRM | 0xd95B44124e475743a7589e68F3D74008A5536D44 | 65383603 | 1.0 | 1.0011483228007143 | 1789650372 | 0xc6189b8fcc4e3e0a92fdd33b0c74c0646165112f113af6782866ca460c64edde |
What this shows:
- Cash dividends raise the multiplier by the dividend yield. AAPL 1.0 → 1.000566 (≈ 0.26 USD on a ≈ 336 USD share on 2026-08-14 at the 1786720366 effective time: Apple's quarterly dividend); MSFT 1.000413; NVDA 1.000775; XOM 1.00104; COST 1.000612; CRM 1.001148 (0.42 USD on a ≈ 240 USD share). The Robinhood corporate-actions API (
/rhj/corporate-actions) lists 51 in-progressCASH_DIVIDENDactions at the time of writing (META 0.525, AVGO 0.65, LMT 3.45, INTU 1.38 …), so the series continues. - Monthly distributions compound. SGOV (a T-bill ETF) went 1.0 → 1.000958 → 1.002982 → 1.005102 across three consecutive monthly payments (blocks 4 629 631, 30 302 195, 51 269 236).
- Splits use the same mechanism with a big step. CRWD 1.0 → 4.0 (a 4-for-1 split staged at block 978 630 and re-emitted at 1 231 096 with the same effective time 1782999000), exactly as Chainlink's Robinhood feed page describes for scheduled corporate actions.
- Today 37 of 195 tokens carry a multiplier above 1.0 (asset API
currentMultiplier, andMeasureMultipliers.s.solon a fork reads the same values on-chain), including CRWD 4.0, CCL 1.0215, SCHD 1.0055, SGOV 1.0051, LHX 1.0049, KSS 1.0046, PR 1.0045, UNH 1.0042. - The Chainlink feed already contains the multiplier (Chainlink: "Token Price = Underlying Equity Market Price × Multiplier"), which is why SCRIP never multiplies a feed price and uses
uiMultiplier()only to show shares.
Gate 3 holds: a slip minted with multAtMint = 1.0 on a company that then pays a dividend represents rawAmount × uiMultiplier / 1e18 > rawAmount shares without any transaction. Scrip.sharesNow / sharesAtMint and the indexer's multiplierUpdate table surface exactly this, and test_sharesNow_growsWithMultiplier_backingDoesNot proves the backing does not move when the multiplier does.
What was deployed and exercised
| Environment | Status on 2026-09-24 |
|---|---|
Local Anvil replica (chain 31337, --code-size-limit 98304, LocalArbSys at 0x64) | Deployed by Deploy.s.sol; SeedSeries.s.sol registered 8 mock tokens and published series 1 (175 slips / 35 packs) and series 2 through the timelock; the keeper committed and revealed all 35 packs of series 1 (series exhausted and every pack opened); a set was sealed (token 176) and redeemed; slip 40 redeemed; the Ponder indexer and the Next.js app served all of it. |
| Robinhood testnet 46630 | Deploy.s.sol simulated cleanly against the live testnet (37.4 M gas, ≈ 0.00075 ETH). Not broadcast: the deployer 0xD44571F6554e9eED40EeA6af171C149F1c7EE2FB holds 0 testnet ETH and the faucet requires a person to pass its browser challenge. The steps to finish are in DEPLOY.md. |
| Mainnet fork | Both fork tests pass against real Stock Tokens, feeds and v3 pools. |


