Skip to content

Functions

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

METADATA
Contract Address 0x090D4613473dEE047c3f2706764f49e0821D256e (etherscan)
Network Ethereum Mainnet
Analysis Date 2026-03-19

Function Selectors

SELECTOR FUNCTION SIGNATURE CATEGORY
0x2e7ba6ef claim(uint256,address,uint256,bytes32[]) User
0x2eb4a7ab merkleRoot() View
0x9e34070f isClaimed(uint256) View
0xfc0c546a token() View

Summary

CATEGORY COUNT
Total Functions 5
User Functions 1
Admin Functions 0
View Functions 3
Private Functions 1

User Functions

Function: claim(uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof)

The primary (and only) state-changing function in the contract. Verifies that the caller provides a valid Merkle proof for the given index, account, and amount, then marks the index as claimed and transfers the specified amount of UNI tokens to the account.

Anyone can call this function on behalf of any eligible address — the tokens are always sent to the account parameter, not to msg.sender. This means a third party can submit a claim transaction for someone else and pay the gas.

ATTRIBUTE VALUE
Selector 0x2e7ba6ef
Parameters index (uint256), account (address), amount (uint256), merkleProof (bytes32[])
Access External, anyone with valid proof
State-Changing Yes
Payable No
CONDITION REQUIREMENT
Not already claimed !isClaimed(index) — reverts if the bit for this index is already set
Valid Merkle proof MerkleProof.verify(merkleProof, merkleRoot, node) where node = keccak256(abi.encodePacked(index, account, amount))
Token transfer succeeds IERC20(token).transfer(account, amount) must return true
STEP ACTION
1 Check that the index has not been claimed (isClaimed(index) returns false)
2 Compute the leaf hash: keccak256(abi.encodePacked(index, account, amount))
3 Verify the Merkle proof against the immutable merkleRoot
4 Mark the index as claimed in the bitmap via _setClaimed(index)
5 Transfer amount UNI tokens from the contract to account
6 Emit Claimed(index, account, amount) event
VARIABLE CHANGE
claimedBitMap[index / 256] Sets bit at position index % 256 to 1
CONDITION REVERT MESSAGE
Index already claimed "MerkleDistributor: Drop already claimed."
Invalid Merkle proof "MerkleDistributor: Invalid proof."
Token transfer fails "MerkleDistributor: Transfer failed."
function claim(
    uint256 index,
    address account,
    uint256 amount,
    bytes32[] calldata merkleProof
) external override {
    require(!isClaimed(index), 'MerkleDistributor: Drop already claimed.');

    // Verify the merkle proof.
    bytes32 node = keccak256(abi.encodePacked(index, account, amount));
    require(
        MerkleProof.verify(merkleProof, merkleRoot, node),
        'MerkleDistributor: Invalid proof.'
    );

    // Mark it claimed and send the token.
    _setClaimed(index);
    require(
        IERC20(token).transfer(account, amount),
        'MerkleDistributor: Transfer failed.'
    );

    emit Claimed(index, account, amount);
}
flowchart TD
    A["claim(index, account, amount, proof)"] --> B{"isClaimed(index)?"}
    B -->|"Yes"| C["REVERT: Drop already claimed"]
    B -->|"No"| D["Compute leaf = keccak256(index, account, amount)"]
    D --> E{"MerkleProof.verify(proof, root, leaf)?"}
    E -->|"Invalid"| F["REVERT: Invalid proof"]
    E -->|"Valid"| G["_setClaimed(index)"]
    G --> H["token.transfer(account, amount)"]
    H -->|"Returns false"| I["REVERT: Transfer failed"]
    H -->|"Returns true"| J["emit Claimed(index, account, amount)"]

Private Functions

Function: _setClaimed(uint256 index)

Internal helper that marks an index as claimed in the packed bitmap. Computes the word index (index / 256) and bit position (index % 256), then sets that bit via bitwise OR.

ATTRIBUTE VALUE
Selector N/A (private)
Parameters index (uint256)
Access Private — called only by claim()
VARIABLE CHANGE
claimedBitMap[index / 256] claimedBitMap[index / 256] | (1 << (index % 256))
function _setClaimed(uint256 index) private {
    uint256 claimedWordIndex = index / 256;
    uint256 claimedBitIndex = index % 256;
    claimedBitMap[claimedWordIndex] = claimedBitMap[claimedWordIndex] | (1 << claimedBitIndex);
}

View Functions

Function: isClaimed(uint256 index)

Returns whether a given index has already been claimed. Reads the packed bitmap by computing the word index (index / 256) and checking whether the bit at position (index % 256) is set.

ATTRIBUTE VALUE
Selector 0x9e34070f
Parameters index (uint256)
Access Public view
Returns booltrue if claimed, false if unclaimed
FLAG OBSERVATION
Gas-efficient: reads a single storage slot and performs bitwise operations
Packing 256 booleans per slot reduces storage reads by 256x compared to a naive mapping
function isClaimed(uint256 index) public view override returns (bool) {
    uint256 claimedWordIndex = index / 256;
    uint256 claimedBitIndex = index % 256;
    uint256 claimedWord = claimedBitMap[claimedWordIndex];
    uint256 mask = (1 << claimedBitIndex);
    return claimedWord & mask == mask;
}

Function: merkleRoot()

Returns the immutable Merkle root that was set at deployment. This root represents the entire eligibility dataset — all addresses and their claimable amounts.

ATTRIBUTE VALUE
Selector 0x2eb4a7ab
Parameters None
Access Public view
Returns bytes320xc8500f8e2fcf3c9a32880e1b973fb28acc88be35787a8abcf9981b2b65dbdeb5
FLAG OBSERVATION
Immutable — stored in contract bytecode, not storage. Cannot be changed after deployment
The off-chain Merkle tree data must be available for users to generate proofs. Uniswap published this data publicly
bytes32 public immutable override merkleRoot;

Function: token()

Returns the immutable address of the ERC-20 token being distributed (UNI).

ATTRIBUTE VALUE
Selector 0xfc0c546a
Parameters None
Access Public view
Returns address0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984 (UNI)
FLAG OBSERVATION
Immutable — cannot be changed after deployment
address public immutable override token;