Stop forking Loot, it’s kind of broken

--

tldr: Don’t use Loot’s code for new projects without fixing the way randomness is used in the smart contract.

Update (Sep 6th): I’ve open-sourced Floot, a blind-drop implementation of Loot designed to address the concerns raised in this article.

4.1 standard deviations from the mean — coincidence? (source: More Loot #435990)

The Loot smart contract has a design limitation (or, depending on your point of view, a security vulnerability) which affects the fairness of the initial token distribution. Depending on the context, this can seriously impact participants who buy tokens from projects that use Loot’s code.

The goal of this post is not to disparage Loot or anyone involved, but to:

  1. encourage a level playing field in NFTs by reducing information asymmetry; and
  2. stop the proliferation of bugs or design patterns that put NFT users at risk.

The problem

Quick recap: Loot is an NFT series of 8000 tokens called Bags, of which 97% were mintable by the public, for no fee other than gas. The smart contract contains randomization and rendering logic allowing it to generate the SVG corresponding to any token ID. Each Bag has eight items, each of which receives a random “greatness” score on the smart contract. A higher score adds variability to the item’s name, tending to make it more rare.

Bags ranking high in rarity sell for multiples over the floor price — in this particular case, around 7x.

So, what’s wrong?… The content of a Bag is deterministic according to its token ID. This means that by reading the smart contract, anyone can easily pre-compute the entire supply of Bags, rarity metrics included, at any point before or during the initial token distribution. Since the claim() function takes the token ID as a parameter, it is easy to pick out the rarest items from the collection, and mint them immediately before anybody else has a chance.

This makes Loot and similar projects easily gameable if the contract code is public during the initial distribution. In fact, Loot and most of its copycats have made a point of using Etherscan as their minting UI, which requires that the source code is verified on Etherscan.

I have confirmed that the initial distributions of the following projects were open to the minting manipulation described above: Loot, Bloot, More Loot, n, CHAR 0… This is a non-exhaustive list and at the time of writing I haven’t found any exceptions.

What is most concerning is that this gameability results in clear disparities between the outcomes of average users and those with insider or technical knowledge.

The exploit in action, pt. 1: More Loot

A stark illustration of the impact of this exploit can be found in the on-chain data for More Loot, a Loot follow-up announced several hours ago, as of the writing of this article, by Loot’s creator, dhof:

Note: The two curves have been normalized to have approximately the same area.

The above graph shows the difference in distributions between the More Loot Bags available to be minted, and those that were actually minted. It includes the “greatness” scores of the over 1.3 million Bags currently available in the series. If minting was random, we would expect these distributions to line up.

Instead, what we can clearly see is that while the vast majority of purchases are made “blindly,” a smaller number of transactions are exploiting the contract to mint only the rarest Bags. This type of targeted minting increased in frequency after a rarity ranking was published on GitHub. However, even hours after this data had been shared in the public Loot Discord, targeted minting continued to make up a small fraction of minting activity, suggesting that most users were in the dark.

Some may brush More Loot aside as an experiment that should not be taken too seriously, but the actual impact should be considered. On the order of $3M in gas fees were paid by users to mint More Loot during these 5.5 hours. The vast majority of these mints were made blindly. With a supply cap of well over 1 million tokens, and thousands of “exceptional” tokens flooding the market, the outlook for resale for the average holder is very bleak.

The exploit in action, pt. 2: CHAR 0

Another recent Loot-based project is CHAR 0, which consumed an estimated $700k in gas fees in a distribution of 9700 tokens from 13:47 UTC Sep 3 to 11:56 UTC Sep 4.

As an early minter in the project, it was easy for me to produce the necessary data to identify and obtain many of the rarest tokens from the series. I minted only a small collection, for demonstration purposes, but nothing would have impeded me from quickly and covertly acquiring the vast majority of the top 1% of the supply.

It is clear that a motivated attacker in my position could have extracted significant value from the CHAR 0 user base, and wielded considerable power over the outcome of the project.

Potential solutions

I’ll limit this section to a high-level discussion, with room for follow-up. Here are a few different approaches to fixing the problem identified above.

Blind drop

Hashmasks popularized the blind drop model in which the creators commit to a hash for the whole series, and the series order is shuffled via on-chain randomness at the conclusion of the sale. This results in a fair, random distribution that is resistant to cheating even by the creators. The Hashmasks smart contract was successfully adopted by BAYC and a zoo of other projects. The most thorough documentation I have found describing this process is in the docstring of ERC721FairDistribution.sol by Chunky Cow Club Tour.

A blind drop strategy can be adapted to work with Loot, while retaining the property that all Loot SVGs are generated by the smart contract.

On-chain RNG

On-chain randomness can be used to make each mint outcome random at runtime. Extra care must be taken with this approach, since sources of on-chain randomness may be exploitable in unexpected ways. The best approach would be to make use of a VRF such as Chainlink’s, but this may be too expensive for some applications.

Unverified contract

A simple fix is to keep the smart contract code private during the initial distribution. This approach is somewhat reasonable in the case where 1) the creator has reputation at stake, and 2) the contract does not receive payments.

While this is arguably an improvement, I would strongly recommend against this approach for the following reasons:

  • Unlike a blind drop, there is no protection against cheating by the NFT creators.
  • Contracts may be vulnerable to reverse-engineering, either through analysis of minting outputs or via bytecode decompilation.
  • Even if the contract creator is trusted and the contract does not take payments, asking users to interact with an unverified contract sets a bad precedent.

Sybil-resistant drop

Finally, it’s worth calling out this recommendation of using data from Mirror to attempt a Sybil-resistant fair distribution. This is a forward-looking approach which I believe will become more and more interesting in the future.

Finally…

There are tradeoffs with each of these approaches and some were likely considered by the original Loot team. The fact remains that the more the current version of the Loot smart contract is proliferated, the worse the situation is for users. Until the problem is fixed, this smart contract should not be reused — at least not without explicit communication that mints are gameable and that the distribution is not intended to be fair or random.

Closing rant

For all the talk of community and fair distribution, NFT users deserve better. They deserve a level playing field. They deserve token distributions that are carefully designed and that aren’t going to screw them.

There’s no arguing that Loot has sparked a revolution and is a critical project in the continued progress of NFTs. What I want to emphasize is that even when experimenting, NFT developers owe a responsibility to their users. This includes first-time developers who copy-paste code from another project. Stop bragging that the guy who deployed your Loot clone learned smart contracts in a day by watching YouTube.

Let’s make the NFT space safer for users. New and high-value smart contracts should be audited or at least code-reviewed by experienced smart contract developers. Known issues should be discussed openly. Let’s improve upon best practices and share them broadly to ensure artists have the tools available to create secure and meaningful NFTs.

--

--