Repository navigation
Add Robinhood Chain support - #1087
Conversation
9bf076d to
698c5ca
Compare
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
698c5ca to
ddb3379
Compare
📸🪓 Transaction history (hack-forced)
🪓 HACK-FORCED: tx list Captured by the agent's in-app test run (build-and-test). |
ddb3379 to
5f04c09
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 5f04c09. Configure here.
47cf391 to
c2ec35e
Compare
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
09495bb to
e01766a
Compare
e01766a to
57c02ba
Compare
Robinhood Chain is an Arbitrum Nitro L2 (chain 4663) using ETH for gas. Etherscan V2 does not cover this chain, so transaction history comes from its Blockscout instance, which has no gastracker or proxy module; the RPC adapter is listed first so nonce and block-height lookups go there. The chain's explorer lists many same-symbol imposters, so no built-in token address comes from a name lookup. The bridged four resolve through the L2 gateway router. USDG, CASHCAT and PONS are issued on the chain itself, so each is corroborated by more than one swap provider settling to that address and then confirmed against the contract's own name, symbol and decimals.
Documents the shipped plugin: why an Arbitrum rollup config rather than an Optimism one, why Blockscout is the only usable history source, and how the built-in token addresses were derived from the canonical bridge rather than read off an explorer's token search.
Phase 1 recorded that no swap provider quotes chain 4663 and deferred a funded send on that basis. A direct sweep of the provider APIs found six advertising the chain, three of which fill orders into it, so the doc now carries an edge-exchange-plugins section, the swap and send verification, and a retrospective note that the non-goal was inferred from Edge's own mapping files rather than checked against a provider.
Records the rates-server work as section 8 and phase 3: what the v3 API keys on, which maps register the chain, and why only half of the change reaches a running server on deploy. Adds phase 4, the pre-merge review pass, and the RPC endpoint swap it forced after the original fallback went dark. Adds phase 5, the full provider audit, and rewrites section 7's provider table from probing every provider rather than only the ones with synchronizers. Adds phase 6 and the chain-native token provenance, covering why the exchange side needed no change to reach the new tokens.
57c02ba to
ff6b61a
Compare




