💡 Element Finance is an open-source protocol for fixed and variable yield markets. Peaking at over $200M Total Value Locked, they were one of the largest protocols in DeFi.
In April 2022, Element airdropped governance tokens to their community via Zero Knowledge Proof. The mechanism verified if users had been active on Discord and let them claim their airdrop without revealing any personal information. Making this work posed an interesting problem.
I am not a member of Element Finance, but I worked with their team and a16z to design the airdrop mechanism. This was a super fun challenge and I’m very proud of the result.
🧠 The Challenge
Element wanted to allow three types of users to claim voting power for their new DAO:
Early users of Element Finance: Individuals that used the Element protocol to LP, Trade, or Mint
Community contributors: Users who have engaged in meaningful conversations on Element’s Discord server
Ecosystem contributors: Builders who have contributed to the public goods infrastructure that keeps the Ethereum blockchain running
The challenge was to allow “community users” to claim their tokens, without sharing any of their personal information.
🎯 The Brief
Design a mechanism for users to create an ID (“commitment”) associated with their Discord ID. Use this later to claim the airdrop.
1. Commitment Generation
Create two random 31 byte strings: “the key” and “the secret”.
This requires some user input to make it truly random.
The two strings are passed through a 32 byte hash algorithm to create the “commitment”. Example:
Key: 0x005f19a53a070505a0d72fec37b47cc4b8950092e5981275ac47980fb8fb4937
Secret: 0x00c7ab67dd880edbf18004ba0c40769bb0fe2f68c09fd1aac35f2c1493a3c6e3
Resulting hash (“commitment”): 0x154ba9f290756408dcc0a97c4e802e3db4dd18db008e7919c392e7a638b4c130
Explain to the user that they should post the commitment to a special Discord channel and keep their key + secret private. A bot on Discord will associate the commitment with their ID, and allow users to claim the airdrop later on.
2. Airdrop Retrieval
Enter key + secret from commitment generation
Click “check for airdrop”
If success, let the user proceed with next steps
If failure, display some message like “no airdrop available, sorry”
Click “generate proof”
This will take 10–60 seconds, as the proof is abstracted away to a library
Once the proof is complete, allow the user to press “claim airdrop” which generates a transaction and allows it to be signed by the wallet of their choice
✍️ Storytime
There were two user stories to the airdrop. Before doing anything, I wanted to make sure these were completely clear.
By creating simple user flows and marking what was a page, what was an input, and what was a backend process, I could make sure we wouldn’t miss anything.
User Story 1: Creating the “commitment”
As a member of Element’s Discord, I need to generate a commitment, in order to send it to Discord.
User Story 2: Claiming the airdrop
As a member of Element’s Discord, I need to check my key and secret against a commitment, in order to claim an airdrop.
The Outcome
After creating the user flows I was fairly confident on the mechanism and what screens I had to design.
I just wanted to think of a fun way to create a random number, and then think how to make the process as clear as possible.
While researching random number generators, I discovered one based on mouse movement: http://www.russellcottrell.com/mousePointerRNG.htm
I wondered if this could be combined with a slider, so that micro movements of the mouse would create random numbers while the user dragged the slider to the end - this would then signal the end of the process and a random hash would be created.
I quickly prototyped my idea and presented to the team:
For the design nerds:
I’m not a merkle tree expert, so a blockchain dev would have to explain that bit, but I can explain how the Figma prototype worked…
I created this with Figma’s interactive components, rather than new screens for every state. I made several nested components, each with a start and end variation. Then I added just the one combined component to the final screen.
The “Numbers” and “Slider” components are combined into the Key/Secret module. Drag the slider, that controls the numbers, and once it ends, the Next Step button becomes active.
If you’re a designer and you’re wondering how the number generation effect was created, take a look at the demo below:
Each number in the field is a vertical strip of numbers and letters: 1,2,3,4 etc. These vertical strips are laid out next to each other in a box that is the height of one number. When you turn on “clip content” in Figma, it cuts off everything outside the box.
Then I created two states: a start position and a finished position. The start position has all the numbers in grey, neatly stacked below the box. The finished position has the strips moved up to various positions, so that a “random” string of digits is shown in the box, and the text is changed to white.
This is then connected to the slider state, so that when you drag the slider from one end to the other, it moves the numbers up and makes the field look like a tumbler.
🖼 High-Fidelity Version
The team liked the idea, so I made a high fidelity version of the full process.
Generate ID
I added a stepper to make the process as clear as possible, and a couple more animations, because they’re fun.
Claim Airdrop
The very talented Tina from Element then created the final version. Sidenote: Tina has been vocal about the need for fun and personality in web3, which I also agree with. That’s one of the things that prompted me to go down an unusual route with the random number generator and experiment with something different.
Some more screenshots and information on the airdrop can be found on their docs page here.
You can see the concept was improved further and brought into line with their style guide.
The Element Airdrop and DAO Launch was also discussed on the Bankless podcast!
🤔 Final Thoughts
There aren’t that many people writing about web3 and design, but I think it’s really interesting to see the process.
I enjoyed this piece of work, so I wanted to share it with a wider audience.
It’s also a perfect example of the decentralised nature of web3. I’m in the UK, Element’s core team is in the States, and most of the ABAG team are in Europe. We had a handful of calls with representatives from Element, ABAG and a16z, and with relatively little co-ordination, quickly thrashed out a new UI.
A bunch of different people came together and built something super cool. I’m glad I got a chance to be a part of that and make it happen.