You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Gas savings are estimated using existing tests and may differ depending on the implementation of the fix. I keep my version of the fix for each finding and can provide them if you need.
Gas Optimizations
Issue
Instances
Estimated gas(deployments)
1
Use Custom Errors instead of Revert/Require Strings to save Gas
76
582064
2
Increment optimization
32
5388 / 23781 / 56517
3
Using bools for storage incurs overhead
7
50164
4
Call to an external contract should be cached.
1
23972
5
The same modifier can be combined into a library
5
8674
6
Loop length can be cached to save gas
2
4113
7
The variable is cached and used only once.
2
1738
8
It is more gas efficient to compare uint variables with != 0 than it is with > 0
10
1533
9
Splitting require() statements that use && saves gas
3
-
Total: 138 instances over 9 issues
Use Custom Errors instead of Revert/Require Strings to save Gas (76 instances)
Deployment gas saved: 582064
Solidity 0.8.4 introduced custom errors. They are more gas efficient than revert strings, when it comes to deploy cost as well as runtime cost when the revert condition is met. Use custom errors instead of revert strings for gas savings.
87for (uint256 i =0; i < _length; i++) {//@audit increment and inicialize
...
136for (uint256 i =0; i < _length; i++) {//@audit increment and inicialize
Important: this optimization affects the use of gas to call the method differently. Function call can become either cheaper or more expensive. Should be tested manually and analyzed according to which functions you consider more important.
Use uint256 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
55boolpublicoverride restrictedToAdmin; //@audit bool usage //16308 deploy gas
...
61mapping(address=>mapping(bytes32=>bool)) publicoverride approvedHashes; //@audit bool usage//4728 deploy gas
Call to an external contract should be cached.
Every call to an external contract costs a decent amount of gas. For optimization of gas usage, external call results should be cached if they are being used for more than one time.
Gas saved: 23972 deploy gas
419// Local variable for total cost allocated. For gas saving.420uint256 _totalAllocated = totalAllocated;
...
438elseif (totalLent - _totalAllocated >= _newCost - _taskCost) {
It is more gas efficient to compare variables with != 0 than it is with > 0. These two comparisons are equivalent when the compared variable is an unsigned integer.
Splitting require() statements that use && saves gas Important: While two separate checks provide gas savings, deployment requires more gas due to code size and string usage. I can recommend to use this assertion logic optimization with if() revert Error() model
Summary
Gas savings are estimated using existing tests and may differ depending on the implementation of the fix. I keep my version of the fix for each finding and can provide them if you need.
Gas Optimizations
Total: 138 instances over 9 issues
Use Custom Errors instead of Revert/Require Strings to save Gas (76 instances)
Deployment gas saved: 582064
Solidity 0.8.4 introduced custom errors. They are more gas efficient than revert strings, when it comes to deploy cost as well as runtime cost when the revert condition is met. Use custom errors instead of revert strings for gas savings.
Custom errors save ~50 gas each time they're hitby avoiding having to allocate and store the revert string.
Additional gas is saved due to the lack of defining string. https://blog.soliditylang.org/2021/04/21/custom-errors/#errors-in-depth
Increment optimization.
Using bools for storage incurs overhead
Deployment gas saved: 50164
Important: this optimization affects the use of gas to call the method differently. Function call can become either cheaper or more expensive. Should be tested manually and analyzed according to which functions you consider more important.
Booleans are more expensive than uint256 or any type that takes up a full word because each write operation emits an extra SLOAD to first read the slot's contents, replace the bits taken up by the boolean, and then write back. This is the compiler's defense against contract upgrades and pointer aliasing, and it cannot be disabled. https://github.com/OpenZeppelin/openzeppelin-contracts/blob/58f635312aa21f947cae5f8578638a85aa2519f5/contracts/security/ReentrancyGuard.sol#L23-L27
Use uint256 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
Call to an external contract should be cached.
Every call to an external contract costs a decent amount of gas. For optimization of gas usage, external call results should be cached if they are being used for more than one time.
Gas saved: 23972 deploy gas
fix:
The same modifier can be combined into a library
8674 gas saved.
Loop length is calculated for each iteration in loop, this can be cached to save gas
Gas saved: 4113 deploy gas. + method call gas depending on loop length
The variable is cached and used only once.
Caching variables cost extra gas.
Gas saved: 1738
It is more gas efficient to compare variables with != 0 than it is with > 0. These two comparisons are equivalent when the compared variable is an unsigned integer.
Gas saved: 1533
Splitting require() statements that use && saves gas
Important: While two separate checks provide gas savings, deployment requires more gas due to code size and string usage. I can recommend to use this assertion logic optimization with
if() revert Error()
modelThe text was updated successfully, but these errors were encountered: