Skip to content

This contract is used to distribute tokens to a whitelist of addresses based on a Merkle root. Includes mitigation for second-preimage attacks.

Notifications You must be signed in to change notification settings

AlexScherbatyuk/foundry-merkle-airdrop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Foundry Merkle Airdrop

A sophisticated airdrop system built with Foundry that combines Merkle tree verification with EIP-712 signatures and account abstraction principles to enable gasless token distribution.

πŸš€ Project Overview

This protocol utilizes Merkle proofs to identify eligible addresses for an airdrop based on a whitelist, while implementing account abstraction concepts to allow users to claim tokens without paying gas fees. The system is designed with security and efficiency in mind, preventing double-spending and ensuring only authorized addresses can claim their allocated tokens.

πŸ” Core Components

MerkleAirdrop Contract

The main contract that handles the distribution of tokens using:

  • Merkle Tree Verification: Efficiently validates eligibility without storing the entire whitelist on-chain
  • EIP-712 Signatures: Secure, typed message signing for claim authorization
  • Double Hashing: Prevents second-preimage attacks on the Merkle tree
  • Claim Tracking: Prevents double-spending through mapping-based verification

Bagel Token (BAGEL)

A simple ERC20 token used to reward users for their contributions to the Bagel ecosystem. These tokens are distributed via the Merkle airdrop to whitelisted addresses.

🌳 Merkle Tree Implementation

What is a Merkle Tree?

A Merkle tree (also known as a hash tree) is a data structure that allows efficient and secure verification of large datasets. In this airdrop system:

  1. Leaf Nodes: Each leaf represents a hash of (address, amount) pair
  2. Internal Nodes: Each internal node is the hash of its two children
  3. Root: The single hash at the top represents the entire dataset

Benefits of Merkle Trees

  • Gas Efficiency: Only the proof path needs to be stored on-chain, not the entire whitelist
  • Scalability: Can handle millions of addresses with minimal on-chain storage
  • Verification: O(log n) complexity for proof verification
  • Security: Tampering with any leaf would change the root hash

Merkle Proof Generation

The system includes scripts to generate Merkle proofs:

# Generate input data
forge script script/GenerateInput.s.sol

# Create Merkle tree and proofs
forge script script/MakeMerkle.s.sol

πŸ” Proof Verification

How Proofs Work

  1. Leaf Creation: keccak256(keccak256(abi.encode(account, amount)))
  2. Proof Path: Array of sibling hashes from leaf to root
  3. Verification: MerkleProof.verify(proof, root, leaf)

Security Features

  • Double Hashing: Prevents second-preimage attacks
  • Collision Resistance: Uses SHA-256 for cryptographic security
  • Proof Validation: Each claim requires a valid Merkle proof

πŸ’³ Account Abstraction & Gasless Transactions

EIP-712 Signature System

The contract implements EIP-712 for secure, typed message signing:

struct AirdropClaim {
    address account;
    uint256 amount;
}

Gasless Claim Process

  1. User Signs: Creates EIP-712 signature of their claim data
  2. Gas Payer Submits: Any address can submit the transaction and pay gas
  3. Contract Verifies: Validates both signature and Merkle proof
  4. Tokens Transferred: Directly to the claiming address

Benefits of Account Abstraction

  • No Gas Fees: Users don't need ETH to claim tokens
  • Better UX: Seamless claiming experience
  • Flexibility: Anyone can pay gas for others
  • Security: Maintains user control through signatures

πŸ› οΈ Technical Implementation

Contract Architecture

  • EIP-712 Compliant: Uses OpenZeppelin's EIP712 implementation
  • SafeERC20: Secure token transfers with proper error handling
  • MerkleProof: OpenZeppelin's battle-tested Merkle verification
  • ECDSA: Elliptic curve digital signature algorithm for verification

Key Functions

  • claim(): Main claiming function with signature and proof verification
  • getMessageHash(): Generates EIP-712 message hash for signing
  • _isValidSignature(): Verifies ECDSA signatures
  • getMerkleRoot(): Returns the current Merkle root

πŸ“‹ Usage Examples

Claiming Tokens

// User signs the message off-chain
bytes32 messageHash = airdrop.getMessageHash(userAddress, amount);
(uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, messageHash);

// Gas payer submits the claim
airdrop.claim(userAddress, amount, merkleProof, v, r, s);

Testing

# Run all tests
forge test

# Run specific test
forge test --match-test testUsersCanClaim

πŸ”§ Development & Deployment

Prerequisites

  • Foundry (latest version)
  • Solidity ^0.8.24
  • OpenZeppelin Contracts

Setup

# Install dependencies
forge install

# Build contracts
forge build

# Deploy
forge script script/DeployMerkleAirdrop.s.sol

Scripts

  • DeployMerkleAirdrop.s.sol: Deploys the airdrop system
  • MakeMerkle.s.sol: Generates Merkle trees and proofs
  • Interact.s.sol: Example interaction with the contract
  • GenerateInput.s.sol: Creates input data for Merkle generation

🚨 Security Considerations

Best Practices Implemented

  • Reentrancy Protection: CEI (Checks-Effects-Interactions) pattern
  • Signature Verification: ECDSA recovery with proper validation
  • Double-Claim Prevention: Mapping-based claim tracking
  • Input Validation: Comprehensive parameter checking

Attack Vectors Mitigated

  • Second-Preimage Attacks: Double hashing of leaf nodes
  • Signature Replay: EIP-712 typed data prevents cross-domain attacks
  • Merkle Tree Manipulation: Cryptographic verification of proofs
  • Unauthorized Claims: Both signature and proof verification required

πŸ“š Additional Resources

πŸ“„ License

MIT License - see LICENSE file for details.

About

This contract is used to distribute tokens to a whitelist of addresses based on a Merkle root. Includes mitigation for second-preimage attacks.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published