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

FactEvidence
Chain IDseth_chainId → 0x1237 (4663) on mainnet, 0xb626 (46630) on testnet
ArchitectureArbitrum Orbit (Robinhood docs "Chain overview"); FCFS sequencing, no fee-based reordering
Block cadenceL2 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 semanticsThe 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)
ArbSys0x64.arbBlockNumber() → 71 274 643 (true L2 height)
Multicall3code present at 0xcA11bde05977b3631167028862bE2a173976CA11 (7 619 hex chars)
Code-size limit96 KB per Robinhood docs; Scrip compiles to 29.8 KB
USDG0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168, symbol() "USDG", decimals() 6, totalSupply() 695 338 558 806 407 (≈ 695 M USDG)
WETH0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73 (Robinhood docs "Contracts")
UniswapFrom 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 APIrobinhoodchain.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

CheckResult
docs.chain.link/vrf/v2-5/supported-networksLists nine mainnets (Arbitrum, Avalanche, Base, BNB, Ethereum, OP, Polygon, Ronin, Soneium) and their testnets. Robinhood Chain does not appear.
docs.chain.link/vrfNo mention of Robinhood Chain; no newer VRF product listed for it.
chainlinkecosystem.com/chain/robinhood-chainOnly 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" pageNames Chainlink for price data only.
Chainlink L2 sequencer uptime feedsNo 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):

  1. For each of the 195 tokens, discover every Uniswap pool quoted in USDG or WETH: v3 via getPool at the four fee tiers, v2 via getPair, v4 via Initialize events on the PoolManager filtered by (currency0, currency1).
  2. Reference price: the Chainlink Total Return Value feed where one exists (35 tokens), otherwise the Robinhood REST tokenBid/tokenAsk mid (already multiplier-adjusted; for AAPL the REST ask 335.99 × multiplier 1.000566 = 336.18, matching the tokenAsk field).
  3. Quote an exact-input USDG purchase at 10 USDG through every pool (v3 QuoterV2.quoteExactInputSingle, v2 getAmountsOut, v4 V4Quoter.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.
  4. Report execution slippage versus the reference in bps (fee included), and depth@200: the largest ladder size whose execution stays within MAX_DEVIATION_BPS = 200 of 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 hours us_equities_24/5. Feed proxies, e.g. AAPL 0x6B22A786bAa607d76728168703a39Ea9C99f2cD0, are in packages/config/assets.4663.json. The other 160 tokens cannot enter a series whatever their liquidity, because AssetRegistry requires 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 as 0x64E9ae1066c47Ac4a3cc0a5bd7B135908590e088). 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 0xAae0d815EE56e4092a5E5C2911E676Fea50B2d6D holds 185 773 USDG and fills 5 000 USDG within 2 bps of Chainlink; TSLA 0xc4f0172D6ac8DD294Dd1137D047d5E1893760236 holds 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:series wrote them to packages/config/series.4663.json with 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:

