code-423n4 / 2022-05-backd-findings

0 stars 0 forks source link

Gas Optimizations #124

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

1. array length in loops can be cached instead of calculating in every iteration

The loop bounds are calculated with array.length which are calculated in every loop iterations which can result in high gas. The array length can be cached instead of calculating in every loop iteration to save gas.

// Before
for (uint i = 0; i < amounts.length; i++) {
}

// After
uint len = amounts.length;
for (uint i = 0; i < len; i++) {
}

The instances where this pattern can be applied is found as follows

> grep -rn './contracts/tokenomics' -e 'for.*[.]length'
./contracts/tokenomics/FeeBurner.sol:59:        for (uint256 i; i < tokens_.length; i = i.uncheckedInc()) {
./contracts/tokenomics/VestedEscrow.sol:94:        for (uint256 i; i < amounts.length; i = i.uncheckedInc()) {
./contracts/tokenomics/InflationManager.sol:119:        for (uint256 i; i < stakerVaults.length; i = i.uncheckedInc()) {

2. Use solidity custom errors to save gas

solidity 0.8.4 introduces custom errors which are cheaper than using revert strings in terms of gas Use the custom error patterns to reduce gas cost.

for eg.


  // Before
  require(condition, "Revert strings");

  // After
  error CustomError();
  if (!condition) {
    revert CustomError();
  }

more details can be found here

3. !=0 is cheaper than >0

> grep -rn "./contracts/tokenomics" -e "require(.* > 0"
./contracts/tokenomics/AmmConvexGauge.sol:158:        require(amount > 0, Error.INVALID_AMOUNT);
./contracts/tokenomics/AmmConvexGauge.sol:171:        require(amount > 0, Error.INVALID_AMOUNT);
./contracts/tokenomics/VestedEscrow.sol:84:        require(unallocatedSupply > 0, "No reward tokens in contract");
./contracts/tokenomics/KeeperGauge.sol:142:        require(totalClaimable > 0, Error.ZERO_TRANSFER_NOT_ALLOWED);
./contracts/tokenomics/AmmGauge.sol:111:        require(amount > 0, Error.INVALID_AMOUNT);
./contracts/tokenomics/AmmGauge.sol:136:        require(amount > 0, Error.INVALID_AMOUNT);
GalloDaSballo commented 2 years ago

1. array length in loops can be cached instead of calculating in every iteration

Would save 3 gas 3 * 3 = 9

2. Use solidity custom errors to save gas

In lack of POC I will not give points

!=0 is cheaper than >0

Will save 3 gas per instance, in Solidity < 0.8.13

3 * 6 = 18

Total Gas Saved 27