`StakingRewardsManager::topUp(...)` Misallocates Funds to `StakingRewards` Contracts
The `StakingRewardsManager::topUp(...)` contract exhibits an issue where the specified `StakingRewards` contracts are not topped up at the correct indices, resulting in an incorrect distribution to different contracts.\\nThe `StakingRewardsManager::topUp(...)` function is designed to top up multiple `StakingRewards` contracts simultaneously by taking the indices of the contract's addresses in the `StakingRewardsManager::stakingContracts` array. However, the flaw lies in the distribution process:\\n```\\n    function topUp(\\n        address source,\\n        uint256[] memory indices\\n    ) external onlyRole(EXECUTOR_ROLE) {\\n        for (uint i = 0; i < indices.length; i++) {\\n            // get staking contract and config\\n            StakingRewards staking = stakingContracts[i];\\n            StakingConfig memory config = stakingConfigs[staking];\\n\\n            // will revert if block.timestamp <= periodFinish\\n            staking.setRewardsDuration(config.rewardsDuration);\\n\\n            // pull tokens from owner of this contract to fund the staking contract\\n            rewardToken.transferFrom(\\n                source,\\n                address(staking),\\n                config.rewardAmount\\n            );\\n\\n            // start periods\\n            staking.notifyRewardAmount(config.rewardAmount);\\n\\n            emit ToppedUp(staking, config);\\n        }\\n    }\\n```\\n\\nGitHub: [254-278]\\nThe rewards are not appropriately distributed to the `StakingRewards` contracts at the specified indices. Instead, they are transferred to the contracts at the loop indices. For instance, if intending to top up contracts at indices `[1, 2]`, the actual top-up occurs at indices `[0, 1]`.
It is recommended to do the following changes:\\n```\\n    function topUp(\\n        address source,\\n        uint256[] memory indices\\n    ) external onlyRole(EXECUTOR_ROLE) {\\n        for (uint i = 0; i < indices.length; i// Add the line below\\n// Add the line below\\n) {\\n            // get staking contract and config\\n// Remove the line below\\n            StakingRewards staking = stakingContracts[i];\\n// Add the line below\\n           StakingRewards staking = stakingContracts[indices[i]];\\n            StakingConfig memory config = stakingConfigs[staking];\\n\\n            // will revert if block.timestamp <= periodFinish\\n            staking.setRewardsDuration(config.rewardsDuration);\\n\\n            // pull tokens from owner of this contract to fund the staking contract\\n            rewardToken.transferFrom(\\n                source,\\n                address(staking),\\n                config.rewardAmount\\n            );\\n\\n            // start periods\\n            staking.notifyRewardAmount(config.rewardAmount);\\n\\n            emit ToppedUp(staking, config);\\n        }\\n    }\\n```\\n
The consequence of this vulnerability is that rewards will be distributed to the incorrect staking contract, leading to potential misallocation and unintended outcomes
```\\n    function topUp(\\n        address source,\\n        uint256[] memory indices\\n    ) external onlyRole(EXECUTOR_ROLE) {\\n        for (uint i = 0; i < indices.length; i++) {\\n            // get staking contract and config\\n            StakingRewards staking = stakingContracts[i];\\n            StakingConfig memory config = stakingConfigs[staking];\\n\\n            // will revert if block.timestamp <= periodFinish\\n            staking.setRewardsDuration(config.rewardsDuration);\\n\\n            // pull tokens from owner of this contract to fund the staking contract\\n            rewardToken.transferFrom(\\n                source,\\n                address(staking),\\n                config.rewardAmount\\n            );\\n\\n            // start periods\\n            staking.notifyRewardAmount(config.rewardAmount);\\n\\n            emit ToppedUp(staking, config);\\n        }\\n    }\\n```\\n