Gas consumption benchmarks for popular airdrop patterns
This repository contains a series of tests to measure gas usage for popular airdrop patterns with various token standards and airdrop mechanisms. Including:
- native currency (ETH);
- ERC20;
- ERC721;
- ERC1155.
The custom mapping-based contracts (AirdropClaimMappingERC{20/721/1155}
), and to some extent and as well, are purposely written poorly to fit common assumptions and patterns found in the wild.
Table of contents
Overview
Airdrop mechanisms (custom contracts):
Type | Tokens | Contract |
---|---|---|
Claimable airdrop (data inscribed into a mapping) | ERC20, ERC721, ERC1155 | AirdropClaimMappingERC20 , , |
Claimable airdrop (merkle proof) | ERC20, ERC721, ERC1155 | , , |
Claimable airdrop (signature) | ERC20, ERC721, ERC1155 | , , |
Airdrop (bytecode contract) | ERC20 |
Airdrop solutions (including already deployed contracts):
Type | Tokens | Contract | Website/source code |
---|---|---|---|
GasliteDrop (airdrop) | ETH, ERC20, ERC721 | drop.gaslite.org | |
GasliteDrop1155 (airdrop) | ERC1155 | drop.gaslite.org | |
GasliteMerkleDN (claimable airdrop, merkle proof) | ETH | GasliteMerkleDN | gaslite.org |
GasliteMerkleDT (claimable airdrop, merkle proof) | ERC20 | gaslite.org | |
Disperse.app (airdrop) | ETH, ERC20 | disperse.app | |
wentokens (airdrop) | ETH, ERC20 | www.wentokens.xyz | |
Thirdweb (airdrop) | ERC20, ERC721, ERC1155 | , , | thirdweb.com |
Thirdweb (claimable airdrop, merkle proof) | ERC20, ERC721, ERC1155 | , , | thirdweb.com |
This Readme is an attempt to showcase the results in an organized and sorted manner.
Note: The benchmarks do not include the gas consumption for , as a current limitation with Forge; this should actually be the most efficient way for airdropping ERC20 tokens.
Results
The tables below are based on gas benchmarks with the following parameters:
- 1,000 different random recipients;
- random amounts between 1e10 and 1e19 (10 * 18 decimals), except for ERC721 (1 token per recipient);
- some amounts are repeated randomly to better simulate real world scenarios ();
- randomness is generated with Solady LibPRNG, taking advantage of random calldata generated with fuzzing (see the unnamed uint256 parameter in each test function);
- the gas consumption is measured with Forge;
- Thirdweb contracts are supposed to be deployed as a proxy pointing to the actual implementation, so the cost of deploying the implementation is not included in the report.
See the full report for more details or generate it yourself.
Notes
For claim-based airdrops, multiple measurements are taken into account:
- deployment/initilization (e.g. Thirdweb contracts require only a proxy to be deployed, but the proxy needs to be initialized with the airdrop data, which can be quite expensive);
- deposit/airdrop (e.g. depositing tokens, writing the airdrop data to the contract);
- claim.
Steps 1 and 2 are aggregated into Gas deployment
, with the details for each amount in such way: total (deployment/initialization + deposit/airdrop)
.
For push-based airdrops, the gas cost of deploying and initializing the contract is ignored, as all solutions, excluding Thirdweb, are already deployed and available for use (direct call to the airdrop function).
ERC20 (push-based)
Rank | Contract | Gas (1,000 recipients) | Difference from #1 |
---|---|---|---|
1 | 25,542,088 --GAS-- | 0 | |
2 | Wentokens | 25,586,923 --GAS-- | +44,835 (+0.18%) --GAS-- |
3 | (disperseToken ) | 26,342,497 --GAS-- | +800,409 (+3.13%) --GAS-- |
4 | (disperseTokenSimple ) | 26,852,552 --GAS-- | +1,310,464 (+5.13%) --GAS-- |
5 | Thirdweb | 26,925,358 --GAS-- | +1,383,270 (+5.41%) --GAS-- |
ERC20 (claim-based)
Rank | Contract | Gas deployment (1,000 recipients) | Difference from #1 | Gas claim (1 recipient) | Difference from #1 |
---|---|---|---|---|---|
1 | 496,127 (496,127 + 0) --GAS-- | 0 | 85,766 --GAS-- | 0 | |
2 | 464,492 (464,492 + 0) --GAS-- | -31,635 (-6.81%) --GAS-- | 87,547 --GAS-- | +1,781 (+2.03%) --GAS-- | |
3 | 647,007 (601,488 + 45,519) --GAS-- | +150,880 (+30.41%) --GAS-- | 88,613 --GAS-- | +2,847 (+3.32%) --GAS-- | |
4 | Thirdweb | 207,525 (66,769 + 140,756) --GAS-- | -288,602 (-58.17%) --GAS-- | 90,267 --GAS-- | +4,501 (+5.25%) --GAS-- |
5 | AirdropClaimMapping | 25,666,389 (538,776 + 25,127,613) --GAS-- | +25,170,262 (+5,073.25%) --GAS-- | 57,631 --GAS-- | -28,135 (-32.80%) --GAS-- |
This comparison is opinionated. Some arguments to support it:
- The difference in deployment cost is too significant for
AirdropClaimMapping
to be considered a viable solution. Although, in pure gas terms, for 1,000 recipients, it's still cheaper than the Thirdweb and signature-based solutions, i.e. it will spend less gas in total. - Although the deployment for Thirdweb's
AirdropERC20Claimable
is half the cost ofAirdropClaimMerkle
orAirdropClaimSignature
, the increase in gas for claiming is too significant to have it ranked higher. I believe that the deployer paying ~400-500,000 gas instead of ~200,000 cannot justify each single claimer having to pay ~90,000 gas instead of ~86,000.
In any case, these are only benchmarks, with a ranking provided for convenience.
It's also worth noting that the top 1 and 2 custom contracts are really just mock implementations. Although they do allow claiming on behalf of another account, they lack some checks and utility functions (e.g. pausing the claim)—the position of these contracts in the ranking is not a recommendation to use them, but rather based on the gas consumption.
ERC721 (push-based)
Rank | Contract | Gas (1,000 recipients) | Difference from #1 |
---|---|---|---|
1 | 33,103,232 --GAS-- | 0 | |
2 | Thirdweb | 35,844,727 --GAS-- | +2,741,495 (+8.28%) --GAS-- |
ERC721 (claim-based)
Rank | Contract | Gas deployment (1,000 recipients) | Difference from #1 | Gas claim (1 recipient) | Difference from #1 |
---|---|---|---|---|---|
1 | 479,098 (479,098 + 0) --GAS-- | 0 | 93,072 --GAS-- | 0 | |
2 | 447,613 (447,613 + 0) --GAS-- | -31,485 (-6.57%) --GAS-- | 94,953 --GAS-- | +1,881 (+2.02%) --GAS-- | |
3 | 36,472,337 (520,397 + 35,951,940) --GAS-- | +35,993,239 (+7,512.71%) --GAS-- | 65,162 --GAS-- | -27,910 (-29.99%) --GAS-- | |
4 | Thirdweb | 22,452,426 (66,769 + 22,385,657) --GAS-- | +21,973,328 (+4,586.40%) --GAS-- | 2,257,594 --GAS-- | +2,164,522 (+2,325.64%) --GAS-- |
It really hurts to not put AirdropClaimMapping
in the last place, but Thirdweb's AirdropERC721Claimable
really is too much with both the ~30M gas deployment and the ~218k gas claims. With 1,000 recipients, it is more than 219M in gas just for users to claim their tokens...
Also, AirdropERC721Claimable
does not allow for airdroping specific tokens to specific accounts, it will just allow to claim n
amount of tokens, and read the tokenIds array in ascending order. So it basically looks like a minting function.
ERC1155 (push-based)
Rank | Contract | Gas (1,000 recipients) | Difference from #1 |
---|---|---|---|
1 | 29,910,313 --GAS-- | 0 | |
2 | Thirdweb | 30,320,907 --GAS-- | +410,594 (+1.37%) --GAS-- |
It's worth noting that GasliteDrop1155
takes advantage of multiple recipients with same amount by packing them into a single struct. Which much better simulates real world scenarios (e.g. users being rewarded the same amounts for the same token IDs after accomplishing a similar task). See:
1struct AirdropTokenAmount {2 uint256 amount;3 address[] recipients;4}
In these tests, there are ~14% of recipients aggregated with the same amount. As the proportion of recipients with the same amount increases, the gap in gas consumption between GasliteDrop1155
and Thirdweb's AirdropERC1155
contract will increase as well.
ERC1155 (claim-based)
Rank | Contract | Gas deployment (1,000 recipients) | Difference from #1 | Gas claim (1 recipient) | Difference from #1 |
---|---|---|---|---|---|
1 | 609,717 (609717 + 0) --GAS-- | 0 | 87,405 --GAS-- | 0 | |
2 | 577,332 (577,332 + 0) --GAS-- | -32,385 (-5.31%) --GAS-- | 89,236 --GAS-- | +1,831 (+2.10%) --GAS-- | |
3 | Thirdweb | 1,556,310 (66,769 + 1,489,541) --GAS-- | +946,593 (+155.25%) --GAS-- | 88,990 --GAS-- | +1,585 (+1.81%) --GAS-- |
4 | 27,929,999 (697,536 + 27,232,463) --GAS-- | +27,320,282 (+4,480.81%) --GAS-- | 59,402 --GAS-- | -28,003 (-32.03%) --GAS-- |
These contracts allow only for claiming a single token ID per recipient, to fit the Thirdweb pattern.
ETH (push-based)
Rank | Contract | Gas (1,000 recipients) | Difference from #1 |
---|---|---|---|
1 | 9,996,017 --GAS-- | 0 | |
2 | Wentokens | 10,050,255 --GAS-- | +54,238 (+0.54%) --GAS-- |
3 | 10,314,834 --GAS-- | +318,817 (+3.19%) --GAS-- |
Note: There tests use already initialized accounts—that is, accounts that were sent 1 wei prior to the measurement—to better simulate real world scenarios. This helps to avoid the cost of both the cold account access (2,500 gas) and the initialization surcharges (25,000 gas). See here for reference
ETH (claim-based)
Rank | Contract | Gas deployment (1,000 recipients) | Difference from #1 | Gas claim (1 recipient) | Difference from #1 |
---|---|---|---|---|---|
1 | GasliteMerkleDN | 536,646 (491,127 + 45,519) --GAS-- | 0 | 87,177 --GAS-- | 0 |
How to run
Setup
- Clone the repository and navigate to the root directory
1git clone git@github.com:0xpolarzero/airdrop-gas-benchmarks.git2cd airdrop-gas-benchmarks
-
Customize the amount of recipients and the amount of ERC1155 tokens ids to distribute
Usage
- Run all tests with gas snapshots
1# Output to stdout2forge test --gas-report3# Output to file4forge test --gas-report > gas-report.txt
- Run benchmarks for a specific token/currency
1# BenchmarksERC202# BenchmarksERC7213# BenchmarksERC11554# BenchmarksETH5forge test --mc BenchmarksERC20 --gas-report
- Run benchmarks for a specific contract/solution
1# AirdropClaimMapping2# AirdropClaimMerkle3# AirdropClaimSignature4# Disperse5# wentokens6# GasliteDrop7# BytecodeDrop8# Thirdweb9# ...10forge test --mt AirdropClaimMapping_ERC20 --gas-report
- Run a specific test
1# See the name of each test2forge test --mt test_ERC20_GasliteDrop --gas-report
Disclaimer
Warning: The custom contracts shared in this repository are not meant to be used in production. They are not audited, and some of them are written precisely to showcase how inefficient airdrops can be if not properly designed. This does not only apply to gas consumption, but also to security and usability.