Skip to content

Potential Risks

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

Risk Summary

SEVERITY COUNT
Critical 0
High 0
Medium 1
Low 2
Informational 3

Medium Risks

No Recovery Mechanism for Unclaimed Tokens

FIELD VALUE
Severity Medium
Category Economic

The contract has no sweep(), withdraw(), or any other function that could recover unclaimed UNI tokens. As of this analysis, approximately 12.57 million UNI remains in the contract — tokens that can only be released via valid claim() calls.

If the off-chain Merkle proof data were ever lost (the JSON file mapping indices to addresses and amounts), the remaining tokens would become permanently irretrievable. Uniswap published the Merkle tree data publicly via their GitHub repository, but the contract itself has no on-chain fallback.

This appears to be an intentional design choice — adding a sweep function would introduce an admin role and trust assumption that contradicts the contract's permissionless design. The trade-off is that unclaimed tokens are locked forever.


Low Risks

Third-Party Claim Submission

FIELD VALUE
Severity Low
Category Trust Assumption

The claim() function does not check msg.sender. Anyone can submit a claim on behalf of any eligible address — the tokens are always sent to the account parameter in the Merkle leaf. This means:

  • A third party can pay gas to claim tokens for another address
  • The intended recipient always receives the tokens regardless of who submits the transaction
  • This is a feature, not a bug — it enables gas-sponsored claims and batch claim services

The risk is minimal because tokens always go to the predetermined address, but users should be aware that their claim status can be triggered by anyone with knowledge of their proof data.


No Reentrancy Guard

FIELD VALUE
Severity Low
Category Complexity

The claim() function calls IERC20(token).transfer() before emitting the Claimed event, but after setting the claimed bit in the bitmap. The state update (_setClaimed) occurs before the external call, which follows the checks-effects-interactions pattern and effectively prevents reentrancy.

However, there is no explicit ReentrancyGuard modifier. Given that:

  1. The token is the well-audited UNI contract (standard ERC-20, no hooks)
  2. The state is updated before the external call
  3. The bitmap prevents double claims regardless of call order

The risk of reentrancy exploitation appears negligible in practice.


Informational

Immutable Merkle Root — No Correction Mechanism

FIELD VALUE
Severity Informational
Category Trust Assumption

The merkleRoot is set once in the constructor and stored as an immutable variable. If the Merkle tree were generated with errors (wrong addresses, wrong amounts, duplicate entries), there is no mechanism to correct it. A new contract would need to be deployed with the corrected root and funded with tokens.

After nearly six years of operation with no reported issues, this appears to be a purely theoretical concern for this specific deployment.


Off-Chain Data Dependency

FIELD VALUE
Severity Informational
Category External Dependency

Claimants need access to the off-chain Merkle proof data to generate valid proofs. The contract itself only stores the root hash — the full tree (index-to-address-to-amount mappings and sibling hashes) exists off-chain.

Uniswap published this data in their merkle-distributor GitHub repository and various third-party interfaces have cached it. If all copies of this data were lost, remaining unclaimed tokens would be irretrievable.


Solidity 0.6.11 — Older Compiler Version

FIELD VALUE
Severity Informational
Category Complexity

The contract was compiled with Solidity 0.6.11 (July 2020). This version predates several compiler improvements including custom errors (0.8.4), user-defined value types (0.8.8), and overflow checks enabled by default (0.8.0).

For this contract, the older compiler version has no practical security impact:

  • No arithmetic operations that could overflow (bit operations and keccak256 only)
  • No complex state management susceptible to compiler bugs
  • The contract has operated without issues for nearly six years on this compiler version