sherlock-audit / 2024-05-tokensoft-distributor-contracts-update-judging

2 stars 1 forks source link

Honour - Incorrect vesting period data DOSes claiming of tokens #58

Closed sherlock-admin2 closed 4 weeks ago

sherlock-admin2 commented 1 month ago

Honour

high

Incorrect vesting period data DOSes claiming of tokens

Summary

PerAddressContinuousVestingMerkle::claim() does not pass encoded vesting periods data to _executeClaim() as result ,users will be unable to claim their tokens.

Vulnerability Detail

The _executeClaim() function expects the encoded vesting periods data to be passed as an argument here, which is in turn pssed to getVestedFraction() through getClaimableAmount() to calculate the amount of tokens claimable based on the user's vesting periods. However , since the incorrect data(empty bytes array) is passed to _executeClaim() , claiming will always fail on getVestedFraction() .

Impact

High, permanent DOS of claim, users will not be able to claim their tokens

Code Snippet

https://github.com/sherlock-audit/2024-05-tokensoft-distributor-contracts-update/blob/main/contracts/packages/hardhat/contracts/claim/PerAddressContinuousVestingMerkle.sol#L67

https://github.com/sherlock-audit/2024-05-tokensoft-distributor-contracts-update/blob/main/contracts/packages/hardhat/contracts/claim/abstract/Distributor.sol#L79

https://github.com/sherlock-audit/2024-05-tokensoft-distributor-contracts-update/blob/main/contracts/packages/hardhat/contracts/claim/abstract/PerAddressContinuousVesting.sol#L25

Tool used

Manual Review

Recommendation

function claim(
    uint256 index, // the beneficiary's index in the merkle root
    address beneficiary, // the address that will receive tokens
    uint256 totalAmount, // the total claimable by this beneficiary
    uint256 start, // the start of the vesting period
    uint256 cliff, // cliff time
    uint256 end, // the end of the vesting period
    bytes32[] calldata merkleProof
  )
    external
    validMerkleProof(keccak256(abi.encodePacked(index, beneficiary, totalAmount, start, cliff, end)), merkleProof)
    nonReentrant
  {
    // effects
-   uint256 claimedAmount = _executeClaim(beneficiary, totalAmount, new bytes(0));
+   uint256 claimedAmount = _executeClaim(beneficiary, totalAmount, abi.encode(start, cliff, end));
    // interactions
    _settleClaim(beneficiary, claimedAmount);
  }

  function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner {
    _setMerkleRoot(_merkleRoot);
  }

Duplicate of #11