Skip to content

docs: add CCTP V2 integration guide for Arc Testnet (closes #110)#127

Open
zkasuran wants to merge 1 commit into
circlefin:mainfrom
zkasuran:docs/cctp-v2-integration
Open

docs: add CCTP V2 integration guide for Arc Testnet (closes #110)#127
zkasuran wants to merge 1 commit into
circlefin:mainfrom
zkasuran:docs/cctp-v2-integration

Conversation

@zkasuran

@zkasuran zkasuran commented Jun 8, 2026

Copy link
Copy Markdown

What this does

Adds a CCTP V2 integration guide at docs/cctp-v2-integration.md and links it from the README documentation section. It resolves #110.

The guide documents the Arc-specific details a developer needs to move native USDC on and off Arc with Cross-Chain Transfer Protocol V2, which are not currently in this repo or obvious from Circle's general docs:

  • Arc CCTP domain is 26. Required as destinationDomain in depositForBurn.
  • All Arc CCTP contracts are V2. The V1 depositForBurn selector (0x6fd3504e) reverts against the V2 TokenMessenger. The V2 selector is 0x8e0250ee. This trips up code ported from older Circle examples.
  • Use minFinalityThreshold: 2000 for burns sourced from Arc. 1000 (Fast Transfer) can leave the attestation stuck pending.
  • eth_estimateGas can return data: null for depositForBurn, so pass an explicit gasLimit (covered with the typical gas range).
  • How to fetch the attestation from the Iris API and check route fees.

How I verified the values

  • Domain 26 and the source-chain domains (Ethereum 0, Base 6, Avalanche 1): Circle's supported blockchains.
  • Contract addresses: Circle's EVM smart contracts reference. I also confirmed the TokenMessenger 0x8FE6…2DAA returns contract code (2175 bytes) on Arc Testnet via eth_getCode.
  • Selectors: computed keccak256 of both signatures. V2 depositForBurn(uint256,uint32,bytes32,address,bytes32,uint256,uint32) = 0x8e0250ee, V1 depositForBurn(uint256,uint32,bytes32,address) = 0x6fd3504e.
  • minFinalityThreshold semantics (1000 = Fast/confirmed, 2000 = Standard/finalized): Circle's contract interfaces. The "use 2000 on Arc" guidance comes from the field report in docs: CCTP V2 integration on Arc Testnet — domain 26, minFinalityThreshold 2000, V1 selector incompatible #110; I documented it as Arc behavior, not as a Circle spec.
  • Iris endpoints: the /v2/messages/{sourceDomain} and /v2/burn/USDC/fees/{src}/{dst} paths return well-formed responses against the sandbox host.

Docs-only change, no code touched.

AI disclosure

This guide was prepared with help from Claude (Anthropic), which drafted the prose. Every value (domain, contract addresses, selectors, finality thresholds, API paths) was verified against Circle's official documentation, an on-chain eth_getCode call, a local keccak computation of the selectors, and live calls to the Iris sandbox API before submitting. The verification steps are listed above so they can be rechecked.

Documents the Arc-specific details needed to move native USDC on and off
Arc with CCTP V2, addressing circlefin#110:

- Arc CCTP domain is 26 (verified against Circle's supported-blockchains
  list; the testnet shares the mainnet domain).
- All Arc CCTP contracts are V2. The V1 depositForBurn selector
  (0x6fd3504e) reverts against the V2 TokenMessenger; the V2 selector is
  0x8e0250ee. Both were checked by computing keccak of the signatures.
- Burns sourced from Arc should use minFinalityThreshold 2000 (finalized);
  1000 can leave the attestation stuck pending.
- eth_estimateGas can return data:null for depositForBurn, so pass an
  explicit gasLimit.
- How to fetch the attestation from the Iris API and the fee endpoint.

Contract addresses are from Circle's EVM smart contracts reference and the
TokenMessenger was confirmed to have code on Arc Testnet. Adds a link from
the README documentation section.
@memosr

memosr commented Jun 15, 2026

Copy link
Copy Markdown

Independently verified the technical values in this guide and they all check out:

  • Domain 26, USDC 0x3600000000000000000000000000000000000000, and the four V2 contract addresses (TokenMessengerV2 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA, MessageTransmitterV2 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275, TokenMinterV2 0xb43db544E2c27092c107639Ad201b3dEfAbcF192, MessageV2 0xbaC0179bB358A8936169a63408C8481D582390C4) match Circle's evm-smart-contracts reference and the official Arc skill values.
  • Selectors are correct by construction: cast sig gives V2 depositForBurn(uint256,uint32,bytes32,address,bytes32,uint256,uint32) = 0x8e0250ee and V1 depositForBurn(uint256,uint32,bytes32,address) = 0x6fd3504e.
  • The minFinalityThreshold 1000 (fast) / 2000 (finalized) semantics match the technical guide.

One small wording nit: the guide says "a value above 2000 is capped to 2000," but per the technical guide the rule is "any value below 1000 is treated as 1000, and any value above 1000 is treated as 2000" — so 10011999 also round up to 2000. Might be worth rephrasing to avoid implying e.g. 1500 stays 1500.

The gas-limit (600k) and USDC-system-address gotchas raised on #110 are already covered here. LGTM.

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.

docs: CCTP V2 integration on Arc Testnet — domain 26, minFinalityThreshold 2000, V1 selector incompatible

2 participants