An array’s length should be cached to save gas in for-loops
Reading array length at each iteration of the loop takes 6 gas (3 for mload and 3 to place memory_offset) in the stack.
Caching the array length in the stack saves around 3 gas per iteration.
Here, I suggest storing the array’s length in a variable before the for-loop, and use it instead:
Instances:
contracts/RewardHandler.sol:42: for (uint256 i; i < pools.length; i = i.uncheckedInc()) {
contracts/access/RoleManager.sol:82: for (uint256 i; i < roles.length; i = i.uncheckedInc()) {
contracts/testing/MockFeeBurner.sol:27: for (uint256 i; i < tokens.length; i++) {
contracts/zaps/PoolMigrationZap.sol:22: for (uint256 i; i < newPools.length; ++i) {
contracts/zaps/PoolMigrationZap.sol:39: for (uint256 i; i < oldPoolAddresses.length; ) {
contracts/tokenomics/VestedEscrow.sol:94: for (uint256 i; i < amounts.length; i = i.uncheckedInc()) {
contracts/tokenomics/FeeBurner.sol:56: for (uint256 i; i < tokens_.length; i = i.uncheckedInc()) {
contracts/tokenomics/InflationManager.sol:116: for (uint256 i; i < stakerVaults.length; i = i.uncheckedInc()) {
contracts/StakerVault.sol:259: for (uint256 i; i < actions.length; i = i.uncheckedInc()) {
contracts/actions/topup/TopUpKeeperHelper.sol:45: for (uint256 i; i < users.length; i = i.uncheckedInc()) {
contracts/actions/topup/TopUpKeeperHelper.sol:48: for (uint256 j; j < positions.length; j = j.uncheckedInc()) {
contracts/actions/topup/TopUpKeeperHelper.sol:74: for (uint256 i; i < keys.length; i = i.uncheckedInc()) {
contracts/actions/topup/TopUpAction.sol:191: for (uint256 i; i < protocols.length; i = i.uncheckedInc()) {
An array’s length should be cached to save gas in for-loops
Reading array length at each iteration of the loop takes 6 gas (3 for mload and 3 to place memory_offset) in the stack.
Caching the array length in the stack saves around 3 gas per iteration.
Here, I suggest storing the array’s length in a variable before the for-loop, and use it instead:
Instances:
contracts/RewardHandler.sol:42: for (uint256 i; i < pools.length; i = i.uncheckedInc()) { contracts/access/RoleManager.sol:82: for (uint256 i; i < roles.length; i = i.uncheckedInc()) { contracts/testing/MockFeeBurner.sol:27: for (uint256 i; i < tokens.length; i++) { contracts/zaps/PoolMigrationZap.sol:22: for (uint256 i; i < newPools.length; ++i) { contracts/zaps/PoolMigrationZap.sol:39: for (uint256 i; i < oldPoolAddresses.length; ) { contracts/tokenomics/VestedEscrow.sol:94: for (uint256 i; i < amounts.length; i = i.uncheckedInc()) { contracts/tokenomics/FeeBurner.sol:56: for (uint256 i; i < tokens_.length; i = i.uncheckedInc()) { contracts/tokenomics/InflationManager.sol:116: for (uint256 i; i < stakerVaults.length; i = i.uncheckedInc()) { contracts/StakerVault.sol:259: for (uint256 i; i < actions.length; i = i.uncheckedInc()) { contracts/actions/topup/TopUpKeeperHelper.sol:45: for (uint256 i; i < users.length; i = i.uncheckedInc()) { contracts/actions/topup/TopUpKeeperHelper.sol:48: for (uint256 j; j < positions.length; j = j.uncheckedInc()) { contracts/actions/topup/TopUpKeeperHelper.sol:74: for (uint256 i; i < keys.length; i = i.uncheckedInc()) { contracts/actions/topup/TopUpAction.sol:191: for (uint256 i; i < protocols.length; i = i.uncheckedInc()) {
Recomendation:
Cache teh array's length in for-loops