Vyper Vested Claims

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

Incorrect Claimable Amount Calculation in VestedAirdrop View Function Due to Improper Vesting Accounting

Summary

A vulnerability was identified in the claimable_amount view function of the VestedAirdrop contract. The function fails to properly account for already claimed amounts when calculating the linear vesting portion, leading to incorrect claimable amount calculations. This could result in users receiving misleading information about their available claims.

Vulnerability Details

The issue lies in the claimable_amount view function where the calculation of vested amount doesn't properly consider the already claimed tokens. While the main claim function correctly handles this by maintaining a claimed_amount mapping, the view function doesn't properly utilize this information in its calculations.

@view
@external
def claimable_amount(user: address, total_amount: uint256) -> uint256:
assert block.timestamp >= self.vesting_start_time, "Claiming is not available yet"
claimable: uint256 = 0
current_amount: uint256 = self.claimed_amount[user]
vested: uint256 = self._calculate_vested_amount(total_amount)
if vested > current_amount:
claimable = vested - current_amount
return claimable

The issue manifests when:

1. A user claims their initial 31% TGE

2. Time passes and linear vesting occurs

3. The view function returns incorrect amounts because it doesn't properly account for the already claimed TGE portion in the linear vesting calculation

Impact

Severity: Medium

This vulnerability could lead to:

  • Incorrect information being displayed to users about their claimable amounts

  • Potential confusion in the frontend interface

  • Miscalculations in user dashboards and analytics

  • Possible disputes if users rely on this information for financial decisions

While this doesn't directly affect the actual token transfers (which are handled correctly in the claim function), it creates a significant user experience issue and could lead to loss of trust in the platform.

POC

The issue can be demonstrated through the failing test cases:
test_claimable_amount:

# After 30 days
warp(time_now + thirty_days())
claimable = self.airdrop.claimable_amount(self.user1, self.amount)
# Fails because incorrect calculation of vested amount
assert claimable == (self.amount * 31 // 100) + (linear_vesting * thirty_days()) // ninety_days()

test_claimable_amount_with_claims

# After 90 days total
warp(block_timestamp() + thirty_days())
claimable = self.airdrop.claimable_amount(self.user1, self.amount)
# Fails because incorrect calculation of remaining vesting
assert claimable == (linear_vesting * thirty_days()) // ninety_days()

Tools Used

  • Manual code review

Recommendations

1. Modify the claimable_amount function to properly account for already claimed amounts in both TGE and linear vesting portions

2. Add additional test cases to verify edge cases in the claimable amount calculations

Updates

Appeal created

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

Support

FAQs

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