Skip to main content

Airdrop System Overview

The TokenOps airdrop system enables efficient, secure, and gas-optimized token distributions to large numbers of recipients. Using Merkle tree technology, the system can handle distributions to thousands of addresses while keeping gas costs minimal.

What are Airdrops?

Airdrops are distributions of tokens or cryptocurrency to multiple wallet addresses, typically used for:

  • Community Building: Reward early adopters and community members
  • Marketing Campaigns: Create awareness and attract new users
  • Product Launches: Distribute governance or utility tokens
  • Retroactive Rewards: Compensate users for past participation

Key Benefits

  • Gas Efficiency: Merkle trees minimize on-chain storage and gas costs
  • Scalability: Handle distributions to unlimited recipients
  • Security: Cryptographic proofs ensure only eligible users can claim
  • Flexibility: Support for ERC20 tokens and native ETH distributions

Airdrop System Architecture

Airdrop Contract Types

1. ERC20 Merkle Distributor

Standard token airdrops

// Perfect for: Token distributions, governance token launches
const distributor = new MerkleDistributorERC20(contractAddress, provider);

Features:

  • ERC20 token distribution
  • Merkle proof verification
  • Efficient gas usage
  • Unclaimed token recovery
  • Time-based claim windows

2. Native Token Merkle Distributor

ETH and native token airdrops

// Perfect for: ETH rewards, native token distributions
const nativeDistributor = new MerkleDistributorNative(contractAddress, provider);

Features:

  • ETH/native token distribution
  • No token approval required
  • Direct value transfers
  • Gas refund mechanisms
  • Emergency withdrawal functions

Factory Deployment

Deploy airdrop contracts using the factory pattern:

import { MerkleDistributorFactory } from 'tokenops-sdk';

const factory = new MerkleDistributorFactory(factoryAddress, provider);

// To get the merkle root and proofs look it up in this repo here: https://github.com/Uniswap/merkle-distributor
const merkleRoot = "0x";

// Deploy ERC20 airdrop
const erc20AirdropResult = await factory.newMerkleDistributor(
tokenAddress, // ERC20 token to distribute
merkleRoot, // Merkle tree root
BigInt(Math.floor(Date.now() / 1000) + 3600), // Start in 1 hour
BigInt(Math.floor(Date.now() / 1000) + 7 * 24 * 3600), // End in 1 week
stakingContractAddress, // Optional staking contract for bonuses
rewardOwnerAddress, // Who receives unclaimed tokens
BigInt(20), // 20% bonus for immediate staking
{ account: deployerAddress }
);

console.log('ERC20 Airdrop deployed:', erc20AirdropResult.merkleDistributor);

Claiming Process

Basic Token Claiming

// Recipients claim their tokens using Merkle proofs
async function claimAirdrop(
distributorAddress: string,
userAddress: string,
amount: bigint,
merkleProof: string[]
) {
const distributor = new MerkleDistributorERC20(distributorAddress, provider);

// Check if user has already claimed
const hasClaimed = await distributor.isClaimed(userAddress);
if (hasClaimed) {
throw new Error('User has already claimed their airdrop');
}

// Claim tokens
const claimResult = await distributor.claim(
0, // Claim index (from Merkle tree)
userAddress, // Recipient address
amount, // Amount to claim
merkleProof, // Merkle proof array
{ account: userAddress }
);

console.log('Claimed amount:', claimResult.amount);
return claimResult;
}

Claim and Stake

// Claim tokens and immediately stake them for bonus rewards
async function claimAndStake(
distributorAddress: string,
userAddress: string,
amount: bigint,
merkleProof: string[]
) {
const claimStakeDistributor = new MerkleDistributorNative(
distributorAddress,
provider
);

// Claim and stake in one transaction
const result = await claimStakeDistributor.claimAndStake(
0, // Claim index
userAddress, // Recipient
amount, // Base amount
merkleProof, // Proof
{ account: userAddress }
);

console.log('Base claimed:', result.baseAmount);
console.log('Bonus received:', result.bonusAmount);
console.log('Total staked:', result.totalStaked);

return result;
}

Resources