SafeDrop: Sybil-resistant airdrop from privately-aggregated data
🪂

SafeDrop: Sybil-resistant airdrop from privately-aggregated data

Learnings
Sybil-resistance: How to make sure an airdrop cannot be farmed? Privacy-preserving data aggregation: How to bring onchain, at once, data from multiple accounts without revealing them or creating a link between them? Double-spending protection (nullifiers): How to avoid double-spends in a Sismo Connect app by leveraging vaultIds? Front-running protection (signatures): How to make sure an attacker could not steal the ZK proof of a legitimate and claim the airdrop for themselves?
Type
Onchain
Use Case
Double-spending protectionData AggregationPrivacy

Summary

SafeDrop is a Sybil-resistant and privacy-preserving ERC20 airdrop that distributes AIR tokens to users proportionally to their reputation, aggregated from diverse sources of data (EVM wallets, Telegram, Twitter and GitHub accounts).

📕
Find the source code and the full tutorial guiding you through the development of its smart contract.

image

In this case study, we analyze how Sismo Connect was used to solve several complex problems:

  • Sybil-resistance: How to make sure an airdrop cannot be farmed, e.g. making it hard for one human to receive multiple airdrops?
  • Privacy-preserving data aggregation: How to bring onchain, at once, data from multiple web2 accounts and wallets without revealing them or creating a link between them?
  • Double-spending protection (nullifiers): Since nothing but the eligible amount of tokens is revealed, how to identify a user and make sure they cannot claim their tokens multiple times?
  • Front-running protection (signatures): With Sismo Connect, users bring their data with ZK Proofs in transactions. How to make sure an attacker could not steal the ZK Proof and claim the airdrop for themselves?

How does it works?

Before explaining more about SafeDrop, let’s introduce the notion of Data Groups.

👀
Sismo 101

In Sismo, users own a sovereign Data Vault in which they import Data Sources (e.g. EVM wallets, Telegram, Twitter or Github). With ZK Proofs, users can prove ownership of a specific Data Source. They can also prove their Data Sources are part of Data Groups (e.g. Group of GitHub contributors to a Sismo Repository, Gitcoin Passport owners, etc.).

Data Group Example

{
  // Sismo Community Group made of multiple types of accounts
  // full group: https://sismo-prod-hub-data.s3.eu-west-1.amazonaws.com/group-snapshot-store/0xd630aa769278cacde879c5c0fe5d203c/1687260637.json
   ...
   "0xb08db4cd36b0309c069f515ced754205912a707a": "2", // contributor level 2
   "0xf1fc0b43f8fd0e8b8fce983732d48925148438c1": "2", // contributor level 2
   "twitter:CharlsCharls_": "3",                      // contributor level 3  
   "github:leosayous21": "2",                         // contributor level 2
   "github:mme022": "2",
   "dhadrien.eth": "2",
   "telegram:dhadrien": "3",
   ...
 }

dhadrien.eth can for instance create a ZK Proof of group membership in the Sismo Community Data Group. They can also prove a claim about it (”I am part of the Data Group with value higher than 2) without revealing their wallet.

SafeDrop integrated Sismo Connect to request personal data proofs. They will be verified onchain by the SafeDrop contract to calculate the eligible amount of AIR tokens for a user:

Data Group Membership
Airdrop amount if user part of group with value v
How Group was created
Types of Data Sources in the Group
Links to full groups and generators
REQUIRED: Gitcoin Passport Group - Proof of Sybil-resistance
+ 100 (required v >= 15)
All Gitcoin Passport holders. Value in the group = Gitcoin passport score
wallets (EVM)
REQUIRED: Sismo Community Group - Proof of contributions
+ v * 100 AIR (required v > 0)
Diverse community members of Sismo Learn more
Twitter, GitHub, Telegram accounts and wallets (EVM)
OPTIONAL: Early Sismo Community Member Group - Proof of early support
+ 100 AIR
Early community members of Sismo Learn more
Twitter, GitHub accounts and wallets (EVM)
OPTIONAL: Sismo Factory User Group - Proof of builder
+ 100 AIR
From the group of all users of Sismo Factory
wallets (EVM)

Users after clicking on the “Sign in With Sismo” button from the app are redirected to their Data Vault where they generate as many ZK proofs of personal data (vaultId ownership and group memberships) as they will/can. These ZK proofs will be verified onchain by the SafeDrop smart contract. The contract then calculates the claimable amount from the verified data.

image

Sybil-resistance with Gitcoin Passport Data Group

On Gitcoin Passport, users are able to generate a Sybil-resistant score that we will brought onchain. We created the Data Group of all Gitcoin Passport owners with their associated Sybil-resistant score which can be found here.

Users can now generate a ZK proof proving they own a Gitcoin Passport with a specific value without revealing their wallet.

