How to Distribute Tokens on Solana: A Developer’s Guide to Merkle Tree Airdrops

·

Distributing tokens efficiently and securely is a critical task for blockchain projects, especially when dealing with large-scale airdrops. On the Solana network, high throughput and low transaction fees make it ideal for mass token distribution—but managing thousands of transfers can still become costly due to rent and operational complexity.

This guide walks you through how to distribute tokens on Solana using a Merkle tree-based distributor, leveraging smart contracts (programs) built with Anchor. We’ll explore the core concepts, analyze real-world code from the saber-hq/merkle-distributor repository, and clarify key distinctions between SOL and SPL token transfers.


Why Use a Merkle Tree for Token Distribution?

Sending tokens directly to thousands of wallets incurs significant costs on Solana—not just in transaction fees, but also in rent-exempt storage required for each associated token account. The solution? Shift the cost to claimers using a Merkle tree.

How It Works

A Merkle tree allows you to:

Only users who can provide a valid Merkle proof (a cryptographic path proving their inclusion in the tree) can claim their tokens.

👉 Discover how blockchain developers streamline token airdrops with efficient claiming mechanisms.


Core Components of the Merkle Distributor Program

The merkle-distributor program, inspired by Uniswap's implementation, uses Anchor Framework to simplify Solana smart contract development. Let’s break down its key functions.

1. Initializing the Distributor

The new_distributor function sets up the distribution campaign:

pub fn new_distributor(
    ctx: Context,
    _bump: u8,
    root: [u8; 32],
    max_total_claim: u64,
    max_num_nodes: u64,
) -> Result<()> { ... }

Parameters Explained:

This function initializes a PDA (Program Derived Address) as the distributor account, storing essential metadata like the mint address, total claimed amount, and claim count.


2. Claiming Tokens: On-Demand Distribution

Users invoke the claim instruction to receive their tokens:

pub fn claim(
    ctx: Context,
    _bump: u8,
    index: u64,
    amount: u64,
    proof: Vec<[u8; 32]>,
) -> Result<()> { ... }

Claim Flow:

  1. Verify Signer: Ensure the claimant is signing the transaction.
  2. Reconstruct Leaf Node:

    let node = hashv(&[&index.to_le_bytes(), &claimant.key().to_bytes(), &amount.to_le_bytes()]);
  3. Validate Merkle Proof: Check if the provided proof leads to the stored root.
  4. Transfer Tokens: Use CPI (Cross-Program Invocation) to transfer SPL tokens from the distributor’s ATA.
  5. Update State: Increment total claimed tokens and number of claims.

The system prevents double claims via the ClaimStatus account, which records whether a specific index has already been redeemed.


Understanding Key Data Structures

MerkleDistributor Account

Stores global state:

ClaimStatus Account

Tracks per-user claim status:

This design ensures immutability and auditability while minimizing on-chain storage.


Verifying Merkle Proofs in Rust

The merkle_proof::verify function checks whether a given leaf belongs to the tree rooted at root.

pub fn verify(proof: Vec<[u8; 32]>, root: [u8; 32], leaf: [u8; 32]) -> bool {
    let mut computed_hash = leaf;
    for proof_element in proof.into_iter() {
        computed_hash = if computed_hash <= proof_element {
            hashv(&[&computed_hash, &proof_element]).0
        } else {
            hashv(&[&proof_element, &computed_hash]).0
        };
    }
    computed_hash == root
}

This logic mirrors OpenZeppelin’s Solidity version, ensuring compatibility across ecosystems.


SOL vs SPL Token Transfers: Know the Difference

A common confusion among Solana developers is mixing up native SOL transfers with SPL token transfers. They use different instructions and programs.

Native SOL Transfer

Uses the System Program:

invoke(
    &system_instruction::transfer(signer.key, recipient.key, lamports),
    &[signer.clone(), recipient.clone()],
);

SPL Token Transfer

Uses the Token Program:

token::transfer(
    CpiContext::new(
        token_program.to_account_info(),
        Transfer {
            from: source_ata.to_account_info(),
            to: destination_ata.to_account_info(),
            authority: distributor.to_account_info(),
        },
    ).with_signer(&[&seeds[..]]),
    amount,
)?;
⚠️ Never confuse these two. Using the wrong instruction will result in failed transactions or security vulnerabilities.

👉 Learn how top-tier blockchain platforms enable secure and scalable token operations.


Benefits of This Approach


Frequently Asked Questions (FAQ)

Q: What tools can I use to generate a Merkle tree off-chain?

You can use JavaScript libraries like merkletreejs or Python's py-merkle to build the Merkle tree and generate proofs before deploying the distributor. Anchor CLI can also assist in local testing.

Q: Can I update the Merkle root after deployment?

No. Once deployed, the root is immutable. To change eligibility, deploy a new distributor instance.

Q: How do users know their index and proof?

Project teams typically provide claim UIs where users connect their wallet and automatically receive their index, amount, and proof via an API.

Q: Is there a gas cost for claimers?

Yes—claimers pay for transaction fees and account creation (if needed). However, they can close unused token accounts later to reclaim rent.

Q: Can I distribute multiple tokens using one program?

Not directly. Each distributor instance supports one mint. For multiple tokens, deploy separate distributors or build a multi-mint wrapper.

Q: Are there alternatives to Merkle trees for airdrops?

Yes—snapshot-based claims or whitelist PDAs work too—but they’re less gas-efficient at scale. Merkle trees remain the gold standard for large distributions.


Final Thoughts

Using a Merkle-based token distributor on Solana is a powerful way to manage large-scale airdrops efficiently and affordably. By shifting verification burden to end-users and minimizing on-chain data storage, projects can ensure fairness, transparency, and scalability.

Whether you're launching a DeFi protocol, NFT project, or governance token, implementing this pattern gives your community confidence in your distribution process.

👉 Explore how leading Web3 platforms support advanced token economics and smart contract deployment.

By mastering these patterns—and understanding the nuances between SOL and SPL operations—you position yourself at the forefront of modern blockchain development on Solana.