TokenContractBlockOldNewEffective atTx
CRWD0xea72Ecca2d0f6bFA1394DBBCff85b52CD42339319786301.04.017829990000x07884f2f2440316a996ab3a9c0f8bce962ec872af6924745f5a04a9e9ac1d31f
CRWD0xea72Ecca2d0f6bFA1394DBBCff85b52CD423393112310961.04.017829990000x5dbbb9524fc402fea6786eb5a5dd40205ce8c6e848fb313eecedf7e9395f5bf0
AVGO0x156E175DD063a8cE274C50654eF40e0032b3fbcF683578721.01.001257318662278217899500360x4f48d60ed90f20583ba87a441e10983c1beb0bf067a85124849d49396fbefdc8
SPY0x117cc2133c37B721F49dE2A7a74833232B3B4C0C657799811.01.00171799118747217896902330x2fe45ab24d1b3fa87883f8b08daf29dae969c5b43d0afe9ccca299c11a641025
CCL0x9651342CeA770aE9a2969Ba2A52611523146aef9509554071.01.021486444855206317881890260x391030f47dae3d1ac98f9f4384c31186fad48fae6d62d1b3fae5e1449e2fdd02
QQQ0xD5f3879160bc7c32ebb4dC785F8a4F505888de68692109981.01.000700791241405417900358340x6331915e6ddac124b1ea59b0db720892615fbd8ffbbea59cc9772147e326bba6
TSM0x58FfE4a942d3885bAa22D7520691F611EF09e7AA640629391.01.001463024159690517895174330x53888b0500828784f8eb5e98b22e2becf1e5d9b00d4e48c26d0b440e08f34037
MSFT0xe93237C50D904957Cf27E7B1133b510C669c2e74603468911.01.00041295257620617891394300x4df2fb31b1e2a4804e73bc8121b0186f3d56d642980de79f77c6fb55c8c82800
META0xc0D6457C16Cc70d6790Dd43521C899C87ce02f35683579191.01.000541459879451817899500360x8928618da3daf1cc5a9e9f7a0e76d7bc28df824fea7d6838434a9c085c6b0b5e
GOOGL0x2e0847E8910a9732eB3fb1bb4b70a580ADAD4FE3637468321.01.000193924414112717894850270x8b9babad437e92388a66f13a03db0ee998a96831c244d1620d88115810b65c51
SGOV0x92FD66527192E3e61d4DDd13322Aa222DE86F9B546296311.01.000957519890990817835416720x79292bc8af671bd6fc4ebc8f5e7a27c814d87988e175cbfab2ab1db1df0efbfb
SGOV0x92FD66527192E3e61d4DDd13322Aa222DE86F9B5303021951.00095751989099081.002981519346766617861154240x94aaa4c5c537412b8a5ed4a1933cc8ee7cb3c5bc903a741e11d4aada5dc02ebd
SGOV0x92FD66527192E3e61d4DDd13322Aa222DE86F9B5512692361.00298151934676661.00510177000321517882208260xf33317c324c4d1d53278dd5c0fcb6ca3afeea41ccf39441ecada548148f5f4e7
NVDA0xd0601CE157Db5bdC3162BbaC2a2C8aF5320D9EEC589526591.01.000775159164630617889984300x4ac23f2e58e2c4962dcd701c2beff581e87f3995152a29d527c07a3afd67d956
XOM0xf9B46d3D1B22199D4D1025a9cEDB540A33F1a2d5603468451.01.001039563764661917891394300x2cd7aa15b670f84e1302097b2bc3e07282c6cef0148b70b7bc3b0f920a49cdbd
JNJ0x03DfbBE0AC4E7bCDaFd08eD41A400326B77D8c80586372941.01.00002149028670217889666260x64c7bfc1e54fe6ca6fb7cbda1b5d8d934f8fb0968c74704684c5e85ef6a5f831
ORCL0xb0992820E760d836549ba69BC7598b4af75dEE03208232721.01.002210914971013417851650230xdb44087be277205a6819d8656cdd87e1c0a061822798c735f3efdf94bbfc9bd7
AAPL0xaF3D76f1834A1d425780943C99Ea8A608f8a93f9363453441.01.000566080061092517867203660x6d72ca599d812b9eb483fa82ba204e6d079e981b675669c9b659b7fac8adff35
COST0x4EA005168D7F09a7A0Ba9D1DEf21a479950E44C2328899131.01.000612040296259717863746240x728a9545a0d36b55ef5b4c12a9b9a3565e22167abe78f4453efb78d1292fcf62
CRM0xd95B44124e475743a7589e68F3D74008A5536D44653836031.01.001148322800714317896503720xc6189b8fcc4e3e0a92fdd33b0c74c0646165112f113af6782866ca460c64edde

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-progress CASH_DIVIDEND actions 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, and MeasureMultipliers.s.sol on 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

EnvironmentStatus 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 46630Deploy.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 forkBoth fork tests pass against real Stock Tokens, feeds and v3 pools.