Technical Design Document
robinhood-chain.md
CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
none
Description
Adds Robinhood Chain (
robinhood, EVM chain 4663) as a currency plugin. It is an Arbitrum Nitro L2 with ETH as its gas token, so the plugin is configuration only:arbitrumRollupParamsselects the existing NodeInterface L1-component fee path, and no engine code changes.Asana: https://app.asana.com/1/9976422036640/project/1213843652804305/task/1217382370104887
Three choices worth a reviewer's attention, all covered in the design doc:
History comes from Blockscout, not Etherscan. Etherscan V2 does not serve chain 4663 (
Missing or unsupported chainid parameter; 4663 is absent from its/v2/chainlist). Routescan returnschain not supported, and HoodScan has no Etherscan-compatible API. Blockscout is the only source that answers, and it has nogastrackerorproxymodule, hencegastrackerSupport: falseand the RPC adapter declared first so nonce and block-height lookups do not hit the missingproxymodule.Built-in token addresses come from the canonical bridge, not a token search. This chain's explorer lists imitations that outrank the real contracts by holder count, including a 30,726-holder "USDC" named Universal Stable Digital Coin. Each bridged address was derived by calling
calculateL2TokenAddress(l1Token)on the L2 Gateway Router from Robinhood's published contract list. USDG, CASHCAT and PONS are issued natively rather than bridged. USDG was confirmed as a verified ERC-1967 proxy whose implementation is namedUSDG. CASHCAT (0x020bfC65…) and PONS (0x39dBED3a…) are each corroborated by more than one swap provider settling to that address, ChangeNow, Swapuz, LetsExchange and Rango for CASHCAT and Swapuz and Rango for PONS, and then confirmed against the contract itself:name()"Cash Cat" / "Pons",symbol()CASHCAT / PONS,decimals()18 for both, with deployed bytecode present. A single provider catalogue is not sufficient on its own, since a provider can list a wrong address as easily as an explorer can.addressQueryLookbackBlocksis 1250, not the 480 copied from Arbitrum. Blocks arrive about every 96ms here (measured: 626 blocks in 60.2s), so 480 blocks is a 46-second re-scan overlap rather than the ~2 minutes the constant means on other chains.No
ethBalCheckerContract: none of the five balance-checker addresses used across Edge's EVM plugins has code on this chain. Multicall3 is deployed at the canonical address but implements a different ABI, so it is not a substitute.Testing. Full
npm testandtscpass;test/builtinTokens.test.tscovers all seven token IDs, deriving each from its entry and asserting the key matches. Both configured RPC servers agree oneth_chainId(0x1237), block height, balance and nonce, and the NodeInterface call at0x…C8returns a base fee, confirming the Arbitrum fee path applies. The second server started asrpc.arrowrpc.com; a pre-merge review found it dead (HTTP 530, Cloudflare error 1033) and it was replaced withrobinhood-rpc.publicnode.com, re-verified through the plugin's own request shape andasRpcResultStringcleaner on all four methods plusgasEstimateL1Component. Driven in-app on the iOS simulator with this branch linked in: the wallet creates, and importing a seed with real on-chain history renders0.000000019866 ETH, matchingeth_getBalancefor that address.Transaction history was verified under a forced response, since the live endpoint rate-limits this host. The public Blockscout
/apireturns HTTP 429 after a handful of requests from one egress address and recovers after about three minutes, and the simulator's own polling shares that budget. Its v2 API has a separate quota, which is where the address's two real rows came from.fetchGetEtherscanwas then temporarily stubbed to return those rows, leaving the cleaner,processEvmScanTransactionand the list component untouched, and both rendered correctly: "Sent Ethereum -Ξ 0.011497, Jul 15 2026" and "Received Ethereum +Ξ 0, Aug 1 2026", matching the chain exactly (21000 gas at 56,326,000 wei on the outgoing transfer). The stub was reverted; screenshot attached below and marked as hack-forced.HTTP 429 already raises
RateLimitErrorand retries with exponential backoff, so no handling is missing here. A Blockscout API key would remove the ceiling with no code change, sinceEvmScanAdapteralready appends&apikey=. No Edge-held provider key covers chain 4663: Etherscan V2 does not serve it, the dRPC key is deactivated account-wide, nowNodes and quiknode have no endpoint, and Alchemy supports the network but answersROBINHOOD_MAINNET is not enabled for this app.Follow-ups, none blocking this PR:
ROBINHOOD_INITneeds adding to the deployedenv.json, or the plugin ships disabled.content.edge.app/currencyIconsV3/robinhood/(robinhood.png,chain_robinhood.png) do not exist yet, so wallets render a text placeholder.robinhood, so ETH on the chain prices at$0throughout the app.Update: send is now verified. The claim that no swap provider quotes chain 4663 was wrong: it was inferred from the chain's absence in Edge's own provider maps rather than checked against a provider API. A sweep of the provider discovery endpoints found six advertising the chain; edge-exchange-plugins#483 maps four of them. With that branch served in, a swap from Sonic funded a Robinhood Chain wallet with 0.006248511112300593 ETH, and a 0.001 ETH send from it is transaction
0x70e4950b5991c9419eff70ea2478c7ae55c5c58adcc3da237d5889394f8fdf62,successin block 35308086. Send and fee estimation on this chain are exercised, not deferred. The design doc's phase history and retrospective are updated accordingly.Note
Medium Risk
New user-facing chain and seven curated token contracts on an explorer full of impersonators; correctness depends on config and third-party RPC/Blockscout availability, though no shared engine logic changes.
Overview
Adds Robinhood Chain support as a new EVM currency plugin (
pluginIdrobinhood, chain ID 4663, native ETH gas) by wiring existingEthereumEnginebehavior through a newrobinhoodInfo.tsand registering it inethereumInfos.ts.The network config targets this chain’s quirks: RPC first, then Blockscout for history (Etherscan V2 does not cover 4663),
gastrackerSupport: false,arbitrumRollupParamsfor Nitro L1 fee estimation, a 1250-block history lookback (~2 minutes at ~96ms blocks), and a lowered 0.01 gweiminPriorityFee. Built-in tokens are USDC, USDT, USDG, WBTC, WETH, CASHCAT, and PONS, with bridged addresses from the gateway router and chain-native ones corroborated off-provider settlement addresses—not explorer search.Also adds an Unreleased CHANGELOG entry and a long
src/docs/robinhood-chain.mddesign note covering cross-repo GUI, swap, and rates follow-ups.Reviewed by Cursor Bugbot for commit ff6b61a. Bugbot is set up for automated code reviews on this repo. Configure here.