Late Snowy Mockingbird
Medium
https://github.com/sherlock-audit/2024-11-tally/blob/main/staker/src/GovernanceStaker.sol#L471
In GovernanceStaker.sol The bumpEarningPower function has no any checking for msg.sender and transfers REWARD_TOKEN to _tipReceiver. So anyone can call the function on any deposit and can receive _requestedTip.
Anyone can call the function on any depositId. So caller can receive tip if the EarningPowerCalculator changed their earning power. Therefore anyone can try to call bumpEarningPower function on all deposits and get tip.
There is no any checking for sender.
function bumpEarningPower(
DepositIdentifier _depositId,
address _tipReceiver,
uint256 _requestedTip
) external virtual {
if (_requestedTip > maxBumpTip) revert GovernanceStaker__InvalidTip();
Deposit storage deposit = deposits[_depositId];
_checkpointGlobalReward();
_checkpointReward(deposit);
uint256 _unclaimedRewards = deposit.scaledUnclaimedRewardCheckpoint / SCALE_FACTOR;
(uint256 _newEarningPower, bool _isQualifiedForBump) = earningPowerCalculator.getNewEarningPower(
deposit.balance, deposit.owner, deposit.delegatee, deposit.earningPower
);
if (!_isQualifiedForBump || _newEarningPower == deposit.earningPower) {
revert GovernanceStaker__Unqualified(_newEarningPower);
}
if (_newEarningPower > deposit.earningPower && _unclaimedRewards < _requestedTip) {
revert GovernanceStaker__InsufficientUnclaimedRewards();
}
// Note: underflow causes a revert if the requested tip is more than unclaimed rewards
if (_newEarningPower < deposit.earningPower && (_unclaimedRewards - _requestedTip) < maxBumpTip)
{
revert GovernanceStaker__InsufficientUnclaimedRewards();
}
// Update global earning power & deposit earning power based on this bump
totalEarningPower =
_calculateTotalEarningPower(deposit.earningPower, _newEarningPower, totalEarningPower);
depositorTotalEarningPower[deposit.owner] = _calculateTotalEarningPower(
deposit.earningPower, _newEarningPower, depositorTotalEarningPower[deposit.owner]
);
deposit.earningPower = _newEarningPower.toUint96();
// Send tip to the receiver
SafeERC20.safeTransfer(REWARD_TOKEN, _tipReceiver, _requestedTip);
deposit.scaledUnclaimedRewardCheckpoint =
deposit.scaledUnclaimedRewardCheckpoint - (_requestedTip * SCALE_FACTOR);
}
Manual Review
Need to add any checking for sender.