code-423n4 / 2022-06-notional-coop-findings

1 stars 1 forks source link

Gas Optimizations #185

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

1. Cache array length in loops instead of computing length in every iteration

While looping through array, the array length can be cached to save gas instead of computing length in each array iteration.

for eg.

uint256 len = modules.length;
for(uint256 i = 0; i < len; i++) {
  ...
}

in index-coop-notional-trade-module/contracts/protocol/modules/v1/NotionalTradeModule.sol:

238:        for(uint256 i = 0; i < modules.length; i++) {
254:        for(uint256 i = 0; i < modules.length; i++) { 

2. Prefix increment (++i) is cheaper than postfix increment (i++)

Using prefix increment is saves small amount of gas than postfix increment because it returns the updated value hence doesn't requires to store intermediate value. This can be more significant in loops where this operation is done multiple times.

for eg.

// before
for(uint256 i = 0; i < len; i++) {
  ...
}

// Replace with
for(uint256 i = 0; i < len; ++i) {
  ...
}

in notional-wrapped-fcash/contracts/lib/DateTime.sol

63:        for (uint256 i = 1; i <= maxMarketIndex; i++) {

in index-coop-notional-trade-module/contracts/protocol/modules/v1/NotionalTradeModule.sol

238:        for(uint256 i = 0; i < modules.length; i++) {
254:        for(uint256 i = 0; i < modules.length; i++) {
393:        for(uint256 i = 0; i < positionsLength; i++) {
605:        for(uint256 i = 0; i < positionsLength; i++) {
610:                    numFCashPositions++;
618:        for(uint256 i = 0; i < positionsLength; i++) {
623:                    j++;

3. 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. This can be used to save gas.

for eg.


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

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

The notional-wrapped-fcash module uses solidity 0.8 where this can be used.

more details can be found here

4. !=0 is more gas efficient than >0 for uints

5. Use of revert string > 32 bytes