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:
- The token is the well-audited UNI contract (standard ERC-20, no hooks)
- The state is updated before the external call
- 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
keccak256only) - No complex state management susceptible to compiler bugs
- The contract has operated without issues for nearly six years on this compiler version