Skip to main content

Version 2 (V2)

V2 represents a major upgrade to the CCTP protocol with significant new features and enhancements.

Major Features

V2 introduces a flexible fee system for cross-chain transfers:
  • Protocol fees configurable via minFee parameter
  • Fees paid in the same token being transferred
  • Separate feeRecipient role receives collected fees
  • minFeeController role for managing fee structure
  • Dynamic fee calculation based on transfer amount
  • Fee validation during deposit operations
New functions:
  • getMinFeeAmount(amount): Calculate minimum required fee
  • setMinFee(newMinFee): Update minimum fee percentage
  • setFeeRecipient(newFeeRecipient): Update fee recipient
Execute custom logic on the destination chain after minting:
  • depositForBurnWithHook() function with hookData parameter
  • Enables complex cross-chain workflows
  • Hook data passed through message and executed after mint
  • Support for DeFi integrations, automatic swaps, and more
  • Flexible hook data encoding for custom use cases
Use cases:
  • Automatic token swaps after receiving USDC
  • Depositing into lending protocols
  • Multi-step cross-chain operations
  • Integration with existing DeFi strategies
Configurable finality levels for different security/speed trade-offs:
  • Finalized (2000+): Full block finality, highest security
  • Confirmed (1000-1999): Strong confirmation, balanced approach
  • Unfinalized (500-999): Faster execution, requires fees
Message fields:
  • minFinalityThreshold: Sender’s requested finality level
  • finalityThresholdExecuted: Actual finality at attestation time
Benefits:
  • Faster transfers for time-sensitive applications
  • Flexibility to choose security vs. speed
  • Fee incentives for accepting lower finality
Address denylist functionality for regulatory compliance:
  • Denylistable contract with denylist management
  • Separate denylister role for operational flexibility
  • Checks both msg.sender and tx.origin
  • Prevents denylisted addresses from initiating transfers
New functions:
  • denylist(account): Add address to denylist
  • unDenylist(account): Remove address from denylist
  • isDenylisted(account): Check denylist status
  • updateDenylister(newDenylister): Update denylister role
Events:
  • Denylisted(address indexed account)
  • UnDenylisted(address indexed account)
  • DenylisterChanged(address indexed oldDenylister, address indexed newDenylister)
Deterministic contract addresses across chains:
  • Create2Factory for deterministic deployments
  • Same contract addresses on all chains
  • Simplified integration and configuration
  • Predictable address calculation before deployment
Components:
  • Create2Factory contract with owner controls
  • Implementation contracts deployed via CREATE2
  • Proxy contracts with deterministic addresses
  • Salt-based addressing scheme
Benefits:
  • Easier multi-chain integration
  • Reduced configuration complexity
  • Single address for all chains
  • Advance address reservation

Enhanced Message Format

V2 uses an updated message format (version 1) with additional fields: New fields:
  • destinationCaller: Authorized caller on destination (V1 had separate function)
  • minFinalityThreshold: Requested finality level
  • finalityThresholdExecuted: Actual finality at execution
  • maxFee: Maximum fee sender willing to pay
  • feeExecuted: Actual fee charged
  • expirationBlock: Optional message expiration
  • hookData: Optional data for hook execution
Message structure:
Field                        Bytes      Type       Index
version                      4          uint32     0
sourceDomain                 4          uint32     4
destinationDomain            4          uint32     8
nonce                        32         bytes32    12
sender                       32         bytes32    44
recipient                    32         bytes32    76
destinationCaller            32         bytes32    108
minFinalityThreshold         4          uint32     140
finalityThresholdExecuted    4          uint32     144
messageBody                  dynamic    bytes      148

Interface Changes

New/Modified functions:
  • depositForBurn(): Added destinationCaller, maxFee, minFinalityThreshold parameters
  • depositForBurnWithHook(): New function with hookData parameter
  • handleReceiveUnfinalizedMessage(): New handler for unfinalized messages
  • handleReceiveFinalizedMessage(): Separate handler for finalized messages
  • getMinFeeAmount(): Calculate minimum fee for an amount
Removed functions:
  • depositForBurnWithCaller(): Unified into depositForBurn with destinationCaller param
New/Modified functions:
  • sendMessage(): Added destinationCaller and minFinalityThreshold parameters
  • Message format version changed from 0 to 1
