General Questions
What is CCTP?
What is CCTP?
Cross-Chain Transfer Protocol (CCTP) is Circle’s permissionless on-chain utility that enables native USDC to be transferred securely between blockchain networks.Instead of traditional lock-and-mint bridge mechanisms, CCTP uses a burn-and-mint approach:
- USDC is burned on the source chain
- Circle’s attestation service signs the burn message
- USDC is minted on the destination chain
Which chains are supported?
Which chains are supported?
CCTP supports multiple EVM-compatible chains. Supported chains are identified by domain IDs configured in the contracts.Common domains include:
- Ethereum mainnet and testnets
- Avalanche C-Chain
- Arbitrum
- Optimism
- Base
- Polygon PoS
How long does a cross-chain transfer take?
How long does a cross-chain transfer take?
Transfer time varies by chain due to different finality requirements:
- Fast chains (e.g., Avalanche): 1-2 minutes
- Medium chains (e.g., Polygon): 5-10 minutes
- Slower chains (e.g., Ethereum): 15-20 minutes
- Source chain transaction confirmation
- Block finality waiting period
- Attestation service signing (usually quick)
- Destination chain transaction submission
What are attesters?
What are attesters?
Attesters are Circle-operated nodes that validate and sign burn messages. They provide the cryptographic proof needed to mint USDC on the destination chain.Key points:
- Multiple attesters create decentralization
- Threshold signatures ensure security (e.g., 2-of-3)
- Attesters verify the burn transaction occurred
- Attestation service coordinates attester signatures
Version Comparison
What's the difference between V1 and V2?
What's the difference between V1 and V2?
V2 introduces significant enhancements over V1:V2 New Features:
- Fee support: Protocol fees for transfers, with fee recipient role
- Hook execution: Custom logic execution on destination chain via
depositForBurnWithHook - Finality thresholds: Configurable finality levels (finalized, confirmed, unfinalized)
- Denylist: Address denylist functionality for compliance
- CREATE2 deployment: Deterministic addresses across chains for easier integration
- Min fee controller: Separate role for managing minimum fee percentages
- Enhanced message format: Additional fields for new functionality
- Basic burn-and-mint functionality
- Simple
depositForBurnanddepositForBurnWithCaller - Role-based access control
- Pausability and rescuability
- V1 and V2 use different message versions (0 vs 1)
- V2 contracts are not backward compatible with V1 messages
- Both versions can coexist on the same chain
Should I use V1 or V2?
Should I use V1 or V2?
Use V2 if you need:
- Fee-based transfers
- Hook functionality for custom destination logic
- Different finality guarantees
- Address denylist support
- Future-proof integration
- You need a simpler, battle-tested implementation
- You don’t need advanced V2 features
- You’re integrating with existing V1 deployments
Function Selection
When should I use depositForBurn vs depositForBurnWithCaller?
When should I use depositForBurn vs depositForBurnWithCaller?
V1 Functions:
depositForBurn(amount, destinationDomain, mintRecipient, burnToken)- Anyone can call
receiveMessageon the destination chain - Simpler, more permissionless
- Use when you don’t need to control who submits the destination transaction
depositForBurnWithCaller(amount, destinationDomain, mintRecipient, burnToken, destinationCaller)- Only the specified
destinationCallercan callreceiveMessage - More control over execution
- Use when you need to restrict destination execution (e.g., specific relayer)
depositForBurn with a destinationCaller parameter:- Set
destinationCallertobytes32(0)for permissionless execution - Set
destinationCallerto specific address for restricted execution
When should I use depositForBurnWithHook? (V2 only)
When should I use depositForBurnWithHook? (V2 only)
Use
depositForBurnWithHook when you need to execute custom logic on the destination chain after minting.Use cases:- Automatic swaps after receiving USDC
- Depositing into DeFi protocols
- Forwarding funds to another contract
- Complex multi-step operations
hookDatamust be non-empty- Destination contract must implement hook handler interface
- Additional gas required on destination for hook execution
What is minFinalityThreshold in V2?
What is minFinalityThreshold in V2?
The
minFinalityThreshold parameter in V2 specifies the minimum level of finality required before attesters will sign the message.Threshold levels:2000+: Finalized (fully confirmed, highest security)1000-1999: Confirmed (strong but not final)500-999: Unfinalized (faster but requires fees)
- Higher threshold: Slower but more secure, no fees required
- Lower threshold: Faster but requires higher fees, small reorg risk
- Time-sensitive transfers: Use 500-999 with appropriate fees
- High-value transfers: Use 2000+ for maximum security
- Standard transfers: Use 1000 for balanced speed and security
Features and Mechanisms
How does the pause mechanism work?
How does the pause mechanism work?
CCTP contracts include an emergency pause mechanism:Pause functionality:
- Pauser role can call
pause()to stop operations - Pauser role can call
unpause()to resume operations - Only affects state-changing functions (marked with
whenNotPaused) - View functions continue to work during pause
depositForBurn/depositForBurnWithCaller(V1)depositForBurn/depositForBurnWithHook(V2)sendMessage(MessageTransmitter)receiveMessage(MessageTransmitter)
- Reading contract state
- Querying balances and allowances
- Checking pause status
How do fees work in V2?
How do fees work in V2?
V2 introduces a flexible fee system:Fee structure:Fee validation:Fee distribution:
- Fees are paid in the same token being transferred (USDC)
- Fees are deducted from the transfer amount on destination
- Fee recipient receives minted fees separately
maxFee: Maximum fee sender is willing to payminFee: Minimum fee percentage set by protocol (basis points)feeExecuted: Actual fee charged (recorded in message)
- Recipient receives:
amount - feeExecuted - Fee recipient receives:
feeExecuted
What is the denylist in V2?
What is the denylist in V2?
V2 includes a denylist mechanism for regulatory compliance:How it works:Impact:
- Denylister role can add/remove addresses
- Checks both
msg.senderandtx.origin - Denylisted addresses cannot call
depositForBurnfunctions - Reverts with “Denylistable: account is on denylist”
- Prevents initiating new transfers
- Does not affect receiving USDC from other addresses
- Does not freeze existing USDC balances
How does CREATE2 deployment work in V2?
How does CREATE2 deployment work in V2?
V2 uses CREATE2 for deterministic contract addresses across chains:Benefits:
- Same contract addresses on all chains
- Easier integration (one address to remember)
- Simplified remote resource configuration
- Predictable deployment planning
Create2Factory: Deploys contracts deterministically- Salt-based addressing: Same salt = same address
- Cross-chain coordination: Deploy in same order everywhere
Development and Testing
How do I test CCTP locally?
How do I test CCTP locally?
Use Foundry’s testing framework:Unit tests:Integration tests with Anvil:Debug tests:Test examples are available in the
test/ directory, including V1 and V2 test suites.What are the gas costs?
What are the gas costs?
Gas costs vary by chain and operation:Typical costs:
depositForBurn: ~100-200k gasdepositForBurnWithHook(V2): ~150-300k gas (depends on hook)receiveMessage: ~100-200k gas- Token approval: ~50k gas
- Chain gas price
- Message body size
- Hook complexity (V2)
- First-time operations (e.g., first approval)
Can I use CCTP on testnets?
Can I use CCTP on testnets?
Yes! CCTP is available on various testnets:Common testnets:Getting testnet USDC:
- Ethereum Sepolia
- Avalanche Fuji
- Arbitrum Sepolia
- Optimism Sepolia
- Base Sepolia
- Use Circle’s testnet faucet
- Check chain-specific faucets
- Bridge from other testnets using CCTP
Need More Help?
Troubleshooting
Common issues and solutions
Security
Security best practices and reporting