code-423n4 / 2022-06-canto-v2-findings

0 stars 0 forks source link

Gas Optimizations #156

Open code423n4 opened 2 years ago

code423n4 commented 2 years ago

1. !=0 instead of >0 for UINT

0 is less efficient than != 0 for unsigned integers (with proof) != 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: https://twitter.com/gzeon/status/1485428085885640706

Instances

https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-core.sol#L256 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-core.sol#L275 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-core.sol#L289 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-core.sol#L306 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-core.sol#L468

https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-periphery.sol#L122 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-periphery.sol#L123 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-periphery.sol#L474 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-periphery.sol#L481

//actual codes which shows the use.

lending-market-v2/contracts/Stableswap/BaseV1-core.sol:
  256:         require(liquidity > 0, 'ILM'); // BaseV1: INSUFFICIENT_LIQUIDITY_MINTED
  275:         require(amount0 > 0 && amount1 > 0, 'ILB'); // BaseV1: INSUFFICIENT_LIQUIDITY_BURNED
  289:         require(amount0Out > 0 || amount1Out > 0, 'IOA'); // BaseV1: INSUFFICIENT_OUTPUT_AMOUNT
  306:         require(amount0In > 0 || amount1In > 0, 'IIA'); // BaseV1: INSUFFICIENT_INPUT_AMOUNT
  468:         require(token.code.length > 0);

lending-market-v2/contracts/Stableswap/BaseV1-periphery.sol:
  122:         require(amountA > 0, "BaseV1Router: INSUFFICIENT_AMOUNT");
  123:         require(reserveA > 0 && reserveB > 0, "BaseV1Router: INSUFFICIENT_LIQUIDITY");
  474:         require(token.code.length > 0);
  481:         require(token.code.length > 0, "token code length failure");

Reference:

https://twitter.com/gzeon/status/1485428085885640706

Remediation:

I suggest changing > 0 with != 0. Also, please enable the Optimizer.


2. Variables: 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.

We can use uint number; instead of uint number = 0;

Instances

//Links to githubfile https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Governance/Comp.sol#L207 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-periphery.sol#L176 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-core.sol#L48 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-core.sol#L72 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-core.sol#L226 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Stableswap/BaseV1-core.sol#L22

//actual codes which shows the use

lending-market-v2/contracts/Governance/Comp.sol:207:        uint32 lower = 0;
lending-market-v2/contracts/Stableswap/BaseV1-periphery.sol:176:        uint _totalSupply = 0;
lending-market-v2/contracts/Stableswap/BaseV1-core.sol:48:    uint public totalSupply = 0;
lending-market-v2/contracts/Stableswap/BaseV1-core.sol:72:    uint constant periodSize = 0;
lending-market-v2/contracts/Stableswap/BaseV1-core.sol:226:        uint nextIndex = 0;
lending-market-v2/contracts/Stableswap/BaseV1-core.sol:22

Recommendation:

I suggest removing explicit initializations for default values.


3. Preincrement Costs less gas(++i) as compared to postincrement(i++)

++i costs less gas as compared to i++ for unsigned integer, as per-increment is cheaper(its about 5 gas per iteration cheaper) i++ increments i and returns initial value of i. Which means uint i = 1; i++; // ==1 but i ==2 But ++i returns the actual incremented value: uint i = 1; ++i; // ==2 and i ==2 , no need for temporary variable here In the first case, the compiler has create a temporary variable (when used) for returning 1 instead of 2.

Instances:

//Links to githubfile https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Governance/GovernorAlpha.sol#L152 https://github.com/Plex-Engineer/lending-market-v2/blob/main/contracts/Governance/GovernorAlpha.sol#L157 https://github.com/Plex-Engineer/lending-market-v2/blob/ea5840de72eab58bec837bb51986ac73712fcfde/contracts/Governance/Comp.sol#L167

//actual codes which shows the use

lending-market-v2/contracts/Governance/GovernorAlpha.sol: 152:     proposalCount++;
lending-market-v2/tests/Contracts/ComptrollerHarness.sol: 157:                 n++;
lending-market-v2/contracts/Governance/Comp.sol: 167:     require(nonce == nonces[signatory]++, "Comp::delegateBySig: invalid nonce");

Reference:

https://www.reddit.com/r/ethdev/comments/tcwspw/i_vs_i_gas_efficiency/

Remediation:

Use Preincrement(++i) instead of Postincrement(i++) in code.

GalloDaSballo commented 2 years ago

Less than 100 gas saved