Technical Reference

Integrate CCTP using these attestation confirmation times, message formats, transaction limits, and more.

Cross-Chain Transfer Protocol (CCTP) is a permissionless on-chain utility that can burn native USDC on a source chain and mint native USDC of the same amount on a destination chain. Developers can embed CCTP into their apps to provide users with the most capital-efficient way to transfer USDC across chains, unifying liquidity across the ecosystem and simplifying user experience.

Domain

Circle-issued identifier for a network/chain where CCTP contracts are deployed. This is passed into the destinationDomain field.

Domain List

NameValue
Ethereum0
Avalanche1

Block Confirmations for Attestations

Before signing an attestation for a source chain event, Circle waits for a specified number of on-chain block confirmations to pass to determine finality. We also check that the block is finalized on Ethereum mainnet. The average time below is the average time it takes for an attestation to become available, which includes the ~20 seconds it takes for the attestation service to observe and sign the source chain event. These values are subject to change.

Mainnet

Source ChainNumber of BlocksAverage Time
Ethereum65~13 minutes
Avalanche1~20 seconds

Testnet

Source ChainNumber of BlocksAverage Time
Ethereum5~1 minute
Avalanche1~20 seconds

Nonce

This is a unique identifier for a message that can be used once, in any order, on the destination domain. When a message is received on the destination domain, its nonce is marked as used in the destination MessageTransmitter contract.

📘

How nonces are stored

On the source domain's MessageTransmitter contract, the next sequential nonce available for a source domain is stored as a public uint64, nextAvailableNonce. On the destination chain, MessageTransmitter contracts store used nonces in a mapping of (bytes32 -> uint256), where bytes32 is a hash of source domain and source domain nonce, and uint256 is 0 if unused, 1 if used.

Message Format

Message

This is the top-level message header format, which is standard for all messages passing through CCTP.

FieldBytesTypeIndexDescription
version4uint320Version identifier.
sourceDomain4uint324Source domain id.
destinationDomain4uint328Destination domain id.
nonce8uint6412Unique message nonce.
sender32bytes3220Address of MessageTransmitter caller on source domain.
recipient32bytes3252Address to handle message body on destination domain.
destinationCaller32bytes3284Address permitted to call MessageTransmitter on destination domain, or bytes32(0) if message can be received by any address
messageBodydynamicbytes116Application-specific message to be handled by recipient.

📘

Why we use bytes32 type for addresses

CCTP is built to support EVM chains, which use 20 byte addresses, and non-EVM chains, many of which use 32 byte addresses. We provide a Message.sol library as a reference implementation for converting between address and bytes32 in Solidity.

BurnMessage

The message format includes a dynamically sized messageBody field, used for application-specific messages. For example, TokenMessenger defines a BurnMessage with data related to cross-chain transfers.

FieldBytesTypeIndexDescription
version4uint320Version identifier.
burnToken32bytes324Address of burned token on source domain.
mintRecipient32bytes3236Address to receive minted tokens on destination domain
amount32uint25668Amount of burned tokens
messageSender32bytes32100Address of caller of depositForBurn (or depositForBurnWithCaller) on source domain

Transaction Limits

Minter Allowance
The USDC smart contract has a concept of minter allowance. This amount is decremented each time the minter mints, and eventually must be re-upped by the master minter. CCTP contracts responsible for minting USDC are periodically re-upped, so if a user tries to mint an amount exceeding the minter allowance, the transaction will fail, but may succeed on a subsequent retry. Minter allowance can be queried from the USDC contract using the public minterAllowance function.

Per-Message Burn Limit
CCTP defines per-message burn limits. This value is configurable by the CCTP administrator (Circle). This limit prevents the case where a user burns an amount on one chain that could never be minted on a destination chain without increasing minter allowance thresholds. Burn limits can be queried on the CCTP TokenMinter contract, using the public burnLimitsPerMessage mapping.