Skip to content

Latest commit

 

History

History
135 lines (95 loc) · 4.45 KB

018.md

File metadata and controls

135 lines (95 loc) · 4.45 KB

Late Snowy Mockingbird

Medium

The earningPower isn't increased for stake more after bumpEarningPower function.

Summary

https://github.com/sherlock-audit/2024-11-tally/blob/main/staker/src/GovernanceStaker.sol#L471

After call bumpEarningPower function, even though depositor stakes more or withdraws, the earningPower of the deposit is not changed.

Impact

  1. The depositor might not believe this system because the earningPower is not increased even though stake more.
  2. The depositor can get reward with old earningpower because the earningPower is not decreased even though withdraw.

Code Snippet

function testFuzz_EarningPowerAfterBumpsEarning(
    address _depositor,
    address _delegatee,
    uint256 _stakeAmount,
    uint256 _rewardAmount,
    address _bumpCaller,
    address _tipReceiver,
    uint256 _requestedTip,
    uint96 _earningPowerIncrease
  ) public {
    vm.assume(_tipReceiver != address(0));
    _stakeAmount = _boundToRealisticStake(_stakeAmount);
    _rewardAmount = _boundToRealisticReward(_rewardAmount);
    _earningPowerIncrease = uint96(bound(_earningPowerIncrease, 1, type(uint48).max));

    // A user deposits staking tokens
    (, GovernanceStaker.DepositIdentifier _depositId) =
      _boundMintAndStake(_depositor, _stakeAmount, _delegatee);

     _mintGovToken(_depositor, _boundMintAmount(_stakeAmount));
    // The contract is notified of a reward
    _mintTransferAndNotifyReward(_rewardAmount);
    // The full duration passes
    _jumpAheadByPercentOfRewardDuration(101);
    // Tip must be less than the max bump, but also less than rewards for the sake of this test
    _requestedTip = bound(_requestedTip, 0, _min(maxBumpTip, govStaker.unclaimedReward(_depositId)));

    // The staker's earning power increases
    earningPowerCalculator.__setEarningPowerForDelegatee(
      _delegatee, _stakeAmount + _earningPowerIncrease
    );
    // Bump earning power is called
    vm.startPrank(_bumpCaller);
    
    govStaker.bumpEarningPower(_depositId, _tipReceiver, _requestedTip);

    (uint96 _newBalanceAfterBump,, uint96 _newEarningPowerAfterBump,,,,) = govStaker.deposits(_depositId);
    assertEq(_newEarningPowerAfterBump, _stakeAmount + _earningPowerIncrease);

    vm.stopPrank();

    vm.startPrank(_depositor);
    govToken.approve(address(govStaker), _boundMintAmount(_stakeAmount));

    govStaker.stakeMore( _depositId, _boundMintAmount(_stakeAmount/2));

    (uint96 _newBalanceAfterMore,, uint96 _newEarningPowerAfterMore,,,,) = govStaker.deposits(_depositId);
    
    govStaker.withdraw( _depositId, _boundMintAmount(_stakeAmount * 3/2));
   
    (uint96 _newBalanceAfterWithdraw,, uint96 _newEarningPowerAfterWithdraw,,,,) = govStaker.deposits(_depositId);

    vm.stopPrank();

    

    console2.log("----Bump earning power-----");
    console2.log("new Balance after bump");
    console2.log(_newBalanceAfterBump);
    console2.log("new Earning Power after bump");
    console2.log(_newEarningPowerAfterBump);

    console2.log("----After stake more-----");
    console2.log("new Balance after stake more");
    console2.log(_newBalanceAfterMore);
    console2.log("new Earning Power after stake more");
    console2.log(_newEarningPowerAfterMore);

    console2.log("----After withdraw-----");
    console2.log("new Balance after withdraw");
    console2.log(_newBalanceAfterWithdraw);
    console2.log("new Earning Power after withdraw");
    console2.log(_newEarningPowerAfterWithdraw);


    assertGt(_newEarningPowerAfterBump, _newEarningPowerAfterMore);
  }

This is test code. The result is following.

----Bump earning power----- new Balance after bump 24999999900000000000011555 new Earning Power after bump 24999999900000000000021462 ----After stake more----- new Balance after stake more 37499999850000000000017332 new Earning Power after stake more 24999999900000000000021462 ----After withdraw----- new Balance after withdraw 0 new Earning Power after withdraw 24999999900000000000021462

Encountered 1 failing test in test/GovernanceStaker.t.sol:BumpEarningPower [FAIL: assertion failed: 24999999900000000000021462 <= 24999999900000000000021462;

Tool used

Manual Review

Recommendation

As the test code had used MockFullEarningPowerCalculator as EarningPowerCalculator, it causes this issue. But if use BinaryEligibilityOracleEarningPowerCalculator as EarningPowerCalculation, the bump will not work. So you need to make proper calculation for bump and need some code for processing after bump.