code-423n4 / 2022-06-infinity-findings

4 stars 0 forks source link

Gas Optimizations #329

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

Gas optimization

1. Optimize _getCurrentPric can save few hundred gas on average

A few optimisation can be applied to this function:

Example Implementation:

// assuming PRECISION is declared as constant

function _getCurrentPrice(OrderTypes.MakerOrder calldata order) internal view returns (uint256) {
    (uint256 startPrice, uint256 endPrice) = (order.constraints[1], order.constraints[2]);

    // return early to optimize fixed price trades
    if (startPrice == endPrice) return startPrice;

    uint256 duration = order.constraints[4] - order.constraints[3];
    if (duration == 0) return startPrice;

    uint256 elapsedTime = block.timestamp - order.constraints[3];

    unchecked {
      // elapsedTime * PRECISION will not overflow
      uint256 portionBps = elapsedTime > duration ? PRECISION : ((elapsedTime * PRECISION) / duration);
      if (startPrice > endPrice) {

        // startPrice - endPrice will not underflow
        uint256 priceDiff = (startPrice - endPrice) * portionBps / PRECISION; 
        return startPrice - priceDiff;
      } else {
        // endPrice - startPrice will not underflow
        uint256 priceDiff = (endPrice - startPrice) * portionBps / PRECISION;  
        return startPrice + priceDiff;
      }  
    }
  }

This saves average of 500 gas for takeOrders , and 1500 gas for matchOneToManyOrders

more gas can be solved if we update the same function in OrderBookComplication too.

2. Remove time check on OrderBookComplication

All orders are already checked if constraints[3] < now && constraint[4] > now in InfinityExchange, so relevent checks can be removed from the Complication layer to save gas.

Gas saving: 2000 ~ 50000. (benchmark on passing tests)

3. remove safeTransfe on WETH

safeERC20 library are designed to be used on non-standard ERC20 tokens. Removing the use of the library from well tested weth token shouldn’t be consider risky, and save you some gas.

4. Pack variables in InfinityToken

packing the following 2 variables into 1 storage slot can save gas when trying to read and write these 2 variables:currentEpoch previousEpochTimestamp.

Gas saving

5. currentEpochTimestamp should be used as immutable

the variable currentEpochTimestamp is not updated outside of the constructor, defining it as immutable can save gas on SLOAD.

Gas saving

nneverlander commented 2 years ago

Thank you.