Open code423n4 opened 2 years ago
This looks really good 10k gas seems a little exaggerated but I will review in detail
Math looks right, will reduce to 8000 gas as I have used heuristics for other reports.
Best submission this contest, well done!
Gas Optimizations
Gas savings are estimated using the gas report of existing
forge test --gas-report
tests (the sum of all deployment costs and the sum of the costs of calling all methods) and may vary depending on the implementation of the fix. I keep my version of the fix for each finding and can provide them if you need them. In this project, the optimizer is set on 500000 runs, so some of the common optimizations are useless or partially useless. Only cases that save gas with this configuration of optimizer are included in the report.storage
pointer to a structure is cheaper than copying each value of the structure intomemory
, same forarray
andmapping
Total: 21 instances over 6 issues
storage
pointer to a structure is cheaper than copying each value of the structure intomemory
, same forarray
andmapping
(5 instances)Deployment Gas Saved: 168 820 Method Call Gas Saved: 1 672
forge snapshot --diff
: 8 746 Gas SavedIt may not be obvious, but every time you copy a storage
struct
/array
/mapping
to amemory
variable, you are copying each member by reading it fromstorage
, which is expensive. And when you use thestorage
keyword, you are just storing a pointer to the storage, which is much cheaper. Exception: case when you need to read all or many members multiple times. In report included only cases that saved gasControversial (Not included in estimation):
Saved in deploy: 25433, but lost 100-300 gas per user
State variables can be packed into fewer storage slots (1 instances)
Deployment Gas Saved: 99 511
forge snapshot --diff
: 1 080 Gas SavedStorage:
Fix:
State variables should be cached in stack variables rather than re-reading them from storage (5 instances)
Deployment Gas Saved: 70 505 Method Call Gas Saved: 2 634
forge snapshot --diff
: 12 481 Gas SavedCaching of a state variable replaces each Gwarmaccess (100 gas) with a much cheaper stack read. Other less obvious fixes/optimizations include having local memory caches of state variable structs or having local caches of state variable contracts/addresses.
SLOADs are expensive (100 gas after the 1st one) compared to MLOADs/MSTOREs (3 gas each). Storage values read multiple times should instead be cached in memory the first time (costing 1 SLOAD) and then read from this cache to avoid multiple SLOADs.
function:
_settleAuction
:auction
cached in 169 but readed from storage in 172 function:_handleOutgoingTransfer
:IWETH(WETH)
can be cachedfunction proposalVotes: There is no need to copy
proposals[_proposalId]
to memory, because you reading every field exactly one timefunction
isReady
:timestamps[_proposalId]
can be cachedfunction
_isForFounder
: use storage pointer to founderfunction
_getItemImage
: complex expression can be cached as storage pointerUsing bools for storage incurs overhead (5 instances)
Deployment Gas Saved: 60 668 Avg. Method Call Gas Saved: 1 191
forge snapshot --diff
: 9 748 Gas SavedUse uint256(1) and uint256(2) for true/false to avoid a Gwarmaccess (100 gas) for the extra SLOAD, and to avoid Gsset (20000 gas) when changing from 'false' to 'true', after having been 'true' in the past
NOTE: in some cases, usually in structs, this optimization can cause significant user gas loss, these cases are intentionally excluded from the report
Storage variable is used when local exists (2 instances)
Deployment Gas Saved: 1 400 Method Call Gas Saved: 2 602
forge snapshot --diff
: 41 326 Gas Savedfunction:
_settleAuction
:auction
cached in 169 but readed from storage in 172src/governance/governor/Governor.sol
function
propose
:proposalThreshold()
cached in 123, but called again in 128Use named returns where appropriate (3 instances)
Deployment Gas Saved: 2 000 Method Call Gas Saved: 174
forge snapshot --diff
: 621 Gas SavedOverall Gas Saved
This is the result of merging all the fixes:
Deployment Gas Saved: 341 027 Method Call Gas Saved: 10 231
forge snapshot --diff
: 73 132 Gas Savedforge test --gas-report
: