Vyper Vested Claims

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

Over-Claiming Risk

Summary

The claim() function allows users to specify total_amount, which is used to calculate the vested amount. Since total_amount is not validated against the Merkle tree data, a malicious user can input an inflated value, claiming more tokens than they should

Vulnerability Details

The function claim() takes total_amount as a parameter:

def claim(user: address, total_amount: uint256, proof: DynArray[bytes32, 20]) -> bool:
assert self.verify_proof(user, total_amount, proof), "Invalid proof"
vested: uint256 = self._calculate_vested_amount(total_amount)

The issue is that total_amount is not validated against the on-chain Merkle root, allowing an attacker to pass an arbitrarily large total_amount and increase their vested balance.

  • Assume a legitimate user is entitled to claim 1000 tokens over time.

  • The attacker calls claim() with total_amount = 10_000 instead of 1000.

  • The _calculate_vested_amount() function calculates a much larger vested balance.

  • The attacker successfully claims more tokens than they should.

Impact

  • Attackers can drain the vesting contract by inflating their claimable amount.

  • This can result in unauthorized token distribution and financial losses for the project.

Tools Used

Manual review

Recommendations

Validate total_amount against the Merkle root to prevent manipulation:

stored_amount: uint256 = self.get_merkle_allocated_amount(user, proof)
assert total_amount == stored_amount, "Invalid total amount"
Updates

Appeal created

bube Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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