# 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

### Architecture Diagram

```
┌────────────────────────────────────────────────────┐
│                MDCreate2 Factory                   │
└────────────────────────┬───────────────────────────┘
                         │ Deploys
┌────────────────────────▼───────────────────────────┐
│               BaseMerkleDistributor                │
│      (Abstract base with core functionality)       │
└────────────────────────┬───────────────────────────┘
                         │ Inherited by
        ┌────────────────┴────────────────┐
        │                                 │
┌───────▼──────────┐           ┌──────────▼──────────┐
│ ERC20 Extensions │           │  ERC721 Extensions  │
└──────────────────┘           └─────────────────────┘
```

### Core Components

* **Base Contract** - Core distribution logic
* **Extensions** - Token-specific implementations
* **Custom Extensions** - Special use cases

## 🔧 Core Contracts

### BaseMerkleDistributor

The foundation contract providing core distribution functionality.

#### Key Features

**Storage Pattern (ERC7201)**

The contract uses ERC7201 storage pattern:

```solidity
struct BaseMerkleDistributorStorage {
    mapping(bytes32 leaf => bool used) usedLeafs;
    bytes32 root;
    address deployer;
    address token;
    address claimDelegate;
    uint256 startTime;
    uint256 endTime;
    address claimHook;
}
```

**Claim Mechanism**

Two ways to claim tokens:

1. **Direct Claim** - Recipients claim their own tokens
2. **Delegate Claim** - Authorized delegate claims for recipients

```solidity
function claim(
    bytes32[] calldata proof,
    bytes32 group,
    bytes calldata data,
    bytes calldata extraData
) external payable
```

**Security Features**

* Reentrancy protection on all claim functions
* Double-claim prevention via leaf tracking
* Time-based access control
* Owner-only administrative functions

## 🔌 Extension Contracts

### ERC20 Extensions

#### TokenTableMerkleDistributor

Standard ERC20 token distribution with time-locked claims.

```solidity
struct TokenTableMerkleDistributorData {
    uint256 index;
    uint256 claimableTimestamp;
    uint256 claimableAmount;
}
```

#### TokenTableNativeMerkleDistributor

Distributes native tokens (ETH) with similar functionality.

**Special Features:**

* Handles ETH transfers
* `receive()` function for accepting ETH
* Native token withdrawal support

### ERC721 Extensions

#### SimpleERC721MerkleDistributor

Mints new NFTs to recipients.

**Key Behavior:**

* Creates new tokens via `safeMint`
* No withdrawal function (mints are permanent)

#### SimpleNoMintERC721MerkleDistributor

Distributes pre-existing NFTs.

**Key Behavior:**

* Transfers NFTs held by contract
* Owner can withdraw specific token IDs
* Repurposes `amount` parameter as `tokenId`

### Custom Extensions

#### CustomFeesNativeMerkleDistributor

Native token distributor with fee threshold logic.

**Features:**

* Configurable `feelessThreshold`
* Claims below threshold bypass fees
* Modified claim flow for fee handling

#### NFTGatedMerkleDistributor

Claims gated by NFT ownership.

```solidity
struct NFTGatedMerkleDistributorData {
    TokenTableMerkleDistributorData base;
    uint256 expiryTimestamp;
    uint256 nftTokenId;
}
```

**Special Features:**

* Claims tied to NFT ownership
* Delegate.xyz integration
* Auto-recipient from NFT owner

## 💰 Fee System

### Overview

The fee system provides flexible fee collection for claims.

### Components

```
     ┌─────────────────┐
     │  Claim Request  │
     └────────┬────────┘
              │
              ▼
    ┌────────────────────┐
    │ Fee Collector Set? │
    └─────┬───────┬──────┘
          │       │
      Yes │       │ No
          │       │
          ▼       ▼
    ┌──────────┐ ┌─────────┐
    │Calculate │ │  No     │
    │   Fee    │ │  Fee    │
    └────┬─────┘ └─────────┘
         │
         ▼
    ┌──────────────────┐
    │    Fee Token?    │
    └─────┬───────┬────┘
          │       │
   Native │       │ ERC20
          │       │
          ▼       ▼
    ┌──────────┐ ┌─────────────┐
    │ Deduct   │ │  Transfer   │
    │ from     │ │  from       │
    │ msg.value│ │  Payer      │
    └──────────┘ └─────────────┘
```

### Configuration

1. **Fee Collector** - Address that receives fees
2. **Fee Token** - Native or ERC20 token for fees
3. **Fee Calculation** - External `ITTUFeeCollector` interface

## 🔒 Security

### Access Control

| Role     | Permissions                                           |
| -------- | ----------------------------------------------------- |
| Owner    | Set parameters, withdraw tokens, configure extensions |
| 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   |

### Errors

| Error                  | Condition             | Selector     |
| ---------------------- | --------------------- | ------------ |
| `UnsupportedOperation` | Operation not allowed | `0x9ba6061b` |
| `TimeInactive`         | Outside claim window  | `0x0c143eb8` |
| `InvalidProof`         | Merkle proof invalid  | `0x09bde339` |
| `LeafUsed`             | Already claimed       | `0x0e4b0ab2` |
| `IncorrectFees`        | Fee amount mismatch   | `0x1669aa83` |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tokentable.xyz/for-developers/airdrop/evm/merkle.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
