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

4 stars 0 forks source link

Gas Optimizations #280

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

1. use encodepacked instead of encode to save gas

encode has padding which wastes gsa and packed puts less than bytes32 togther to save gas and dosnt pad which in return saves gas https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L107 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L1172-L1181

2. calculate the keccack hash off chain to save gas and just plug in the hash

https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L108-L110 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L1172-L1181 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/token/InfinityToken.sol#L24-L28

3. No need to explicitly initialize variables with default values

If a variable is not set/initialized, it is assumed to have the default value (0 for uint, false for bool, address(0) for address...). Explicitly initializing it with its default value is an anti-pattern and wastes gas. instances include: https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L148 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L200 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L219 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L272 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L308 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L349 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L1048 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L1086 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L1109 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L1190 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityOrderBookComplication.sol#L76 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityOrderBookComplication.sol#L82 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityOrderBookComplication.sol#L199 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityOrderBookComplication.sol#L214 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityOrderBookComplication.sol#L246-L247 make variable uninlize to save gas https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityOrderBookComplication.sol#L197 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityOrderBookComplication.sol#L289-L292 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityOrderBookComplication.sol#L318 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityOrderBookComplication.sol#L320

4 .Use Custom Errors instead of Revert Strings to save Gas

Custom errors from Solidity 0.8.4 are cheaper than revert strings (cheaper deployment cost and runtime cost when the revert condition is met) Source Custom Errors in Solidity: Starting from Solidity v0.8.4, there is a convenient and gas-efficient way to explain to users why an operation failed through the use of custom errors. Until now, you could already use strings to give more information about failures (e.g., revert("Insufficient funds.");), but they are rather expensive, especially when it comes to deploy cost, and it is difficult to use dynamic information in them. Custom errors are defined using the error statement, which can be used inside and outside of contracts (including interfaces and libraries). ex of instances include: https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/staking/InfinityStaker.sol#L68-L69 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/staking/InfinityStaker.sol#L91-L96 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L138-L139 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L150 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L155 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L183-L188 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L263-L264 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L310 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L313-L315 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L326 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L342 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L380-L381 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L621 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L649 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L684 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityOrderBookComplication.sol#L255

5 uint Var is anything greater or equal to zero saves gas to make the condition != 0 in require statement

https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L392 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/staking/InfinityStaker.sol#L193

reduce the size of error messages ( Long revert strings)

Shortening revert strings to fit in 32 bytes will decrease deployment time gas and will decrease runtime gas when the revert condition is met. Revert strings that are longer than 32 bytes require at least one additional mstore, along with additional overhead for computing memory offset, etc. 1 byte for character https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L395 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/staking/InfinityStaker.sol#L91-L96

use 1e4 instead of 10**4

10 **4 can be changed to 1e4 to avoid unnecessary arithmetic operation and save gas. https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityExchange.sol#L1161 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/core/InfinityOrderBookComplication.sol#L338https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/staking/InfinityStaker.sol#L238

use memory variables instead of storage to save gas on sload

userstakedAmounts[user][Duration.NONE].amount make it into a memory var to save 100 gas on each sload even though its warm it still more gas then memory https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/staking/InfinityStaker.sol#L156-L159 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/staking/InfinityStaker.sol#L234-L238

Mark functions as payable when users can't mistakenly send ETH

impact

Functions marked as payable are 24 gas cheaper than their counterpart (in non-payable functions, Solidity adds an extra check to ensure msg.value is zero). When users can't mistakenly send ETH to a function (as an example, when there's an onlyOwner modifier or alike), it is safe to mark it as payable

proof of concept

Functions with onlyOwner modifier that aren't payable yet: instances include: https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/staking/InfinityStaker.sol#L351 https://github.com/code-423n4/2022-06-infinity/blob/601e0e5498587f5b1ae33f345223c86526ae9ce1/contracts/staking/InfinityStaker.sol#L364