Note: If you're writing your own integration, it's more gas-efficient to include this logic directly in your contract rather than calling an external one.
TokenMessengerV2: Entrypoint for cross-chain USDC transfer. Routes messages to burn USDC on a source chain, and mint USDC on a destination chain.
MessageTransmitterV2: Generic message passing. Sends all messages on the source chain, and receives all messages on the destination chain.
TokenMinterV2: Responsible for minting and burning USDC. Contains chain-specific settings used by burners and minters.
MessageV2: Provides helper functions for cross-chain transfers, such as
bytes32ToAddress
and addressToBytes32
, which are commonly used when
bridging between EVM and non-EVM chains. These conversions are simple: prepend
12 zero bytes to an EVM address, or strip them to convert back.
Note: If you're writing your own integration, it's more gas-efficient to include this logic directly in your contract rather than calling an external one.
Full contract source code is available on GitHub.
Chain | Domain | Address |
---|---|---|
Ethereum Sepolia | 0 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
Avalanche Fuji | 1 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
OP Sepolia | 2 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
Arbitrum Sepolia | 3 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
Base Sepolia | 6 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
Polygon PoS Amoy | 7 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
Unichain Sepolia | 10 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
Linea Sepolia | 11 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
Codex Testnet | 12 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
Sonic Testnet | 13 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
World Chain Sepolia | 14 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
Sei Testnet | 16 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA |
Chain | Domain | Address |
---|---|---|
Ethereum Sepolia | 0 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 |
Avalanche Fuji | 1 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 |
OP Sepolia | 2 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 |
Arbitrum Sepolia | 3 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 |
Base Sepolia | 6 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 |
Polygon PoS Amoy | 7 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 |
Unichain Sepolia | 10 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 |
Linea Sepolia | 11 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 |
Codex Testnet | 12 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 |
Sonic Testnet | 13 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 |
World Chain Sepolia | 14 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 |
Sei Testnet | 16 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 |
Chain | Domain | Address |
---|---|---|
Ethereum Sepolia | 0 | 0xb43db544E2c27092c107639Ad201b3dEfAbcF192 |
Avalanche Fuji | 1 | 0xb43db544E2c27092c107639Ad201b3dEfAbcF192 |
OP Sepolia | 2 | 0xb43db544E2c27092c107639Ad201b3dEfAbcF192 |
Arbitrum Sepolia | 3 | 0xb43db544E2c27092c107639Ad201b3dEfAbcF192 |
Base Sepolia | 6 | 0xb43db544E2c27092c107639Ad201b3dEfAbcF192 |
Polygon PoS Amoy | 7 | 0xb43db544E2c27092c107639Ad201b3dEfAbcF192 |
Unichain Sepolia | 10 | 0xb43db544E2c27092c107639Ad201b3dEfAbcF192 |
Linea Sepolia | 11 | 0xb43db544E2c27092c107639Ad201b3dEfAbcF192 |
Codex Testnet | 12 | 0xb43db544E2c27092c107639Ad201b3dEfAbcF192 |
Sonic Testnet | 13 | 0xb43db544E2c27092c107639Ad201b3dEfAbcF192 |
World Chain Sepolia | 14 | 0xb43db544E2c27092c107639Ad201b3dEfAbcF192 |
Sei Testnet | 16 | 0xb43db544E2c27092c107639Ad201b3dEfAbcF192 |
Chain | Domain | Address |
---|---|---|
Ethereum Sepolia | 0 | 0xbaC0179bB358A8936169a63408C8481D582390C4 |
Avalanche Fuji | 1 | 0xbaC0179bB358A8936169a63408C8481D582390C4 |
OP Sepolia | 2 | 0xbac0179bb358a8936169a63408c8481d582390c4 |
Arbitrum Sepolia | 3 | 0xbaC0179bB358A8936169a63408C8481D582390C4 |
Base Sepolia | 6 | 0xbaC0179bB358A8936169a63408C8481D582390C4 |
Polygon PoS Amoy | 7 | 0xbac0179bb358a8936169a63408c8481d582390c4 |
Unichain Sepolia | 10 | 0xbaC0179bB358A8936169a63408C8481D582390C4 |
Linea Sepolia | 11 | 0xbaC0179bB358A8936169a63408C8481D582390C4 |
Codex Testnet | 12 | 0xbac0179bb358a8936169a63408c8481d582390c4 |
Sonic Testnet | 13 | 0xbaC0179bB358A8936169a63408C8481D582390C4 |
World Chain Sepolia | 14 | 0xbaC0179bB358A8936169a63408C8481D582390C4 |
Sei Testnet | 16 | 0xbaC0179bB358A8936169a63408C8481D582390C4 |
This section provides the Smart Contract Interface exposed by CCTP V2, outlining the available functions, and their parameters.
The interface below serves as a reference for permissionless messaging functions exposed by the TokenMessengerV2 and MessageTransmitterV2 functions.
TokenMessengerV2#depositForBurnWithHook
(extends depositForBurn
by adding
hook data)TokenMessengerV2#handleReceiveUnfinalizedMessage
(replaces
handleReceiveMessage
)TokenMessengerV2#handleReceiveFinalizedMessage
(replaces
handleReceiveMessage
)TokenMessengerV2#depositForBurn
MessageTransmitterV2#sendMessage
MessageTransmitterV2#receiveMessage
TokenMessengerV2#handleReceiveMessage
TokenMessengerV2#replaceDepositForBurn
TokenMessengerV2#depositForBurnWithCaller
MessageTransmitterV2#replaceMessage
MessageTransmitterV2#sendMessageWithCaller
Deposits and burns tokens from sender to be minted on destination domain, and
emits a cross-chain message by calling MessageTransmitter's sendMessage
function. Minted tokens will be transferred to mintRecipient
.
Parameters
Field | Type | Description |
---|---|---|
amount | uint256 | Amount of tokens to deposit and burn |
destinationDomain | uint32 | Destination domain ID to send the message to |
mintRecipient | bytes32 | Address of mint recipient on destination domain (must be converted to 32 byte array, that is, prefix with zeros if needed) |
burnToken | address | Address of contract to burn deposited tokens on local domain |
destinationCaller | bytes32 | Address as bytes32 which can call receiveMessage on destination domain. If set to bytes32(0), any address can call receiveMessage |
maxFee | uint256 | Max fee paid for fast burn, specified in units of burnToken |
minFinalityThreshold | uint32 | Minimum finality threshold at which burn will be attested |
Deposits and burns tokens from sender to be minted on destination domain, and
emits a cross-chain message with additional hook data appended. In addition to
the standard depositForBurn
parameters, depositForBurnWithHook
accepts a
dynamic-length hookData
parameter, allowing the caller to include additional
metadata to the attested message, which can be used to trigger custom logic on
the destination chain.
Parameters
Field | Type | Description |
---|---|---|
amount | uint256 | Amount of tokens to burn |
destinationDomain | uint32 | Destination domain to send the message to |
mintRecipient | bytes32 | Address of mint recipient on destination domain (must be converted to 32 byte array, that is, prefix with zeros if needed) |
burnToken | address | Address of contract to burn deposited tokens on local domain |
destinationCaller | bytes32 | Address as bytes32 which can call receiveMessage on destination domain. If set to bytes32(0), any address can call receiveMessage |
maxFee | uint256 | Max fee paid for fast burn, specified in units of burnToken |
minFinalityThreshold | uint32 | Minimum finality threshold at which burn will be attested |
hookData | bytes | Additional metadata attached to the attested message, which can be used to trigger custom logic on the destination chain |
Calculates and returns the minimum fee required for a given amount in a Standard
Transfer. If the minFee
(per unit of burnToken
) is non-zero, the specified
maxFee
must be at least the returned minimum fee. Otherwise, the burn will
revert onchain.
Parameters
Field | Type | Description |
---|---|---|
amount | uint256 | The amount used to compute the minimum fee. Must be greater than 1 if standard fee is applied |
Handles incoming message received by the local MessageTransmitter, and takes the
appropriate action. For a burn message, mints the associated token to the
requested recipient on the local domain. Validates the function sender is the
local MessageTransmitter, and the remote sender is a registered remote
TokenMessenger for remoteDomain
.
Parameters
Field | Type | Description |
---|---|---|
remoteDomain | uint32 | The domain where the message originated from |
sender | bytes32 | The sender of the message (remote TokenMessenger) |
finalityThresholdExecuted | uint32 | Specifies the level of finality Iris signed the message with |
messageBody | bytes (dynamic length) | The message body bytes |
Handles incoming message received by the local MessageTransmitter, and takes the
appropriate action. For a burn message, mints the associated token to the
requested recipient on the local domain. Validates the function sender is the
local MessageTransmitter, and the remote sender is a registered remote
TokenMessenger for remoteDomain
.
Similar to handleReceiveFinalizedMessage
, but is called for messages which are
not finalized (finalityThresholdExecuted
< 2000).
Unlike handleReceiveFinalizedMessage
, handleReceiveUnfinalizedMessage
has
the following messageBody
parameters:
expirationBlock
. If expirationBlock
≤ blockNumber
on the destination
domain, the message will revert and must be re-signed without the expiration
block.feeExecuted
. If nonzero, the feeExecuted
is minted to the
feeRecipient
.Parameters
Field | Type | Description |
---|---|---|
remoteDomain | uint32 | The domain where the message originated from |
sender | bytes32 | The sender of the message (remote TokenMessenger) |
finalityThresholdExecuted | uint32 | Specifies the level of finality Iris signed the message with |
messageBody | bytes (dynamic length) | The message body bytes (see Message format) |
Receive message on destination chain by passing message and attestation. Emits
MessageReceived
event. Messages with a given nonce can only be broadcast
successfully once for a pair of domains. The message body of a valid message is
passed to the specified recipient for further processing.
Parameters
Field | Type | Description |
---|---|---|
message | bytes | Encoded message (see Message format) |
attestation | bytes | Signed attestation received from attestation service (Iris) |
Sends a message to the recipient on the destination domain. Emits a
MessageSent
event which will be attested by Circle's attestation service.
Parameters
Field | Type | Description |
---|---|---|
destinationDomain | uint32 | Destination domain ID to send the message to |
recipient | bytes32 | Address of recipient on destination domain |
destinationCaller | bytes32 | Address as bytes32 which can call receiveMessage on destination domain. If set to bytes32(0), any address can call receiveMessage |
minFinalityThreshold | uint32 | Minimum finality threshold requested. Initially, supported values for minFinalityThreshold are [1, 2000]. A value outside of the support values range will be interpreted as 2000 (finalized) by the attestation service (Iris). For a value within the supported range, the attestation service (Iris) will attest the message with a finalityThresholdExecuted >= minFinalityThreshold . Initial thresholds supported: 1000: Confirmed 2000: Finalized |
messageBody | bytes | App-specific message to be handled by recipient |
This table highlights the key workflow improvements of CCTP V2 over CCTP V1 in terms of enhanced cross-chain messaging, fewer manual steps, and greater control over message acceptance:
CCTP V2 | CCTP V1 |
---|---|
Burn USDC via depositForBurnWithHook Currently, you can call depositForBurnWithHook on TokenMessengerV2, which supports hooks and finality thresholds. New parameters include destinationCaller , maxFee , and minFinalityThreshold , allowing you to choose Fast Transfer (1000) or Standard Transfer (2000). | Burn USDC via depositForBurn In CCTP V1, you call depositForBurn on TokenMessenger. |
Retrieve, Hash, and Wait for Attestation Currently, Iris automates message retrieval and hashing, allowing you to just poll for attestation via GET /v2/messages. The attestation includes both the hashed message and the attestation signature. | Retrieve and Hash Message explicitly In CCTP V1, you need to manually extract and hash the messageBytes data from the MessageSent event logs using Keccak256 . |
Wait for Attestation via Iris Currently, the attestation request is merged with message retrieval and hashing from the previous step. You simply wait for the polling to complete and retrieve the attestation. | Request Attestation from Circle's Attestation Service In CCTP V1, you poll for attestation via GET /v1/attestations. |
Send Messages via MessageTransmitterV2#sendMessage Currently, the recipient must implement message handling methods based on finality thresholds: • handleReceiveFinalizedMessage for messages with finalityThresholdExecuted ≥ 2000 (fully finalized). • handleReceiveUnfinalizedMessage for messages with finalityThresholdExecuted < 2000 (pre-finalized). This allows recipients to enforce specific finality requirements before accepting a message. | Send Messages via MessageTransmitter#sendMessage In CCTP V1, you send an arbitrary message via sendMessage on MessageTransmitter. The recipient must implement IMessageHandler#handleReceiveMessage to process the message. |
WHAT'S NEXT