Skip to main content
This is CCTP V1 version. For the latest version, see CCTP.

Contract responsibilities

  • TokenMessenger: Entrypoint for cross-chain USDC transfer. Routes messages to burn USDC on a source chain, and mint USDC on a destination chain.
  • MessageTransmitter: Generic message passing. Sends all messages on the source chain, and receives all messages on the destination chain.
  • TokenMinter: Responsible for minting and burning USDC. Contains chain-specific settings used by burners and minters.
  • Message: 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.

Mainnet contract addresses

TokenMessenger: Mainnet

ChainDomainAddress
Ethereum00xBd3fa81B58Ba92a82136038B25aDec7066af3155
Avalanche10x6B25532e1060CE10cc3B0A99e5683b91BFDe6982
OP Mainnet20x2B4069517957735bE00ceE0fadAE88a26365528f
Arbitrum30x19330d10D9Cc8751218eaf51E8885D058642E08A
Base60x1682Ae6375C4E4A97e4B583BC394c861A46D8962
Polygon PoS70x9daF8c91AEFAE50b9c0E69629D3F6Ca40cA3B3FE
Unichain100x4e744b28E787c3aD0e810eD65A24461D4ac5a762

MessageTransmitter: Mainnet

ChainDomainAddress
Ethereum00x0a992d191DEeC32aFe36203Ad87D7d289a738F81
Avalanche10x8186359aF5F57FbB40c6b14A588d2A59C0C29880
OP Mainnet20x4D41f22c5a0e5c74090899E5a8Fb597a8842b3e8
Arbitrum30xC30362313FBBA5cf9163F0bb16a0e01f01A896ca
Base60xAD09780d193884d503182aD4588450C416D6F9D4
Polygon PoS70xF3be9355363857F3e001be68856A2f96b4C39Ba9
Unichain100x353bE9E2E38AB1D19104534e4edC21c643Df86f4

TokenMinter: Mainnet

ChainDomainAddress
Ethereum00xc4922d64a24675E16e1586e3e3Aa56C06fABe907
Avalanche10x420F5035fd5dC62a167E7e7f08B604335aE272b8
OP Mainnet20x33E76C5C31cb928dc6FE6487AB3b2C0769B1A1e3
Arbitrum30xE7Ed1fa7f45D05C508232aa32649D89b73b8bA48
Base60xe45B133ddc64bE80252b0e9c75A8E74EF280eEd6
Polygon PoS70x10f7835F827D6Cf035115E10c50A853d7FB2D2EC
Unichain100x726bFEF3cBb3f8AF7d8CB141E78F86Ae43C34163

Message: Mainnet

ChainDomainAddress
Ethereum00xB2f38107A18f8599331677C14374Fd3A952fb2c8
Avalanche10x21F337db7A718F23e061262470Af8c1Fd01232D1
OP Mainnet20xDB2831EaF163be1B564d437A97372deB0046C70D
Arbitrum30xE189BDCFbceCEC917b937247666a44ED959D81e4
Base60x827ae40E55C4355049ab91e441b6e269e4091441
Polygon PoS70x02d9fa3e7f870E5FAA7Ca6c112031E0ddC5E646C
Unichain100x395b1be6E432033B676e3e36B2c2121a1f952622

Testnet contract addresses

TokenMessenger: Testnet

ChainDomainAddress
Ethereum Sepolia00x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5
Avalanche Fuji10xeb08f243E5d3FCFF26A9E38Ae5520A669f4019d0
OP Sepolia20x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5
Arbitrum Sepolia30x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5
Base Sepolia60x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5
Polygon PoS Amoy70x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5
Unichain Sepolia100x8ed94B8dAd2Dc5453862ea5e316A8e71AAed9782

MessageTransmitter: Testnet

ChainDomainAddress
Ethereum Sepolia00x7865fAfC2db2093669d92c0F33AeEF291086BEFD
Avalanche Fuji10xa9fB1b3009DCb79E2fe346c16a604B8Fa8aE0a79
OP Sepolia20x7865fAfC2db2093669d92c0F33AeEF291086BEFD
Arbitrum Sepolia30xaCF1ceeF35caAc005e15888dDb8A3515C41B4872
Base Sepolia60x7865fAfC2db2093669d92c0F33AeEF291086BEFD
Polygon PoS Amoy70x7865fAfC2db2093669d92c0F33AeEF291086BEFD
Unichain Sepolia100xbc498c326533d675cf571B90A2Ced265ACb7d086

TokenMinter: Testnet

ChainDomainAddress
Ethereum Sepolia00xE997d7d2F6E065a9A93Fa2175E878Fb9081F1f0A
Avalanche Fuji10x4ED8867f9947A5fe140C9dC1c6f207F3489F501E
OP Sepolia20xE997d7d2F6E065a9A93Fa2175E878Fb9081F1f0A
Arbitrum Sepolia30xE997d7d2F6E065a9A93Fa2175E878Fb9081F1f0A
Base Sepolia60xE997d7d2F6E065a9A93Fa2175E878Fb9081F1f0A
Polygon PoS Amoy70xE997d7d2F6E065a9A93Fa2175E878Fb9081F1f0A
Unichain Sepolia100x7348358C94519Da790DB38638d8c23669d343Bc6

