SS2ERC721 is an ERC721 base contract that uses SSTORE2 for extremely efficient batch minting, as in mass airdrops to large numbers of recipients.
This repository demonstrates how to deploy a very simple but usable implementation, SimpleSS2ERC721.
Some observations:
- it is an ownable contract that implements
SS2ERC721
- it expects the final owner of the contract as a constructor argument
- the constructor also expects the typical
name
,symbol
andbaseURI
parameters - it exposes a
mintBatch(bytes calldata packedRecipients)
that only the contract owner can execute - it exposes
tokenURI(uint256 id)
, that simply returns the concatenation ofbaseURI
with the token id
And that's it! If that's all you need, you can certainly use it as is. No bells and whistles, just the simplest possible SimpleSS2ERC721
implementation that still behaves the way you would expect from a regular NFT.
Using the deployment script attached:
action | cost in gas | cost in ETH at 40 gwei |
---|---|---|
deploy | 1.27M | 0.05 |
mint batch of 1200 | 7.67M | 0.30 |
To put it differently, minting 1200 NFTs costs 6.4k gas per mint, about 90% cheaper than the most efficient "regular" ERC721 implementations.
- Install foundry
- clone/fork this repository (or click
Use this template
) cp .env.example .env
- generate a new wallet/deployer address with
cast wallet new
- configure the
PRIVATE_KEY
section of the.env
file with the private key you just generated - configure
ETHERSCAN_API_KEY
if you intend to deploy and verify the contract on a real chain - run
forge test
, the tests should come out clean
The deployment script SimpleSS2ERC721.s.sol will do the following:
- load the
PRIVATE_KEY
from your.env
, use the corresponding address to send transactions - load the configuration from token-config.json
- deploy
SimpleSS2ERC721
with your configuration - mint an NFT to all the
recipients
in token-config.json in a single transaction - (optionally) transfer the ownership of the contract to the
owner
address specified in token-config.json
If this all makes sense to you, you are now ready to go!
# configure `token-config.json` with the parameters that make sense for your collection
# note that the `recipients` in `token-config.json` need to be sorted in ascending numerical order, with no duplicates
# run a local simulation of the deployment, you should see the token transfers to the recipients in the trace (e.g. `emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x1111111111111111111111111111111111111111, id: 1)`)
forge script script/SimpleSS2ERC721.s.sol -vvvv
# run a simulation against a network
forge script script/SimpleSS2ERC721.s.sol --rpc-url <rpc>
# if everything looks good, deploy and mint!
forge script script/SimpleSS2ERC721.s.sol --rpc-url <rpc> --broadcast --verify --watch
The most notable limitation is that SS2ERC721 does not support on-demand minting, only batch minting. And in the case of the specific implementation used in this starter kit, only a single batch is supported, with a maximum size of 1228 recipients.
The other big trade-off is that SS2ERC721 initializes as little storage as possible upfront, instead delaying writes to storage on transfers. This makes transfers initially more expensive, and the view functions ownerOf
and balanceOf
are also more complex and more expensive.
Check out the full SS2ERC721 documentation for more details about the trade-offs.