{ // Gitcoin Passport Data Group
  // full group: https://sismo-prod-hub-data.s3.eu-west-1.amazonaws.com/group-snapshot-store/0x1cde61966decb8600dfd0749bd371f12/1687268688.json
		...	
  "0x85ff01cff157199527528788ec4ea6336615c989": "20",
  "0x21d30f59957828e6ff9f3eddee97e5249f354cb5": "0",
  "0x04a89743aa0193be6e5c5ba19c9020dd79e09adb": "9",
  "0x6900145eed1f9de22ac5a2f4cd1581471ff053cc": "21",
  "0x076709f65b76f1430b18b0fb6fb423e4c5a481de": "21",
  "0xbf5d6a75814365ae9c100f98d435eb9d1c5a8c5b": "19",
  "0xe32483768a4eca1b0786fb5bd29c3fd1a6c65c67": "22",
    ...
}

Example:

  • The owner of “0x85ff01cff157199527528788ec4ea6336615c989” can prove they are part of the Gitcoin Passport Group with a value > 15 (i.e They have a Sybil-resistant score > 15)

It means that a user can bring their Sybil-resistance reputation onchain without revealing who they exactly are.

Privacy-preserving Aggregation

Similarly to the process described for Gitcoin Passport, users will be able to prove one or multiple of the following properties by proving membership of their Data Source in groups:

  • Sismo community member
  • Early community member
  • Sismo Factory user

Data Groups can be created from hybrid groups of web2 and web3 accounts.

{ // Sismo Community Group made of multiple types of accounts
  // full group: https://sismo-prod-hub-data.s3.eu-west-1.amazonaws.com/group-snapshot-store/0xd630aa769278cacde879c5c0fe5d203c/1687260637.json
	...
	"twitter:robsvensek": "3",
  "twitter:PN79161154": "3",
  "github:AdamSchinzel": "2",
  "github:mme022": "2",
	"0xb08db4cd36b0309c069f515ced754205912a707a": "2",
  "0xf1fc0b43f8fd0e8b8fce983732d48925148438c1": "2",
  "telegram:change_000": "3",
  "telegram:developerSec": "3",
  ...
}
📕
Data Group can be created in two ways: - in a few minutes via Sismo Factory (guide) - programmatically by opening a PR on the Sismo Hub (guide)

What is interesting here is that through the ZK proofs proving diverse Data Group memberships, users are effectively able to aggregate their data from multiple wallets and web2 accounts without revealing them. User can finally leverage their private wallets alongside their public social accounts without fearing being doxxed.

Nullifying users with vaultId

Users prove their group membership anonymously. It means there is no wallet or identifier that can be used by the contract to store the fact that a user already claimed the airdrop.

Sismo Connect provides applications with a vaultId that enables smart contracts to identify users anonymously. The SafeDrop contract uses this identifier to track who has already claimed the airdrop.

ℹ️
A Vault Identifier is calculated using the following formula:

vaultId = hash(vaultSecret, hash(appId, derivationKey)), where

vaultSecret is a secret only known by the Data Vault’s owner (similar to a seed/ private key of a user);

appId is a unique identifier for an associated Sismo Connect app;

derivationKey is a an optional parameter that can be used to generate multiple user identifiers for a single Data Vault owner. derivationKey = 0 by default.

The vaultId is computed by the user when they generate a ZK proof of group membership, thus enabling them to associate a ZK Proof generator by its vaultId. Learn more about Vault Identifier in the Docs →

Since the vaultId is deterministically generated from the vaultSecret and one Data Source can only be added to one Vault, the application is sure that Data Sources cannot be reused to claim the airdrop multiple times.

Front-running protection with Signatures

Along side proofs of ownership/group membership of Data Sources, applications can request signatures from their users. In SafeDrop, we do not use the msg.sender account to check eligibility but instead verify its ZK Proof. Blockchains transactions being public before they are validated, anyone could steal the ZK Proof and mimic the transaction choosing the recipient of their choice.

To protect against these front-running attacks, SafeDrop request a signature of the intended recipient the airdrop, embedded in the ZK Proofs. Tokens will be minted to this recipient, and not to msg.sender

Key Takeaways

  • Using Sismo Connect, users can bring their reputation onchain from diverse Data Sources at once.
  • Data Sources can be diverse: Telegram, GitHub, Twitter, and wallets (EVM).
  • Sismo Connect uses ZK proofs so users do not need to reveal their Data Sources; they only reveal granular data (from group memberships).
  • No link is ever created between Data Sources when selectively revealing personal data.
  • Sismo Connect provides a Vault Identifier for all apps so they can keep track of users anonymously and avoid double-spending.
  • Sismo Connect enables applications to request signatures from users. The signed message will be embedded in the ZK Proof.

Resources