Liquid Staking

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

Conversion Rate Is Broken

Summary

In multiple places within the StakingPool contract, it is incorrectly assumed that the rate between the asset token and liquid staking tokens is 1:1. However, this assumption is broken by the donateTokens function, which updates totalStaked but not the number of shares, leading to incorrect calculations in other parts of the contract.

Vulnerability Details

The donateTokens function causes a break in the assumed 1:1 rate between the asset token and liquid staking tokens. This happens because donateTokens increases totalStaked without updating the number of shares. This flawed assumption of 1:1 rate leads to incorrect computations in several parts of the contract. One example is the _updateStrategyRewards function, where:

if (totalFeeAmounts > 0) {
uint256 sharesToMint = (totalFeeAmounts * totalShares) /
(totalStaked - totalFeeAmounts);
_mintShares(address(this), sharesToMint);
uint256 feesPaidCount;
for (uint256 i = 0; i < receivers.length; i++) {
for (uint256 j = 0; j < receivers[i].length; j++) {
if (feesPaidCount == totalFeeCount - 1) {
transferAndCallFrom(
address(this),
receivers[i][j],
balanceOf(address(this)),
"0x"
);
} else {
transferAndCallFrom(address(this), receivers[i][j], feeAmounts[i][j], "0x");
feesPaidCount++;
}
}
}
}

transferAndCallFrom is using feeAmounts[i][j], but feeAmounts[i][j] is amount, not shares. And it's possible for shares to be smaller number and this will lead to wrong computation. feeAmounts[i][j] should calculate the number of shares in terms of sharesToMint. Since the donateTokens function can distort the relationship between token amounts and shares, this leads to incorrect reward distribution and fee allocation.

Impact

Due to the wrong logic, it will lead to wrong computation on different place in the protocol. Because this rate 1:1 is assumed by the other contracts that rely on the StakingPool.

Tools Used

Manual review

Recommendations

Always convert from amount to share or vice versa, and don't rely that the conversion rate is 1:1. Or remove the donate function.

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.