Overview
Create2Factory is a utility contract that enables deterministic deployment of contracts across multiple chains. Using the CREATE2 opcode, it ensures that contracts deployed with the same salt and bytecode will have identical addresses on different EVM chains, which is essential for CCTP’s cross-chain functionality.
Contract Location: src/v2/Create2Factory.sol
Purpose
The Create2Factory serves several critical functions in CCTP:- Deterministic Addresses: Deploy contracts to the same address across multiple chains
- Predictability: Compute contract addresses before deployment
- Cross-Chain Compatibility: Enable seamless interaction between contracts on different chains
- Simplified Configuration: Reduce configuration complexity by using consistent addresses
How It Works
CREATE2 deployment uses the following formula to compute addresses:Constructor
The contract inherits fromOwnable and uses the standard Ownable constructor.
Core Functions
deploy
src/v2/Create2Factory.sol:37
Parameters
amount(uint256): Amount of native token (e.g., ETH) to seed the deployment withsalt(bytes32): A unique identifier for the deploymentbytecode(bytes): The contract bytecode to deploy (including constructor arguments if any)
Returns
addr(address): The deployed contract address
Requirements
- Caller must be the owner
- Must send
amountof native token with the transaction ifamount > 0
Behavior
Deploys the contract using OpenZeppelin’sCreate2.deploy() function. The same salt and bytecode will always produce the same address, regardless of which chain the deployment occurs on (as long as the Create2Factory is at the same address).
deployAndMultiCall
src/v2/Create2Factory.sol:54
Parameters
amount(uint256): Amount of native token to seed the deployment withsalt(bytes32): A unique identifier for the deploymentbytecode(bytes): The contract bytecode to deploydata(bytes[]): Array of encoded function call data to execute on the deployed contract
Returns
addr(address): The deployed contract address
Requirements
- Caller must be the owner
- Must send
amountof native token with the transaction ifamount > 0 - All function calls in
datamust succeed
Behavior
- Deploys the contract using CREATE2
- Iterates through the
dataarray and makes each function call to the deployed contract - Reverts if any function call fails
computeAddress
src/v2/Create2Factory.sol:75
Parameters
salt(bytes32): The unique identifier for the deploymentbytecodeHash(bytes32): The keccak256 hash of the deployment bytecode
Returns
addr(address): The deterministic address where the contract would be deployed
Behavior
This is a view function that computes the address without performing a deployment. It’s useful for:- Predicting contract addresses before deployment
- Verifying that a deployment will produce the expected address
- Configuring systems that need to know contract addresses in advance
Usage in CCTP Deployment
The Create2Factory is used in CCTP deployment scripts to ensure that contracts are deployed to the same addresses across multiple chains:Deployment Process
- Deploy Create2Factory: Deploy the factory to the same address on each chain (using CREATE2 itself or a consistent deployer account)
- Compute Addresses: Use
computeAddress()to predict where contracts will be deployed - Configure Systems: Configure contracts and off-chain systems with the predicted addresses
- Deploy Contracts: Use
deploy()ordeployAndMultiCall()to deploy contracts to the predicted addresses - Verify: Confirm that deployed addresses match predicted addresses
Example Deployment Flow
Initialization Example
Cross-Chain Deployment Example
To deploy CCTP contracts to the same address on multiple chains:Step 1: Deploy Create2Factory
Step 2: Deploy CCTP Contracts
Benefits for CCTP
- Simplified Configuration: Contract addresses don’t need to be configured per-chain
- Reduced Errors: Eliminates mistakes from manual address configuration
- Easier Auditing: Consistent addresses make it easier to verify deployments
- Better UX: Users can interact with the same addresses across chains
- Improved Reliability: Reduces configuration complexity in cross-chain message validation
State Variables
Inherited fromOwnable:
owner(address): The owner of the factory who can deploy contracts
Integration Example
Basic Deployment
Deploy and Initialize
Important Considerations
- Unique Salts: Use unique salts to avoid deployment collisions
- Bytecode Matching: The exact bytecode (including constructor args) must match across chains
- Factory Address: The Create2Factory must be at the same address on all chains
- Chain-Specific Data: Constructor arguments that differ per chain will result in different addresses
- Gas Costs: Consider gas costs when deploying to multiple chains
Security Considerations
- Owner Access: Only the owner can deploy contracts - protect the owner key
- Salt Collisions: Using the same salt twice will revert the second deployment
- Bytecode Verification: Always verify that the bytecode matches expectations before deployment
- Initialization: Use
deployAndMultiCall()to ensure contracts are properly initialized immediately after deployment - Address Prediction: Always verify computed addresses match deployed addresses