Liquid Staking

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

**Inconsistent Units in `WithdrawalPool::_finalizeWithdrawals`: Mixing Wei, LST, and Shares Without Proper Conversion**

Summary

The WithdrawalPool::_finalizeWithdrawals function in the contract handles withdrawal accounting but suffers from inconsistent unit handling. It mixes Wei (Ether), LST, and shares without properly converting between them. This issue could lead to serious miscalculations during withdrawal processing, where users could receive incorrect amounts or incorrect value transfers, ultimately breaking the functionality of the withdrawal system.

Vulnerability Detail

The vulnerability arises due to the inconsistent use of different token units throughout the WithdrawalPool::_finalizeWithdrawals function. Specifically:

  • Wei (Ether) is used in the input amount (_amount).

  • Shares are used internally to represent staking amounts.

  • LST are used to represent stLINK's .

Expectec unit in _getStakeByShares function parameter _amount is shares but it is given 1 ether which causes mismatch of units. The _getStakeByShares function is invoked using 1 ether (Wei).

This inconsistency can result in users receiving the wrong amount of LST tokens, leading to potential financial losses or operational issues with the contract.

Impact

  • Potential Financial Losses: Users could lose a significant amount of funds if the miscalculation results in lower-than-expected withdrawals. Conversely, the protocol could lose assets if it over-distributes tokens, leading to potential insolvency or liquidity issues.

  • Protocol Disruption: The staking and withdrawal system may be thrown off balance if this vulnerability is exploited. Incorrect accounting could lead to discrepancies in the total assets under management (AUM), making it difficult or impossible to process withdrawals correctly, which might eventually lock users out of their funds.

  • Reputation Damage: The financial and operational consequences of this issue could lead to a loss of trust in the protocol, reducing user confidence and harming the protocol's reputation in the market.

This vulnerability could lead to the contract being unusable if the system cannot process withdrawals correctly due to miscalculations based on unit mismatches.

Code Snippet

https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/priorityPool/WithdrawalPool.sol#L422

function _finalizeWithdrawals(uint256 _amount) internal {
uint256 sharesToWithdraw = _getSharesByStake(_amount);
uint256 numWithdrawals = queuedWithdrawals.length;
totalQueuedShareWithdrawals -= sharesToWithdraw;
for (uint256 i = indexOfNextWithdrawal; i < numWithdrawals; ++i) {
uint256 sharesRemaining = queuedWithdrawals[i].sharesRemaining;
if (sharesRemaining < sharesToWithdraw) {
sharesToWithdraw -= sharesRemaining;
continue;
}
if (sharesRemaining > sharesToWithdraw) {
queuedWithdrawals[i] = Withdrawal(
uint128(sharesRemaining - sharesToWithdraw),
uint128(
queuedWithdrawals[i].partiallyWithdrawableAmount +
_getStakeByShares(sharesToWithdraw)
)
);
indexOfNextWithdrawal = i;
withdrawalBatches.push(
@>>> WithdrawalBatch(uint128(i - 1), uint128(_getStakeByShares(1 ether)))
);
} else {
// fully finalize withdrawal
indexOfNextWithdrawal = i + 1;
withdrawalBatches.push(
@>>>> WithdrawalBatch(uint128(i), uint128(_getStakeByShares(1 ether)))
);
}
sharesToWithdraw = 0;
break;
}
// entire amount must be accounted for
assert(sharesToWithdraw == 0);
emit WithdrawalsFinalized(_amount);
}

Tool Used

Manual code review and analysis of the unit handling within the function, focusing on conversion between different token units (Wei, LST, and shares).

Recommendation

Inuser that the given amount is always shares.

Updates

Lead Judging Commences

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

Support

FAQs

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