Liquid Staking

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

wrong calculation of updateDeposits

Summary

wrong calculation of amounts and receivers array.

Vulnerability Details

https://github.com/Cyfrin/2024-09-stakelink/blob/main/contracts/linkStaking/OperatorVCS.sol#L198

function updateDeposits(
bytes calldata _data
)
external
override
onlyStakingPool
returns (int256 depositChange, address[] memory receivers, uint256[] memory amounts)
{
uint256 minRewards = _data.length == 0 ? 0 : abi.decode(_data, (uint256));
uint256 newTotalDeposits = totalDeposits;
uint256 newTotalPrincipalDeposits;
uint256 vaultDeposits;
uint256 operatorRewards;
uint256 vaultCount = vaults.length;
address receiver = address(this);
for (uint256 i = 0; i < vaultCount; ++i) {
(uint256 deposits, uint256 principal, uint256 rewards) = IOperatorVault(
address(vaults[i])
).updateDeposits(minRewards, receiver);
vaultDeposits += deposits;
newTotalPrincipalDeposits += principal;
operatorRewards += rewards;
}
uint256 balance = token.balanceOf(address(this));
depositChange = int256(vaultDeposits + balance) - int256(totalDeposits);
if (operatorRewards != 0) {
receivers = new address[](1 + (depositChange > 0 ? fees.length : 0));
amounts = new uint256[](receivers.length);
receivers[0] = address(this);
amounts[0] = operatorRewards;
unclaimedOperatorRewards += operatorRewards;
}
if (depositChange > 0) {
newTotalDeposits += uint256(depositChange);
@>> if (receivers.length == 0) {
receivers = new address[](fees.length);
amounts = new uint256[](receivers.length);
for (uint256 i = 0; i < receivers.length; ++i) {
receivers[i] = fees[i].receiver;
amounts[i] = (uint256(depositChange) * fees[i].basisPoints) / 10000;
}
} else {
for (uint256 i = 1; i < receivers.length; ++i) {
receivers[i] = fees[i - 1].receiver;
amounts[i] = (uint256(depositChange) * fees[i - 1].basisPoints) / 10000;
}
}
} else if (depositChange < 0) {
newTotalDeposits -= uint256(depositChange * -1);
}
if (balance != 0) {
token.safeTransfer(address(stakingPool), balance);
newTotalDeposits -= balance;
}
totalDeposits = newTotalDeposits;
totalPrincipalDeposits = newTotalPrincipalDeposits;
}

Impact

updatedeposit will be wrongly uodated.

Tools Used

Recommendations

if (receivers.length != 0) {
receivers = new address[](fees.length);
amounts = new uint256[](receivers.length);
for (uint256 i = 0; i < receivers.length; ++i) {
receivers[i] = fees[i].receiver;
amounts[i] = (uint256(depositChange) * fees[i].basisPoints) / 10000;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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