SkillAgentSearch skills...

Stealthdrop

Anonymous Airdrops using ZK-SNARKs

Install / Use

/learn @stealthdrop/Stealthdrop
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

StealthDrop

Anonymous Airdrops using ZK proofs

stealthdrop.xyz is an airdrop utility by 0xPARC (Aayush, Adhyyan, Nalin) that enables ERC20 token airdrops that can be claimed by completely anonymous accounts.

EDIT: @0xB07DAD discovered a vulnerability in this scheme described in more detail here. To fix this problem without sacrificing privacy or decentralization. we embarked on a years long project. We published a paper for a new cryptographic signature PLUME on existing ECDSA keys, that was not malleable. We open sourced end to end code, made that into ERC 7524, and made PRs for it into Metamask and Taho Wallet. They are looking for more activity on our ethmagicians post and ERC -- if you would like to help accelerate ZK adoption, leave some likes/upvotes/questions on those links (1, 2)! We are excited to redo this repo with that signature scheme -- reach out to us if you'd like to help! There are bigger grants available (help redo stealthdrop with PLUME, help implement in halo2) and smaller grants (help fix any of the issues on the repo).

Demo

https://user-images.githubusercontent.com/6984346/153767431-b2e88fda-1403-4840-8e00-75b5c6df5ddf.mov

User flow:

  • Connect the "public" wallet that is eligible for the airdrop.
  • Sign a message proving your ownership of the "public" wallet.
  • Switch to another (anonymous) account and claim your airdrop without linking your original account in any way.

You can play around with the demo yourself on stealthdrop.xyz on the xDai chain! If you've played DarkForest with an address that's linked to any Twitter account (or contributed to the community at ETHUni/HackLodge), you can claim the token yourself! What you do with these tokens is up to you, but understand that we only intend for this token to be a proof of concept for what's possible. None of our code is audited or recommended for production use without serious considerations. At the very least, the circuits require a trusted setup ceremony, proper auditing (if not formal verification) and significant optimisations before production use.

In this post, we'll dive into the motivation behind making StealthDrop and explain the inner workings of the application.

Why?

To motivate this construction, let's look at how airdrops currently work: Usually, protocols will set up airdrops that distribute a limited supply of ERC20 tokens to their team, early contributors, users and others involved in the success of the protocol. While often, the underlying goal of such airdrops is to create a medium for governance for future decisions (DeGov for DeFi), the limited supply creates interesting game-theoretic conditions: FOMO and the promise of power establishes a "market value" for the cost of governance, and many end up trading their tokens at high valuations. The science behind coin voting mechanisms have been a hot topic of study right at the intersection of microeconomics and behavioural economics, and even has a name these days: tokenomics.

Focusing on the DeGov enabled by these tokens, one fatal flaw in current token systems is the muddling between identity and governance. If everyone knows vitalik.eth voted "No" for a protocol proposal, how does that influence the opinion of the rest of the community? Does everyone still consider the impact of the proposal fairly and independently?

<p> <img width="400" alt="image" src="https://user-images.githubusercontent.com/6984346/149878638-18c79ac2-a8fd-4122-9f00-a069ab76f108.png">

<em>Snapshot Labs shares everyone's votes publicly</em>

</p>

On the other end of the spectrum, when someone with a public identity deviates from the norm and casts a vote others in the community don't like, they end up exposing themselves to harassment on Twitter and other social media.

<p> <img width="431" alt="image" src="https://user-images.githubusercontent.com/6984346/149878894-678988f2-f453-41de-b07d-a75ab6dc88b2.png">

<em>Everyone knows your vote</em>

</p> <p> <img width="593" alt="image" src="https://user-images.githubusercontent.com/6984346/152887131-3a2d2b3b-3903-42d5-8ea7-97d760e39867.png">

<em>Everyone knows if you sell your token</em>

</p>

Even if votes are hidden under MACI, knowing whether Vitalik voted on the proposal could change how much thought people put into their own vote. While it's arguable if such accountability is actually a positive attribute of these token systems, we think it's important to explore the alternative. In fact, real-world elections don't enforce such peer pressure (beyond the occasional dinner party debates), likely for a good reason.

With this vision, we present StealthDrop: an airdrop that lets addresses claim their airdrops completely anonymously. We enable truly anonymous governance by effectively letting completely virgin wallets claim an airdrop on behalf of other wallets. Nobody even knows if the original wallet has claimed their airdrop or not.

How?

The mechanism for making this possible is quite complex and has lots of subtle details, so let's start with an overview:

Untitled-2022-01-13-2340-2

Now, let's peel layers off this diagram step by step:

Merkle tree

Much like regular airdrops, StealthDrop starts with an airdropper creating a Merkle tree of addresses eligible for the airdrop. The Merkle tree acts as a vector commitment scheme, allowing the airdropper to commit a long list of addresses by just publishing the Merkle tree's root hash on-chain. Any claimer can then prove the existence of their address in the tree by opening a Merkle path proof in just O(log n) elements (where n is the length of the list).

Zero-knowledge proof

This is where things get more interesting. Here's an exact spec of what the zk-SNARK proves:

  1. Given an ECDSA signature, does it originate from a particular public key?
  2. Does the public key corresponding to the signature belong to the Merkle tree?
  3. Is the hash of the signature a non-malleable one-way function's output from the input signature? (This is the hash used to prevent double-claiming, more on this to follow)

Untitled-2022-01-13-2340-3

Peeling another layer, next we'll talk about how each part works and the design choices involved at each step.

ECDSA Signature Verification

While this is certainly the most complex part of the circuits, we actually had no role in creating it! Just recently, a team from 0xPARC's learning group worked on making ECDSA inside a ZK-SNARK possible. These circuits are extremely beautiful! There are lots of clever tricks going on to minimise the total number of constraints, many of which they've written about in their blog post here. Even so, this circuit is a behemoth: it takes 400k constraints just to derive a public key from a private key and 9.6 million(!) constraints to verify a signature.

For our application, we originally considered using the private -> public key derivation instead (as that would save our application ~9 million constraints) but we decided to use the signature verification circuit since current API specs make it nearly impossible to obtain a private key from a wallet interface like MetaMask or WalletConnect (for good reason, of course). Perhaps, one day, wallets will allow for running ZK-SNARKs inside the wallet itself.<sup>coming soon from a 0xPARC ZKID Working Group team<a href="https://twitter.com/MetaMask/status/1483488847866458115?s=20&t=5k5itqBx4uQUhHyC1iqMaQ">👀</a></sup>

Merkle Tree Path Proofs

This component of the circuits is rather straightforward. Checking a Merkle path proof is just a matter of traversing the path and hashing a node's children at each step. However, one design choice worth considering in this construction is the values at the leaves of the tree: the list of addresses eligible for the airdrop. Whether it is practically possible to make this list private as well is an open question. It seems like a very non-trivial problem since any counterparty trying to deanonymise the list essentially has infinite time (since the Merkle Tree and its leaves need to be publicly stored to generate path proofs) and the search space of addresses is finite. The simple centralised solution to this might be to store the tree itself in a central server and only reveal path proofs by making addresses provide a valid signature, but that's not the most satisfying. Claim codes are another similar approach that trade-off centralisation for the privacy of the list.

Nullifier Hash Construction

Next, we need a method to make sure no

View on GitHub
GitHub Stars363
CategoryDevelopment
Updated1mo ago
Forks39

Languages

Circom

Security Score

100/100

Audited on Feb 16, 2026

No findings