Skip to content

Contract Analysis

DISCLAIMER // NFA // DYOR

This analysis is based on observations of the contract behavior. We are not smart contract security experts. This document aims to explain what the contract appears to do based on the code. It should not be considered a comprehensive security audit or financial advice. Always verify critical information independently and consult with blockchain security professionals for important decisions.

⊙ generated by robots | curated by humans

Analysis Date: 2026-03-19


Metadata

Primary Contract

PROPERTY VALUE
Contract Address 0x090D4613473dEE047c3f2706764f49e0821D256e (etherscan)
Network Ethereum Mainnet
Contract Type Standalone (not upgradeable)
Deployment Date 2020-09-16 20:05:38 UTC
Deployment Block 10,875,192
Contract Creator 0x41653c7d...4142cfb (etherscan)
Creation TX 0x1d80567e...b8624cd (tx)
Compiler Version Solidity v0.6.11+commit.5ef660b1
Optimization Enabled (200 runs)
Total Functions 5 (4 external, 1 private)
External Contract Dependencies 1 (UNI token)
Upgrade Mechanism ☒ None — Not Upgradeable
Verification Status ☑ Verified (Exact Match)
Audit Status ☑ Part of Uniswap protocol — audited codebase
TYPE ADDRESS NOTES
Distributed Token 0x1f9840a8...4201F984 (etherscan) Uniswap (UNI) governance token
Deployer 0x41653c7d...4142cfb (etherscan) Uniswap deployer address

Executive Summary

This is the Uniswap Merkle Distributor contract — the mechanism used to distribute the UNI governance token airdrop to approximately 250,000 historical Uniswap users on September 16, 2020. Each eligible address received 400 UNI tokens (worth ~$1,200 at launch), making this one of the largest airdrops in DeFi history.

The contract is a textbook implementation of the Merkle Distributor pattern: a single Merkle Root committed at deployment represents every eligible address and their claimable amount. Users prove eligibility by submitting a Merkle Proof alongside their claim, which the contract verifies on-chain before releasing tokens. A packed bitmap tracks which indices have already been claimed, preventing double claims.

At 162 lines of verified Solidity, this is one of the most minimal and well-understood contracts in the Ethereum ecosystem. It has no owner, no admin functions, no upgrade mechanism, and no pause capability. The only state change possible is claiming an unclaimed allocation — nothing else. Once deployed, the contract's behavior was permanently fixed.

As of this analysis, approximately 12.57 million UNI (~8.4% of the 150M allocation) remains unclaimed in the contract. Over 31,500 transactions have interacted with the contract across nearly six years, with claims still occurring as recently as March 2026. The unclaimed tokens are effectively locked — there is no admin function or sweep mechanism to recover them, and they will remain in the contract indefinitely unless claimed by their rightful owners.


Architecture

graph TB
    subgraph Deployer["Deployment (One-Time)"]
        D["Uniswap Deployer<br/>0x41653c7d...4142cfb"]
    end

    subgraph MerkleDistributor["MerkleDistributor<br/>0x090D4613...1D256e"]
        MR["Immutable: merkleRoot<br/>0xc8500f8e...dbdeb5"]
        TK["Immutable: token<br/>UNI (0x1f9840a8...01F984)"]
        BM["Storage: claimedBitMap<br/>mapping(uint256 => uint256)"]
        CF["claim()"]
        IC["isClaimed()"]
    end

    subgraph UNI["UNI Token<br/>0x1f9840a8...01F984"]
        BAL["balanceOf(distributor)<br/>~12.57M UNI remaining"]
        TR["transfer()"]
    end

    subgraph Users["Eligible Claimants"]
        U["~250,000 addresses<br/>400 UNI each"]
    end

    D -->|"constructor(token, merkleRoot)"| MerkleDistributor
    U -->|"claim(index, account, amount, proof)"| CF
    CF -->|"verify proof against"| MR
    CF -->|"check/set claimed"| BM
    CF -->|"transfer(account, amount)"| TR
    IC -->|"read bitmap"| BM

    style MerkleDistributor fill:#f0f0f0,stroke:#333
    style UNI fill:#ff007a15,stroke:#ff007a

System Overview

The Merkle Distributor serves a single purpose: distribute a fixed allocation of UNI tokens to a predetermined set of eligible addresses. The entire eligibility dataset (addresses and amounts) is compressed into a single 32-byte Merkle root stored as an immutable variable.

  • Claiming requires a valid index, account, amount, and Merkle proof
  • The contract transfers UNI tokens directly from its own balance to the claimant
  • A packed bitmap (256 claims per storage slot) tracks claimed indices gas-efficiently
  • The contract does not hold ETH, collect fees, or perform any action besides token distribution
  • There is no mechanism to recover unclaimed tokens — they remain locked in the contract forever

