Skip to content

Add Networks section with Arc page - #105

Open
zherring wants to merge 3 commits into
mainfrom
zherring/networks-arc
Open

zherring wants to merge 3 commits into
mainfrom
zherring/networks-arc

Conversation

@zherring

@zherring zherring commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds a top-level Networks section to the nav, with an index page and an Arc page (/networks/arc).
  • The Arc page covers what is deployed on Arc, SDK requirements, how the native and ERC-20 USDC token ids behave in Splits, Push vs Pull guidance, distributing and withdrawing, network notes, and a pre-transaction checklist.
  • public/llms.txt gets a ## Networks section with entries for both pages. The markdown twins and llms-full.txt pick the pages up automatically from _meta.json.
  • The introduction page's network list now names Arc and Robinhood Chain.

How the claims were checked

  • Primary sources: contract source at tag splits-v2.2, and the @0xsplits/splits-sdk 6.7.0 package.
  • Read-only eth_getCode, eth_call with state overrides, and eth_getLogs against Arc mainnet and testnet.
  • Real transactions on Arc mainnet, described in "Mainnet test" below.
  • Arc-owned facts (USDC native/ERC-20 views, fee requirements, duplicate Transfer logs) link to Arc's docs instead of being restated.

Mainnet test (2026-10-23)

The token-id behavior on the page was checked with real transactions on Arc mainnet, not only simulations. A throwaway wallet created four splits and ran each through fund, distribute and (for Pull) withdraw, using @0xsplits/splits-sdk 6.7.0 and viem. Each split had 3 recipients (50/30/20), no owner, a 0 distributor fee, and 0.1 USDC of principal. All transactions succeeded. Leftover funds were swept back afterwards.

Run Split type Funded by distribute / withdraw id Split address
1 Pull ERC-20 transfer 0x3600… 0x7560aA123F217A1281A1F7D1b4f629c1f34CB5f5
2 Pull native send 0xEeee… 0xb6d8F7BE383f2caAf24EC01853522C5D189eD130
3 Pull native send 0x3600… 0xc79913251CF91c1c227d897f4057c9797259D829
4 Push ERC-20 transfer 0x3600… (with splitFields) 0x7De8Ee7C00824Ab33B5de53c5b2c8F19A7740CB3

What the runs showed:

  • Funding by either route is visible under both ids. After an ERC-20 transfer of 0.1 USDC (run 1), getSplitBalance returned 100000 under 0x3600… and 100000000000000000 under 0xEeee….
  • distribute credits only the id you pass. Run 1 credited recipients' Warehouse balances under 0x3600… (49,999 / 29,999 / 19,999) and left 0xEeee… at 0. Run 2 credited only 0xEeee…, and the recipients' 0x3600… balances did not change. Run 3, funded natively but distributed under 0x3600…, matched run 1.
  • withdraw pays the balance minus 1, per id. Run 1 paid 49,998 / 29,998 / 19,998 units. Run 2 (native id) paid 49999999999999998 / 29999999999999998 / 19999999999999998 wei, each 1 wei below the credited balance.
  • A Pull split keeps more than 1 unit behind. In run 1, 6 of 100,000 units stayed in the contracts: 1 in the split, 2 in the split's Warehouse balance, and 1 in each recipient's Warehouse balance. The unit left in a recipient's Warehouse balance carries over: run 3 ran after run 1 and found 50,000 / 30,000 / 20,000 in the recipients' balances (49,999 / 29,999 / 19,999 newly credited, plus 1 each left from run 1), and withdrew 49,999 / 29,999 / 19,999.
  • Push pays directly. Run 4 paid 49,999 / 29,999 / 19,999 units in the distribute transaction. splitFields skipped config recovery and worked in 6.7.0.
  • Config recovery works on Arc. For all four splits, the SDK's log-based recovery rebuilt a config whose keccak256(abi.encode(config)) equals splitHash(), and updateBlockNumber() matched the block it read.
  • Transfer logs depend on the route. ERC-20 transfers, and distribute or withdraw under 0x3600…, emitted two logs per move: one from 0xffff…fffE and one from 0x3600…. Native sends, and distribute or withdraw under 0xEeee…, emitted one, from 0xffff…fffE.
  • Gas price. Runs 1 to 3 ran at 25 gwei and run 4 at 20 gwei. All transactions succeeded.

