code-423n4 / 2022-10-inverse-findings

0 stars 0 forks source link

Gas Optimizations #592

Open code423n4 opened 1 year ago

code423n4 commented 1 year ago

Summary

Total: 112 instances in 8 issues


G-01 Multiple address mappings can be combined into a single mapping of an address to a struct, where appropriate

Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot.

14 instances in 3 files:

DBR.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L19 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L20 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L23 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L24 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L25 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L26 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L27 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L28

Market.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L57 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L58 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L59

Oracle.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Oracle.sol#L25 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Oracle.sol#L26 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Oracle.sol#L27

G-02 State variables only set in the constructor should be declared immutable

Avoids a Gsset (20000 gas) in the constructor, and replaces each Gwarmacces (100 gas) with a PUSH32 (3 gas)

2 instances in 1 file:

DBR.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L11 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L12

G-03 State variables can be packed into fewer storage slots

Solidity contracts have contiguous 32 bytes (256 bits) slots used in storage. By arranging the variables, it is possible to minimize the number of slots used within a contract’s storage and therefore reduce deployment costs. address type variables are each of 20 bytes size (way less than 32 bytes). However, they here take up a whole 32 bytes slot (they are contiguous). As bool type variables are of size 1 byte, there’s a slot here that can get saved by moving them closer to an address

2 instances in 2 files:

DBR.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L24-L25

Market.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L52-L53

G-04 += costs more gas than = + for state variables

15 instances in 3 files:

DBR.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L174 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L198 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L288 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L289 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L304 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L332 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L360 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L362

Fed.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Fed.sol#L91 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Fed.sol#L92

Market.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L395 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L397 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L565 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L568 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L598

G-05 Splitting require() statements that use && saves gas

Instead of using the && operator in a single require statement to check multiple conditions, I suggest using multiple require statements with 1 condition per require statement (saving 3 gas per &).

7 instances in 1 file:

Market.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L75 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L162 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L173 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L184 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L195 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L448 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L512

G-06 Public functions to external

Public functions not called by the contract should be declared external instead. Contracts are allowed to override their parents’ functions and change the visibility from external to public and can save gas by doing so. https://docs.soliditylang.org/en/latest/contracts.html#function-overriding

52 instances in 8 files:

BorrowController.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/BorrowController.sol#L26 https://github.com/code-423n4/2022-10-inverse/blob/main/src/BorrowController.sol#L32 https://github.com/code-423n4/2022-10-inverse/blob/main/src/BorrowController.sol#L38 https://github.com/code-423n4/2022-10-inverse/blob/main/src/BorrowController.sol#L46

DBR.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L53 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L62 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L70 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L81 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L90 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L99 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L109 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L120 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L133 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L146 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L223 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L258 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L300 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L313 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L325

Market.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L118 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L124 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L130 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L136 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L142 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L149 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L161 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L172 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L183 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L194

Fed.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Fed.sol#L48 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Fed.sol#L57 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Fed.sol#L66 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Fed.sol#L75 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Fed.sol#L86 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Fed.sol#L103 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Fed.sol#L120 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Fed.sol#L131

Oracle.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Oracle.sol#L44 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Oracle.sol#L53 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Oracle.sol#L66

GovTokenEscrow.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/GovTokenEscrow.sol#L30 https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/GovTokenEscrow.sol#L43 https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/GovTokenEscrow.sol#L52 https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/GovTokenEscrow.sol#L66

INVEscrow.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/INVEscrow.sol#L44 https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/INVEscrow.sol#L59 https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/INVEscrow.sol#L70 https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/INVEscrow.sol#L79 https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/INVEscrow.sol#L90

SimpleERC20Escrow.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/SimpleERC20Escrow.sol#L25 https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/SimpleERC20Escrow.sol#L36 https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/SimpleERC20Escrow.sol#L45

G-07 Use simple comparison in trinary logic / in if statement

The comparison operators >= and <= use more gas than >, <, or ==. Replacing the >= and ≤ operators with a comparison operator that has an opcode in the EVM saves gas.

Recommended Mitigation Steps: Replace the comparison operator and reverse the logic to save gas using the suggestions above.

15 instances in 3 files:

DBR.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L171 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L195 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L224 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L329 https://github.com/code-423n4/2022-10-inverse/blob/main/src/DBR.sol#L373

Market.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L396 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L423 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L462 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L487 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L533 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L562 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L567 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L582 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L607

Fed.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Fed.sol#L123

G-08 Amounts should be checked for 0 before calling a transfer

Checking non-zero transfer values can avoid an expensive external call and save gas. While this is done at some places, it’s not consistently done in the solution.

Recommended Mitigation Steps: I suggest adding a non-zero-value before calling a transfer.

6 instances in 2 files:

Market.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L205 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L399 https://github.com/code-423n4/2022-10-inverse/blob/main/src/Market.sol#L570

Fed.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/Fed.sol#L135

INVEscrow.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/INVEscrow.sol#L63

SimpleERC20Escrow.sol https://github.com/code-423n4/2022-10-inverse/blob/main/src/escrows/SimpleERC20Escrow.sol#L38

c4-judge commented 1 year ago

0xean marked the issue as grade-b