The logic in _updateStrategyRewards
may not need to update all the strategies
The _updateStrategyRewards
function is called whenever the fees in the PolygonStrategy are changed in order to call into the staking pool to distribute rewards at the old fee configuration first:
function _updateStrategyRewards() internal {
address[] memory strategies = stakingPool.getStrategies();
uint256[] memory strategyIdxs = new uint256[](strategies.length);
for (uint256 i = 0; i < strategies.length; ++i) {
strategyIdxs[i] = i;
}
stakingPool.updateStrategyRewards(strategyIdxs, "");
}
The updateStrategyRewards
function in the StakingPool contract then calls updateDeposits
on the PolygonStrategy contract:
function updateStrategyRewards(uint256[] memory _strategyIdxs, bytes memory _data) external {
if (msg.sender != rebaseController && !_strategyExists(msg.sender))
revert SenderNotAuthorized();
_updateStrategyRewards(_strategyIdxs, _data);
}
// [...]
function _updateStrategyRewards(uint256[] memory _strategyIdxs, bytes memory _data) private {
// [...]
// sum up rewards and fees across strategies
for (uint256 i = 0; i < _strategyIdxs.length; ++i) {
IStrategy strategy = IStrategy(strategies[_strategyIdxs[i]]);
(
int256 depositChange,
address[] memory strategyReceivers,
uint256[] memory strategyFeeAmounts
) = strategy.updateDeposits(_data);
totalRewards += depositChange;
// [...]
}
// [...]
}
It is unclear whether it is valid to call updateStrategyRewards
with a subset of the strategies, but since the fees configured in the PolygonStrategy only apply to itself, it is likely that only the caller PolygonStrategy needs to actually be updated, because no other contract will behave differently from the newly set fees.
If so, we recommend determining the index of the current strategy and only calling updateStrategyRewards
on itself, to save gas and reduce the attack surface for timing or sandwiching the updateDeposits
calls on other strategies.