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 (), 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):

TypeTokensContract
Claimable airdrop (data inscribed into a mapping)ERC20, ERC721, ERC1155, ,
Claimable airdrop (merkle proof)ERC20, ERC721, ERC1155, ,
Claimable airdrop (signature)ERC20, ERC721, ERC1155, ,
Airdrop (bytecode contract)ERC20

Airdrop solutions (including already deployed contracts):

TypeTokensContractWebsite/source code
GasliteDrop (airdrop)ETH, ERC20, ERC721drop.gaslite.org
GasliteDrop1155 (airdrop)ERC1155drop.gaslite.org
GasliteMerkleDN (claimable airdrop, merkle proof)ETHgaslite.org
GasliteMerkleDT (claimable airdrop, merkle proof)ERC20gaslite.org
Disperse.app (airdrop)ETH, ERC20disperse.app
wentokens (airdrop)ETH, ERC20www.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:

  1. 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);
  2. deposit/airdrop (e.g. depositing tokens, writing the airdrop data to the contract);
  3. 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)

RankContractGas (1,000 recipients)Difference from #1
125,542,088 --GAS--0
2Wentokens 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--
5Thirdweb 26,925,358 --GAS--+1,383,270 (+5.41%) --GAS--

ERC20 (claim-based)

RankContractGas deployment (1,000 recipients)Difference from #1Gas claim (1 recipient)Difference from #1
1496,127 (496,127 + 0) --GAS--085,766 --GAS--0
2464,492 (464,492 + 0) --GAS---31,635 (-6.81%) --GAS--87,547 --GAS--+1,781 (+2.03%) --GAS--
3647,007 (601,488 + 45,519) --GAS--+150,880 (+30.41%) --GAS--88,613 --GAS--+2,847 (+3.32%) --GAS--
4Thirdweb 207,525 (66,769 + 140,756) --GAS---288,602 (-58.17%) --GAS--90,267 --GAS--+4,501 (+5.25%) --GAS--
525,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 of AirdropClaimMerkle or AirdropClaimSignature, 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)

RankContractGas (1,000 recipients)Difference from #1
133,103,232 --GAS--0
2Thirdweb 35,844,727 --GAS--+2,741,495 (+8.28%) --GAS--

ERC721 (claim-based)

RankContractGas deployment (1,000 recipients)Difference from #1Gas claim (1 recipient)Difference from #1
1479,098 (479,098 + 0) --GAS--093,072 --GAS--0
2447,613 (447,613 + 0) --GAS---31,485 (-6.57%) --GAS--94,953 --GAS--+1,881 (+2.02%) --GAS--
336,472,337 (520,397 + 35,951,940) --GAS--+35,993,239 (+7,512.71%) --GAS--65,162 --GAS---27,910 (-29.99%) --GAS--
4Thirdweb 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)

RankContractGas (1,000 recipients)Difference from #1
129,910,313 --GAS--0
2Thirdweb 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:

1
struct 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)

RankContractGas deployment (1,000 recipients)Difference from #1Gas claim (1 recipient)Difference from #1
1609,717 (609717 + 0) --GAS--087,405 --GAS--0
2577,332 (577,332 + 0) --GAS---32,385 (-5.31%) --GAS--89,236 --GAS--+1,831 (+2.10%) --GAS--
3Thirdweb 1,556,310 (66,769 + 1,489,541) --GAS--+946,593 (+155.25%) --GAS--88,990 --GAS--+1,585 (+1.81%) --GAS--
427,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)

RankContractGas (1,000 recipients)Difference from #1
19,996,017 --GAS--0
2Wentokens 10,050,255 --GAS--+54,238 (+0.54%) --GAS--
310,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)

RankContractGas deployment (1,000 recipients)Difference from #1Gas claim (1 recipient)Difference from #1
1536,646 (491,127 + 45,519) --GAS--087,177 --GAS--0

How to run

Setup

  1. Clone the repository and navigate to the root directory
1
git clone git@github.com:0xpolarzero/airdrop-gas-benchmarks.git
2
cd airdrop-gas-benchmarks
  1. Install Foundry

  2. Customize the amount of recipients and the amount of ERC1155 tokens ids to distribute

Usage

  1. Run all tests with gas snapshots
1
# Output to stdout
2
forge test --gas-report
3
# Output to file
4
forge test --gas-report > gas-report.txt
  1. Run benchmarks for a specific token/currency
1
# BenchmarksERC20
2
# BenchmarksERC721
3
# BenchmarksERC1155
4
# BenchmarksETH
5
forge test --mc BenchmarksERC20 --gas-report
  1. Run benchmarks for a specific contract/solution
1
# AirdropClaimMapping
2
# AirdropClaimMerkle
3
# AirdropClaimSignature
4
# Disperse
5
# wentokens
6
# GasliteDrop
7
# BytecodeDrop
8
# Thirdweb
9
# ...
10
forge test --mt AirdropClaimMapping_ERC20 --gas-report
  1. Run a specific test
1
# See the name of each test
2
forge 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.

Design shamelessly forked and modified from 5/9