Submitted by hansfriese, also found by unforgiven, wagmi, betweenETHlines, Allarious, HollaDieWaldfee, and chaduke
contracts/contract/MinipoolManager.sol#L374
Node operators can manipulate the assigned high water to be higher than the actual.
The protocol rewards node operators according to the AVAXAssignedHighWater that is the maximum amount assigned to the specific staker during the reward cycle.
In the function MinipoolManager.recordStakingStart(), the AVAXAssignedHighWater is updated as below.
In the line #373, if the current assigned AVAX is greater than the owners AVAXAssignedHighWater, it is increased by avaxLiquidStakerAmt.
But this is supposed to be updated to staking.getAVAXAssigned(owner) rather than being increased by the amount.
Example:
The node operator creates a minipool with 1000AVAX via createMinipool(nodeID, 2 weeks, delegationFee, 1000*1e18).
On creation, the assigned AVAX for the operator will be 1000AVAX.
If the Rialtor calls recordStakingStart(), AVAXAssignedHighWater will be updated to 1000AVAX.
After the validation finishes, the operator creates another minipool with 1500AVAX this time. Then on recordStakingStart(), AVAXAssignedHighWater will be updated to 2500AVAX by increasing 1500AVAX because the current assigned AVAX is 1500AVAX which is higher than the current AVAXAssignedHighWater=1000AVAX.
This is wrong because the actual highest assigned amount is 1500AVAX.
Note that AVAXAssignedHighWater is reset only through the function calculateAndDistributeRewards which can be called after RewardsCycleSeconds=28 days.
Call staking.resetAVAXAssignedHighWater(owner) instead of calling increaseAVAXAssignedHighWater().
emersoncloud (GoGoPool) confirmed
Franfran (warden) commented:
0xju1ie (GoGoPool) commented:
Alex the Entreprenerd (judge) commented:
emersoncloud (GoGoPool) mitigated:
Status: Mitigation confirmed with comments. Full details in report from RaymondFam.
