Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: medium
Invalid

Underflow in `claimLSDTokens` could result in automatic revert

Summary

Missing check if _amount < accountClaimed[account] in PriorityPool::claimLSDTokens function, which could lead to incorrect calculations and automatic reverts.

Vulnerability Details

Without this check, if _amount < accountClaimed[account], the amountToClaim calculation (_amount - accountClaimed[account]) could result in a negative number or an underflow (though with Solidity 0.8+ this would result in an automatic revert). This would prevent the function from working as intended.
For example: If _amount = 50 and accountClaimed[account] = 100, the operation 50 - 100 will result in -50, which cannot be stored in a uint256 and will cause a revert.

Impact

  • When performing the operation _amount - accountClaimed[account], where accountClaimed[account] is greater than _amount, the result will be a negative number. Since uint256 cannot represent negative values, this will cause an underflow and automatic revert.

  • The logic assumes that users cannot claim more than what has been allocated to them. Adding this check ensures that users don’t try to claim an amount lower than what they’ve already claimed, which would not make sense in the context of a claim function.

Tools Used

Manual review

Recommendations

function claimLSDTokens(
uint256 _amount,
uint256 _sharesAmount,
bytes32[] calldata _merkleProof
) external {
address account = msg.sender;
+ if (_amount < accountClaimed[account]) revert InvalidClaimAmount();
bytes32 node = keccak256(bytes.concat(keccak256(abi.encode(account, _amount, _sharesAmount))));
if (!MerkleProofUpgradeable.verify(_merkleProof, merkleRoot, node)) revert InvalidProof();
uint256 amountToClaim = _amount - accountClaimed[account];
uint256 sharesAmountToClaim = _sharesAmount - accountSharesClaimed[account];
uint256 amountToClaimWithYield = stakingPool.getStakeByShares(sharesAmountToClaim);
if (amountToClaimWithYield == 0) revert NothingToClaim();
accountClaimed[account] = _amount;
accountSharesClaimed[account] = _sharesAmount;
IERC20Upgradeable(address(stakingPool)).safeTransfer(account, amountToClaimWithYield);
emit ClaimLSDTokens(account, amountToClaim, amountToClaimWithYield);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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