{"id":14737495,"url":"https://github.com/pcaversaccio/createx","last_synced_at":"2025-05-16T10:06:18.199Z","repository":{"id":197302283,"uuid":"670118056","full_name":"pcaversaccio/createx","owner":"pcaversaccio","description":"Factory smart contract to make easier and safer usage of the `CREATE` and `CREATE2` EVM opcodes as well as of `CREATE3`-based (i.e. without an initcode factor) contract creations.","archived":false,"fork":false,"pushed_at":"2025-05-14T09:11:07.000Z","size":3237,"stargazers_count":435,"open_issues_count":1,"forks_count":41,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-05-14T10:36:16.594Z","etag":null,"topics":["create","create2","create3","deployment","ethereum","factory-contract","solidity"],"latest_commit_sha":null,"homepage":"https://createx.rocks","language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pcaversaccio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-07-24T10:34:05.000Z","updated_at":"2025-05-14T09:11:10.000Z","dependencies_parsed_at":null,"dependency_job_id":"26cb00c8-f474-40fc-9bcf-019cedb3c112","html_url":"https://github.com/pcaversaccio/createx","commit_stats":null,"previous_names":["pcaversaccio/createx"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcaversaccio%2Fcreatex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcaversaccio%2Fcreatex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcaversaccio%2Fcreatex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pcaversaccio%2Fcreatex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pcaversaccio","download_url":"https://codeload.github.com/pcaversaccio/createx/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254509477,"owners_count":22082891,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["create","create2","create3","deployment","ethereum","factory-contract","solidity"],"created_at":"2024-09-14T12:01:09.738Z","updated_at":"2025-05-16T10:06:18.192Z","avatar_url":"https://github.com/pcaversaccio.png","language":"Solidity","readme":"# [`CreateX`](./src/CreateX.sol) – A Trustless, Universal Contract Deployer \u003c!-- omit from toc --\u003e\n\n[![🕵️‍♂️ Test CreateX](https://github.com/pcaversaccio/createx/actions/workflows/test-createx.yml/badge.svg)](https://github.com/pcaversaccio/createx/actions/workflows/test-createx.yml)\n[![Test Coverage](https://img.shields.io/badge/Coverage-100%25-green)](#test-coverage)\n[![👮‍♂️ Sanity checks](https://github.com/pcaversaccio/createx/actions/workflows/checks.yml/badge.svg)](https://github.com/pcaversaccio/createx/actions/workflows/checks.yml)\n[![🚀 UI deployment](https://github.com/pcaversaccio/createx/actions/workflows/deploy.yml/badge.svg)](https://github.com/pcaversaccio/createx/actions/workflows/deploy.yml)\n[![License: AGPL-3.0-only](https://img.shields.io/badge/License-AGPL--3.0--only-blue)](https://www.gnu.org/licenses/agpl-3.0)\n\n\u003cimg src=https://github-production-user-asset-6210df.s3.amazonaws.com/25297591/272914952-38a5989c-0113-427d-9158-47646971b7d8.png  width=\"1050\"/\u003e\n\nFactory smart contract to make easier and safer usage of the [`CREATE`](https://www.evm.codes/#f0?fork=shanghai) and [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai) EVM opcodes as well as of [`CREATE3`](https://github.com/ethereum/EIPs/pull/3171)-based (i.e. without an initcode factor) contract creations.\n\n\u003e [!NOTE]\n\u003e The [`CreateX`](./src/CreateX.sol) contract should be considered as maximally extensible. Be encouraged to build on top of it! The Solidity-based interface can be found [here](./src/ICreateX.sol).\n\n- [So What on Earth Is a Contract Factory?](#so-what-on-earth-is-a-contract-factory)\n- [Available Versatile Functions](#available-versatile-functions)\n- [Special Features](#special-features)\n  - [Permissioned Deploy Protection and Cross-Chain Redeploy Protection](#permissioned-deploy-protection-and-cross-chain-redeploy-protection)\n  - [Pseudo-Random Salt Value](#pseudo-random-salt-value)\n- [Design Principles](#design-principles)\n- [Security Considerations](#security-considerations)\n- [Tests](#tests)\n  - [Test Coverage](#test-coverage)\n- [ABI (Application Binary Interface)](#abi-application-binary-interface)\n- [New Deployment(s)](#new-deployments)\n  - [`ethers.js`](#ethersjs)\n  - [`cast`](#cast)\n  - [Contract Verification](#contract-verification)\n- [`CreateX` Deployments](#createx-deployments)\n  - [EVM-Based Production Networks](#evm-based-production-networks)\n  - [Ethereum Test Networks](#ethereum-test-networks)\n  - [Additional EVM-Based Test Networks](#additional-evm-based-test-networks)\n- [Integration With External Tooling](#integration-with-external-tooling)\n- [Community-Maintained Dune Dashboards](#community-maintained-dune-dashboards)\n- [🙏🏼 Acknowledgement](#-acknowledgement)\n\n## So What on Earth Is a Contract Factory?\n\nIt is important to understand that Ethereum Virtual Machine (EVM) opcodes can only be called via a smart contract. A contract factory in the context of the EVM refers to a special smart contract that is used to create and deploy other smart contracts on EVM-compatible blockchains using contract creation opcodes (i.e. [`CREATE`](https://www.evm.codes/#f0?fork=shanghai) or [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai)). Using a contract factory provides a flexible and efficient way to deploy and manage smart contracts that share similar functionalities but may have different configurations or settings.\n\nDifferent approaches can be used to create contracts using a factory contract, and this is exactly what [`CreateX`](./src/CreateX.sol) offers: _a comprehensive range of contract creation functions that are triggered by a smart contract itself_. It is worth emphasising the two differences in the address calculation of the opcodes [`CREATE`](https://www.evm.codes/#f0?fork=shanghai) and [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai) (`||` stands for byte-wise concatenation, `[12:]` refers to the last 20 bytes of a 32-byte expression, and `rlp` is an abbreviation for Ethereum's \"Recursive Length Prefix\" serialisation scheme):\n\n- [`CREATE`](https://www.evm.codes/#f0?fork=shanghai): `address computedAddress = keccak256(rlpEncode([deployerAddress, deployerNonce]))[12:]`,\n- [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai): `address computedAddress = keccak256(0xff||deployerAddress||salt||keccak256(initCode))[12:]`.\n\n## Available Versatile Functions\n\n```ml\nCreateX\n├── CREATE\n│   ├── Read-Only Functions\n│   │   ├── \"function computeCreateAddress(uint256) view returns (address)\"\n│   │   └── \"function computeCreateAddress(address,uint256) view returns (address)\"\n│   └── Write Functions\n│       ├── \"function deployCreate(bytes) payable returns (address)\"\n│       ├── \"function deployCreateAndInit(bytes,bytes,tuple(uint256,uint256)) payable returns (address)\"\n│       ├── \"function deployCreateAndInit(bytes,bytes,tuple(uint256,uint256),address) payable returns (address)\"\n│       └── \"function deployCreateClone(address,bytes) payable returns (address)\"\n├── CREATE2\n│   ├── Read-Only Functions\n│   │   ├── \"function computeCreate2Address(bytes32,bytes32) view returns (address)\"\n│   │   └── \"function computeCreate2Address(bytes32,bytes32,address) pure returns (address)\"\n│   └── Write Functions\n│       ├── \"function deployCreate2(bytes) payable returns (address)\"\n│       ├── \"function deployCreate2(bytes32,bytes) payable returns (address)\"\n│       ├── \"function deployCreate2AndInit(bytes,bytes,tuple(uint256,uint256)) payable returns (address)\"\n│       ├── \"function deployCreate2AndInit(bytes32,bytes,bytes,tuple(uint256,uint256)) payable returns (address)\"\n│       ├── \"function deployCreate2AndInit(bytes,bytes,tuple(uint256,uint256),address) payable returns (address)\"\n│       ├── \"function deployCreate2AndInit(bytes32,bytes,bytes,tuple(uint256,uint256),address) payable returns (address)\"\n│       ├── \"function deployCreate2Clone(address,bytes) payable returns (address)\"\n│       └── \"function deployCreate2Clone(bytes32,address,bytes) payable returns (address)\"\n└── CREATE3\n    ├── Read-Only Functions\n    │   ├── \"function computeCreate3Address(bytes32) view returns (address)\"\n    │   └── \"function computeCreate3Address(bytes32,address) pure returns (address)\"\n    └── Write Functions\n        ├── \"function deployCreate3(bytes) payable returns (address)\"\n        ├── \"function deployCreate3(bytes32,bytes) payable returns (address)\"\n        ├── \"function deployCreate3AndInit(bytes,bytes,tuple(uint256,uint256)) payable returns (address)\"\n        ├── \"function deployCreate3AndInit(bytes32,bytes,bytes,tuple(uint256,uint256)) payable returns (address)\"\n        ├── \"function deployCreate3AndInit(bytes,bytes,tuple(uint256,uint256),address) payable returns (address)\"\n        └── \"function deployCreate3AndInit(bytes32,bytes,bytes,tuple(uint256,uint256),address) payable returns (address)\"\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L302-L317\"\u003e\u003ccode\u003ecomputeCreateAddress(uint256)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nReturns the address where a contract will be stored if deployed via _this contract_ (i.e. [`CreateX`](./src/CreateX.sol)) using the [`CREATE`](https://www.evm.codes/#f0?fork=shanghai) opcode. For the specification of the Recursive Length Prefix (RLP) encoding scheme, please refer to p. 19 of the [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) and the [Ethereum Wiki](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/). Based on the [EIP-161](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md) specification, all contract accounts on the Ethereum mainnet are initiated with `nonce = 1`. Thus, the first contract address created by another contract is calculated with a non-zero nonce.\n\n```yml\n# /*:°• Function Argument •°:*/ #\n- name: nonce\n  type: uint256\n  description: The next 32-byte nonce of this contract.\n\n# /*:°• Return Value •°:*/ #\n- name: computedAddress\n  type: address\n  description: The 20-byte address where a contract will be stored.\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L242-L300\"\u003e\u003ccode\u003ecomputeCreateAddress(address,uint256)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nReturns the address where a contract will be stored if deployed via `deployer` using the [`CREATE`](https://www.evm.codes/#f0?fork=shanghai) opcode. For the specification of the Recursive Length Prefix (RLP) encoding scheme, please refer to p. 19 of the [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) and the [Ethereum Wiki](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/). Based on the [EIP-161](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md) specification, all contract accounts on the Ethereum mainnet are initiated with `nonce = 1`. Thus, the first contract address created by another contract is calculated with a non-zero nonce.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: deployer\n  type: address\n  description: The 20-byte deployer address.\n- name: nonce\n  type: uint256\n  description: The next 32-byte nonce of the deployer address.\n\n# /*:°• Return Value •°:*/ #\n- name: computedAddress\n  type: address\n  description: The 20-byte address where a contract will be stored.\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L122-L136\"\u003e\u003ccode\u003edeployCreate(bytes)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys a new contract via calling the [`CREATE`](https://www.evm.codes/#f0?fork=shanghai) opcode and using the creation bytecode `initCode` and `msg.value` as inputs. In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `msg.value` is non-zero, `initCode` must have a `payable` constructor.\n\n```yml\n# /*:°• Function Argument •°:*/ #\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L180-L200\"\u003e\u003ccode\u003edeployCreateAndInit(bytes,bytes,tuple(uint256,uint256))\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys and initialises a new contract via calling the [`CREATE`](https://www.evm.codes/#f0?fork=shanghai) opcode and using the creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` amounts `values`, and `msg.value` as inputs. In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor, and any excess ether is returned to `msg.sender`.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed contract.\n- name: values\n  type: tuple(uint256,uint256)\n  description: The specific `payable` amounts for the deployment and initialisation call.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L138-L178\"\u003e\u003ccode\u003edeployCreateAndInit(bytes,bytes,tuple(uint256,uint256),address)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys and initialises a new contract via calling the [`CREATE`](https://www.evm.codes/#f0?fork=shanghai) opcode and using the creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` amounts `values`, the refund address `refundAddress`, and `msg.value` as inputs. In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed contract.\n- name: values\n  type: tuple(uint256,uint256)\n  description: The specific `payable` amounts for the deployment and initialisation call.\n- name: refundAddress\n  type: address\n  description: The 20-byte address where any excess ether is returned to.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L202-L240\"\u003e\u003ccode\u003edeployCreateClone(address,bytes)\u003c/code\u003e \u003c/a\u003e \u003c/summary\u003e\n\nDeploys a new [EIP-1167](https://eips.ethereum.org/EIPS/eip-1167) minimal proxy contract using the [`CREATE`](https://www.evm.codes/#f0?fork=shanghai) opcode, and initialises the implementation contract using the implementation address `implementation`, the initialisation code `data`, and `msg.value` as inputs. Note that if `msg.value` is non-zero, the initialiser function called via `data` must be `payable`.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: implementation\n  type: address\n  description: The 20-byte implementation contract address.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed proxy contract.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the clone was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L600-L610\"\u003e\u003ccode\u003ecomputeCreate2Address(bytes32,bytes32)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nReturns the address where a contract will be stored if deployed via _this contract_ (i.e. [`CreateX`](./src/CreateX.sol)) using the [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai) opcode. Any change in the `initCodeHash` or `salt` values will result in a new destination address.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: salt\n  type: bytes32\n  description: The 32-byte random value used to create the contract address.\n- name: initCodeHash\n  type: bytes32\n  description: The 32-byte bytecode digest of the contract creation bytecode.\n\n# /*:°• Return Value •°:*/ #\n- name: computedAddress\n  type: address\n  description: The 20-byte address where a contract will be stored.\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L565-L598\"\u003e\u003ccode\u003ecomputeCreate2Address(bytes32,bytes32,address)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nReturns the address where a contract will be stored if deployed via `deployer` using the [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai) opcode. Any change in the `initCodeHash` or `salt` values will result in a new destination address.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: salt\n  type: bytes32\n  description: The 32-byte random value used to create the contract address.\n- name: initCodeHash\n  type: bytes32\n  description: The 32-byte bytecode digest of the contract creation bytecode.\n- name: deployer\n  type: address\n  description: The 20-byte deployer address.\n\n# /*:°• Return Value •°:*/ #\n- name: computedAddress\n  type: address\n  description: The 20-byte address where a contract will be stored.\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L341-L354\"\u003e\u003ccode\u003edeployCreate2(bytes)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys a new contract via calling the [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai) opcode and using the creation bytecode `initCode` and `msg.value` as inputs. The salt value is calculated _pseudo-randomly_ using a diverse selection of block and transaction properties. This approach does not guarantee true randomness! In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `msg.value` is non-zero, `initCode` must have a `payable` constructor.\n\n```yml\n# /*:°• Function Argument •°:*/ #\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L323-L339\"\u003e\u003ccode\u003edeployCreate2(bytes32,bytes)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys a new contract via calling the [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai) opcode and using the salt value `salt`, the creation bytecode `initCode`, and `msg.value` as inputs. In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `msg.value` is non-zero, `initCode` must have a `payable` constructor.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: salt\n  type: bytes32\n  description: The 32-byte random value used to create the contract address.\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L467-L497\"\u003e\u003ccode\u003edeployCreate2AndInit(bytes,bytes,tuple(uint256,uint256))\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys and initialises a new contract via calling the [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai) opcode and using the creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` amounts `values`, and `msg.value` as inputs. The salt value is calculated _pseudo-randomly_ using a diverse selection of block and transaction properties. This approach does not guarantee true randomness! In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor, and any excess ether is returned to `msg.sender`.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed contract.\n- name: values\n  type: tuple(uint256,uint256)\n  description: The specific `payable` amounts for the deployment and initialisation call.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L401-L431\"\u003e\u003ccode\u003edeployCreate2AndInit(bytes32,bytes,bytes,tuple(uint256,uint256))\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys and initialises a new contract via calling the [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai) opcode and using the salt value `salt`, creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` amounts `values`, and `msg.value` as inputs. In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor, and any excess ether is returned to `msg.sender`.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: salt\n  type: bytes32\n  description: The 32-byte random value used to create the contract address.\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed contract.\n- name: values\n  type: tuple(uint256,uint256)\n  description: The specific `payable` amounts for the deployment and initialisation call.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L433-L465\"\u003e\u003ccode\u003edeployCreate2AndInit(bytes,bytes,tuple(uint256,uint256),address)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys and initialises a new contract via calling the [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai) opcode and using the creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` amounts `values`, the refund address `refundAddress`, and `msg.value` as inputs. The salt value is calculated _pseudo-randomly_ using a diverse selection of block and transaction properties. This approach does not guarantee true randomness! In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed contract.\n- name: values\n  type: tuple(uint256,uint256)\n  description: The specific `payable` amounts for the deployment and initialisation call.\n- name: refundAddress\n  type: address\n  description: The 20-byte address where any excess ether is returned to.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L356-L399\"\u003e\u003ccode\u003edeployCreate2AndInit(bytes32,bytes,bytes,tuple(uint256,uint256),address)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys and initialises a new contract via calling the [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai) opcode and using the salt value `salt`, the creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` amounts `values`, the refund address `refundAddress`, and `msg.value` as inputs. In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: salt\n  type: bytes32\n  description: The 32-byte random value used to create the contract address.\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed contract.\n- name: values\n  type: tuple(uint256,uint256)\n  description: The specific `payable` amounts for the deployment and initialisation call.\n- name: refundAddress\n  type: address\n  description: The 20-byte address where any excess ether is returned to.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L545-L563\"\u003e\u003ccode\u003edeployCreate2Clone(address,bytes)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys a new [EIP-1167](https://eips.ethereum.org/EIPS/eip-1167) minimal proxy contract using the [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai) opcode and the salt value `salt`, and initialises the implementation contract using the implementation address `implementation`, the initialisation code `data`, and `msg.value` as inputs. The salt value is calculated _pseudo-randomly_ using a diverse selection of block and transaction properties. This approach does not guarantee true randomness! Note that if `msg.value` is non-zero, the initialiser function called via `data` must be `payable`.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: implementation\n  type: address\n  description: The 20-byte implementation contract address.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed proxy contract.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the clone was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L499-L543\"\u003e\u003ccode\u003edeployCreate2Clone(bytes32,address,bytes)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys a new [EIP-1167](https://eips.ethereum.org/EIPS/eip-1167) minimal proxy contract using the [`CREATE2`](https://www.evm.codes/#f5?fork=shanghai) opcode and the salt value `salt`, and initialises the implementation contract using the implementation address `implementation`, the initialisation code `data`, and `msg.value` as inputs. Note that if `msg.value` is non-zero, the initialiser function called via `data` must be `payable`.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: salt\n  type: bytes32\n  description: The 32-byte random value used to create the proxy contract address.\n- name: implementation\n  type: address\n  description: The 20-byte implementation contract address.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed proxy contract.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the clone was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L857-L867\"\u003e\u003ccode\u003ecomputeCreate3Address(bytes32)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nReturns the address where a contract will be stored if deployed via _this contract_ (i.e. [`CreateX`](./src/CreateX.sol)) using the [`CREATE3`](https://github.com/ethereum/EIPs/pull/3171) pattern (i.e. without an initcode factor). Any change in the `salt` value will result in a new destination address.\n\n```yml\n# /*:°• Function Argument •°:*/ #\n- name: salt\n  type: bytes32\n  description: The 32-byte random value used to create the proxy contract address.\n\n# /*:°• Return Value •°:*/ #\n- name: computedAddress\n  type: address\n  description: The 20-byte address where a contract will be stored.\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L830-L855\"\u003e\u003ccode\u003ecomputeCreate3Address(bytes32,address)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nReturns the address where a contract will be stored if deployed via `deployer` using the [`CREATE3`](https://github.com/ethereum/EIPs/pull/3171) pattern (i.e. without an initcode factor). Any change in the `salt` value will result in a new destination address.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: salt\n  type: bytes32\n  description: The 32-byte random value used to create the proxy contract address.\n- name: deployer\n  type: address\n  description: The 20-byte deployer address.\n\n# /*:°• Return Value •°:*/ #\n- name: computedAddress\n  type: address\n  description: The 20-byte address where a contract will be stored.\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L648-L663\"\u003e\u003ccode\u003edeployCreate3(bytes)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys a new contract via employing the [`CREATE3`](https://github.com/ethereum/EIPs/pull/3171) pattern (i.e. without an initcode factor) and using the salt value `salt`, the creation bytecode `initCode`, and `msg.value` as inputs. The salt value is calculated _pseudo-randomly_ using a diverse selection of block and transaction properties. This approach does not guarantee true randomness! In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `msg.value` is non-zero, `initCode` must have a `payable` constructor.\n\n```yml\n# /*:°• Function Argument •°:*/ #\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L616-L646\"\u003e\u003ccode\u003edeployCreate3(bytes32,bytes)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys a new contract via employing the [`CREATE3`](https://github.com/ethereum/EIPs/pull/3171) pattern (i.e. without an initcode factor) and using the salt value `salt`, the creation bytecode `initCode`, and `msg.value` as inputs. In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `msg.value` is non-zero, `initCode` must have a `payable` constructor.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: salt\n  type: bytes32\n  description: The 32-byte random value used to create the proxy contract address.\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e We strongly recommend implementing a permissioned deploy protection by setting the first 20 bytes equal to `msg.sender` in the `salt` to prevent maliciously intended frontrun proxy deployments on other chains.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L797-L828\"\u003e\u003ccode\u003edeployCreate3AndInit(bytes,bytes,tuple(uint256,uint256))\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys and initialises a new contract via employing the [`CREATE3`](https://github.com/ethereum/EIPs/pull/3171) pattern (i.e. without an initcode factor) and using the creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` amounts `values`, `msg.value` as inputs. The salt value is calculated _pseudo-randomly_ using a diverse selection of block and transaction properties. This approach does not guarantee true randomness! In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor, and any excess ether is returned to `msg.sender`.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed contract.\n- name: values\n  type: tuple(uint256,uint256)\n  description: The specific `payable` amounts for the deployment and initialisation call.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L725-L760\"\u003e\u003ccode\u003edeployCreate3AndInit(bytes32,bytes,bytes,tuple(uint256,uint256))\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys and initialises a new contract via employing the [`CREATE3`](https://github.com/ethereum/EIPs/pull/3171) pattern (i.e. without an initcode factor) and using the salt value `salt`, the creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` amounts `values`, and `msg.value` as inputs. In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor, and any excess ether is returned to `msg.sender`.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: salt\n  type: bytes32\n  description: The 32-byte random value used to create the proxy contract address.\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed contract.\n- name: values\n  type: tuple(uint256,uint256)\n  description: The specific `payable` amounts for the deployment and initialisation call.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system. Furthermore, we strongly recommend implementing a permissioned deploy protection by setting the first 20 bytes equal to `msg.sender` in the `salt` to prevent maliciously intended frontrun proxy deployments on other chains.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L762-L795\"\u003e\u003ccode\u003edeployCreate3AndInit(bytes,bytes,tuple(uint256,uint256),address)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys and initialises a new contract via employing the [`CREATE3`](https://github.com/ethereum/EIPs/pull/3171) pattern (i.e. without an initcode factor) and using the creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` amounts `values`, the refund address `refundAddress`, and `msg.value` as inputs. The salt value is calculated _pseudo-randomly_ using a diverse selection of block and transaction properties. This approach does not guarantee true randomness! In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed contract.\n- name: values\n  type: tuple(uint256,uint256)\n  description: The specific `payable` amounts for the deployment and initialisation call.\n- name: refundAddress\n  type: address\n  description: The 20-byte address where any excess ether is returned to.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L665-L723\"\u003e\u003ccode\u003edeployCreate3AndInit(bytes32,bytes,bytes,tuple(uint256,uint256),address)\u003c/code\u003e\u003c/a\u003e \u003c/summary\u003e\n\nDeploys and initialises a new contract via employing the [`CREATE3`](https://github.com/ethereum/EIPs/pull/3171) pattern (i.e. without an initcode factor) and using the salt value `salt`, the creation bytecode `initCode`, the initialisation code `data`, the struct for the `payable` amounts `values`, the refund address `refundAddress`, and `msg.value` as inputs. In order to save deployment costs, we do not sanity check the `initCode` length. Note that if `values.constructorAmount` is non-zero, `initCode` must have a `payable` constructor.\n\n```yml\n# /*:°• Function Arguments •°:*/ #\n- name: salt\n  type: bytes32\n  description: The 32-byte random value used to create the proxy contract address.\n- name: initCode\n  type: bytes\n  description: The creation bytecode.\n- name: data\n  type: bytes\n  description: The initialisation code that is passed to the deployed contract.\n- name: values\n  type: tuple(uint256,uint256)\n  description: The specific `payable` amounts for the deployment and initialisation call.\n- name: refundAddress\n  type: address\n  description: The 20-byte address where any excess ether is returned to.\n\n# /*:°• Return Value •°:*/ #\n- name: newContract\n  type: address\n  description: The 20-byte address where the contract was deployed.\n```\n\n\u003e ℹ️ **Note**\u003cbr\u003e\n\u003e This function allows for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system. Furthermore, we strongly recommend implementing a permissioned deploy protection by setting the first 20 bytes equal to `msg.sender` in the `salt` to prevent maliciously intended frontrun proxy deployments on other chains.\n\n\u003c/details\u003e\n\n## Special Features\n\n\u003e [!TIP]\n\u003e Note that the separate project [`createXcrunch`](https://github.com/HrikB/createXcrunch) is a [Rust](https://www.rust-lang.org)-based program designed to efficiently find _zero-leading_, _zero-containing_, or _pattern-matching_ deployment addresses, taking into account the subsequent special features of [`CreateX`](./src/CreateX.sol).\n\n### Permissioned Deploy Protection and Cross-Chain Redeploy Protection\n\nThe `salt` value implements different safeguarding mechanisms depending on the encoded values in the salt (`||` stands for byte-wise concatenation):\n\n```console\n=\u003e salt (32 bytes) = 0xbebebebebebebebebebebebebebebebebebebebe||ff||1212121212121212121212\n```\n\n- The first 20 bytes (i.e. `bebebebebebebebebebebebebebebebebebebebe`) may be used to implement a permissioned deploy protection by setting them equal to `msg.sender`,\n- The 21st byte (i.e. `ff`) may be used to implement a cross-chain redeploy protection by setting it equal to `0x01`,\n- The last random 11 bytes (i.e. `1212121212121212121212`) allow for $2^{88}$ bits of entropy for mining a salt.\n\nThe full logic is implemented in the `internal` [`_guard`](./src/CreateX.sol#L873-L912) function:\n\n```solidity\nfunction _guard(bytes32 salt) internal view returns (bytes32 guardedSalt) {\n  (\n    SenderBytes senderBytes,\n    RedeployProtectionFlag redeployProtectionFlag\n  ) = _parseSalt({ salt: salt });\n\n  if (\n    senderBytes == SenderBytes.MsgSender \u0026\u0026\n    redeployProtectionFlag == RedeployProtectionFlag.True\n  ) {\n    // Configures a permissioned deploy protection as well as a cross-chain redeploy protection.\n    guardedSalt = keccak256(abi.encode(msg.sender, block.chainid, salt));\n  } else if (\n    senderBytes == SenderBytes.MsgSender \u0026\u0026\n    redeployProtectionFlag == RedeployProtectionFlag.False\n  ) {\n    // Configures solely a permissioned deploy protection.\n    guardedSalt = _efficientHash({\n      a: bytes32(uint256(uint160(msg.sender))),\n      b: salt\n    });\n  } else if (senderBytes == SenderBytes.MsgSender) {\n    // Reverts if the 21st byte is greater than `0x01` in order to enforce developer explicitness.\n    revert InvalidSalt({ emitter: _SELF });\n  } else if (\n    senderBytes == SenderBytes.ZeroAddress \u0026\u0026\n    redeployProtectionFlag == RedeployProtectionFlag.True\n  ) {\n    // Configures solely a cross-chain redeploy protection. In order to prevent a pseudo-randomly\n    // generated cross-chain redeploy protection, we enforce the zero address check for the first 20 bytes.\n    guardedSalt = _efficientHash({ a: bytes32(block.chainid), b: salt });\n  } else if (\n    senderBytes == SenderBytes.ZeroAddress \u0026\u0026\n    redeployProtectionFlag == RedeployProtectionFlag.Unspecified\n  ) {\n    // Reverts if the 21st byte is greater than `0x01` in order to enforce developer explicitness.\n    revert InvalidSalt({ emitter: _SELF });\n  } else {\n    // For the non-pseudo-random cases, the salt value `salt` is hashed to prevent the safeguard mechanisms\n    // from being bypassed. Otherwise, the salt value `salt` is not modified.\n    guardedSalt = (salt != _generateSalt())\n      ? keccak256(abi.encode(salt))\n      : salt;\n  }\n}\n```\n\nPlease note that when you configure a permissioned deploy protection, you **must** specify whether you want cross-chain redeploy protection (i.e. 21st byte equals `0x01`) or not (i.e. the 21st byte equals `0x00`). The underlying reason for this logic is to enforce developer explicitness. If you don't specify a cross-chain redeploy protection decision (i.e. the 21st byte is greater than `0x01`) the function reverts.\n\nFurthermore, you can configure _only_ cross-chain redeploy protection by setting the first 20 bytes equal to the zero address `0x0000000000000000000000000000000000000000`. The rationale behind this logic is to prevent a pseudo-randomly generated 32 byte salt from inadvertently activating cross-chain redeploy protection. Also in this case, if you don't specify a cross-chain redeploy protection, i.e. the 21st byte is greater than `0x01`, the function reverts. The underlying reason for this logic is as well to enforce developer explicitness.\n\n\u003e [!IMPORTANT]\n\u003e When using the read-only functions [`computeCreate2Address(bytes32,bytes32)`](https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L600-L610) or [`computeCreate3Address(bytes32)`](https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L857-L867), it is essential to provide the _guarded_ `salt` value, meaning the value after being processed by the `_guard` function, as the input parameter. This ensures the correct computation of the deployment address. For more details, refer to [this issue](https://github.com/pcaversaccio/createx/issues/140).\n\n### Pseudo-Random Salt Value\n\nFor developer convenience, the [`CreateX`](./src/CreateX.sol) contract offers several overloaded functions that generate the salt value pseudo-randomly using a diverse selection of block and transaction properties. Please note that this approach does not guarantee true randomness!\n\nThe full logic is implemented in the `internal` [`_generateSalt`](./src/CreateX.sol#L960-L988) function:\n\n```solidity\nfunction _generateSalt() internal view returns (bytes32 salt) {\n  unchecked {\n    salt = keccak256(\n      abi.encode(\n        // We don't use `block.number - 256` (the maximum value on the EVM) to accommodate\n        // any chains that may try to reduce the amount of available historical block hashes.\n        // We also don't subtract 1 to mitigate any risks arising from consecutive block\n        // producers on a PoS chain. Therefore, we use `block.number - 32` as a reasonable\n        // compromise, one we expect should work on most chains, which is 1 epoch on Ethereum\n        // mainnet. Please note that if you use this function between the genesis block and block\n        // number 31, the block property `blockhash` will return zero, but the returned salt value\n        // `salt` will still have a non-zero value due to the hashing characteristic and the other\n        // remaining properties.\n        blockhash(block.number - 32),\n        block.coinbase,\n        block.number,\n        block.timestamp,\n        block.prevrandao,\n        block.chainid,\n        msg.sender\n      )\n    );\n  }\n}\n```\n\n## Design Principles\n\n- [`CreateX`](./src/CreateX.sol) should cover _most_ but not all contract creation use cases.\n- [`CreateX`](./src/CreateX.sol) should be human-readable and should be simple to understand for readers with low prior experience.\n- [`CreateX`](./src/CreateX.sol) should be maximally secure, i.e. no hidden footguns.\n- [`CreateX`](./src/CreateX.sol) should be trustless.\n- [`CreateX`](./src/CreateX.sol) should be stateless.\n- [`CreateX`](./src/CreateX.sol) should be extensible (i.e. it can be used to deploy protocols, within protocols, or to deploy other types of deterministic deployer factories).\n\nThe following consequences result from these principles:\n\n- We only use inline assembly if it is required or if the code section itself is based on short and/or audited code.\n- We document the contract to the smallest detail.\n- We extensively fuzz test all functions.\n- We deliberately do not implement special functions for [clones with immutable arguments](https://github.com/wighawag/clones-with-immutable-args), as there is neither a finalised standard nor a properly audited contract version.\n- We do not implement any special functions for [EIP-5202](https://eips.ethereum.org/EIPS/eip-5202) (a.k.a. blueprint contracts), as all existing functions in [`CreateX`](./src/CreateX.sol) are already cost-effective alternatives in our opinion.\n\n## Security Considerations\n\n\u003c!-- prettier-ignore-start --\u003e\n\u003e [!WARNING]\n\u003e **This contract is unaudited!** Special thanks go to [Oleksii Matiiasevych](https://github.com/lastperson) for his thorough review and feedback 🙏🏽.\n\u003c!-- prettier-ignore-end --\u003e\n\nGenerally, for security issues, see our [Security Policy](./SECURITY.md). Furthermore, you must be aware of the following aspects:\n\n- Several functions allow for reentrancy, however we refrain from adding a mutex lock to keep it as use-case agnostic as possible. Please ensure at the protocol level that potentially malicious reentrant calls do not affect your smart contract system.\n- In the functions:\n\n  - [`deployCreate3(bytes32,bytes)`](https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L616-L646),\n  - [`deployCreate3AndInit(bytes32,bytes,bytes,tuple(uint256,uint256))`](https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L725-L760), and\n  - [`deployCreate3AndInit(bytes32,bytes,bytes,tuple(uint256,uint256),address)`](https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L665-L723)\n\n  we strongly recommend implementing a permissioned deploy protection by setting the first 20 bytes equal to `msg.sender` in the `salt` to prevent maliciously intended frontrun proxy deployments on other chains.\n\n- The target EVM version for compilation is set to [`paris`](https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md), i.e. neither the contract creation bytecode of [`CreateX`](./src/CreateX.sol) nor the returned runtime bytecode contains a [`PUSH0`](https://www.evm.codes/#5f?fork=shanghai) instruction.\n- Please refer to our comment in the discussion [here](https://github.com/pcaversaccio/createx/discussions/61#discussioncomment-7937359) for background information on the risks of our private-key-based deployment approach. We recommend verifying prior to interacting with [`CreateX`](./src/CreateX.sol) on any chain, that the `keccak256` hash of the broadcasted contract creation bytecode is `0x12ec861579b63a3ab9db3b5a23c57d56402ad3061475b088f17054e2f2daf22f` or of the deployed runtime bytecode is `0xbd8a7ea8cfca7b4e5f5041d7d4b17bc317c5ce42cfbc42066a00cf26b43eb53f`.\n\n## Tests\n\nFor all (fuzz) tests available in the [`test`](./test) directory, we have consistently applied the [Branching Tree Technique](https://x.com/PaulRBerg/status/1682346315806539776) with [`bulloak`](https://github.com/alexfertel/bulloak). This means that each test file is accompanied by a `.tree` file that defines all the necessary branches to be tested.\n\n**Example ([`CreateX._guard.tree`](./test/internal/CreateX._guard.tree)):**\n\n```tree\nCreateX_Guard_Internal_Test\n├── When the first 20 bytes of the salt equals the caller\n│   ├── When the 21st byte of the salt equals 0x01\n│   │   └── It should return the keccak256 hash of the ABI-encoded values msg.sender, block.chainid, and the salt.\n│   ├── When the 21st byte of the salt equals 0x00\n│   │   └── It should return the keccak256 hash of the ABI-encoded values msg.sender and the salt.\n│   └── When the 21st byte of the salt is greater than 0x01\n│       └── It should revert.\n├── When the first 20 bytes of the salt equals the zero address\n│   ├── When the 21st byte of the salt equals 0x01\n│   │   └── It should return the keccak256 hash of the ABI-encoded values block.chainid and the salt.\n│   ├── When the 21st byte of the salt equals 0x00\n│   │   └── It should return the keccak256 hash of the ABI-encoded value salt.\n│   └── When the 21st byte of the salt is greater than 0x01\n│       └── It should revert.\n└── When the first 20 bytes of the salt do not equal the caller or the zero address\n    ├── It should return the keccak256 hash of the ABI-encoded value salt.\n    └── When the salt value is generated pseudo-randomly\n        └── It should return the unmodified salt value.\n```\n\n### Test Coverage\n\nThis project repository uses [`forge coverage`](https://book.getfoundry.sh/reference/forge/forge-coverage). Simply run:\n\n```console\nforge coverage\n```\n\nIn order to generate an `HTML` file with the coverage data, you can invoke:\n\n```console\npnpm coverage:report\n```\n\nThe written tests available in the directory [`test`](./test) achieve a test coverage of **100%** for the [`CreateX`](./src/CreateX.sol) contract:\n\n```console\n| File            | % Lines           | % Statements      | % Branches      | % Funcs         |\n|-----------------|-------------------|-------------------|-----------------|-----------------|\n| src/CreateX.sol | 100.00% (206/206) | 100.00% (211/211) | 100.00% (61/61) | 100.00% (31/31) |\n```\n\n\u003e [!IMPORTANT]\n\u003e A test coverage of 100% does not mean that there are no vulnerabilities. What really counts is the quality and spectrum of the tests themselves!\n\n## ABI (Application Binary Interface)\n\n\u003e [!TIP]\n\u003e If you `forge install` this repository, the Solidity-based interface can also be found [here](./src/ICreateX.sol).\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://docs.soliditylang.org/en/latest/\"\u003eSolidity\u003c/a\u003e \u003c/summary\u003e\n\n```solidity\n// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.4;\n\n/**\n * @title CreateX Factory Interface Definition\n * @author pcaversaccio (https://web.archive.org/web/20230921103111/https://pcaversaccio.com/)\n * @custom:coauthor Matt Solomon (https://web.archive.org/web/20230921103335/https://mattsolomon.dev/)\n */\ninterface ICreateX {\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n  /*                            TYPES                           */\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n  struct Values {\n    uint256 constructorAmount;\n    uint256 initCallAmount;\n  }\n\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n  /*                           EVENTS                           */\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n  event ContractCreation(address indexed newContract, bytes32 indexed salt);\n  event ContractCreation(address indexed newContract);\n  event Create3ProxyContractCreation(\n    address indexed newContract,\n    bytes32 indexed salt\n  );\n\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n  /*                        CUSTOM ERRORS                       */\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n  error FailedContractCreation(address emitter);\n  error FailedContractInitialisation(address emitter, bytes revertData);\n  error InvalidSalt(address emitter);\n  error InvalidNonceValue(address emitter);\n  error FailedEtherTransfer(address emitter, bytes revertData);\n\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n  /*                           CREATE                           */\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n  function deployCreate(\n    bytes memory initCode\n  ) external payable returns (address newContract);\n\n  function deployCreateAndInit(\n    bytes memory initCode,\n    bytes memory data,\n    Values memory values,\n    address refundAddress\n  ) external payable returns (address newContract);\n\n  function deployCreateAndInit(\n    bytes memory initCode,\n    bytes memory data,\n    Values memory values\n  ) external payable returns (address newContract);\n\n  function deployCreateClone(\n    address implementation,\n    bytes memory data\n  ) external payable returns (address proxy);\n\n  function computeCreateAddress(\n    address deployer,\n    uint256 nonce\n  ) external view returns (address computedAddress);\n\n  function computeCreateAddress(\n    uint256 nonce\n  ) external view returns (address computedAddress);\n\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n  /*                           CREATE2                          */\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n  function deployCreate2(\n    bytes32 salt,\n    bytes memory initCode\n  ) external payable returns (address newContract);\n\n  function deployCreate2(\n    bytes memory initCode\n  ) external payable returns (address newContract);\n\n  function deployCreate2AndInit(\n    bytes32 salt,\n    bytes memory initCode,\n    bytes memory data,\n    Values memory values,\n    address refundAddress\n  ) external payable returns (address newContract);\n\n  function deployCreate2AndInit(\n    bytes32 salt,\n    bytes memory initCode,\n    bytes memory data,\n    Values memory values\n  ) external payable returns (address newContract);\n\n  function deployCreate2AndInit(\n    bytes memory initCode,\n    bytes memory data,\n    Values memory values,\n    address refundAddress\n  ) external payable returns (address newContract);\n\n  function deployCreate2AndInit(\n    bytes memory initCode,\n    bytes memory data,\n    Values memory values\n  ) external payable returns (address newContract);\n\n  function deployCreate2Clone(\n    bytes32 salt,\n    address implementation,\n    bytes memory data\n  ) external payable returns (address proxy);\n\n  function deployCreate2Clone(\n    address implementation,\n    bytes memory data\n  ) external payable returns (address proxy);\n\n  function computeCreate2Address(\n    bytes32 salt,\n    bytes32 initCodeHash,\n    address deployer\n  ) external pure returns (address computedAddress);\n\n  function computeCreate2Address(\n    bytes32 salt,\n    bytes32 initCodeHash\n  ) external view returns (address computedAddress);\n\n  /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/\n  /*                           CREATE3                          */\n  /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/\n\n  function deployCreate3(\n    bytes32 salt,\n    bytes memory initCode\n  ) external payable returns (address newContract);\n\n  function deployCreate3(\n    bytes memory initCode\n  ) external payable returns (address newContract);\n\n  function deployCreate3AndInit(\n    bytes32 salt,\n    bytes memory initCode,\n    bytes memory data,\n    Values memory values,\n    address refundAddress\n  ) external payable returns (address newContract);\n\n  function deployCreate3AndInit(\n    bytes32 salt,\n    bytes memory initCode,\n    bytes memory data,\n    Values memory values\n  ) external payable returns (address newContract);\n\n  function deployCreate3AndInit(\n    bytes memory initCode,\n    bytes memory data,\n    Values memory values,\n    address refundAddress\n  ) external payable returns (address newContract);\n\n  function deployCreate3AndInit(\n    bytes memory initCode,\n    bytes memory data,\n    Values memory values\n  ) external payable returns (address newContract);\n\n  function computeCreate3Address(\n    bytes32 salt,\n    address deployer\n  ) external pure returns (address computedAddress);\n\n  function computeCreate3Address(\n    bytes32 salt\n  ) external view returns (address computedAddress);\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://docs.ethers.org/v6/\"\u003eethers.js\u003c/a\u003e \u003c/summary\u003e\n\n```json\n[\n  \"error FailedContractCreation(address)\",\n  \"error FailedContractInitialisation(address,bytes)\",\n  \"error FailedEtherTransfer(address,bytes)\",\n  \"error InvalidNonceValue(address)\",\n  \"error InvalidSalt(address)\",\n  \"event ContractCreation(address indexed,bytes32 indexed)\",\n  \"event ContractCreation(address indexed)\",\n  \"event Create3ProxyContractCreation(address indexed,bytes32 indexed)\",\n  \"function computeCreate2Address(bytes32,bytes32) view returns (address)\",\n  \"function computeCreate2Address(bytes32,bytes32,address) pure returns (address)\",\n  \"function computeCreate3Address(bytes32,address) pure returns (address)\",\n  \"function computeCreate3Address(bytes32) view returns (address)\",\n  \"function computeCreateAddress(uint256) view returns (address)\",\n  \"function computeCreateAddress(address,uint256) view returns (address)\",\n  \"function deployCreate(bytes) payable returns (address)\",\n  \"function deployCreate2(bytes32,bytes) payable returns (address)\",\n  \"function deployCreate2(bytes) payable returns (address)\",\n  \"function deployCreate2AndInit(bytes32,bytes,bytes,tuple(uint256,uint256),address) payable returns (address)\",\n  \"function deployCreate2AndInit(bytes,bytes,tuple(uint256,uint256)) payable returns (address)\",\n  \"function deployCreate2AndInit(bytes,bytes,tuple(uint256,uint256),address) payable returns (address)\",\n  \"function deployCreate2AndInit(bytes32,bytes,bytes,tuple(uint256,uint256)) payable returns (address)\",\n  \"function deployCreate2Clone(bytes32,address,bytes) payable returns (address)\",\n  \"function deployCreate2Clone(address,bytes) payable returns (address)\",\n  \"function deployCreate3(bytes) payable returns (address)\",\n  \"function deployCreate3(bytes32,bytes) payable returns (address)\",\n  \"function deployCreate3AndInit(bytes32,bytes,bytes,tuple(uint256,uint256)) payable returns (address)\",\n  \"function deployCreate3AndInit(bytes,bytes,tuple(uint256,uint256)) payable returns (address)\",\n  \"function deployCreate3AndInit(bytes32,bytes,bytes,tuple(uint256,uint256),address) payable returns (address)\",\n  \"function deployCreate3AndInit(bytes,bytes,tuple(uint256,uint256),address) payable returns (address)\",\n  \"function deployCreateAndInit(bytes,bytes,tuple(uint256,uint256)) payable returns (address)\",\n  \"function deployCreateAndInit(bytes,bytes,tuple(uint256,uint256),address) payable returns (address)\",\n  \"function deployCreateClone(address,bytes) payable returns (address)\"\n]\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://viem.sh\"\u003eviem\u003c/a\u003e \u003c/summary\u003e\n\n```ts\n[\n  \"error FailedContractCreation(address emitter)\",\n  \"error FailedContractInitialisation(address emitter, bytes revertData)\",\n  \"error FailedEtherTransfer(address emitter, bytes revertData)\",\n  \"error InvalidNonceValue(address emitter)\",\n  \"error InvalidSalt(address emitter)\",\n  \"event ContractCreation(address indexed newContract, bytes32 indexed salt)\",\n  \"event ContractCreation(address indexed newContract)\",\n  \"event Create3ProxyContractCreation(address indexed newContract, bytes32 indexed salt)\",\n  \"function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) view returns (address computedAddress)\",\n  \"function computeCreate2Address(bytes32 salt, bytes32 initCodeHash, address deployer) pure returns (address computedAddress)\",\n  \"function computeCreate3Address(bytes32 salt, address deployer) pure returns (address computedAddress)\",\n  \"function computeCreate3Address(bytes32 salt) view returns (address computedAddress)\",\n  \"function computeCreateAddress(uint256 nonce) view returns (address computedAddress)\",\n  \"function computeCreateAddress(address deployer, uint256 nonce) view returns (address computedAddress)\",\n  \"function deployCreate(bytes initCode) payable returns (address newContract)\",\n  \"function deployCreate2(bytes32 salt, bytes initCode) payable returns (address newContract)\",\n  \"function deployCreate2(bytes initCode) payable returns (address newContract)\",\n  \"function deployCreate2AndInit(bytes32 salt, bytes initCode, bytes data, (uint256 constructorAmount, uint256 initCallAmount) values, address refundAddress) payable returns (address newContract)\",\n  \"function deployCreate2AndInit(bytes initCode, bytes data, (uint256 constructorAmount, uint256 initCallAmount) values) payable returns (address newContract)\",\n  \"function deployCreate2AndInit(bytes initCode, bytes data, (uint256 constructorAmount, uint256 initCallAmount) values, address refundAddress) payable returns (address newContract)\",\n  \"function deployCreate2AndInit(bytes32 salt, bytes initCode, bytes data, (uint256 constructorAmount, uint256 initCallAmount) values) payable returns (address newContract)\",\n  \"function deployCreate2Clone(bytes32 salt, address implementation, bytes data) payable returns (address proxy)\",\n  \"function deployCreate2Clone(address implementation, bytes data) payable returns (address proxy)\",\n  \"function deployCreate3(bytes initCode) payable returns (address newContract)\",\n  \"function deployCreate3(bytes32 salt, bytes initCode) payable returns (address newContract)\",\n  \"function deployCreate3AndInit(bytes32 salt, bytes initCode, bytes data, (uint256 constructorAmount, uint256 initCallAmount) values) payable returns (address newContract)\",\n  \"function deployCreate3AndInit(bytes initCode, bytes data, (uint256 constructorAmount, uint256 initCallAmount) values) payable returns (address newContract)\",\n  \"function deployCreate3AndInit(bytes32 salt, bytes initCode, bytes data, (uint256 constructorAmount, uint256 initCallAmount) values, address refundAddress) payable returns (address newContract)\",\n  \"function deployCreate3AndInit(bytes initCode, bytes data, (uint256 constructorAmount, uint256 initCallAmount) values, address refundAddress) payable returns (address newContract)\",\n  \"function deployCreateAndInit(bytes initCode, bytes data, (uint256 constructorAmount, uint256 initCallAmount) values) payable returns (address newContract)\",\n  \"function deployCreateAndInit(bytes initCode, bytes data, (uint256 constructorAmount, uint256 initCallAmount) values, address refundAddress) payable returns (address newContract)\",\n  \"function deployCreateClone(address implementation, bytes data) payable returns (address proxy)\",\n] as const;\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e \u003ca href=\"https://docs.soliditylang.org/en/latest/abi-spec.html#json\"\u003eJSON\u003c/a\u003e \u003c/summary\u003e\n\n```json\n[\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"emitter\",\n        \"type\": \"address\"\n      }\n    ],\n    \"name\": \"FailedContractCreation\",\n    \"type\": \"error\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"emitter\",\n        \"type\": \"address\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"revertData\",\n        \"type\": \"bytes\"\n      }\n    ],\n    \"name\": \"FailedContractInitialisation\",\n    \"type\": \"error\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"emitter\",\n        \"type\": \"address\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"revertData\",\n        \"type\": \"bytes\"\n      }\n    ],\n    \"name\": \"FailedEtherTransfer\",\n    \"type\": \"error\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"emitter\",\n        \"type\": \"address\"\n      }\n    ],\n    \"name\": \"InvalidNonceValue\",\n    \"type\": \"error\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"emitter\",\n        \"type\": \"address\"\n      }\n    ],\n    \"name\": \"InvalidSalt\",\n    \"type\": \"error\"\n  },\n  {\n    \"anonymous\": false,\n    \"inputs\": [\n      {\n        \"indexed\": true,\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      },\n      {\n        \"indexed\": true,\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      }\n    ],\n    \"name\": \"ContractCreation\",\n    \"type\": \"event\"\n  },\n  {\n    \"anonymous\": false,\n    \"inputs\": [\n      {\n        \"indexed\": true,\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"name\": \"ContractCreation\",\n    \"type\": \"event\"\n  },\n  {\n    \"anonymous\": false,\n    \"inputs\": [\n      {\n        \"indexed\": true,\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      },\n      {\n        \"indexed\": true,\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      }\n    ],\n    \"name\": \"Create3ProxyContractCreation\",\n    \"type\": \"event\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      },\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"initCodeHash\",\n        \"type\": \"bytes32\"\n      }\n    ],\n    \"name\": \"computeCreate2Address\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"computedAddress\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"view\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      },\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"initCodeHash\",\n        \"type\": \"bytes32\"\n      },\n      {\n        \"internalType\": \"address\",\n        \"name\": \"deployer\",\n        \"type\": \"address\"\n      }\n    ],\n    \"name\": \"computeCreate2Address\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"computedAddress\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"pure\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      },\n      {\n        \"internalType\": \"address\",\n        \"name\": \"deployer\",\n        \"type\": \"address\"\n      }\n    ],\n    \"name\": \"computeCreate3Address\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"computedAddress\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"pure\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      }\n    ],\n    \"name\": \"computeCreate3Address\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"computedAddress\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"view\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"uint256\",\n        \"name\": \"nonce\",\n        \"type\": \"uint256\"\n      }\n    ],\n    \"name\": \"computeCreateAddress\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"computedAddress\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"view\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"deployer\",\n        \"type\": \"address\"\n      },\n      {\n        \"internalType\": \"uint256\",\n        \"name\": \"nonce\",\n        \"type\": \"uint256\"\n      }\n    ],\n    \"name\": \"computeCreateAddress\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"computedAddress\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"view\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      }\n    ],\n    \"name\": \"deployCreate\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      }\n    ],\n    \"name\": \"deployCreate2\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      }\n    ],\n    \"name\": \"deployCreate2\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"components\": [\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"constructorAmount\",\n            \"type\": \"uint256\"\n          },\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"initCallAmount\",\n            \"type\": \"uint256\"\n          }\n        ],\n        \"internalType\": \"struct CreateX.Values\",\n        \"name\": \"values\",\n        \"type\": \"tuple\"\n      },\n      {\n        \"internalType\": \"address\",\n        \"name\": \"refundAddress\",\n        \"type\": \"address\"\n      }\n    ],\n    \"name\": \"deployCreate2AndInit\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"components\": [\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"constructorAmount\",\n            \"type\": \"uint256\"\n          },\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"initCallAmount\",\n            \"type\": \"uint256\"\n          }\n        ],\n        \"internalType\": \"struct CreateX.Values\",\n        \"name\": \"values\",\n        \"type\": \"tuple\"\n      }\n    ],\n    \"name\": \"deployCreate2AndInit\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"components\": [\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"constructorAmount\",\n            \"type\": \"uint256\"\n          },\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"initCallAmount\",\n            \"type\": \"uint256\"\n          }\n        ],\n        \"internalType\": \"struct CreateX.Values\",\n        \"name\": \"values\",\n        \"type\": \"tuple\"\n      },\n      {\n        \"internalType\": \"address\",\n        \"name\": \"refundAddress\",\n        \"type\": \"address\"\n      }\n    ],\n    \"name\": \"deployCreate2AndInit\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"components\": [\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"constructorAmount\",\n            \"type\": \"uint256\"\n          },\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"initCallAmount\",\n            \"type\": \"uint256\"\n          }\n        ],\n        \"internalType\": \"struct CreateX.Values\",\n        \"name\": \"values\",\n        \"type\": \"tuple\"\n      }\n    ],\n    \"name\": \"deployCreate2AndInit\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      },\n      {\n        \"internalType\": \"address\",\n        \"name\": \"implementation\",\n        \"type\": \"address\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      }\n    ],\n    \"name\": \"deployCreate2Clone\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"proxy\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"implementation\",\n        \"type\": \"address\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      }\n    ],\n    \"name\": \"deployCreate2Clone\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"proxy\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      }\n    ],\n    \"name\": \"deployCreate3\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      }\n    ],\n    \"name\": \"deployCreate3\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"components\": [\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"constructorAmount\",\n            \"type\": \"uint256\"\n          },\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"initCallAmount\",\n            \"type\": \"uint256\"\n          }\n        ],\n        \"internalType\": \"struct CreateX.Values\",\n        \"name\": \"values\",\n        \"type\": \"tuple\"\n      }\n    ],\n    \"name\": \"deployCreate3AndInit\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"components\": [\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"constructorAmount\",\n            \"type\": \"uint256\"\n          },\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"initCallAmount\",\n            \"type\": \"uint256\"\n          }\n        ],\n        \"internalType\": \"struct CreateX.Values\",\n        \"name\": \"values\",\n        \"type\": \"tuple\"\n      }\n    ],\n    \"name\": \"deployCreate3AndInit\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes32\",\n        \"name\": \"salt\",\n        \"type\": \"bytes32\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"components\": [\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"constructorAmount\",\n            \"type\": \"uint256\"\n          },\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"initCallAmount\",\n            \"type\": \"uint256\"\n          }\n        ],\n        \"internalType\": \"struct CreateX.Values\",\n        \"name\": \"values\",\n        \"type\": \"tuple\"\n      },\n      {\n        \"internalType\": \"address\",\n        \"name\": \"refundAddress\",\n        \"type\": \"address\"\n      }\n    ],\n    \"name\": \"deployCreate3AndInit\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"components\": [\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"constructorAmount\",\n            \"type\": \"uint256\"\n          },\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"initCallAmount\",\n            \"type\": \"uint256\"\n          }\n        ],\n        \"internalType\": \"struct CreateX.Values\",\n        \"name\": \"values\",\n        \"type\": \"tuple\"\n      },\n      {\n        \"internalType\": \"address\",\n        \"name\": \"refundAddress\",\n        \"type\": \"address\"\n      }\n    ],\n    \"name\": \"deployCreate3AndInit\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"components\": [\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"constructorAmount\",\n            \"type\": \"uint256\"\n          },\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"initCallAmount\",\n            \"type\": \"uint256\"\n          }\n        ],\n        \"internalType\": \"struct CreateX.Values\",\n        \"name\": \"values\",\n        \"type\": \"tuple\"\n      }\n    ],\n    \"name\": \"deployCreateAndInit\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"initCode\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      },\n      {\n        \"components\": [\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"constructorAmount\",\n            \"type\": \"uint256\"\n          },\n          {\n            \"internalType\": \"uint256\",\n            \"name\": \"initCallAmount\",\n            \"type\": \"uint256\"\n          }\n        ],\n        \"internalType\": \"struct CreateX.Values\",\n        \"name\": \"values\",\n        \"type\": \"tuple\"\n      },\n      {\n        \"internalType\": \"address\",\n        \"name\": \"refundAddress\",\n        \"type\": \"address\"\n      }\n    ],\n    \"name\": \"deployCreateAndInit\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"newContract\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  },\n  {\n    \"inputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"implementation\",\n        \"type\": \"address\"\n      },\n      {\n        \"internalType\": \"bytes\",\n        \"name\": \"data\",\n        \"type\": \"bytes\"\n      }\n    ],\n    \"name\": \"deployCreateClone\",\n    \"outputs\": [\n      {\n        \"internalType\": \"address\",\n        \"name\": \"proxy\",\n        \"type\": \"address\"\n      }\n    ],\n    \"stateMutability\": \"payable\",\n    \"type\": \"function\"\n  }\n]\n```\n\n\u003c/details\u003e\n\n## New Deployment(s)\n\nWe offer two options for deploying [`CreateX`](./src/CreateX.sol) to your desired chain:\n\n1. Deploy it yourself by using one of the pre-signed transactions. Details can be found in the subsequent paragraph.\n2. Request a deployment by opening an [issue](https://github.com/pcaversaccio/createx/issues/new?assignees=pcaversaccio\u0026labels=new+deployment+%E2%9E%95\u0026projects=\u0026template=deployment_request.yml\u0026title=%5BNew-Deployment-Request%5D%3A+). You can significantly reduce the time to deployment by sending funds to cover the deployment cost (a reliable amount with a small tip 😏 would be ~0.3 ETH) to the deployer account: `0xeD456e05CaAb11d66C4c797dD6c1D6f9A7F352b5`.\n\n\u003e [!CAUTION]\n\u003e Prior to using a pre-signed transaction, you **MUST** ensure that the gas metering of the target chain is **EQUIVALENT** to that of Ethereum's EVM version!\n\u003e\n\u003e The _default_ pre-signed transaction has a gas limit of 3,000,000 gas, so if the target chain requires more than 3 million gas to deploy, the contract creation transaction will revert and we will not be able to deploy [`CreateX`](./src/CreateX.sol) to the address `0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed`. In this case, the only way to get [`CreateX`](./src/CreateX.sol) deployed at the expected address is for the chain to store the contract there as a predeploy.\n\u003e\n\u003e If you are not sure how to validate this, you can either use the [`eth_estimateGas`](https://ethereum.github.io/execution-apis/api-documentation/) JSON-RPC method or simply deploy the [`CreateX`](./src/CreateX.sol) contract from another account and see how much gas is needed for the deployment. Standard EVM chains should require exactly 2,580,902 gas to deploy [`CreateX`](./src/CreateX.sol).\n\nWe repeat: PLEASE DO NOT BROADCAST ANY PRE-SIGNED TRANSACTION WITHOUT LOCAL TESTING! Also, before deploying, you MUST send at least 0.3 ETH to the deployer address `0xeD456e05CaAb11d66C4c797dD6c1D6f9A7F352b5`. We offer three pre-signed, pre-[`EIP-155`](https://eips.ethereum.org/EIPS/eip-155) transactions with the same gas price of 100 gwei, but different `gasLimit` levels:\n\n- _Default Case:_ `gasLimit = 3_000_000`; [`signed_serialised_transaction_gaslimit_3000000_.json`](./scripts/presigned-createx-deployment-transactions/signed_serialised_transaction_gaslimit_3000000_.json),\n- _Medium Case:_ `gasLimit = 25_000_000`; [`signed_serialised_transaction_gaslimit_25000000_.json`](./scripts/presigned-createx-deployment-transactions/signed_serialised_transaction_gaslimit_25000000_.json),\n- _Heavy Case:_ `gasLimit = 45_000_000`; [`signed_serialised_transaction_gaslimit_45000000_.json`](./scripts/presigned-createx-deployment-transactions/signed_serialised_transaction_gaslimit_45000000_.json).\n\nYou can broadcast the transaction using either [`ethers.js`](https://docs.ethers.org/v6/) or [`cast`](https://book.getfoundry.sh/reference/cli/cast):\n\n#### [`ethers.js`](https://docs.ethers.org/v6/)\n\nIt is recommended to install [`pnpm`](https://pnpm.io) through the `npm` package manager, which comes bundled with [Node.js](https://nodejs.org/en) when you install it on your system. It is recommended to use a Node.js version `\u003e=22.11.0`.\n\nOnce you have `npm` installed, you can run the following both to install and upgrade `pnpm`:\n\n```console\nnpm install -g pnpm\n```\n\nAfter having installed `pnpm`, simply run:\n\n```console\ngit clone https://github.com/pcaversaccio/createx.git\ncd createx\npnpm install\n```\n\nNow configure your target chain in the [`hardhat.config.ts`](./hardhat.config.ts) file with the `networks` and `etherscan` properties, or use one of the preconfigured network configurations. After you have locally ensured that the `gasLimit` of 3 million works on your target chain, you can invoke:\n\n```console\nnpx hardhat run --no-compile --network \u003cNETWORK_NAME\u003e scripts/deploy.ts\n```\n\nThe [`deploy.ts`](./scripts/deploy.ts) script ensures that [`CreateX`](./src/CreateX.sol) is automatically verified if you have configured the `etherscan` property accordingly. The current script broadcasts the _default_ pre-signed transaction, which has a gas limit of 3,000,000 gas. If you want to use a different pre-signed transaction, you must change the import of the pre-signed transaction in the [`deploy.ts`](./scripts/deploy.ts) script.\n\n#### [`cast`](https://book.getfoundry.sh/reference/cli/cast)\n\nIt is recommended to install [Foundry](https://github.com/foundry-rs/foundry) via:\n\n```console\ncurl -L https://foundry.paradigm.xyz | bash\nfoundryup\n```\n\nTo broadcast a pre-signed transaction, you can invoke:\n\n```console\n# $TX is the pre-signed transaction.\n# $RPC_URL is the RPC URL of the target chain to which you want to deploy.\ncast publish $TX --rpc-url $RPC_URL\n```\n\nYou must verify the [`CreateX`](./src/CreateX.sol) contract separately, as specified in the next section.\n\n\u003e [!IMPORTANT]\n\u003e After deployment, please open a pull request that updates the [`deployments.json`](./deployments/deployments.json) file and the [`CreateX` Deployments](#createx-deployments) section with the new deployment so that other users can easily know that it has been deployed.\n\n### Contract Verification\n\nTo verify a deployed [`CreateX`](./src/CreateX.sol) contract on a block explorer, use the following parameters:\n\n- _Verification Method / Compiler Type:_ `Solidity (Standard JSON Input)`,\n- _Compiler Version:_ `v0.8.23+commit.f704f362`,\n- _Open Source License Type:_ `GNU Affero General Public License (GNU AGPLv3)`,\n- _Standard Input JSON File:_ Upload the file [here](./verification/CreateX.json),\n- _Constructor Arguments ABI-Encoded:_ Leave empty.\n\n\u003e [!IMPORTANT]\n\u003e We removed the metadata hash `bytecodeHash` from the bytecode in order to guarantee a deterministic compilation across all operating systems. This implies that all [sourcify.eth](https://sourcify.dev) verifications have partial verification, as opposed to [perfect verification](https://docs.sourcify.dev/blog/verify-contracts-perfectly/), which requires a matching metadata hash.\n\n## [`CreateX`](./src/CreateX.sol) Deployments\n\n📌 The deployment address of [`CreateX`](./src/CreateX.sol) is **`0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed`**.\n\n\u003e [!TIP]\n\u003e The complete list with additional chain information per deployment can be retrieved via [createx.rocks](https://createx.rocks). In addition, all [sourcify.eth](https://sourcify.dev) verification links (for the chains that are [supported](https://docs.sourcify.dev/docs/chains/) by [sourcify.eth](https://sourcify.dev)) can be found in the [`deployments.json`](./deployments/deployments.json) file.\n\n#### EVM-Based Production Networks\n\n- [Ethereum](https://etherscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [BNB Smart Chain](https://bscscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [OP (Optimism)](https://optimistic.etherscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Arbitrum One](https://arbiscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Arbitrum Nova](https://nova.arbiscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Polygon](https://polygonscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Polygon zkEVM](https://zkevm.polygonscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Fantom](https://explorer.fantom.network/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Avalanche](https://snowscan.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Gnosis Chain](https://gnosisscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Moonriver](https://moonriver.moonscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Moonbeam](https://moonbeam.moonscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Celo](https://celoscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Aurora](https://explorer.mainnet.aurora.dev/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Harmony](https://explorer.harmony.one/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Fuse Network](https://explorer.fuse.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Cronos](https://cronoscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Evmos](https://www.mintscan.io/evmos/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Boba Network](https://bobascan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Canto](https://tuber.build/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Base](https://basescan.org/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Mantle](https://mantlescan.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Filecoin](https://filfox.info/en/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Scroll](https://scrollscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Linea](https://lineascan.build/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Zora](https://explorer.zora.energy/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [LUKSO](https://explorer.execution.mainnet.lukso.network/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Manta Pacific](https://pacific-explorer.manta.network/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Blast](https://blastscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [DOS Chain](https://doscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Fraxtal](https://fraxscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Endurance](https://explorer-endurance.fusionist.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Kava](https://kavascan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Metis Andromeda](https://andromeda-explorer.metis.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Mode](https://explorer.mode.network/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Sei](https://seitrace.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed?chain=pacific-1)\n- [X Layer](https://www.oklink.com/x-layer/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [BOB](https://explorer.gobob.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Core](https://scan.coredao.org/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Telos](https://www.teloscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Rootstock](https://rootstock.blockscout.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Chiliz](https://chiliscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Taraxa](https://mainnet.explorer.taraxa.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Gravity Alpha](https://explorer.gravity.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Taiko](https://taikoscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [ZetaChain](https://explorer.zetachain.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [5ireChain](https://5irescan.io/contract/evm/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Oasis Sapphire](https://explorer.oasis.io/mainnet/sapphire/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [World Chain](https://worldscan.org/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Plume](https://explorer.plume.org/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Unichain](https://uniscan.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [XDC Network](https://xdcscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [SX Network](https://explorerl2.sx.technology/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Lisk](https://blockscout.lisk.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Metal L2](https://explorer.metall2.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Superseed](https://explorer.superseed.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Sonic](https://sonicscan.org/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [EVM on Flow](https://evm.flowscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Ink](https://explorer.inkonchain.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Morph](https://explorer.morphl2.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Shape](https://shapescan.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Etherlink](https://explorer.etherlink.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Soneium](https://soneium.blockscout.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Swellchain](https://explorer.swellnetwork.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Hemi](https://explorer.hemi.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Berachain](https://berascan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Corn Maizenet](https://cornscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Arena-Z](https://explorer.arena-z.gg/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [IoTeX](https://iotexscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [HYCHAIN](https://explorer.hychain.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Zircuit](https://explorer.zircuit.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Bitlayer](https://www.btrscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Ronin](https://app.roninchain.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [ZKsync Era](https://era.zksync.network/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Immutable zkEVM](https://explorer.immutable.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Abstract](https://abscan.org/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [HyperEVM](https://purrsec.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n\n#### Ethereum Test Networks\n\n- [Sepolia](https://sepolia.etherscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Holešky (Holešovice)](https://holesky.etherscan.io/address/0xba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed)\n- [Hoodi](https://hoodi.etherscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n\n#### Additional EVM-Based Test Networks\n\n- [BNB Smart Chain Testnet](https://testnet.bscscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [OP (Optimism) Sepolia Testnet](https://sepolia-optimism.etherscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Arbitrum Sepolia Testnet](https://sepolia.arbiscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Polygon Sepolia Testnet (Amoy)](https://amoy.polygonscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Polygon Testnet (zkEVM)](https://cardona-zkevm.polygonscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Fantom Testnet](https://explorer.testnet.fantom.network/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Avalanche Testnet (Fuji)](https://testnet.snowscan.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Gnosis Chain Testnet (Chiado)](https://gnosis-chiado.blockscout.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Moonbeam Testnet (Moonbase Alpha)](https://moonbase.moonscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Celo Testnet (Alfajores)](https://alfajores.celoscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Aurora Testnet](https://explorer.testnet.aurora.dev/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Harmony Testnet](https://explorer.testnet.harmony.one/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Fuse Network Testnet (Spark)](https://explorer.fusespark.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Cronos Testnet](https://cronos.org/explorer/testnet3/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Evmos Testnet](https://www.mintscan.io/evmos-testnet/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Boba Network Testnet](https://testnet.bobascan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Canto Testnet](https://testnet.tuber.build/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Base Sepolia Testnet](https://sepolia.basescan.org/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Mantle Sepolia Testnet](https://sepolia.mantlescan.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Filecoin Testnet (Calibration)](https://calibration.filfox.info/en/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Scroll Sepolia Testnet](https://sepolia.scrollscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Linea Sepolia Testnet](https://sepolia.lineascan.build/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Zora Sepolia Testnet](https://sepolia.explorer.zora.energy/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [LUKSO Testnet](https://explorer.execution.testnet.lukso.network/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Manta Pacific Sepolia Testnet](https://pacific-explorer.sepolia-testnet.manta.network/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Blast Sepolia Testnet](https://sepolia.blastscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [DOS Chain Testnet](https://test.doscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Fraxtal Holešky Testnet](https://holesky.fraxscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Metis Sepolia Testnet](https://sepolia-explorer.metisdevops.link/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Mode Sepolia Testnet](https://sepolia.explorer.mode.network/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Sei Arctic Devnet](https://seitrace.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed?chain=arctic-1)\n- [Sei Atlantic Testnet](https://seitrace.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed?chain=atlantic-2)\n- [X Layer Sepolia Testnet](https://www.oklink.com/x-layer-testnet/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [BOB Sepolia Testnet](https://testnet-explorer.gobob.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Core Testnet](https://scan.test.btcs.network/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Telos Testnet](https://testnet.teloscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Rootstock Testnet](https://rootstock-testnet.blockscout.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Chiliz Testnet (Spicy)](https://testnet.chiliscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Taraxa Testnet](https://testnet.explorer.taraxa.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Taiko Holešky Testnet](https://hekla.taikoscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [ZetaChain Testnet (Athens-3)](https://athens.explorer.zetachain.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [5ireChain Testnet](https://testnet.5irescan.io/contract/evm/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Oasis Sapphire Testnet](https://explorer.oasis.io/testnet/sapphire/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [World Chain Sepolia Testnet](https://sepolia.worldscan.org/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Plume Sepolia Testnet](https://testnet-explorer.plume.org/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Unichain Sepolia Testnet](https://sepolia.uniscan.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [XDC Network Testnet (Apothem)](https://testnet.xdcscan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [SX Network Sepolia Testnet (Toronto)](https://explorerl2.toronto.sx.technology/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Lisk Sepolia Testnet](https://sepolia-blockscout.lisk.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Metal L2 Sepolia Testnet](https://testnet.explorer.metall2.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Superseed Sepolia Testnet](https://sepolia-explorer.superseed.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Story Testnet (Aeneid)](https://aeneid.storyscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Sonic Testnet (Blaze)](https://testnet.sonicscan.org/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [EVM on Flow Testnet](https://evm-testnet.flowscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Ink Sepolia Testnet](https://explorer-sepolia.inkonchain.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Morph Holešky Testnet](https://explorer-holesky.morphl2.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Shape Sepolia Testnet](https://sepolia.shapescan.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Etherlink Testnet (Ghostnet)](https://testnet.explorer.etherlink.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Soneium Sepolia Testnet (Minato)](https://soneium-minato.blockscout.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Swellchain Sepolia Testnet](https://swell-testnet-explorer.alt.technology/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Hemi Sepolia Testnet](https://testnet.explorer.hemi.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Berachain Testnet (Bepolia)](https://testnet.berascan.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Monad Testnet](https://testnet.monadexplorer.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Corn Sepolia Testnet](https://testnet.cornscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Arena-Z Sepolia Testnet](https://arena-z.blockscout.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [IoTeX Testnet](https://testnet.iotexscan.io/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [HYCHAIN Testnet](https://testnet.explorer.hychain.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Zircuit Sepolia Testnet (Garfield)](https://explorer.garfield-testnet.zircuit.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [MegaETH Testnet](https://www.megaexplorer.xyz/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Bitlayer Testnet](https://testnet-scan.bitlayer.org/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Ronin Testnet (Saigon)](https://saigon-app.roninchain.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [ZKsync Era Sepolia Testnet](https://sepolia-era.zksync.network/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Immutable zkEVM Sepolia Testnet](https://explorer.testnet.immutable.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [Abstract Sepolia Testnet](https://sepolia.abscan.org/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n- [HyperEVM Testnet](https://testnet.purrsec.com/address/0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed)\n\n## Integration With External Tooling\n\nA list of external tooling that integrates with [`CreateX`](./src/CreateX.sol):\n\n- [`xdeployer`](https://github.com/pcaversaccio/xdeployer)\n- [`createx-forge`](https://github.com/radeksvarz/createx-forge)\n- [`createXcrunch`](https://github.com/HrikB/createXcrunch)\n- [`hardhat-ignition`](https://github.com/NomicFoundation/hardhat-ignition)\n\n## Community-Maintained Dune Dashboards\n\n- [`CreateX` Factory](https://dune.com/patronumlabs/createx)\n\n## 🙏🏼 Acknowledgement\n\nAll the work has been done jointly by myself and [Matt Solomon](https://github.com/mds1) as a public good for our ecosystem. Public good software is not just code; it's the embodiment of collective progress, a testament to collaboration's power, and a canvas where innovation meets the needs of the many. I hope we can live up to these principles! 🫡\n","funding_links":[],"categories":["By Language","Solidity"],"sub_categories":["Solidity"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpcaversaccio%2Fcreatex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpcaversaccio%2Fcreatex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpcaversaccio%2Fcreatex/lists"}