Vyper Vested Claims

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

Possible Underflow in _calculate_vested_amount()

Summary

The _calculate_vested_amount() function does not properly handle cases where block.timestamp is less than self.vesting_start_time, potentially leading to underflow issues when calculating elapsed

Vulnerability Details

In the _calculate_vested_amount() function:

@view
def _calculate_vested_amount(total_amount: uint256) -> uint256:
current_time: uint256 = block.timestamp
start_time: uint256 = self.vesting_start_time
end_time: uint256 = self.vesting_end_time
vested: uint256 = 0
if current_time >= end_time:
return total_amount
vesting_duration: uint256 = end_time - start_time
elapsed: uint256 = current_time - start_time
instant_release: uint256 = (total_amount * 31) // 100
linear_vesting: uint256 = (total_amount * 69) // 100
vested = instant_release + (linear_vesting * elapsed) // vesting_duration
return vested
  • If block.timestamp < self.vesting_start_time, then elapsed = current_time - start_time will underflow, as unsigned integers (uint256) cannot be negative.

  • This could lead to an incorrect vested amount calculation or unexpected contract behavior.

Impact

  • If an underflow occurs, it can cause incorrect vested amounts to be returned, leading to miscalculations in token distribution.

Tools Used

Manual Review

Recommendations

Modify _calculate_vested_amount() to ensure elapsed does not go negative by adding an additional check:

@view
def _calculate_vested_amount(total_amount: uint256) -> uint256:
current_time: uint256 = block.timestamp
start_time: uint256 = self.vesting_start_time
end_time: uint256 = self.vesting_end_time
vested: uint256 = 0
if current_time < start_time:
return 0 # Ensure no underflow
if current_time >= end_time:
return total_amount
vesting_duration: uint256 = end_time - start_time
elapsed: uint256 = current_time - start_time
instant_release: uint256 = (total_amount * 31) // 100
linear_vesting: uint256 = (total_amount * 69) // 100
vested = instant_release + (linear_vesting * elapsed) // vesting_duration
return vested
Updates

Appeal created

bube Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

[Invalid] Underflow in `_calculate_vested_amount`

The `_calculate_vested_amount` function is called in ` claim` and `claimable_amount` functions. There is a check that ensures the `block.timestamp` is greater or equal to the `vesting_start_time` in the both functions. Also, the admin sets the start and end time of the vesting. This means it will be always correct. Therefore, there is no risk from underflow or division by zero in `_calculate_vested_amount` function.

Support

FAQs

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