Message: Testnet

ChainDomainAddress
Ethereum Sepolia00x80537e4e8bAb73D21096baa3a8c813b45CA0b7c9
Avalanche Fuji10xeAf1DB5E3eb86FEbD8080368a956622b62Dcb78f
OP Sepolia20xffbeA106ce4A3CdAfcC82BAebeD78C81814e32Ed
Arbitrum Sepolia30x70fAB9868cd54E12C7d87196424d6E0ca21be534
Base Sepolia60x8E52a9e76148185536F0f0779749Cc895E5f70dC
Polygon PoS Amoy70x8E52a9e76148185536F0f0779749Cc895E5f70dC
Unichain Sepolia100x1Fae490d95dDcFFD70728AF5024C524ed303a2e3

CCTP V1 Interface

This section provides the CCTP V1 Smart Contract Interface exposed by CCTP V1, outlining the available functions, and their parameters. The interface below serves as a reference for permissionless messaging functions exposed by the TokenMessenger and MessageTransmitter functions. The full ABIs are available on GitHub.

TokenMessenger

depositForBurn

Deposits and burns tokens from sender to be minted on destination domain. Minted tokens will be transferred to mintRecipient. Parameters
FieldTypeDescription
amountuint256Amount of tokens to deposit and burn
destinationDomainuint32Destination domain identifier
mintRecipientbytes32Address of mint recipient on destination domain
burnTokenaddressAddress of contract to burn deposited tokens on local domain

depositForBurnWithCaller

Same as depositForBurn but with an additional parameter, destinationCaller. This parameter specifies which address has permission to call receiveMessage on the destination domain for the message. Parameters
FieldTypeDescription
amountuint256Amount of tokens to deposit and burn
destinationDomainuint32Destination domain identifier
mintRecipientbytes32Address of mint recipient on destination domain
burnTokenaddressAddress of contract to burn deposited tokens on local domain
destinationCallerbytes32Address of caller on the destination domain

replaceDepositForBurn

Replace a BurnMessage to change the mint recipient and/or destination caller. Allows the sender of a previous BurnMessage (created by depositForBurn or depositForBurnWithCaller) to send a new BurnMessage to replace the original. The new BurnMessage will reuse the amount and burn token of the original, without requiring a new deposit. This is useful in situations where the user specified an incorrect address and has no way to safely mint the previously burned USDC.
The sender of the original depositForBurn has access to call replaceDepositForBurn. The resulting mint will supersede the original mint, as long as the original mint has not confirmed yet onchain. When using a third-party app/bridge that integrates with CCTP V1 to burn and mint USDC, it is the choice of the app/bridge if and when to replace messages on behalf of users. When sending USDC to smart contracts, be aware of the functionality that those contracts have and their respective trust model.
Parameters
FieldTypeDescription
originalMessagebytes calldataOriginal message bytes (to replace)
originalAttestationbytes calldataOriginal attestation bytes
newDestinationCallerbytes32The new destination caller, which may be the same as the original destination caller, a new destination caller, or an empty destination caller, indicating that any destination caller is valid
newMintRecipientbytes32The new mint recipient, which may be the same as the original mint recipient, or different

MessageTransmitter

receiveMessage

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
FieldTypeDescription
messagebytes calldataMessage bytes
attestationbytes calldataSigned attestation of message

sendMessage

Sends a message to the destination domain and recipient. Emits a MessageSent event which will be attested by Circle’s attestation service (Iris). Parameters
FieldTypeDescription
destinationDomainuint32Destination domain identifier
recipientbytes32Address to handle message body on destination domain
messageBodybytes calldataApp-specific message to be handled by recipient

sendMessageWithCaller

Same as sendMessage but with an additional parameter, destinationCaller. This parameter specifies which address has permission to call receiveMessage on the destination domain for the message. Parameters
FieldTypeDescription
destinationDomainuint32Destination domain identifier
recipientbytes32Address of message recipient on destination domain
destinationCallerbytes32Address of caller on the destination domain
messageBodybytes calldataApp-specific message to be handled by recipient

replaceMessage

Replace a message with a new message body and/or destination caller. The originalAttestation must be a valid attestation of originalMessage, produced by Circle’s attestation service (Iris). Parameters
FieldTypeDescription
originalMessagebytes calldataOriginal message to replace
originalAttestationbytes calldataAttestation of originalMessage
newMessageBodybytes calldataNew message body of replaced message
newDestinationCallerbytes32The new destination caller, which may be the same as the original destination caller, a new destination caller, or an empty destination caller (bytes32(0), indicating that any destination caller is valid)

WHAT’S NEXT
I