Skip to main content
Circle’s Cross-Chain Transfer Protocol moves native USDC between chains. Its depositForBurn burns it on this chain, Circle attests the burn, and a receiveMessage on the destination mints it there.

When to use it

  • Move USDC to another chain as native USDC, with Circle’s attestation as the only trust.
  • Only the burn happens in the program’s transaction. The mint is a separate transaction on the destination, sent by anyone with the attestation.

Pitfalls for a program

  • Approve the TokenMessenger for the amount first.
  • destinationDomain is Circle’s domain id, not the chain id: each chain’s file in chains gives its CCTP domain.
  • mintRecipient and destinationCaller are 32-byte words: an EVM address fits as is, and a destinationCaller of 0 lets anyone complete the mint.
  • minFinalityThreshold 2000 waits for standard finality; 1000 asks for a fast transfer, for which maxFee (in USDC units, taken on the destination) must cover Circle’s fee.

In a Sauce program

Burn the Pot’s USDC on Base for recipient on Arbitrum:
To Arc the domain is 26, for Arc and Arc Testnet alike. From Base to recipient on Arc, the burn is Cctp.TokenMessenger.depositForBurn(amount, 26, recipient, USDC, 0, maxFee, 2000), after the same approve:
A burn on Arc spends Arc’s USDC token, in its 6 decimals. Burn a given amount rather than pot.USDC whole: the token and the Pot’s native coin are one balance there. A simulation or a cook of the burn shows only the source chain: USDC leaves the Pot and is burned. The mint on the destination comes after Circle attests the burn, in a transaction of its own, which no program here sends.

Notes

  • Domains are Circle’s numbering; the registry records them per chain.
  • On a testnet (Arc Testnet, Base Sepolia, Ethereum Sepolia) the TokenMessenger is Circle’s testnet contract, not the mainnet one, and the domain is the mainnet’s (Arc Testnet 26, Base Sepolia 6, Ethereum Sepolia 0). Cctp.TokenMessenger resolves to the chain’s own; its attestation comes from Circle’s sandbox API, https://iris-api-sandbox.circle.com.

Its names in a program

On Ethereum, Cctp is a namespace: its contracts need no import.

Deployments

ABI

TokenMessengerABI

import TokenMessengerABI from "./protocols/cctp/TokenMessengerABI.json"; Speaks for: tokenMessenger.
  • depositForBurn(uint256 amount, uint32 destinationDomain, bytes32 mintRecipient, address burnToken, bytes32 destinationCaller, uint256 maxFee, uint32 minFinalityThreshold)

Next steps