Vyper Vested Claims

First Flight #34
Beginner FriendlyDeFi
100 EXP
View results
Submission Details
Severity: low
Invalid

Merkle Tree Proof Size Limitation Restricts Airdrop to ~1 Million Users

Summary

The VestedAirdrop contract limits Merkle proofs to a maximum of 20 elements, which restricts the maximum number of unique users that can be included in the airdrop to approximately 1 million (2^20). This could be problematic if the airdrop needs to support a larger user base.

Vulnerability Details

The contract defines the Merkle proof as a dynamic array with a maximum size of 20 elements:

def _verify_proof(proof: DynArray[bytes32, 20], leaf: bytes32) -> bool:
computed_hash: bytes32 = leaf
for proof_element: bytes32 in proof:
computed_hash = self._hash_pair(computed_hash, proof_element)
return computed_hash == self.merkle_root

In a binary Merkle tree, the maximum number of leaves that can be supported with a proof of depth N is 2^N. With a maximum proof size of 20, the contract can support up to 2^20 = 1,048,576 unique user-amount combinations.

Impact

If the airdrop needs to support more than ~1 million users, the current implementation will not be able to accommodate all users. This could lead to:

  1. The need to deploy multiple airdrop contracts

  2. Exclusion of some users from the airdrop

  3. Increased complexity in managing the airdrop distribution

This is a low severity issue as it's primarily a limitation rather than a security vulnerability, and most airdrops don't reach this scale. However, for projects with large user bases, this could become a significant operational constraint.

Tools Used

Manual code review

Recommendations

If supporting more than 1 million users is a requirement, consider increasing the maximum proof size:

# Increase the maximum proof size to support more users
# 24 elements would support ~16 million users (2^24)
# 30 elements would support ~1 billion users (2^30)
def _verify_proof(proof: DynArray[bytes32, 30], leaf: bytes32) -> bool:
computed_hash: bytes32 = leaf
for proof_element: bytes32 in proof:
computed_hash = self._hash_pair(computed_hash, proof_element)
return computed_hash == self.merkle_root

Alternatively, if gas efficiency is a concern with larger proofs, consider implementing a more scalable approach such as:

  1. Multiple Merkle trees with separate roots

  2. A tiered verification system

  3. Alternative proof systems that are more efficient for large datasets

The appropriate solution depends on the specific requirements and expected scale of the airdrop.

Updates

Appeal created

bube Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.