@onnnnnnnion on Twitter
1/ Last Night, the @Visu...
1/ Last night, the @visualizevalue team released the much anticipated Infinity collection. It has a unique mechanic I haven't seen before: infinite editions with infinite supply, that can be refunded for the original mint price at any time. Let's take a look at the contract 👇


2/ Note before diving in: in this thread we're only going to look at the Infinity token contract, which handles minting, payment, and burning of Infinity tokens. The generative art and metadata are handled by separate contracts, referenced by the token contract. (View Tweet)
2/ We begin by initializing the name and symbol of the contract, along with the price of .008 ETH. We also set the address of the VV creator wallet.

3/ The constructor passes in an array of addresses. We call an internal function _checkDeposit with the length of the array, and then mint 1 of token 0 to each of the genesis recipients.

4/ The receive() function indicates that you can also mint Infinity tokens just by sending ETH to the contract. It does this by calling _generateViaDeposit() which we'll look at later.

5/ generate() allows users to mint a new unique Infinity edition, setting a random tokenID via _randomId() and then calling the internal _generateViaDeposit(). Users can also add a message with their mint - h/t the @ourZORA team for inventing a new behavior!

6/ generateExisting() allows users to mint a copy of an existing Infinity Check edition. It works similarly to the previous function, except users must specify a source (an address that owns that edition) and the tokenID. It calls a _validateId check before proceeding with mint.

7/ regenerate() allows users to swap an existing Infinity check for a new mint, by burning the existing Infinity they've specified and minting a new random Infinity. degenerate() burns an existing amount of an Infinity and pays back the equivalent amount of ETH.

8/ The following functions - generateMany(), generateManyExisting(), regenerateMany(), degenerateMany() - all do the same actions as the previous ones, but allow users to execute those actions in batch by specifying arrays of values instead of individual values.

9/ svg() and uri() call their respective functions on the InfiniteArt and InfiniteMetadata contracts. totalSupply() returns the max uint value, because the max supply is functionally infinite for both any individual edition and the amount of total unique editions.

10/ _generateViaDeposit() is the internal function that was called previously. It calculates the amount able to be minted based on the ETH sent, and mints that many of the token (either a random new one or existing one) to the user. Any remaining ETH is sent back to the minter.

11/ _validateId() checks the source address specified owns at least 1 of the id. Otherwise it reverts, unless it's the VV team minting the token. Practically this means, if I'm interpreting this correctly, that the VV team can mint new tokens that target specific tokenIDs.

12/ _randomId() generates a random uint for a tokenID based on the block prevrandao, msg.sender, and gas left in the txn. _checkDeposit checks that the ETH sent in the txn is a multiple of .008. _totalAmount() sums up all the amounts sent in a batch mint txn.

13/ Lastly, _send() transfers ETH back to the user, and _message() emits a Message event so clients can listen to and display any messages sent by minters.

14/ And that's the Infinity contract! Note: it doesn't look like messages are supported yet in the https://t.co/kguTW8aTM8 client. Will be cool when that comes - I love the idea of mints with comments as a primitive for new social experiences. (View Tweet)
15/ That's the Infinity contract! You can view the full code here: https://t.co/wcJwTBSLMH Once again a big kudos to @jackbutcher @jalil_eth @traf on executing a brilliant project. (View Tweet)
16/ If you liked this thread, feel free to share it and give me a follow @onnnnnnnion. I write daily about crypto, software, and media. You might also like my breakdown of the Checks contract here: https://t.co/fA8UOCJJMc (View Tweet)
