Factory contract for easily deploying contracts to the same address on multiple chains, using CREATE3.
This was forked from https://github.com/lifinance/create3-factory (which forked https://github.com/zeframlou/create3-factory).
The deploy script was updated to use legacy (non EIP-1559) transactions due to the fact that some chains do not support EIP-1559.
Deploying a contract to multiple chains with the same address is annoying. One usually would create a new Ethereum account, seed it with enough tokens to pay for gas on every chain, and then deploy the contract naively. This relies on the fact that the new account's nonce is synced on all the chains, therefore resulting in the same contract address. However, deployment is often a complex process that involves several transactions (e.g. for initialization), which means it's easy for nonces to fall out of sync and make it forever impossible to deploy the contract at the desired address.
One could use a CREATE2
factory that deterministically deploys contracts to an address that's unrelated to the deployer's nonce, but the address is still related to the hash of the contract's creation code. This means if you wanted to use different constructor parameters on different chains, the deployed contracts will have different addresses.
A CREATE3
factory offers the best solution: the address of the deployed contract is determined by only the deployer address and the salt. This makes it far easier to deploy contracts to multiple chains at the same addresses.
CREATE3 allows us to manage our deployments better as well as make integration by developers more painless.
Reach out to us at @aori_io on Twitter if you would like us to deploy the CREATE3Factory
to a certain chain.
CREATE3Factory
has been deployed by the deployer address 0x243Eac06A13b3d83d0310fA320Dd9dF16147B08b
to 0x2Dfcc7415D89af828cbef005F0d072D8b3F23183
on the following networks:
- Ethereum Mainnet
- Arbitrum Nova
- Arbitrum (One)
- Avalanche
- Base
- Binance Smart Chain
- Blast
- Canto
- Celo
- Cronos
- Flare*
- Fantom
- Gnosis
- Linea
- Kava
- Klaytn*
- Manta Pacific
- Mantle
- Moonbeam
- Moonriver
- OKXChain
- opBNB
- Optimism
- Polygon
- Polygon zkEVM
- Pulsechain
- Scroll
- X Layer
- ZKSync
- Zora
- Arbitrum Goerli
- Arbitrum Sepolia
- Arbitrum Stylus Testnet
- Artela Testnet
- Avalanche Fuji
- Base Goerli
- Base Sepolia
- Berachain bArtio
- Blast Sepolia
- BSC Testnet
- Fantom Testnet
- Frame Testnet
- Goerli
- Holesky
- Linea Goerli
- Mantle Testnet
- Mode Sepolia
- Morph Testnet
- Move M1 Devnet
- Neon Devnet
- opBNB Testnet
- Optimism Goerli
- Optimism Sepolia
- Polygon Mumbai
- Sei Devnet
- Sepolia
- Taiko Jolnir
- Taiko Katla
- Unichain Sepolia
(* = Unable to Verify) (** = Issues Deploying)
Call CREATE3Factory::deploy()
to deploy a contract and CREATE3Factory::getDeployed()
to predict the deployment address, it's as simple as it gets.
A few notes:
- The salt provided is hashed together with the deployer address (i.e. msg.sender) to form the final salt, such that each deployer has its own namespace of deployed addresses.
- The deployed contract should be aware that
msg.sender
in the constructor will be the temporary proxy contract used byCREATE3
rather than the deployer, so common patterns likeOwnable
should be modified to accomodate for this.
To install with Foundry:
forge install aori-io/create3-factory
This project uses Foundry as the development framework.
forge install
forge build
Make sure that the network is defined in foundry.toml, then run:
./deploy/deploy.sh [network]
Verifying a contract on the relevant block explorer can have its issues. You can run:
forge verify-contract 0x2Dfcc7415D89af828cbef005F0d072D8b3F23183 CREATE3Factory --watch --chain [network]
to verify the contract separately if such a fail occurs. In the worst case, you can run the following command to output the standard JSON input to etherscan.json
:
forge verify-contract 0x2Dfcc7415D89af828cbef005F0d072D8b3F23183 CREATE3Factory --optimizer-runs=1000000 --show-standard-json-input > etherscan.json