Not covered by the transactions, so these still rest on eth_call simulation: withdrawing under an id with no credit reverting, blocklisted and reverting recipients, owned splits (update and pause), and Push on the native id.

Safeguards in the harness: chain id 5042 only, an allowlist of signers, payees and calldata, a principal cap per invocation, and no automatic retries on broadcasts. The harness itself is not committed to this repo.

Transaction hashes (Arc mainnet, chain id 5042)

Run 1 (Pull, funded by ERC-20 transfer, id 0x3600…)

  • createSplitDeterministic (pull): 0x44f0672c6635d19edd7c7e8bb16008b5ea8ad78f9aa7cb51342a046399d0e279 (148023 gas)
  • fund 0.1 USDC via ERC-20 transfer on 0x3600: 0x8e1071ffbc04c7a1eeb1ebc3a6624a1195eb0079813649892680e1846dcbb5bd (48950 gas)
  • distribute(token=0x3600 (0x3600), distributor=0x8caE3eaD2A22882c1a9A453414e8F5628aF53E4a): 0x11706e2843fdfb350047908a2557c8f769d318c732283197d27f81e8932ac3ae (205949 gas)
  • withdraw owner=0x07413009D3e3780d4Bb0433e3Ad6Ec099463508A token=0x3600 (0x3600): 0x3daab51c17a9c4823981c18e45caa5b6fb7c0e64a0cc2306f0a39842c95fde8e (92926 gas)
  • withdraw owner=0x71fd7Cb9Bb83DEA0A45a2069a6fF84be4F603D6e token=0x3600 (0x3600): 0x75eacd78035aa3628b9cf1226cd0e9829f8d8ec5ee564157853eed5dbdada050 (92926 gas)
  • withdraw owner=0xBdfc1Ac87fa808dE4A27C05b31Eab40939951EB7 token=0x3600 (0x3600): 0x704ad6e0cce762b312634a230408600da3039f8ce5cc967e25127322073dd8cf (92926 gas)

Run 2 (Pull, funded by native send, id 0xEeee…)

  • createSplitDeterministic (pull): 0xd5e5080fa2e9ed637d776fca9ebb61c87a62dee2cf208ae7da712c20f12e049e (148035 gas)
  • fund 0.1 USDC via native value send: 0x340557ce1f15710121a05d7c5c21f3408350abeb7d93fc48f359c3b0cb4c89e2 (22038 gas)
  • distribute(token=0xEeee (native), distributor=0x8caE3eaD2A22882c1a9A453414e8F5628aF53E4a): 0x796abd6c58d6f97006edd3d5957f4b76838e6208213809d96b95c488974861a3 (151536 gas)
  • withdraw owner=0x07413009D3e3780d4Bb0433e3Ad6Ec099463508A token=0xEeee (native): 0x830e19dddf020cbf18574fdb59717455b6bfbab563c4fae45f4e811a6e0b3a90 (44746 gas)
  • withdraw owner=0x71fd7Cb9Bb83DEA0A45a2069a6fF84be4F603D6e token=0xEeee (native): 0x6e8d9bacabeaefaffdb4b6f15384464a402c5bcc77d23e767629dca7e5d0ecad (44746 gas)
  • withdraw owner=0xBdfc1Ac87fa808dE4A27C05b31Eab40939951EB7 token=0xEeee (native): 0xc238f8369e36585030be094d395f9f0fd7b141b31795127415c9eb643f6df436 (44746 gas)

Run 3 (Pull, funded by native send, id 0x3600…)

  • createSplitDeterministic (pull): 0x84c908525d94663e0b67bb9bf866512bbb942d7279615345e260a8bcdc157d34 (148035 gas)
  • fund 0.1 USDC via native value send: 0x6ebd2c1a74b369d55ce4dcf41bc01674bb1b43bd462cf873a4c9218b2badebf5 (22038 gas)
  • distribute(token=0x3600 (0x3600), distributor=0x8caE3eaD2A22882c1a9A453414e8F5628aF53E4a): 0x1e109c863909d4b8200aa85d7a9629a9d1dfb52684bc7fff1ce0b37086ef7dc8 (154649 gas)
  • withdraw owner=0x07413009D3e3780d4Bb0433e3Ad6Ec099463508A token=0x3600 (0x3600): 0x325614021e89f6ba432ab47f0379e67952aa931c9a12e09ace89f86debe7da18 (67926 gas)
  • withdraw owner=0x71fd7Cb9Bb83DEA0A45a2069a6fF84be4F603D6e token=0x3600 (0x3600): 0x3c41b3eaf90553d69db6e1c25da21fdd325b08d6c25f5898880116b21b214b0b (67926 gas)
  • withdraw owner=0xBdfc1Ac87fa808dE4A27C05b31Eab40939951EB7 token=0x3600 (0x3600): 0x883aecae305239985140823c1c0bdb25922d94e4a5ce3cd2ea2f83e43831a84c (67926 gas)

Run 4 (Push, funded by ERC-20 transfer, id 0x3600… (with splitFields))

  • createSplitDeterministic (push): 0x12fd4a288390a9516387d31be6cd52b65a124e65d1b068563153cdc214108361 (147941 gas)
  • fund 0.1 USDC via ERC-20 transfer on 0x3600: 0x55e432e5a65d55d3aacb4bc05a829e170f743782620526e09627c17a8025843c (48938 gas)
  • distribute(token=0x3600 (0x3600), distributor=0x8caE3eaD2A22882c1a9A453414e8F5628aF53E4a) with splitFields: 0xe0070d94419bcb3fd034d8f74e0d61279491b0683e72c1fe40b922500530994b (112326 gas)

Deliberately not asserted

  • Sub-20-gwei mempool-drop behavior: the page says Arc sets a minimum fee per gas and links to Arc's docs.
  • Mainnet blocklist contents. The blocklist cases were observed with an address blocked on Arc testnet, and the page says so.
  • Which token id the Splits app uses.

Notes for reviewers

  • 0x3600...0000 is an upgradeable contract controlled by Circle/Arc, so USDC behavior described on the page can change.
  • Line 5 of public/llms.txt is changed separately in Update llms.txt for protocols we support #104 and is intentionally not touched here.
  • distribute accepts a splitFields argument in the SDK that is not in the SDK docs; the page mentions it.

Test plan

  • pnpm build passes
  • /protocol/docs/networks/arc renders with a "Networks" breadcrumb
  • /protocol/docs/networks/arc.md twin has the tables

🤖 Generated with Claude Code

https://claude.ai/code/session_01WmTHDeVKp4PcqbpqhvBGME

Adds a top-level Networks section with an Arc page covering what is deployed,
SDK requirements, and how the native and ERC-20 USDC token ids behave. Adds the
section to llms.txt and names Arc and Robinhood Chain on the introduction page.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WmTHDeVKp4PcqbpqhvBGME
@vercel

vercel Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
protocol-docs Ready Ready Preview Oct 26, 2026 3:32pm UTC

Request Review

Four 0.1 USDC splits on Arc mainnet (Pull and Push; ERC-20 and native
funding) confirmed that funding by either route is visible under both
ids, distribute credits only the id passed, and withdraw pays per id.
Only the failure-mode table still rests on simulation.

A Pull split also keeps 1 unit in its own Warehouse balance, plus
rounding remainders, so replace "leaves 1 unit in the split" with the
measured breakdown.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WmTHDeVKp4PcqbpqhvBGME
Cut the createSplit defaults, the "Push or Pull on Arc" table and the
pre-transaction checklist, which restate the SDK and SplitV2 pages.
Shrink the not-deployed table to a sentence and drop the repeated chain
ids.

Fix three statements against the splits-v2.2 contracts: a blocklisted
distributor only reverts a Push distribute when the fee is above 0, a
Pull split credits the distributor reward to the Warehouse instead of
paying it out, and a native Push split can still be blocked by a
recipient that re-enters distribute (link to the SplitV2 notes).
Describe Transfer logs per route as observed on mainnet.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WmTHDeVKp4PcqbpqhvBGME
@zherring
zherring marked this pull request as ready for review October 26, 2026 16:59
@zherring
zherring requested a review from 0xdiid October 26, 2026 16:59

This branch was successfully deployed

1 active deployment
Preview — 3bb3d20c Deployed Oct 26, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants