The Trouble with the NFT Worlds Mint
Published: 2022-03-01 04:29:47

NFT Worlds is a self-described "Minecraft compatible metaverse" ERC721 NFT that exists on the Ethereum blockchain. 

Since I just threw out a lot of jargon I will explain the terms here. Feel free to skip if you already know this.

**Blockchain** - Distributed ledger for recording transactions. 
**ETH (Ethereum)** - A blockchain that natively supports smart contracts which be used to create virtual fungible and non-fungible tokens that can be bought, sold and traded.
**Polygon** - A blockchain on a blockchain. Also known as a "Layer 2". Popular because they are typically cheaper to work on that the root chain, which in the case of Polygon is Ethereum.
**ERC721** - An ETH smart contract standard for creating NFTs (non-fungible tokens). Non-fungible means that the tokens are unique and cannot be sub-divided. You can only own either own 0 or 1 of any singular NFT.

Some additional definitions for words that will appear later in the article:

**Transaction** - Making a change to the blockchain by transferring tokens or calling a method on a smart contract
Gas - The payment made in order to commit a transaction to the blockchain. Paid by the user who makes the transaction on the blockchain.
**Presale list** - Sometimes referred to as a "whitelist". A list of individuals who can mint (create) an token before the public.
**Mint** - The act of creating a new token by calling a method on a smart contract
**Address** - An address in an ETH wallet that can be used to send or receive tokens.
**Deployer address** - The ETH address used to deploy a smart contract. Is considered by default the "owner" of a contract
**Signed payload** - A block of data signed by a specific address. Can be used to check that the owner of a specific address verified a block of data.

## Early History

NFT Worlds was created in October of 2021. A discord was created and users were invited to join the presale. 

Presale spots were provisioned by visiting the pre-sale website. The pre-sale website had a backend component that contained the private key of the deployer address. The private key was used to create signed payloads that were used when calling "joinWhitelist" on the [NFT Worlds contract](https://etherscan.io/address/0xbd4455da5929d5639ee098abfaa3241e9ae111af#code).

![Join whitelist method](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ggt78f6ddbwn7yalmik8.png)

Calling this method with the signed payload cost gas by each of the users submitting an address in order to commit the transaction to the blockchain. The presale continued until the day of the mint. In total, 2751 unique addresses were added to the presale.

### How to Mint

Minting an NFT Worlds token required a few things.

1. Minting needs to be enabled (the contract owner can turn minting on or off)
1. There needs to be tokens left to mint
1. A payload signed by the contract owner needs to be submitted

The signed payload contained all of the information about the token that was to be minted and was signed by the private key of the contract owner, which was the contract deployer address. The reason the payload is signed is to make sure the NFT World tokens were created with the expected data. The expected data includes:

- The token number
- The Minecraft seed for the token
- The aggregate properties of the minecraft world origin of the Minecraft seed
- Additional random properties unrelated to Minecraft

The mint was free except for the cost of gas and optionally the cost of gas for reserving the presale spot.

### Day of the Mint

The day of the mint arrives. Presale holders are told they have 48 hours to mint and that there spots were reserved. This mint proceeded normally until the mint was halted. The reason given was because of an "exploit". Holders were assured that everything would be fine and that minting would resume. Sure enough minting was disabled and re-enabled a couple of times over a 2 hour period.

![It's hackers! lol](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ixcjgq5qf3nz0r50znii.jpg)
 
Presale holders were told not to worry. Their spot was reserved and not to worry. 

![Don't worry 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lrhuidru2dmoxuq0x585.png) 

![Don't worry 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqw0x67vlmy2m7o43om5.png) 

Minting was turned off mid mint here: https://etherscan.io/tx/0xcd79892d276ecb76e22fc33776a53f927b84c34492798e28a52c693480901306 (Oct-06-2021 08:13:30 AM +UTC) and then re-enabled 3 minutes later here https://etherscan.io/tx/0x0558f03a3f15d0a6239480b13e4e800c2025894a408f0c588be944487beae1bf at (Oct-06-2021 08:16:19 AM +UTC)

Then turned back OFF again after 30 seconds https://etherscan.io/tx/0x31e72df70aed0eba62d31ef7a1e49de8608151e7fa3344b793aad2a9b729237a at (Oct-06-2021 08:16:52 AM +UTC)

And then finally turned back on almost 2 hours later https://etherscan.io/tx/0xac5921c223faa8e3ffd5b40ce80a14d11cf10376364b7a1125232840235f7e38 at (Oct-06-2021 10:05:18 AM +UTC)

However... the next morning all tokens were sold out. 802 presale holders were left with no tokens to purchase.

Those that missed out were understandable upset. The NFT Worlds team continued to blame the issue on a "sniping bug", but the problem was actually their own contract and website.

What happened?

### The First NFT Worlds Bug

When whitelist spots were being created, a variable `whitelistAddressCount` is incremented by 2. This is because all whitelist addresses were allowed to mint two tokens.

When minting, the smart contract has several branches depending on if the address minting is an owner (of the contract), on the presale (whitelist) or everybody else. If an owner or a presale mints, then counters are incremented to keep track of how many of each have been minted.

![Track owner and presale mints](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h3da5uwif6d23q4siveb.png)

Great! But what happens if the user is not on the presale and is not an owners? Well there are some additional checks to make sure that they can mint. The bug is in this block of code, which must evaluate to true in order for the mint to proceed:

![Bad logic](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3yr51179gguk808djf2x.png)

See the problem? Don't worry... it took me awhile to notice as well. What this check is trying to do is add up the total minted, plus the remaining owner mints, plus the remaining presale mints, and make sure that is less than the total mint. However, because presale holders can mint 2 tokens, a bug occurs after 1/2 of the presale mints. If everyone on the presale mints, then `whitelistMintCount` would be twice as big as `whitelistAddressCount `

```
((whitelistAddressCount - whitelistMintCount) * 2)
```

should be

```
((whitelistAddressCount) * 2 - whitelistMintCount)
```

_Was there anything that NFT Worlds developers could do?_

Well yes. As mentioned earlier, every call to mint an NFT Worlds token required a signed payload. The NFT Worlds team could have invalidated all existing payloads by changing the contract owner. New payloads could have been generated for the presale holders. Once they finished minting, then the team could start generating signed payloads for the public.

Instead, what happened is that the NFT Worlds team, wanting to move forward, began kicking and banning individuals that complained about the fiasco. As far as I know, the team never owned up to the fact that the problem was entirely on the team, the smart contract and backend component generating signed payloads. Rather the problem was blamed on sniping and/or exploits.

## Conclusion

NFT Worlds has more recently went through a boom phase of growth and hype. Token prices ballooned to tens of thousands of dollars. A new currency $WRLD was created and airdropped to NFT World token holders. NFT Worlds started paying out $WRLD tokens to players on Minecraft worlds.

All during this, Microsoft has made no official statement on what is and is not allowed.

I will however note the following part of their "Commerical use" EULA 

![Microsoft Minecraft EULA](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/16rotaw03jd300t5jckb.png)

Code used to generate some of the analysis in this post: https://github.com/0xFlicker/nft-worlds-transaction-analysis
 
Header image credit Sunndayz/Shutterstock.com