Merkle Distributor

Introduction

The Merkle Distributor provides a modular and efficient solution for token distribution using merkle proofs, supporting various token standards and customizable distribution patterns.

🚀 Quick Start

What is a Merkle Distributor?

A Merkle Distributor is a smart contract system that enables efficient and verifiable token airdrops. Instead of storing all recipient data on-chain, it uses a Merkle tree where only the root is stored, significantly reducing gas costs while maintaining security.

Key Benefits

  • Gas Efficient - Only stores Merkle root on-chain

  • Verifiable - Claims are cryptographically proven

  • Flexible - Supports multiple token types and distribution patterns

  • Secure - Built with security best practices

📋 System Overview

Account Structure

Storage Pattern

A contract has one config storage account, which stores the contract admin's account address and the default fee collector's deployment address. This account will also store a new admin's account address for secure two-step ownership transfers.

pub struct Config {
  pub admin: Pubkey,
  pub new_admin: Pubkey,
  pub default_fee_collector: Pubkey,
}

A Merkle Distributor deployment can manage multiple airdrops. Airdrops use the following storage pattern:

pub struct MerkleAirdrop {
  pub owner: Pubkey,
  pub root: [u8; 32],
  pub project_token: Pubkey,
  pub claim_delegate: Pubkey,
  pub start_time: u64,
  pub end_time: u64,
  pub fee_collector: Pubkey,
  pub fee_token: Pubkey,
  pub paused: bool,
  pub uri: String,
}

A standard time-locked claim is created with the following storage pattern:

pub struct TokenTableMerkleDistributorData {
  pub index: u64,
  pub claimable_timestamp: u64,
  pub claimable_amount: u64,
}

Claim Mechanism

There are two ways to claim tokens:

  1. Direct Claim - Recipients claim their own tokens

  2. Delegate Claim - Authorized delegate claims for recipients

pub fn claim(
  ctx: Context<Claim>,
  project_id: String,
  leaf: [u8; 32],
  proof: Vec<[u8; 32]>,
  group: [u8; 32],
  data: TokenTableMerkleDistributorData
) -> Result<()>

Security Features

  • Reentrancy protection on all claim functions

  • Double-claim prevention via leaf tracking

  • Time-based access control

  • Owner-only administrative functions

💰 Fee System

Overview

The fee system provides flexible fee collection for claims.

Components

  1. Fee Collector - External FeeCollector program that calculates and manages vault accounts

  2. Fee Token - Native or SPL token for fees

  3. Vault Accounts - Program Derived Accounts (PDAs) for holding fee tokens

🔒 Security

Access Control

Role
Permissions

Program Admin

Set fee collector, transfer program admin

Airdrop Owner

Set airdrop parameters, withdraw tokens, transfer airdrop ownership

Delegate

Claim on behalf of recipients

Users

Claim their allocated tokens

Security Features

  • Reentrancy Guards - All state-changing functions protected

  • Leaf Tracking - Prevents double claims

  • Time Windows - Enforced distribution periods

  • Proof Verification - Cryptographic claim validation

📡 Events & Errors

Events

Event
Description

ClaimDelegateSet

Delegate address updated

Claimed

Successful token claim

Initialized

Successful aidrop initialization

Errors

Error
Condition

UnsupportedOperation

Operation not allowed

TimeInactive

Outside airdrop claim window

InvalidSignature

Signature invalid

LeafUsed

Already claimed

IncorrectFees

Fee amount mismatch

OutsideClaimableTimeRange

Outside claim window

NotOwner

Not airdrop owner

NotProgramAdmin

Not program admin

NotPermissioned

Missing permissions for user

InvalidFeeCollector

Provided fee collector account is incorrect

Paused

Airdrop is paused

Last updated

Was this helpful?