Comparisons: != is more efficient than > in require
!= 0 costs less gas compared to > 0 for unsigned integers in require statements with the optimizer enabled (6 gas)
Proof: While it may seem that > 0 is cheaper than !=, this is only true without the optimizer enabled and outside a require statement. If you enable the optimizer at 10k AND you're in a require statement, this will save gas. You can see this tweet for more proofs:
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.
Therefore, it’s possible to save a significant amount of gas especially when the length is significantly big.
Here, I suggest storing the array’s length in a variable before the for-loop, and use it instead:
Also Implemented on here:
File:InflationManager.sol line 96-100
uint256 length = liquidityPools.length;
for (uint256 i; i < length; i = i.uncheckedInc()) {
_removeKeeperGauge(address(liquidityPools[i]));
}
Using unchecked blocks to save gas
Solidity version 0.8+ comes with implicit overflow and underflow checks on unsigned integers. When an overflow or an underflow isn't possible (as an example, when a comparison is made before the arithmetic operation), some gas can be saved by using an unchecked block: see official docs
FINDINGS
Comparisons: != is more efficient than > in require
!= 0 costs less gas compared to > 0 for unsigned integers in require statements with the optimizer enabled (6 gas)
Proof: While it may seem that > 0 is cheaper than !=, this is only true without the optimizer enabled and outside a require statement. If you enable the optimizer at 10k AND you're in a require statement, this will save gas. You can see this tweet for more proofs:
I suggest changing > 0 with != 0 here:
File: BkdLocker.sol line 91
Since amount is a uint256, it means it's value can never be less than 0 so the test > 0 is essentially testing that amount is not equal to 0 a
Other Instances File: BkdLocker.sol line 92
File: BkdLocker.sol line 137
File: VestedEscrow.sol line 84
File: AmmGauge.sol line 104
File: AmmGauge.sol line 125
use shorter revert strings(less than 32 bytes) or use custom errors
File: Minter.sol line 150
Cache the length of arrays in 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. Therefore, it’s possible to save a significant amount of gas especially when the length is significantly big.
Here, I suggest storing the array’s length in a variable before the for-loop, and use it instead:
File:StakerVault.sol line 259
The line to modify:
Other Instance to change File: RewardHandler.sol line 35-55
The specific line to change here
File: PoolMigrationZap.sol line 22
Something similar to my propasal was implemented on this contract as shown in the function below. File:Controller.sol line 121-130
Note the array length was cached to numActions
Also Implemented on here: File:InflationManager.sol line 96-100
Using unchecked blocks to save gas
Solidity version 0.8+ comes with implicit overflow and underflow checks on unsigned integers. When an overflow or an underflow isn't possible (as an example, when a comparison is made before the arithmetic operation), some gas can be saved by using an unchecked block: see official docs
File: VestedEscrow.sol line 63
The above line cannot overflow due to the check on the line shown below File: VestedEscrow.sol line 58
In this contract we have a library that can aid in having unchecked arithmetics that is libraries/UncheckedMath.sol imported on line 21
With the help of this library we can modify our arithmetic to
A similar approach was implemented in the file below. File: StakerVault.sol lines 229-230
Other Instances to modify File: VestedEscrow.sol line 155
The above cannot underflow due to the check on line 152 which ensures that time is greater than startTime
This
uint256 elapsed = _time - startTime;
should be changed touint256 elapsed = _time.uncheckedSub(startTime);
File: StakerVault.sol line 124
The above line cannot underflow due the check on line 113
The checks ensures that balances[msg.sender] is greater or equal to amount therefore balances[msg.sender]-amount will never underflow.