The _updateStrategyRewards
function in the StakingPool
contract allows malicious strategies to decrease the totalStaked
amount and potentially drain pool funds. The contract should be updated to validate the strategy rewards and cap totalStaked
before deployment.
In the _updateStrategyRewards
function of StakingPool.sol
, the contract sums up the rewards across all strategies being updated: https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/StakingPool.sol#L530-L538
Then, it directly adds totalRewards to totalStaked
: https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/StakingPool.sol#L551-L553
If totalRewards
is negative and its absolute value is greater than totalStaked
, this will cause an integer underflow, setting totalStaked
to a very large number.
Even if totalRewards
is only slightly negative, it will still incorrectly decrease totalStaked when it should only ever stay the same or increase.
This violates the expected behavior that updating rewards should never decrease the total staked.
The issue occurs because _updateStrategyRewards
directly adds the totalRewards
value returned by strategies to totalStaked
: https://github.com/Cyfrin/2024-09-stakelink/blob/f5824f9ad67058b24a2c08494e51ddd7efdbb90b/contracts/core/StakingPool.sol#L522-L600
If totalRewards
is negative and its absolute value is greater than totalStaked
, this will cause an integer underflow, setting totalStaked
to a very large number. Even if totalRewards
is only slightly negative, it will still incorrectly decrease totalStaked
.
This breaks the core invariant that the total amount staked in the pool should always be the sum of all user stakes. If totalStaked
decreases below that sum, the pool will not have enough funds to let everyone withdraw their original stake. Malicious strategies could exploit this bug to drain the pool's funds over time.
with a malicious strategy that returns negative rewards when updateDeposits
is called.
Some users stake tokens into the pool so totalStaked > 0
.
Call updateStrategyRewards
with the malicious strategy, passing data that makes it return a negative reward greater in absolute value than the current totalStaked
.
Observe that totalStaked
decreases incorrectly, or underflows to a very large number.
This vulnerability allows malicious strategies to drain funds from the staking pool over time by repeatedly decreasing totalStaked
with negative rewards. In the worst case, a single large negative reward could cause an integer underflow, setting totalStaked
to a huge number and completely breaking the pool's accounting. This would block further withdrawals and reward distributions.
This undermines the core purpose of the staking pool, which is to hold all user funds and accurately distribute rewards.
Vs
Validate that the strategy rewards are non-negative, and cap the subtraction so totalStaked
never goes below zero. Update the _updateStrategyRewards
function as follows.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.