Liquid Staking

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

Integer Downcasting Leading to Data Truncation in Withdrawal Processing

Summary

The WithdrawalPool contract instances of unsafe integer downcasting from uint256 to uint128. This can lead to data truncation, resulting in incorrect withdrawal processing and financial discrepancies. The vulnerability arises from direct casting without checks, which can lead to significant data loss if the values exceed the uint128 range.

Vulnerability Details

The contract performs direct downcasting of integer types without ensuring the value fits within the target type's range.

function queueWithdrawal(address _account, uint256 _amount) external onlyPriorityPool {
if (_amount < minWithdrawalAmount) revert AmountTooSmall();
lst.safeTransferFrom(msg.sender, address(this), _amount);
uint256 sharesAmount = _getSharesByStake(_amount);
@=> queuedWithdrawals.push(Withdrawal(uint128(sharesAmount), 0));
totalQueuedShareWithdrawals += sharesAmount;
uint256 withdrawalId = queuedWithdrawals.length - 1;
queuedWithdrawalsByAccount[_account].push(withdrawalId);
withdrawalOwners[withdrawalId] = _account;
emit QueueWithdrawal(_account, _amount);
}
function updateWithdrawalBatchIdCutoff() external {
uint256 numWithdrawals = queuedWithdrawals.length;
uint256 newWithdrawalIdCutoff = withdrawalIdCutoff;
// find the first withdrawal that has funds remaining
for (uint256 i = newWithdrawalIdCutoff; i < numWithdrawals; ++i) {
newWithdrawalIdCutoff = i;
Withdrawal memory withdrawal = queuedWithdrawals[i];
if (withdrawal.sharesRemaining != 0 || withdrawal.partiallyWithdrawableAmount != 0) {
break;
}
}
uint256 numBatches = withdrawalBatches.length;
uint256 newWithdrawalBatchIdCutoff = withdrawalBatchIdCutoff;
// find the last batch where all withdrawals have no funds remaining
for (uint256 i = newWithdrawalBatchIdCutoff; i < numBatches; ++i) {
if (withdrawalBatches[i].indexOfLastWithdrawal >= newWithdrawalIdCutoff) {
break;
}
newWithdrawalBatchIdCutoff = i;
}
withdrawalIdCutoff = uint128(newWithdrawalIdCutoff);
@=> withdrawalBatchIdCutoff = uint128(newWithdrawalBatchIdCutoff);
}

Impact

Users could withdraw more than their fair share due to incorrect share accounting, leading to financial losses for the contract.

Tools Used

Manual review

Recommendations

Use OpenZeppelin SafeCast library to safely perform downcasting.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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