Sprites Minting Contract: An ERC721S Solution.

Check out the contract here.

Sprite Club
5 min readMar 22, 2022

Given current world events, searching “Gas Prices” on your favourite browser will most likely yield results showing high IRL petrol prices over the esoteric metaverse equivalent that we have all become far to accustomed to in the NFT space. However, that doesn’t mean they aren’t the only gas prices that are Gwei too high!

Whilst we all patiently await the post-merge scaling solutions outlined in The Ethereum Vision, the NFT ecosystem still struggles from crippling gas prices that can make participating in your favourite projects financially inaccessible. In the last 12 months, we have all experienced the frustration of paying eye-watering sums to mint hyped projects, approve marketplaces and accept offers on secondary.

Given this, we felt it was incredibly important to optimise the Sprites minting contract, building it from scratch to be as efficient as possible.

Let’s go through some of those optimisations:

TLDR

Gas prices suck, we’ve optimised the contract to reduce gas fees at mint.

Implementation of the Enurmerable extension & Batch Minting.

Approve OpenSea & LooksRare trading within the Sprites mint transaction.

On-chain allowlist means Spritelist = a guaranteed a chance to mint.

Minting quiz answers stored on-chain so you can see them forever.

Gas Savings

It’s first important to note that we’ve taken lots of inspiration from other projects, including many of our own and, of course, the ERC721A from Azuki which you can read about here.

The biggest gas savings come from efficient implementation of something called the ERC721Enumerable extension. This is an extension to the ERC721 specification that adds functions for getting the exact list of tokens owned by a user.

The contracts written by OpenZepellin (which most projects fork from) implement this in such a way that calling the function is very fast but costs more in gas when minting and trading because it requires more storage on the contract. We expect OpenZeppelin to update their version of this soon (they wrote it when gas wasn’t a big deal) but in the meantime, as Azuki says, everyone should be using the new style!

The next biggest gas saving comes from batch minting. Instead of updating all the data for each token in a batch, we only update what is required for each token and then update everything that can be batched only once at the end. We chose not to follow ERC721A exactly here because they optimised for a slightly different use case — minting up to 5 NFTs. There were efficiencies to be had during minting as if you bought 5, their ids would be sequential and so some clever storage tricks could be used to save space. This comes at a slight cost when selling for the first time. For Sprites, we only allow minting a max of 2 each so it doesn’t make as much sense to use this space saving trick.

Marketplace Approval at Mint

Whenever new mints happen, one of the first things that you see people do is approve a marketplace — most often OpenSea. It’s slightly annoying however, that you have to make another transaction in order to do this.

A solution OpenSea proposed is to auto-approve their proxy network for each user, which you can read about here. This works, but it isn’t ideal. In their implementation everyone gets approved for OpenSea by default whether they wanted to or not. If OpenSea is compromised in some way this would be terrible for anyone that had been approved without giving permission, especially if you are transferring to a cold wallet explicitly to avoid this!

Our solution is slightly simpler. All we do is allow you to provide some addresses to approve during the mint process. This way in a single transaction you can mint your Sprites and get your favourite marketplaces approved. If you transfer the token away, the permission doesn’t move with it, as with any well-implemented ERC721. We’ve included this as an option so that if you choose not to approve marketplaces your tokens will be minted as normal.

On average at 100gwei we calculate this will save ~$7 per user (the cost of just the transaction).

Spritelists

Due to the nature of our minting process, we needed to have a 100% allowlist mint. Technically, however, we have two allow lists — the main Spritelist and the raffle winners list for any unclaimed spots. In order to store these on-chain we use Merkle Trees.

A Merkle Tree provides an efficient way for leaf nodes (addresses in this case) to be validated as part of a set, given a set’s calculated “root” and a proof. We store the root of the tree on-chain and the lists will be made publicly available, which give us a provable way of showing who is on the list and not. This doesn’t save or cost any gas for minters, but it saves a lot of gas in the development process and gives minters the confidence they aren’t going to be rugged by not being included.

Other projects often do this “off-chain” by simply signing a transaction and then sending it via the frontend. This works fine but adds a centralised component to the process which we wanted to avoid.

On-chain Quiz Answers

One of the unique aspects of our minting process is the story-based personality quiz in which your answers directly influence the Sprite Class you mint. Once we compile everyone’s answers, and have taken you through the lore-building pre-reveal period, we will reveal the class for each Sprite — but how do you know we will do this fairly?

There’s 2 parts to this:

Firstly, we will make the quiz endlessly re-playable once the mint process is complete. Just revisit spriteclubnft.com to keep reliving ‘The Prologue’ to your heart’s content. Your Class will be instantly revealed at the end of the questions this time around!

Secondly, we store minters’ answers on-chain. Each person will go through a question flow, each of which has 5 answers, one for each Sprite Class. When the minting happens, we store these answers on-chain as a single number with the answers concatenated. So if your answers are:

A) 2

B) 1

C) 4

D) 5

E) 3

then your on-chain answer String will be ‘21453’.

We will then use this to allocate the Classes after the mint process. However, it’s so much more powerful than that — imagine all the cool things we could do with this information! We could find answer twins (minters with the exact same answers) or find the select few people that have answered in a completely unique way.

There are 5⁵=~3125 possible answers and even though we expect a linear distribution, it’s certainly not going to be flat!

If you’d like to take a look at the contract, the link is at the top of this article. We are openly publishing this now to allow for anyone to spot potential bugs. If you find something you would like to raise, or have any questions, reach out to @TheCryptoClancy via Twitter DM or open a ticket in our Discord server.

Sprites mint on the 26th of March at 5pm UTC for community members on the Spritelist. If you read this far and aren’t in our Discord server yet then join us here.

--

--