The Samples Airdrop — It’s all very technical

Eoghan
Thingdoms
Published in
4 min readMar 13, 2022
Tiger Stripes

It’s been almost exactly 3 months since we released the Things of Thingdoms. We’ve now airdropped Samples from the Thing Lab to all owners of a Thing.

We wanted to provide a fair distribution so went with an approach which would ensure randomness.

This article goes through the methodology we used to try and ensure this.

Snapshot

We started by taking a snapshot on 6th March at 11pm GMT. This gave us a wallet address for all 10,000 Things at that time. Given that the tokens have sequential ids from 1–10,000, this gave us an ordered list of wallet addresses with duplicates for any address that owned more than 1 Thing.

10,000 Samples

We wanted 5 types in different proportions in a list of 10,000 samples. We went with:

  • 4430 of Sample T
  • 3500 of Sample H
  • 1800 of Sample I
  • 250 of Sample N
  • 20 of Sample G

We stored these in those proportions in that order in a big list using the ids:

  • 0 for T
  • 1 for H
  • 3 for I
  • 2 for N
  • 4 for G

There is no mistake in the order of the ids.

Shuffle

We then shuffled this list using pseudo-randomness. What this means is that although the results appear random, they are in fact repeatable and deterministic. This means that if you use the same seed number as we did, you would get the same order of sample type ids

We chose a seed number of 69420.

Verifiably Random starting point

Seems fair

The last step was to use our deployer contract to request a verifiably random starting point in the list of sample types. The video below explains how we used Chainlink for this task.

The proof of our use of this approach can be seen on the blockchain. We request the random starting point in a single transaction. This requires Chainlink to then do its bit and come back to us once its got the response. In our case this took 1 hour 15 minutes to return a starting index of 4659! It is now stored on the deployer contract under the “startIndex” public property for anyone to see and verify.

Final list

We then took this starting point and used this to determine which element in the sample type list would be at the start of the list. The rest of the list was in the same order, looping back round to the start when it reached the old end point to finish at a new endpoint 1 place before the new starting point.

This new list could now be used to match up with the ordered list of wallet addresses gathered from the snapshot. The first sample type in the list is assigned to the first address, the second sample type to the second address, and so on.

Reducing transactions

Because we’re using an ERC-1155 contract for Thing Lab we can stack tokens that are of the same type. This means that we have the opportunity to reduce the number of transactions below 10,000 if any wallets in the list have more than one of a specific Sample type.

We aggregated the types for each address so that we could reduce the size of the list to 6278 transactions.

Deployer

Our deployer contract was set up so that it could receive 3 equally sized input lists of addresses, sample type ids, and quantities. These would be used to wrap up many transfers into a single transaction on the deployer contract. Unfortunately we couldn’t wrap them all up in a single transaction because the Ethereum network has a maximum amount of gas that can be used in a single transaction and this would exceed that.

Therefore we created 32 chunks of up to 200 transfer transactions which would be fed in, requiring only 32 calls to the deployer contract.

Learnings

There have been some lessons learnt in the process of doing this airdrop. The most important take-aways are:

  • Select appropriate gas limits for transactions — too low and the transaction will fail with a gas cost; too high and miners will deprioritise the transactions, leaving them pending for long periods of time.
  • Check all wallet addresses are capable of receiving ERC1155 tokens beforehand. All externally-owned accounts can receive them but contracts can only receive them if they implement the ERC1155-receiver interface.

Some Data

--

--