Open c4-bot-1 opened 7 months ago
0xean marked the issue as grade-b
Hi @0xean thanks for judging
I dont' know why my report has grade b , I suggest a lot of gas optimization techniques, That are similar to the grade a reports and with more unique ones,Please kindly review my report again
issue | instance | |
---|---|---|
[G‑01] | Use calldata instead of memory for function arguments that do not get mutated | 70 |
[G‑02] | Use assembly to check for address(0) |
55 |
[G‑03] | State variables that are used multiple times in a function should be cached in stack variables | 14 |
[G‑04] | Can Make The Variable Outside The Loop To Save Gas | 17 |
[G‑05] | Use assembly to write address storage values | 17 |
[G‑06] | Use nested if statements instead of && | 20 |
[G‑07] | Multiple Address/id Mappings Can Be Combined Into A Single Mapping Of An Address/id To A Struct, Where Appropriate | 5 |
[G‑08] | internal functions not called by the contract should be removed to save deployment gas |
13 |
[G‑09] | Amounts should be checked for 0 before calling a transfer | 6 |
[G‑10] | Avoid updating storage when the value hasn't changed | 20 |
[G‑11] | Do not calculate constants | 2 |
[G‑12] | State variables can be packed into fewer storage slots | 2 |
[G‑13] | With assembly, .call (bool success) transfer can be done gas-optimized | 1 |
[G‑14] | Use hardcode address instead address(this) | 31 |
[G‑15] | Structs can be packed to use fewer storage slots | 4 |
[G‑16] | use Mappings Instead of Arrays | 1 |
[G‑17] | Use constants instead of type(uintx).max | 4 |
[G‑18] | Duplicated require()/if() checks should be refactored to a modifier or function | 3 |
[G‑19] | Not using the named return variables when a function returns, wastes deployment gas | 10 |
[G‑20] | Using storage instead of memory for structs/arrays saves gas |
2 |
[G‑21] | Multiple accesses of a mapping/array should use a local variable cache | 45 |
[G‑22] | internal functions only called once can be inlined to save gas | 23 |
[G‑23] | bytes constants are more eficient than string constans | 5 |
[G‑24] | Use assembly to hash instead of solidity | 28 |
[G‑25] | Stack variable used as a cheaper cache for a state variable is only used once | 1 |
[G‑26] | Use assembly to emit an event | 55 |
[G‑27] | Using a positive conditional flow to save a NOT opcode | 2 |
[G‑28] | Avoid contract existence checks by using low level calls | 25 |
[G‑29] | Use do while loops instead of for loops | 5 |
[G‑30] | Splitting require() statements that use && saves gas | 3 |
[G‑31] | Do not shrink Variables | 2 |
[G‑32] | Constructors can be marked payable | 3 |
[G‑33] | The result of function calls should be cached rather than re-calling the function | 33 |
[G‑34] | Empty Blocks Should Be Removed Or Emit Something | 4 |
[G‑35] | Use custom errors rather than revert()/require() strings to save gas | 35 |
[G‑36] | State variables only set in the constructor should be declared immutable | 2 |
[G‑37] | Caching global variables is more expensive than using the actual variable (use msg.sender instead of caching it) | 2 |
[G‑38] | Use local variables for emitting | 6 |
[G‑39] | Use selfbalance() instead of address(this).balance | 6 |
[G‑40] | Private functions used once can be inlined | 35 |
[G‑41] | State variable read in a loop | 15 |
[G‑42] | Use struct dot notation to avoid memory allocation | 4 |
[G‑43] | Use assembly in place of abi.decode to extract calldata values more efficiently | 16 |
[G‑44] | Cache external calls outside of loop to avoid re-calling function on each iteration | 6 |
[G‑45] | Structs can be modified to fit in fewer storage slots | 1 |
[G‑46] | Use assembly to validate msg.sender | 10 |
[G‑47] | Pre-increment and pre-decrement are cheaper thanĀ +1 ,-1 | 5 |
[G‑48] | Storage re-read via storage pointer | 4 |
[G‑49] | Initializer can be marked payable | 25 |
[G‑50] | Use inline assembly to access the chain ID | 37 |
[G‑51] | Consider using OZ EnumerateSet in place of nested mappings | 7 |
[G‑52] | Instead of counting down in for statements, count up | 25 |
[G‑53] | require() or revert() statements that check input arguments should be at the top of the function | 4 |
[G‑54] | Structs should group like types together to save gas | 12 |
[G‑55] | >= costs less gas than > |
1 |
[G‑56] | Usage of uints /ints smaller than 32 bytes (256 bits) incurs overhead |
16 |
[G‑57] | Emit Used In Loop | 3 |
[G‑58] | Require()/revert() Strings Longer Than 32 Bytes Cost Extra Gas | 1 |
[G‑59] | Using private rather than public for constants, saves gas |
2 |
[G‑60] | Functions guaranteed to revert when called by normal users can be marked payable |
2 |
[G‑61] | Superfluous event fields | 1 |
[G‑62] | Use assembly to perform efficient back-to-back calls | 2 |
[G‑63] | Delete variables that you don't need | 1 |
[G-01] Use calldata instead of memory for function arguments that do not get mutated
[G-02] Use assembly to check for address(0)
[G‑03] State variables that are used multiple times in a function should be cached in stack variables
[G-04] Can Make The Variable Outside The Loop To Save Gas
[G-05] Use assembly to write address storage values
[G-06] Use nested if statements instead of &&
[G-07] Multiple Address/id Mappings Can Be Combined Into A Single Mapping Of An Address/id To A Struct, Where Appropriate
[G-08] internal
functions not called by the contract should be removed to save deployment gas
[G-09] Amounts should be checked for 0 before calling a transfer
[G-10] Avoid updating storage when the value hasn't changed
[G-11] Do not calculate constants
[G-12] State variables can be packed into fewer storage slots
[G-13] With assembly, .call (bool success) transfer can be done gas-optimized
[G-14] Use hardcode address instead address(this)
[G-15] Structs can be packed to use fewer storage slots
[G-16] use Mappings Instead of Arrays
[G-17] Use constants instead of type(uintx).max
[G-18] Duplicated require()/if() checks should be refactored to a modifier or function
[G-19] Not using the named return variables when a function returns, wastes deployment gas
[G-20] Using storage instead of memory
for structs/arrays saves gas
[G‑21] Multiple accesses of a mapping/array should use a local variable cache
[G‑22] internal functions only called once can be inlined to save gas
[G-23] bytes constants are more eficient than string constans
[G-24] Use assembly to hash instead of solidity
[G-25] Stack variable used as a cheaper cache for a state variable is only used once
[G-26] Use assembly to emit an event
[G-27] Using a positive conditional flow to save a NOT opcode
uniqe
[G-28] Avoid contract existence checks by using low level calls
uniqe
[G-29] Use do while loops instead of for loops
[G-30] Splitting require() statements that use && saves gas
uniqe
[G-31] Do not shrink Variables
[G-32] Constructors can be marked payable
[G-33] The result of function calls should be cached rather than re-calling the function
[G-34] Empty Blocks Should Be Removed Or Emit Something
[G‑35] Use custom errors rather than revert()/require() strings to save gas note: these are instance missed from bots
[G‑36] State variables only set in the constructor should be declared immutable
[G-37] Caching global variables is more expensive than using the actual variable (use msg.sender instead of caching it)
[G-38] Use local variables for emitting
[G-39] Use selfbalance() instead of address(this).balance
[G-40] Private functions used once can be inlined
[G-41] State variable read in a loop
[G-42] Use struct dot notation to avoid memory allocation
[G-43] Use assembly in place of abi.decode to extract calldata values more efficiently
[G-44] Cache external calls outside of loop to avoid re-calling function on each iteration
[G-45] Structs can be modified to fit in fewer storage slots
[G‑46] Use assembly to validate msg.sender
[G-47] Pre-increment and pre-decrement are cheaper thanĀ +1 ,-1
[G-48] Storage re-read via storage pointer
[G-49] Initializer can be marked payable
[G‑50] Use inline assembly to access the chain ID
[G-51] Consider using OZ EnumerateSet in place of nested mappings
[G-52] Instead of counting down in for statements, count up
[G-53] require() or revert() statements that check input arguments should be at the top of the function
[G-54] Structs should group like types together to save gas
[G-55] >=
costs less gas than >
[G-56] Usage of uints
/ints
smaller than 32 bytes (256 bits) incurs overhead
[G-57] Emit Used In Loop
[G-58] Require()/revert() Strings Longer Than 32 Bytes Cost Extra Gas
[G-59] Using private
rather than public
for constants, saves gas
[G-60] Functions guaranteed to revert when called by normal users can be marked payable
Note: these insteance are missed from bots
[G-61] Superfluous event fields
[G-62] Use assembly to perform efficient back-to-back calls [G-63] Delete variables that you don't need
in the future would encourage you to quantify the gas savings in the report and ensure its fully de-duped against the bot findings.
Hi @0xean thanks for judging
Thank you for your review once again. Regarding the gas findings, I followed a specific approach. I used a checklist to manually examine each finding. Additionally, I checked the bot findings for any missed instances of the issues. In my report, I made sure to include a note in the description section to indicate the instances that were missed by the bot.
Note: In my report, I manually identified additional issues, but the ones I mentioned specifically stand out due to their significant cost implications
Here are the issues found by the bots but with incomplete instances. I thoroughly checked everything manually and identified these missed instances:
Furthermore, I discovered additional expensive issues in my report that were not only identified by me but also by other wardens. These issues are particularly costly to address. Despite being marked as grade-A reports, not all of them were thoroughly examined. In one report, these high-cost issues were notably overlooked, underscoring the importance of addressing such critical matters comprehensively.
Additionally, Some wardens might not have conducted a thorough examination of the complete codebase, resulting in the identification of only a limited number of instances for each issue. Conversely, in my report, I carefully reviewed the entire codebase.
This issue is costly, and they were not identified by other wardens. It's important to note that external calls can be particularly expensive, especially when they're used within a loop. By caching external calls outside of the loop, you can prevent the function from being recalled on each iteration, saving a significant amount of gas.
This issue also stands out as unique
0xean marked the issue as grade-a
See the markdown file with the details of this report here.