├── .editorconfig ├── .github ├── dependabot.yml └── workflows │ ├── checks.yml │ ├── codeql.yml │ └── test-contracts.yml ├── .gitignore ├── .prettierignore ├── .prettierrc.yml ├── .solcover.js ├── .solhint.json ├── .solhintignore ├── LICENSE ├── README.md ├── abis └── contracts │ └── Create.sol │ └── Create.json ├── contracts ├── Create.sol └── mocks │ └── ERC20Mock.sol ├── eslint.config.js ├── hardhat.config.ts ├── package.json ├── pnpm-lock.yaml ├── renovate.json ├── scripts └── deploy.ts ├── slither.config.json ├── test └── Create.test.ts └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = false 10 | 11 | [*.sol] 12 | indent_size = 4 13 | max_line_length = 120 14 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | day: "monday" 8 | target-branch: "main" 9 | labels: 10 | - "dependencies" 11 | assignees: 12 | - "pcaversaccio" 13 | -------------------------------------------------------------------------------- /.github/workflows/checks.yml: -------------------------------------------------------------------------------- 1 | name: 👮‍♂️ Sanity checks 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | concurrency: 6 | group: ${{ github.workflow }}-${{ github.ref }} 7 | cancel-in-progress: true 8 | 9 | jobs: 10 | prettify-n-lint: 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | matrix: 14 | os: 15 | - ubuntu-latest 16 | node_version: 17 | - 22 18 | 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v4 22 | 23 | - name: Install pnpm 24 | uses: pnpm/action-setup@v4 25 | with: 26 | run_install: false 27 | 28 | - name: Get pnpm cache directory path 29 | id: pnpm-cache-dir-path 30 | run: echo "dir=$(pnpm store path --silent)" >> $GITHUB_OUTPUT 31 | 32 | - name: Restore pnpm cache 33 | uses: actions/cache@v4 34 | id: pnpm-cache 35 | with: 36 | path: ${{ steps.pnpm-cache-dir-path.outputs.dir }} 37 | key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} 38 | restore-keys: | 39 | ${{ runner.os }}-pnpm-store- 40 | 41 | - name: Use Node.js ${{ matrix.node_version }} 42 | uses: actions/setup-node@v4 43 | with: 44 | node-version: ${{ matrix.node_version }} 45 | 46 | - name: Install pnpm project with a clean slate 47 | run: pnpm install --prefer-offline --frozen-lockfile 48 | 49 | - name: Prettier and lint 50 | run: pnpm lint:check 51 | 52 | codespell: 53 | runs-on: ${{ matrix.os }} 54 | strategy: 55 | matrix: 56 | os: 57 | - ubuntu-latest 58 | 59 | steps: 60 | - name: Checkout 61 | uses: actions/checkout@v4 62 | 63 | - name: Run codespell 64 | uses: codespell-project/actions-codespell@v2 65 | with: 66 | check_filenames: true 67 | skip: ./.git,pnpm-lock.yaml 68 | ignore_words_list: superseed 69 | 70 | validate-links: 71 | runs-on: ${{ matrix.os }} 72 | strategy: 73 | matrix: 74 | os: 75 | - ubuntu-latest 76 | ruby_version: 77 | - 3.4 78 | 79 | steps: 80 | - name: Checkout 81 | uses: actions/checkout@v4 82 | 83 | - name: Set up Ruby 84 | uses: ruby/setup-ruby@v1 85 | with: 86 | ruby-version: ${{ matrix.ruby_version }} 87 | bundler-cache: true 88 | 89 | - name: Install awesome_bot 90 | run: gem install awesome_bot 91 | 92 | - name: Validate URLs 93 | run: awesome_bot ./*.md contracts/*.sol contracts/**/*.sol --request-delay 0.4 94 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: 🔍️ CodeQL 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | concurrency: 6 | group: ${{ github.workflow }}-${{ github.ref }} 7 | cancel-in-progress: true 8 | 9 | jobs: 10 | analyse: 11 | runs-on: ${{ matrix.os }} 12 | permissions: 13 | security-events: write 14 | strategy: 15 | matrix: 16 | os: 17 | - ubuntu-latest 18 | language: 19 | - javascript-typescript 20 | 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@v4 24 | 25 | - name: Initialise CodeQL 26 | uses: github/codeql-action/init@v3 27 | with: 28 | languages: ${{ matrix.language }} 29 | queries: +security-and-quality 30 | 31 | - name: Autobuild 32 | uses: github/codeql-action/autobuild@v3 33 | 34 | - name: Perform CodeQL analysis 35 | uses: github/codeql-action/analyze@v3 36 | with: 37 | category: "/language:${{ matrix.language }}" 38 | -------------------------------------------------------------------------------- /.github/workflows/test-contracts.yml: -------------------------------------------------------------------------------- 1 | name: 🕵️‍♂️ Test smart contracts 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | concurrency: 6 | group: ${{ github.workflow }}-${{ github.ref }} 7 | cancel-in-progress: true 8 | 9 | jobs: 10 | tests: 11 | runs-on: ${{ matrix.os }} 12 | permissions: 13 | contents: read 14 | security-events: write 15 | strategy: 16 | matrix: 17 | os: 18 | - ubuntu-latest 19 | node_version: 20 | - 22 21 | 22 | steps: 23 | - name: Checkout 24 | uses: actions/checkout@v4 25 | 26 | - name: Install pnpm 27 | uses: pnpm/action-setup@v4 28 | with: 29 | run_install: false 30 | 31 | - name: Get pnpm cache directory path 32 | id: pnpm-cache-dir-path 33 | run: echo "dir=$(pnpm store path --silent)" >> $GITHUB_OUTPUT 34 | 35 | - name: Restore pnpm cache 36 | uses: actions/cache@v4 37 | id: pnpm-cache 38 | with: 39 | path: ${{ steps.pnpm-cache-dir-path.outputs.dir }} 40 | key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} 41 | restore-keys: | 42 | ${{ runner.os }}-pnpm-store- 43 | 44 | - name: Use Node.js ${{ matrix.node_version }} 45 | uses: actions/setup-node@v4 46 | with: 47 | node-version: ${{ matrix.node_version }} 48 | 49 | - name: Install pnpm project with a clean slate 50 | run: pnpm install --prefer-offline --frozen-lockfile 51 | 52 | - name: Hardhat tests 53 | run: pnpm test 54 | 55 | - name: Slither static analyser 56 | uses: crytic/slither-action@v0.4.1 57 | id: slither 58 | with: 59 | node-version: ${{ matrix.node_version }} 60 | fail-on: config 61 | sarif: results.sarif 62 | 63 | - name: Upload SARIF file 64 | uses: github/codeql-action/upload-sarif@v3 65 | with: 66 | sarif_file: ${{ steps.slither.outputs.sarif }} 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all Visual Studio Code settings 2 | .vscode/* 3 | !.vscode/settings.json 4 | !.vscode/tasks.json 5 | !.vscode/launch.json 6 | !.vscode/extensions.json 7 | !.vscode/*.code-snippets 8 | 9 | # Local history for Visual Studio Code 10 | .history 11 | 12 | # Built Visual Studio Code extensions 13 | *.vsix 14 | 15 | # Dependency directory 16 | node_modules 17 | 18 | # dotenv environment variable files 19 | .env 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | .env.local 24 | 25 | # Hardhat configuration file 26 | vars.json 27 | 28 | # Log files 29 | logs 30 | *.log 31 | npm-debug.log* 32 | yarn-debug.log* 33 | yarn-error.log* 34 | .pnpm-debug.log* 35 | 36 | # Yarn integrity file 37 | .yarn-integrity 38 | 39 | # Optional npm cache directory 40 | .npm 41 | 42 | # Modern Yarn files 43 | .pnp.* 44 | .yarn/* 45 | !.yarn/cache 46 | !.yarn/patches 47 | !.yarn/plugins 48 | !.yarn/releases 49 | !.yarn/sdks 50 | !.yarn/versions 51 | 52 | # Hardhat files 53 | cache 54 | artifacts 55 | .deps 56 | 57 | # TypeScript bindings output directory 58 | typechain-types 59 | 60 | # solidity-coverage directory and output file 61 | coverage 62 | coverage.json 63 | 64 | # xdeployer output directory 65 | deployments 66 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | pnpm-lock.yaml 3 | cache 4 | artifacts 5 | typechain-types 6 | coverage 7 | deployments 8 | -------------------------------------------------------------------------------- /.prettierrc.yml: -------------------------------------------------------------------------------- 1 | plugins: 2 | - "prettier-plugin-solidity" 3 | -------------------------------------------------------------------------------- /.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | skipFiles: ["mocks/"], 3 | }; 4 | -------------------------------------------------------------------------------- /.solhint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "solhint:recommended", 3 | "rules": { 4 | "compiler-version": "off", 5 | "func-visibility": ["warn", { "ignoreConstructors": true }], 6 | "no-inline-assembly": "off", 7 | "no-empty-blocks": "off" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.solhintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | pnpm-lock.yaml 3 | cache 4 | artifacts 5 | typechain-types 6 | coverage 7 | deployments 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2025 Pascal Marco Caversaccio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # `CREATE` Factory 2 | 3 | [![🕵️‍♂️ Test smart contracts](https://github.com/pcaversaccio/create-util/actions/workflows/test-contracts.yml/badge.svg)](https://github.com/pcaversaccio/create-util/actions/workflows/test-contracts.yml) 4 | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/license/mit) 5 | 6 | Helper smart contract [`Create`](./contracts/Create.sol) to make easier and safer usage of the [`CREATE`](https://www.evm.codes/#f0) Ethereum Virtual Machine (EVM) opcode. `CREATE`, in a way, does a built-in call. What actually happens is that the data passed to that call isn't the contract bytecode, it's the **init bytecode** (a.k.a. creation bytecode). 7 | 8 | When the `CREATE` opcode is executed, the EVM creates a call frame in the context of the new contract (e.g. `address(this)` is the new contract's address). This executes the data passed to `CREATE` as the code, which in higher level languages is basically the constructor. At the end of this init stuff, it returns the actual code of the contract that is stored in the state trie. 9 | 10 | The easiest way to think about it, which is also fairly accurate, is that the Solidity compiler takes all the executional code of the contract, compiles it to bytecode, and adds it as a return statement at the end of the constructor. 11 | 12 | The smart contract [`Create`](./contracts/Create.sol) also provides a function `computeAddress` that returns (via the Recursive Length Prefix (RLP) encoding scheme) the address where a contract will be stored if deployed via `CREATE`. 13 | 14 | ## Test Deployments 15 | 16 | - Sepolia: [`0x910F5D1Ec00F5E7226A14eAAeD8C3b5B03E11950`](https://sepolia.etherscan.io/address/0x910F5D1Ec00F5E7226A14eAAeD8C3b5B03E11950) 17 | - Holešky (Holešovice): [`0x910F5D1Ec00F5E7226A14eAAeD8C3b5B03E11950`](https://holesky.etherscan.io/address/0x910F5D1Ec00F5E7226A14eAAeD8C3b5B03E11950) 18 | 19 | ## `CREATE2` Factory 20 | 21 | A helper smart contract to make easier and safer usage of the [`CREATE2`](https://eips.ethereum.org/EIPS/eip-1014) EVM opcode can be found [here](https://github.com/pcaversaccio/create2deployer) (a.k.a. [`Create2Deployer`](https://github.com/pcaversaccio/create2deployer/blob/main/contracts/Create2Deployer.sol)) and [here](https://github.com/pcaversaccio/createx) (a.k.a. [`CreateX`](https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol); a versatile, trustless, and stateless successor to `Create2Deployer`). 22 | -------------------------------------------------------------------------------- /abis/contracts/Create.sol/Create.json: -------------------------------------------------------------------------------- 1 | [ 2 | "error Failed(address)", 3 | "error InsufficientBalance(address)", 4 | "error InvalidNonceValue(address)", 5 | "error ZeroBytecodeLength(address)", 6 | "event ContractCreation(address)", 7 | "function computeAddress(address,uint256) view returns (address)", 8 | "function deploy(uint256,bytes) returns (address)" 9 | ] 10 | -------------------------------------------------------------------------------- /contracts/Create.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.4; 3 | 4 | /** 5 | * @dev Error that occurs when the contract creation failed. 6 | * @param emitter The contract that emits the error. 7 | */ 8 | error Failed(address emitter); 9 | 10 | /** 11 | * @dev Error that occurs when the factory contract has insufficient balance. 12 | * @param emitter The contract that emits the error. 13 | */ 14 | error InsufficientBalance(address emitter); 15 | 16 | /** 17 | * @dev Error that occurs when the bytecode length is zero. 18 | * @param emitter The contract that emits the error. 19 | */ 20 | error ZeroBytecodeLength(address emitter); 21 | 22 | /** 23 | * @dev Error that occurs when the nonce value is invalid. 24 | * @param emitter The contract that emits the error. 25 | */ 26 | error InvalidNonceValue(address emitter); 27 | 28 | /** 29 | * @title CREATE Deployer Smart Contract 30 | * @author Pascal Marco Caversaccio, pascal.caversaccio@hotmail.ch 31 | * @notice Helper smart contract to make easier and safer usage of the `CREATE` EVM opcode. 32 | * @dev Adjusted from here: https://github.com/safe-global/safe-smart-account/blob/main/contracts/libraries/CreateCall.sol. 33 | */ 34 | 35 | contract Create { 36 | /** 37 | * @dev Event that is emitted when a contract is successfully created. 38 | * @param newContract The address of the new contract. 39 | */ 40 | event ContractCreation(address newContract); 41 | 42 | /** 43 | * @dev The function `deploy` deploys a new contract via calling 44 | * the `CREATE` opcode and using the creation bytecode as input. 45 | * @param amount The value in wei to send to the new account. If `amount` is non-zero, 46 | * `bytecode` must have a `payable` constructor. 47 | * @param bytecode The creation bytecode. 48 | */ 49 | function deploy(uint256 amount, bytes memory bytecode) public returns (address newContract) { 50 | if (address(this).balance < amount) revert InsufficientBalance(address(this)); 51 | if (bytecode.length == 0) revert ZeroBytecodeLength(address(this)); 52 | /// @solidity memory-safe-assembly 53 | assembly { 54 | /** @dev `CREATE` opcode 55 | * 56 | * Stack input 57 | * ------------ 58 | * value: value in wei to send to the new account. 59 | * offset: byte offset in the memory in bytes, the instructions of the new account. 60 | * size: byte size to copy (size of the instructions). 61 | * 62 | * Stack output 63 | * ------------ 64 | * address: the address of the deployed contract. 65 | * 66 | * How are bytes stored in Solidity: 67 | * In memory the `bytes` is stored by having first the length of the `bytes` and then the data, 68 | * this results in the following schema: `<32-bytes length>` at the location where bytecode points to. 69 | * 70 | * Now if we want to use the data with `CREATE`, we first point to the start of the raw data, which is after the length. 71 | * Therefore, we add 32 (the space required for the length) to the location stored in the bytecode variable. 72 | * This is the first parameter. For the second parameter, we read the length from memory using `mload`. 73 | * As the length is the first 32 bytes at the location of `bytecode`, we can read the length by calling `mload(bytecode)`. 74 | */ 75 | newContract := create(amount, add(bytecode, 0x20), mload(bytecode)) 76 | } 77 | if (newContract == address(0)) revert Failed(address(this)); 78 | emit ContractCreation(newContract); 79 | return newContract; 80 | } 81 | 82 | /** 83 | * @dev Returns the address where a contract will be stored if deployed via `deploy`. 84 | * For the specification of the Recursive Length Prefix (RLP) encoding scheme, please 85 | * refer to p. 19 of the Ethereum Yellow Paper (https://ethereum.github.io/yellowpaper/paper.pdf) 86 | * and the Ethereum Wiki (https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/). 87 | * For further insights also, see the following issue: https://github.com/transmissions11/solmate/issues/207. 88 | * 89 | * Based on the EIP-161 (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md) specification, 90 | * all contract accounts on the Ethereum mainnet are initiated with `nonce = 1`. 91 | * Thus, the first contract address created by another contract is calculated with a non-zero nonce. 92 | */ 93 | // prettier-ignore 94 | function computeAddress(address addr, uint256 nonce) public view returns (address) { 95 | bytes memory data; 96 | bytes1 len = bytes1(0x94); 97 | 98 | /** 99 | * @dev The theoretical allowed limit, based on EIP-2681, for an account nonce is 2**64-2: 100 | * https://eips.ethereum.org/EIPS/eip-2681. 101 | */ 102 | if (nonce > type(uint64).max - 1) revert InvalidNonceValue(address(this)); 103 | 104 | /** 105 | * @dev The integer zero is treated as an empty byte string and therefore has only one 106 | * length prefix, 0x80, which is calculated via 0x80 + 0. 107 | */ 108 | if (nonce == 0x00) data = abi.encodePacked(bytes1(0xd6), len, addr, bytes1(0x80)); 109 | 110 | /** 111 | * @dev A one-byte integer in the [0x00, 0x7f] range uses its own value as a length prefix, 112 | * there is no additional "0x80 + length" prefix that precedes it. 113 | */ 114 | else if (nonce <= 0x7f) data = abi.encodePacked(bytes1(0xd6), len, addr, uint8(nonce)); 115 | 116 | /** 117 | * @dev In the case of `nonce > 0x7f` and `nonce <= type(uint8).max`, we have the following 118 | * encoding scheme (the same calculation can be carried over for higher nonce bytes): 119 | * 0xda = 0xc0 (short RLP prefix) + 0x1a (= the bytes length of: 0x94 + address + 0x84 + nonce, in hex), 120 | * 0x94 = 0x80 + 0x14 (= the bytes length of an address, 20 bytes, in hex), 121 | * 0x84 = 0x80 + 0x04 (= the bytes length of the nonce, 4 bytes, in hex). 122 | */ 123 | else if (nonce <= type(uint8).max) data = abi.encodePacked(bytes1(0xd7), len, addr, bytes1(0x81), uint8(nonce)); 124 | else if (nonce <= type(uint16).max) data = abi.encodePacked(bytes1(0xd8), len, addr, bytes1(0x82), uint16(nonce)); 125 | else if (nonce <= type(uint24).max) data = abi.encodePacked(bytes1(0xd9), len, addr, bytes1(0x83), uint24(nonce)); 126 | else if (nonce <= type(uint32).max) data = abi.encodePacked(bytes1(0xda), len, addr, bytes1(0x84), uint32(nonce)); 127 | else if (nonce <= type(uint40).max) data = abi.encodePacked(bytes1(0xdb), len, addr, bytes1(0x85), uint40(nonce)); 128 | else if (nonce <= type(uint48).max) data = abi.encodePacked(bytes1(0xdc), len, addr, bytes1(0x86), uint48(nonce)); 129 | else if (nonce <= type(uint56).max) data = abi.encodePacked(bytes1(0xdd), len, addr, bytes1(0x87), uint56(nonce)); 130 | else data = abi.encodePacked(bytes1(0xde), len, addr, bytes1(0x88), uint64(nonce)); 131 | 132 | return address(uint160(uint256(keccak256(data)))); 133 | } 134 | 135 | /** 136 | * @dev Receive function to enable deployments of `bytecode` with a `payable` constructor. 137 | */ 138 | receive() external payable {} 139 | } 140 | -------------------------------------------------------------------------------- /contracts/mocks/ERC20Mock.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity ^0.8.4; 3 | 4 | import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract ERC20Mock is ERC20 { 7 | constructor( 8 | string memory name_, 9 | string memory symbol_, 10 | address initialAccount_, 11 | uint256 initialBalance_ 12 | ) payable ERC20(name_, symbol_) { 13 | _mint(initialAccount_, initialBalance_); 14 | } 15 | 16 | function mint(address account, uint256 amount) public { 17 | _mint(account, amount); 18 | } 19 | 20 | function burn(address account, uint256 amount) public { 21 | _burn(account, amount); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-require-imports */ 2 | const eslint = require("@eslint/js"); 3 | const tseslint = require("typescript-eslint"); 4 | const eslintConfigPrettier = require("eslint-config-prettier"); 5 | /* eslint-enable @typescript-eslint/no-require-imports */ 6 | 7 | module.exports = tseslint.config( 8 | { 9 | files: ["**/*.{js,ts}"], 10 | extends: [ 11 | eslint.configs.recommended, 12 | ...tseslint.configs.recommended, 13 | ...tseslint.configs.stylistic, 14 | eslintConfigPrettier, 15 | ], 16 | plugins: { 17 | "@typescript-eslint": tseslint.plugin, 18 | }, 19 | languageOptions: { 20 | ecmaVersion: "latest", 21 | parser: tseslint.parser, 22 | parserOptions: { 23 | project: true, 24 | }, 25 | }, 26 | }, 27 | { 28 | ignores: [ 29 | "node_modules/**", 30 | "pnpm-lock.yaml", 31 | "cache/**", 32 | "artifacts/**", 33 | "typechain-types/**", 34 | "coverage/**", 35 | "deployments/**", 36 | ], 37 | }, 38 | ); 39 | -------------------------------------------------------------------------------- /hardhat.config.ts: -------------------------------------------------------------------------------- 1 | import { HardhatUserConfig, task, vars } from "hardhat/config"; 2 | 3 | import "@nomicfoundation/hardhat-ethers"; 4 | import "@nomicfoundation/hardhat-chai-matchers"; 5 | import "@nomicfoundation/hardhat-verify"; 6 | import "@nomicfoundation/hardhat-ledger"; 7 | import "@typechain/hardhat"; 8 | import "xdeployer"; 9 | import "hardhat-gas-reporter"; 10 | import "solidity-coverage"; 11 | import "hardhat-contract-sizer"; 12 | import "hardhat-abi-exporter"; 13 | 14 | const ethMainnetUrl = vars.get("ETH_MAINNET_URL", "https://rpc.ankr.com/eth"); 15 | const accounts = [ 16 | vars.get( 17 | "PRIVATE_KEY", 18 | // `keccak256("DEFAULT_VALUE")` 19 | "0x0d1706281056b7de64efd2088195fa8224c39103f578c9b84f951721df3fa71c", 20 | ), 21 | ]; 22 | const ledgerAccounts = [ 23 | vars.get( 24 | "LEDGER_ACCOUNT", 25 | // `bytes20(uint160(uint256(keccak256("DEFAULT_VALUE"))))` 26 | "0x8195fa8224c39103f578c9b84f951721df3fa71c", 27 | ), 28 | ]; 29 | 30 | task("accounts", "Prints the list of accounts", async (_, hre) => { 31 | const accounts = await hre.ethers.getSigners(); 32 | 33 | for (const account of accounts) { 34 | console.log(account.address); 35 | } 36 | }); 37 | 38 | task("evm", "Prints the configured EVM version", async (_, hre) => { 39 | console.log(hre.config.solidity.compilers[0].settings.evmVersion); 40 | }); 41 | 42 | task( 43 | "balances", 44 | "Prints the list of accounts and their balances", 45 | async (_, hre) => { 46 | const accounts = await hre.ethers.getSigners(); 47 | 48 | for (const account of accounts) { 49 | console.log( 50 | account.address + 51 | " " + 52 | (await hre.ethers.provider.getBalance(account.address)), 53 | ); 54 | } 55 | }, 56 | ); 57 | 58 | const config: HardhatUserConfig = { 59 | solidity: { 60 | // Only use Solidity default versions `>=0.8.25` for EVM networks that support the new `cancun` opcodes: 61 | // https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md 62 | // Only use Solidity default versions `>=0.8.20` for EVM networks that support the opcode `PUSH0` 63 | // Otherwise, use the versions `<=0.8.19` 64 | version: "0.8.30", 65 | settings: { 66 | optimizer: { 67 | enabled: true, 68 | runs: 999_999, 69 | }, 70 | evmVersion: "paris", // Prevent using the `PUSH0` and `cancun` opcodes 71 | }, 72 | }, 73 | networks: { 74 | hardhat: { 75 | initialBaseFeePerGas: 0, 76 | chainId: 31337, 77 | hardfork: "cancun", 78 | forking: { 79 | url: vars.get("ETH_MAINNET_URL", ethMainnetUrl), 80 | // The Hardhat network will by default fork from the latest mainnet block 81 | // To pin the block number, specify it below 82 | // You will need access to a node with archival data for this to work! 83 | // blockNumber: 14743877, 84 | // If you want to do some forking, set `enabled` to true 85 | enabled: false, 86 | }, 87 | ledgerAccounts, 88 | }, 89 | localhost: { 90 | url: "http://127.0.0.1:8545", 91 | ledgerAccounts, 92 | }, 93 | tenderly: { 94 | // Add your own Tenderly fork ID 95 | url: `https://rpc.tenderly.co/fork/${vars.get("TENDERLY_FORK_ID", "")}`, 96 | ledgerAccounts, 97 | }, 98 | devnet: { 99 | // Add your own Tenderly DevNet ID 100 | url: `https://rpc.vnet.tenderly.co/devnet/${vars.get( 101 | "TENDERLY_DEVNET_ID", 102 | "", 103 | )}`, 104 | accounts, 105 | ledgerAccounts, 106 | }, 107 | goerli: { 108 | chainId: 5, 109 | url: vars.get( 110 | "ETH_GOERLI_TESTNET_URL", 111 | "https://rpc.ankr.com/eth_goerli", 112 | ), 113 | accounts, 114 | ledgerAccounts, 115 | }, 116 | sepolia: { 117 | chainId: 11155111, 118 | url: vars.get("ETH_SEPOLIA_TESTNET_URL", "https://rpc.sepolia.org"), 119 | accounts, 120 | ledgerAccounts, 121 | }, 122 | holesky: { 123 | chainId: 17000, 124 | url: vars.get( 125 | "ETH_HOLESKY_TESTNET_URL", 126 | "https://holesky.rpc.thirdweb.com", 127 | ), 128 | accounts, 129 | ledgerAccounts, 130 | }, 131 | hoodi: { 132 | chainId: 560048, 133 | url: vars.get( 134 | "ETH_HOODI_TESTNET_URL", 135 | "https://rpc.hoodi.ethpandaops.io", 136 | ), 137 | accounts, 138 | ledgerAccounts, 139 | }, 140 | ethMain: { 141 | chainId: 1, 142 | url: ethMainnetUrl, 143 | accounts, 144 | ledgerAccounts, 145 | }, 146 | bscTestnet: { 147 | chainId: 97, 148 | url: vars.get( 149 | "BSC_TESTNET_URL", 150 | "https://data-seed-prebsc-1-s1.binance.org:8545", 151 | ), 152 | accounts, 153 | ledgerAccounts, 154 | }, 155 | bscMain: { 156 | chainId: 56, 157 | url: vars.get("BSC_MAINNET_URL", "https://bsc-dataseed1.binance.org"), 158 | accounts, 159 | ledgerAccounts, 160 | }, 161 | optimismTestnet: { 162 | chainId: 420, 163 | url: vars.get("OPTIMISM_TESTNET_URL", "https://goerli.optimism.io"), 164 | accounts, 165 | ledgerAccounts, 166 | }, 167 | optimismSepolia: { 168 | chainId: 11155420, 169 | url: vars.get("OPTIMISM_SEPOLIA_URL", "https://sepolia.optimism.io"), 170 | accounts, 171 | ledgerAccounts, 172 | }, 173 | optimismMain: { 174 | chainId: 10, 175 | url: vars.get("OPTIMISM_MAINNET_URL", "https://mainnet.optimism.io"), 176 | accounts, 177 | ledgerAccounts, 178 | }, 179 | arbitrumSepolia: { 180 | chainId: 421614, 181 | url: vars.get( 182 | "ARBITRUM_SEPOLIA_URL", 183 | "https://sepolia-rollup.arbitrum.io/rpc", 184 | ), 185 | accounts, 186 | ledgerAccounts, 187 | }, 188 | arbitrumMain: { 189 | chainId: 42161, 190 | url: vars.get("ARBITRUM_MAINNET_URL", "https://arb1.arbitrum.io/rpc"), 191 | accounts, 192 | ledgerAccounts, 193 | }, 194 | arbitrumNova: { 195 | chainId: 42170, 196 | url: vars.get("ARBITRUM_NOVA_URL", "https://nova.arbitrum.io/rpc"), 197 | accounts, 198 | ledgerAccounts, 199 | }, 200 | amoy: { 201 | chainId: 80002, 202 | url: vars.get( 203 | "POLYGON_TESTNET_URL", 204 | "https://rpc-amoy.polygon.technology", 205 | ), 206 | accounts, 207 | ledgerAccounts, 208 | }, 209 | polygonZkEVMTestnet: { 210 | chainId: 2442, 211 | url: vars.get( 212 | "POLYGON_ZKEVM_TESTNET_URL", 213 | "https://rpc.cardona.zkevm-rpc.com", 214 | ), 215 | accounts, 216 | ledgerAccounts, 217 | }, 218 | polygon: { 219 | chainId: 137, 220 | url: vars.get("POLYGON_MAINNET_URL", "https://polygon-rpc.com"), 221 | accounts, 222 | ledgerAccounts, 223 | }, 224 | polygonZkEVMMain: { 225 | chainId: 1101, 226 | url: vars.get("POLYGON_ZKEVM_MAINNET_URL", "https://zkevm-rpc.com"), 227 | accounts, 228 | ledgerAccounts, 229 | }, 230 | hecoMain: { 231 | chainId: 128, 232 | url: vars.get("HECO_MAINNET_URL", "https://http-mainnet.hecochain.com"), 233 | accounts, 234 | ledgerAccounts, 235 | }, 236 | fantomTestnet: { 237 | chainId: 4002, 238 | url: vars.get("FANTOM_TESTNET_URL", "https://rpc.testnet.fantom.network"), 239 | accounts, 240 | ledgerAccounts, 241 | }, 242 | fantomMain: { 243 | chainId: 250, 244 | url: vars.get("FANTOM_MAINNET_URL", "https://rpc.ankr.com/fantom"), 245 | accounts, 246 | ledgerAccounts, 247 | }, 248 | fuji: { 249 | chainId: 43113, 250 | url: vars.get( 251 | "AVALANCHE_TESTNET_URL", 252 | "https://api.avax-test.network/ext/bc/C/rpc", 253 | ), 254 | accounts, 255 | ledgerAccounts, 256 | }, 257 | avalanche: { 258 | chainId: 43114, 259 | url: vars.get( 260 | "AVALANCHE_MAINNET_URL", 261 | "https://api.avax.network/ext/bc/C/rpc", 262 | ), 263 | accounts, 264 | ledgerAccounts, 265 | }, 266 | chiado: { 267 | chainId: 10200, 268 | url: vars.get("GNOSIS_TESTNET_URL", "https://rpc.chiadochain.net"), 269 | accounts, 270 | ledgerAccounts, 271 | }, 272 | gnosis: { 273 | chainId: 100, 274 | url: vars.get("GNOSIS_MAINNET_URL", "https://rpc.gnosischain.com"), 275 | accounts, 276 | ledgerAccounts, 277 | }, 278 | moonbaseAlpha: { 279 | chainId: 1287, 280 | url: vars.get( 281 | "MOONBEAM_TESTNET_URL", 282 | "https://rpc.api.moonbase.moonbeam.network", 283 | ), 284 | accounts, 285 | ledgerAccounts, 286 | }, 287 | moonriver: { 288 | chainId: 1285, 289 | url: vars.get( 290 | "MOONRIVER_MAINNET_URL", 291 | "https://moonriver.public.blastapi.io", 292 | ), 293 | accounts, 294 | ledgerAccounts, 295 | }, 296 | moonbeam: { 297 | chainId: 1284, 298 | url: vars.get( 299 | "MOONBEAM_MAINNET_URL", 300 | "https://moonbeam.public.blastapi.io", 301 | ), 302 | accounts, 303 | ledgerAccounts, 304 | }, 305 | alfajores: { 306 | chainId: 44787, 307 | url: vars.get( 308 | "CELO_TESTNET_URL", 309 | "https://alfajores-forno.celo-testnet.org", 310 | ), 311 | accounts, 312 | ledgerAccounts, 313 | }, 314 | celo: { 315 | chainId: 42220, 316 | url: vars.get("CELO_MAINNET_URL", "https://forno.celo.org"), 317 | accounts, 318 | ledgerAccounts, 319 | }, 320 | auroraTestnet: { 321 | chainId: 1313161555, 322 | url: vars.get("AURORA_TESTNET_URL", "https://testnet.aurora.dev"), 323 | accounts, 324 | ledgerAccounts, 325 | }, 326 | auroraMain: { 327 | chainId: 1313161554, 328 | url: vars.get("AURORA_MAINNET_URL", "https://mainnet.aurora.dev"), 329 | accounts, 330 | ledgerAccounts, 331 | }, 332 | harmonyTestnet: { 333 | chainId: 1666700000, 334 | url: vars.get("HARMONY_TESTNET_URL", "https://api.s0.b.hmny.io"), 335 | accounts, 336 | ledgerAccounts, 337 | }, 338 | harmonyMain: { 339 | chainId: 1666600000, 340 | url: vars.get("HARMONY_MAINNET_URL", "https://api.harmony.one"), 341 | accounts, 342 | ledgerAccounts, 343 | }, 344 | spark: { 345 | chainId: 123, 346 | url: vars.get("FUSE_TESTNET_URL", "https://rpc.fusespark.io"), 347 | accounts, 348 | ledgerAccounts, 349 | }, 350 | fuse: { 351 | chainId: 122, 352 | url: vars.get("FUSE_MAINNET_URL", "https://rpc.fuse.io"), 353 | accounts, 354 | ledgerAccounts, 355 | }, 356 | cronosTestnet: { 357 | chainId: 338, 358 | url: vars.get("CRONOS_TESTNET_URL", "https://evm-t3.cronos.org"), 359 | accounts, 360 | ledgerAccounts, 361 | }, 362 | cronosMain: { 363 | chainId: 25, 364 | url: vars.get("CRONOS_MAINNET_URL", "https://evm.cronos.org"), 365 | accounts, 366 | ledgerAccounts, 367 | }, 368 | evmosTestnet: { 369 | chainId: 9000, 370 | url: vars.get("EVMOS_TESTNET_URL", "https://evmos-testnet.lava.build"), 371 | accounts, 372 | ledgerAccounts, 373 | }, 374 | evmosMain: { 375 | chainId: 9001, 376 | url: vars.get("EVMOS_MAINNET_URL", "https://evmos.lava.build"), 377 | accounts, 378 | ledgerAccounts, 379 | }, 380 | bobaTestnet: { 381 | chainId: 2888, 382 | url: vars.get("BOBA_TESTNET_URL", "https://goerli.boba.network"), 383 | accounts, 384 | ledgerAccounts, 385 | }, 386 | bobaMain: { 387 | chainId: 288, 388 | url: vars.get("BOBA_MAINNET_URL", "https://replica.boba.network"), 389 | accounts, 390 | ledgerAccounts, 391 | }, 392 | cantoTestnet: { 393 | chainId: 7701, 394 | url: vars.get("CANTO_TESTNET_URL", "https://canto-testnet.plexnode.wtf"), 395 | accounts, 396 | ledgerAccounts, 397 | }, 398 | cantoMain: { 399 | chainId: 7700, 400 | url: vars.get("CANTO_MAINNET_URL", "https://canto.slingshot.finance"), 401 | accounts, 402 | ledgerAccounts, 403 | }, 404 | baseTestnet: { 405 | chainId: 84531, 406 | url: vars.get("BASE_TESTNET_URL", "https://goerli.base.org"), 407 | accounts, 408 | ledgerAccounts, 409 | }, 410 | baseSepolia: { 411 | chainId: 84532, 412 | url: vars.get("BASE_SEPOLIA_URL", "https://sepolia.base.org"), 413 | accounts, 414 | ledgerAccounts, 415 | }, 416 | baseMain: { 417 | chainId: 8453, 418 | url: vars.get("BASE_MAINNET_URL", "https://mainnet.base.org"), 419 | accounts, 420 | ledgerAccounts, 421 | }, 422 | mantleTestnet: { 423 | chainId: 5003, 424 | url: vars.get("MANTLE_TESTNET_URL", "https://rpc.sepolia.mantle.xyz"), 425 | accounts, 426 | ledgerAccounts, 427 | }, 428 | mantleMain: { 429 | chainId: 5000, 430 | url: vars.get("MANTLE_MAINNET_URL", "https://rpc.mantle.xyz"), 431 | accounts, 432 | ledgerAccounts, 433 | }, 434 | filecoinTestnet: { 435 | chainId: 314159, 436 | url: vars.get( 437 | "FILECOIN_TESTNET_URL", 438 | "https://rpc.ankr.com/filecoin_testnet", 439 | ), 440 | accounts, 441 | ledgerAccounts, 442 | }, 443 | filecoinMain: { 444 | chainId: 314, 445 | url: vars.get("FILECOIN_MAINNET_URL", "https://rpc.ankr.com/filecoin"), 446 | accounts, 447 | ledgerAccounts, 448 | }, 449 | scrollTestnet: { 450 | chainId: 534351, 451 | url: vars.get("SCROLL_TESTNET_URL", "https://sepolia-rpc.scroll.io"), 452 | accounts, 453 | ledgerAccounts, 454 | }, 455 | scrollMain: { 456 | chainId: 534352, 457 | url: vars.get("SCROLL_MAINNET_URL", "https://rpc.scroll.io"), 458 | accounts, 459 | ledgerAccounts, 460 | }, 461 | lineaTestnet: { 462 | chainId: 59141, 463 | url: vars.get("LINEA_TESTNET_URL", "https://rpc.sepolia.linea.build"), 464 | accounts, 465 | ledgerAccounts, 466 | }, 467 | lineaMain: { 468 | chainId: 59144, 469 | url: vars.get("LINEA_MAINNET_URL", "https://rpc.linea.build"), 470 | accounts, 471 | ledgerAccounts, 472 | }, 473 | shimmerEVMTestnet: { 474 | chainId: 1071, 475 | url: vars.get( 476 | "SHIMMEREVM_TESTNET_URL", 477 | "https://json-rpc.evm.testnet.shimmer.network", 478 | ), 479 | accounts, 480 | ledgerAccounts, 481 | }, 482 | zoraTestnet: { 483 | chainId: 999999999, 484 | url: vars.get("ZORA_TESTNET_URL", "https://sepolia.rpc.zora.energy"), 485 | accounts, 486 | ledgerAccounts, 487 | }, 488 | zoraMain: { 489 | chainId: 7777777, 490 | url: vars.get("ZORA_MAINNET_URL", "https://rpc.zora.energy"), 491 | accounts, 492 | ledgerAccounts, 493 | }, 494 | luksoTestnet: { 495 | chainId: 4201, 496 | url: vars.get("LUKSO_TESTNET_URL", "https://rpc.testnet.lukso.network"), 497 | accounts, 498 | ledgerAccounts, 499 | }, 500 | luksoMain: { 501 | chainId: 42, 502 | url: vars.get("LUKSO_MAINNET_URL", "https://rpc.lukso.gateway.fm"), 503 | accounts, 504 | ledgerAccounts, 505 | }, 506 | mantaTestnet: { 507 | chainId: 3441006, 508 | url: vars.get( 509 | "MANTA_TESTNET_URL", 510 | "https://pacific-rpc.sepolia-testnet.manta.network/http", 511 | ), 512 | accounts, 513 | ledgerAccounts, 514 | }, 515 | mantaMain: { 516 | chainId: 169, 517 | url: vars.get( 518 | "MANTA_MAINNET_URL", 519 | "https://pacific-rpc.manta.network/http", 520 | ), 521 | accounts, 522 | ledgerAccounts, 523 | }, 524 | shardeumTestnet: { 525 | chainId: 8081, 526 | url: vars.get("SHARDEUM_TESTNET_URL", "https://dapps.shardeum.org"), 527 | accounts, 528 | ledgerAccounts, 529 | }, 530 | artheraTestnet: { 531 | chainId: 10243, 532 | url: vars.get("ARTHERA_TESTNET_URL", "https://rpc-test.arthera.net"), 533 | accounts, 534 | ledgerAccounts, 535 | }, 536 | frameTestnet: { 537 | chainId: 68840142, 538 | url: vars.get("FRAME_TESTNET_URL", "https://rpc.testnet.frame.xyz/http"), 539 | accounts, 540 | ledgerAccounts, 541 | }, 542 | enduranceTestnet: { 543 | chainId: 6480, 544 | url: vars.get( 545 | "ENDURANCE_TESTNET_URL", 546 | "https://myrpctestnet.fusionist.io", 547 | ), 548 | accounts, 549 | ledgerAccounts, 550 | }, 551 | openduranceTestnet: { 552 | chainId: 6480001001, 553 | url: vars.get( 554 | "OPENDURANCE_TESTNET_URL", 555 | "https://rpc-l2-testnet.fusionist.io", 556 | ), 557 | accounts, 558 | ledgerAccounts, 559 | }, 560 | enduranceMain: { 561 | chainId: 648, 562 | url: vars.get( 563 | "ENDURANCE_MAINNET_URL", 564 | "https://rpc-endurance.fusionist.io", 565 | ), 566 | accounts, 567 | ledgerAccounts, 568 | }, 569 | blastTestnet: { 570 | chainId: 168587773, 571 | url: vars.get("BLAST_TESTNET_URL", "https://sepolia.blast.io"), 572 | accounts, 573 | ledgerAccounts, 574 | }, 575 | blastMain: { 576 | chainId: 81457, 577 | url: vars.get("BLAST_MAINNET_URL", "https://rpc.blast.io"), 578 | accounts, 579 | ledgerAccounts, 580 | }, 581 | kromaTestnet: { 582 | chainId: 2358, 583 | url: vars.get("KROMA_TESTNET_URL", "https://api.sepolia.kroma.network"), 584 | accounts, 585 | ledgerAccounts, 586 | }, 587 | kromaMain: { 588 | chainId: 255, 589 | url: vars.get("KROMA_MAINNET_URL", "https://api.kroma.network"), 590 | accounts, 591 | ledgerAccounts, 592 | }, 593 | dosTestnet: { 594 | chainId: 3939, 595 | url: vars.get("DOS_TESTNET_URL", "https://test.doschain.com"), 596 | accounts, 597 | ledgerAccounts, 598 | }, 599 | dosMain: { 600 | chainId: 7979, 601 | url: vars.get("DOS_MAINNET_URL", "https://main.doschain.com"), 602 | accounts, 603 | ledgerAccounts, 604 | }, 605 | fraxtalTestnet: { 606 | chainId: 2522, 607 | url: vars.get("FRAXTAL_TESTNET_URL", "https://rpc.testnet.frax.com"), 608 | accounts, 609 | ledgerAccounts, 610 | }, 611 | fraxtalMain: { 612 | chainId: 252, 613 | url: vars.get("FRAXTAL_MAINNET_URL", "https://rpc.frax.com"), 614 | accounts, 615 | ledgerAccounts, 616 | }, 617 | kavaMain: { 618 | chainId: 2222, 619 | url: vars.get("KAVA_MAINNET_URL", "https://evm.kava-rpc.com"), 620 | accounts, 621 | ledgerAccounts, 622 | }, 623 | metisTestnet: { 624 | chainId: 59902, 625 | url: vars.get("METIS_TESTNET_URL", "https://sepolia.metisdevops.link"), 626 | accounts, 627 | ledgerAccounts, 628 | }, 629 | metisMain: { 630 | chainId: 1088, 631 | url: vars.get( 632 | "METIS_MAINNET_URL", 633 | "https://andromeda.metis.io/?owner=1088", 634 | ), 635 | accounts, 636 | ledgerAccounts, 637 | }, 638 | modeTestnet: { 639 | chainId: 919, 640 | url: vars.get("MODE_TESTNET_URL", "https://sepolia.mode.network"), 641 | accounts, 642 | ledgerAccounts, 643 | }, 644 | modeMain: { 645 | chainId: 34443, 646 | url: vars.get("MODE_MAINNET_URL", "https://mainnet.mode.network"), 647 | accounts, 648 | ledgerAccounts, 649 | }, 650 | seiDevnet: { 651 | chainId: 713715, 652 | url: vars.get("SEI_DEVNET_URL", "https://evm-rpc-arctic-1.sei-apis.com"), 653 | accounts, 654 | ledgerAccounts, 655 | }, 656 | seiTestnet: { 657 | chainId: 1328, 658 | url: vars.get("SEI_TESTNET_URL", "https://evm-rpc-testnet.sei-apis.com"), 659 | accounts, 660 | ledgerAccounts, 661 | }, 662 | seiMain: { 663 | chainId: 1329, 664 | url: vars.get("SEI_MAINNET_URL", "https://evm-rpc.sei-apis.com"), 665 | accounts, 666 | ledgerAccounts, 667 | }, 668 | xlayerTestnet: { 669 | chainId: 195, 670 | url: vars.get("XLAYER_TESTNET_URL", "https://testrpc.xlayer.tech"), 671 | accounts, 672 | ledgerAccounts, 673 | }, 674 | xlayerMain: { 675 | chainId: 196, 676 | url: vars.get("XLAYER_MAINNET_URL", "https://rpc.xlayer.tech"), 677 | accounts, 678 | ledgerAccounts, 679 | }, 680 | bobTestnet: { 681 | chainId: 111, 682 | url: vars.get("BOB_TESTNET_URL", "https://testnet.rpc.gobob.xyz"), 683 | accounts, 684 | ledgerAccounts, 685 | }, 686 | bobMain: { 687 | chainId: 60808, 688 | url: vars.get("BOB_MAINNET_URL", "https://rpc.gobob.xyz"), 689 | accounts, 690 | ledgerAccounts, 691 | }, 692 | coreTestnet: { 693 | chainId: 1115, 694 | url: vars.get("CORE_TESTNET_URL", "https://rpc.test.btcs.network"), 695 | accounts, 696 | ledgerAccounts, 697 | }, 698 | coreMain: { 699 | chainId: 1116, 700 | url: vars.get("CORE_MAINNET_URL", "https://rpc.coredao.org"), 701 | accounts, 702 | ledgerAccounts, 703 | }, 704 | telosTestnet: { 705 | chainId: 41, 706 | url: vars.get("TELOS_TESTNET_URL", "https://testnet.telos.net/evm"), 707 | accounts, 708 | ledgerAccounts, 709 | }, 710 | telosMain: { 711 | chainId: 40, 712 | url: vars.get("TELOS_MAINNET_URL", "https://mainnet.telos.net/evm"), 713 | accounts, 714 | ledgerAccounts, 715 | }, 716 | rootstockTestnet: { 717 | chainId: 31, 718 | url: vars.get( 719 | "ROOTSTOCK_TESTNET_URL", 720 | "https://public-node.testnet.rsk.co", 721 | ), 722 | accounts, 723 | ledgerAccounts, 724 | }, 725 | rootstockMain: { 726 | chainId: 30, 727 | url: vars.get("ROOTSTOCK_MAINNET_URL", "https://public-node.rsk.co"), 728 | accounts, 729 | ledgerAccounts, 730 | }, 731 | chilizTestnet: { 732 | chainId: 88882, 733 | url: vars.get("CHILIZ_TESTNET_URL", "https://spicy-rpc.chiliz.com"), 734 | accounts, 735 | ledgerAccounts, 736 | }, 737 | chilizMain: { 738 | chainId: 88888, 739 | url: vars.get("CHILIZ_MAINNET_URL", "https://rpc.ankr.com/chiliz"), 740 | accounts, 741 | ledgerAccounts, 742 | }, 743 | taraxaTestnet: { 744 | chainId: 842, 745 | url: vars.get("TARAXA_TESTNET_URL", "https://rpc.testnet.taraxa.io"), 746 | accounts, 747 | ledgerAccounts, 748 | }, 749 | taraxaMain: { 750 | chainId: 841, 751 | url: vars.get("TARAXA_MAINNET_URL", "https://rpc.mainnet.taraxa.io"), 752 | accounts, 753 | ledgerAccounts, 754 | }, 755 | gravityAlphaTestnet: { 756 | chainId: 13505, 757 | url: vars.get( 758 | "GRAVITY_ALPHA_TESTNET_URL", 759 | "https://rpc-sepolia.gravity.xyz", 760 | ), 761 | accounts, 762 | ledgerAccounts, 763 | }, 764 | gravityAlphaMain: { 765 | chainId: 1625, 766 | url: vars.get("GRAVITY_ALPHA_MAINNET_URL", "https://rpc.gravity.xyz"), 767 | accounts, 768 | ledgerAccounts, 769 | }, 770 | taikoTestnet: { 771 | chainId: 167009, 772 | url: vars.get("TAIKO_TESTNET_URL", "https://rpc.hekla.taiko.xyz"), 773 | accounts, 774 | ledgerAccounts, 775 | }, 776 | taikoMain: { 777 | chainId: 167000, 778 | url: vars.get("TAIKO_MAINNET_URL", "https://rpc.taiko.xyz"), 779 | accounts, 780 | ledgerAccounts, 781 | }, 782 | zetaChainTestnet: { 783 | chainId: 7001, 784 | url: vars.get("ZETA_CHAIN_TESTNET_URL", "https://7001.rpc.thirdweb.com"), 785 | accounts, 786 | ledgerAccounts, 787 | }, 788 | zetaChainMain: { 789 | chainId: 7000, 790 | url: vars.get("ZETA_CHAIN_MAINNET_URL", "https://7000.rpc.thirdweb.com"), 791 | accounts, 792 | ledgerAccounts, 793 | }, 794 | "5ireChainTestnet": { 795 | chainId: 997, 796 | url: vars.get( 797 | "5IRE_CHAIN_TESTNET_URL", 798 | "https://rpc.testnet.5ire.network", 799 | ), 800 | accounts, 801 | ledgerAccounts, 802 | }, 803 | "5ireChainMain": { 804 | chainId: 995, 805 | url: vars.get("5IRE_CHAIN_MAINNET_URL", "https://rpc.5ire.network"), 806 | accounts, 807 | ledgerAccounts, 808 | }, 809 | sapphireTestnet: { 810 | chainId: 23295, 811 | url: vars.get( 812 | "SAPPHIRE_TESTNET_URL", 813 | "https://testnet.sapphire.oasis.io", 814 | ), 815 | accounts, 816 | ledgerAccounts, 817 | }, 818 | sapphireMain: { 819 | chainId: 23294, 820 | url: vars.get("SAPPHIRE_MAINNET_URL", "https://sapphire.oasis.io"), 821 | accounts, 822 | ledgerAccounts, 823 | }, 824 | worldChainTestnet: { 825 | chainId: 4801, 826 | url: vars.get( 827 | "WORLD_CHAIN_TESTNET_URL", 828 | "https://worldchain-sepolia.g.alchemy.com/public", 829 | ), 830 | accounts, 831 | ledgerAccounts, 832 | }, 833 | worldChainMain: { 834 | chainId: 480, 835 | url: vars.get( 836 | "WORLD_CHAIN_MAINNET_URL", 837 | "https://worldchain-mainnet.g.alchemy.com/public", 838 | ), 839 | accounts, 840 | ledgerAccounts, 841 | }, 842 | plumeTestnet: { 843 | chainId: 98867, 844 | url: vars.get("PLUME_TESTNET_URL", "https://testnet-rpc.plume.org"), 845 | accounts, 846 | ledgerAccounts, 847 | }, 848 | plumeMain: { 849 | chainId: 98866, 850 | url: vars.get("PLUME_MAINNET_URL", "https://rpc.plume.org"), 851 | accounts, 852 | ledgerAccounts, 853 | }, 854 | unichainTestnet: { 855 | chainId: 1301, 856 | url: vars.get("UNICHAIN_TESTNET_URL", "https://sepolia.unichain.org"), 857 | accounts, 858 | ledgerAccounts, 859 | }, 860 | unichainMain: { 861 | chainId: 130, 862 | url: vars.get("UNICHAIN_MAINNET_URL", "https://mainnet.unichain.org"), 863 | accounts, 864 | ledgerAccounts, 865 | }, 866 | xdcTestnet: { 867 | chainId: 51, 868 | url: vars.get("XDC_TESTNET_URL", "https://erpc.apothem.network"), 869 | accounts, 870 | ledgerAccounts, 871 | }, 872 | xdcMain: { 873 | chainId: 50, 874 | url: vars.get("XDC_MAINNET_URL", "https://rpc.xinfin.network"), 875 | accounts, 876 | ledgerAccounts, 877 | }, 878 | sxTestnet: { 879 | chainId: 79479957, 880 | url: vars.get( 881 | "SX_TESTNET_URL", 882 | "https://rpc.sx-rollup-testnet.t.raas.gelato.cloud", 883 | ), 884 | accounts, 885 | ledgerAccounts, 886 | }, 887 | sxMain: { 888 | chainId: 4162, 889 | url: vars.get("SX_MAINNET_URL", "https://rpc.sx-rollup.gelato.digital"), 890 | accounts, 891 | ledgerAccounts, 892 | }, 893 | liskTestnet: { 894 | chainId: 4202, 895 | url: vars.get("LISK_TESTNET_URL", "https://rpc.sepolia-api.lisk.com"), 896 | accounts, 897 | ledgerAccounts, 898 | }, 899 | liskMain: { 900 | chainId: 1135, 901 | url: vars.get("LISK_MAINNET_URL", "https://rpc.api.lisk.com"), 902 | accounts, 903 | ledgerAccounts, 904 | }, 905 | metalL2Testnet: { 906 | chainId: 1740, 907 | url: vars.get("METALL2_TESTNET_URL", "https://testnet.rpc.metall2.com"), 908 | accounts, 909 | ledgerAccounts, 910 | }, 911 | metalL2Main: { 912 | chainId: 1750, 913 | url: vars.get("METALL2_MAINNET_URL", "https://rpc.metall2.com"), 914 | accounts, 915 | ledgerAccounts, 916 | }, 917 | superseedTestnet: { 918 | chainId: 53302, 919 | url: vars.get("SUPERSEED_TESTNET_URL", "https://sepolia.superseed.xyz"), 920 | accounts, 921 | ledgerAccounts, 922 | }, 923 | superseedMain: { 924 | chainId: 5330, 925 | url: vars.get("SUPERSEED_MAINNET_URL", "https://mainnet.superseed.xyz"), 926 | accounts, 927 | ledgerAccounts, 928 | }, 929 | storyTestnet: { 930 | chainId: 1315, 931 | url: vars.get("STORY_TESTNET_URL", "https://aeneid.storyrpc.io"), 932 | accounts, 933 | ledgerAccounts, 934 | }, 935 | sonicTestnet: { 936 | chainId: 57054, 937 | url: vars.get("SONIC_TESTNET_URL", "https://rpc.blaze.soniclabs.com"), 938 | accounts, 939 | ledgerAccounts, 940 | }, 941 | sonicMain: { 942 | chainId: 146, 943 | url: vars.get("SONIC_MAINNET_URL", "https://rpc.soniclabs.com"), 944 | accounts, 945 | ledgerAccounts, 946 | }, 947 | flowTestnet: { 948 | chainId: 545, 949 | url: vars.get("FLOW_TESTNET_URL", "https://testnet.evm.nodes.onflow.org"), 950 | accounts, 951 | ledgerAccounts, 952 | }, 953 | flowMain: { 954 | chainId: 747, 955 | url: vars.get("FLOW_MAINNET_URL", "https://mainnet.evm.nodes.onflow.org"), 956 | accounts, 957 | ledgerAccounts, 958 | }, 959 | inkTestnet: { 960 | chainId: 763373, 961 | url: vars.get( 962 | "INK_TESTNET_URL", 963 | "https://rpc-gel-sepolia.inkonchain.com", 964 | ), 965 | accounts, 966 | ledgerAccounts, 967 | }, 968 | inkMain: { 969 | chainId: 57073, 970 | url: vars.get("INK_MAINNET_URL", "https://rpc-gel.inkonchain.com"), 971 | accounts, 972 | ledgerAccounts, 973 | }, 974 | morphTestnet: { 975 | chainId: 2810, 976 | url: vars.get( 977 | "MORPH_TESTNET_URL", 978 | "https://rpc-quicknode-holesky.morphl2.io", 979 | ), 980 | accounts, 981 | ledgerAccounts, 982 | }, 983 | morphMain: { 984 | chainId: 2818, 985 | url: vars.get("MORPH_MAINNET_URL", "https://rpc-quicknode.morphl2.io"), 986 | accounts, 987 | ledgerAccounts, 988 | }, 989 | shapeTestnet: { 990 | chainId: 11011, 991 | url: vars.get("SHAPE_TESTNET_URL", "https://sepolia.shape.network"), 992 | accounts, 993 | ledgerAccounts, 994 | }, 995 | shapeMain: { 996 | chainId: 360, 997 | url: vars.get("SHAPE_MAINNET_URL", "https://mainnet.shape.network"), 998 | accounts, 999 | ledgerAccounts, 1000 | }, 1001 | etherlinkTestnet: { 1002 | chainId: 128123, 1003 | url: vars.get( 1004 | "ETHERLINK_TESTNET_URL", 1005 | "https://node.ghostnet.etherlink.com", 1006 | ), 1007 | accounts, 1008 | ledgerAccounts, 1009 | }, 1010 | etherlinkMain: { 1011 | chainId: 42793, 1012 | url: vars.get( 1013 | "ETHERLINK_MAINNET_URL", 1014 | "https://node.mainnet.etherlink.com", 1015 | ), 1016 | accounts, 1017 | ledgerAccounts, 1018 | }, 1019 | soneiumTestnet: { 1020 | chainId: 1946, 1021 | url: vars.get("SONEIUM_TESTNET_URL", "https://rpc.minato.soneium.org"), 1022 | accounts, 1023 | ledgerAccounts, 1024 | }, 1025 | soneiumMain: { 1026 | chainId: 1868, 1027 | url: vars.get("SONEIUM_MAINNET_URL", "https://rpc.soneium.org"), 1028 | accounts, 1029 | ledgerAccounts, 1030 | }, 1031 | swellTestnet: { 1032 | chainId: 1924, 1033 | url: vars.get( 1034 | "SWELL_TESTNET_URL", 1035 | "https://swell-testnet.alt.technology", 1036 | ), 1037 | accounts, 1038 | ledgerAccounts, 1039 | }, 1040 | swellMain: { 1041 | chainId: 1923, 1042 | url: vars.get( 1043 | "SWELL_MAINNET_URL", 1044 | "https://swell-mainnet.alt.technology", 1045 | ), 1046 | accounts, 1047 | ledgerAccounts, 1048 | }, 1049 | hemiTestnet: { 1050 | chainId: 743111, 1051 | url: vars.get("HEMI_TESTNET_URL", "https://testnet.rpc.hemi.network/rpc"), 1052 | accounts, 1053 | ledgerAccounts, 1054 | }, 1055 | hemiMain: { 1056 | chainId: 43111, 1057 | url: vars.get("HEMI_MAINNET_URL", "https://rpc.hemi.network/rpc"), 1058 | accounts, 1059 | ledgerAccounts, 1060 | }, 1061 | berachainTestnet: { 1062 | chainId: 80084, 1063 | url: vars.get("BERACHAIN_TESTNET_URL", "https://bartio.drpc.org"), 1064 | accounts, 1065 | ledgerAccounts, 1066 | }, 1067 | berachainMain: { 1068 | chainId: 80094, 1069 | url: vars.get("BERACHAIN_MAINNET_URL", "https://rpc.berachain.com"), 1070 | accounts, 1071 | ledgerAccounts, 1072 | }, 1073 | monadTestnet: { 1074 | chainId: 10143, 1075 | url: vars.get("MONAD_TESTNET_URL", "https://testnet-rpc.monad.xyz"), 1076 | accounts, 1077 | ledgerAccounts, 1078 | }, 1079 | cornTestnet: { 1080 | chainId: 21000001, 1081 | url: vars.get("CORN_TESTNET_URL", "https://testnet.corn-rpc.com"), 1082 | accounts, 1083 | ledgerAccounts, 1084 | }, 1085 | cornMain: { 1086 | chainId: 21000000, 1087 | url: vars.get("CORN_MAINNET_URL", "https://mainnet.corn-rpc.com"), 1088 | accounts, 1089 | ledgerAccounts, 1090 | }, 1091 | arenazTestnet: { 1092 | chainId: 9897, 1093 | url: vars.get( 1094 | "ARENAZ_TESTNET_URL", 1095 | "https://rpc.arena-z.t.raas.gelato.cloud", 1096 | ), 1097 | accounts, 1098 | ledgerAccounts, 1099 | }, 1100 | arenazMain: { 1101 | chainId: 7897, 1102 | url: vars.get("ARENAZ_MAINNET_URL", "https://rpc.arena-z.gg"), 1103 | accounts, 1104 | ledgerAccounts, 1105 | }, 1106 | iotexTestnet: { 1107 | chainId: 4690, 1108 | url: vars.get("IOTEX_TESTNET_URL", "https://babel-api.testnet.iotex.io"), 1109 | accounts, 1110 | ledgerAccounts, 1111 | }, 1112 | iotexMain: { 1113 | chainId: 4689, 1114 | url: vars.get("IOTEX_MAINNET_URL", "https://babel-api.mainnet.iotex.io"), 1115 | accounts, 1116 | ledgerAccounts, 1117 | }, 1118 | hychainTestnet: { 1119 | chainId: 29112, 1120 | url: vars.get( 1121 | "HYCHAIN_TESTNET_URL", 1122 | "https://testnet-rpc.hychain.com/http", 1123 | ), 1124 | accounts, 1125 | ledgerAccounts, 1126 | }, 1127 | hychainMain: { 1128 | chainId: 2911, 1129 | url: vars.get("HYCHAIN_MAINNET_URL", "https://rpc.hychain.com/http"), 1130 | accounts, 1131 | ledgerAccounts, 1132 | }, 1133 | zircuitTestnet: { 1134 | chainId: 48898, 1135 | url: vars.get( 1136 | "ZIRCUIT_TESTNET_URL", 1137 | "https://garfield-testnet.zircuit.com", 1138 | ), 1139 | accounts, 1140 | ledgerAccounts, 1141 | }, 1142 | zircuitMain: { 1143 | chainId: 48900, 1144 | url: vars.get("ZIRCUIT_MAINNET_URL", "https://zircuit-mainnet.drpc.org"), 1145 | accounts, 1146 | ledgerAccounts, 1147 | }, 1148 | megaETHTestnet: { 1149 | chainId: 6342, 1150 | url: vars.get("MEGAETH_TESTNET_URL", "https://carrot.megaeth.com/rpc"), 1151 | accounts, 1152 | ledgerAccounts, 1153 | }, 1154 | bitlayerTestnet: { 1155 | chainId: 200810, 1156 | url: vars.get("BITLAYER_TESTNET_URL", "https://testnet-rpc.bitlayer.org"), 1157 | accounts, 1158 | ledgerAccounts, 1159 | }, 1160 | bitlayerMain: { 1161 | chainId: 200901, 1162 | url: vars.get("BITLAYER_MAINNET_URL", "https://rpc.bitlayer.org"), 1163 | accounts, 1164 | ledgerAccounts, 1165 | }, 1166 | roninTestnet: { 1167 | chainId: 2021, 1168 | url: vars.get( 1169 | "RONIN_TESTNET_URL", 1170 | "https://saigon-testnet.roninchain.com/rpc", 1171 | ), 1172 | accounts, 1173 | ledgerAccounts, 1174 | }, 1175 | roninMain: { 1176 | chainId: 2020, 1177 | url: vars.get("RONIN_MAINNET_URL", "https://api.roninchain.com/rpc"), 1178 | accounts, 1179 | ledgerAccounts, 1180 | }, 1181 | }, 1182 | xdeploy: { 1183 | contract: "Create", 1184 | constructorArgsPath: undefined, 1185 | salt: vars.get( 1186 | "SALT", 1187 | // `keccak256("SALT")` 1188 | "0x087ee6a43229fddc3e140062b42bcff0c6d1c5a3bba8123976a59688e7024c25", 1189 | ), 1190 | signer: accounts[0], 1191 | networks: ["sepolia", "holesky"], 1192 | rpcUrls: [ 1193 | vars.get("ETH_SEPOLIA_TESTNET_URL", "https://rpc.sepolia.org"), 1194 | vars.get("ETH_HOLESKY_TESTNET_URL", "https://holesky.rpc.thirdweb.com"), 1195 | ], 1196 | gasLimit: 1.2 * 10 ** 6, 1197 | }, 1198 | contractSizer: { 1199 | alphaSort: true, 1200 | runOnCompile: true, 1201 | disambiguatePaths: false, 1202 | strict: true, 1203 | only: [], 1204 | except: ["CreateX", "Create2DeployerLocal"], 1205 | }, 1206 | gasReporter: { 1207 | enabled: vars.has("REPORT_GAS") ? true : false, 1208 | currency: "USD", 1209 | }, 1210 | abiExporter: { 1211 | path: "./abis", 1212 | runOnCompile: true, 1213 | clear: true, 1214 | flat: false, 1215 | only: ["Create"], 1216 | spacing: 2, 1217 | pretty: true, 1218 | }, 1219 | sourcify: { 1220 | // Enable Sourcify verification by default 1221 | enabled: true, 1222 | apiUrl: "https://sourcify.dev/server", 1223 | browserUrl: "https://repo.sourcify.dev", 1224 | }, 1225 | etherscan: { 1226 | // Add your own API key by getting an account at etherscan (https://etherscan.io), snowtrace (https://snowtrace.io) etc. 1227 | // This is used for verification purposes when you want to `npx hardhat verify` your contract using Hardhat 1228 | // The same API key works usually for both testnet and mainnet 1229 | apiKey: { 1230 | // For Ethereum testnets & mainnet 1231 | mainnet: vars.get("ETHERSCAN_API_KEY", ""), 1232 | goerli: vars.get("ETHERSCAN_API_KEY", ""), 1233 | sepolia: vars.get("ETHERSCAN_API_KEY", ""), 1234 | holesky: vars.get("ETHERSCAN_API_KEY", ""), 1235 | hoodi: vars.get("ETHERSCAN_API_KEY", ""), 1236 | // For BSC testnet & mainnet 1237 | bsc: vars.get("BSC_API_KEY", ""), 1238 | bscTestnet: vars.get("BSC_API_KEY", ""), 1239 | // For Heco mainnet 1240 | heco: vars.get("HECO_API_KEY", ""), 1241 | // For Fantom testnet & mainnet 1242 | opera: vars.get("FANTOM_API_KEY", ""), 1243 | ftmTestnet: vars.get("FANTOM_API_KEY", ""), 1244 | // For Optimism testnets & mainnet 1245 | optimisticEthereum: vars.get("OPTIMISM_API_KEY", ""), 1246 | optimisticGoerli: vars.get("OPTIMISM_API_KEY", ""), 1247 | optimisticSepolia: vars.get("OPTIMISM_API_KEY", ""), 1248 | // For Polygon testnets & mainnets 1249 | polygon: vars.get("POLYGON_API_KEY", ""), 1250 | polygonZkEVM: vars.get("POLYGON_ZKEVM_API_KEY", ""), 1251 | polygonAmoy: vars.get("POLYGON_API_KEY", ""), 1252 | polygonZkEVMTestnet: vars.get("POLYGON_ZKEVM_API_KEY", ""), 1253 | // For Arbitrum testnet & mainnets 1254 | arbitrumOne: vars.get("ARBITRUM_API_KEY", ""), 1255 | arbitrumNova: vars.get("ARBITRUM_API_KEY", ""), 1256 | arbitrumSepolia: vars.get("ARBITRUM_API_KEY", ""), 1257 | // For Avalanche testnet & mainnet 1258 | avalanche: vars.get("AVALANCHE_API_KEY", ""), 1259 | avalancheFujiTestnet: vars.get("AVALANCHE_API_KEY", ""), 1260 | // For Moonbeam testnet & mainnets 1261 | moonbeam: vars.get("MOONBEAM_API_KEY", ""), 1262 | moonriver: vars.get("MOONBEAM_API_KEY", ""), 1263 | moonbaseAlpha: vars.get("MOONBEAM_API_KEY", ""), 1264 | // For Celo testnet & mainnet 1265 | celo: vars.get("CELO_API_KEY", ""), 1266 | alfajores: vars.get("CELO_API_KEY", ""), 1267 | // For Harmony testnet & mainnet 1268 | harmony: vars.get("HARMONY_API_KEY", ""), 1269 | harmonyTestnet: vars.get("HARMONY_API_KEY", ""), 1270 | // For Aurora testnet & mainnet 1271 | aurora: vars.get("AURORA_API_KEY", ""), 1272 | auroraTestnet: vars.get("AURORA_API_KEY", ""), 1273 | // For Cronos testnet & mainnet 1274 | cronos: vars.get("CRONOS_API_KEY", ""), 1275 | cronosTestnet: vars.get("CRONOS_API_KEY", ""), 1276 | // For Gnosis/xDai testnet & mainnets 1277 | gnosis: vars.get("GNOSIS_API_KEY", ""), 1278 | xdai: vars.get("GNOSIS_API_KEY", ""), 1279 | chiado: vars.get("GNOSIS_API_KEY", ""), 1280 | // For Fuse testnet & mainnet 1281 | fuse: vars.get("FUSE_API_KEY", ""), 1282 | spark: vars.get("FUSE_API_KEY", ""), 1283 | // For Evmos testnet & mainnet 1284 | evmos: vars.get("EVMOS_API_KEY", ""), 1285 | evmosTestnet: vars.get("EVMOS_API_KEY", ""), 1286 | // For Boba network testnet & mainnet 1287 | boba: vars.get("BOBA_API_KEY", ""), 1288 | bobaTestnet: vars.get("BOBA_API_KEY", ""), 1289 | // For Canto testnet & mainnet 1290 | canto: vars.get("CANTO_API_KEY", ""), 1291 | cantoTestnet: vars.get("CANTO_API_KEY", ""), 1292 | // For Base testnets & mainnet 1293 | base: vars.get("BASE_API_KEY", ""), 1294 | baseTestnet: vars.get("BASE_API_KEY", ""), 1295 | baseSepolia: vars.get("BASE_API_KEY", ""), 1296 | // For Mantle testnet & mainnet 1297 | mantle: vars.get("MANTLE_API_KEY", ""), 1298 | mantleTestnet: vars.get("MANTLE_API_KEY", ""), 1299 | // For Filecoin testnet & mainnet 1300 | filecoin: vars.get("FILECOIN_API_KEY", ""), 1301 | filecoinTestnet: vars.get("FILECOIN_API_KEY", ""), 1302 | // For Scroll testnet & mainnet 1303 | scroll: vars.get("SCROLL_API_KEY", ""), 1304 | scrollTestnet: vars.get("SCROLL_API_KEY", ""), 1305 | // For Linea testnet & mainnet 1306 | linea: vars.get("LINEA_API_KEY", ""), 1307 | lineaTestnet: vars.get("LINEA_API_KEY", ""), 1308 | // For ShimmerEVM testnet 1309 | shimmerEVMTestnet: vars.get("SHIMMEREVM_API_KEY", ""), 1310 | // For Zora testnet & mainnet 1311 | zora: vars.get("ZORA_API_KEY", ""), 1312 | zoraTestnet: vars.get("ZORA_API_KEY", ""), 1313 | // For Lukso testnet & mainnet 1314 | lukso: vars.get("LUKSO_API_KEY", ""), 1315 | luksoTestnet: vars.get("LUKSO_API_KEY", ""), 1316 | // For Manta testnet & mainnet 1317 | manta: vars.get("MANTA_API_KEY", ""), 1318 | mantaTestnet: vars.get("MANTA_API_KEY", ""), 1319 | // For Arthera testnet 1320 | artheraTestnet: vars.get("ARTHERA_API_KEY", ""), 1321 | // For Endurance testnets & mainnet 1322 | endurance: vars.get("ENDURANCE_API_KEY", ""), 1323 | enduranceTestnet: vars.get("ENDURANCE_API_KEY", ""), 1324 | openduranceTestnet: vars.get("OPENDURANCE_API_KEY", ""), 1325 | // For Blast testnet & mainnet 1326 | blast: vars.get("BLAST_API_KEY", ""), 1327 | blastTestnet: vars.get("BLAST_API_KEY", ""), 1328 | // For Kroma testnet & mainnet 1329 | kroma: vars.get("KROMA_API_KEY", ""), 1330 | kromaTestnet: vars.get("KROMA_API_KEY", ""), 1331 | // For DOS Chain testnet & mainnet 1332 | dos: vars.get("DOS_API_KEY", ""), 1333 | dosTestnet: vars.get("DOS_API_KEY", ""), 1334 | // For Fraxtal testnet & mainnet 1335 | fraxtal: vars.get("FRAXTAL_API_KEY", ""), 1336 | fraxtalTestnet: vars.get("FRAXTAL_API_KEY", ""), 1337 | // For Kava mainnet 1338 | kava: vars.get("KAVA_API_KEY", ""), 1339 | // For Metis testnet & mainnet 1340 | metis: vars.get("METIS_API_KEY", ""), 1341 | metisTestnet: vars.get("METIS_API_KEY", ""), 1342 | // For Mode testnet & mainnet 1343 | mode: vars.get("MODE_API_KEY", ""), 1344 | modeTestnet: vars.get("MODE_API_KEY", ""), 1345 | // For X Layer testnet & mainnet 1346 | xlayer: vars.get("OKLINK_API_KEY", ""), 1347 | xlayerTestnet: vars.get("OKLINK_API_KEY", ""), 1348 | // For BOB testnet & mainnet 1349 | bob: vars.get("BOB_API_KEY", ""), 1350 | bobTestnet: vars.get("BOB_API_KEY", ""), 1351 | // For Core testnet & mainnet 1352 | core: vars.get("CORE_MAINNET_API_KEY", ""), 1353 | coreTestnet: vars.get("CORE_TESTNET_API_KEY", ""), 1354 | // For Telos testnet & mainnet 1355 | telos: vars.get("TELOS_API_KEY", ""), 1356 | telosTestnet: vars.get("TELOS_API_KEY", ""), 1357 | // For Rootstock testnet & mainnet 1358 | rootstock: vars.get("ROOTSTOCK_API_KEY", ""), 1359 | rootstockTestnet: vars.get("ROOTSTOCK_API_KEY", ""), 1360 | // For Chiliz testnet & mainnet 1361 | chiliz: vars.get("CHILIZ_API_KEY", ""), 1362 | chilizTestnet: vars.get("CHILIZ_API_KEY", ""), 1363 | // For Gravity Alpha testnet & mainnet 1364 | gravityAlpha: vars.get("GRAVITY_ALPHA_API_KEY", ""), 1365 | gravityAlphaTestnet: vars.get("GRAVITY_ALPHA_API_KEY", ""), 1366 | // For Taiko testnet & mainnet 1367 | taiko: vars.get("TAIKO_API_KEY", ""), 1368 | taikoTestnet: vars.get("TAIKO_API_KEY", ""), 1369 | // For ZetaChain testnet & mainnet 1370 | zetaChain: vars.get("ZETA_CHAIN_API_KEY", ""), 1371 | zetaChainTestnet: vars.get("ZETA_CHAIN_API_KEY", ""), 1372 | // For 5ireChain testnet & mainnet 1373 | "5ireChain": vars.get("5IRE_CHAIN_API_KEY", ""), 1374 | "5ireChainTestnet": vars.get("5IRE_CHAIN_API_KEY", ""), 1375 | // For Oasis Sapphire testnet & mainnet 1376 | sapphire: vars.get("SAPPHIRE_API_KEY", ""), 1377 | sapphireTestnet: vars.get("SAPPHIRE_API_KEY", ""), 1378 | // For World Chain testnet & mainnet 1379 | worldChain: vars.get("WORLD_CHAIN_API_KEY", ""), 1380 | worldChainTestnet: vars.get("WORLD_CHAIN_API_KEY", ""), 1381 | // For Plume testnet & mainnet 1382 | plume: vars.get("PLUME_API_KEY", ""), 1383 | plumeTestnet: vars.get("PLUME_API_KEY", ""), 1384 | // For Unichain testnet & mainnet 1385 | unichain: vars.get("UNICHAIN_API_KEY", ""), 1386 | unichainTestnet: vars.get("UNICHAIN_API_KEY", ""), 1387 | // For XDC testnet & mainnet 1388 | xdc: vars.get("XDC_API_KEY", ""), 1389 | xdcTestnet: vars.get("XDC_API_KEY", ""), 1390 | // For SX testnet & mainnet 1391 | sx: vars.get("SX_API_KEY", ""), 1392 | sxTestnet: vars.get("SX_API_KEY", ""), 1393 | // For Lisk testnet & mainnet 1394 | lisk: vars.get("LISK_API_KEY", ""), 1395 | liskTestnet: vars.get("LISK_API_KEY", ""), 1396 | // For Metal L2 testnet & mainnet 1397 | metalL2: vars.get("METALL2_API_KEY", ""), 1398 | metalL2Testnet: vars.get("METALL2_API_KEY", ""), 1399 | // For Superseed testnet & mainnet 1400 | superseed: vars.get("SUPERSEED_API_KEY", ""), 1401 | superseedTestnet: vars.get("SUPERSEED_API_KEY", ""), 1402 | // For Story testnet 1403 | storyTestnet: vars.get("STORY_API_KEY", ""), 1404 | // For Sonic testnet & mainnet 1405 | sonic: vars.get("SONIC_API_KEY", ""), 1406 | sonicTestnet: vars.get("SONIC_API_KEY", ""), 1407 | // For EVM on Flow testnet & mainnet 1408 | flow: vars.get("FLOW_API_KEY", ""), 1409 | flowTestnet: vars.get("FLOW_API_KEY", ""), 1410 | // For Ink testnet & mainnet 1411 | ink: vars.get("INK_API_KEY", ""), 1412 | inkTestnet: vars.get("INK_API_KEY", ""), 1413 | // For Morph testnet & mainnet 1414 | morph: vars.get("MORPH_API_KEY", ""), 1415 | morphTestnet: vars.get("MORPH_API_KEY", ""), 1416 | // For Shape testnet & mainnet 1417 | shape: vars.get("SHAPE_API_KEY", ""), 1418 | shapeTestnet: vars.get("SHAPE_API_KEY", ""), 1419 | // For Etherlink testnet & mainnet 1420 | etherlink: vars.get("ETHERLINK_API_KEY", ""), 1421 | etherlinkTestnet: vars.get("ETHERLINK_API_KEY", ""), 1422 | // For Soneium testnet & mainnet 1423 | soneium: vars.get("SONEIUM_API_KEY", ""), 1424 | soneiumTestnet: vars.get("SONEIUM_API_KEY", ""), 1425 | // For Swellchain testnet & mainnet 1426 | swell: vars.get("SWELL_API_KEY", ""), 1427 | swellTestnet: vars.get("SWELL_API_KEY", ""), 1428 | // For Hemi testnet & mainnet 1429 | hemi: vars.get("HEMI_API_KEY", ""), 1430 | hemiTestnet: vars.get("HEMI_API_KEY", ""), 1431 | // For Berachain testnet & mainnet 1432 | berachain: vars.get("BERACHAIN_API_KEY", ""), 1433 | berachainTestnet: vars.get("BERACHAIN_API_KEY", ""), 1434 | // For Corn testnet & mainnet 1435 | corn: vars.get("CORN_API_KEY", ""), 1436 | cornTestnet: vars.get("CORN_API_KEY", ""), 1437 | // For Arena-Z testnet & mainnet 1438 | arenaz: vars.get("ARENAZ_API_KEY", ""), 1439 | arenazTestnet: vars.get("ARENAZ_API_KEY", ""), 1440 | // For IoTeX testnet & mainnet 1441 | iotex: vars.get("IOTEX_API_KEY", ""), 1442 | iotexTestnet: vars.get("IOTEX_API_KEY", ""), 1443 | // For HYCHAIN testnet & mainnet 1444 | hychain: vars.get("HYCHAIN_API_KEY", ""), 1445 | hychainTestnet: vars.get("HYCHAIN_API_KEY", ""), 1446 | // For Zircuit testnet & mainnet 1447 | zircuit: vars.get("ZIRCUIT_API_KEY", ""), 1448 | zircuitTestnet: vars.get("ZIRCUIT_API_KEY", ""), 1449 | // For Bitlayer testnet & mainnet 1450 | bitlayer: vars.get("BITLAYER_API_KEY", ""), 1451 | bitlayerTestnet: vars.get("BITLAYER_API_KEY", ""), 1452 | }, 1453 | customChains: [ 1454 | { 1455 | network: "holesky", 1456 | chainId: 17000, 1457 | urls: { 1458 | apiURL: "https://api-holesky.etherscan.io/api", 1459 | browserURL: "https://holesky.etherscan.io", 1460 | }, 1461 | }, 1462 | { 1463 | network: "hoodi", 1464 | chainId: 560048, 1465 | urls: { 1466 | apiURL: "https://api-hoodi.etherscan.io/api", 1467 | browserURL: "https://hoodi.etherscan.io", 1468 | }, 1469 | }, 1470 | { 1471 | network: "optimisticSepolia", 1472 | chainId: 11155420, 1473 | urls: { 1474 | apiURL: "https://api-sepolia-optimistic.etherscan.io/api", 1475 | browserURL: "https://sepolia-optimism.etherscan.io", 1476 | }, 1477 | }, 1478 | { 1479 | network: "chiado", 1480 | chainId: 10200, 1481 | urls: { 1482 | apiURL: "https://gnosis-chiado.blockscout.com/api", 1483 | browserURL: "https://gnosis-chiado.blockscout.com", 1484 | }, 1485 | }, 1486 | { 1487 | network: "celo", 1488 | chainId: 42220, 1489 | urls: { 1490 | apiURL: "https://api.celoscan.io/api", 1491 | browserURL: "https://celoscan.io", 1492 | }, 1493 | }, 1494 | { 1495 | network: "alfajores", 1496 | chainId: 44787, 1497 | urls: { 1498 | apiURL: "https://api-alfajores.celoscan.io/api", 1499 | browserURL: "https://alfajores.celoscan.io", 1500 | }, 1501 | }, 1502 | { 1503 | network: "cronos", 1504 | chainId: 25, 1505 | urls: { 1506 | apiURL: "https://api.cronoscan.com/api", 1507 | browserURL: "https://cronoscan.com", 1508 | }, 1509 | }, 1510 | { 1511 | network: "cronosTestnet", 1512 | chainId: 338, 1513 | urls: { 1514 | apiURL: "https://cronos.org/explorer/testnet3/api", 1515 | browserURL: "https://cronos.org/explorer/testnet3", 1516 | }, 1517 | }, 1518 | { 1519 | network: "fuse", 1520 | chainId: 122, 1521 | urls: { 1522 | apiURL: "https://explorer.fuse.io/api", 1523 | browserURL: "https://explorer.fuse.io", 1524 | }, 1525 | }, 1526 | { 1527 | network: "spark", 1528 | chainId: 123, 1529 | urls: { 1530 | apiURL: "https://explorer.fusespark.io/api", 1531 | browserURL: "https://explorer.fusespark.io", 1532 | }, 1533 | }, 1534 | { 1535 | network: "evmos", 1536 | chainId: 9001, 1537 | urls: { 1538 | apiURL: "https://api.verify.mintscan.io/evm/api/0x2329", 1539 | browserURL: "https://www.mintscan.io/evmos", 1540 | }, 1541 | }, 1542 | { 1543 | network: "evmosTestnet", 1544 | chainId: 9000, 1545 | urls: { 1546 | apiURL: "https://api.verify.mintscan.io/evm/api/0x2328", 1547 | browserURL: "https://www.mintscan.io/evmos-testnet", 1548 | }, 1549 | }, 1550 | { 1551 | network: "boba", 1552 | chainId: 288, 1553 | urls: { 1554 | apiURL: 1555 | "https://api.routescan.io/v2/network/mainnet/evm/288/etherscan", 1556 | browserURL: "https://bobascan.com", 1557 | }, 1558 | }, 1559 | { 1560 | network: "bobaTestnet", 1561 | chainId: 2888, 1562 | urls: { 1563 | apiURL: 1564 | "https://api.routescan.io/v2/network/testnet/evm/2888/etherscan", 1565 | browserURL: "https://testnet.bobascan.com", 1566 | }, 1567 | }, 1568 | { 1569 | network: "arbitrumNova", 1570 | chainId: 42170, 1571 | urls: { 1572 | apiURL: "https://api-nova.arbiscan.io/api", 1573 | browserURL: "https://nova.arbiscan.io", 1574 | }, 1575 | }, 1576 | { 1577 | network: "arbitrumSepolia", 1578 | chainId: 421614, 1579 | urls: { 1580 | apiURL: "https://api-sepolia.arbiscan.io/api", 1581 | browserURL: "https://sepolia.arbiscan.io", 1582 | }, 1583 | }, 1584 | { 1585 | network: "canto", 1586 | chainId: 7700, 1587 | urls: { 1588 | apiURL: "https://tuber.build/api", 1589 | browserURL: "https://tuber.build", 1590 | }, 1591 | }, 1592 | { 1593 | network: "cantoTestnet", 1594 | chainId: 7701, 1595 | urls: { 1596 | apiURL: "https://testnet.tuber.build/api", 1597 | browserURL: "https://testnet.tuber.build", 1598 | }, 1599 | }, 1600 | { 1601 | network: "base", 1602 | chainId: 8453, 1603 | urls: { 1604 | apiURL: "https://api.basescan.org/api", 1605 | browserURL: "https://basescan.org", 1606 | }, 1607 | }, 1608 | { 1609 | network: "baseTestnet", 1610 | chainId: 84531, 1611 | urls: { 1612 | apiURL: "https://api-goerli.basescan.org/api", 1613 | browserURL: "https://goerli.basescan.org", 1614 | }, 1615 | }, 1616 | { 1617 | network: "baseSepolia", 1618 | chainId: 84532, 1619 | urls: { 1620 | apiURL: "https://api-sepolia.basescan.org/api", 1621 | browserURL: "https://sepolia.basescan.org", 1622 | }, 1623 | }, 1624 | { 1625 | network: "mantle", 1626 | chainId: 5000, 1627 | urls: { 1628 | apiURL: "https://api.mantlescan.xyz/api", 1629 | browserURL: "https://mantlescan.xyz", 1630 | }, 1631 | }, 1632 | { 1633 | network: "mantleTestnet", 1634 | chainId: 5003, 1635 | urls: { 1636 | apiURL: "https://api-sepolia.mantlescan.xyz/api", 1637 | browserURL: "https://sepolia.mantlescan.xyz", 1638 | }, 1639 | }, 1640 | { 1641 | network: "filecoin", 1642 | chainId: 314, 1643 | urls: { 1644 | apiURL: "https://filfox.info/api/v1/tools/verifyContract", 1645 | browserURL: "https://filfox.info/en", 1646 | }, 1647 | }, 1648 | { 1649 | network: "filecoinTestnet", 1650 | chainId: 314159, 1651 | urls: { 1652 | apiURL: "https://calibration.filfox.info/api/v1/tools/verifyContract", 1653 | browserURL: "https://calibration.filfox.info/en", 1654 | }, 1655 | }, 1656 | { 1657 | network: "scroll", 1658 | chainId: 534352, 1659 | urls: { 1660 | apiURL: "https://api.scrollscan.com/api", 1661 | browserURL: "https://scrollscan.com", 1662 | }, 1663 | }, 1664 | { 1665 | network: "scrollTestnet", 1666 | chainId: 534351, 1667 | urls: { 1668 | apiURL: "https://api-sepolia.scrollscan.com/api", 1669 | browserURL: "https://sepolia.scrollscan.com", 1670 | }, 1671 | }, 1672 | { 1673 | network: "polygonZkEVM", 1674 | chainId: 1101, 1675 | urls: { 1676 | apiURL: "https://api-zkevm.polygonscan.com/api", 1677 | browserURL: "https://zkevm.polygonscan.com", 1678 | }, 1679 | }, 1680 | { 1681 | network: "polygonAmoy", 1682 | chainId: 80002, 1683 | urls: { 1684 | apiURL: "https://api-amoy.polygonscan.com/api", 1685 | browserURL: "https://amoy.polygonscan.com", 1686 | }, 1687 | }, 1688 | { 1689 | network: "polygonZkEVMTestnet", 1690 | chainId: 2442, 1691 | urls: { 1692 | apiURL: "https://api-cardona-zkevm.polygonscan.com/api", 1693 | browserURL: "https://cardona-zkevm.polygonscan.com", 1694 | }, 1695 | }, 1696 | { 1697 | network: "linea", 1698 | chainId: 59144, 1699 | urls: { 1700 | apiURL: "https://api.lineascan.build/api", 1701 | browserURL: "https://lineascan.build", 1702 | }, 1703 | }, 1704 | { 1705 | network: "lineaTestnet", 1706 | chainId: 59141, 1707 | urls: { 1708 | apiURL: "https://api-sepolia.lineascan.build/api", 1709 | browserURL: "https://sepolia.lineascan.build", 1710 | }, 1711 | }, 1712 | { 1713 | network: "shimmerEVMTestnet", 1714 | chainId: 1071, 1715 | urls: { 1716 | apiURL: "https://explorer.evm.testnet.shimmer.network/api", 1717 | browserURL: "https://explorer.evm.testnet.shimmer.network", 1718 | }, 1719 | }, 1720 | { 1721 | network: "zora", 1722 | chainId: 7777777, 1723 | urls: { 1724 | apiURL: "https://explorer.zora.energy/api", 1725 | browserURL: "https://explorer.zora.energy", 1726 | }, 1727 | }, 1728 | { 1729 | network: "zoraTestnet", 1730 | chainId: 999999999, 1731 | urls: { 1732 | apiURL: "https://sepolia.explorer.zora.energy/api", 1733 | browserURL: "https://sepolia.explorer.zora.energy", 1734 | }, 1735 | }, 1736 | { 1737 | network: "lukso", 1738 | chainId: 42, 1739 | urls: { 1740 | apiURL: "https://explorer.execution.mainnet.lukso.network/api", 1741 | browserURL: "https://explorer.execution.mainnet.lukso.network", 1742 | }, 1743 | }, 1744 | { 1745 | network: "luksoTestnet", 1746 | chainId: 4201, 1747 | urls: { 1748 | apiURL: "https://explorer.execution.testnet.lukso.network/api", 1749 | browserURL: "https://explorer.execution.testnet.lukso.network", 1750 | }, 1751 | }, 1752 | { 1753 | network: "manta", 1754 | chainId: 169, 1755 | urls: { 1756 | apiURL: "https://pacific-explorer.manta.network/api", 1757 | browserURL: "https://pacific-explorer.manta.network", 1758 | }, 1759 | }, 1760 | { 1761 | network: "mantaTestnet", 1762 | chainId: 3441006, 1763 | urls: { 1764 | apiURL: "https://pacific-explorer.sepolia-testnet.manta.network/api", 1765 | browserURL: "https://pacific-explorer.sepolia-testnet.manta.network", 1766 | }, 1767 | }, 1768 | { 1769 | network: "artheraTestnet", 1770 | chainId: 10243, 1771 | urls: { 1772 | apiURL: "https://explorer-test.arthera.net/api", 1773 | browserURL: "https://explorer-test.arthera.net", 1774 | }, 1775 | }, 1776 | { 1777 | network: "endurance", 1778 | chainId: 648, 1779 | urls: { 1780 | apiURL: "https://explorer-endurance.fusionist.io/api", 1781 | browserURL: "https://explorer-endurance.fusionist.io", 1782 | }, 1783 | }, 1784 | { 1785 | network: "enduranceTestnet", 1786 | chainId: 6480, 1787 | urls: { 1788 | apiURL: "https://myexplorertestnet.fusionist.io/api", 1789 | browserURL: "https://myexplorertestnet.fusionist.io", 1790 | }, 1791 | }, 1792 | { 1793 | network: "openduranceTestnet", 1794 | chainId: 6480001001, 1795 | urls: { 1796 | apiURL: "https://explorer-l2-testnet.fusionist.io/api", 1797 | browserURL: "https://explorer-l2-testnet.fusionist.io", 1798 | }, 1799 | }, 1800 | { 1801 | network: "blast", 1802 | chainId: 81457, 1803 | urls: { 1804 | apiURL: "https://api.blastscan.io/api", 1805 | browserURL: "https://blastscan.io", 1806 | }, 1807 | }, 1808 | { 1809 | network: "blastTestnet", 1810 | chainId: 168587773, 1811 | urls: { 1812 | apiURL: "https://api-sepolia.blastscan.io/api", 1813 | browserURL: "https://sepolia.blastscan.io", 1814 | }, 1815 | }, 1816 | { 1817 | network: "kroma", 1818 | chainId: 255, 1819 | urls: { 1820 | apiURL: "https://api.kromascan.com/api", 1821 | browserURL: "https://kromascan.com", 1822 | }, 1823 | }, 1824 | { 1825 | network: "kromaTestnet", 1826 | chainId: 2358, 1827 | urls: { 1828 | apiURL: "https://api-sepolia.kromascan.com", 1829 | browserURL: "https://sepolia.kromascan.com", 1830 | }, 1831 | }, 1832 | { 1833 | network: "dos", 1834 | chainId: 7979, 1835 | urls: { 1836 | apiURL: "https://doscan.io/api", 1837 | browserURL: "https://doscan.io", 1838 | }, 1839 | }, 1840 | { 1841 | network: "dosTestnet", 1842 | chainId: 3939, 1843 | urls: { 1844 | apiURL: "https://test.doscan.io/api", 1845 | browserURL: "https://test.doscan.io", 1846 | }, 1847 | }, 1848 | { 1849 | network: "fraxtal", 1850 | chainId: 252, 1851 | urls: { 1852 | apiURL: "https://api.fraxscan.com/api", 1853 | browserURL: "https://fraxscan.com", 1854 | }, 1855 | }, 1856 | { 1857 | network: "fraxtalTestnet", 1858 | chainId: 2522, 1859 | urls: { 1860 | apiURL: "https://api-holesky.fraxscan.com/api", 1861 | browserURL: "https://holesky.fraxscan.com", 1862 | }, 1863 | }, 1864 | { 1865 | network: "kava", 1866 | chainId: 2222, 1867 | urls: { 1868 | apiURL: "https://kavascan.com/api", 1869 | browserURL: "https://kavascan.com", 1870 | }, 1871 | }, 1872 | { 1873 | network: "metis", 1874 | chainId: 1088, 1875 | urls: { 1876 | apiURL: "https://andromeda-explorer.metis.io/api", 1877 | browserURL: "https://andromeda-explorer.metis.io", 1878 | }, 1879 | }, 1880 | { 1881 | network: "metisTestnet", 1882 | chainId: 59902, 1883 | urls: { 1884 | apiURL: "https://sepolia-explorer.metisdevops.link/api", 1885 | browserURL: "https://sepolia-explorer.metisdevops.link", 1886 | }, 1887 | }, 1888 | { 1889 | network: "mode", 1890 | chainId: 34443, 1891 | urls: { 1892 | apiURL: "https://explorer.mode.network/api", 1893 | browserURL: "https://explorer.mode.network", 1894 | }, 1895 | }, 1896 | { 1897 | network: "modeTestnet", 1898 | chainId: 919, 1899 | urls: { 1900 | apiURL: "https://sepolia.explorer.mode.network/api", 1901 | browserURL: "https://sepolia.explorer.mode.network", 1902 | }, 1903 | }, 1904 | { 1905 | network: "xlayer", 1906 | chainId: 196, 1907 | urls: { 1908 | apiURL: 1909 | "https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/XLAYER", 1910 | browserURL: "https://www.oklink.com/x-layer", 1911 | }, 1912 | }, 1913 | { 1914 | network: "xlayerTestnet", 1915 | chainId: 195, 1916 | urls: { 1917 | apiURL: 1918 | "https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/XLAYER_TESTNET", 1919 | browserURL: "https://www.oklink.com/x-layer-testnet", 1920 | }, 1921 | }, 1922 | { 1923 | network: "bob", 1924 | chainId: 60808, 1925 | urls: { 1926 | apiURL: "https://explorer.gobob.xyz/api", 1927 | browserURL: "https://explorer.gobob.xyz", 1928 | }, 1929 | }, 1930 | { 1931 | network: "bobTestnet", 1932 | chainId: 111, 1933 | urls: { 1934 | apiURL: "https://testnet-explorer.gobob.xyz/api", 1935 | browserURL: "https://testnet-explorer.gobob.xyz", 1936 | }, 1937 | }, 1938 | { 1939 | network: "core", 1940 | chainId: 1116, 1941 | urls: { 1942 | apiURL: "https://openapi.coredao.org/api", 1943 | browserURL: "https://scan.coredao.org", 1944 | }, 1945 | }, 1946 | { 1947 | network: "coreTestnet", 1948 | chainId: 1115, 1949 | urls: { 1950 | apiURL: "https://api.test.btcs.network/api", 1951 | browserURL: "https://scan.test.btcs.network", 1952 | }, 1953 | }, 1954 | { 1955 | network: "telos", 1956 | chainId: 40, 1957 | urls: { 1958 | apiURL: "https://api.teloscan.io/api", 1959 | browserURL: "https://www.teloscan.io", 1960 | }, 1961 | }, 1962 | { 1963 | network: "telosTestnet", 1964 | chainId: 41, 1965 | urls: { 1966 | apiURL: "https://api.testnet.teloscan.io/api", 1967 | browserURL: "https://testnet.teloscan.io", 1968 | }, 1969 | }, 1970 | { 1971 | network: "rootstock", 1972 | chainId: 30, 1973 | urls: { 1974 | apiURL: "https://rootstock.blockscout.com/api", 1975 | browserURL: "https://rootstock.blockscout.com", 1976 | }, 1977 | }, 1978 | { 1979 | network: "rootstockTestnet", 1980 | chainId: 31, 1981 | urls: { 1982 | apiURL: "https://rootstock-testnet.blockscout.com/api", 1983 | browserURL: "https://rootstock-testnet.blockscout.com", 1984 | }, 1985 | }, 1986 | { 1987 | network: "chiliz", 1988 | chainId: 88888, 1989 | urls: { 1990 | apiURL: 1991 | "https://api.routescan.io/v2/network/mainnet/evm/88888/etherscan/api", 1992 | browserURL: "https://chiliscan.com", 1993 | }, 1994 | }, 1995 | { 1996 | network: "chilizTestnet", 1997 | chainId: 88882, 1998 | urls: { 1999 | apiURL: 2000 | "https://api.routescan.io/v2/network/testnet/evm/88882/etherscan/api", 2001 | browserURL: "https://testnet.chiliscan.com", 2002 | }, 2003 | }, 2004 | { 2005 | network: "harmony", 2006 | chainId: 1666600000, 2007 | urls: { 2008 | apiURL: "https://explorer.harmony.one/api", 2009 | browserURL: "https://explorer.harmony.one", 2010 | }, 2011 | }, 2012 | { 2013 | network: "harmonyTestnet", 2014 | chainId: 1666700000, 2015 | urls: { 2016 | apiURL: "https://explorer.testnet.harmony.one/api", 2017 | browserURL: "https://explorer.testnet.harmony.one", 2018 | }, 2019 | }, 2020 | { 2021 | network: "gravityAlpha", 2022 | chainId: 1625, 2023 | urls: { 2024 | apiURL: "https://explorer.gravity.xyz/api", 2025 | browserURL: "https://explorer.gravity.xyz", 2026 | }, 2027 | }, 2028 | { 2029 | network: "gravityAlphaTestnet", 2030 | chainId: 13505, 2031 | urls: { 2032 | apiURL: "https://explorer-sepolia.gravity.xyz/api", 2033 | browserURL: "https://explorer-sepolia.gravity.xyz", 2034 | }, 2035 | }, 2036 | { 2037 | network: "taiko", 2038 | chainId: 167000, 2039 | urls: { 2040 | apiURL: "https://api.taikoscan.io/api", 2041 | browserURL: "https://taikoscan.io", 2042 | }, 2043 | }, 2044 | { 2045 | network: "taikoTestnet", 2046 | chainId: 167009, 2047 | urls: { 2048 | apiURL: "https://api-hekla.taikoscan.io/api", 2049 | browserURL: "https://hekla.taikoscan.io", 2050 | }, 2051 | }, 2052 | { 2053 | network: "zetaChain", 2054 | chainId: 7000, 2055 | urls: { 2056 | apiURL: "https://zetachain.blockscout.com/api", 2057 | browserURL: "https://zetachain.blockscout.com", 2058 | }, 2059 | }, 2060 | { 2061 | network: "zetaChainTestnet", 2062 | chainId: 7001, 2063 | urls: { 2064 | apiURL: "https://zetachain-athens-3.blockscout.com/api", 2065 | browserURL: "https://zetachain-athens-3.blockscout.com", 2066 | }, 2067 | }, 2068 | { 2069 | network: "5ireChain", 2070 | chainId: 995, 2071 | urls: { 2072 | apiURL: "https://5irescan.io/api", 2073 | browserURL: "https://5irescan.io", 2074 | }, 2075 | }, 2076 | { 2077 | network: "5ireChainTestnet", 2078 | chainId: 997, 2079 | urls: { 2080 | apiURL: "https://testnet.5irescan.io/api", 2081 | browserURL: "https://testnet.5irescan.io", 2082 | }, 2083 | }, 2084 | { 2085 | network: "sapphire", 2086 | chainId: 23294, 2087 | urls: { 2088 | apiURL: "https://explorer.oasis.io/mainnet/sapphire/api", 2089 | browserURL: "https://explorer.oasis.io/mainnet/sapphire", 2090 | }, 2091 | }, 2092 | { 2093 | network: "sapphireTestnet", 2094 | chainId: 23295, 2095 | urls: { 2096 | apiURL: "https://explorer.oasis.io/testnet/sapphire/api", 2097 | browserURL: "https://explorer.oasis.io/testnet/sapphire", 2098 | }, 2099 | }, 2100 | { 2101 | network: "worldChain", 2102 | chainId: 480, 2103 | urls: { 2104 | apiURL: "https://worldchain-mainnet.explorer.alchemy.com/api", 2105 | browserURL: "https://worldchain-mainnet.explorer.alchemy.com", 2106 | }, 2107 | }, 2108 | { 2109 | network: "worldChainTestnet", 2110 | chainId: 4801, 2111 | urls: { 2112 | apiURL: "https://worldchain-sepolia.explorer.alchemy.com/api", 2113 | browserURL: "https://worldchain-sepolia.explorer.alchemy.com", 2114 | }, 2115 | }, 2116 | { 2117 | network: "plume", 2118 | chainId: 98866, 2119 | urls: { 2120 | apiURL: "https://explorer.plume.org/api", 2121 | browserURL: "https://explorer.plume.org", 2122 | }, 2123 | }, 2124 | { 2125 | network: "plumeTestnet", 2126 | chainId: 98867, 2127 | urls: { 2128 | apiURL: "https://testnet-explorer.plume.org/api", 2129 | browserURL: "https://testnet-explorer.plume.org", 2130 | }, 2131 | }, 2132 | { 2133 | network: "unichain", 2134 | chainId: 130, 2135 | urls: { 2136 | apiURL: "https://api.uniscan.xyz/api", 2137 | browserURL: "https://uniscan.xyz", 2138 | }, 2139 | }, 2140 | { 2141 | network: "unichainTestnet", 2142 | chainId: 1301, 2143 | urls: { 2144 | apiURL: "https://api-sepolia.uniscan.xyz/api", 2145 | browserURL: "https://sepolia.uniscan.xyz", 2146 | }, 2147 | }, 2148 | { 2149 | network: "xdc", 2150 | chainId: 50, 2151 | urls: { 2152 | apiURL: "https://api.xdcscan.com/api", 2153 | browserURL: "https://xdcscan.com", 2154 | }, 2155 | }, 2156 | { 2157 | network: "xdcTestnet", 2158 | chainId: 51, 2159 | urls: { 2160 | apiURL: "https://api-testnet.xdcscan.com/api", 2161 | browserURL: "https://testnet.xdcscan.com", 2162 | }, 2163 | }, 2164 | { 2165 | network: "sx", 2166 | chainId: 4162, 2167 | urls: { 2168 | apiURL: "https://explorerl2.sx.technology/api", 2169 | browserURL: "https://explorerl2.sx.technology", 2170 | }, 2171 | }, 2172 | { 2173 | network: "sxTestnet", 2174 | chainId: 79479957, 2175 | urls: { 2176 | apiURL: "https://explorerl2.toronto.sx.technology/api", 2177 | browserURL: "https://explorerl2.toronto.sx.technology", 2178 | }, 2179 | }, 2180 | { 2181 | network: "lisk", 2182 | chainId: 1135, 2183 | urls: { 2184 | apiURL: "https://blockscout.lisk.com/api", 2185 | browserURL: "https://blockscout.lisk.com", 2186 | }, 2187 | }, 2188 | { 2189 | network: "liskTestnet", 2190 | chainId: 4202, 2191 | urls: { 2192 | apiURL: "https://sepolia-blockscout.lisk.com/api", 2193 | browserURL: "https://sepolia-blockscout.lisk.com", 2194 | }, 2195 | }, 2196 | { 2197 | network: "metalL2", 2198 | chainId: 1750, 2199 | urls: { 2200 | apiURL: "https://explorer.metall2.com/api", 2201 | browserURL: "https://explorer.metall2.com", 2202 | }, 2203 | }, 2204 | { 2205 | network: "metalL2Testnet", 2206 | chainId: 1740, 2207 | urls: { 2208 | apiURL: "https://testnet.explorer.metall2.com/api", 2209 | browserURL: "https://testnet.explorer.metall2.com", 2210 | }, 2211 | }, 2212 | { 2213 | network: "superseed", 2214 | chainId: 5330, 2215 | urls: { 2216 | apiURL: "https://explorer.superseed.xyz/api", 2217 | browserURL: "https://explorer.superseed.xyz", 2218 | }, 2219 | }, 2220 | { 2221 | network: "superseedTestnet", 2222 | chainId: 53302, 2223 | urls: { 2224 | apiURL: "https://sepolia-explorer.superseed.xyz/api", 2225 | browserURL: "https://sepolia-explorer.superseed.xyz", 2226 | }, 2227 | }, 2228 | { 2229 | network: "storyTestnet", 2230 | chainId: 1315, 2231 | urls: { 2232 | apiURL: "https://aeneid.storyscan.io/api", 2233 | browserURL: "https://aeneid.storyscan.io", 2234 | }, 2235 | }, 2236 | { 2237 | network: "sonic", 2238 | chainId: 146, 2239 | urls: { 2240 | apiURL: "https://api.sonicscan.org/api", 2241 | browserURL: "https://sonicscan.org", 2242 | }, 2243 | }, 2244 | { 2245 | network: "sonicTestnet", 2246 | chainId: 57054, 2247 | urls: { 2248 | apiURL: "https://api-testnet.sonicscan.org/api", 2249 | browserURL: "https://testnet.sonicscan.org", 2250 | }, 2251 | }, 2252 | { 2253 | network: "flow", 2254 | chainId: 747, 2255 | urls: { 2256 | apiURL: "https://evm.flowscan.io/api", 2257 | browserURL: "https://evm.flowscan.io", 2258 | }, 2259 | }, 2260 | { 2261 | network: "flowTestnet", 2262 | chainId: 545, 2263 | urls: { 2264 | apiURL: "https://evm-testnet.flowscan.io/api", 2265 | browserURL: "https://evm-testnet.flowscan.io", 2266 | }, 2267 | }, 2268 | { 2269 | network: "ink", 2270 | chainId: 57073, 2271 | urls: { 2272 | apiURL: "https://explorer.inkonchain.com/api", 2273 | browserURL: "https://explorer.inkonchain.com", 2274 | }, 2275 | }, 2276 | { 2277 | network: "inkTestnet", 2278 | chainId: 763373, 2279 | urls: { 2280 | apiURL: "https://explorer-sepolia.inkonchain.com/api", 2281 | browserURL: "https://explorer-sepolia.inkonchain.com", 2282 | }, 2283 | }, 2284 | { 2285 | network: "morph", 2286 | chainId: 2818, 2287 | urls: { 2288 | apiURL: "https://explorer.morphl2.io/api", 2289 | browserURL: "https://explorer.morphl2.io", 2290 | }, 2291 | }, 2292 | { 2293 | network: "morphTestnet", 2294 | chainId: 2810, 2295 | urls: { 2296 | apiURL: "https://explorer-holesky.morphl2.io/api", 2297 | browserURL: "https://explorer-holesky.morphl2.io", 2298 | }, 2299 | }, 2300 | { 2301 | network: "shape", 2302 | chainId: 360, 2303 | urls: { 2304 | apiURL: "https://shapescan.xyz/api", 2305 | browserURL: "https://shapescan.xyz", 2306 | }, 2307 | }, 2308 | { 2309 | network: "shapeTestnet", 2310 | chainId: 11011, 2311 | urls: { 2312 | apiURL: "https://sepolia.shapescan.xyz/api", 2313 | browserURL: "https://sepolia.shapescan.xyz", 2314 | }, 2315 | }, 2316 | { 2317 | network: "etherlink", 2318 | chainId: 42793, 2319 | urls: { 2320 | apiURL: "https://explorer.etherlink.com/api", 2321 | browserURL: "https://explorer.etherlink.com", 2322 | }, 2323 | }, 2324 | { 2325 | network: "etherlinkTestnet", 2326 | chainId: 128123, 2327 | urls: { 2328 | apiURL: "https://testnet.explorer.etherlink.com/api", 2329 | browserURL: "https://testnet.explorer.etherlink.com", 2330 | }, 2331 | }, 2332 | { 2333 | network: "soneium", 2334 | chainId: 1868, 2335 | urls: { 2336 | apiURL: "https://soneium.blockscout.com/api", 2337 | browserURL: "https://soneium.blockscout.com", 2338 | }, 2339 | }, 2340 | { 2341 | network: "soneiumTestnet", 2342 | chainId: 1946, 2343 | urls: { 2344 | apiURL: "https://soneium-minato.blockscout.com/api", 2345 | browserURL: "https://soneium-minato.blockscout.com", 2346 | }, 2347 | }, 2348 | { 2349 | network: "swell", 2350 | chainId: 1923, 2351 | urls: { 2352 | apiURL: "https://explorer.swellnetwork.io/api", 2353 | browserURL: "https://explorer.swellnetwork.io", 2354 | }, 2355 | }, 2356 | { 2357 | network: "swellTestnet", 2358 | chainId: 1924, 2359 | urls: { 2360 | apiURL: "https://swell-testnet-explorer.alt.technology/api", 2361 | browserURL: "https://swell-testnet-explorer.alt.technology", 2362 | }, 2363 | }, 2364 | { 2365 | network: "hemi", 2366 | chainId: 43111, 2367 | urls: { 2368 | apiURL: "https://explorer.hemi.xyz/api", 2369 | browserURL: "https://explorer.hemi.xyz", 2370 | }, 2371 | }, 2372 | { 2373 | network: "hemiTestnet", 2374 | chainId: 743111, 2375 | urls: { 2376 | apiURL: "https://testnet.explorer.hemi.xyz/api", 2377 | browserURL: "https://testnet.explorer.hemi.xyz", 2378 | }, 2379 | }, 2380 | { 2381 | network: "berachain", 2382 | chainId: 80094, 2383 | urls: { 2384 | apiURL: "https://api.berascan.com/api", 2385 | browserURL: "https://berascan.com", 2386 | }, 2387 | }, 2388 | { 2389 | network: "berachainTestnet", 2390 | chainId: 80084, 2391 | urls: { 2392 | apiURL: 2393 | "https://api.routescan.io/v2/network/testnet/evm/80084/etherscan", 2394 | browserURL: "https://bartio.beratrail.io", 2395 | }, 2396 | }, 2397 | { 2398 | network: "corn", 2399 | chainId: 21000000, 2400 | urls: { 2401 | apiURL: 2402 | "https://api.routescan.io/v2/network/mainnet/evm/21000000/etherscan", 2403 | browserURL: "https://cornscan.io", 2404 | }, 2405 | }, 2406 | { 2407 | network: "cornTestnet", 2408 | chainId: 21000001, 2409 | urls: { 2410 | apiURL: 2411 | "https://api.routescan.io/v2/network/testnet/evm/21000001/etherscan", 2412 | browserURL: "https://testnet.cornscan.io", 2413 | }, 2414 | }, 2415 | { 2416 | network: "arenaz", 2417 | chainId: 7897, 2418 | urls: { 2419 | apiURL: "https://explorer.arena-z.gg/api", 2420 | browserURL: "https://explorer.arena-z.gg", 2421 | }, 2422 | }, 2423 | { 2424 | network: "arenazTestnet", 2425 | chainId: 9897, 2426 | urls: { 2427 | apiURL: "https://arena-z.blockscout.com/api", 2428 | browserURL: "https://arena-z.blockscout.com", 2429 | }, 2430 | }, 2431 | { 2432 | network: "iotex", 2433 | chainId: 4689, 2434 | urls: { 2435 | apiURL: "https://iotexscout.io/api", 2436 | browserURL: "https://iotexscan.io", 2437 | }, 2438 | }, 2439 | { 2440 | network: "iotexTestnet", 2441 | chainId: 4690, 2442 | urls: { 2443 | apiURL: "https://testnet.iotexscan.io/api", 2444 | browserURL: "https://testnet.iotexscan.io", 2445 | }, 2446 | }, 2447 | { 2448 | network: "hychain", 2449 | chainId: 2911, 2450 | urls: { 2451 | apiURL: "https://explorer.hychain.com/api", 2452 | browserURL: "https://explorer.hychain.com", 2453 | }, 2454 | }, 2455 | { 2456 | network: "hychainTestnet", 2457 | chainId: 29112, 2458 | urls: { 2459 | apiURL: "https://testnet.explorer.hychain.com/api", 2460 | browserURL: "https://testnet.explorer.hychain.com", 2461 | }, 2462 | }, 2463 | { 2464 | network: "zircuit", 2465 | chainId: 48900, 2466 | urls: { 2467 | apiURL: "https://explorer.zircuit.com/api/contractVerifyHardhat", 2468 | browserURL: "https://explorer.zircuit.com", 2469 | }, 2470 | }, 2471 | { 2472 | network: "zircuitTestnet", 2473 | chainId: 48898, 2474 | urls: { 2475 | apiURL: 2476 | "https://explorer.garfield-testnet.zircuit.com/api/contractVerifyHardhat", 2477 | browserURL: "https://explorer.garfield-testnet.zircuit.com", 2478 | }, 2479 | }, 2480 | { 2481 | network: "bitlayer", 2482 | chainId: 200901, 2483 | urls: { 2484 | apiURL: "https://api.btrscan.com/scan/api", 2485 | browserURL: "https://www.btrscan.com", 2486 | }, 2487 | }, 2488 | { 2489 | network: "bitlayerTestnet", 2490 | chainId: 200810, 2491 | urls: { 2492 | apiURL: "https://api-testnet.btrscan.com/scan/api", 2493 | browserURL: "https://testnet.btrscan.com", 2494 | }, 2495 | }, 2496 | ], 2497 | }, 2498 | }; 2499 | 2500 | export default config; 2501 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-util", 3 | "version": "1.0.0", 4 | "description": "Helper smart contract to make easier and safer usage of the `CREATE` EVM opcode.", 5 | "keywords": [ 6 | "deployment", 7 | "ethereum", 8 | "smart-contracts", 9 | "solidity", 10 | "create" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/pcaversaccio/create-util.git" 15 | }, 16 | "homepage": "https://github.com/pcaversaccio/create-util#readme", 17 | "bugs": { 18 | "url": "git+https://github.com/pcaversaccio/create-util/issues" 19 | }, 20 | "author": "Pascal Marco Caversaccio ", 21 | "license": "MIT", 22 | "packageManager": "pnpm@10.11.1", 23 | "scripts": { 24 | "help": "npx hardhat help", 25 | "accounts": "npx hardhat accounts", 26 | "balances": "npx hardhat balances", 27 | "node:hh": "npx hardhat node", 28 | "clean": "npx hardhat clean", 29 | "test": "npx hardhat test", 30 | "coverage": "npx hardhat coverage", 31 | "compile": "npx hardhat compile", 32 | "size": "npx hardhat size-contracts", 33 | "xdeploy": "npx hardhat xdeploy", 34 | "abi": "npx hardhat export-abi", 35 | "vars:path": "npx hardhat vars path", 36 | "evm": "npx hardhat evm", 37 | "deploy:hh": "npx hardhat run --network hardhat scripts/deploy.ts", 38 | "deploy:localhost": "npx hardhat run --network localhost scripts/deploy.ts", 39 | "deploy:dashboard": "npx hardhat run --network truffleDashboard scripts/deploy.ts", 40 | "deploy:tenderly": "npx hardhat run --network tenderly scripts/deploy.ts", 41 | "deploy:devnet": "npx hardhat run --network devnet scripts/deploy.ts", 42 | "deploy:goerli": "npx hardhat run --network goerli scripts/deploy.ts", 43 | "deploy:sepolia": "npx hardhat run --network sepolia scripts/deploy.ts", 44 | "deploy:holesky": "npx hardhat run --network holesky scripts/deploy.ts", 45 | "deploy:hoodi": "npx hardhat run --network hoodi scripts/deploy.ts", 46 | "deploy:ethmain": "npx hardhat run --network ethMain scripts/deploy.ts", 47 | "deploy:bsctestnet": "npx hardhat run --network bscTestnet scripts/deploy.ts", 48 | "deploy:bscmain": "npx hardhat run --network bscMain scripts/deploy.ts", 49 | "deploy:optimismtestnet": "npx hardhat run --network optimismTestnet scripts/deploy.ts", 50 | "deploy:optimismsepolia": "npx hardhat run --network optimismSepolia scripts/deploy.ts", 51 | "deploy:optimismmain": "npx hardhat run --network optimismMain scripts/deploy.ts", 52 | "deploy:arbitrumsepolia": "npx hardhat run --network arbitrumSepolia scripts/deploy.ts", 53 | "deploy:arbitrummain": "npx hardhat run --network arbitrumMain scripts/deploy.ts", 54 | "deploy:arbitrumnova": "npx hardhat run --network arbitrumNova scripts/deploy.ts", 55 | "deploy:amoy": "npx hardhat run --network amoy scripts/deploy.ts", 56 | "deploy:polygonzkevmtestnet": "npx hardhat run --network polygonZkEVMTestnet scripts/deploy.ts", 57 | "deploy:polygon": "npx hardhat run --network polygon scripts/deploy.ts", 58 | "deploy:polygonzkevmmain": "npx hardhat run --network polygonZkEVMMain scripts/deploy.ts", 59 | "deploy:hecomain": "npx hardhat run --network hecoMain scripts/deploy.ts", 60 | "deploy:fantomtestnet": "npx hardhat run --network fantomTestnet scripts/deploy.ts", 61 | "deploy:fantommain": "npx hardhat run --network fantomMain scripts/deploy.ts", 62 | "deploy:fuji": "npx hardhat run --network fuji scripts/deploy.ts", 63 | "deploy:avalanche": "npx hardhat run --network avalanche scripts/deploy.ts", 64 | "deploy:chiado": "npx hardhat run --network chiado scripts/deploy.ts", 65 | "deploy:gnosis": "npx hardhat run --network gnosis scripts/deploy.ts", 66 | "deploy:moonbasealpha": "npx hardhat run --network moonbaseAlpha scripts/deploy.ts", 67 | "deploy:moonriver": "npx hardhat run --network moonriver scripts/deploy.ts", 68 | "deploy:moonbeam": "npx hardhat run --network moonbeam scripts/deploy.ts", 69 | "deploy:alfajores": "npx hardhat run --network alfajores scripts/deploy.ts", 70 | "deploy:celo": "npx hardhat run --network celo scripts/deploy.ts", 71 | "deploy:auroratestnet": "npx hardhat run --network auroraTestnet scripts/deploy.ts", 72 | "deploy:auroramain": "npx hardhat run --network auroraMain scripts/deploy.ts", 73 | "deploy:harmonytestnet": "npx hardhat run --network harmonyTestnet scripts/deploy.ts", 74 | "deploy:harmonymain": "npx hardhat run --network harmonyMain scripts/deploy.ts", 75 | "deploy:spark": "npx hardhat run --network spark scripts/deploy.ts", 76 | "deploy:fuse": "npx hardhat run --network fuse scripts/deploy.ts", 77 | "deploy:cronostestnet": "npx hardhat run --network cronosTestnet scripts/deploy.ts", 78 | "deploy:cronosmain": "npx hardhat run --network cronosMain scripts/deploy.ts", 79 | "deploy:evmostestnet": "npx hardhat run --network evmosTestnet scripts/deploy.ts", 80 | "deploy:evmosmain": "npx hardhat run --network evmosMain scripts/deploy.ts", 81 | "deploy:bobatestnet": "npx hardhat run --network bobaTestnet scripts/deploy.ts", 82 | "deploy:bobamain": "npx hardhat run --network bobaMain scripts/deploy.ts", 83 | "deploy:cantotestnet": "npx hardhat run --network cantoTestnet scripts/deploy.ts", 84 | "deploy:cantomain": "npx hardhat run --network cantoMain scripts/deploy.ts", 85 | "deploy:basetestnet": "npx hardhat run --network baseTestnet scripts/deploy.ts", 86 | "deploy:basesepolia": "npx hardhat run --network baseSepolia scripts/deploy.ts", 87 | "deploy:basemain": "npx hardhat run --network baseMain scripts/deploy.ts", 88 | "deploy:mantletestnet": "npx hardhat run --network mantleTestnet scripts/deploy.ts", 89 | "deploy:mantlemain": "npx hardhat run --network mantleMain scripts/deploy.ts", 90 | "deploy:filecointestnet": "npx hardhat run --network filecoinTestnet scripts/deploy.ts", 91 | "deploy:filecoinmain": "npx hardhat run --network filecoinMain scripts/deploy.ts", 92 | "deploy:scrolltestnet": "npx hardhat run --network scrollTestnet scripts/deploy.ts", 93 | "deploy:scrollmain": "npx hardhat run --network scrollMain scripts/deploy.ts", 94 | "deploy:lineatestnet": "npx hardhat run --network lineaTestnet scripts/deploy.ts", 95 | "deploy:lineamain": "npx hardhat run --network lineaMain scripts/deploy.ts", 96 | "deploy:shimmerevmtestnet": "npx hardhat run --network shimmerEVMTestnet scripts/deploy.ts", 97 | "deploy:zoratestnet": "npx hardhat run --network zoraTestnet scripts/deploy.ts", 98 | "deploy:zoramain": "npx hardhat run --network zoraMain scripts/deploy.ts", 99 | "deploy:luksotestnet": "npx hardhat run --network luksoTestnet scripts/deploy.ts", 100 | "deploy:luksomain": "npx hardhat run --network luksoMain scripts/deploy.ts", 101 | "deploy:mantatestnet": "npx hardhat run --network mantaTestnet scripts/deploy.ts", 102 | "deploy:mantamain": "npx hardhat run --network mantaMain scripts/deploy.ts", 103 | "deploy:shardeumtestnet": "npx hardhat run --network shardeumTestnet scripts/deploy.ts", 104 | "deploy:artheratestnet": "npx hardhat run --network artheraTestnet scripts/deploy.ts", 105 | "deploy:frametestnet": "npx hardhat run --network frameTestnet scripts/deploy.ts", 106 | "deploy:endurancetestnet": "npx hardhat run --network enduranceTestnet scripts/deploy.ts", 107 | "deploy:opendurancetestnet": "npx hardhat run --network openduranceTestnet scripts/deploy.ts", 108 | "deploy:endurancemain": "npx hardhat run --network enduranceMain scripts/deploy.ts", 109 | "deploy:blasttestnet": "npx hardhat run --network blastTestnet scripts/deploy.ts", 110 | "deploy:blastmain": "npx hardhat run --network blastMain scripts/deploy.ts", 111 | "deploy:kromatestnet": "npx hardhat run --network kromaTestnet scripts/deploy.ts", 112 | "deploy:kromamain": "npx hardhat run --network kromaMain scripts/deploy.ts", 113 | "deploy:dostestnet": "npx hardhat run --network dosTestnet scripts/deploy.ts", 114 | "deploy:dosmain": "npx hardhat run --network dosMain scripts/deploy.ts", 115 | "deploy:fraxtaltestnet": "npx hardhat run --network fraxtalTestnet scripts/deploy.ts", 116 | "deploy:fraxtalmain": "npx hardhat run --network fraxtalMain scripts/deploy.ts", 117 | "deploy:kavamain": "npx hardhat run --network kavaMain scripts/deploy.ts", 118 | "deploy:metistestnet": "npx hardhat run --network metisTestnet scripts/deploy.ts", 119 | "deploy:metismain": "npx hardhat run --network metisMain scripts/deploy.ts", 120 | "deploy:modetestnet": "npx hardhat run --network modeTestnet scripts/deploy.ts", 121 | "deploy:modemain": "npx hardhat run --network modeMain scripts/deploy.ts", 122 | "deploy:seidevnet": "npx hardhat run --network seiDevnet scripts/deploy.ts", 123 | "deploy:seitestnet": "npx hardhat run --network seiTestnet scripts/deploy.ts", 124 | "deploy:seimain": "npx hardhat run --network seiMain scripts/deploy.ts", 125 | "deploy:xlayertestnet": "npx hardhat run --network xlayerTestnet scripts/deploy.ts", 126 | "deploy:xlayermain": "npx hardhat run --network xlayerMain scripts/deploy.ts", 127 | "deploy:bobtestnet": "npx hardhat run --network bobTestnet scripts/deploy.ts", 128 | "deploy:bobmain": "npx hardhat run --network bobMain scripts/deploy.ts", 129 | "deploy:coretestnet": "npx hardhat run --network coreTestnet scripts/deploy.ts", 130 | "deploy:coremain": "npx hardhat run --network coreMain scripts/deploy.ts", 131 | "deploy:telostestnet": "npx hardhat run --network telosTestnet scripts/deploy.ts", 132 | "deploy:telosmain": "npx hardhat run --network telosMain scripts/deploy.ts", 133 | "deploy:rootstocktestnet": "npx hardhat run --network rootstockTestnet scripts/deploy.ts", 134 | "deploy:rootstockmain": "npx hardhat run --network rootstockMain scripts/deploy.ts", 135 | "deploy:chiliztestnet": "npx hardhat run --network chilizTestnet scripts/deploy.ts", 136 | "deploy:chilizmain": "npx hardhat run --network chilizMain scripts/deploy.ts", 137 | "deploy:taraxatestnet": "npx hardhat run --network taraxaTestnet scripts/deploy.ts", 138 | "deploy:taraxamain": "npx hardhat run --network taraxaMain scripts/deploy.ts", 139 | "deploy:gravityalphatestnet": "npx hardhat run --network gravityAlphaTestnet scripts/deploy.ts", 140 | "deploy:gravityalphamain": "npx hardhat run --network gravityAlphaMain scripts/deploy.ts", 141 | "deploy:taikotestnet": "npx hardhat run --network taikoTestnet scripts/deploy.ts", 142 | "deploy:taikomain": "npx hardhat run --network taikoMain scripts/deploy.ts", 143 | "deploy:zetachaintestnet": "npx hardhat run --network zetaChainTestnet scripts/deploy.ts", 144 | "deploy:zetachainmain": "npx hardhat run --network zetaChainMain scripts/deploy.ts", 145 | "deploy:5irechaintestnet": "npx hardhat run --network 5ireChainTestnet scripts/deploy.ts", 146 | "deploy:5irechainmain": "npx hardhat run --network 5ireChainMain scripts/deploy.ts", 147 | "deploy:sapphiretestnet": "npx hardhat run --network sapphireTestnet scripts/deploy.ts", 148 | "deploy:sapphiremain": "npx hardhat run --network sapphireMain scripts/deploy.ts", 149 | "deploy:worldchaintestnet": "npx hardhat run --network worldChainTestnet scripts/deploy.ts", 150 | "deploy:worldchainmain": "npx hardhat run --network worldChainMain scripts/deploy.ts", 151 | "deploy:plumetestnet": "npx hardhat run --network plumeTestnet scripts/deploy.ts", 152 | "deploy:plumemain": "npx hardhat run --network plumeMain scripts/deploy.ts", 153 | "deploy:unichaintestnet": "npx hardhat run --network unichainTestnet scripts/deploy.ts", 154 | "deploy:unichainmain": "npx hardhat run --network unichainMain scripts/deploy.ts", 155 | "deploy:xdctestnet": "npx hardhat run --network xdcTestnet scripts/deploy.ts", 156 | "deploy:xdcmain": "npx hardhat run --network xdcMain scripts/deploy.ts", 157 | "deploy:sxtestnet": "npx hardhat run --network sxTestnet scripts/deploy.ts", 158 | "deploy:sxmain": "npx hardhat run --network sxMain scripts/deploy.ts", 159 | "deploy:lisktestnet": "npx hardhat run --network liskTestnet scripts/deploy.ts", 160 | "deploy:liskmain": "npx hardhat run --network liskMain scripts/deploy.ts", 161 | "deploy:metall2testnet": "npx hardhat run --network metalL2Testnet scripts/deploy.ts", 162 | "deploy:metall2main": "npx hardhat run --network metalL2Main scripts/deploy.ts", 163 | "deploy:superseedtestnet": "npx hardhat run --network superseedTestnet scripts/deploy.ts", 164 | "deploy:superseedmain": "npx hardhat run --network superseedMain scripts/deploy.ts", 165 | "deploy:storytestnet": "npx hardhat run --network storyTestnet scripts/deploy.ts", 166 | "deploy:sonictestnet": "npx hardhat run --network sonicTestnet scripts/deploy.ts", 167 | "deploy:sonicmain": "npx hardhat run --network sonicMain scripts/deploy.ts", 168 | "deploy:flowtestnet": "npx hardhat run --network flowTestnet scripts/deploy.ts", 169 | "deploy:flowmain": "npx hardhat run --network flowMain scripts/deploy.ts", 170 | "deploy:inktestnet": "npx hardhat run --network inkTestnet scripts/deploy.ts", 171 | "deploy:inkmain": "npx hardhat run --network inkMain scripts/deploy.ts", 172 | "deploy:morphtestnet": "npx hardhat run --network morphTestnet scripts/deploy.ts", 173 | "deploy:morphmain": "npx hardhat run --network morphMain scripts/deploy.ts", 174 | "deploy:shapetestnet": "npx hardhat run --network shapeTestnet scripts/deploy.ts", 175 | "deploy:shapemain": "npx hardhat run --network shapeMain scripts/deploy.ts", 176 | "deploy:etherlinktestnet": "npx hardhat run --network etherlinkTestnet scripts/deploy.ts", 177 | "deploy:etherlinkmain": "npx hardhat run --network etherlinkMain scripts/deploy.ts", 178 | "deploy:soneiumtestnet": "npx hardhat run --network soneiumTestnet scripts/deploy.ts", 179 | "deploy:soneiummain": "npx hardhat run --network soneiumMain scripts/deploy.ts", 180 | "deploy:swelltestnet": "npx hardhat run --network swellTestnet scripts/deploy.ts", 181 | "deploy:swellmain": "npx hardhat run --network swellMain scripts/deploy.ts", 182 | "deploy:hemitestnet": "npx hardhat run --network hemiTestnet scripts/deploy.ts", 183 | "deploy:hemimain": "npx hardhat run --network hemiMain scripts/deploy.ts", 184 | "deploy:berachaintestnet": "npx hardhat run --network berachainTestnet scripts/deploy.ts", 185 | "deploy:berachainmain": "npx hardhat run --network berachainMain scripts/deploy.ts", 186 | "deploy:monadtestnet": "npx hardhat run --network monadTestnet scripts/deploy.ts", 187 | "deploy:corntestnet": "npx hardhat run --network cornTestnet scripts/deploy.ts", 188 | "deploy:cornmain": "npx hardhat run --network cornMain scripts/deploy.ts", 189 | "deploy:arenaztestnet": "npx hardhat run --network arenazTestnet scripts/deploy.ts", 190 | "deploy:arenazmain": "npx hardhat run --network arenazMain scripts/deploy.ts", 191 | "deploy:iotextestnet": "npx hardhat run --network iotexTestnet scripts/deploy.ts", 192 | "deploy:iotexmain": "npx hardhat run --network iotexMain scripts/deploy.ts", 193 | "deploy:hychaintestnet": "npx hardhat run --network hychainTestnet scripts/deploy.ts", 194 | "deploy:hychainmain": "npx hardhat run --network hychainMain scripts/deploy.ts", 195 | "deploy:zircuittestnet": "npx hardhat run --network zircuitTestnet scripts/deploy.ts", 196 | "deploy:zircuitmain": "npx hardhat run --network zircuitMain scripts/deploy.ts", 197 | "deploy:megaethtestnet": "npx hardhat run --network megaETHTestnet scripts/deploy.ts", 198 | "deploy:bitlayertestnet": "npx hardhat run --network bitlayerTestnet scripts/deploy.ts", 199 | "deploy:bitlayermain": "npx hardhat run --network bitlayerMain scripts/deploy.ts", 200 | "deploy:ronintestnet": "npx hardhat run --network roninTestnet scripts/deploy.ts", 201 | "deploy:roninmain": "npx hardhat run --network roninMain scripts/deploy.ts", 202 | "prettier:check": "npx prettier -c \"**/*.{js,ts,md,sol,json,yml,yaml}\"", 203 | "prettier:fix": "npx prettier -w \"**/*.{js,ts,md,sol,json,yml,yaml}\"", 204 | "solhint:check": "npx solhint \"contracts/**/*.sol\"", 205 | "solhint:fix": "npx solhint \"contracts/**/*.sol\" --fix", 206 | "lint:check": "pnpm prettier:check && pnpm solhint:check && npx eslint .", 207 | "lint:fix": "pnpm prettier:fix && pnpm solhint:fix && npx eslint . --fix" 208 | }, 209 | "devDependencies": { 210 | "@eslint/js": "^9.28.0", 211 | "@nomicfoundation/hardhat-chai-matchers": "^2.0.8", 212 | "@nomicfoundation/hardhat-ethers": "^3.0.8", 213 | "@nomicfoundation/hardhat-ledger": "^1.1.0", 214 | "@nomicfoundation/hardhat-network-helpers": "^1.0.12", 215 | "@nomicfoundation/hardhat-verify": "^2.0.14", 216 | "@openzeppelin/contracts": "^5.3.0", 217 | "@typechain/ethers-v6": "^0.5.1", 218 | "@typechain/hardhat": "^9.1.0", 219 | "@types/chai": "^4.3.20", 220 | "@types/mocha": "^10.0.10", 221 | "@types/node": "^22.15.30", 222 | "chai": "^4.5.0", 223 | "eslint": "^9.28.0", 224 | "eslint-config-prettier": "^10.1.5", 225 | "ethers": "^6.14.3", 226 | "hardhat": "^2.24.2", 227 | "hardhat-abi-exporter": "^2.11.0", 228 | "hardhat-contract-sizer": "^2.10.0", 229 | "hardhat-gas-reporter": "^2.3.0", 230 | "prettier": "^3.5.3", 231 | "prettier-plugin-solidity": "^2.0.0", 232 | "solhint": "^5.1.0", 233 | "solidity-coverage": "^0.8.16", 234 | "ts-node": "^10.9.2", 235 | "typechain": "^8.3.2", 236 | "typescript": "^5.8.3", 237 | "typescript-eslint": "^8.33.1", 238 | "xdeployer": "^3.1.15" 239 | }, 240 | "pnpm": { 241 | "onlyBuiltDependencies": [ 242 | "keccak", 243 | "node-hid", 244 | "secp256k1", 245 | "usb" 246 | ] 247 | } 248 | } 249 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseBranches": ["main"], 3 | "labels": ["dependencies"], 4 | "assignees": ["pcaversaccio"], 5 | "separateMajorMinor": false, 6 | "extends": [ 7 | ":preserveSemverRanges", 8 | "group:all", 9 | "schedule:monthly", 10 | ":maintainLockFilesMonthly" 11 | ], 12 | "lockFileMaintenance": { 13 | "extends": ["group:all"], 14 | "commitMessageAction": "Update" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scripts/deploy.ts: -------------------------------------------------------------------------------- 1 | import hre from "hardhat"; 2 | 3 | // Colour codes for terminal prints 4 | const RESET = "\x1b[0m"; 5 | const GREEN = "\x1b[32m"; 6 | 7 | function delay(ms: number) { 8 | return new Promise((resolve) => setTimeout(resolve, ms)); 9 | } 10 | 11 | async function main() { 12 | const create = await hre.ethers.deployContract("Create"); 13 | 14 | await create.waitForDeployment(); 15 | const createAddress = await create.getAddress(); 16 | 17 | console.log("Create deployed to: " + `${GREEN}${createAddress}${RESET}\n`); 18 | 19 | console.log( 20 | "Waiting 30 seconds before beginning the contract verification to allow the block explorer to index the contract...\n", 21 | ); 22 | await delay(30000); // Wait for 30 seconds before verifying the contract 23 | 24 | await hre.run("verify:verify", { 25 | address: createAddress, 26 | }); 27 | } 28 | 29 | main().catch((error) => { 30 | console.error(error); 31 | process.exitCode = 1; 32 | }); 33 | -------------------------------------------------------------------------------- /slither.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "compile_force_framework": "hardhat", 3 | "hardhat_ignore_compile": false, 4 | "detectors_to_exclude": "pragma,solc-version,locked-ether,assembly", 5 | "fail_on": "none", 6 | "exclude_informational": false, 7 | "exclude_low": false, 8 | "exclude_medium": false, 9 | "exclude_high": false, 10 | "filter_paths": "contracts/mocks|@openzeppelin" 11 | } 12 | -------------------------------------------------------------------------------- /test/Create.test.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | import { ContractDeployTransaction } from "ethers"; 3 | import hre from "hardhat"; 4 | import { SignerWithAddress } from "@nomicfoundation/hardhat-ethers/signers"; 5 | import { Create } from "../typechain-types"; 6 | 7 | describe("Create", function () { 8 | const name = "MyToken"; 9 | const symbol = "MTKN"; 10 | const initialBalance = 100; 11 | 12 | let deployerAccount: SignerWithAddress; 13 | 14 | let create: Create; 15 | let createAddr: string; 16 | 17 | let creationBytecode: ContractDeployTransaction; 18 | 19 | beforeEach(async function () { 20 | [deployerAccount] = await hre.ethers.getSigners(); 21 | 22 | create = await hre.ethers.deployContract("Create", deployerAccount); 23 | await create.waitForDeployment(); 24 | createAddr = await create.getAddress(); 25 | 26 | const ERC20Mock = await hre.ethers.getContractFactory("ERC20Mock"); 27 | creationBytecode = await ERC20Mock.getDeployTransaction( 28 | name, 29 | symbol, 30 | deployerAccount, 31 | initialBalance, 32 | ); 33 | }); 34 | 35 | describe("computeAddress", function () { 36 | it("computes the correct contract address - case 1: nonce 0x00", async function () { 37 | const nonce = 0x00; 38 | const onChainComputed = await create.computeAddress( 39 | deployerAccount.address, 40 | nonce, 41 | ); 42 | const offChainComputed = hre.ethers.getCreateAddress({ 43 | from: deployerAccount.address, 44 | nonce: nonce, 45 | }); 46 | expect(onChainComputed).to.equal(offChainComputed); 47 | }); 48 | 49 | it("computes the correct contract address - case 2: nonce <= 0x7f", async function () { 50 | const nonce = 0x7f; 51 | const onChainComputed = await create.computeAddress(createAddr, nonce); 52 | const offChainComputed = hre.ethers.getCreateAddress({ 53 | from: createAddr, 54 | nonce: nonce, 55 | }); 56 | expect(onChainComputed).to.equal(offChainComputed); 57 | }); 58 | 59 | it("computes the correct contract address - case 3: nonce <= uint8", async function () { 60 | const nonce = 0xff; 61 | const onChainComputed = await create.computeAddress(createAddr, nonce); 62 | const offChainComputed = hre.ethers.getCreateAddress({ 63 | from: createAddr, 64 | nonce: nonce, 65 | }); 66 | expect(onChainComputed).to.equal(offChainComputed); 67 | }); 68 | 69 | it("computes the correct contract address - case 4: nonce <= uint16", async function () { 70 | const nonce = 0xffff; 71 | const onChainComputed = await create.computeAddress(createAddr, nonce); 72 | const offChainComputed = hre.ethers.getCreateAddress({ 73 | from: createAddr, 74 | nonce: nonce, 75 | }); 76 | expect(onChainComputed).to.equal(offChainComputed); 77 | }); 78 | 79 | it("computes the correct contract address - case 5: nonce <= uint24", async function () { 80 | const nonce = 0xffffff; 81 | const onChainComputed = await create.computeAddress(createAddr, nonce); 82 | const offChainComputed = hre.ethers.getCreateAddress({ 83 | from: createAddr, 84 | nonce: nonce, 85 | }); 86 | expect(onChainComputed).to.equal(offChainComputed); 87 | }); 88 | 89 | it("computes the correct contract address - case 6: nonce <= uint32", async function () { 90 | const nonce = 0xffffffff; 91 | const onChainComputed = await create.computeAddress(createAddr, nonce); 92 | const offChainComputed = hre.ethers.getCreateAddress({ 93 | from: createAddr, 94 | nonce: nonce, 95 | }); 96 | expect(onChainComputed).to.equal(offChainComputed); 97 | }); 98 | 99 | it("computes the correct contract address - case 7: nonce <= uint40", async function () { 100 | const nonce = 0xffffffffff; 101 | const onChainComputed = await create.computeAddress(createAddr, nonce); 102 | const offChainComputed = hre.ethers.getCreateAddress({ 103 | from: createAddr, 104 | nonce: nonce, 105 | }); 106 | expect(onChainComputed).to.equal(offChainComputed); 107 | }); 108 | 109 | it("computes the correct contract address - case 8: nonce <= uint48", async function () { 110 | const nonce = 0xffffffffffff; 111 | const onChainComputed = await create.computeAddress(createAddr, nonce); 112 | const offChainComputed = hre.ethers.getCreateAddress({ 113 | from: createAddr, 114 | nonce: nonce, 115 | }); 116 | expect(onChainComputed).to.equal(offChainComputed); 117 | }); 118 | 119 | it("computes the correct contract address - case 9: nonce <= uint56", async function () { 120 | const nonce = 0xffffffffffffffn; 121 | const onChainComputed = await create.computeAddress(createAddr, nonce); 122 | const offChainComputed = hre.ethers.getCreateAddress({ 123 | from: createAddr, 124 | nonce: nonce, 125 | }); 126 | expect(onChainComputed).to.equal(offChainComputed); 127 | }); 128 | 129 | it("computes the correct contract address - case 10: nonce < uint64", async function () { 130 | const nonce = 0xfffffffffffffffen; 131 | const onChainComputed = await create.computeAddress(createAddr, nonce); 132 | const offChainComputed = hre.ethers.getCreateAddress({ 133 | from: createAddr, 134 | nonce: nonce, 135 | }); 136 | expect(onChainComputed).to.equal(offChainComputed); 137 | }); 138 | 139 | it("reverts if the nonce is larger than type(uint64).max - 1", async function () { 140 | await expect(create.computeAddress(createAddr, 0xffffffffffffffffn)) 141 | .to.be.revertedWithCustomError(create, "InvalidNonceValue") 142 | .withArgs(createAddr); 143 | }); 144 | }); 145 | 146 | describe("deploy", function () { 147 | it("deploys an ERC20Mock with correct balances", async function () { 148 | const offChainComputed = hre.ethers.getCreateAddress({ 149 | from: createAddr, 150 | nonce: 1, 151 | }); 152 | expect(await create.deploy(0, creationBytecode.data)) 153 | .to.emit(create, "ContractCreation") 154 | .withArgs(offChainComputed); 155 | const erc20 = await hre.ethers.getContractAt( 156 | "ERC20Mock", 157 | offChainComputed, 158 | ); 159 | expect(await erc20.balanceOf(deployerAccount.address)).to.equal( 160 | initialBalance, 161 | ); 162 | }); 163 | 164 | it("deploys a contract with funds deposited in the factory", async function () { 165 | const deposit = hre.ethers.parseEther("2"); 166 | await deployerAccount.sendTransaction({ to: createAddr, value: deposit }); 167 | expect(await hre.ethers.provider.getBalance(createAddr)).to.equal( 168 | deposit, 169 | ); 170 | const offChainComputed = hre.ethers.getCreateAddress({ 171 | from: createAddr, 172 | nonce: 1, 173 | }); 174 | expect(await create.deploy(deposit, creationBytecode.data)) 175 | .to.emit(create, "ContractCreation") 176 | .withArgs(offChainComputed); 177 | expect(await hre.ethers.provider.getBalance(offChainComputed)).to.equal( 178 | deposit, 179 | ); 180 | }); 181 | 182 | it("fails deploying a contract with invalid constructor bytecode", async function () { 183 | await expect(create.deploy(0, "0x01")) 184 | .to.be.revertedWithCustomError(create, "Failed") 185 | .withArgs(createAddr); 186 | }); 187 | 188 | it("fails deploying a contract if the bytecode length is zero", async function () { 189 | await expect(create.deploy(0, "0x")) 190 | .to.be.revertedWithCustomError(create, "ZeroBytecodeLength") 191 | .withArgs(createAddr); 192 | }); 193 | 194 | it("fails deploying a contract if factory contract does not have sufficient balance", async function () { 195 | await expect(create.deploy(1, creationBytecode.data)) 196 | .to.be.revertedWithCustomError(create, "InsufficientBalance") 197 | .withArgs(createAddr); 198 | }); 199 | }); 200 | }); 201 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2021", 4 | "module": "commonjs", 5 | "allowJs": true, 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "outDir": "dist", 9 | "declaration": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "skipLibCheck": true, 12 | "resolveJsonModule": true 13 | }, 14 | "include": [ 15 | "./scripts/**/*.js", 16 | "./scripts/**/*.ts", 17 | "./test/**/*.js", 18 | "./test/**/*.ts", 19 | "./typechain-types/**/*.ts" 20 | ], 21 | "files": ["./hardhat.config.ts", "eslint.config.js", ".solcover.js"] 22 | } 23 | --------------------------------------------------------------------------------