Vyper Vested Claims

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

Missing Validation for Vesting Timeframe

Description: The contract's constructor doesn't validate that the vesting end time is greater than the vesting start time. This could lead to a permanently broken vesting schedule if incorrect parameters are provided during deployment.

Lines 42-55 in the init function:

@deploy
def __init__(merkle_root: bytes32, token: address, vesting_start_time: uint256, vesting_end_time: uint256):
"""
@notice Initialize the contract with the merkle root, token address, vesting start and end time
@param merkle_root: bytes32, the merkle root of the vesting list
@param token: address, the address of the token contract
@param vesting_start_time: uint256, the start time of the vesting
@param vesting_end_time: uint256, the end time of the vesting
"""
self.merkle_root = merkle_root
self.token = token
self.vesting_start_time = vesting_start_time
self.vesting_end_time = vesting_end_time
self.owner = msg.sender
log MerkleRootUpdated(merkle_root)

Impact: If vesting_end_time ≤ vesting_start_time, the vesting calculation will break, potentially causing:

  1. Division by zero if the times are equal (in the _calculate_vested_amount function)

  2. Negative elapsed time calculations if end time is before start time

  3. Users unable to claim their rightful tokens due to broken vesting mechanics

Proof of Concept: If the contract is deployed with vesting_start_time = 1000 and vesting_end_time = 1000, then:

  • vesting_duration = end_time - start_time = 0

  • In _calculate_vested_amount, the calculation (linear_vesting * elapsed) // vesting_duration would attempt to divide by zero, causing the transaction to revert

Recommended Mitigation: Add validation in the constructor to ensure the vesting timeframe is valid:

@deploy
def __init__(merkle_root: bytes32, token: address, vesting_start_time: uint256, vesting_end_time: uint256):
assert vesting_end_time > vesting_start_time, "Invalid vesting timeframe"
assert token != empty(address), "Token address cannot be zero"
assert merkle_root != empty(bytes32), "Merkle root cannot be empty"
self.merkle_root = merkle_root
self.token = token
self.vesting_start_time = vesting_start_time
self.vesting_end_time = vesting_end_time
self.owner = msg.sender
log MerkleRootUpdated(merkle_root)
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.