├── .gitignore ├── .gitmodules ├── Dockerfile ├── Makefile ├── README.md ├── benchmarks ├── 0.8.20-via-ir │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── 0.8.20 │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── 0.8.21-via-ir │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── 0.8.21 │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── 0.8.22-via-ir │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── 0.8.22 │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── 0.8.23-via-ir │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── 0.8.23 │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── 0.8.24-via-ir │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── 0.8.24 │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── 0.8.25-via-ir │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── 0.8.25 │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── 0.8.26-via-ir │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md └── 0.8.26 │ ├── ERC1155.md │ ├── ERC20.md │ └── ERC721.md ├── codegen.sh ├── data.json ├── foundry.toml ├── gas-snapshots ├── 0-8-20 ├── 0-8-20-via-ir ├── 0-8-21 ├── 0-8-21-via-ir ├── 0-8-22 ├── 0-8-22-via-ir ├── 0-8-23 ├── 0-8-23-via-ir ├── 0-8-24 ├── 0-8-24-via-ir ├── 0-8-25 ├── 0-8-25-via-ir ├── 0-8-26 └── 0-8-26-via-ir ├── generator ├── .gitignore ├── Package.resolved ├── Package.swift └── Sources │ ├── Cmd │ └── Solbench.swift │ ├── SolbenchKit │ ├── Common.swift │ ├── ERC20.swift │ ├── GasSnapshots.swift │ └── SolidityVersion.swift │ └── SolbenchKitTests │ └── CommonTests.swift ├── remappings.txt ├── requirements.txt ├── scripts ├── common.py ├── erc1155.py ├── erc20.py ├── erc721.py ├── gen_json.py ├── gyb.py └── main.py ├── src ├── ERC1155_OZ.sol ├── ERC1155_Solmate.sol ├── ERC20_Maple.sol ├── ERC20_OZ.sol ├── ERC20_OZPermit.sol ├── ERC20_Solmate.sol ├── ERC721_A.sol ├── ERC721_B.sol ├── ERC721_K.sol ├── ERC721_OZ.sol ├── ERC721_OZConsecutive.sol ├── ERC721_OZEnumerable.sol ├── ERC721_Solady.sol ├── ERC721_Solmate.sol └── test │ ├── ERC1155.t.sol │ ├── ERC20.t.sol │ └── ERC721.t.sol ├── templates ├── ERC1155.t.sol.gyb ├── ERC20.t.sol.gyb └── ERC721.t.sol.gyb └── test-cases.yml /.gitignore: -------------------------------------------------------------------------------- 1 | cache/ 2 | out/ 3 | __pycache__/ 4 | .vscode -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/ds-test"] 2 | path = lib/ds-test 3 | url = https://github.com/dapphub/ds-test 4 | [submodule "lib/forge-std"] 5 | path = lib/forge-std 6 | url = https://github.com/brockelmore/forge-std 7 | [submodule "lib/openzeppelin-contracts"] 8 | path = lib/openzeppelin-contracts 9 | url = https://github.com/OpenZeppelin/openzeppelin-contracts 10 | [submodule "lib/ERC721A"] 11 | path = lib/ERC721A 12 | url = https://github.com/chiru-labs/ERC721A 13 | [submodule "lib/solmate"] 14 | path = lib/solmate 15 | url = https://github.com/transmissions11/solmate 16 | [submodule "lib/ERC721B"] 17 | path = lib/ERC721B 18 | url = https://github.com/beskay/ERC721B 19 | [submodule "lib/ERC721K"] 20 | path = lib/ERC721K 21 | url = https://github.com/kadenzipfel/ERC721K 22 | [submodule "lib/maple-erc20"] 23 | path = lib/maple-erc20 24 | url = https://github.com/maple-labs/erc20.git 25 | [submodule "lib/solady"] 26 | path = lib/solady 27 | url = https://github.com/Vectorized/solady 28 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM swift:5.9 2 | 3 | WORKDIR /app 4 | 5 | COPY generator/Sources Sources 6 | COPY generator/Package.resolved Pacakge.resolved 7 | COPY generator/Package.swift Package.swift 8 | 9 | RUN swift package resolve 10 | RUN swift build -c release 11 | 12 | ENTRYPOINT ["/app/.build/release/solbench"] -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Generate solidity files using the gyb templates in ./templates and the data in test-cases.yml 2 | .PHONY: codegen 3 | codegen: 4 | ./codegen.sh 5 | 6 | # Build and run tests, output the results to the ./gas-snapshots dir 7 | .PHONY: snapshot 8 | snapshot: 9 | forge snapshot --force --optimize --use 0.8.20 --snap gas-snapshots/0-8-20 10 | forge snapshot --force --optimize --use 0.8.20 --snap gas-snapshots/0-8-20-via-ir --via-ir 11 | forge snapshot --force --optimize --use 0.8.21 --snap gas-snapshots/0-8-21 12 | forge snapshot --force --optimize --use 0.8.21 --snap gas-snapshots/0-8-21-via-ir --via-ir 13 | forge snapshot --force --optimize --use 0.8.22 --snap gas-snapshots/0-8-22 14 | forge snapshot --force --optimize --use 0.8.22 --snap gas-snapshots/0-8-22-via-ir --via-ir 15 | forge snapshot --force --optimize --use 0.8.23 --snap gas-snapshots/0-8-23 16 | forge snapshot --force --optimize --use 0.8.23 --snap gas-snapshots/0-8-23-via-ir --via-ir 17 | forge snapshot --force --optimize --use 0.8.24 --snap gas-snapshots/0-8-24 18 | forge snapshot --force --optimize --use 0.8.24 --snap gas-snapshots/0-8-24-via-ir --via-ir 19 | forge snapshot --force --optimize --use 0.8.25 --snap gas-snapshots/0-8-25 20 | forge snapshot --force --optimize --use 0.8.25 --snap gas-snapshots/0-8-25-via-ir --via-ir 21 | forge snapshot --force --optimize --use 0.8.26 --snap gas-snapshots/0-8-26 22 | forge snapshot --force --optimize --use 0.8.26 --snap gas-snapshots/0-8-26-via-ir --via-ir 23 | 24 | # Generate a structured json from gas-snapshots and outputs to ./data.json 25 | .PHONY: json 26 | json: 27 | python scripts/gen_json.py 28 | 29 | # Generate readme files in benchmarks/ 30 | .PHONY: readme 31 | readme: 32 | python scripts/main.py 33 | 34 | # run swift generator 35 | .PHONY: readme-swift 36 | readme-swift: 37 | swift run --package-path generator solbench erc20 data.json benchmarks 38 | 39 | # build swift generator docker image 40 | .PHONY: build-generator-docker 41 | build-solbench: 42 | docker build . -t solbench 43 | 44 | # run solbench image 45 | .PHONY: run-generator-docker 46 | run-generator-docker: 47 | 48 | docker run -v ./data.json:/data.json -v ./benchmarks:/benchmarks solbench erc20 /data.json /benchmarks 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Solidity Benchmarks 2 | 3 | Benchmarks for popular implementations of contract standards. 4 | 5 | > ⚠️ The gas usage shown in the benchmarks doesn't take into account the 21k gas added to every ethereum transaction 6 | 7 | - [ERC20 0.8.26](benchmarks/0.8.26/ERC20.md) 8 | - [ERC721 0.8.26](benchmarks/0.8.26/ERC721.md) 9 | - [ERC1155 0.8.26](benchmarks/0.8.26/ERC1155.md) 10 | 11 | You can see benchmarks for different compiler versions on [`benchmarks/`](benchmarks) 12 | 13 | The file [`data.json`](data.json) provides a json format of all the data used in the benchmarks. That file is generated by running the command `make json`. 14 | 15 | ## Method used 16 | 17 | We create a minimal implementation of each contract that uses the specific implementation as a base. Then for each of the methods we want to benchmark, we create a test contract that set the environment in the `setUp` function and each test only runs the specific function we're benchmarking, trying to reduce the noise as much as possible. 18 | 19 | The gas usage shown here is not 100% accurate, but it's good enough to be able to compare the gas usage between the implementations. 20 | 21 | All tests are generated using the template files in [`templates`](templates) 22 | 23 | All tables in the readmes are generated using the scripts in [`scripts`](scripts) 24 | 25 | ## Contributing 26 | 27 | There are many ways to contribute to this project 28 | 29 | - Add a snapshot for the latest solc version 30 | - Add or suggest a contract implementation (the instructions for adding are below) 31 | - Update a contract implementation 32 | - Enhance the codegen scripts 33 | 34 | ### Setup for local development 35 | 36 | - Install foundry http://getfoundry.sh 37 | - You'll need python 3 installed to run the scripts under the `scripts` folder 38 | - Install the python dependencies `pip install -r requirements.txt` 39 | - `git clone --recurse-submodules https://github.com/alephao/solidity-benchmarks.git` 40 | 41 | ### How to add a contract 42 | 43 | 1. Create a minimal implementation on `src/`, the contract name and file name should follow the convention `_`. 44 | 2. Implement the common interface that is in other files of the same contract type (for ERC721 for example, it's `mint` and `safeMint` functions) 45 | 3. Add an entry to the `contracts..variations` property on [test-cases.yml](test-cases.yml), following the examples there. 46 | 4. Add an entry to [scripts/.py](scripts)'s `variants` var following the examples there. It should map the variant name you used in the contract like `ERC721_` to the name you want to appear on the table. E.g.: 47 | 5. In case you added an ERC721 that's also ERC2309 compliant, add a another contract in the same file following the convention `__ERC2309`, and add an entry to the `contracts.ERC721.ERC2309Variations` in the [test-cases.yml](test-cases.yml) 48 | 49 | ```python 50 | variations = { 51 | "OZ": "OpenZeppelin", 52 | "OZEnumerable": "OpenZeppelin Enumerable", 53 | "OZConsecutive": "OpenZeppelin Consecutive", 54 | "Solady": "Solady", 55 | "Solmate": "Solmate", 56 | "A": "ERC721A", 57 | "B": "ERC721B", 58 | "K": "ERC721K", 59 | } 60 | ``` 61 | 62 | 63 | 5. Run the following commands: 64 | 65 | ```console 66 | make codegen 67 | make snapshot 68 | make readme 69 | make json 70 | ``` 71 | 72 | 73 | 6. Add the contract to the list at the top of the `.md`. (If you added a new ERC721, update the list on top of [`ERC721.md`](benchmarks/0.8.26/ERC721.md)) 74 | 75 | ### Quick links 76 | 77 | **ERC20** 78 | 79 | * [0.8.20](benchmarks/0.8.20/ERC20.md) or [0.8.20-ir](benchmarks/0.8.20-via-ir/ERC20.md) 80 | * [0.8.21](benchmarks/0.8.21/ERC20.md) or [0.8.21-ir](benchmarks/0.8.21-via-ir/ERC20.md) 81 | * [0.8.22](benchmarks/0.8.22/ERC20.md) or [0.8.22-ir](benchmarks/0.8.22-via-ir/ERC20.md) 82 | * [0.8.23](benchmarks/0.8.23/ERC20.md) or [0.8.23-ir](benchmarks/0.8.23-via-ir/ERC20.md) 83 | * [0.8.24](benchmarks/0.8.24/ERC20.md) or [0.8.24-ir](benchmarks/0.8.24-via-ir/ERC20.md) 84 | * [0.8.25](benchmarks/0.8.25/ERC20.md) or [0.8.25-ir](benchmarks/0.8.25-via-ir/ERC20.md) 85 | * [0.8.26](benchmarks/0.8.26/ERC20.md) or [0.8.26-ir](benchmarks/0.8.26-via-ir/ERC20.md) 86 | 87 | 88 | **ERC721** 89 | 90 | * [0.8.20](benchmarks/0.8.20/ERC721.md) or [0.8.20-ir](benchmarks/0.8.20-via-ir/ERC721.md) 91 | * [0.8.21](benchmarks/0.8.21/ERC721.md) or [0.8.21-ir](benchmarks/0.8.21-via-ir/ERC721.md) 92 | * [0.8.22](benchmarks/0.8.22/ERC721.md) or [0.8.22-ir](benchmarks/0.8.22-via-ir/ERC721.md) 93 | * [0.8.23](benchmarks/0.8.23/ERC721.md) or [0.8.23-ir](benchmarks/0.8.23-via-ir/ERC721.md) 94 | * [0.8.24](benchmarks/0.8.24/ERC721.md) or [0.8.24-ir](benchmarks/0.8.24-via-ir/ERC721.md) 95 | * [0.8.25](benchmarks/0.8.25/ERC721.md) or [0.8.25-ir](benchmarks/0.8.25-via-ir/ERC721.md) 96 | * [0.8.26](benchmarks/0.8.26/ERC721.md) or [0.8.26-ir](benchmarks/0.8.26-via-ir/ERC721.md) 97 | 98 | 99 | **ERC1155** 100 | 101 | * [0.8.20](benchmarks/0.8.20/ERC1155.md) or [0.8.20-ir](benchmarks/0.8.20-via-ir/ERC1155.md) 102 | * [0.8.21](benchmarks/0.8.21/ERC1155.md) or [0.8.21-ir](benchmarks/0.8.21-via-ir/ERC1155.md) 103 | * [0.8.22](benchmarks/0.8.22/ERC1155.md) or [0.8.22-ir](benchmarks/0.8.22-via-ir/ERC1155.md) 104 | * [0.8.23](benchmarks/0.8.23/ERC1155.md) or [0.8.23-ir](benchmarks/0.8.23-via-ir/ERC1155.md) 105 | * [0.8.24](benchmarks/0.8.24/ERC1155.md) or [0.8.24-ir](benchmarks/0.8.24-via-ir/ERC1155.md) 106 | * [0.8.25](benchmarks/0.8.25/ERC1155.md) or [0.8.25-ir](benchmarks/0.8.25-via-ir/ERC1155.md) 107 | * [0.8.26](benchmarks/0.8.26/ERC1155.md) or [0.8.26-ir](benchmarks/0.8.26-via-ir/ERC1155.md) 108 | 109 | -------------------------------------------------------------------------------- /benchmarks/0.8.20-via-ir/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|------| 27 | | OpenZeppelin |962365| 28 | | Solmate |735871| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33707| 39 | | Solmate |33026| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35719|131858|250350| 50 | | Solmate |36907|131491|249838| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |38003| 61 | | Solmate |36834| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39614|138468|260316| 72 | | Solmate |39545|134484|253249| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.20-via-ir/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 8091 | 32530 | 7788 | 675231 | 7487 | 45055 | 27933 | 37864 | 20793 | 32 | | 7961 | 32524 | 7725 | 452958 | 7490 | 43266 | 26144 | 37830 | 20759 | 33 | | 8049 | 32562 | 7747 | 833229 | 7490 | 43266 | 26144 | 37896 | 20825 | 34 | | 8025 | 32485 | 7744 | 640959 | 7487 | 43114 | 25992 | 37764 | 20693 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.20-via-ir/ERC721.md: -------------------------------------------------------------------------------- 1 | # ERC721 Benchmark 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | The most popular way of implementing ERC721 is by having sequential ids for each token, so if a collection has 10000 tokens, the ids of each token are in the range 1~10000. Some of the latest implementations focus on making mint cheaper at the cost of an expensive transfer, this bechmark highlights that. 6 | 7 | We'll be comparing the following implementations: 8 | 9 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 10 | - [Solady](https://github.com/Vectorized/solady/) 11 | - [Solmate](https://github.com/rari-capital/solmate) 12 | - [ERC721A](https://github.com/chiru-labs/ERC721A) 13 | - [ERC721B](https://github.com/beskay/ERC721B) 14 | - [ERC721K](https://github.com/kadenzipfel/ERC721K) 15 | 16 | ## Methods TODO 17 | 18 | - [x] deploy 19 | - [x] mint (not in the specification, but common) 20 | - [x] safeMint (not in the specification, but common) 21 | - [x] burn (not in the specification, but common) 22 | - [x] balanceOf 23 | - [x] ownerOf 24 | - [x] transferFrom 25 | - [x] safeTransferFrom 26 | - [x] approve 27 | - [x] setApprovalForAll 28 | - [x] getApproved 29 | - [x] isApprovedForAll 30 | 31 | ## Deployment 32 | 33 | How much gas to deploy the contract as is? 34 | 35 | 36 | | Implementation | -- | 37 | |------------------------|-------| 38 | | ERC721A | 903150| 39 | | ERC721B | 918310| 40 | | ERC721K |1002924| 41 | |OpenZeppelin Consecutive|1014508| 42 | | OpenZeppelin Enumerable|1120129| 43 | | OpenZeppelin | 848572| 44 | | Solady | 611428| 45 | | Solmate | 797867| 46 | 47 | 48 | ## Deployment with ERC2309 minting 49 | 50 | How much gas to deploy the ERC2309 compliant contracts when minting N tokens in the constructor? 51 | 52 | 53 | | Implementation | 5 | 10 | 50 | 100 | 200 | 300 | 54 | |------------------------|------|------|------|------|------|------| 55 | | ERC721A |776046|776145|776079|776189|776123|776101| 56 | |OpenZeppelin Consecutive|850635|850734|850668|850778|850712|850690| 57 | 58 | 59 | ## Write methods 60 | 61 | ### mint 62 | 63 | How much gas to mint N tokens? 64 | 65 | 66 | | Implementation | 1 | 2 | 3 | 4 | 5 | 10 | 50 | 100 | 67 | |------------------------|------|------|------|------|------|-------|-------|--------| 68 | | ERC721A | 56978| 59083| 61042| 62894| 64872| 74535 | 151971| 248975 | 69 | | ERC721B | 52176| 54576| 56830| 58977| 61250| 72388 | 161624| 273378 | 70 | | ERC721K | 57609| 59784| 61813| 63735| 65783| 75796 | 156032| 256536 | 71 | |OpenZeppelin Consecutive| 79151|104919|130541|156056|181697| 309675|1333631| 2613785| 72 | | OpenZeppelin Enumerable|146003|260464|374779|488987|603321|1174764|5746440|11461244| 73 | | OpenZeppelin | 74324| 99250|124030|148703|173502| 297270|1287546| 2525600| 74 | | Solady | 74108| 98839|123424|147902|172506| 295299|1277775| 2506079| 75 | | Solmate | 74329| 99260|124045|148723|173527| 297320|1287796| 2526100| 76 | 77 | 78 | ### safeMint 79 | 80 | How much gas to safeMint N tokens? 81 | 82 | 83 | | Implementation | 1 | 2 | 3 | 4 | 5 | 10 | 50 | 100 | 84 | |------------------------|------|------|------|------|------|-------|-------|--------| 85 | | ERC721A | 59956| 61942| 63923| 65748| 67838| 77460 | 154825| 251637 | 86 | | ERC721B | 55363| 57644| 59920| 62040| 64425| 75522 | 164687| 276249 | 87 | | ERC721K | 60521| 62577| 64628| 66523| 68683| 78655 | 158820| 259132 | 88 | |OpenZeppelin Consecutive| 82114|107994|133869|159588|185572| 314664|1347794| 2639322| 89 | | OpenZeppelin Enumerable|149000|263557|378109|492505|607166|1179643|5759853|11485231| 90 | | OpenZeppelin | 77299|102321|127338|152199|177325| 302127|1300937| 2549565| 91 | | Solady | 77091|101924|126752|151424|176361| 300218|1291468| 2530646| 92 | | Solmate | 77268|102257|127241|152069|177162| 301799|1299284| 2546246| 93 | 94 | 95 | ### burn 96 | 97 | How much gas to burn the `nth` token? 98 | 99 | 100 | | Implementation | 1 | 10 | 50 | 100 | 101 | |------------------------|-----|------|------|------| 102 | | ERC721A |69705|106820|195215|305837| 103 | | ERC721B | 8453| 8560 | 8475 | 8497 | 104 | | ERC721K |73478|112150|207551|327009| 105 | |OpenZeppelin Consecutive|20785| 20892| 20807| 20829| 106 | | OpenZeppelin Enumerable|47407| 51972| 51904| 51922| 107 | | OpenZeppelin |18241| 18348| 18263| 18285| 108 | | Solady |18146| 18253| 18168| 18190| 109 | | Solmate |18212| 18319| 18234| 18256| 110 | 111 | 112 | ### transferFrom 113 | 114 | How much gas to transfer the `nth` token id if you own all tokens from 1 to 100? 115 | 116 | #### To a wallet that already owns a token from the collection 117 | 118 | 119 | | Implementation | 1 | 10 | 50 | 100 | 120 | |------------------------|------|------|------|------| 121 | | ERC721A | 53024| 90054|178468|289046| 122 | | ERC721B |294996|273760|179214| 43992| 123 | | ERC721K | 56471| 95058|190478|309892| 124 | |OpenZeppelin Consecutive| 28826| 28848| 28782| 28760| 125 | | OpenZeppelin Enumerable| 79656| 67378| 67312| 67290| 126 | | OpenZeppelin | 28538| 28560| 28494| 28472| 127 | | Solady | 28004| 28026| 27960| 27938| 128 | | Solmate | 28433| 28455| 28389| 28367| 129 | 130 | 131 | #### To a wallet that owns no token from the collection 132 | 133 | 134 | | Implementation | 1 | 10 | 50 | 100 | 135 | |------------------------|------|------|------|------| 136 | | ERC721A | 70090|107120|195534|306156| 137 | | ERC721B |294962|273726|179180| 44002| 138 | | ERC721K | 73537|112124|207544|327002| 139 | |OpenZeppelin Consecutive| 45892| 45914| 45848| 45870| 140 | | OpenZeppelin Enumerable| 76822| 79644| 79578| 79600| 141 | | OpenZeppelin | 45604| 45626| 45560| 45582| 142 | | Solady | 45070| 45092| 45026| 45048| 143 | | Solmate | 45499| 45521| 45455| 45477| 144 | 145 | 146 | ### safeTransferFrom 147 | 148 | How much gas to transfer the `nth` token id if you own all tokens from 1 to 100? 149 | 150 | #### To a wallet that already owns a token from the collection 151 | 152 | 153 | | Implementation | 1 | 10 | 50 | 100 | 154 | |------------------------|------|------|------|------| 155 | | ERC721A | 55835| 92799|181301|291817| 156 | | ERC721B |297857|276555|182097| 46813| 157 | | ERC721K | 59323| 97844|193352|312705| 158 | |OpenZeppelin Consecutive| 31640| 31596| 31618| 31534| 159 | | OpenZeppelin Enumerable| 82484| 70140| 70162| 70078| 160 | | OpenZeppelin | 31344| 31300| 31322| 31238| 161 | | Solady | 30676| 30632| 30654| 30570| 162 | | Solmate | 31169| 31125| 31147| 31063| 163 | 164 | 165 | #### To a wallet that owns no token from the collection 166 | 167 | 168 | | Implementation | 1 | 10 | 50 | 100 | 169 | |------------------------|------|------|------|------| 170 | | ERC721A | 72901|109865|198367|309011| 171 | | ERC721B |297823|276521|182063| 46907| 172 | | ERC721K | 76389|114910|210418|329899| 173 | |OpenZeppelin Consecutive| 48706| 48662| 48684| 48728| 174 | | OpenZeppelin Enumerable| 79650| 82406| 82428| 82472| 175 | | OpenZeppelin | 48410| 48366| 48388| 48432| 176 | | Solady | 47742| 47698| 47720| 47764| 177 | | Solmate | 48235| 48191| 48213| 48257| 178 | 179 | 180 | ### setApprovalForAll 181 | 182 | How much gas for `setApprovalForAll`? 183 | 184 | 185 | | Implementation | -- | 186 | |------------------------|-----| 187 | | ERC721A |32787| 188 | | ERC721B |32852| 189 | | ERC721K |32804| 190 | |OpenZeppelin Consecutive|32832| 191 | | OpenZeppelin Enumerable|32841| 192 | | OpenZeppelin |32775| 193 | | Solady |32633| 194 | | Solmate |32758| 195 | 196 | 197 | ### approve 198 | 199 | How much gas to approve the `nth` token id if you own all tokens from 1 to 100? 200 | 201 | 202 | | Implementation | 1 | 10 | 50 | 100 | 203 | |------------------------|------|------|------|------| 204 | | ERC721A | 37039| 56991|145449|256005| 205 | | ERC721B |271322|250108|155606| 37462| 206 | | ERC721K | 37507| 59016|154480|273872| 207 | |OpenZeppelin Consecutive| 35093| 35137| 35115| 35071| 208 | | OpenZeppelin Enumerable| 34926| 34970| 34948| 34904| 209 | | OpenZeppelin | 34926| 34970| 34948| 34904| 210 | | Solady | 34707| 34751| 34729| 34685| 211 | | Solmate | 34830| 34874| 34852| 34808| 212 | 213 | 214 | ## View methods 215 | 216 | #### balanceOf 217 | 218 | How much gas to run balanceOf in an account with N tokens. 219 | 220 | 221 | | Implementation | 1 | 10 | 50 | 100 | 222 | |------------------------|-------|-------|-------|-------| 223 | | ERC721A | 7934 | 7873 | 7851 | 7829 | 224 | | ERC721B |2719313|2719495|2720553|2721881| 225 | | ERC721K | 7975 | 7914 | 7892 | 7870 | 226 | |OpenZeppelin Consecutive| 7906 | 7845 | 7823 | 7801 | 227 | | OpenZeppelin Enumerable| 8017 | 7956 | 7934 | 7912 | 228 | | OpenZeppelin | 7931 | 7870 | 7848 | 7826 | 229 | | Solady | 7894 | 7833 | 7811 | 7789 | 230 | | Solmate | 7939 | 7878 | 7856 | 7834 | 231 | 232 | 233 | #### ownerOf 234 | 235 | How much gas to find the owner of a token when the owner owns 100 tokens and the token to find is the nth token. 236 | 237 | 238 | | Implementation | 1 | 10 | 50 | 100 | 239 | |------------------------|------|------|------|------| 240 | | ERC721A | 10132| 30018|118564|229028| 241 | | ERC721B |244356|223076|128662| 10426| 242 | | ERC721K | 10576| 32019|127571|246872| 243 | |OpenZeppelin Consecutive| 8034 | 8012 | 8078 | 7942 | 244 | | OpenZeppelin Enumerable| 7990 | 7968 | 8034 | 7898 | 245 | | OpenZeppelin | 7924 | 7902 | 7968 | 7832 | 246 | | Solady | 7909 | 7887 | 7953 | 7817 | 247 | | Solmate | 7900 | 7878 | 7944 | 7808 | 248 | 249 | 250 | #### getApproved 251 | 252 | How much gas to find the approved address of the nth token when the onwer owns 100 tokens and there are no approved addresses. 253 | 254 | 255 | | Implementation | 1 | 10 | 50 | 100 | 256 | |------------------------|------|------|------|------| 257 | | ERC721A | 10110| 30062|118564|229076| 258 | | ERC721B |244334|223120|128662| 10474| 259 | | ERC721K | 10554| 32063|127571|246920| 260 | |OpenZeppelin Consecutive| 8012 | 8056 | 8078 | 7990 | 261 | | OpenZeppelin Enumerable| 7968 | 8012 | 8034 | 7946 | 262 | | OpenZeppelin | 7902 | 7946 | 7968 | 7880 | 263 | | Solady | 7887 | 7931 | 7953 | 7865 | 264 | | Solmate | 7878 | 7922 | 7944 | 7856 | 265 | 266 | 267 | #### isApprovedForAll 268 | 269 | How much gas to check if an address is allowed to control another's nfts. 270 | 271 | 272 | | Implementation | -- | 273 | |------------------------|----| 274 | | ERC721A |8226| 275 | | ERC721B |8270| 276 | | ERC721K |8211| 277 | |OpenZeppelin Consecutive|8204| 278 | | OpenZeppelin Enumerable|8250| 279 | | OpenZeppelin |8184| 280 | | Solady |8081| 281 | | Solmate |8189| 282 | 283 | -------------------------------------------------------------------------------- /benchmarks/0.8.20/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|-------| 27 | | OpenZeppelin |1041636| 28 | | Solmate |1055715| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33972| 39 | | Solmate |33170| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35473|131195|249199| 50 | | Solmate |36552|130616|248280| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |38068| 61 | | Solmate |36926| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39831|138299|259752| 72 | | Solmate |39907|135144|254289| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.20/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 7927 | 32599 | 7692 | 669717 | 7579 | 45274 | 28152 | 37744 | 20666 | 32 | | 7960 | 32764 | 7690 | 463064 | 7542 | 43739 | 26617 | 38013 | 20935 | 33 | | 7960 | 32787 | 7691 | 869640 | 7565 | 43695 | 26573 | 37991 | 20913 | 34 | | 7927 | 32548 | 7692 | 654281 | 7556 | 43305 | 26183 | 37677 | 20599 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.21-via-ir/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|------| 27 | | OpenZeppelin |962165| 28 | | Solmate |735871| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33707| 39 | | Solmate |33026| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35719|131858|250350| 50 | | Solmate |36907|131491|249838| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |38003| 61 | | Solmate |36834| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39614|138468|260316| 72 | | Solmate |39545|134484|253249| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.21-via-ir/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 8091 | 32530 | 7788 | 681038 | 7487 | 45055 | 27933 | 37864 | 20793 | 32 | | 7961 | 32524 | 7725 | 452958 | 7490 | 43266 | 26144 | 37830 | 20759 | 33 | | 8049 | 32562 | 7747 | 836042 | 7490 | 43266 | 26144 | 37896 | 20825 | 34 | | 8025 | 32485 | 7744 | 646771 | 7487 | 43114 | 25992 | 37764 | 20693 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.21-via-ir/ERC721.md: -------------------------------------------------------------------------------- 1 | # ERC721 Benchmark 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | The most popular way of implementing ERC721 is by having sequential ids for each token, so if a collection has 10000 tokens, the ids of each token are in the range 1~10000. Some of the latest implementations focus on making mint cheaper at the cost of an expensive transfer, this bechmark highlights that. 6 | 7 | We'll be comparing the following implementations: 8 | 9 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 10 | - [Solady](https://github.com/Vectorized/solady/) 11 | - [Solmate](https://github.com/rari-capital/solmate) 12 | - [ERC721A](https://github.com/chiru-labs/ERC721A) 13 | - [ERC721B](https://github.com/beskay/ERC721B) 14 | - [ERC721K](https://github.com/kadenzipfel/ERC721K) 15 | 16 | ## Methods TODO 17 | 18 | - [x] deploy 19 | - [x] mint (not in the specification, but common) 20 | - [x] safeMint (not in the specification, but common) 21 | - [x] burn (not in the specification, but common) 22 | - [x] balanceOf 23 | - [x] ownerOf 24 | - [x] transferFrom 25 | - [x] safeTransferFrom 26 | - [x] approve 27 | - [x] setApprovalForAll 28 | - [x] getApproved 29 | - [x] isApprovedForAll 30 | 31 | ## Deployment 32 | 33 | How much gas to deploy the contract as is? 34 | 35 | 36 | | Implementation | -- | 37 | |------------------------|-------| 38 | | ERC721A | 909163| 39 | | ERC721B | 918110| 40 | | ERC721K |1002924| 41 | |OpenZeppelin Consecutive|1014308| 42 | | OpenZeppelin Enumerable|1120129| 43 | | OpenZeppelin | 848572| 44 | | Solady | 611428| 45 | | Solmate | 799067| 46 | 47 | 48 | ## Deployment with ERC2309 minting 49 | 50 | How much gas to deploy the ERC2309 compliant contracts when minting N tokens in the constructor? 51 | 52 | 53 | | Implementation | 5 | 10 | 50 | 100 | 200 | 300 | 54 | |------------------------|------|------|------|------|------|------| 55 | | ERC721A |776646|776745|776679|776789|776723|776701| 56 | |OpenZeppelin Consecutive|850668|850767|850701|850811|850745|850723| 57 | 58 | 59 | ## Write methods 60 | 61 | ### mint 62 | 63 | How much gas to mint N tokens? 64 | 65 | 66 | | Implementation | 1 | 2 | 3 | 4 | 5 | 10 | 50 | 100 | 67 | |------------------------|------|------|------|------|------|-------|-------|--------| 68 | | ERC721A | 57002| 59107| 61066| 62918| 64896| 74559 | 151995| 248999 | 69 | | ERC721B | 52176| 54576| 56830| 58977| 61250| 72388 | 161624| 273378 | 70 | | ERC721K | 57609| 59784| 61813| 63735| 65783| 75796 | 156032| 256536 | 71 | |OpenZeppelin Consecutive| 79151|104919|130541|156056|181697| 309675|1333631| 2613785| 72 | | OpenZeppelin Enumerable|146003|260464|374779|488987|603321|1174764|5746440|11461244| 73 | | OpenZeppelin | 74324| 99250|124030|148703|173502| 297270|1287546| 2525600| 74 | | Solady | 74108| 98839|123424|147902|172506| 295299|1277775| 2506079| 75 | | Solmate | 74329| 99260|124045|148723|173527| 297320|1287796| 2526100| 76 | 77 | 78 | ### safeMint 79 | 80 | How much gas to safeMint N tokens? 81 | 82 | 83 | | Implementation | 1 | 2 | 3 | 4 | 5 | 10 | 50 | 100 | 84 | |------------------------|------|------|------|------|------|-------|-------|--------| 85 | | ERC721A | 59980| 61966| 63947| 65772| 67862| 77484 | 154849| 251661 | 86 | | ERC721B | 55363| 57644| 59920| 62040| 64425| 75522 | 164687| 276249 | 87 | | ERC721K | 60521| 62577| 64628| 66523| 68683| 78655 | 158820| 259132 | 88 | |OpenZeppelin Consecutive| 82111|107991|133866|159585|185569| 314661|1347791| 2639319| 89 | | OpenZeppelin Enumerable|149000|263557|378109|492505|607166|1179643|5759853|11485231| 90 | | OpenZeppelin | 77299|102321|127338|152199|177325| 302127|1300937| 2549565| 91 | | Solady | 77091|101924|126752|151424|176361| 300218|1291468| 2530646| 92 | | Solmate | 77268|102257|127241|152069|177162| 301799|1299284| 2546246| 93 | 94 | 95 | ### burn 96 | 97 | How much gas to burn the `nth` token? 98 | 99 | 100 | | Implementation | 1 | 10 | 50 | 100 | 101 | |------------------------|-----|------|------|------| 102 | | ERC721A |69732|106847|195242|305864| 103 | | ERC721B | 8453| 8560 | 8475 | 8497 | 104 | | ERC721K |73478|112150|207551|327009| 105 | |OpenZeppelin Consecutive|20785| 20892| 20807| 20829| 106 | | OpenZeppelin Enumerable|47407| 51972| 51904| 51922| 107 | | OpenZeppelin |18241| 18348| 18263| 18285| 108 | | Solady |18146| 18253| 18168| 18190| 109 | | Solmate |18212| 18319| 18234| 18256| 110 | 111 | 112 | ### transferFrom 113 | 114 | How much gas to transfer the `nth` token id if you own all tokens from 1 to 100? 115 | 116 | #### To a wallet that already owns a token from the collection 117 | 118 | 119 | | Implementation | 1 | 10 | 50 | 100 | 120 | |------------------------|------|------|------|------| 121 | | ERC721A | 53027| 90057|178471|289049| 122 | | ERC721B |294990|273754|179208| 43986| 123 | | ERC721K | 56471| 95058|190478|309892| 124 | |OpenZeppelin Consecutive| 28826| 28848| 28782| 28760| 125 | | OpenZeppelin Enumerable| 79656| 67378| 67312| 67290| 126 | | OpenZeppelin | 28538| 28560| 28494| 28472| 127 | | Solady | 28004| 28026| 27960| 27938| 128 | | Solmate | 28433| 28455| 28389| 28367| 129 | 130 | 131 | #### To a wallet that owns no token from the collection 132 | 133 | 134 | | Implementation | 1 | 10 | 50 | 100 | 135 | |------------------------|------|------|------|------| 136 | | ERC721A | 70093|107123|195537|306159| 137 | | ERC721B |294956|273720|179174| 43996| 138 | | ERC721K | 73537|112124|207544|327002| 139 | |OpenZeppelin Consecutive| 45892| 45914| 45848| 45870| 140 | | OpenZeppelin Enumerable| 76822| 79644| 79578| 79600| 141 | | OpenZeppelin | 45604| 45626| 45560| 45582| 142 | | Solady | 45070| 45092| 45026| 45048| 143 | | Solmate | 45499| 45521| 45455| 45477| 144 | 145 | 146 | ### safeTransferFrom 147 | 148 | How much gas to transfer the `nth` token id if you own all tokens from 1 to 100? 149 | 150 | #### To a wallet that already owns a token from the collection 151 | 152 | 153 | | Implementation | 1 | 10 | 50 | 100 | 154 | |------------------------|------|------|------|------| 155 | | ERC721A | 55838| 92802|181304|291820| 156 | | ERC721B |297851|276549|182091| 46807| 157 | | ERC721K | 59317| 97838|193346|312699| 158 | |OpenZeppelin Consecutive| 31640| 31596| 31618| 31534| 159 | | OpenZeppelin Enumerable| 82484| 70140| 70162| 70078| 160 | | OpenZeppelin | 31344| 31300| 31322| 31238| 161 | | Solady | 30676| 30632| 30654| 30570| 162 | | Solmate | 31169| 31125| 31147| 31063| 163 | 164 | 165 | #### To a wallet that owns no token from the collection 166 | 167 | 168 | | Implementation | 1 | 10 | 50 | 100 | 169 | |------------------------|------|------|------|------| 170 | | ERC721A | 72904|109868|198370|309014| 171 | | ERC721B |297817|276515|182057| 46901| 172 | | ERC721K | 76383|114904|210412|329893| 173 | |OpenZeppelin Consecutive| 48706| 48662| 48684| 48728| 174 | | OpenZeppelin Enumerable| 79650| 82406| 82428| 82472| 175 | | OpenZeppelin | 48410| 48366| 48388| 48432| 176 | | Solady | 47742| 47698| 47720| 47764| 177 | | Solmate | 48235| 48191| 48213| 48257| 178 | 179 | 180 | ### setApprovalForAll 181 | 182 | How much gas for `setApprovalForAll`? 183 | 184 | 185 | | Implementation | -- | 186 | |------------------------|-----| 187 | | ERC721A |32787| 188 | | ERC721B |32852| 189 | | ERC721K |32804| 190 | |OpenZeppelin Consecutive|32832| 191 | | OpenZeppelin Enumerable|32841| 192 | | OpenZeppelin |32775| 193 | | Solady |32633| 194 | | Solmate |32758| 195 | 196 | 197 | ### approve 198 | 199 | How much gas to approve the `nth` token id if you own all tokens from 1 to 100? 200 | 201 | 202 | | Implementation | 1 | 10 | 50 | 100 | 203 | |------------------------|------|------|------|------| 204 | | ERC721A | 37039| 56991|145449|256005| 205 | | ERC721B |271322|250108|155606| 37462| 206 | | ERC721K | 37507| 59016|154480|273872| 207 | |OpenZeppelin Consecutive| 35093| 35137| 35115| 35071| 208 | | OpenZeppelin Enumerable| 34926| 34970| 34948| 34904| 209 | | OpenZeppelin | 34926| 34970| 34948| 34904| 210 | | Solady | 34707| 34751| 34729| 34685| 211 | | Solmate | 34830| 34874| 34852| 34808| 212 | 213 | 214 | ## View methods 215 | 216 | #### balanceOf 217 | 218 | How much gas to run balanceOf in an account with N tokens. 219 | 220 | 221 | | Implementation | 1 | 10 | 50 | 100 | 222 | |------------------------|-------|-------|-------|-------| 223 | | ERC721A | 7934 | 7873 | 7851 | 7829 | 224 | | ERC721B |2719313|2719495|2720553|2721881| 225 | | ERC721K | 7975 | 7914 | 7892 | 7870 | 226 | |OpenZeppelin Consecutive| 7906 | 7845 | 7823 | 7801 | 227 | | OpenZeppelin Enumerable| 8017 | 7956 | 7934 | 7912 | 228 | | OpenZeppelin | 7931 | 7870 | 7848 | 7826 | 229 | | Solady | 7894 | 7833 | 7811 | 7789 | 230 | | Solmate | 7939 | 7878 | 7856 | 7834 | 231 | 232 | 233 | #### ownerOf 234 | 235 | How much gas to find the owner of a token when the owner owns 100 tokens and the token to find is the nth token. 236 | 237 | 238 | | Implementation | 1 | 10 | 50 | 100 | 239 | |------------------------|------|------|------|------| 240 | | ERC721A | 10132| 30018|118564|229028| 241 | | ERC721B |244356|223076|128662| 10426| 242 | | ERC721K | 10576| 32019|127571|246872| 243 | |OpenZeppelin Consecutive| 8034 | 8012 | 8078 | 7942 | 244 | | OpenZeppelin Enumerable| 7990 | 7968 | 8034 | 7898 | 245 | | OpenZeppelin | 7924 | 7902 | 7968 | 7832 | 246 | | Solady | 7909 | 7887 | 7953 | 7817 | 247 | | Solmate | 7900 | 7878 | 7944 | 7808 | 248 | 249 | 250 | #### getApproved 251 | 252 | How much gas to find the approved address of the nth token when the onwer owns 100 tokens and there are no approved addresses. 253 | 254 | 255 | | Implementation | 1 | 10 | 50 | 100 | 256 | |------------------------|------|------|------|------| 257 | | ERC721A | 10110| 30062|118564|229076| 258 | | ERC721B |244334|223120|128662| 10474| 259 | | ERC721K | 10554| 32063|127571|246920| 260 | |OpenZeppelin Consecutive| 8012 | 8056 | 8078 | 7990 | 261 | | OpenZeppelin Enumerable| 7968 | 8012 | 8034 | 7946 | 262 | | OpenZeppelin | 7902 | 7946 | 7968 | 7880 | 263 | | Solady | 7887 | 7931 | 7953 | 7865 | 264 | | Solmate | 7878 | 7922 | 7944 | 7856 | 265 | 266 | 267 | #### isApprovedForAll 268 | 269 | How much gas to check if an address is allowed to control another's nfts. 270 | 271 | 272 | | Implementation | -- | 273 | |------------------------|----| 274 | | ERC721A |8226| 275 | | ERC721B |8270| 276 | | ERC721K |8211| 277 | |OpenZeppelin Consecutive|8204| 278 | | OpenZeppelin Enumerable|8250| 279 | | OpenZeppelin |8184| 280 | | Solady |8081| 281 | | Solmate |8189| 282 | 283 | -------------------------------------------------------------------------------- /benchmarks/0.8.21/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|-------| 27 | | OpenZeppelin |1041636| 28 | | Solmate |1055715| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33972| 39 | | Solmate |33170| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35473|131195|249199| 50 | | Solmate |36552|130616|248280| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |38068| 61 | | Solmate |36926| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39831|138299|259752| 72 | | Solmate |39907|135144|254289| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.21/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 7927 | 32599 | 7692 | 669717 | 7579 | 45274 | 28152 | 37744 | 20666 | 32 | | 7960 | 32764 | 7690 | 463064 | 7542 | 43739 | 26617 | 38013 | 20935 | 33 | | 7960 | 32787 | 7691 | 869640 | 7565 | 43695 | 26573 | 37991 | 20913 | 34 | | 7927 | 32548 | 7692 | 654281 | 7556 | 43305 | 26183 | 37677 | 20599 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.22-via-ir/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|------| 27 | | OpenZeppelin |956352| 28 | | Solmate |736471| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33655| 39 | | Solmate |33026| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35667|131598|249830| 50 | | Solmate |36907|131491|249838| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |37950| 61 | | Solmate |36834| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39561|138209|259797| 72 | | Solmate |39545|134484|253249| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.22-via-ir/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 8091 | 32530 | 7788 | 677031 | 7487 | 45055 | 27933 | 37864 | 20793 | 32 | | 7961 | 32524 | 7725 | 453758 | 7490 | 43266 | 26144 | 37830 | 20759 | 33 | | 8049 | 32562 | 7747 | 838842 | 7490 | 43266 | 26144 | 37896 | 20825 | 34 | | 8025 | 32485 | 7744 | 641359 | 7487 | 43114 | 25992 | 37764 | 20693 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.22-via-ir/ERC721.md: -------------------------------------------------------------------------------- 1 | # ERC721 Benchmark 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | The most popular way of implementing ERC721 is by having sequential ids for each token, so if a collection has 10000 tokens, the ids of each token are in the range 1~10000. Some of the latest implementations focus on making mint cheaper at the cost of an expensive transfer, this bechmark highlights that. 6 | 7 | We'll be comparing the following implementations: 8 | 9 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 10 | - [Solady](https://github.com/Vectorized/solady/) 11 | - [Solmate](https://github.com/rari-capital/solmate) 12 | - [ERC721A](https://github.com/chiru-labs/ERC721A) 13 | - [ERC721B](https://github.com/beskay/ERC721B) 14 | - [ERC721K](https://github.com/kadenzipfel/ERC721K) 15 | 16 | ## Methods TODO 17 | 18 | - [x] deploy 19 | - [x] mint (not in the specification, but common) 20 | - [x] safeMint (not in the specification, but common) 21 | - [x] burn (not in the specification, but common) 22 | - [x] balanceOf 23 | - [x] ownerOf 24 | - [x] transferFrom 25 | - [x] safeTransferFrom 26 | - [x] approve 27 | - [x] setApprovalForAll 28 | - [x] getApproved 29 | - [x] isApprovedForAll 30 | 31 | ## Deployment 32 | 33 | How much gas to deploy the contract as is? 34 | 35 | 36 | | Implementation | -- | 37 | |------------------------|-------| 38 | | ERC721A | 912163| 39 | | ERC721B | 920117| 40 | | ERC721K |1006737| 41 | |OpenZeppelin Consecutive|1029942| 42 | | OpenZeppelin Enumerable|1121929| 43 | | OpenZeppelin | 850372| 44 | | Solady | 611828| 45 | | Solmate | 801067| 46 | 47 | 48 | ## Deployment with ERC2309 minting 49 | 50 | How much gas to deploy the ERC2309 compliant contracts when minting N tokens in the constructor? 51 | 52 | 53 | | Implementation | 5 | 10 | 50 | 100 | 200 | 300 | 54 | |------------------------|------|------|------|------|------|------| 55 | | ERC721A |779246|779345|779279|779389|779323|779301| 56 | |OpenZeppelin Consecutive|852475|852574|852508|852618|852552|852530| 57 | 58 | 59 | ## Write methods 60 | 61 | ### mint 62 | 63 | How much gas to mint N tokens? 64 | 65 | 66 | | Implementation | 1 | 2 | 3 | 4 | 5 | 10 | 50 | 100 | 67 | |------------------------|------|------|------|------|------|-------|-------|--------| 68 | | ERC721A | 57002| 59107| 61066| 62918| 64896| 74559 | 151995| 248999 | 69 | | ERC721B | 52176| 54576| 56830| 58977| 61250| 72388 | 161624| 273378 | 70 | | ERC721K | 57609| 59784| 61813| 63735| 65783| 75796 | 156032| 256536 | 71 | |OpenZeppelin Consecutive| 79151|104919|130541|156056|181697| 309675|1333631| 2613785| 72 | | OpenZeppelin Enumerable|146003|260464|374779|488987|603321|1174764|5746440|11461244| 73 | | OpenZeppelin | 74324| 99250|124030|148703|173502| 297270|1287546| 2525600| 74 | | Solady | 74108| 98839|123424|147902|172506| 295299|1277775| 2506079| 75 | | Solmate | 74329| 99260|124045|148723|173527| 297320|1287796| 2526100| 76 | 77 | 78 | ### safeMint 79 | 80 | How much gas to safeMint N tokens? 81 | 82 | 83 | | Implementation | 1 | 2 | 3 | 4 | 5 | 10 | 50 | 100 | 84 | |------------------------|------|------|------|------|------|-------|-------|--------| 85 | | ERC721A | 59980| 61966| 63947| 65772| 67862| 77484 | 154849| 251661 | 86 | | ERC721B | 55363| 57644| 59920| 62040| 64425| 75522 | 164687| 276249 | 87 | | ERC721K | 60524| 62580| 64631| 66526| 68686| 78658 | 158823| 259135 | 88 | |OpenZeppelin Consecutive| 82113|107977|133836|159539|185507| 314519|1347009| 2637737| 89 | | OpenZeppelin Enumerable|149000|263557|378109|492505|607166|1179643|5759853|11485231| 90 | | OpenZeppelin | 77299|102321|127338|152199|177325| 302127|1300937| 2549565| 91 | | Solady | 77091|101924|126752|151424|176361| 300218|1291468| 2530646| 92 | | Solmate | 77268|102257|127241|152069|177162| 301799|1299284| 2546246| 93 | 94 | 95 | ### burn 96 | 97 | How much gas to burn the `nth` token? 98 | 99 | 100 | | Implementation | 1 | 10 | 50 | 100 | 101 | |------------------------|-----|------|------|------| 102 | | ERC721A |69732|106847|195242|305864| 103 | | ERC721B | 8453| 8560 | 8475 | 8497 | 104 | | ERC721K |73478|112150|207551|327009| 105 | |OpenZeppelin Consecutive|20779| 20886| 20801| 20823| 106 | | OpenZeppelin Enumerable|47407| 51972| 51904| 51922| 107 | | OpenZeppelin |18241| 18348| 18263| 18285| 108 | | Solady |18146| 18253| 18168| 18190| 109 | | Solmate |18212| 18319| 18234| 18256| 110 | 111 | 112 | ### transferFrom 113 | 114 | How much gas to transfer the `nth` token id if you own all tokens from 1 to 100? 115 | 116 | #### To a wallet that already owns a token from the collection 117 | 118 | 119 | | Implementation | 1 | 10 | 50 | 100 | 120 | |------------------------|------|------|------|------| 121 | | ERC721A | 53027| 90057|178471|289049| 122 | | ERC721B |294990|273754|179208| 43986| 123 | | ERC721K | 56471| 95058|190478|309892| 124 | |OpenZeppelin Consecutive| 28826| 28848| 28782| 28760| 125 | | OpenZeppelin Enumerable| 79656| 67378| 67312| 67290| 126 | | OpenZeppelin | 28538| 28560| 28494| 28472| 127 | | Solady | 28004| 28026| 27960| 27938| 128 | | Solmate | 28433| 28455| 28389| 28367| 129 | 130 | 131 | #### To a wallet that owns no token from the collection 132 | 133 | 134 | | Implementation | 1 | 10 | 50 | 100 | 135 | |------------------------|------|------|------|------| 136 | | ERC721A | 70093|107123|195537|306159| 137 | | ERC721B |294956|273720|179174| 43996| 138 | | ERC721K | 73537|112124|207544|327002| 139 | |OpenZeppelin Consecutive| 45892| 45914| 45848| 45870| 140 | | OpenZeppelin Enumerable| 76822| 79644| 79578| 79600| 141 | | OpenZeppelin | 45604| 45626| 45560| 45582| 142 | | Solady | 45070| 45092| 45026| 45048| 143 | | Solmate | 45499| 45521| 45455| 45477| 144 | 145 | 146 | ### safeTransferFrom 147 | 148 | How much gas to transfer the `nth` token id if you own all tokens from 1 to 100? 149 | 150 | #### To a wallet that already owns a token from the collection 151 | 152 | 153 | | Implementation | 1 | 10 | 50 | 100 | 154 | |------------------------|------|------|------|------| 155 | | ERC721A | 55838| 92802|181304|291820| 156 | | ERC721B |297851|276549|182091| 46807| 157 | | ERC721K | 59317| 97838|193346|312699| 158 | |OpenZeppelin Consecutive| 31640| 31596| 31618| 31534| 159 | | OpenZeppelin Enumerable| 82484| 70140| 70162| 70078| 160 | | OpenZeppelin | 31344| 31300| 31322| 31238| 161 | | Solady | 30676| 30632| 30654| 30570| 162 | | Solmate | 31169| 31125| 31147| 31063| 163 | 164 | 165 | #### To a wallet that owns no token from the collection 166 | 167 | 168 | | Implementation | 1 | 10 | 50 | 100 | 169 | |------------------------|------|------|------|------| 170 | | ERC721A | 72904|109868|198370|309014| 171 | | ERC721B |297817|276515|182057| 46901| 172 | | ERC721K | 76383|114904|210412|329893| 173 | |OpenZeppelin Consecutive| 48706| 48662| 48684| 48728| 174 | | OpenZeppelin Enumerable| 79650| 82406| 82428| 82472| 175 | | OpenZeppelin | 48410| 48366| 48388| 48432| 176 | | Solady | 47742| 47698| 47720| 47764| 177 | | Solmate | 48235| 48191| 48213| 48257| 178 | 179 | 180 | ### setApprovalForAll 181 | 182 | How much gas for `setApprovalForAll`? 183 | 184 | 185 | | Implementation | -- | 186 | |------------------------|-----| 187 | | ERC721A |32787| 188 | | ERC721B |32852| 189 | | ERC721K |32804| 190 | |OpenZeppelin Consecutive|32832| 191 | | OpenZeppelin Enumerable|32841| 192 | | OpenZeppelin |32775| 193 | | Solady |32633| 194 | | Solmate |32758| 195 | 196 | 197 | ### approve 198 | 199 | How much gas to approve the `nth` token id if you own all tokens from 1 to 100? 200 | 201 | 202 | | Implementation | 1 | 10 | 50 | 100 | 203 | |------------------------|------|------|------|------| 204 | | ERC721A | 37039| 56991|145449|256005| 205 | | ERC721B |271322|250108|155606| 37462| 206 | | ERC721K | 37507| 59016|154480|273872| 207 | |OpenZeppelin Consecutive| 35093| 35137| 35115| 35071| 208 | | OpenZeppelin Enumerable| 34926| 34970| 34948| 34904| 209 | | OpenZeppelin | 34926| 34970| 34948| 34904| 210 | | Solady | 34707| 34751| 34729| 34685| 211 | | Solmate | 34830| 34874| 34852| 34808| 212 | 213 | 214 | ## View methods 215 | 216 | #### balanceOf 217 | 218 | How much gas to run balanceOf in an account with N tokens. 219 | 220 | 221 | | Implementation | 1 | 10 | 50 | 100 | 222 | |------------------------|-------|-------|-------|-------| 223 | | ERC721A | 7934 | 7873 | 7851 | 7829 | 224 | | ERC721B |2719313|2719495|2720553|2721881| 225 | | ERC721K | 7975 | 7914 | 7892 | 7870 | 226 | |OpenZeppelin Consecutive| 7906 | 7845 | 7823 | 7801 | 227 | | OpenZeppelin Enumerable| 8017 | 7956 | 7934 | 7912 | 228 | | OpenZeppelin | 7931 | 7870 | 7848 | 7826 | 229 | | Solady | 7894 | 7833 | 7811 | 7789 | 230 | | Solmate | 7939 | 7878 | 7856 | 7834 | 231 | 232 | 233 | #### ownerOf 234 | 235 | How much gas to find the owner of a token when the owner owns 100 tokens and the token to find is the nth token. 236 | 237 | 238 | | Implementation | 1 | 10 | 50 | 100 | 239 | |------------------------|------|------|------|------| 240 | | ERC721A | 10132| 30018|118564|229028| 241 | | ERC721B |244356|223076|128662| 10426| 242 | | ERC721K | 10576| 32019|127571|246872| 243 | |OpenZeppelin Consecutive| 8034 | 8012 | 8078 | 7942 | 244 | | OpenZeppelin Enumerable| 7990 | 7968 | 8034 | 7898 | 245 | | OpenZeppelin | 7924 | 7902 | 7968 | 7832 | 246 | | Solady | 7909 | 7887 | 7953 | 7817 | 247 | | Solmate | 7900 | 7878 | 7944 | 7808 | 248 | 249 | 250 | #### getApproved 251 | 252 | How much gas to find the approved address of the nth token when the onwer owns 100 tokens and there are no approved addresses. 253 | 254 | 255 | | Implementation | 1 | 10 | 50 | 100 | 256 | |------------------------|------|------|------|------| 257 | | ERC721A | 10110| 30062|118564|229076| 258 | | ERC721B |244334|223120|128662| 10474| 259 | | ERC721K | 10554| 32063|127571|246920| 260 | |OpenZeppelin Consecutive| 8012 | 8056 | 8078 | 7990 | 261 | | OpenZeppelin Enumerable| 7968 | 8012 | 8034 | 7946 | 262 | | OpenZeppelin | 7902 | 7946 | 7968 | 7880 | 263 | | Solady | 7887 | 7931 | 7953 | 7865 | 264 | | Solmate | 7878 | 7922 | 7944 | 7856 | 265 | 266 | 267 | #### isApprovedForAll 268 | 269 | How much gas to check if an address is allowed to control another's nfts. 270 | 271 | 272 | | Implementation | -- | 273 | |------------------------|----| 274 | | ERC721A |8226| 275 | | ERC721B |8270| 276 | | ERC721K |8211| 277 | |OpenZeppelin Consecutive|8204| 278 | | OpenZeppelin Enumerable|8250| 279 | | OpenZeppelin |8184| 280 | | Solady |8081| 281 | | Solmate |8189| 282 | 283 | -------------------------------------------------------------------------------- /benchmarks/0.8.22/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|-------| 27 | | OpenZeppelin |1032616| 28 | | Solmate |1055915| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33906| 39 | | Solmate |33170| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35407|130865|248539| 50 | | Solmate |36552|130616|248280| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |38002| 61 | | Solmate |36926| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39767|137971|259094| 72 | | Solmate |39907|135144|254289| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.22/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 7927 | 32599 | 7692 | 670317 | 7579 | 45274 | 28152 | 37744 | 20666 | 32 | | 7960 | 32764 | 7690 | 463270 | 7542 | 43739 | 26617 | 38013 | 20935 | 33 | | 7960 | 32787 | 7691 | 870240 | 7565 | 43695 | 26573 | 37991 | 20913 | 34 | | 7927 | 32548 | 7692 | 654881 | 7556 | 43305 | 26183 | 37677 | 20599 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.23-via-ir/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|------| 27 | | OpenZeppelin |956352| 28 | | Solmate |736471| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33655| 39 | | Solmate |33026| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35667|131598|249830| 50 | | Solmate |36907|131491|249838| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |37950| 61 | | Solmate |36834| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39561|138209|259797| 72 | | Solmate |39545|134484|253249| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.23-via-ir/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 8091 | 32530 | 7788 | 677031 | 7487 | 45055 | 27933 | 37864 | 20793 | 32 | | 7961 | 32524 | 7725 | 453758 | 7490 | 43266 | 26144 | 37830 | 20759 | 33 | | 8049 | 32562 | 7747 | 838842 | 7490 | 43266 | 26144 | 37896 | 20825 | 34 | | 8025 | 32485 | 7744 | 641359 | 7487 | 43114 | 25992 | 37764 | 20693 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.23-via-ir/ERC721.md: -------------------------------------------------------------------------------- 1 | # ERC721 Benchmark 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | The most popular way of implementing ERC721 is by having sequential ids for each token, so if a collection has 10000 tokens, the ids of each token are in the range 1~10000. Some of the latest implementations focus on making mint cheaper at the cost of an expensive transfer, this bechmark highlights that. 6 | 7 | We'll be comparing the following implementations: 8 | 9 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 10 | - [Solady](https://github.com/Vectorized/solady/) 11 | - [Solmate](https://github.com/rari-capital/solmate) 12 | - [ERC721A](https://github.com/chiru-labs/ERC721A) 13 | - [ERC721B](https://github.com/beskay/ERC721B) 14 | - [ERC721K](https://github.com/kadenzipfel/ERC721K) 15 | 16 | ## Methods TODO 17 | 18 | - [x] deploy 19 | - [x] mint (not in the specification, but common) 20 | - [x] safeMint (not in the specification, but common) 21 | - [x] burn (not in the specification, but common) 22 | - [x] balanceOf 23 | - [x] ownerOf 24 | - [x] transferFrom 25 | - [x] safeTransferFrom 26 | - [x] approve 27 | - [x] setApprovalForAll 28 | - [x] getApproved 29 | - [x] isApprovedForAll 30 | 31 | ## Deployment 32 | 33 | How much gas to deploy the contract as is? 34 | 35 | 36 | | Implementation | -- | 37 | |------------------------|-------| 38 | | ERC721A | 912163| 39 | | ERC721B | 920117| 40 | | ERC721K |1006737| 41 | |OpenZeppelin Consecutive|1029942| 42 | | OpenZeppelin Enumerable|1121929| 43 | | OpenZeppelin | 850372| 44 | | Solady | 611828| 45 | | Solmate | 801067| 46 | 47 | 48 | ## Deployment with ERC2309 minting 49 | 50 | How much gas to deploy the ERC2309 compliant contracts when minting N tokens in the constructor? 51 | 52 | 53 | | Implementation | 5 | 10 | 50 | 100 | 200 | 300 | 54 | |------------------------|------|------|------|------|------|------| 55 | | ERC721A |779246|779345|779279|779389|779323|779301| 56 | |OpenZeppelin Consecutive|852475|852574|852508|852618|852552|852530| 57 | 58 | 59 | ## Write methods 60 | 61 | ### mint 62 | 63 | How much gas to mint N tokens? 64 | 65 | 66 | | Implementation | 1 | 2 | 3 | 4 | 5 | 10 | 50 | 100 | 67 | |------------------------|------|------|------|------|------|-------|-------|--------| 68 | | ERC721A | 57002| 59107| 61066| 62918| 64896| 74559 | 151995| 248999 | 69 | | ERC721B | 52176| 54576| 56830| 58977| 61250| 72388 | 161624| 273378 | 70 | | ERC721K | 57609| 59784| 61813| 63735| 65783| 75796 | 156032| 256536 | 71 | |OpenZeppelin Consecutive| 79151|104919|130541|156056|181697| 309675|1333631| 2613785| 72 | | OpenZeppelin Enumerable|146003|260464|374779|488987|603321|1174764|5746440|11461244| 73 | | OpenZeppelin | 74324| 99250|124030|148703|173502| 297270|1287546| 2525600| 74 | | Solady | 74108| 98839|123424|147902|172506| 295299|1277775| 2506079| 75 | | Solmate | 74329| 99260|124045|148723|173527| 297320|1287796| 2526100| 76 | 77 | 78 | ### safeMint 79 | 80 | How much gas to safeMint N tokens? 81 | 82 | 83 | | Implementation | 1 | 2 | 3 | 4 | 5 | 10 | 50 | 100 | 84 | |------------------------|------|------|------|------|------|-------|-------|--------| 85 | | ERC721A | 59980| 61966| 63947| 65772| 67862| 77484 | 154849| 251661 | 86 | | ERC721B | 55363| 57644| 59920| 62040| 64425| 75522 | 164687| 276249 | 87 | | ERC721K | 60524| 62580| 64631| 66526| 68686| 78658 | 158823| 259135 | 88 | |OpenZeppelin Consecutive| 82113|107977|133836|159539|185507| 314519|1347009| 2637737| 89 | | OpenZeppelin Enumerable|149000|263557|378109|492505|607166|1179643|5759853|11485231| 90 | | OpenZeppelin | 77299|102321|127338|152199|177325| 302127|1300937| 2549565| 91 | | Solady | 77091|101924|126752|151424|176361| 300218|1291468| 2530646| 92 | | Solmate | 77268|102257|127241|152069|177162| 301799|1299284| 2546246| 93 | 94 | 95 | ### burn 96 | 97 | How much gas to burn the `nth` token? 98 | 99 | 100 | | Implementation | 1 | 10 | 50 | 100 | 101 | |------------------------|-----|------|------|------| 102 | | ERC721A |69732|106847|195242|305864| 103 | | ERC721B | 8453| 8560 | 8475 | 8497 | 104 | | ERC721K |73478|112150|207551|327009| 105 | |OpenZeppelin Consecutive|20779| 20886| 20801| 20823| 106 | | OpenZeppelin Enumerable|47407| 51972| 51904| 51922| 107 | | OpenZeppelin |18241| 18348| 18263| 18285| 108 | | Solady |18146| 18253| 18168| 18190| 109 | | Solmate |18212| 18319| 18234| 18256| 110 | 111 | 112 | ### transferFrom 113 | 114 | How much gas to transfer the `nth` token id if you own all tokens from 1 to 100? 115 | 116 | #### To a wallet that already owns a token from the collection 117 | 118 | 119 | | Implementation | 1 | 10 | 50 | 100 | 120 | |------------------------|------|------|------|------| 121 | | ERC721A | 53027| 90057|178471|289049| 122 | | ERC721B |294990|273754|179208| 43986| 123 | | ERC721K | 56471| 95058|190478|309892| 124 | |OpenZeppelin Consecutive| 28826| 28848| 28782| 28760| 125 | | OpenZeppelin Enumerable| 79656| 67378| 67312| 67290| 126 | | OpenZeppelin | 28538| 28560| 28494| 28472| 127 | | Solady | 28004| 28026| 27960| 27938| 128 | | Solmate | 28433| 28455| 28389| 28367| 129 | 130 | 131 | #### To a wallet that owns no token from the collection 132 | 133 | 134 | | Implementation | 1 | 10 | 50 | 100 | 135 | |------------------------|------|------|------|------| 136 | | ERC721A | 70093|107123|195537|306159| 137 | | ERC721B |294956|273720|179174| 43996| 138 | | ERC721K | 73537|112124|207544|327002| 139 | |OpenZeppelin Consecutive| 45892| 45914| 45848| 45870| 140 | | OpenZeppelin Enumerable| 76822| 79644| 79578| 79600| 141 | | OpenZeppelin | 45604| 45626| 45560| 45582| 142 | | Solady | 45070| 45092| 45026| 45048| 143 | | Solmate | 45499| 45521| 45455| 45477| 144 | 145 | 146 | ### safeTransferFrom 147 | 148 | How much gas to transfer the `nth` token id if you own all tokens from 1 to 100? 149 | 150 | #### To a wallet that already owns a token from the collection 151 | 152 | 153 | | Implementation | 1 | 10 | 50 | 100 | 154 | |------------------------|------|------|------|------| 155 | | ERC721A | 55838| 92802|181304|291820| 156 | | ERC721B |297851|276549|182091| 46807| 157 | | ERC721K | 59317| 97838|193346|312699| 158 | |OpenZeppelin Consecutive| 31640| 31596| 31618| 31534| 159 | | OpenZeppelin Enumerable| 82484| 70140| 70162| 70078| 160 | | OpenZeppelin | 31344| 31300| 31322| 31238| 161 | | Solady | 30676| 30632| 30654| 30570| 162 | | Solmate | 31169| 31125| 31147| 31063| 163 | 164 | 165 | #### To a wallet that owns no token from the collection 166 | 167 | 168 | | Implementation | 1 | 10 | 50 | 100 | 169 | |------------------------|------|------|------|------| 170 | | ERC721A | 72904|109868|198370|309014| 171 | | ERC721B |297817|276515|182057| 46901| 172 | | ERC721K | 76383|114904|210412|329893| 173 | |OpenZeppelin Consecutive| 48706| 48662| 48684| 48728| 174 | | OpenZeppelin Enumerable| 79650| 82406| 82428| 82472| 175 | | OpenZeppelin | 48410| 48366| 48388| 48432| 176 | | Solady | 47742| 47698| 47720| 47764| 177 | | Solmate | 48235| 48191| 48213| 48257| 178 | 179 | 180 | ### setApprovalForAll 181 | 182 | How much gas for `setApprovalForAll`? 183 | 184 | 185 | | Implementation | -- | 186 | |------------------------|-----| 187 | | ERC721A |32787| 188 | | ERC721B |32852| 189 | | ERC721K |32804| 190 | |OpenZeppelin Consecutive|32832| 191 | | OpenZeppelin Enumerable|32841| 192 | | OpenZeppelin |32775| 193 | | Solady |32633| 194 | | Solmate |32758| 195 | 196 | 197 | ### approve 198 | 199 | How much gas to approve the `nth` token id if you own all tokens from 1 to 100? 200 | 201 | 202 | | Implementation | 1 | 10 | 50 | 100 | 203 | |------------------------|------|------|------|------| 204 | | ERC721A | 37039| 56991|145449|256005| 205 | | ERC721B |271322|250108|155606| 37462| 206 | | ERC721K | 37507| 59016|154480|273872| 207 | |OpenZeppelin Consecutive| 35093| 35137| 35115| 35071| 208 | | OpenZeppelin Enumerable| 34926| 34970| 34948| 34904| 209 | | OpenZeppelin | 34926| 34970| 34948| 34904| 210 | | Solady | 34707| 34751| 34729| 34685| 211 | | Solmate | 34830| 34874| 34852| 34808| 212 | 213 | 214 | ## View methods 215 | 216 | #### balanceOf 217 | 218 | How much gas to run balanceOf in an account with N tokens. 219 | 220 | 221 | | Implementation | 1 | 10 | 50 | 100 | 222 | |------------------------|-------|-------|-------|-------| 223 | | ERC721A | 7934 | 7873 | 7851 | 7829 | 224 | | ERC721B |2719313|2719495|2720553|2721881| 225 | | ERC721K | 7975 | 7914 | 7892 | 7870 | 226 | |OpenZeppelin Consecutive| 7906 | 7845 | 7823 | 7801 | 227 | | OpenZeppelin Enumerable| 8017 | 7956 | 7934 | 7912 | 228 | | OpenZeppelin | 7931 | 7870 | 7848 | 7826 | 229 | | Solady | 7894 | 7833 | 7811 | 7789 | 230 | | Solmate | 7939 | 7878 | 7856 | 7834 | 231 | 232 | 233 | #### ownerOf 234 | 235 | How much gas to find the owner of a token when the owner owns 100 tokens and the token to find is the nth token. 236 | 237 | 238 | | Implementation | 1 | 10 | 50 | 100 | 239 | |------------------------|------|------|------|------| 240 | | ERC721A | 10132| 30018|118564|229028| 241 | | ERC721B |244356|223076|128662| 10426| 242 | | ERC721K | 10576| 32019|127571|246872| 243 | |OpenZeppelin Consecutive| 8034 | 8012 | 8078 | 7942 | 244 | | OpenZeppelin Enumerable| 7990 | 7968 | 8034 | 7898 | 245 | | OpenZeppelin | 7924 | 7902 | 7968 | 7832 | 246 | | Solady | 7909 | 7887 | 7953 | 7817 | 247 | | Solmate | 7900 | 7878 | 7944 | 7808 | 248 | 249 | 250 | #### getApproved 251 | 252 | How much gas to find the approved address of the nth token when the onwer owns 100 tokens and there are no approved addresses. 253 | 254 | 255 | | Implementation | 1 | 10 | 50 | 100 | 256 | |------------------------|------|------|------|------| 257 | | ERC721A | 10110| 30062|118564|229076| 258 | | ERC721B |244334|223120|128662| 10474| 259 | | ERC721K | 10554| 32063|127571|246920| 260 | |OpenZeppelin Consecutive| 8012 | 8056 | 8078 | 7990 | 261 | | OpenZeppelin Enumerable| 7968 | 8012 | 8034 | 7946 | 262 | | OpenZeppelin | 7902 | 7946 | 7968 | 7880 | 263 | | Solady | 7887 | 7931 | 7953 | 7865 | 264 | | Solmate | 7878 | 7922 | 7944 | 7856 | 265 | 266 | 267 | #### isApprovedForAll 268 | 269 | How much gas to check if an address is allowed to control another's nfts. 270 | 271 | 272 | | Implementation | -- | 273 | |------------------------|----| 274 | | ERC721A |8226| 275 | | ERC721B |8270| 276 | | ERC721K |8211| 277 | |OpenZeppelin Consecutive|8204| 278 | | OpenZeppelin Enumerable|8250| 279 | | OpenZeppelin |8184| 280 | | Solady |8081| 281 | | Solmate |8189| 282 | 283 | -------------------------------------------------------------------------------- /benchmarks/0.8.23/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|-------| 27 | | OpenZeppelin |1032616| 28 | | Solmate |1055915| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33906| 39 | | Solmate |33170| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35407|130865|248539| 50 | | Solmate |36552|130616|248280| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |38002| 61 | | Solmate |36926| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39767|137971|259094| 72 | | Solmate |39907|135144|254289| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.23/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 7927 | 32599 | 7692 | 670317 | 7579 | 45274 | 28152 | 37744 | 20666 | 32 | | 7960 | 32764 | 7690 | 463270 | 7542 | 43739 | 26617 | 38013 | 20935 | 33 | | 7960 | 32787 | 7691 | 870240 | 7565 | 43695 | 26573 | 37991 | 20913 | 34 | | 7927 | 32548 | 7692 | 654881 | 7556 | 43305 | 26183 | 37677 | 20599 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.24-via-ir/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|------| 27 | | OpenZeppelin |956352| 28 | | Solmate |736471| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33655| 39 | | Solmate |33026| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35667|131598|249830| 50 | | Solmate |36907|131491|249838| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |37950| 61 | | Solmate |36834| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39561|138209|259797| 72 | | Solmate |39545|134484|253249| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.24-via-ir/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 8091 | 32530 | 7788 | 677031 | 7487 | 45055 | 27933 | 37864 | 20793 | 32 | | 7961 | 32524 | 7725 | 453758 | 7490 | 43266 | 26144 | 37830 | 20759 | 33 | | 8049 | 32562 | 7747 | 838842 | 7490 | 43266 | 26144 | 37896 | 20825 | 34 | | 8025 | 32485 | 7744 | 641359 | 7487 | 43114 | 25992 | 37764 | 20693 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.24-via-ir/ERC721.md: -------------------------------------------------------------------------------- 1 | # ERC721 Benchmark 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | The most popular way of implementing ERC721 is by having sequential ids for each token, so if a collection has 10000 tokens, the ids of each token are in the range 1~10000. Some of the latest implementations focus on making mint cheaper at the cost of an expensive transfer, this bechmark highlights that. 6 | 7 | We'll be comparing the following implementations: 8 | 9 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 10 | - [Solady](https://github.com/Vectorized/solady/) 11 | - [Solmate](https://github.com/rari-capital/solmate) 12 | - [ERC721A](https://github.com/chiru-labs/ERC721A) 13 | - [ERC721B](https://github.com/beskay/ERC721B) 14 | - [ERC721K](https://github.com/kadenzipfel/ERC721K) 15 | 16 | ## Methods TODO 17 | 18 | - [x] deploy 19 | - [x] mint (not in the specification, but common) 20 | - [x] safeMint (not in the specification, but common) 21 | - [x] burn (not in the specification, but common) 22 | - [x] balanceOf 23 | - [x] ownerOf 24 | - [x] transferFrom 25 | - [x] safeTransferFrom 26 | - [x] approve 27 | - [x] setApprovalForAll 28 | - [x] getApproved 29 | - [x] isApprovedForAll 30 | 31 | ## Deployment 32 | 33 | How much gas to deploy the contract as is? 34 | 35 | 36 | | Implementation | -- | 37 | |------------------------|-------| 38 | | ERC721A | 912163| 39 | | ERC721B | 920117| 40 | | ERC721K |1006737| 41 | |OpenZeppelin Consecutive|1029942| 42 | | OpenZeppelin Enumerable|1121929| 43 | | OpenZeppelin | 850372| 44 | | Solady | 611828| 45 | | Solmate | 801067| 46 | 47 | 48 | ## Deployment with ERC2309 minting 49 | 50 | How much gas to deploy the ERC2309 compliant contracts when minting N tokens in the constructor? 51 | 52 | 53 | | Implementation | 5 | 10 | 50 | 100 | 200 | 300 | 54 | |------------------------|------|------|------|------|------|------| 55 | | ERC721A |779246|779345|779279|779389|779323|779301| 56 | |OpenZeppelin Consecutive|852475|852574|852508|852618|852552|852530| 57 | 58 | 59 | ## Write methods 60 | 61 | ### mint 62 | 63 | How much gas to mint N tokens? 64 | 65 | 66 | | Implementation | 1 | 2 | 3 | 4 | 5 | 10 | 50 | 100 | 67 | |------------------------|------|------|------|------|------|-------|-------|--------| 68 | | ERC721A | 57002| 59107| 61066| 62918| 64896| 74559 | 151995| 248999 | 69 | | ERC721B | 52176| 54576| 56830| 58977| 61250| 72388 | 161624| 273378 | 70 | | ERC721K | 57609| 59784| 61813| 63735| 65783| 75796 | 156032| 256536 | 71 | |OpenZeppelin Consecutive| 79151|104919|130541|156056|181697| 309675|1333631| 2613785| 72 | | OpenZeppelin Enumerable|146003|260464|374779|488987|603321|1174764|5746440|11461244| 73 | | OpenZeppelin | 74324| 99250|124030|148703|173502| 297270|1287546| 2525600| 74 | | Solady | 74108| 98839|123424|147902|172506| 295299|1277775| 2506079| 75 | | Solmate | 74329| 99260|124045|148723|173527| 297320|1287796| 2526100| 76 | 77 | 78 | ### safeMint 79 | 80 | How much gas to safeMint N tokens? 81 | 82 | 83 | | Implementation | 1 | 2 | 3 | 4 | 5 | 10 | 50 | 100 | 84 | |------------------------|------|------|------|------|------|-------|-------|--------| 85 | | ERC721A | 59980| 61966| 63947| 65772| 67862| 77484 | 154849| 251661 | 86 | | ERC721B | 55363| 57644| 59920| 62040| 64425| 75522 | 164687| 276249 | 87 | | ERC721K | 60524| 62580| 64631| 66526| 68686| 78658 | 158823| 259135 | 88 | |OpenZeppelin Consecutive| 82113|107977|133836|159539|185507| 314519|1347009| 2637737| 89 | | OpenZeppelin Enumerable|149000|263557|378109|492505|607166|1179643|5759853|11485231| 90 | | OpenZeppelin | 77299|102321|127338|152199|177325| 302127|1300937| 2549565| 91 | | Solady | 77091|101924|126752|151424|176361| 300218|1291468| 2530646| 92 | | Solmate | 77268|102257|127241|152069|177162| 301799|1299284| 2546246| 93 | 94 | 95 | ### burn 96 | 97 | How much gas to burn the `nth` token? 98 | 99 | 100 | | Implementation | 1 | 10 | 50 | 100 | 101 | |------------------------|-----|------|------|------| 102 | | ERC721A |69732|106847|195242|305864| 103 | | ERC721B | 8453| 8560 | 8475 | 8497 | 104 | | ERC721K |73478|112150|207551|327009| 105 | |OpenZeppelin Consecutive|20779| 20886| 20801| 20823| 106 | | OpenZeppelin Enumerable|47407| 51972| 51904| 51922| 107 | | OpenZeppelin |18241| 18348| 18263| 18285| 108 | | Solady |18146| 18253| 18168| 18190| 109 | | Solmate |18212| 18319| 18234| 18256| 110 | 111 | 112 | ### transferFrom 113 | 114 | How much gas to transfer the `nth` token id if you own all tokens from 1 to 100? 115 | 116 | #### To a wallet that already owns a token from the collection 117 | 118 | 119 | | Implementation | 1 | 10 | 50 | 100 | 120 | |------------------------|------|------|------|------| 121 | | ERC721A | 53027| 90057|178471|289049| 122 | | ERC721B |294990|273754|179208| 43986| 123 | | ERC721K | 56471| 95058|190478|309892| 124 | |OpenZeppelin Consecutive| 28826| 28848| 28782| 28760| 125 | | OpenZeppelin Enumerable| 79656| 67378| 67312| 67290| 126 | | OpenZeppelin | 28538| 28560| 28494| 28472| 127 | | Solady | 28004| 28026| 27960| 27938| 128 | | Solmate | 28433| 28455| 28389| 28367| 129 | 130 | 131 | #### To a wallet that owns no token from the collection 132 | 133 | 134 | | Implementation | 1 | 10 | 50 | 100 | 135 | |------------------------|------|------|------|------| 136 | | ERC721A | 70093|107123|195537|306159| 137 | | ERC721B |294956|273720|179174| 43996| 138 | | ERC721K | 73537|112124|207544|327002| 139 | |OpenZeppelin Consecutive| 45892| 45914| 45848| 45870| 140 | | OpenZeppelin Enumerable| 76822| 79644| 79578| 79600| 141 | | OpenZeppelin | 45604| 45626| 45560| 45582| 142 | | Solady | 45070| 45092| 45026| 45048| 143 | | Solmate | 45499| 45521| 45455| 45477| 144 | 145 | 146 | ### safeTransferFrom 147 | 148 | How much gas to transfer the `nth` token id if you own all tokens from 1 to 100? 149 | 150 | #### To a wallet that already owns a token from the collection 151 | 152 | 153 | | Implementation | 1 | 10 | 50 | 100 | 154 | |------------------------|------|------|------|------| 155 | | ERC721A | 55838| 92802|181304|291820| 156 | | ERC721B |297851|276549|182091| 46807| 157 | | ERC721K | 59317| 97838|193346|312699| 158 | |OpenZeppelin Consecutive| 31640| 31596| 31618| 31534| 159 | | OpenZeppelin Enumerable| 82484| 70140| 70162| 70078| 160 | | OpenZeppelin | 31344| 31300| 31322| 31238| 161 | | Solady | 30676| 30632| 30654| 30570| 162 | | Solmate | 31169| 31125| 31147| 31063| 163 | 164 | 165 | #### To a wallet that owns no token from the collection 166 | 167 | 168 | | Implementation | 1 | 10 | 50 | 100 | 169 | |------------------------|------|------|------|------| 170 | | ERC721A | 72904|109868|198370|309014| 171 | | ERC721B |297817|276515|182057| 46901| 172 | | ERC721K | 76383|114904|210412|329893| 173 | |OpenZeppelin Consecutive| 48706| 48662| 48684| 48728| 174 | | OpenZeppelin Enumerable| 79650| 82406| 82428| 82472| 175 | | OpenZeppelin | 48410| 48366| 48388| 48432| 176 | | Solady | 47742| 47698| 47720| 47764| 177 | | Solmate | 48235| 48191| 48213| 48257| 178 | 179 | 180 | ### setApprovalForAll 181 | 182 | How much gas for `setApprovalForAll`? 183 | 184 | 185 | | Implementation | -- | 186 | |------------------------|-----| 187 | | ERC721A |32787| 188 | | ERC721B |32852| 189 | | ERC721K |32804| 190 | |OpenZeppelin Consecutive|32832| 191 | | OpenZeppelin Enumerable|32841| 192 | | OpenZeppelin |32775| 193 | | Solady |32633| 194 | | Solmate |32758| 195 | 196 | 197 | ### approve 198 | 199 | How much gas to approve the `nth` token id if you own all tokens from 1 to 100? 200 | 201 | 202 | | Implementation | 1 | 10 | 50 | 100 | 203 | |------------------------|------|------|------|------| 204 | | ERC721A | 37039| 56991|145449|256005| 205 | | ERC721B |271322|250108|155606| 37462| 206 | | ERC721K | 37507| 59016|154480|273872| 207 | |OpenZeppelin Consecutive| 35093| 35137| 35115| 35071| 208 | | OpenZeppelin Enumerable| 34926| 34970| 34948| 34904| 209 | | OpenZeppelin | 34926| 34970| 34948| 34904| 210 | | Solady | 34707| 34751| 34729| 34685| 211 | | Solmate | 34830| 34874| 34852| 34808| 212 | 213 | 214 | ## View methods 215 | 216 | #### balanceOf 217 | 218 | How much gas to run balanceOf in an account with N tokens. 219 | 220 | 221 | | Implementation | 1 | 10 | 50 | 100 | 222 | |------------------------|-------|-------|-------|-------| 223 | | ERC721A | 7934 | 7873 | 7851 | 7829 | 224 | | ERC721B |2719313|2719495|2720553|2721881| 225 | | ERC721K | 7975 | 7914 | 7892 | 7870 | 226 | |OpenZeppelin Consecutive| 7906 | 7845 | 7823 | 7801 | 227 | | OpenZeppelin Enumerable| 8017 | 7956 | 7934 | 7912 | 228 | | OpenZeppelin | 7931 | 7870 | 7848 | 7826 | 229 | | Solady | 7894 | 7833 | 7811 | 7789 | 230 | | Solmate | 7939 | 7878 | 7856 | 7834 | 231 | 232 | 233 | #### ownerOf 234 | 235 | How much gas to find the owner of a token when the owner owns 100 tokens and the token to find is the nth token. 236 | 237 | 238 | | Implementation | 1 | 10 | 50 | 100 | 239 | |------------------------|------|------|------|------| 240 | | ERC721A | 10132| 30018|118564|229028| 241 | | ERC721B |244356|223076|128662| 10426| 242 | | ERC721K | 10576| 32019|127571|246872| 243 | |OpenZeppelin Consecutive| 8034 | 8012 | 8078 | 7942 | 244 | | OpenZeppelin Enumerable| 7990 | 7968 | 8034 | 7898 | 245 | | OpenZeppelin | 7924 | 7902 | 7968 | 7832 | 246 | | Solady | 7909 | 7887 | 7953 | 7817 | 247 | | Solmate | 7900 | 7878 | 7944 | 7808 | 248 | 249 | 250 | #### getApproved 251 | 252 | How much gas to find the approved address of the nth token when the onwer owns 100 tokens and there are no approved addresses. 253 | 254 | 255 | | Implementation | 1 | 10 | 50 | 100 | 256 | |------------------------|------|------|------|------| 257 | | ERC721A | 10110| 30062|118564|229076| 258 | | ERC721B |244334|223120|128662| 10474| 259 | | ERC721K | 10554| 32063|127571|246920| 260 | |OpenZeppelin Consecutive| 8012 | 8056 | 8078 | 7990 | 261 | | OpenZeppelin Enumerable| 7968 | 8012 | 8034 | 7946 | 262 | | OpenZeppelin | 7902 | 7946 | 7968 | 7880 | 263 | | Solady | 7887 | 7931 | 7953 | 7865 | 264 | | Solmate | 7878 | 7922 | 7944 | 7856 | 265 | 266 | 267 | #### isApprovedForAll 268 | 269 | How much gas to check if an address is allowed to control another's nfts. 270 | 271 | 272 | | Implementation | -- | 273 | |------------------------|----| 274 | | ERC721A |8226| 275 | | ERC721B |8270| 276 | | ERC721K |8211| 277 | |OpenZeppelin Consecutive|8204| 278 | | OpenZeppelin Enumerable|8250| 279 | | OpenZeppelin |8184| 280 | | Solady |8081| 281 | | Solmate |8189| 282 | 283 | -------------------------------------------------------------------------------- /benchmarks/0.8.24/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|-------| 27 | | OpenZeppelin |1032616| 28 | | Solmate |1055915| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33906| 39 | | Solmate |33170| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35407|130865|248539| 50 | | Solmate |36552|130616|248280| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |38002| 61 | | Solmate |36926| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39767|137971|259094| 72 | | Solmate |39907|135144|254289| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.24/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 7927 | 32599 | 7692 | 670317 | 7579 | 45274 | 28152 | 37744 | 20666 | 32 | | 7960 | 32764 | 7690 | 463270 | 7542 | 43739 | 26617 | 38013 | 20935 | 33 | | 7960 | 32787 | 7691 | 870240 | 7565 | 43695 | 26573 | 37991 | 20913 | 34 | | 7927 | 32548 | 7692 | 654881 | 7556 | 43305 | 26183 | 37677 | 20599 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.25-via-ir/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|------| 27 | | OpenZeppelin |956352| 28 | | Solmate |736471| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33655| 39 | | Solmate |33026| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35667|131598|249830| 50 | | Solmate |36907|131491|249838| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |37950| 61 | | Solmate |36834| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39561|138209|259797| 72 | | Solmate |39545|134484|253249| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.25-via-ir/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 7927 | 32599 | 7692 | 670317 | 7579 | 45274 | 28152 | 37744 | 20666 | 32 | | 7960 | 32764 | 7690 | 463270 | 7542 | 43739 | 26617 | 38013 | 20935 | 33 | | 7960 | 32787 | 7691 | 870240 | 7565 | 43695 | 26573 | 37991 | 20913 | 34 | | 7927 | 32548 | 7692 | 654881 | 7556 | 43305 | 26183 | 37677 | 20599 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.25-via-ir/ERC721.md: -------------------------------------------------------------------------------- 1 | # ERC721 Benchmark 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | The most popular way of implementing ERC721 is by having sequential ids for each token, so if a collection has 10000 tokens, the ids of each token are in the range 1~10000. Some of the latest implementations focus on making mint cheaper at the cost of an expensive transfer, this bechmark highlights that. 6 | 7 | We'll be comparing the following implementations: 8 | 9 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 10 | - [Solady](https://github.com/Vectorized/solady/) 11 | - [Solmate](https://github.com/rari-capital/solmate) 12 | - [ERC721A](https://github.com/chiru-labs/ERC721A) 13 | - [ERC721B](https://github.com/beskay/ERC721B) 14 | - [ERC721K](https://github.com/kadenzipfel/ERC721K) 15 | 16 | ## Methods TODO 17 | 18 | - [x] deploy 19 | - [x] mint (not in the specification, but common) 20 | - [x] safeMint (not in the specification, but common) 21 | - [x] burn (not in the specification, but common) 22 | - [x] balanceOf 23 | - [x] ownerOf 24 | - [x] transferFrom 25 | - [x] safeTransferFrom 26 | - [x] approve 27 | - [x] setApprovalForAll 28 | - [x] getApproved 29 | - [x] isApprovedForAll 30 | 31 | ## Deployment 32 | 33 | How much gas to deploy the contract as is? 34 | 35 | 36 | | Implementation | -- | 37 | |------------------------|-------| 38 | | ERC721A | 912156| 39 | | ERC721B | 920104| 40 | | ERC721K |1006723| 41 | |OpenZeppelin Consecutive|1029935| 42 | | OpenZeppelin Enumerable|1121923| 43 | | OpenZeppelin | 850365| 44 | | Solady | 611828| 45 | | Solmate | 801061| 46 | 47 | 48 | ## Deployment with ERC2309 minting 49 | 50 | How much gas to deploy the ERC2309 compliant contracts when minting N tokens in the constructor? 51 | 52 | 53 | | Implementation | 5 | 10 | 50 | 100 | 200 | 300 | 54 | |------------------------|------|------|------|------|------|------| 55 | | ERC721A |779240|779339|779273|779383|779317|779295| 56 | |OpenZeppelin Consecutive|852448|852547|852481|852591|852525|852503| 57 | 58 | 59 | ## Write methods 60 | 61 | ### mint 62 | 63 | How much gas to mint N tokens? 64 | 65 | 66 | | Implementation | 1 | 2 | 3 | 4 | 5 | 10 | 50 | 100 | 67 | |------------------------|------|------|------|------|------|-------|-------|--------| 68 | | ERC721A | 57002| 59107| 61066| 62918| 64896| 74559 | 151995| 248999 | 69 | | ERC721B | 52176| 54576| 56830| 58977| 61250| 72388 | 161624| 273378 | 70 | | ERC721K | 57609| 59784| 61813| 63735| 65783| 75796 | 156032| 256536 | 71 | |OpenZeppelin Consecutive| 79151|104919|130541|156056|181697| 309675|1333631| 2613785| 72 | | OpenZeppelin Enumerable|146003|260464|374779|488987|603321|1174764|5746440|11461244| 73 | | OpenZeppelin | 74324| 99250|124030|148703|173502| 297270|1287546| 2525600| 74 | | Solady | 74108| 98839|123424|147902|172506| 295299|1277775| 2506079| 75 | | Solmate | 74329| 99260|124045|148723|173527| 297320|1287796| 2526100| 76 | 77 | 78 | ### safeMint 79 | 80 | How much gas to safeMint N tokens? 81 | 82 | 83 | | Implementation | 1 | 2 | 3 | 4 | 5 | 10 | 50 | 100 | 84 | |------------------------|------|------|------|------|------|-------|-------|--------| 85 | | ERC721A | 59980| 61966| 63947| 65772| 67862| 77484 | 154849| 251661 | 86 | | ERC721B | 55363| 57644| 59920| 62040| 64425| 75522 | 164687| 276249 | 87 | | ERC721K | 60524| 62580| 64631| 66526| 68686| 78658 | 158823| 259135 | 88 | |OpenZeppelin Consecutive| 82113|107977|133836|159539|185507| 314519|1347009| 2637737| 89 | | OpenZeppelin Enumerable|149000|263557|378109|492505|607166|1179643|5759853|11485231| 90 | | OpenZeppelin | 77299|102321|127338|152199|177325| 302127|1300937| 2549565| 91 | | Solady | 77091|101924|126752|151424|176361| 300218|1291468| 2530646| 92 | | Solmate | 77268|102257|127241|152069|177162| 301799|1299284| 2546246| 93 | 94 | 95 | ### burn 96 | 97 | How much gas to burn the `nth` token? 98 | 99 | 100 | | Implementation | 1 | 10 | 50 | 100 | 101 | |------------------------|-----|------|------|------| 102 | | ERC721A |69732|106847|195242|305864| 103 | | ERC721B | 8453| 8560 | 8475 | 8497 | 104 | | ERC721K |73478|112150|207551|327009| 105 | |OpenZeppelin Consecutive|20779| 20886| 20801| 20823| 106 | | OpenZeppelin Enumerable|47407| 51972| 51904| 51922| 107 | | OpenZeppelin |18241| 18348| 18263| 18285| 108 | | Solady |18146| 18253| 18168| 18190| 109 | | Solmate |18212| 18319| 18234| 18256| 110 | 111 | 112 | ### transferFrom 113 | 114 | How much gas to transfer the `nth` token id if you own all tokens from 1 to 100? 115 | 116 | #### To a wallet that already owns a token from the collection 117 | 118 | 119 | | Implementation | 1 | 10 | 50 | 100 | 120 | |------------------------|------|------|------|------| 121 | | ERC721A | 53027| 90057|178471|289049| 122 | | ERC721B |294990|273754|179208| 43986| 123 | | ERC721K | 56471| 95058|190478|309892| 124 | |OpenZeppelin Consecutive| 28826| 28848| 28782| 28760| 125 | | OpenZeppelin Enumerable| 79656| 67378| 67312| 67290| 126 | | OpenZeppelin | 28538| 28560| 28494| 28472| 127 | | Solady | 28004| 28026| 27960| 27938| 128 | | Solmate | 28433| 28455| 28389| 28367| 129 | 130 | 131 | #### To a wallet that owns no token from the collection 132 | 133 | 134 | | Implementation | 1 | 10 | 50 | 100 | 135 | |------------------------|------|------|------|------| 136 | | ERC721A | 70093|107123|195537|306159| 137 | | ERC721B |294956|273720|179174| 43996| 138 | | ERC721K | 73537|112124|207544|327002| 139 | |OpenZeppelin Consecutive| 45892| 45914| 45848| 45870| 140 | | OpenZeppelin Enumerable| 76822| 79644| 79578| 79600| 141 | | OpenZeppelin | 45604| 45626| 45560| 45582| 142 | | Solady | 45070| 45092| 45026| 45048| 143 | | Solmate | 45499| 45521| 45455| 45477| 144 | 145 | 146 | ### safeTransferFrom 147 | 148 | How much gas to transfer the `nth` token id if you own all tokens from 1 to 100? 149 | 150 | #### To a wallet that already owns a token from the collection 151 | 152 | 153 | | Implementation | 1 | 10 | 50 | 100 | 154 | |------------------------|------|------|------|------| 155 | | ERC721A | 55838| 92802|181304|291820| 156 | | ERC721B |297851|276549|182091| 46807| 157 | | ERC721K | 59317| 97838|193346|312699| 158 | |OpenZeppelin Consecutive| 31640| 31596| 31618| 31534| 159 | | OpenZeppelin Enumerable| 82484| 70140| 70162| 70078| 160 | | OpenZeppelin | 31344| 31300| 31322| 31238| 161 | | Solady | 30676| 30632| 30654| 30570| 162 | | Solmate | 31169| 31125| 31147| 31063| 163 | 164 | 165 | #### To a wallet that owns no token from the collection 166 | 167 | 168 | | Implementation | 1 | 10 | 50 | 100 | 169 | |------------------------|------|------|------|------| 170 | | ERC721A | 72904|109868|198370|309014| 171 | | ERC721B |297817|276515|182057| 46901| 172 | | ERC721K | 76383|114904|210412|329893| 173 | |OpenZeppelin Consecutive| 48706| 48662| 48684| 48728| 174 | | OpenZeppelin Enumerable| 79650| 82406| 82428| 82472| 175 | | OpenZeppelin | 48410| 48366| 48388| 48432| 176 | | Solady | 47742| 47698| 47720| 47764| 177 | | Solmate | 48235| 48191| 48213| 48257| 178 | 179 | 180 | ### setApprovalForAll 181 | 182 | How much gas for `setApprovalForAll`? 183 | 184 | 185 | | Implementation | -- | 186 | |------------------------|-----| 187 | | ERC721A |32787| 188 | | ERC721B |32852| 189 | | ERC721K |32804| 190 | |OpenZeppelin Consecutive|32832| 191 | | OpenZeppelin Enumerable|32841| 192 | | OpenZeppelin |32775| 193 | | Solady |32633| 194 | | Solmate |32758| 195 | 196 | 197 | ### approve 198 | 199 | How much gas to approve the `nth` token id if you own all tokens from 1 to 100? 200 | 201 | 202 | | Implementation | 1 | 10 | 50 | 100 | 203 | |------------------------|------|------|------|------| 204 | | ERC721A | 37039| 56991|145449|256005| 205 | | ERC721B |271322|250108|155606| 37462| 206 | | ERC721K | 37507| 59016|154480|273872| 207 | |OpenZeppelin Consecutive| 35093| 35137| 35115| 35071| 208 | | OpenZeppelin Enumerable| 34926| 34970| 34948| 34904| 209 | | OpenZeppelin | 34926| 34970| 34948| 34904| 210 | | Solady | 34707| 34751| 34729| 34685| 211 | | Solmate | 34830| 34874| 34852| 34808| 212 | 213 | 214 | ## View methods 215 | 216 | #### balanceOf 217 | 218 | How much gas to run balanceOf in an account with N tokens. 219 | 220 | 221 | | Implementation | 1 | 10 | 50 | 100 | 222 | |------------------------|-------|-------|-------|-------| 223 | | ERC721A | 7934 | 7873 | 7851 | 7829 | 224 | | ERC721B |2719313|2719495|2720553|2721881| 225 | | ERC721K | 7975 | 7914 | 7892 | 7870 | 226 | |OpenZeppelin Consecutive| 7906 | 7845 | 7823 | 7801 | 227 | | OpenZeppelin Enumerable| 8017 | 7956 | 7934 | 7912 | 228 | | OpenZeppelin | 7931 | 7870 | 7848 | 7826 | 229 | | Solady | 7894 | 7833 | 7811 | 7789 | 230 | | Solmate | 7939 | 7878 | 7856 | 7834 | 231 | 232 | 233 | #### ownerOf 234 | 235 | How much gas to find the owner of a token when the owner owns 100 tokens and the token to find is the nth token. 236 | 237 | 238 | | Implementation | 1 | 10 | 50 | 100 | 239 | |------------------------|------|------|------|------| 240 | | ERC721A | 10132| 30018|118564|229028| 241 | | ERC721B |244356|223076|128662| 10426| 242 | | ERC721K | 10576| 32019|127571|246872| 243 | |OpenZeppelin Consecutive| 8034 | 8012 | 8078 | 7942 | 244 | | OpenZeppelin Enumerable| 7990 | 7968 | 8034 | 7898 | 245 | | OpenZeppelin | 7924 | 7902 | 7968 | 7832 | 246 | | Solady | 7909 | 7887 | 7953 | 7817 | 247 | | Solmate | 7900 | 7878 | 7944 | 7808 | 248 | 249 | 250 | #### getApproved 251 | 252 | How much gas to find the approved address of the nth token when the onwer owns 100 tokens and there are no approved addresses. 253 | 254 | 255 | | Implementation | 1 | 10 | 50 | 100 | 256 | |------------------------|------|------|------|------| 257 | | ERC721A | 10110| 30062|118564|229076| 258 | | ERC721B |244334|223120|128662| 10474| 259 | | ERC721K | 10554| 32063|127571|246920| 260 | |OpenZeppelin Consecutive| 8012 | 8056 | 8078 | 7990 | 261 | | OpenZeppelin Enumerable| 7968 | 8012 | 8034 | 7946 | 262 | | OpenZeppelin | 7902 | 7946 | 7968 | 7880 | 263 | | Solady | 7887 | 7931 | 7953 | 7865 | 264 | | Solmate | 7878 | 7922 | 7944 | 7856 | 265 | 266 | 267 | #### isApprovedForAll 268 | 269 | How much gas to check if an address is allowed to control another's nfts. 270 | 271 | 272 | | Implementation | -- | 273 | |------------------------|----| 274 | | ERC721A |8226| 275 | | ERC721B |8270| 276 | | ERC721K |8211| 277 | |OpenZeppelin Consecutive|8204| 278 | | OpenZeppelin Enumerable|8250| 279 | | OpenZeppelin |8184| 280 | | Solady |8081| 281 | | Solmate |8189| 282 | 283 | -------------------------------------------------------------------------------- /benchmarks/0.8.25/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|-------| 27 | | OpenZeppelin |1032609| 28 | | Solmate |1055915| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33906| 39 | | Solmate |33170| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35407|130865|248539| 50 | | Solmate |36552|130616|248280| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |38002| 61 | | Solmate |36926| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39767|137971|259094| 72 | | Solmate |39907|135144|254289| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.25/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 7927 | 32599 | 7692 | 670317 | 7579 | 45274 | 28152 | 37744 | 20666 | 32 | | 7960 | 32764 | 7690 | 463270 | 7542 | 43739 | 26617 | 38013 | 20935 | 33 | | 7960 | 32787 | 7691 | 870240 | 7565 | 43695 | 26573 | 37991 | 20913 | 34 | | 7927 | 32548 | 7692 | 654881 | 7556 | 43305 | 26183 | 37677 | 20599 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.26-via-ir/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|------| 27 | | OpenZeppelin |890595| 28 | | Solmate |755090| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33719| 39 | | Solmate |33085| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35716|131561|249715| 50 | | Solmate |36911|131373|249582| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |37994| 61 | | Solmate |36858| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39679|138235|259747| 72 | | Solmate |39590|134484|253223| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.26-via-ir/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 7927 | 32599 | 7692 | 670317 | 7579 | 45274 | 28152 | 37744 | 20666 | 32 | | 7960 | 32764 | 7690 | 463270 | 7542 | 43739 | 26617 | 38013 | 20935 | 33 | | 7960 | 32787 | 7691 | 870240 | 7565 | 43695 | 26573 | 37991 | 20913 | 34 | | 7927 | 32548 | 7692 | 654881 | 7556 | 43305 | 26183 | 37677 | 20599 | 35 | -------------------------------------------------------------------------------- /benchmarks/0.8.26/ERC1155.md: -------------------------------------------------------------------------------- 1 | # ERC1155 Benchmarks (WIP) 2 | 3 | Benchmarks for implementations of the ERC115 standard. 4 | 5 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 6 | - [Solmate](https://github.com/rari-capital/solmate) 7 | 8 | ## Methods TODO 9 | 10 | - [x] deploy 11 | - [x] mint (not in the specification, but common) 12 | - [x] mintBatch (not in the specification, but common) 13 | - [x] safeTransferFrom 14 | - [x] safeBatchTransferFrom 15 | - [ ] setApprovalForAll 16 | - [ ] balanceOf 17 | - [ ] balanceOfBatch 18 | - [ ] isApprovedForAll 19 | 20 | ## Deployment 21 | 22 | How much gas to deploy the contract as is? 23 | 24 | 25 | |Implementation| -- | 26 | |--------------|-------| 27 | | OpenZeppelin |1032404| 28 | | Solmate |1060327| 29 | 30 | 31 | ### mint 32 | 33 | How much gas to mint a token? 34 | 35 | 36 | |Implementation| -- | 37 | |--------------|-----| 38 | | OpenZeppelin |33906| 39 | | Solmate |33170| 40 | 41 | 42 | ### mintBatch 43 | 44 | How much gas to mint n different tokens? 45 | 46 | 47 | |Implementation| 1 | 5 | 10 | 48 | |--------------|-----|------|------| 49 | | OpenZeppelin |35443|130945|248679| 50 | | Solmate |36536|130648|248372| 51 | 52 | 53 | ### safeTransferFrom 54 | 55 | How much gas to transfer one token? 56 | 57 | 58 | |Implementation| -- | 59 | |--------------|-----| 60 | | OpenZeppelin |38038| 61 | | Solmate |36926| 62 | 63 | 64 | ### safeBatchTransferFrom 65 | 66 | How much gas to transfer n tokens to the same address? 67 | 68 | 69 | |Implementation| 1 | 5 | 10 | 70 | |--------------|-----|------|------| 71 | | OpenZeppelin |39850|138098|259281| 72 | | Solmate |39892|135153|254328| 73 | 74 | -------------------------------------------------------------------------------- /benchmarks/0.8.26/ERC20.md: -------------------------------------------------------------------------------- 1 | # ERC20 Benchmarks 2 | 3 | Benchmarks for implementations of the ERC20 standard. 4 | 5 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 6 | 7 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 8 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 9 | - [Solmate](https://github.com/rari-capital/solmate) 10 | - [Maple](https://github.com/maple-labs/erc20) 11 | 12 | ## Methods 13 | 14 | ### Write Methods 15 | - [x] deploy: How much gas to deploy the contract as is? 16 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 17 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 18 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 19 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 20 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 21 | 22 | ### Read Methods 23 | - [x] totalSupply: How much gas to check the total supply of tokens? 24 | - [x] balanceOf: How much gas to check the balance of an account? 25 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 26 | 27 | ## Table 28 | 29 | | Implementation | allowance | approve | balanceOf | deploy | totalSupply | transferFromToNonOwner | transferFromToOwner | transferToNonOwner | transferToOwner | 30 | | - | - | - | - | - | - | - | - | - | - | 31 | | 7927 | 32599 | 7692 | 670317 | 7579 | 45274 | 28152 | 37744 | 20666 | 32 | | 7960 | 32764 | 7690 | 463270 | 7542 | 43739 | 26617 | 38013 | 20935 | 33 | | 7960 | 32787 | 7691 | 870240 | 7565 | 43695 | 26573 | 37991 | 20913 | 34 | | 7927 | 32548 | 7692 | 654881 | 7556 | 43305 | 26183 | 37677 | 20599 | 35 | -------------------------------------------------------------------------------- /codegen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | cd templates 3 | find . -name '*.gyb' | \ 4 | while read file; do \ 5 | ../scripts/gyb.py --line-directive '' -o "../src/test/${file%.gyb}" "$file"; \ 6 | done 7 | cd -- -------------------------------------------------------------------------------- /foundry.toml: -------------------------------------------------------------------------------- 1 | [profile.default] 2 | src = 'src' 3 | out = 'out' 4 | libs = ['lib'] 5 | solc = "0.8.20" 6 | 7 | # See more config options https://github.com/gakonst/foundry/tree/master/config -------------------------------------------------------------------------------- /generator/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | xcuserdata/ 5 | DerivedData/ 6 | .swiftpm/configuration/registries.json 7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 8 | .netrc 9 | .vscode -------------------------------------------------------------------------------- /generator/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "combine-schedulers", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/pointfreeco/combine-schedulers", 7 | "state" : { 8 | "revision" : "9dc9cbe4bc45c65164fa653a563d8d8db61b09bb", 9 | "version" : "1.0.0" 10 | } 11 | }, 12 | { 13 | "identity" : "swift-argument-parser", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/apple/swift-argument-parser.git", 16 | "state" : { 17 | "revision" : "c8ed701b513cf5177118a175d85fbbbcd707ab41", 18 | "version" : "1.3.0" 19 | } 20 | }, 21 | { 22 | "identity" : "swift-clocks", 23 | "kind" : "remoteSourceControl", 24 | "location" : "https://github.com/pointfreeco/swift-clocks", 25 | "state" : { 26 | "revision" : "a8421d68068d8f45fbceb418fbf22c5dad4afd33", 27 | "version" : "1.0.2" 28 | } 29 | }, 30 | { 31 | "identity" : "swift-concurrency-extras", 32 | "kind" : "remoteSourceControl", 33 | "location" : "https://github.com/pointfreeco/swift-concurrency-extras", 34 | "state" : { 35 | "revision" : "bb5059bde9022d69ac516803f4f227d8ac967f71", 36 | "version" : "1.1.0" 37 | } 38 | }, 39 | { 40 | "identity" : "swift-dependencies", 41 | "kind" : "remoteSourceControl", 42 | "location" : "https://github.com/pointfreeco/swift-dependencies", 43 | "state" : { 44 | "revision" : "adb04a8e35f07edc001877af9f9f97fcc21d409e", 45 | "version" : "1.2.0" 46 | } 47 | }, 48 | { 49 | "identity" : "swift-prelude", 50 | "kind" : "remoteSourceControl", 51 | "location" : "https://github.com/pointfreeco/swift-prelude.git", 52 | "state" : { 53 | "branch" : "main", 54 | "revision" : "da5ead261fbfa57b9d0e993e9f9405c1734a1a1c" 55 | } 56 | }, 57 | { 58 | "identity" : "swift-snapshot-testing", 59 | "kind" : "remoteSourceControl", 60 | "location" : "https://github.com/pointfreeco/swift-snapshot-testing", 61 | "state" : { 62 | "revision" : "8e68404f641300bfd0e37d478683bb275926760c", 63 | "version" : "1.15.2" 64 | } 65 | }, 66 | { 67 | "identity" : "swift-syntax", 68 | "kind" : "remoteSourceControl", 69 | "location" : "https://github.com/apple/swift-syntax", 70 | "state" : { 71 | "revision" : "64889f0c732f210a935a0ad7cda38f77f876262d", 72 | "version" : "509.1.1" 73 | } 74 | }, 75 | { 76 | "identity" : "xctest-dynamic-overlay", 77 | "kind" : "remoteSourceControl", 78 | "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", 79 | "state" : { 80 | "revision" : "b58e6627149808b40634c4552fcf2f44d0b3ca87", 81 | "version" : "1.1.0" 82 | } 83 | } 84 | ], 85 | "version" : 2 86 | } 87 | -------------------------------------------------------------------------------- /generator/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.9 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "solbench", 7 | platforms: [ 8 | .macOS(.v13), 9 | ], 10 | products: [ 11 | .executable(name: "solbench", targets: ["Cmd"]), 12 | ], 13 | dependencies: [ 14 | .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.0"), 15 | .package(url: "https://github.com/pointfreeco/swift-prelude.git", branch: "main"), 16 | .package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.15.2"), 17 | ], 18 | targets: [ 19 | .executableTarget( 20 | name: "Cmd", 21 | dependencies: [ 22 | .product(name: "ArgumentParser", package: "swift-argument-parser"), 23 | .byName(name: "SolbenchKit") 24 | ] 25 | ), 26 | .target( 27 | name: "SolbenchKit", 28 | dependencies: [ 29 | .product(name: "Prelude", package: "swift-prelude") 30 | ] 31 | ), 32 | .testTarget( 33 | name: "SolbenchKitTests", 34 | dependencies: [ 35 | .byName(name: "SolbenchKit"), 36 | .product(name: "InlineSnapshotTesting", package: "swift-snapshot-testing"), 37 | ] 38 | ) 39 | ] 40 | ) 41 | -------------------------------------------------------------------------------- /generator/Sources/Cmd/Solbench.swift: -------------------------------------------------------------------------------- 1 | import ArgumentParser 2 | import SolbenchKit 3 | 4 | @main 5 | struct Solbench: ParsableCommand { 6 | static var configuration: CommandConfiguration = .init( 7 | commandName: "solbench", 8 | abstract: "An utility to generate the readmes for solidity-benchamarks", 9 | subcommands: [ERC20Command.self] 10 | ) 11 | } 12 | 13 | extension Solbench { 14 | struct ERC20Command: ParsableCommand { 15 | static var configuration: CommandConfiguration = .init( 16 | commandName: "erc20", 17 | abstract: "Generate ERC20 readmes for solidity-benchmarks" 18 | ) 19 | 20 | @Argument(help: "path to data.json") 21 | var jsonPath: String 22 | 23 | @Argument(help: "path to benchmarks folder") 24 | var benchmarksPath: String 25 | 26 | func run() throws { 27 | try generateERC20Readmes(jsonPath: jsonPath, benchmarksPath: benchmarksPath) 28 | } 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /generator/Sources/SolbenchKit/Common.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Prelude 3 | 4 | struct ReadFile { 5 | let path: String 6 | } 7 | 8 | struct WriteFile { 9 | let path: String 10 | let contents: String 11 | } 12 | 13 | func pathToData(_ path: String) -> Data { 14 | try! String(contentsOfFile: path).data(using: .utf8)! 15 | } 16 | 17 | func read(_ rf: ReadFile) -> Data { 18 | pathToData(rf.path) 19 | } 20 | 21 | func write(_ wf: WriteFile) -> Void { 22 | try! wf.contents.write( 23 | toFile: wf.path, 24 | atomically: true, 25 | encoding: .utf8 26 | ) 27 | } 28 | 29 | func joinWithColumnSeparator(_ cols: [String]) -> String { cols.joined(separator: " | ") } 30 | 31 | func joinWithLinebreak(_ lines: [String]) -> String { lines.joined(separator: "\n") } 32 | 33 | func addTableEdge(_ str: String) -> String { "| \(str) |" } 34 | 35 | func tableComponentsToString(_ components: (head: [String], body: [[String]])) -> String { 36 | ( 37 | [ 38 | components.head, 39 | components.head.map(const("-")), 40 | ] 41 | + components.body 42 | ) 43 | |> map(joinWithColumnSeparator >>> addTableEdge) 44 | >>> joinWithLinebreak 45 | } 46 | -------------------------------------------------------------------------------- /generator/Sources/SolbenchKit/ERC20.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import Prelude 3 | 4 | public func generateERC20Readmes(jsonPath: String, benchmarksPath: String) throws { 5 | ReadFile(path: jsonPath) 6 | |> read 7 | >>> decodeGasSnapshot(data:) 8 | >>> \.ERC20 9 | >>> map(ERC20.writeERC20Readme(base: benchmarksPath)) 10 | >>> forEach(write) 11 | } 12 | 13 | enum ERC20 { 14 | enum Method: String, CaseIterable { 15 | case allowance 16 | case approve 17 | case balanceOf 18 | case deploy 19 | case totalSupply 20 | case transferFromToNonOwner 21 | case transferFromToOwner 22 | case transferToNonOwner 23 | case transferToOwner 24 | } 25 | 26 | enum Implementation: String, CaseIterable { 27 | case Maple = "Maple" 28 | case OpenZeppelin = "OZ" 29 | case OpenZeppelinPermit = "OZPermit" 30 | case Solmate = "Solmate" 31 | } 32 | 33 | typealias Dict = [ 34 | SolidityVersion: [ 35 | Method.RawValue: [Implementation.RawValue: String] 36 | ] 37 | ] 38 | 39 | static func readmePath(base: String, version: SolidityVersion) -> String { 40 | "\(base)/\(version)/ERC20.md" 41 | } 42 | 43 | static func readmeMarkdown(_ table: String) -> String { 44 | """ 45 | # ERC20 Benchmarks 46 | 47 | Benchmarks for implementations of the ERC20 standard. 48 | 49 | Note: When comparing, keep in mind that Solmate and Maple implements ERC-2612 permit so it's more fairt to compare them against OpenZeppelin Permit and not the raw OpenZeppelin implementation. 50 | 51 | - [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts) 52 | - [OpenZeppelin Permit](https://github.com/OpenZeppelin/openzeppelin-contracts) 53 | - [Solmate](https://github.com/rari-capital/solmate) 54 | - [Maple](https://github.com/maple-labs/erc20) 55 | 56 | ## Methods 57 | 58 | ### Write Methods 59 | - [x] deploy: How much gas to deploy the contract as is? 60 | - [x] transfer (toOwner): How much gas to transfer tokens to an account that already owns more than 0 tokens? 61 | - [x] transfer (toNonOwner): How much gas to transfer tokens to an account that owns 0 tokens? 62 | - [x] transferFrom (toOwner): How much gas for an operator to transfer tokens from one account to another that already owns more than 0 tokens? 63 | - [x] transferFrom (toNonOwner): How much gas for an operator to transfer tokens from one account to another that owns 0 tokens? 64 | - [x] approve: How much gas to approve an account to spend x amount of tokens? 65 | 66 | ### Read Methods 67 | - [x] totalSupply: How much gas to check the total supply of tokens? 68 | - [x] balanceOf: How much gas to check the balance of an account? 69 | - [x] allowance: How much gas to check how many tokens an operator can spend on behalf of another account? 70 | 71 | ## Table 72 | 73 | \(table) 74 | 75 | """ 76 | } 77 | 78 | static func dictToTableComponents(_ dict: [Method.RawValue: [Implementation.RawValue: String]]) -> (head: [String], body: [[String]]) { 79 | let head = ["Implementation"] + Method.allCases.map(\.rawValue) 80 | let body = Implementation.allCases.map { impl in 81 | Method.allCases.map { method in 82 | dict[method.rawValue]![impl.rawValue]! 83 | } 84 | } 85 | return (head, body) 86 | } 87 | 88 | static func writeERC20Readme( 89 | base: String 90 | ) -> (SolidityVersion, [Method.RawValue: [Implementation.RawValue: String]]) -> WriteFile { 91 | { version, dict in 92 | WriteFile( 93 | path: readmePath(base: base, version: version), 94 | contents: dict 95 | |> dictToTableComponents 96 | >>> tableComponentsToString 97 | >>> readmeMarkdown 98 | ) 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /generator/Sources/SolbenchKit/GasSnapshots.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | struct GasSnapshots: Decodable { 4 | let ERC20: ERC20.Dict 5 | } 6 | 7 | func decodeGasSnapshot(data: Data) -> GasSnapshots { 8 | try! JSONDecoder().decode(GasSnapshots.self, from: data) 9 | } 10 | -------------------------------------------------------------------------------- /generator/Sources/SolbenchKit/SolidityVersion.swift: -------------------------------------------------------------------------------- 1 | typealias SolidityVersion = String 2 | -------------------------------------------------------------------------------- /generator/Sources/SolbenchKitTests/CommonTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import InlineSnapshotTesting 3 | @testable import SolbenchKit 4 | 5 | final class CommonTests: XCTestCase { 6 | override class func setUp() { 7 | super.setUp() 8 | isRecording = false 9 | } 10 | 11 | func test_joinWithColumnSeparator() { 12 | let sut = joinWithColumnSeparator(["a", "b", "c"]) 13 | assertInlineSnapshot(of: sut, as: .lines) { 14 | """ 15 | a | b | c 16 | """ 17 | } 18 | } 19 | 20 | func test_joinWithLinebreak() { 21 | let sut = joinWithLinebreak(["a", "b", "c"]) 22 | assertInlineSnapshot(of: sut, as: .lines) { 23 | """ 24 | a 25 | b 26 | c 27 | """ 28 | } 29 | } 30 | 31 | func test_tableComponentsToString() { 32 | let components = (["h1", "h2", "h3"], [["a1", "a2", "a3"], ["b1", "b2", "b3"]]) 33 | let sut = tableComponentsToString(components) 34 | assertInlineSnapshot(of: sut, as: .lines) { 35 | """ 36 | | h1 | h2 | h3 | 37 | | - | - | - | 38 | | a1 | a2 | a3 | 39 | | b1 | b2 | b3 | 40 | """ 41 | } 42 | } 43 | 44 | func test_addTableEdge() { 45 | let sut = addTableEdge("hello") 46 | assertInlineSnapshot(of: sut, as: .lines) { 47 | """ 48 | | hello | 49 | """ 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /remappings.txt: -------------------------------------------------------------------------------- 1 | @ds-test/=lib/ds-test/src/ 2 | @forge-std/=lib/forge-std/src/ 3 | @openzeppelin/=lib/openzeppelin-contracts/ 4 | @ERC721A/=lib/ERC721A/contracts/ 5 | @ERC721B/=lib/ERC721B/contracts/ 6 | @ERC721K/=lib/ERC721K/src/ 7 | @solady/=lib/solady/src/ 8 | @solmate/=lib/solmate/src/ 9 | @maple-erc20/=lib/maple-erc20/contracts/ 10 | $/=src/ -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | py-markdown-table 2 | pyyaml -------------------------------------------------------------------------------- /scripts/common.py: -------------------------------------------------------------------------------- 1 | from itertools import groupby 2 | import re 3 | from markdownTable import markdownTable 4 | 5 | # Pattern: ___Test:test___() (gas: ) 6 | # Example: ERC721_B_transfer_Test:test_transfer_toNonOwner_id50() (gas: 179836) 7 | 8 | 9 | def group_by_contract(lines): 10 | grouped_by_contract = groupby(lines, lambda x: x.split("_")[0]) 11 | grouped_by_contract_dict = {} 12 | for key, elements in grouped_by_contract: 13 | grouped_by_contract_dict[key] = list(elements) 14 | return grouped_by_contract_dict 15 | 16 | 17 | def group_by_variant(lines): 18 | grouped_by_variant = groupby(lines, lambda x: x.split("_")[1]) 19 | grouped_by_variant_dict = {} 20 | for key, elements in grouped_by_variant: 21 | grouped_by_variant_dict[key] = list(elements) 22 | return grouped_by_variant_dict 23 | 24 | 25 | def group_by_method(lines): 26 | grouped_by_method = groupby(lines, lambda x: x.split("_")[2]) 27 | grouped_by_method_dict = {} 28 | for key, elements in grouped_by_method: 29 | if key in grouped_by_method_dict: 30 | grouped_by_method_dict[key] = grouped_by_method_dict[key] + \ 31 | list(elements) 32 | else: 33 | grouped_by_method_dict[key] = list(elements) 34 | return grouped_by_method_dict 35 | 36 | 37 | def group_by_constraint(lines): 38 | grouped_by_constraint = groupby(lines, lambda x: x.split("_")[5]) 39 | grouped_by_constraint_dict = {} 40 | for key, elements in grouped_by_constraint: 41 | grouped_by_constraint_dict[key] = list(elements) 42 | return grouped_by_constraint_dict 43 | 44 | 45 | def group_methods_and_variant(lines): 46 | methods = group_by_method(lines) 47 | grouped = {} 48 | for key in methods: 49 | grouped[key] = group_by_variant(methods[key]) 50 | return grouped 51 | 52 | 53 | def rows_for_method(methods, variations, method_name, method_fn): 54 | rows = [] 55 | for variant in methods[method_name]: 56 | vrows = list(map(method_fn, methods[method_name][variant])) 57 | if "key" in vrows[0]: 58 | vrows = sorted(vrows, key=lambda x: int(x["key"])) 59 | 60 | rows_dict = {"Implementation": variations[variant]} 61 | for r in vrows: 62 | if "key" in r: 63 | rows_dict[r["key"]] = r["gas"] 64 | else: 65 | rows_dict["--"] = r["gas"] 66 | 67 | rows.append(rows_dict) 68 | return rows 69 | 70 | 71 | def table_for_rows(rows): 72 | return markdownTable(rows).setParams( 73 | row_sep='markdown', quote=False).getMarkdown() 74 | 75 | 76 | def sub_readme(file, method, content): 77 | pattern = "(.|\n)+".format( 78 | method, method) 79 | sub = "\n{}\n".format( 80 | method, content, method) 81 | return re.sub(pattern, sub, file, 1, re.M) 82 | -------------------------------------------------------------------------------- /scripts/erc1155.py: -------------------------------------------------------------------------------- 1 | import re 2 | import common 3 | 4 | variations = { 5 | "OZ": "OpenZeppelin", 6 | "Solmate": "Solmate", 7 | } 8 | 9 | # Methods to format .gas-snapshot line to an object with relevant info 10 | 11 | deploy_regex = re.compile("deploy.+gas:\s(\d+)") 12 | 13 | 14 | def deploy(line): 15 | match = re.search(deploy_regex, line) 16 | return { 17 | "gas": match.group(1) 18 | } 19 | 20 | 21 | mint_regex = re.compile("test_mint.+gas:\s(\d+)") 22 | 23 | 24 | def mint(line): 25 | match = re.search(mint_regex, line) 26 | return { 27 | "gas": match.group(1) 28 | } 29 | 30 | 31 | mintBatch_regex = re.compile("test_mintBatch_(\d+).+gas:\s(\d+)") 32 | 33 | 34 | def mintBatch(line): 35 | match = re.search(mintBatch_regex, line) 36 | return { 37 | "key": match.group(1), 38 | "gas": match.group(2) 39 | } 40 | 41 | 42 | safeTransferFrom_regex = re.compile("test_safeTransferFrom.+gas:\s(\d+)") 43 | 44 | 45 | def safeTransferFrom(line): 46 | match = re.search(safeTransferFrom_regex, line) 47 | return { 48 | "gas": match.group(1) 49 | } 50 | 51 | 52 | safeBatchTransferFrom_regex = re.compile( 53 | "test_safeBatchTransferFrom_(\d+).+gas:\s(\d+)") 54 | 55 | 56 | def safeBatchTransferFrom(line): 57 | match = re.search(safeBatchTransferFrom_regex, line) 58 | return { 59 | "key": match.group(1), 60 | "gas": match.group(2) 61 | } 62 | 63 | 64 | def group(lines): 65 | methods = common.group_methods_and_variant(lines) 66 | 67 | def rows_for_method(method_name, method_fn): 68 | return common.rows_for_method(methods, variations, method_name, method_fn) 69 | 70 | methods["deploy"] = rows_for_method("deploy", deploy) 71 | methods["mint"] = rows_for_method("mint", mint) 72 | methods["mintBatch"] = rows_for_method("mintBatch", mintBatch) 73 | methods["safeTransferFrom"] = rows_for_method( 74 | "safeTransferFrom", safeTransferFrom) 75 | methods["safeBatchTransferFrom"] = rows_for_method( 76 | "safeBatchTransferFrom", safeBatchTransferFrom) 77 | 78 | return methods 79 | -------------------------------------------------------------------------------- /scripts/erc20.py: -------------------------------------------------------------------------------- 1 | import re 2 | import common 3 | 4 | variations = { 5 | "OZ": "OpenZeppelin v5", 6 | "OZPermit": "OpenZeppelin v5 Permit", 7 | "Solmate": "Solmate", 8 | "Maple": "Maple", 9 | } 10 | 11 | def regex_for_method(method): 12 | regex_string = "test_{}.+gas:\s(\d+)".format(method) 13 | return re.compile(regex_string) 14 | 15 | def fn_for_method(method): 16 | def get_gas(line): 17 | match = re.search(regex_for_method(method), line) 18 | return { 19 | "gas": match.group(1) 20 | } 21 | return get_gas 22 | 23 | def group(lines): 24 | methods = common.group_methods_and_variant(lines) 25 | 26 | def rows_for_method(method_name, method_fn): 27 | return common.rows_for_method(methods, variations, method_name, method_fn) 28 | 29 | method_keys = [ 30 | "deploy", 31 | "transferToOwner", 32 | "transferToNonOwner", 33 | "transferFromToOwner", 34 | "transferFromToNonOwner", 35 | "approve", 36 | "totalSupply", 37 | "balanceOf", 38 | "allowance", 39 | ] 40 | 41 | for method in method_keys: 42 | methods[method] = rows_for_method(method, fn_for_method(method)) 43 | 44 | return methods 45 | -------------------------------------------------------------------------------- /scripts/erc721.py: -------------------------------------------------------------------------------- 1 | import re 2 | import common 3 | 4 | variations = { 5 | "OZ": "OpenZeppelin", 6 | "OZEnumerable": "OpenZeppelin Enumerable", 7 | "OZConsecutive": "OpenZeppelin Consecutive", 8 | "Solady": "Solady", 9 | "Solmate": "Solmate", 10 | "A": "ERC721A", 11 | "B": "ERC721B", 12 | "K": "ERC721K", 13 | } 14 | 15 | # Methods to format .gas-snapshot line to an object with relevant info 16 | 17 | # For snapshots of methods with no variations 18 | def regex_for_method_simple(method): 19 | regex_string = "test_{}.+gas:\s(\d+)".format(method) 20 | return re.compile(regex_string) 21 | 22 | def fn_for_method_simple(method): 23 | def get_gas(line): 24 | match = re.search(regex_for_method_simple(method), line) 25 | return { 26 | "gas": match.group(1) 27 | } 28 | return get_gas 29 | 30 | # For snapshots of methods with amount variations 31 | def regex_for_method_amount(method): 32 | regex_string = "test_{}_(\d+).+gas:\s(\d+)".format(method) 33 | return re.compile(regex_string) 34 | 35 | def fn_for_method_amount(method): 36 | def get_gas(line): 37 | match = re.search(regex_for_method_amount(method), line) 38 | return { 39 | "key": match.group(1), 40 | "gas": match.group(2), 41 | } 42 | return get_gas 43 | 44 | # For snapshots of methods with id variations 45 | def regex_for_method_id(method): 46 | regex_string = "test_{}_id(\d+).+gas:\s(\d+)".format(method) 47 | return re.compile(regex_string) 48 | 49 | def fn_for_method_id(method): 50 | def get_gas(line): 51 | match = re.search(regex_for_method_id(method), line) 52 | return { 53 | "key": match.group(1), 54 | "gas": match.group(2), 55 | } 56 | return get_gas 57 | 58 | def group_methods_and_variant(lines): 59 | methods = common.group_by_method(lines) 60 | grouped = {} 61 | for key in methods: 62 | grouped[key] = common.group_by_variant(methods[key]) 63 | return grouped 64 | 65 | 66 | def group(lines): 67 | methods = group_methods_and_variant(lines) 68 | 69 | def rows_for_method(method_name, method_fn): 70 | return common.rows_for_method(methods, variations, method_name, method_fn) 71 | 72 | methods_simple = [ 73 | "deploy", 74 | "isApprovedForAll", 75 | "setApprovalForAll", 76 | ] 77 | methods_amount = [ 78 | "deployERC2309", 79 | "mint", 80 | "safeMint", 81 | "balanceOf", 82 | "ownerOf", 83 | "getApproved", 84 | ] 85 | methods_id = [ 86 | "burn", 87 | "transferToOwner", 88 | "transferToNonOwner", 89 | "safeTransferToOwner", 90 | "safeTransferToNonOwner", 91 | "approve", 92 | ] 93 | 94 | for method in methods_simple: 95 | methods[method] = rows_for_method(method, fn_for_method_simple(method)) 96 | 97 | for method in methods_amount: 98 | methods[method] = rows_for_method(method, fn_for_method_amount(method)) 99 | 100 | for method in methods_id: 101 | methods[method] = rows_for_method(method, fn_for_method_id(method)) 102 | 103 | return methods 104 | -------------------------------------------------------------------------------- /scripts/gen_json.py: -------------------------------------------------------------------------------- 1 | # Pattern: ___Test:test___() (gas: ) 2 | # Example: ERC721_B_transfer_Test:test_transfer_toNonOwner_id50() (gas: 179836) 3 | 4 | import os 5 | import re 6 | import json 7 | 8 | regex = re.compile( 9 | r"(?P.+?)_(?P.+?)_(?P.+?)_Test:test_(?P.+?)(_(?P.+?))?\(.+?(?P\d+)") 10 | 11 | 12 | def main(): 13 | obj = {} 14 | 15 | snapshot_files = os.listdir('./gas-snapshots') 16 | 17 | for snapshot_file in snapshot_files: 18 | version = snapshot_file.replace('0-8-', '0.8.') 19 | snapshot = open('./gas-snapshots/{}'.format(snapshot_file), "r") 20 | lines = snapshot.readlines() 21 | 22 | for line in lines: 23 | match = regex.match(line) 24 | 25 | groupdict = match.groupdict() 26 | contract = groupdict["contract"] 27 | variant = groupdict["variant"] 28 | method1 = groupdict["method1"] 29 | # method2 = groupdict["method2"] 30 | constraint = groupdict["constraint"] 31 | gas = groupdict["gas"] 32 | 33 | if not (contract in obj): 34 | obj[contract] = {} 35 | 36 | if not (version in obj[contract]): 37 | obj[contract][version] = {} 38 | 39 | if not (method1 in obj[contract][version]): 40 | obj[contract][version][method1] = {} 41 | 42 | if not (variant in obj[contract][version][method1]): 43 | obj[contract][version][method1][variant] = {} 44 | 45 | if constraint: 46 | obj[contract][version][method1][variant][constraint] = gas 47 | else: 48 | obj[contract][version][method1][variant] = gas 49 | 50 | json_dump = json.dumps(obj, indent=2) 51 | f = open("data.json", "w") 52 | f.write(json_dump) 53 | 54 | main() 55 | -------------------------------------------------------------------------------- /scripts/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import erc20 3 | import erc721 4 | import erc1155 5 | import common 6 | 7 | 8 | def group_by_contract(lines): 9 | contracts = common.group_by_contract(lines) 10 | grouped_by_contract_dict = {} 11 | 12 | grouped_by_contract_dict["ERC20"] = erc20.group(contracts["ERC20"]) 13 | grouped_by_contract_dict["ERC721"] = erc721.group(contracts["ERC721"]) 14 | grouped_by_contract_dict["ERC1155"] = erc1155.group(contracts["ERC1155"]) 15 | 16 | return grouped_by_contract_dict 17 | 18 | 19 | # ERC20 20 | 21 | def erc20_subreadme(contracts, readme, method): 22 | return common.sub_readme(readme, method, common.table_for_rows( 23 | contracts["ERC20"][method])) 24 | 25 | 26 | def update_erc20_readme(contracts, file): 27 | f = open(file, "r+") 28 | readme = f.read() 29 | f.seek(0) 30 | readme = erc20_subreadme(contracts, readme, "deploy") 31 | readme = erc20_subreadme(contracts, readme, "transferToOwner") 32 | readme = erc20_subreadme(contracts, readme, "transferToNonOwner") 33 | readme = erc20_subreadme(contracts, readme, "transferFromToOwner") 34 | readme = erc20_subreadme(contracts, readme, "transferFromToNonOwner") 35 | readme = erc20_subreadme(contracts, readme, "approve") 36 | readme = erc20_subreadme(contracts, readme, "totalSupply") 37 | readme = erc20_subreadme(contracts, readme, "balanceOf") 38 | readme = erc20_subreadme(contracts, readme, "allowance") 39 | f.write(readme) 40 | f.truncate() 41 | 42 | # ERC721 43 | 44 | 45 | def erc721_subreadme(contracts, readme, method): 46 | return common.sub_readme(readme, method, common.table_for_rows( 47 | contracts["ERC721"][method])) 48 | 49 | 50 | def update_erc721_readme(contracts, file): 51 | f = open(file, "r+") 52 | readme = f.read() 53 | f.seek(0) 54 | readme = erc721_subreadme(contracts, readme, "deploy") 55 | readme = erc721_subreadme(contracts, readme, "deployERC2309") 56 | readme = erc721_subreadme(contracts, readme, "mint") 57 | readme = erc721_subreadme(contracts, readme, "safeMint") 58 | readme = erc721_subreadme(contracts, readme, "burn") 59 | readme = erc721_subreadme(contracts, readme, "transferToOwner") 60 | readme = erc721_subreadme(contracts, readme, "transferToNonOwner") 61 | readme = erc721_subreadme(contracts, readme, "safeTransferToOwner") 62 | readme = erc721_subreadme(contracts, readme, "safeTransferToNonOwner") 63 | readme = erc721_subreadme(contracts, readme, "approve") 64 | readme = erc721_subreadme(contracts, readme, "setApprovalForAll") 65 | readme = erc721_subreadme(contracts, readme, "balanceOf") 66 | readme = erc721_subreadme(contracts, readme, "ownerOf") 67 | readme = erc721_subreadme(contracts, readme, "getApproved") 68 | readme = erc721_subreadme(contracts, readme, "isApprovedForAll") 69 | f.write(readme) 70 | f.truncate() 71 | 72 | # ERC1155 73 | 74 | 75 | def erc1155_subreadme(contracts, readme, method): 76 | return common.sub_readme(readme, method, common.table_for_rows( 77 | contracts["ERC1155"][method])) 78 | 79 | 80 | def update_erc1155_readme(contracts, file): 81 | f = open(file, "r+") 82 | readme = f.read() 83 | f.seek(0) 84 | readme = erc1155_subreadme(contracts, readme, "deploy") 85 | readme = erc1155_subreadme(contracts, readme, "mint") 86 | readme = erc1155_subreadme(contracts, readme, "mintBatch") 87 | readme = erc1155_subreadme(contracts, readme, "safeTransferFrom") 88 | readme = erc1155_subreadme(contracts, readme, "safeBatchTransferFrom") 89 | f.write(readme) 90 | f.truncate() 91 | 92 | 93 | def update_readmes(snapshot_file): 94 | version = snapshot_file.replace('0-8-', '0.8.') 95 | snapshot = open('./gas-snapshots/{}'.format(snapshot_file), "r") 96 | lines = snapshot.readlines() 97 | 98 | contracts = group_by_contract(lines) 99 | 100 | base_write_path = "benchmarks/{}".format(version) 101 | update_erc20_readme(contracts, "{}/ERC20.md".format(base_write_path)) 102 | update_erc721_readme(contracts, "{}/ERC721.md".format(base_write_path)) 103 | update_erc1155_readme(contracts, "{}/ERC1155.md".format(base_write_path)) 104 | 105 | def main(): 106 | snapshot_files = os.listdir('./gas-snapshots') 107 | 108 | for snapshot_file in snapshot_files: 109 | update_readmes(snapshot_file) 110 | 111 | 112 | main() 113 | -------------------------------------------------------------------------------- /src/ERC1155_OZ.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC1155} from "@openzeppelin/contracts/token/ERC1155/ERC1155.sol"; 5 | 6 | contract ERC1155_OZ is ERC1155 { 7 | constructor() ERC1155("") {} 8 | 9 | function mint( 10 | address to, 11 | uint256 id, 12 | uint256 amount 13 | ) external payable { 14 | _mint(to, id, amount, ""); 15 | } 16 | 17 | function mintBatch( 18 | address to, 19 | uint256[] calldata ids, 20 | uint256[] calldata amounts 21 | ) external payable { 22 | _mintBatch(to, ids, amounts, ""); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/ERC1155_Solmate.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC1155} from "@solmate/tokens/ERC1155.sol"; 5 | 6 | contract ERC1155_Solmate is ERC1155 { 7 | constructor() {} 8 | 9 | function mint( 10 | address to, 11 | uint256 id, 12 | uint256 amount 13 | ) external payable { 14 | _mint(to, id, amount, ""); 15 | } 16 | 17 | function mintBatch( 18 | address to, 19 | uint256[] calldata ids, 20 | uint256[] calldata amounts 21 | ) external payable { 22 | _batchMint(to, ids, amounts, ""); 23 | } 24 | 25 | function uri(uint256) public pure override returns (string memory) { 26 | return ""; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/ERC20_Maple.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC20} from "@maple-erc20/ERC20.sol"; 5 | 6 | contract ERC20_Maple is ERC20 { 7 | constructor() ERC20("Token", "TK", 18) {} 8 | 9 | function mint(address to, uint256 amount) external { 10 | _mint(to, amount); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/ERC20_OZ.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 5 | 6 | contract ERC20_OZ is ERC20 { 7 | constructor() ERC20("Token", "TK") {} 8 | 9 | function mint(address to, uint256 amount) external { 10 | _mint(to, amount); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/ERC20_OZPermit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC20, ERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; 5 | 6 | contract ERC20_OZPermit is ERC20, ERC20Permit { 7 | constructor() ERC20("Token", "TK") ERC20Permit("Token") {} 8 | 9 | function mint(address to, uint256 amount) external { 10 | _mint(to, amount); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/ERC20_Solmate.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC20} from "@solmate/tokens/ERC20.sol"; 5 | 6 | contract ERC20_Solmate is ERC20 { 7 | constructor() ERC20("Token", "TK", 18) {} 8 | 9 | function mint(address to, uint256 amount) external { 10 | _mint(to, amount); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/ERC721_A.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC721A} from "@ERC721A/ERC721A.sol"; 5 | 6 | contract ERC721_A is ERC721A { 7 | constructor() ERC721A("Name", "Sy") {} 8 | 9 | function mint(address to, uint256 amount) external payable { 10 | _mint(to, amount); 11 | } 12 | 13 | function safeMint(address to, uint256 amount) external payable { 14 | _safeMint(to, amount); 15 | } 16 | 17 | function burn(uint256 tokenId) external { 18 | _burn(tokenId, false); 19 | } 20 | 21 | function _startTokenId() internal pure override returns (uint256) { 22 | return 1; 23 | } 24 | } 25 | 26 | contract ERC721_A_ERC2309 is ERC721A { 27 | constructor(uint96 amount) ERC721A("Name", "Sy") { 28 | _mintERC2309(address(1), amount); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/ERC721_B.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC721B} from "@ERC721B/ERC721B.sol"; 5 | 6 | contract ERC721_B is ERC721B { 7 | constructor() ERC721B("Name", "Sy") {} 8 | 9 | function mint(address to, uint256 amount) external payable { 10 | _mint(to, amount); 11 | } 12 | 13 | function safeMint(address to, uint256 amount) external payable { 14 | _safeMint(to, amount); 15 | } 16 | 17 | function burn(uint256 tokenId) external {} 18 | 19 | function tokenURI(uint256 id) public pure override returns (string memory) { 20 | return ""; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/ERC721_K.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC721K} from "@ERC721K/ERC721K.sol"; 5 | 6 | contract ERC721_K is ERC721K { 7 | constructor() ERC721K("ERC721K", "K") {} 8 | 9 | function mint(address to, uint256 amount) external payable { 10 | _mint(to, amount, "", false); 11 | } 12 | 13 | function safeMint(address to, uint256 amount) external payable { 14 | _safeMint(to, amount); 15 | } 16 | 17 | function burn(uint256 tokenId) external { 18 | _burn(tokenId, false); 19 | } 20 | 21 | function tokenURI(uint256) 22 | public 23 | pure 24 | virtual 25 | override 26 | returns (string memory) 27 | {} 28 | } 29 | -------------------------------------------------------------------------------- /src/ERC721_OZ.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; 5 | 6 | contract ERC721_OZ is ERC721 { 7 | uint256 currentSupply; 8 | 9 | constructor() ERC721("Name", "Sy") {} 10 | 11 | function mint(address to, uint256 amount) external payable { 12 | uint256 startingIndex; 13 | unchecked { 14 | startingIndex = currentSupply + 1; 15 | currentSupply += amount; 16 | } 17 | 18 | for (uint256 i; i < amount; ) { 19 | _mint(to, startingIndex + i); 20 | unchecked { 21 | i++; 22 | } 23 | } 24 | } 25 | 26 | function safeMint(address to, uint256 amount) external payable { 27 | uint256 startingIndex; 28 | unchecked { 29 | startingIndex = currentSupply + 1; 30 | currentSupply += amount; 31 | } 32 | 33 | for (uint256 i; i < amount; ) { 34 | _safeMint(to, startingIndex + i); 35 | unchecked { 36 | i++; 37 | } 38 | } 39 | } 40 | 41 | function burn(uint256 tokenId) external { 42 | _burn(tokenId); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/ERC721_OZConsecutive.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; 5 | import {ERC721Consecutive} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Consecutive.sol"; 6 | 7 | contract ERC721_OZConsecutive is ERC721Consecutive { 8 | uint256 currentSupply; 9 | 10 | constructor() ERC721("Name", "Sy") {} 11 | 12 | function mint(address to, uint256 amount) external payable { 13 | uint256 startingIndex; 14 | unchecked { 15 | startingIndex = currentSupply + 1; 16 | currentSupply += amount; 17 | } 18 | 19 | for (uint256 i; i < amount; ) { 20 | _mint(to, startingIndex + i); 21 | unchecked { 22 | i++; 23 | } 24 | } 25 | } 26 | 27 | function safeMint(address to, uint256 amount) external payable { 28 | uint256 startingIndex; 29 | unchecked { 30 | startingIndex = currentSupply + 1; 31 | currentSupply += amount; 32 | } 33 | 34 | for (uint256 i; i < amount; ) { 35 | _safeMint(to, startingIndex + i); 36 | unchecked { 37 | i++; 38 | } 39 | } 40 | } 41 | 42 | function burn(uint256 tokenId) external { 43 | _burn(tokenId); 44 | } 45 | } 46 | 47 | contract ERC721_OZConsecutive_ERC2309 is ERC721Consecutive { 48 | constructor(uint96 amount) ERC721("Name", "Sy") { 49 | _mintConsecutive(address(1), amount); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/ERC721_OZEnumerable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; 5 | import {ERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; 6 | 7 | contract ERC721_OZEnumerable is ERC721Enumerable { 8 | uint256 currentSupply; 9 | 10 | constructor() ERC721("Name", "Sy") {} 11 | 12 | function mint(address to, uint256 amount) external payable { 13 | uint256 startingIndex; 14 | unchecked { 15 | startingIndex = currentSupply + 1; 16 | currentSupply += amount; 17 | } 18 | 19 | for (uint256 i; i < amount; ) { 20 | _mint(to, startingIndex + i); 21 | unchecked { 22 | i++; 23 | } 24 | } 25 | } 26 | 27 | function safeMint(address to, uint256 amount) external payable { 28 | uint256 startingIndex; 29 | unchecked { 30 | startingIndex = currentSupply + 1; 31 | currentSupply += amount; 32 | } 33 | 34 | for (uint256 i; i < amount; ) { 35 | _safeMint(to, startingIndex + i); 36 | unchecked { 37 | i++; 38 | } 39 | } 40 | } 41 | 42 | function burn(uint256 tokenId) external { 43 | _burn(tokenId); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/ERC721_Solady.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC721} from "@solady/tokens/ERC721.sol"; 5 | 6 | contract ERC721_Solady is ERC721 { 7 | uint256 currentSupply; 8 | 9 | constructor() {} 10 | 11 | function name() public view virtual override returns (string memory) { 12 | return "Name"; 13 | } 14 | 15 | function symbol() public view virtual override returns (string memory) { 16 | return "Sy"; 17 | } 18 | 19 | function mint(address to, uint256 amount) external payable { 20 | uint256 startingIndex; 21 | unchecked { 22 | startingIndex = currentSupply + 1; 23 | currentSupply += amount; 24 | } 25 | 26 | for (uint256 i; i < amount;) { 27 | _mint(to, startingIndex + i); 28 | unchecked { 29 | i++; 30 | } 31 | } 32 | } 33 | 34 | function safeMint(address to, uint256 amount) external payable { 35 | uint256 startingIndex; 36 | unchecked { 37 | startingIndex = currentSupply + 1; 38 | currentSupply += amount; 39 | } 40 | 41 | for (uint256 i; i < amount;) { 42 | _safeMint(to, startingIndex + i); 43 | unchecked { 44 | i++; 45 | } 46 | } 47 | } 48 | 49 | function burn(uint256 tokenId) external { 50 | _burn(tokenId); 51 | } 52 | 53 | function tokenURI(uint256 id) public view override returns (string memory) { 54 | return ""; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/ERC721_Solmate.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {ERC721} from "@solmate/tokens/ERC721.sol"; 5 | 6 | contract ERC721_Solmate is ERC721 { 7 | uint256 currentSupply; 8 | 9 | constructor() ERC721("Name", "Sy") {} 10 | 11 | function mint(address to, uint256 amount) external payable { 12 | uint256 startingIndex; 13 | unchecked { 14 | startingIndex = currentSupply + 1; 15 | currentSupply += amount; 16 | } 17 | 18 | for (uint256 i; i < amount; ) { 19 | _mint(to, startingIndex + i); 20 | unchecked { 21 | i++; 22 | } 23 | } 24 | } 25 | 26 | function safeMint(address to, uint256 amount) external payable { 27 | uint256 startingIndex; 28 | unchecked { 29 | startingIndex = currentSupply + 1; 30 | currentSupply += amount; 31 | } 32 | 33 | for (uint256 i; i < amount; ) { 34 | _safeMint(to, startingIndex + i); 35 | unchecked { 36 | i++; 37 | } 38 | } 39 | } 40 | 41 | function burn(uint256 tokenId) external { 42 | _burn(tokenId); 43 | } 44 | 45 | function tokenURI(uint256 id) public view override returns (string memory) { 46 | return ""; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/test/ERC1155.t.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | pragma solidity >=0.8.4; 3 | 4 | import {DSTest} from "@ds-test/test.sol"; 5 | import {Vm} from "@forge-std/Vm.sol"; 6 | import {ERC1155_OZ} from "$/ERC1155_OZ.sol"; 7 | import {ERC1155_Solmate} from "$/ERC1155_Solmate.sol"; 8 | 9 | // deploy 10 | contract ERC1155_OZ_deploy_Test is DSTest { 11 | function test_deploy() public { 12 | ERC1155_OZ sut = new ERC1155_OZ(); 13 | } 14 | } 15 | 16 | // mint 17 | contract ERC1155_OZ_mint_Test is DSTest { 18 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 19 | 20 | ERC1155_OZ internal sut; 21 | 22 | function setUp() public { 23 | sut = new ERC1155_OZ(); 24 | } 25 | 26 | function test_mint() public { 27 | sut.mint(address(0xAAAA), 1, 1); 28 | } 29 | } 30 | 31 | // mintBatch 32 | contract ERC1155_OZ_mintBatch_Test is DSTest { 33 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 34 | 35 | ERC1155_OZ internal sut; 36 | 37 | function setUp() public { 38 | sut = new ERC1155_OZ(); 39 | } 40 | 41 | function test_mintBatch_1() public { 42 | uint256[] memory ids = new uint256[](1); 43 | ids[0] = 1; 44 | 45 | uint256[] memory amounts = new uint256[](1); 46 | amounts[0] = 1; 47 | 48 | sut.mintBatch(address(0xAAAA), ids, amounts); 49 | } 50 | 51 | function test_mintBatch_5() public { 52 | uint256[] memory ids = new uint256[](5); 53 | ids[0] = 1; 54 | ids[1] = 2; 55 | ids[2] = 3; 56 | ids[3] = 4; 57 | ids[4] = 5; 58 | 59 | uint256[] memory amounts = new uint256[](5); 60 | amounts[0] = 1; 61 | amounts[1] = 1; 62 | amounts[2] = 1; 63 | amounts[3] = 1; 64 | amounts[4] = 1; 65 | 66 | sut.mintBatch(address(0xAAAA), ids, amounts); 67 | } 68 | 69 | function test_mintBatch_10() public { 70 | uint256[] memory ids = new uint256[](10); 71 | ids[0] = 1; 72 | ids[1] = 2; 73 | ids[2] = 3; 74 | ids[3] = 4; 75 | ids[4] = 5; 76 | ids[5] = 6; 77 | ids[6] = 7; 78 | ids[7] = 8; 79 | ids[8] = 9; 80 | ids[9] = 10; 81 | 82 | uint256[] memory amounts = new uint256[](10); 83 | amounts[0] = 1; 84 | amounts[1] = 1; 85 | amounts[2] = 1; 86 | amounts[3] = 1; 87 | amounts[4] = 1; 88 | amounts[5] = 1; 89 | amounts[6] = 1; 90 | amounts[7] = 1; 91 | amounts[8] = 1; 92 | amounts[9] = 2; 93 | 94 | sut.mintBatch(address(0xAAAA), ids, amounts); 95 | } 96 | } 97 | 98 | // safeTransferFrom 99 | contract ERC1155_OZ_safeTransferFrom_Test is DSTest { 100 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 101 | 102 | ERC1155_OZ internal sut; 103 | 104 | function setUp() public { 105 | sut = new ERC1155_OZ(); 106 | sut.mint(address(0xAAAA), 1, 1); 107 | } 108 | 109 | function test_safeTransferFrom() public { 110 | HEVM.prank(address(0xAAAA)); 111 | sut.safeTransferFrom(address(0xAAAA), address(0xBBBB), 1, 1, ""); 112 | } 113 | } 114 | 115 | // safeBatchTransferFrom 116 | contract ERC1155_OZ_safeBatchTransferFrom_Test is DSTest { 117 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 118 | 119 | ERC1155_OZ internal sut; 120 | 121 | function setUp() public { 122 | sut = new ERC1155_OZ(); 123 | 124 | uint256[] memory ids = new uint256[](11); 125 | ids[0] = 1; 126 | ids[1] = 2; 127 | ids[2] = 3; 128 | ids[3] = 4; 129 | ids[4] = 5; 130 | ids[5] = 6; 131 | ids[6] = 7; 132 | ids[7] = 8; 133 | ids[8] = 9; 134 | ids[9] = 10; 135 | ids[10] = 11; 136 | 137 | uint256[] memory amounts = new uint256[](11); 138 | amounts[0] = 1; 139 | amounts[1] = 1; 140 | amounts[2] = 1; 141 | amounts[3] = 1; 142 | amounts[4] = 1; 143 | amounts[5] = 1; 144 | amounts[6] = 1; 145 | amounts[7] = 1; 146 | amounts[8] = 1; 147 | amounts[9] = 1; 148 | amounts[10] = 1; 149 | 150 | sut.mintBatch(address(0xAAAA), ids, amounts); 151 | } 152 | 153 | function test_safeBatchTransferFrom_1() public { 154 | uint256[] memory ids = new uint256[](1); 155 | ids[0] = 1; 156 | 157 | uint256[] memory amounts = new uint256[](1); 158 | amounts[0] = 1; 159 | 160 | HEVM.prank(address(0xAAAA)); 161 | sut.safeBatchTransferFrom(address(0xAAAA), address(0xBBBB), ids, amounts, ""); 162 | } 163 | 164 | function test_safeBatchTransferFrom_5() public { 165 | uint256[] memory ids = new uint256[](5); 166 | ids[0] = 1; 167 | ids[1] = 2; 168 | ids[2] = 3; 169 | ids[3] = 4; 170 | ids[4] = 5; 171 | 172 | uint256[] memory amounts = new uint256[](5); 173 | amounts[0] = 1; 174 | amounts[1] = 1; 175 | amounts[2] = 1; 176 | amounts[3] = 1; 177 | amounts[4] = 1; 178 | 179 | HEVM.prank(address(0xAAAA)); 180 | sut.safeBatchTransferFrom(address(0xAAAA), address(0xBBBB), ids, amounts, ""); 181 | } 182 | 183 | function test_safeBatchTransferFrom_10() public { 184 | uint256[] memory ids = new uint256[](10); 185 | ids[0] = 1; 186 | ids[1] = 2; 187 | ids[2] = 3; 188 | ids[3] = 4; 189 | ids[4] = 5; 190 | ids[5] = 6; 191 | ids[6] = 7; 192 | ids[7] = 8; 193 | ids[8] = 9; 194 | ids[9] = 10; 195 | 196 | uint256[] memory amounts = new uint256[](10); 197 | amounts[0] = 1; 198 | amounts[1] = 1; 199 | amounts[2] = 1; 200 | amounts[3] = 1; 201 | amounts[4] = 1; 202 | amounts[5] = 1; 203 | amounts[6] = 1; 204 | amounts[7] = 1; 205 | amounts[8] = 1; 206 | amounts[9] = 1; 207 | 208 | HEVM.prank(address(0xAAAA)); 209 | sut.safeBatchTransferFrom(address(0xAAAA), address(0xBBBB), ids, amounts, ""); 210 | } 211 | } 212 | 213 | // deploy 214 | contract ERC1155_Solmate_deploy_Test is DSTest { 215 | function test_deploy() public { 216 | ERC1155_Solmate sut = new ERC1155_Solmate(); 217 | } 218 | } 219 | 220 | // mint 221 | contract ERC1155_Solmate_mint_Test is DSTest { 222 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 223 | 224 | ERC1155_Solmate internal sut; 225 | 226 | function setUp() public { 227 | sut = new ERC1155_Solmate(); 228 | } 229 | 230 | function test_mint() public { 231 | sut.mint(address(0xAAAA), 1, 1); 232 | } 233 | } 234 | 235 | // mintBatch 236 | contract ERC1155_Solmate_mintBatch_Test is DSTest { 237 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 238 | 239 | ERC1155_Solmate internal sut; 240 | 241 | function setUp() public { 242 | sut = new ERC1155_Solmate(); 243 | } 244 | 245 | function test_mintBatch_1() public { 246 | uint256[] memory ids = new uint256[](1); 247 | ids[0] = 1; 248 | 249 | uint256[] memory amounts = new uint256[](1); 250 | amounts[0] = 1; 251 | 252 | sut.mintBatch(address(0xAAAA), ids, amounts); 253 | } 254 | 255 | function test_mintBatch_5() public { 256 | uint256[] memory ids = new uint256[](5); 257 | ids[0] = 1; 258 | ids[1] = 2; 259 | ids[2] = 3; 260 | ids[3] = 4; 261 | ids[4] = 5; 262 | 263 | uint256[] memory amounts = new uint256[](5); 264 | amounts[0] = 1; 265 | amounts[1] = 1; 266 | amounts[2] = 1; 267 | amounts[3] = 1; 268 | amounts[4] = 1; 269 | 270 | sut.mintBatch(address(0xAAAA), ids, amounts); 271 | } 272 | 273 | function test_mintBatch_10() public { 274 | uint256[] memory ids = new uint256[](10); 275 | ids[0] = 1; 276 | ids[1] = 2; 277 | ids[2] = 3; 278 | ids[3] = 4; 279 | ids[4] = 5; 280 | ids[5] = 6; 281 | ids[6] = 7; 282 | ids[7] = 8; 283 | ids[8] = 9; 284 | ids[9] = 10; 285 | 286 | uint256[] memory amounts = new uint256[](10); 287 | amounts[0] = 1; 288 | amounts[1] = 1; 289 | amounts[2] = 1; 290 | amounts[3] = 1; 291 | amounts[4] = 1; 292 | amounts[5] = 1; 293 | amounts[6] = 1; 294 | amounts[7] = 1; 295 | amounts[8] = 1; 296 | amounts[9] = 2; 297 | 298 | sut.mintBatch(address(0xAAAA), ids, amounts); 299 | } 300 | } 301 | 302 | // safeTransferFrom 303 | contract ERC1155_Solmate_safeTransferFrom_Test is DSTest { 304 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 305 | 306 | ERC1155_Solmate internal sut; 307 | 308 | function setUp() public { 309 | sut = new ERC1155_Solmate(); 310 | sut.mint(address(0xAAAA), 1, 1); 311 | } 312 | 313 | function test_safeTransferFrom() public { 314 | HEVM.prank(address(0xAAAA)); 315 | sut.safeTransferFrom(address(0xAAAA), address(0xBBBB), 1, 1, ""); 316 | } 317 | } 318 | 319 | // safeBatchTransferFrom 320 | contract ERC1155_Solmate_safeBatchTransferFrom_Test is DSTest { 321 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 322 | 323 | ERC1155_Solmate internal sut; 324 | 325 | function setUp() public { 326 | sut = new ERC1155_Solmate(); 327 | 328 | uint256[] memory ids = new uint256[](11); 329 | ids[0] = 1; 330 | ids[1] = 2; 331 | ids[2] = 3; 332 | ids[3] = 4; 333 | ids[4] = 5; 334 | ids[5] = 6; 335 | ids[6] = 7; 336 | ids[7] = 8; 337 | ids[8] = 9; 338 | ids[9] = 10; 339 | ids[10] = 11; 340 | 341 | uint256[] memory amounts = new uint256[](11); 342 | amounts[0] = 1; 343 | amounts[1] = 1; 344 | amounts[2] = 1; 345 | amounts[3] = 1; 346 | amounts[4] = 1; 347 | amounts[5] = 1; 348 | amounts[6] = 1; 349 | amounts[7] = 1; 350 | amounts[8] = 1; 351 | amounts[9] = 1; 352 | amounts[10] = 1; 353 | 354 | sut.mintBatch(address(0xAAAA), ids, amounts); 355 | } 356 | 357 | function test_safeBatchTransferFrom_1() public { 358 | uint256[] memory ids = new uint256[](1); 359 | ids[0] = 1; 360 | 361 | uint256[] memory amounts = new uint256[](1); 362 | amounts[0] = 1; 363 | 364 | HEVM.prank(address(0xAAAA)); 365 | sut.safeBatchTransferFrom(address(0xAAAA), address(0xBBBB), ids, amounts, ""); 366 | } 367 | 368 | function test_safeBatchTransferFrom_5() public { 369 | uint256[] memory ids = new uint256[](5); 370 | ids[0] = 1; 371 | ids[1] = 2; 372 | ids[2] = 3; 373 | ids[3] = 4; 374 | ids[4] = 5; 375 | 376 | uint256[] memory amounts = new uint256[](5); 377 | amounts[0] = 1; 378 | amounts[1] = 1; 379 | amounts[2] = 1; 380 | amounts[3] = 1; 381 | amounts[4] = 1; 382 | 383 | HEVM.prank(address(0xAAAA)); 384 | sut.safeBatchTransferFrom(address(0xAAAA), address(0xBBBB), ids, amounts, ""); 385 | } 386 | 387 | function test_safeBatchTransferFrom_10() public { 388 | uint256[] memory ids = new uint256[](10); 389 | ids[0] = 1; 390 | ids[1] = 2; 391 | ids[2] = 3; 392 | ids[3] = 4; 393 | ids[4] = 5; 394 | ids[5] = 6; 395 | ids[6] = 7; 396 | ids[7] = 8; 397 | ids[8] = 9; 398 | ids[9] = 10; 399 | 400 | uint256[] memory amounts = new uint256[](10); 401 | amounts[0] = 1; 402 | amounts[1] = 1; 403 | amounts[2] = 1; 404 | amounts[3] = 1; 405 | amounts[4] = 1; 406 | amounts[5] = 1; 407 | amounts[6] = 1; 408 | amounts[7] = 1; 409 | amounts[8] = 1; 410 | amounts[9] = 1; 411 | 412 | HEVM.prank(address(0xAAAA)); 413 | sut.safeBatchTransferFrom(address(0xAAAA), address(0xBBBB), ids, amounts, ""); 414 | } 415 | } 416 | -------------------------------------------------------------------------------- /templates/ERC1155.t.sol.gyb: -------------------------------------------------------------------------------- 1 | %{ 2 | import yaml 3 | with open('../test-cases.yml', 'r') as file: 4 | config = yaml.safe_load(file) 5 | contracts = config["contracts"] 6 | }% 7 | // SPDX-License-Identifier: UNLICENSED 8 | pragma solidity >=0.8.4; 9 | 10 | import {DSTest} from "@ds-test/test.sol"; 11 | import {Vm} from "@forge-std/Vm.sol"; 12 | %for variation in contracts["erc1155"]["variations"]: 13 | import {ERC1155_${variation}} from "$/ERC1155_${variation}.sol"; 14 | % end 15 | %for variation in contracts["erc1155"]["variations"]: 16 | 17 | // deploy 18 | contract ERC1155_${variation}_deploy_Test is DSTest { 19 | function test_deploy() public { 20 | ERC1155_${variation} sut = new ERC1155_${variation}(); 21 | } 22 | } 23 | 24 | // mint 25 | contract ERC1155_${variation}_mint_Test is DSTest { 26 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 27 | 28 | ERC1155_${variation} internal sut; 29 | 30 | function setUp() public { 31 | sut = new ERC1155_${variation}(); 32 | } 33 | 34 | function test_mint() public { 35 | sut.mint(address(0xAAAA), 1, 1); 36 | } 37 | } 38 | 39 | // mintBatch 40 | contract ERC1155_${variation}_mintBatch_Test is DSTest { 41 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 42 | 43 | ERC1155_${variation} internal sut; 44 | 45 | function setUp() public { 46 | sut = new ERC1155_${variation}(); 47 | } 48 | 49 | function test_mintBatch_1() public { 50 | uint256[] memory ids = new uint256[](1); 51 | ids[0] = 1; 52 | 53 | uint256[] memory amounts = new uint256[](1); 54 | amounts[0] = 1; 55 | 56 | sut.mintBatch(address(0xAAAA), ids, amounts); 57 | } 58 | 59 | function test_mintBatch_5() public { 60 | uint256[] memory ids = new uint256[](5); 61 | ids[0] = 1; 62 | ids[1] = 2; 63 | ids[2] = 3; 64 | ids[3] = 4; 65 | ids[4] = 5; 66 | 67 | uint256[] memory amounts = new uint256[](5); 68 | amounts[0] = 1; 69 | amounts[1] = 1; 70 | amounts[2] = 1; 71 | amounts[3] = 1; 72 | amounts[4] = 1; 73 | 74 | sut.mintBatch(address(0xAAAA), ids, amounts); 75 | } 76 | 77 | function test_mintBatch_10() public { 78 | uint256[] memory ids = new uint256[](10); 79 | ids[0] = 1; 80 | ids[1] = 2; 81 | ids[2] = 3; 82 | ids[3] = 4; 83 | ids[4] = 5; 84 | ids[5] = 6; 85 | ids[6] = 7; 86 | ids[7] = 8; 87 | ids[8] = 9; 88 | ids[9] = 10; 89 | 90 | uint256[] memory amounts = new uint256[](10); 91 | amounts[0] = 1; 92 | amounts[1] = 1; 93 | amounts[2] = 1; 94 | amounts[3] = 1; 95 | amounts[4] = 1; 96 | amounts[5] = 1; 97 | amounts[6] = 1; 98 | amounts[7] = 1; 99 | amounts[8] = 1; 100 | amounts[9] = 2; 101 | 102 | sut.mintBatch(address(0xAAAA), ids, amounts); 103 | } 104 | } 105 | 106 | // safeTransferFrom 107 | contract ERC1155_${variation}_safeTransferFrom_Test is DSTest { 108 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 109 | 110 | ERC1155_${variation} internal sut; 111 | 112 | function setUp() public { 113 | sut = new ERC1155_${variation}(); 114 | sut.mint(address(0xAAAA), 1, 1); 115 | } 116 | 117 | function test_safeTransferFrom() public { 118 | HEVM.prank(address(0xAAAA)); 119 | sut.safeTransferFrom(address(0xAAAA), address(0xBBBB), 1, 1, ""); 120 | } 121 | } 122 | 123 | // safeBatchTransferFrom 124 | contract ERC1155_${variation}_safeBatchTransferFrom_Test is DSTest { 125 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 126 | 127 | ERC1155_${variation} internal sut; 128 | 129 | function setUp() public { 130 | sut = new ERC1155_${variation}(); 131 | 132 | uint256[] memory ids = new uint256[](11); 133 | ids[0] = 1; 134 | ids[1] = 2; 135 | ids[2] = 3; 136 | ids[3] = 4; 137 | ids[4] = 5; 138 | ids[5] = 6; 139 | ids[6] = 7; 140 | ids[7] = 8; 141 | ids[8] = 9; 142 | ids[9] = 10; 143 | ids[10] = 11; 144 | 145 | uint256[] memory amounts = new uint256[](11); 146 | amounts[0] = 1; 147 | amounts[1] = 1; 148 | amounts[2] = 1; 149 | amounts[3] = 1; 150 | amounts[4] = 1; 151 | amounts[5] = 1; 152 | amounts[6] = 1; 153 | amounts[7] = 1; 154 | amounts[8] = 1; 155 | amounts[9] = 1; 156 | amounts[10] = 1; 157 | 158 | sut.mintBatch(address(0xAAAA), ids, amounts); 159 | } 160 | 161 | function test_safeBatchTransferFrom_1() public { 162 | uint256[] memory ids = new uint256[](1); 163 | ids[0] = 1; 164 | 165 | uint256[] memory amounts = new uint256[](1); 166 | amounts[0] = 1; 167 | 168 | HEVM.prank(address(0xAAAA)); 169 | sut.safeBatchTransferFrom(address(0xAAAA), address(0xBBBB), ids, amounts, ""); 170 | } 171 | 172 | function test_safeBatchTransferFrom_5() public { 173 | uint256[] memory ids = new uint256[](5); 174 | ids[0] = 1; 175 | ids[1] = 2; 176 | ids[2] = 3; 177 | ids[3] = 4; 178 | ids[4] = 5; 179 | 180 | uint256[] memory amounts = new uint256[](5); 181 | amounts[0] = 1; 182 | amounts[1] = 1; 183 | amounts[2] = 1; 184 | amounts[3] = 1; 185 | amounts[4] = 1; 186 | 187 | HEVM.prank(address(0xAAAA)); 188 | sut.safeBatchTransferFrom(address(0xAAAA), address(0xBBBB), ids, amounts, ""); 189 | } 190 | 191 | function test_safeBatchTransferFrom_10() public { 192 | uint256[] memory ids = new uint256[](10); 193 | ids[0] = 1; 194 | ids[1] = 2; 195 | ids[2] = 3; 196 | ids[3] = 4; 197 | ids[4] = 5; 198 | ids[5] = 6; 199 | ids[6] = 7; 200 | ids[7] = 8; 201 | ids[8] = 9; 202 | ids[9] = 10; 203 | 204 | uint256[] memory amounts = new uint256[](10); 205 | amounts[0] = 1; 206 | amounts[1] = 1; 207 | amounts[2] = 1; 208 | amounts[3] = 1; 209 | amounts[4] = 1; 210 | amounts[5] = 1; 211 | amounts[6] = 1; 212 | amounts[7] = 1; 213 | amounts[8] = 1; 214 | amounts[9] = 1; 215 | 216 | HEVM.prank(address(0xAAAA)); 217 | sut.safeBatchTransferFrom(address(0xAAAA), address(0xBBBB), ids, amounts, ""); 218 | } 219 | } 220 | % end 221 | -------------------------------------------------------------------------------- /templates/ERC20.t.sol.gyb: -------------------------------------------------------------------------------- 1 | %{ 2 | import yaml 3 | with open('../test-cases.yml', 'r') as file: 4 | config = yaml.safe_load(file) 5 | contracts = config["contracts"] 6 | }% 7 | // SPDX-License-Identifier: UNLICENSED 8 | pragma solidity >=0.8.4; 9 | 10 | import {DSTest} from "@ds-test/test.sol"; 11 | import {Vm} from "@forge-std/Vm.sol"; 12 | % for variation in contracts["erc20"]["variations"]: 13 | import {ERC20_${variation}} from "$/ERC20_${variation}.sol"; 14 | % end 15 | % for variation in contracts["erc20"]["variations"]: 16 | 17 | // deploy 18 | contract ERC20_${variation}_deploy_Test is DSTest { 19 | function test_deploy() public { 20 | ERC20_${variation} sut = new ERC20_${variation}(); 21 | } 22 | } 23 | 24 | // transferToNonOwner 25 | contract ERC20_${variation}_transferToNonOwner_Test is DSTest { 26 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 27 | 28 | ERC20_${variation} internal sut; 29 | 30 | function setUp() public { 31 | sut = new ERC20_${variation}(); 32 | sut.mint(address(0xAAAA), 1000 ether); 33 | } 34 | 35 | function test_transferToNonOwner() public { 36 | HEVM.prank(address(0xAAAA)); 37 | sut.transfer(address(0xBBBB), 500 ether); 38 | } 39 | } 40 | 41 | // transferToOwner 42 | contract ERC20_${variation}_transferToOwner_Test is DSTest { 43 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 44 | 45 | ERC20_${variation} internal sut; 46 | 47 | function setUp() public { 48 | sut = new ERC20_${variation}(); 49 | sut.mint(address(0xAAAA), 1000 ether); 50 | sut.mint(address(0xBBBB), 1000 ether); 51 | } 52 | 53 | function test_transferToOwner() public { 54 | HEVM.prank(address(0xAAAA)); 55 | sut.transfer(address(0xBBBB), 500 ether); 56 | } 57 | } 58 | 59 | // transferFromToNonOwner 60 | contract ERC20_${variation}_transferFromToNonOwner_Test is DSTest { 61 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 62 | 63 | ERC20_${variation} internal sut; 64 | 65 | function setUp() public { 66 | sut = new ERC20_${variation}(); 67 | sut.mint(address(0xAAAA), 1000 ether); 68 | HEVM.prank(address(0xAAAA)); 69 | sut.approve(address(0xBBBB), 1000 ether); 70 | } 71 | 72 | function test_transferFromToNonOwner() public { 73 | HEVM.prank(address(0xBBBB)); 74 | sut.transferFrom(address(0xAAAA), address(0xCCCC), 500 ether); 75 | } 76 | } 77 | 78 | // transferFromToOwner 79 | contract ERC20_${variation}_transferFromToOwner_Test is DSTest { 80 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 81 | 82 | ERC20_${variation} internal sut; 83 | 84 | function setUp() public { 85 | sut = new ERC20_${variation}(); 86 | sut.mint(address(0xAAAA), 1000 ether); 87 | sut.mint(address(0xCCCC), 1000 ether); 88 | HEVM.prank(address(0xAAAA)); 89 | sut.approve(address(0xBBBB), 1000 ether); 90 | } 91 | 92 | function test_transferFromToOwner() public { 93 | HEVM.prank(address(0xBBBB)); 94 | sut.transferFrom(address(0xAAAA), address(0xCCCC), 500 ether); 95 | } 96 | } 97 | 98 | // approve 99 | contract ERC20_${variation}_approve_Test is DSTest { 100 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 101 | 102 | ERC20_${variation} internal sut; 103 | 104 | function setUp() public { 105 | sut = new ERC20_${variation}(); 106 | sut.mint(address(0xAAAA), 1000 ether); 107 | } 108 | 109 | function test_approve() public { 110 | HEVM.prank(address(0xAAAA)); 111 | sut.approve(address(0xBBBB), 1000 ether); 112 | } 113 | } 114 | 115 | // totalSupply 116 | contract ERC20_${variation}_totalSupply_Test is DSTest { 117 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 118 | 119 | ERC20_${variation} internal sut; 120 | 121 | function setUp() public { 122 | sut = new ERC20_${variation}(); 123 | sut.mint(address(0xAAAA), 1000 ether); 124 | } 125 | 126 | function test_totalSupply() public view { 127 | sut.totalSupply(); 128 | } 129 | } 130 | 131 | // balanceOf 132 | contract ERC20_${variation}_balanceOf_Test is DSTest { 133 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 134 | 135 | ERC20_${variation} internal sut; 136 | 137 | function setUp() public { 138 | sut = new ERC20_${variation}(); 139 | sut.mint(address(0xAAAA), 1000 ether); 140 | } 141 | 142 | function test_balanceOf() public view { 143 | sut.balanceOf(address(0xAAAA)); 144 | } 145 | } 146 | 147 | // allowance 148 | contract ERC20_${variation}_allowance_Test is DSTest { 149 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 150 | 151 | ERC20_${variation} internal sut; 152 | 153 | function setUp() public { 154 | sut = new ERC20_${variation}(); 155 | sut.mint(address(0xAAAA), 1000 ether); 156 | HEVM.prank(address(0xAAAA)); 157 | sut.approve(address(0xBBBB), 1000 ether); 158 | } 159 | 160 | function test_allowance() public view { 161 | sut.allowance(address(0xAAAA), address(0xBBBB)); 162 | } 163 | } 164 | % end -------------------------------------------------------------------------------- /templates/ERC721.t.sol.gyb: -------------------------------------------------------------------------------- 1 | %{ 2 | import yaml 3 | with open('../test-cases.yml', 'r') as file: 4 | config = yaml.safe_load(file) 5 | contracts = config["contracts"] 6 | }% 7 | // SPDX-License-Identifier: UNLICENSED 8 | pragma solidity >=0.8.4; 9 | 10 | import {DSTest} from "@ds-test/test.sol"; 11 | import {Vm} from "@forge-std/Vm.sol"; 12 | % for variation in contracts["erc721"]["variations"]: 13 | import {ERC721_${variation}${",ERC721_{}_ERC2309".format(variation) if variation in contracts["erc721"]["ERC2309Variations"] else ""}} from "$/ERC721_${variation}.sol"; 14 | % end 15 | % for variation in contracts["erc721"]["variations"]: 16 | 17 | // deploy 18 | contract ERC721_${variation}_deploy_Test is DSTest { 19 | function test_deploy() public { 20 | ERC721_${variation} sut = new ERC721_${variation}(); 21 | } 22 | } 23 | % if variation in contracts["erc721"]["ERC2309Variations"]: 24 | 25 | // deployERC2309 26 | contract ERC721_${variation}_deployERC2309_Test is DSTest { 27 | % for mintAmount in contracts["erc721"]["methods"]["ERC2309Mint"]: 28 | 29 | function test_deployERC2309_${mintAmount}() public { 30 | ERC721_${variation}_ERC2309 sut = new ERC721_${variation}_ERC2309(${mintAmount}); 31 | } 32 | % end 33 | } 34 | % end 35 | 36 | // mint 37 | contract ERC721_${variation}_mint_Test is DSTest { 38 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 39 | 40 | ERC721_${variation} internal sut; 41 | 42 | function setUp() public { 43 | sut = new ERC721_${variation}(); 44 | } 45 | % for mintAmount in contracts["erc721"]["methods"]["mint"]: 46 | 47 | function test_mint_${mintAmount}() public { 48 | sut.mint(address(0xAAAA), ${mintAmount}); 49 | } 50 | % end 51 | } 52 | 53 | // safeMint 54 | contract ERC721_${variation}_safeMint_Test is DSTest { 55 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 56 | 57 | ERC721_${variation} internal sut; 58 | 59 | function setUp() public { 60 | sut = new ERC721_${variation}(); 61 | } 62 | % for mintAmount in contracts["erc721"]["methods"]["mint"]: 63 | 64 | function test_safeMint_${mintAmount}() public { 65 | sut.safeMint(address(0xAAAA), ${mintAmount}); 66 | } 67 | % end 68 | } 69 | 70 | // burn 71 | contract ERC721_${variation}_burn_Test is DSTest { 72 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 73 | 74 | ERC721_${variation} internal sut; 75 | 76 | function setUp() public { 77 | sut = new ERC721_${variation}(); 78 | sut.mint(address(0xAAAA), 101); 79 | } 80 | % for tokenId in contracts["erc721"]["methods"]["burn"]: 81 | 82 | function test_burn_id${tokenId}() public { 83 | HEVM.prank(address(0xAAAA)); 84 | sut.burn(${tokenId}); 85 | } 86 | % end 87 | } 88 | 89 | // transfer toOwner 90 | contract ERC721_${variation}_transferToOwner_Test is DSTest { 91 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 92 | 93 | ERC721_${variation} internal sut; 94 | 95 | function setUp() public { 96 | sut = new ERC721_${variation}(); 97 | sut.mint(address(0xAAAA), 101); 98 | sut.mint(address(0xBBBB), 101); 99 | } 100 | % for tokenId in contracts["erc721"]["methods"]["transfer"]: 101 | 102 | function test_transferToOwner_id${tokenId}() public { 103 | HEVM.prank(address(0xAAAA)); 104 | sut.transferFrom(address(0xAAAA), address(0xBBBB), ${tokenId}); 105 | } 106 | % end 107 | } 108 | 109 | // transfer toNonOwner 110 | contract ERC721_${variation}_transferToNonOwner_Test is DSTest { 111 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 112 | 113 | ERC721_${variation} internal sut; 114 | 115 | function setUp() public { 116 | sut = new ERC721_${variation}(); 117 | sut.mint(address(0xAAAA), 101); 118 | } 119 | % for tokenId in contracts["erc721"]["methods"]["transfer"]: 120 | 121 | function test_transferToNonOwner_id${tokenId}() public { 122 | HEVM.prank(address(0xAAAA)); 123 | sut.transferFrom(address(0xAAAA), address(0xCCCC), ${tokenId}); 124 | } 125 | % end 126 | } 127 | 128 | // safeTransfer toOwner 129 | contract ERC721_${variation}_safeTransferToOwner_Test is DSTest { 130 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 131 | 132 | ERC721_${variation} internal sut; 133 | 134 | function setUp() public { 135 | sut = new ERC721_${variation}(); 136 | sut.mint(address(0xAAAA), 101); 137 | sut.mint(address(0xBBBB), 101); 138 | } 139 | % for tokenId in contracts["erc721"]["methods"]["transfer"]: 140 | 141 | function test_safeTransferToOwner_id${tokenId}() public { 142 | HEVM.prank(address(0xAAAA)); 143 | sut.safeTransferFrom(address(0xAAAA), address(0xBBBB), ${tokenId}); 144 | } 145 | % end 146 | } 147 | 148 | // safeTransfer toNonOwner 149 | contract ERC721_${variation}_safeTransferToNonOwner_Test is DSTest { 150 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 151 | 152 | ERC721_${variation} internal sut; 153 | 154 | function setUp() public { 155 | sut = new ERC721_${variation}(); 156 | sut.mint(address(0xAAAA), 101); 157 | } 158 | % for tokenId in contracts["erc721"]["methods"]["transfer"]: 159 | 160 | function test_safeTransferToNonOwner_id${tokenId}() public { 161 | HEVM.prank(address(0xAAAA)); 162 | sut.safeTransferFrom(address(0xAAAA), address(0xCCCC), ${tokenId}); 163 | } 164 | % end 165 | } 166 | 167 | // setApprovalForAll 168 | contract ERC721_${variation}_setApprovalForAll_Test is DSTest { 169 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 170 | 171 | ERC721_${variation} internal sut; 172 | 173 | function setUp() public { 174 | sut = new ERC721_${variation}(); 175 | sut.mint(address(0xAAAA), 101); 176 | } 177 | 178 | function test_setApprovalForAll() public { 179 | HEVM.prank(address(0xAAAA)); 180 | sut.setApprovalForAll(address(0xCCCC), true); 181 | } 182 | } 183 | 184 | // approve 185 | contract ERC721_${variation}_approve_Test is DSTest { 186 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 187 | 188 | ERC721_${variation} internal sut; 189 | 190 | function setUp() public { 191 | sut = new ERC721_${variation}(); 192 | sut.mint(address(0xAAAA), 101); 193 | } 194 | 195 | % for tokenId in contracts["erc721"]["methods"]["transfer"]: 196 | 197 | function test_approve_id${tokenId}() public { 198 | HEVM.prank(address(0xAAAA)); 199 | sut.approve(address(0xCCCC), ${tokenId}); 200 | } 201 | % end 202 | } 203 | 204 | // balanceOf 205 | contract ERC721_${variation}_balanceOf_Test is DSTest { 206 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 207 | 208 | ERC721_${variation} internal sut; 209 | 210 | function setUp() public { 211 | sut = new ERC721_${variation}(); 212 | sut.mint(address(0xAAAA), 1); 213 | sut.mint(address(0xBBBB), 10); 214 | sut.mint(address(0xCCCC), 50); 215 | sut.mint(address(0xDDDD), 100); 216 | } 217 | 218 | function test_balanceOf_1() view public { 219 | sut.balanceOf(address(0xAAAA)); 220 | } 221 | 222 | function test_balanceOf_10() view public { 223 | sut.balanceOf(address(0xBBBB)); 224 | } 225 | 226 | function test_balanceOf_50() view public { 227 | sut.balanceOf(address(0xCCCC)); 228 | } 229 | 230 | function test_balanceOf_100() view public { 231 | sut.balanceOf(address(0xDDDD)); 232 | } 233 | } 234 | 235 | contract ERC721_${variation}_ownerOf_Test is DSTest { 236 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 237 | 238 | ERC721_${variation} internal sut; 239 | 240 | function setUp() public { 241 | sut = new ERC721_${variation}(); 242 | sut.mint(address(0xAAAA), 101); 243 | } 244 | 245 | function test_ownerOf_1() view public { 246 | sut.ownerOf(1); 247 | } 248 | 249 | function test_ownerOf_10() view public { 250 | sut.ownerOf(10); 251 | } 252 | 253 | function test_ownerOf_50() view public { 254 | sut.ownerOf(50); 255 | } 256 | 257 | function test_ownerOf_100() view public { 258 | sut.ownerOf(100); 259 | } 260 | } 261 | 262 | contract ERC721_${variation}_getApproved_Test is DSTest { 263 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 264 | 265 | ERC721_${variation} internal sut; 266 | 267 | function setUp() public { 268 | sut = new ERC721_${variation}(); 269 | sut.mint(address(0xAAAA), 101); 270 | } 271 | 272 | function test_getApproved_1() view public { 273 | sut.ownerOf(1); 274 | } 275 | 276 | function test_getApproved_10() view public { 277 | sut.ownerOf(10); 278 | } 279 | 280 | function test_getApproved_50() view public { 281 | sut.ownerOf(50); 282 | } 283 | 284 | function test_getApproved_100() view public { 285 | sut.ownerOf(100); 286 | } 287 | } 288 | 289 | // isApprovedForAll 290 | contract ERC721_${variation}_isApprovedForAll_Test is DSTest { 291 | Vm internal constant HEVM = Vm(HEVM_ADDRESS); 292 | 293 | ERC721_${variation} internal sut; 294 | 295 | function setUp() public { 296 | sut = new ERC721_${variation}(); 297 | sut.mint(address(0xAAAA), 10); 298 | } 299 | 300 | function test_isApprovedForAll() view public { 301 | sut.isApprovedForAll(address(0xAAAA), address(0xBBBB)); 302 | } 303 | } 304 | % end 305 | -------------------------------------------------------------------------------- /test-cases.yml: -------------------------------------------------------------------------------- 1 | contracts: 2 | erc20: 3 | variations: [OZ, OZPermit, Solmate, Maple] 4 | erc721: 5 | variations: [OZ, OZEnumerable, OZConsecutive, Solady, Solmate, A, B, K] 6 | ERC2309Variations: [OZConsecutive, A] 7 | methods: 8 | # Transfer 9 | # - For transfer tests, there is one account with tokens from 1 to 100. 10 | # - The numbers below is which token ID to transfer. Each number in the 11 | # array will generate a test transfering the specific token Id. This only 12 | # affects a few implementations like ERC721A. 13 | transfer: [1, 10, 50, 100] 14 | # Approve 15 | # - same logic as Transfer, but for approval, the numbers below are token ids 16 | approve: [1, 10, 50, 100] 17 | # Burn 18 | # - same logic as Transfer, but for burn, the numbers below are token ids 19 | burn: [1, 10, 50, 100] 20 | 21 | # Mint 22 | # - The numbers below are the amount to mint. Each number in the array will 23 | # generate a test minting the number. 24 | mint: [1, 2, 3, 4, 5, 10, 50, 100] 25 | 26 | # ERC2309Mint 27 | # - The numbers below are the amount to mint using ERC2309 during constructor. 28 | # - Only apply to ERC2309Variations 29 | # - Same logic as Mint for each amount. 30 | ERC2309Mint: [5, 10, 50, 100, 200, 300] 31 | erc1155: 32 | variations: [OZ, Solmate] 33 | --------------------------------------------------------------------------------