> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/circlefin/evm-cctp-contracts/llms.txt
> Use this file to discover all available pages before exploring further.

# Create2Factory

> Deterministic contract deployment factory for consistent addresses across chains

## 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:

1. **Deterministic Addresses**: Deploy contracts to the same address across multiple chains
2. **Predictability**: Compute contract addresses before deployment
3. **Cross-Chain Compatibility**: Enable seamless interaction between contracts on different chains
4. **Simplified Configuration**: Reduce configuration complexity by using consistent addresses

## How It Works

CREATE2 deployment uses the following formula to compute addresses:

```
address = keccak256(0xff ++ deployerAddress ++ salt ++ keccak256(bytecode))[12:]
```

Since the deployer address (Create2Factory), salt, and bytecode are known in advance, the resulting contract address is deterministic and can be computed before deployment.

## Constructor

The contract inherits from `Ownable` and uses the standard Ownable constructor.

```solidity theme={null}
constructor()
```

The deployer of the Create2Factory becomes the owner.

## Core Functions

### deploy

```solidity theme={null}
function deploy(
    uint256 amount,
    bytes32 salt,
    bytes calldata bytecode
) external payable returns (address addr)
```

Deploys a contract deterministically using CREATE2.

**Reference**: `src/v2/Create2Factory.sol:37`

#### Parameters

* `amount` (uint256): Amount of native token (e.g., ETH) to seed the deployment with
* `salt` (bytes32): A unique identifier for the deployment
* `bytecode` (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 `amount` of native token with the transaction if `amount > 0`

#### Behavior

Deploys the contract using OpenZeppelin's `Create2.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

```solidity theme={null}
function deployAndMultiCall(
    uint256 amount,
    bytes32 salt,
    bytes calldata bytecode,
    bytes[] calldata data
) external payable returns (address addr)
```

Deploys a contract and makes multiple calls to it in a single transaction.

**Reference**: `src/v2/Create2Factory.sol:54`

#### Parameters

* `amount` (uint256): Amount of native token to seed the deployment with
* `salt` (bytes32): A unique identifier for the deployment
* `bytecode` (bytes): The contract bytecode to deploy
* `data` (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 `amount` of native token with the transaction if `amount > 0`
* All function calls in `data` must succeed

#### Behavior

1. Deploys the contract using CREATE2
2. Iterates through the `data` array and makes each function call to the deployed contract
3. Reverts if any function call fails

This is useful for initialization functions that need to be called immediately after deployment.

### computeAddress

```solidity theme={null}
function computeAddress(
    bytes32 salt,
    bytes32 bytecodeHash
) external view returns (address addr)
```

Computes the address where a contract would be deployed given a salt and bytecode hash.

**Reference**: `src/v2/Create2Factory.sol:75`

#### Parameters

* `salt` (bytes32): The unique identifier for the deployment
* `bytecodeHash` (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

1. **Deploy Create2Factory**: Deploy the factory to the same address on each chain (using CREATE2 itself or a consistent deployer account)
2. **Compute Addresses**: Use `computeAddress()` to predict where contracts will be deployed
3. **Configure Systems**: Configure contracts and off-chain systems with the predicted addresses
4. **Deploy Contracts**: Use `deploy()` or `deployAndMultiCall()` to deploy contracts to the predicted addresses
5. **Verify**: Confirm that deployed addresses match predicted addresses

### Example Deployment Flow

```solidity theme={null}
// 1. Compute the expected address
bytes32 salt = keccak256("MessageTransmitterV2");
bytes memory bytecode = abi.encodePacked(
    type(MessageTransmitterV2).creationCode,
    abi.encode(localDomain, version)
);
bytes32 bytecodeHash = keccak256(bytecode);
address expectedAddress = factory.computeAddress(salt, bytecodeHash);

// 2. Deploy to the predicted address
address deployedAddress = factory.deploy(
    0, // No ETH needed
    salt,
    bytecode
);

// 3. Verify
assert(expectedAddress == deployedAddress);
```

### Initialization Example

```solidity theme={null}
// Deploy and initialize in one transaction
bytes[] memory calls = new bytes[](1);
calls[0] = abi.encodeWithSignature(
    "initialize(address,address,address,address,address[],uint256,uint256)",
    owner,
    pauser,
    rescuer,
    attesterManager,
    attesters,
    signatureThreshold,
    maxMessageBodySize
);

address deployed = factory.deployAndMultiCall(
    0,
    salt,
    bytecode,
    calls
);
```

## Cross-Chain Deployment Example

To deploy CCTP contracts to the same address on multiple chains:

### Step 1: Deploy Create2Factory

```solidity theme={null}
// Deploy Create2Factory to address 0x1234... on all chains
// This can be done using a consistent deployer address or
// by deploying the factory itself via CREATE2
```

### Step 2: Deploy CCTP Contracts

```solidity theme={null}
// On Ethereum
bytes32 salt = keccak256("CCTP-MessageTransmitterV2");
address ethAddress = factory.deploy(0, salt, bytecode);
// Result: 0xabcd...

// On Avalanche (using same salt and bytecode)
address avaxAddress = factory.deploy(0, salt, bytecode);
// Result: 0xabcd... (same as Ethereum!)

// On Arbitrum (using same salt and bytecode)
address arbAddress = factory.deploy(0, salt, bytecode);
// Result: 0xabcd... (same as Ethereum and Avalanche!)
```

## Benefits for CCTP

1. **Simplified Configuration**: Contract addresses don't need to be configured per-chain
2. **Reduced Errors**: Eliminates mistakes from manual address configuration
3. **Easier Auditing**: Consistent addresses make it easier to verify deployments
4. **Better UX**: Users can interact with the same addresses across chains
5. **Improved Reliability**: Reduces configuration complexity in cross-chain message validation

## State Variables

Inherited from `Ownable`:

* `owner` (address): The owner of the factory who can deploy contracts

## Integration Example

### Basic Deployment

```solidity theme={null}
// 1. Prepare deployment
bytes32 salt = keccak256(abi.encodePacked("MyContract", block.chainid));
bytes memory bytecode = type(MyContract).creationCode;

// 2. Compute expected address
address expected = factory.computeAddress(
    salt,
    keccak256(bytecode)
);

// 3. Deploy
address deployed = factory.deploy(0, salt, bytecode);

require(deployed == expected, "Address mismatch");
```

### Deploy and Initialize

```solidity theme={null}
// Deploy a contract and call initialize() immediately
bytes[] memory initCalls = new bytes[](1);
initCalls[0] = abi.encodeWithSignature(
    "initialize(address,address)",
    admin,
    manager
);

address deployed = factory.deployAndMultiCall(
    0,
    salt,
    bytecode,
    initCalls
);
```

## Important Considerations

1. **Unique Salts**: Use unique salts to avoid deployment collisions
2. **Bytecode Matching**: The exact bytecode (including constructor args) must match across chains
3. **Factory Address**: The Create2Factory must be at the same address on all chains
4. **Chain-Specific Data**: Constructor arguments that differ per chain will result in different addresses
5. **Gas Costs**: Consider gas costs when deploying to multiple chains

## Security Considerations

1. **Owner Access**: Only the owner can deploy contracts - protect the owner key
2. **Salt Collisions**: Using the same salt twice will revert the second deployment
3. **Bytecode Verification**: Always verify that the bytecode matches expectations before deployment
4. **Initialization**: Use `deployAndMultiCall()` to ensure contracts are properly initialized immediately after deployment
5. **Address Prediction**: Always verify computed addresses match deployed addresses
