CreateX provides a comprehensive solution for deploying smart contracts using various creation opcodes and patterns, offering both a standalone library and a unified factory contract for traditional and deterministic deployment methods.
- CREATE: Traditional contract deployment
- CREATE2: Deterministic contract deployment
- CREATE3: Chain-agnostic deterministic deployment
- EIP-1167 Clone: Minimal proxy pattern deployment
- EIP-1167 CloneDeterministic: Deterministic minimal proxy deployment
- Address Prediction: Compute contract addresses before deployment
- Dual Approach: Use as a library in your contracts or interact with the deployed factory
createx/
├── deployments/...
├── script/
│ ├── CreateX.s.sol
│ └── Deploy.s.sol
├── src/
│ ├── CreateX.sol
│ ├── CreateXFactory.sol
│ └── ICreateXFactory.sol
└── test/
├── mocks/...
└── CreateXFactory.t.sol
forge install fomoweth/createxforge build --sizes# Run all tests
forge test# Run with detailed traces
forge test -vvv
# Run with gas reporting
forge test --gas-reportforge script script/Deploy.s.sol:DeployScript \
--broadcast \
--multi \
--slow \
--verify \
-vvvvCreateXFactory is deployed on the following networks:
| Network | Chain ID | Address |
|---|---|---|
| Ethereum | 1 | 0xfC5D1D7b066730fC403C994365205a96fE1d8Bcf |
| Optimism | 10 | 0xfC5D1D7b066730fC403C994365205a96fE1d8Bcf |
| Polygon | 137 | 0xfC5D1D7b066730fC403C994365205a96fE1d8Bcf |
| Base | 8453 | 0xfC5D1D7b066730fC403C994365205a96fE1d8Bcf |
| Arbitrum One | 42161 | 0xfC5D1D7b066730fC403C994365205a96fE1d8Bcf |
A low-level library that enables deterministic contract deployments and proxy clones using various creation patterns with gas efficiency.
function create(bytesmemoryinitCode) internalreturns (address);
function create(bytesmemoryinitCode, uint256value) internalreturns (address);
function create2(bytesmemoryinitCode, bytes32salt) internalreturns (address);
function create2(bytesmemoryinitCode, bytes32salt, uint256value) internalreturns (address);
function create3(bytesmemoryinitCode, bytes32salt) internalreturns (address);
function create3(bytesmemoryinitCode, bytes32salt, uint256value) internalreturns (address);
function clone(addressimplementation) internalreturns (address);
function clone(addressimplementation, uint256value) internalreturns (address);
function cloneDeterministic(addressimplementation, bytes32salt) internalreturns (address);
function cloneDeterministic(addressimplementation, bytes32salt, uint256value) internalreturns (address);function computeCreateAddress(uint256nonce) internalviewreturns (address);
function computeCreateAddress(addressdeployer, uint256nonce) internalpurereturns (address);
function computeCreate2Address(bytes32initCodeHash, bytes32salt) internalviewreturns (address);
function computeCreate2Address(addressdeployer, bytes32initCodeHash, bytes32salt) internalpurereturns (address);
function computeCreate3Address(bytes32salt) internalviewreturns (address);
function computeCreate3Address(addressdeployer, bytes32salt) internalpurereturns (address);
function computeCloneDeterministicAddress(addressimplementation, bytes32salt) internalviewreturns (address);
function computeCloneDeterministicAddress(addressdeployer, addressimplementation, bytes32salt) internalpurereturns (address);Import and use the library functions directly:
// SPDX-License-Identifier: MITpragma solidity^0.8.30;
import {CreateX} from"lib/createx/src/CreateX.sol";
contractMyContract {
function deployCreate(bytescalldatainitCode) externalpayablereturns (address) {
return CreateX.create(initCode, msg.value);
}
function deployCreate2(bytescalldatainitCode, bytes32salt) externalpayablereturns (address) {
return CreateX.create2(initCode, salt, msg.value);
}
function deployCreate3(bytescalldatainitCode, bytes32salt) externalpayablereturns (address) {
return CreateX.create3(initCode, salt, msg.value);
}
function deployClone(addressimplementation) externalpayablereturns (address) {
return CreateX.clone(implementation, msg.value);
}
function deployCloneDeterministic(addressimplementation, bytes32salt) externalpayablereturns (address) {
return CreateX.cloneDeterministic(implementation, salt, msg.value);
}
function computeAddress(uint256nonce) publicviewreturns (address) {
return CreateX.computeCreateAddress(nonce);
}
function computeAddress(bytes32initCodeHash, bytes32salt) publicviewreturns (address) {
return CreateX.computeCreate2Address(initCodeHash, salt);
}
function computeAddress(bytes32salt) publicviewreturns (address) {
return CreateX.computeCreate3Address(salt);
}
function computeAddress(addressimplementation, bytes32salt) publicviewreturns (address) {
return CreateX.computeCloneDeterministicAddress(implementation, salt);
}
}A public deployment contract that exposes CreateX capabilities via a unified interface with salt guard.
enum CreationType {
CREATE, // 0 – traditional deployment
CREATE2, // 1 – deterministic deployment
CREATE3, // 2 – chain-agnostic deployment
Clone, // 3 – EIP-1167 via CREATE
CloneDeterministic // 4 – EIP-1167 via CREATE2
}function createX(
CreationType creationType,
bytescalldatainitCode,
bytes32salt
) externalpayablereturns (address);
function create(bytescalldatainitCode) externalpayablereturns (address);
function create2(bytescalldatainitCode, bytes32salt) externalpayablereturns (address);
function create3(bytescalldatainitCode, bytes32salt) externalpayablereturns (address);
function clone(addressimplementation) externalpayablereturns (address);
function cloneDeterministic(addressimplementation, bytes32salt) externalpayablereturns (address);function computeCreateXAddress(CreationType creationType, bytes32initCodeHash, bytes32salt) externalviewreturns (address);
function computeCreateAddress(uint256nonce) externalviewreturns (address);
function computeCreate2Address(bytes32initCodeHash, bytes32salt) externalviewreturns (address);
function computeCreate3Address(bytes32salt) externalviewreturns (address);
function computeCloneDeterministicAddress(addressimplementation, bytes32salt) externalviewreturns (address);The factory emits events for all deployments:
event ContractCreation(addressindexedinstance, addressindexeddeployer);
event ContractCreation(addressindexedinstance, addressindexeddeployer, bytes32indexedsalt);Both the library and factory include comprehensive error handling:
error ContractCreationFailed(); // Deployment failederror ProxyCreationFailed(); // CREATE3 proxy deployment failederror InsufficientBalance(); // Insufficient ETH balanceerror InvalidImplementation(); // Invalid implementation address for proxieserror InvalidNonce(); // Nonce exceeds EIP-2681 limiterror InvalidCreationType(); // Unsupported creation type (factory only)error InvalidSalt(); // Salt validation failed (factory only)Import the interface and interact with the deployed factory:
// SPDX-License-Identifier: MITpragma solidity^0.8.30;
import {ICreateXFactory} from"lib/createx/src/ICreateXFactory.sol";
contractMyContract {
ICreateXFactory publicimmutable factory;
constructor(address_factory) {
factory =ICreateXFactory(_factory);
}
function deployCreate(bytescalldatainitCode) externalpayablereturns (address) {
return factory.create{value: msg.value}(initCode);
}
function deployCreate2(bytescalldatainitCode, bytes32salt) externalpayablereturns (address) {
return factory.create2{value: msg.value}(initCode, salt);
}
function deployCreate3(bytescalldatainitCode, bytes32salt) externalpayablereturns (address) {
return factory.create3{value: msg.value}(initCode, salt);
}
function deployClone(addressimplementation) externalpayablereturns (address) {
return factory.clone{value: msg.value}(implementation);
}
function deployCloneDeterministic(addressimplementation, bytes32salt) externalpayablereturns (address) {
return factory.cloneDeterministic{value: msg.value}(implementation, salt);
}
function computeAddress(uint256nonce) publicviewreturns (address) {
return factory.computeCreateAddress(nonce);
}
function computeAddress(bytes32initCodeHash, bytes32salt) publicviewreturns (address) {
return factory.computeCreate2Address(initCodeHash, salt);
}
function computeAddress(bytes32salt) publicviewreturns (address) {
return factory.computeCreate3Address(salt);
}
function computeAddress(addressimplementation, bytes32salt) publicviewreturns (address) {
return factory.computeCloneDeterministicAddress(implementation, salt);
}
}The factory provides a single function that supports all deployment methods:
function deployCreateX(
ICreateXFactory.CreationType creationType,
bytescalldatainitCode,
bytes32salt
) externalpayablereturns (address) {
return factory.createX{value: msg.value}(creationType, initCode, salt);
}The factory includes built-in access control through salt validation:
- For salted deployments (CREATE2, CREATE3, CloneDeterministic), the first 20 bytes of the salt must match either:
- The caller's address (for user-specific deployments)
- Zero address (for open deployments)
The following repositories served as key references during the development of this project: