A gas-efficient Merkle airdrop smart contract system with EIP-712 signature verification and ZkSync support.
Hash-Airdrop enables token distribution to thousands of recipients with minimal gas costs using Merkle tree verification. Instead of storing all eligible addresses on-chain, it stores a single 32-byte Merkle root, allowing O(log n) proof verification.
- Gas Efficient: Merkle tree verification reduces on-chain storage costs
- Signature-Based Claims: EIP-712 signatures enable meta-transactions (gasless claims for users)
- Double-Hash Protection: Prevents second preimage attacks on leaf nodes
- ZkSync Compatible: Full support for ZkSync Era deployment and interaction
- Comprehensive Tooling: Scripts for Merkle tree generation, signature splitting, and claim automation
┌─────────────────────────────────────────────────────────────────┐
│ Hash-Airdrop System │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌──────────────────┐ ┌──────────────┐ │
│ │ HashToken │────▶│ MerkleAirdrop │◀────│ Claimer │ │
│ │ (ERC20) │ │ (Distributor) │ │ (User/Bot) │ │
│ └─────────────┘ └──────────────────┘ └──────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌─────────────┐ │
│ │ Merkle Root │ │ EIP-712 │ │
│ │ Verification │ │ Signature │ │
│ └──────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
| Contract | Description |
|---|---|
MerkleAirdrop.sol |
Core airdrop contract with Merkle proof and signature verification |
HashToken.sol |
ERC20 token with owner-controlled minting |
# Clone the repository
git clone https://github.com/Hash-Hokage/Hash-Airdrop.git
cd Hash-Airdrop
# Install dependencies
forge install
# Build contracts
forge buildFirst, update the whitelist in GenerateInput.s.sol, then generate the Merkle tree:
# Generate input.json with whitelist data
forge script script/GenerateInput.s.sol:GenerateInput
# Generate Merkle root and proofs
forge script script/MakeMerkle.s.sol:MakeMerkle
# Or run both in one command
make merkleOutput files are saved to script/target/:
input.json- Whitelist addresses and amountsoutput.json- Merkle root and proofs for each address
# Deploy to local Anvil
make deploy
# Deploy to Sepolia
make deploy ARGS="--network sepolia"
# Deploy to ZkSync local
make deploy-zkOption A: Using Makefile (Anvil)
# Get signature for claim
make sign
# Execute claim transaction
make claim
# Check token balance
make balanceOption B: Using Scripts
# Sign the claim message
cast wallet sign --no-hash --private-key <PRIVATE_KEY> $(cast call <AIRDROP_ADDRESS> "getMessageHash(address,uint256)" <YOUR_ADDRESS> <AMOUNT>)
# Run claim script
forge script script/interact.s.sol:ClaimAirdrop --broadcastFor ZkSync Era, use the automated shell script:
# Start ZkSync local node
make zk-anvil
# Run full deployment and claim flow
./interactZk.sh# Run all tests
forge test
# Run with verbosity
forge test -vvv
# Run ZkSync-specific tests
make zktest
# Generate gas report
forge test --gas-report- Double Hashing: Leaf nodes use
keccak256(bytes.concat(keccak256(abi.encode(account, amount))))to prevent second preimage attacks - Immutable Root: The Merkle root is set at deployment and cannot be modified
- SafeERC20: Uses OpenZeppelin's SafeERC20 for safe token transfers
- Claim Tracking: Prevents double-claiming via
s_hasClaimedmapping
- EIP-712: Typed structured data hashing prevents signature replay across contracts/chains
- ECDSA Recovery: Uses OpenZeppelin's ECDSA library with
tryRecoverfor safe signature verification
├── src/
│ ├── MerkleAirdrop.sol # Core airdrop contract
│ └── HashToken.sol # ERC20 token contract
├── script/
│ ├── DeployMerkleAirdrop.s.sol # Deployment script
│ ├── GenerateInput.s.sol # Whitelist JSON generator
│ ├── MakeMerkle.s.sol # Merkle tree generator
│ ├── SplitSignature.s.sol # Signature utility
│ └── interact.s.sol # Claim automation script
├── test/
│ └── MerkleAirdrop.t.sol # Test suite
├── interactZk.sh # ZkSync deployment automation
└── Makefile # Command shortcuts
- OpenZeppelin Contracts - ERC20, SafeERC20, ECDSA, MerkleProof, EIP712
- Murky - Merkle tree generation library
- Foundry DevOps - Deployment utilities
This project is licensed under the MIT License - see the LICENSE file for details.
Hash-Hokage
⚠️ Disclaimer: This code is provided as-is for educational purposes. Always conduct thorough audits before deploying to production.