Skip to content

Latest commit

 

History

History
231 lines (140 loc) · 14.4 KB

ReyAdmirado-G.md

File metadata and controls

231 lines (140 loc) · 14.4 KB

GAS

issue
1 Structs can be packed into fewer storage slots
2 expressions for constant values such as a call to keccak256(), should use immutable rather than constant
3 state var is defined but not used anywhere but
4 <x> += <y> costs more gas than <x> = <x> + <y> for state variables
5 not using the named return variables when a function returns, wastes deployment gas
6 can make the variable outside the loop to save gas
7 splitting require() statements that use && saves gas
8 require() or revert() statements that check input arguments should be at the top of the function
9 require() is repeated so it wastes has due to being checked again
10 use a more recent version of solidity
11 using calldata instead of memory for read-only arguments in external functions saves gas
12 internal functions only called once can be inlined to save gas
13 Multiple address/ID mappings can be combined into a single mapping of an address/ID to a struct
14 abi.encode() is less efficient than abi.encodepacked()
15 usage of uint/int smaller than 32 bytes (256 bits) incurs overhead
16 public functions not called by the contract should be declared external instead
17 emit can be optimized

1. Structs can be packed into fewer storage slots

Each slot saved can avoid an extra Gsset (20000 gas) for the first setting of the struct. Subsequent reads as well as writes have smaller gas savings

zkPorterIsAvailable can be put after or before one of the address variables to make the struct smaller and save gas

2. expressions for constant values such as a call to keccak256(), should use immutable rather than constant

3. state var is defined but not used anywhere but

even if they are for readability, consider making them comments instead

4. <x> += <y> costs more gas than <x> = <x> + <y> for state variables

Using the addition operator instead of plus-equals saves gas

here ++s.diamondCutStorage.currentProposalId would be even cheaper

5. not using the named return variables when a function returns, wastes deployment gas

6. can make the variable outside the loop to save gas

logSender

priorityOp

currentBlockCommitment

facetAddr

facetToSelectors

hashedBytecode

7. splitting require() statements that use && saves gas

this will have a large deployment gas cost but with enough runtime calls the split require version will be 3 gas cheaper

8. require() or revert() statements that check input arguments should be at the top of the function

Checks that involve constants should come before checks that involve state variables, function calls, and calculations. By doing these checks first, the function is able to revert before wasting a Gcoldsload (2100 gas*) in a function that may ultimately revert in the unhappy case.

bring this require before the 2 requires before it because of possible gas saves

9. require() is repeated so it wastes has due to being checked again

first part of the require() is being repeated so under no circumstances it will happen

10. use a more recent version of solidity

Use a solidity version of at least 0.8.2 to get compiler automatic inlining Use a solidity version of at least 0.8.3 to get better struct packing and cheaper multiple storage reads Use a solidity version of at least 0.8.4 to get custom errors, which are cheaper at deployment than revert()/require() strings Use a solidity version of at least 0.8.10 to have external calls skip contract existence checks if the external call has a return value Use a solidity version of at least 0.8.12 to get string.concat() to be used instead of abi.encodePacked(,) Use a solidity version of at least 0.8.13 to get the ability to use using for with a list of free functions

11. using calldata instead of memory for read-only arguments in external functions saves gas

When a function with a memory array is called externally, the abi.decode() step has to use a for-loop to copy each index of the calldata to the memory index. Each iteration of this for-loop costs at least 60 gas (i.e. 60 * <mem_array>.length). Using calldata directly, obliviates the need for such a loop in the contract code and runtime execution.

_lastCommittedBlockData

_log

12. internal functions only called once can be inlined to save gas

Not inlining costs 20 to 40 gas because of two extra JUMP instructions and additional stack operations needed for function calls.

_collectOperationsFromPriorityQueue

_executeOneBlock

_getBlockProofPublicInput

_verifyRecursivePartOfProof

_maxU256

_createBlockCommitment

_blockPassThroughData

_blockMetaParameters

_blockAuxilaryOutput

_L2MessageToLog

_requestL2Transaction

_writePriorityOp

_hashFactoryDeps

_depositFunds

_getDepositL2Calldata

_getERC20Getters

_parseL2WithdrawalMessage

13. Multiple address/ID mappings can be combined into a single mapping of an address/ID to a struct

if both fields are accessed in the same function, can save ~42 gas per access due to not having to recalculate the key’s keccak256 hash (Gkeccak256 - 30 gas) and that calculation’s associated stack operations.

14. abi.encode() is less efficient than abi.encodepacked()

15. usage of uint/int smaller than 32 bytes (256 bits) incurs overhead

When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size. Each operation involving a uint8 costs an extra 22-28 gas (depending on whether the other operand is also a variable of type uint8) as compared to ones involving uint256, due to the compiler having to clear the higher bits of the memory word before operating on the uint8, as well as the associated stack operations of doing so. Use a larger size then downcast where needed https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html Use a larger size then downcast where needed

16. 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.

l2TokenAddress

17. emit can be optimized

use newTotalBlocksCommitted instead of s.totalBlocksCommitted