Enhanced validation:
  • Destination caller validation
  • Finality threshold checks
  • Message version validation
Fee-aware minting:
  • mint(): Now handles fee deduction
  • Separate minting for recipient and fee recipient
  • Fee validation and calculation

Deployment Process

V2 introduces a multi-step deployment process:
  1. Deploy Create2Factory: One-time factory deployment
  2. Deploy Implementation Contracts: MessageTransmitterV2, TokenMessengerV2, TokenMinterV2
  3. Deploy Proxy Contracts: Using CREATE2 for deterministic addresses
  4. Setup Remote Resources: Configure cross-chain connections
  5. Key Rotation (Mainnet only): Transfer ownership to production keys
See the V2 deployment documentation for detailed instructions.

Migration Considerations

V1 and V2 are not directly compatible. Messages created with V1 cannot be received by V2 contracts and vice versa.
Key differences:
  • Different message versions (0 vs 1)
  • Incompatible message formats
  • Different function signatures
  • Additional parameters required
Migration strategy:
  • Both versions can coexist on the same chain
  • Plan phased migration for existing integrations
  • Update client code to support V2 message format
  • Test thoroughly on testnets before production migration

Version 1 (V1)

Initial Release Features

V1 established the foundational CCTP protocol:
  • TokenMessenger: Manages deposits and minting
  • MessageTransmitter: Handles cross-chain message passing
  • TokenMinter: Controls token minting and burning
  • Burn tokens on source chain
  • Attestation service signing
  • Mint tokens on destination chain
Initial message format with essential fields:
Field                 Bytes      Type       Index
version               4          uint32     0
sourceDomain          4          uint32     4
destinationDomain     4          uint32     8
nonce                 32         bytes32    12
sender                32         bytes32    44
recipient             32         bytes32    76
destinationCaller     32         bytes32    108
messageBody           dynamic    bytes      140
Secure administrative role system:
  • Owner: Full administrative control with two-step transfer
  • Pauser: Emergency pause/unpause capability
  • Rescuer: Rescue accidentally sent tokens
  • Attester Manager: Manage attesters and signature threshold
  • Token Controller: Manage token minting permissions
Based on OpenZeppelin’s Ownable pattern with security enhancements.
Decentralized attestation mechanism:
  • Multiple attester nodes operated by Circle
  • Threshold signature requirement (e.g., 2-of-3)
  • Attester enable/disable functionality
  • Configurable signature threshold
  • Replay protection via nonce tracking
Emergency stop mechanism:
  • Pauser role can pause contract operations
  • Protects against attacks or bugs
  • Affects all state-changing functions
  • View functions remain operational
  • Quick resume capability via unpause
Protect user funds:
  • Rescuer role can withdraw accidentally sent tokens
  • Prevents permanent loss of funds
  • Separate from owner role for security
  • Cannot rescue USDC (only accidentally sent tokens)

V1 Functions

TokenMessenger:
  • depositForBurn(): Basic burn and transfer
  • depositForBurnWithCaller(): Burn with restricted destination caller
  • handleReceiveMessage(): Process incoming messages and mint
  • addRemoteTokenMessenger(): Register remote chain
  • removeRemoteTokenMessenger(): Unregister remote chain
MessageTransmitter:
  • sendMessage(): Send cross-chain message
  • receiveMessage(): Receive and validate message
  • enableAttester(): Add new attester
  • disableAttester(): Remove attester
  • setSignatureThreshold(): Update signature requirement
TokenMinter:
  • mint(): Mint tokens to recipient
  • burn(): Burn tokens from address
  • addLocalTokenMessenger(): Register local messenger
  • setMaxBurnAmountPerMessage(): Set burn limits

Upgrade Path

For projects looking to upgrade from V1 to V2:
  1. Assess V2 features: Determine which V2 features benefit your use case
  2. Test on testnets: Thoroughly test V2 integration on testnets
  3. Update contracts: Modify integration contracts for V2 message format
  4. Update client code: Update frontend/backend to use V2 functions
  5. Deploy to mainnet: Deploy V2 integration after thorough testing
  6. Gradual migration: Consider supporting both V1 and V2 during transition
Both V1 and V2 contracts can operate simultaneously on the same chain, allowing for gradual migration strategies.

Additional Resources

Deployment Guide

Deploy V1 or V2 contracts

FAQ

Version comparison and feature questions

Build docs developers (and LLMs) love