Users who deposits reward tokens into the Staking contract does not accrue any Staking rewards.
After deposit of rewardTokens into the Staking contract, no rewards accrue to the depositor as the condition for claimable reward accrual is never satisfied. Consider the following scenario to understand the issue:
Staking contract has 2000 WETH.
User deposits 1000 rewardTokens by calling Staking.deposit()
.
Execution enters updateFor(user)
, which calls update()
.
The stakingIndex (0 to begin with) is incremented by the deposit ratio: uint256 _ratio = _diff * 1e18 / totalSupply
and _diff = _balance - balance
. This ratio stands at 2e18 as per the calculation .
Staking.index
is set to 2e18
Staking.balance
is set to WETH.balanceOf(address(this))
i.e., its own WETH balance.
We continue in updateFor(user)
:
Staking.index is set to 1000e18 (user's staked reward token balance)
The differece between userIndex and global index uint256 _delta = index - _supplyIndex;
is calculated: User index is 2e18 (as set in update()
), as global index is also 2e18, so _delta
is 0.
Due to 0 delta, no shares accrue to depositor.
The global index value will always be equal to the recipient supplyIndex, leading to uint256 _delta = index - _supplyIndex;
always resolving to 0 and no rewards ever accruing to any user.
The only way for rewards to accrue to depositors is if the Staking contract WETH balance increases after the first user deposit. This results in the updateFor()
's _delta
calculation to be greater than 0 as the global index becomes greater than the supplier index. Even with this subsequent WETH balance increase in Staking.sol, the rewards accrue only to the subsequent depositors. Those who deposited before won't accrue any rewards.
The following test can be placed in Lender.t.sol
to demonstrate the issue:
High
Manual Review
A redesign of the entire staking and rewards system is recommended. One mitigation is to drop the index system and simply calculate depositor claimable rewards based on staking amount and staking period.
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.