Design Patterns Used

  • Merkle Distributor: Stores ~250,000 eligible addresses in a single 32-byte root, enabling O(log n) proof verification per claim (~30,000-50,000 gas per claim vs. millions if stored individually)
  • Packed Bitmap: Uses mapping(uint256 => uint256) where each uint256 tracks 256 claim statuses as individual bits, reducing storage costs by 256x compared to a naive mapping(address => bool)
  • Immutable Variables: Both token and merkleRoot are immutable, stored in contract bytecode rather than storage, saving gas on every read and making them permanently unmodifiable

Access Control

Roles & Permissions

ROLE ASSIGNED BY REVOKABLE CALL COUNT
Claimant Merkle tree inclusion N/A Once per index

There are no admin roles, owner roles, or privileged functions. Every external function is callable by anyone, and the only meaningful action (claim) is gated by Merkle proof verification rather than access control lists.

Permission Matrix

FUNCTION ANYONE
claim() ☑ (with valid proof)
isClaimed()
merkleRoot()
token()

Time Locks & Delays

ACTION TIME LOCK CAN CANCEL PURPOSE
Claim tokens None ☒ No — irreversible Claims execute immediately with no delay

Economic Model

Token Distribution Flow

flowchart LR
    A["UNI Token Contract<br/>~150M UNI allocated"] -->|"transfer to distributor<br/>at deployment"| B["MerkleDistributor<br/>holds UNI balance"]
    B -->|"claim() with valid proof<br/>transfers amount to claimant"| C["Eligible Address<br/>receives 400 UNI"]
    B -.->|"no sweep function<br/>unclaimed tokens locked forever"| D["~12.57M UNI<br/>permanently locked"]

Fee Structure

This contract collects zero fees. There are no protocol fees, admin fees, or any other charges. The only cost to claimants is the Ethereum gas fee for the claim() transaction itself.

Current State

METRIC VALUE
Original Allocation ~150,000,000 UNI
Claimed ~137,430,378 UNI (91.6%)
Unclaimed ~12,569,622 UNI (8.4%)
Total Transactions ~31,515
Most Recent Claim 2026-03-17
Per-Address Allocation 400 UNI (standard)

Summary of Observations

The Uniswap MerkleDistributor at 0x090D4613...1D256e is the canonical airdrop contract that distributed UNI governance tokens to historical Uniswap users beginning September 16, 2020. It implements the Merkle Distributor pattern — a gas-efficient method for distributing tokens to a large set of recipients using a single on-chain Merkle Root and off-chain proofs.

The contract is notable for what it does not do. There is no owner. There are no admin functions. There is no upgrade mechanism, no pause capability, and no sweep function. The contract's behavior was permanently fixed at deployment. The only possible state change is a valid claim — nothing else.

Approximately 8.4% of the allocated UNI (~12.57 million tokens) remains unclaimed after nearly six years. At current UNI prices, this represents significant value that is effectively locked forever. The absence of a recovery mechanism means these tokens cannot be retrieved by Uniswap governance or any other party — they will remain in the contract until claimed by the rightful addresses, if ever.

The contract has processed over 31,500 transactions and continues to receive claims as recently as March 2026. Its simplicity (162 lines, 4 external functions, 1 storage mapping) makes it one of the most transparent and verifiable contracts on Ethereum. The packed bitmap pattern packs 256 claim statuses into a single storage slot, and the immutable Merkle root and token address are embedded directly in the bytecode.

From a risk perspective, this contract has no centralization concerns, no admin key risks, and no economic extraction mechanisms. The primary risks are theoretical: the Merkle root was assumed correct at deployment (if it contained errors, there is no correction mechanism), and any token-transfer vulnerability in the UNI contract itself could theoretically affect claims. Neither risk appears to have materialized in six years of operation.

This analysis was performed for educational purposes and should not be considered a comprehensive security audit or financial advice. The contract's simplicity and long operational history make it among the lowest-risk contracts we have analyzed, but independent verification is always recommended.


References

RESOURCE NOTES
Etherscan — MerkleDistributor Verified source code and transaction history
Uniswap Blog — UNI Announcement Original announcement of UNI token and airdrop
Uniswap merkle-distributor GitHub Original source repository for the MerkleDistributor contract
Etherscan — UNI Token UNI governance token contract

Change Log

DATE AUTHOR NOTES
2026-03-19 Artificial. Generated by robots. Gas: 45 tok
? ? Reviewed, edited, and curated by humans.