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
[G-01] Usage of uints/ints 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.
[G-06] No need to explicitly initialize variables with default values
If a variable is not set/initialized, it is assumed to have the default value (0 for uint, false for bool, address(0) for address…). Explicitly initializing it with its default value is an anti-pattern and wastes gas.
As an example: for (uint256 i = 0; i < numIterations; ++i) { should be replaced with for (uint256 i; i < numIterations; ++i) {
In Solidity 0.8+, there’s a default overflow check on unsigned integers. It’s possible to uncheck this in for-loops and save some gas at each iteration, but at the cost of some code readability, as this uncheck cannot be made inline.
[G-09] Functions guaranteed to revert when called normal users can be marked payable
If a function modifier such as onlyOwner is used, the function will revert if a normal user tries to pay the function. Marking the function as payable will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided.
[G-17] Using private rather than public for constants, saves gas
If needed, the value can be read from the verified contract source code. Savings are due to the compiler not having to create non-payable getter functions for deployment calldata, and not adding another entry to the method ID table
[G-01] Usage of
uints
/ints
smaller than 32 bytes (256 bits) incurs overheadWhen 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.
https://docs.soliditylang.org/en/v0.8.11/internals/layout_in_storage.html Use a larger size then downcast where needed.
There are 2 instances of this issue:
DebtToken.sol#L16
Disputes.sol#L100
[G-02] Use custom error rather than
revert()
/require()
strings to save deployment gasCustom errors are available from solidity version 0.8.4. The instances below match or exceed that version.
There are 63 instances of this issue:
DebtToken.sol#L33
DebtToken.sol#L50
DebtToken.sol#L96
DebtToken.sol#L104
ProjectFactory.sol#L36
HomeFiProxy.sol#L41
HomeFiProxy.sol#L81
HomeFiProxy.sol#L105
HomeFiProxy.sol#L133
HomeFi.sol#L73
HomeFi.sol#L78
HomeFi.sol#L84
HomeFi.sol#L142
HomeFi.sol#L191
HomeFi.sol#L255
Disputes.sol#L64
Disputes.sol#L106
Disputes.sol#L183
25 instances here
Project.sol
20 instances here
Community.sol
[G-03] Duplicated
require()
/revert()
checks should be refactored to a modifier or functionSaves deployment costs.
There is 1 instance of this issue:
DebtToken.sol#L96
DebtToken.sol#L104
[G-04] Using
calldata
instead ofmemory
for read-only arguments inexternal
function saves gasThere are 4 instances of this issue:
DebtToken.sol#L45-L46
HomeFi.sol#L210
Community.sol#L489
[G-05] 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).There are 17 instances of this issue:
ProjectFactory.sol#L28
HomeFiProxy.sol#L20
Disputes.sol#L27
HomeFi.sol#L38-L42
HomeFi.sol#L54-L56
Project.sol#L40
Project.sol#L52-L58
Community.sol#L33-L35
Community.sol#L48
[G-06] No need to explicitly initialize variables with default values
If a variable is not set/initialized, it is assumed to have the default value (
0
foruint
,false
forbool
,address(0)
foraddress
…). Explicitly initializing it with its default value is an anti-pattern and wastes gas.As an example:
for (uint256 i = 0; i < numIterations; ++i) {
should be replaced withfor (uint256 i; i < numIterations; ++i) {
There are 6 instances of this issue:
HomeFiProxy.sol#L87
Project.sol#L248
Project.sol#L311
Project.sol#L322
Project.sol#L412
Community.sol#L624
[G-07]
++i
costs less gas thani++
, especially when it's used in for-loops (--i
/i--
too)Saves 6 gas per loop.
There are 9 instances of this issue:
HomeFiProxy.sol#L87
Project.sol#L248
Project.sol#L311
Project.sol#L322
Project.sol#L368
Project.sol#L603
Project.sol#L650
Project.sol#L710
Community.sol#L624
[G-08] Increments can be unchecked
In Solidity 0.8+, there’s a default overflow check on unsigned integers. It’s possible to uncheck this in for-loops and save some gas at each iteration, but at the cost of some code readability, as this uncheck cannot be made inline.
ethereum/solidity#10695
There are 9 instances of this issue:
HomeFiProxy.sol#L87
Project.sol#L248
Project.sol#L311
Project.sol#L322
Project.sol#L368
Project.sol#L603
Project.sol#L650
Project.sol#L710
Community.sol#L624
[G-09] Functions guaranteed to revert when called normal users can be marked
payable
If a function modifier such as
onlyOwner
is used, the function will revert if a normal user tries to pay the function. Marking the function aspayable
will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided.There are 18 instances of this issue:
HomeFiProxy.sol#L102
HomeFiProxy.sol#L128
HomeFiProxy.sol#L152
HomeFi.sol#L123
HomeFi.sol#L157
HomeFi.sol#L171
HomeFi.sol#L185
HomeFi.sol#L200
Disputes.sol#L145
Disputes.sol#L84-L88
Community.sol#L555
Community.sol#L566
Community.sol#L577
Community.sol#L592
Community.sol#L290
Community.sol#L303
Community.sol#L340
Community.sol#L465
[G-10] Not using the named return variables when a function returns, wastes deployment gas
There is 1 instance of this issue:
HomeFi.sol#L307
[G-11] Splitting
require()
statements that use&&
saves gasSee this issue which describes the fact that there is a larger deployment gas cost, but with enough runtime calls, the change ends up being cheaper
There are 5 instances of this issue:
Disputes.sol#L61-L65
Disputes.sol#L106-L109
Project.sol#L195
Community.sol#L353-L357
[G-12]
internal
functions only called once can be inlined to save gasNot inlining costs 20 to 40 gas because of two extra
JUMP
instructions and additional stack operations needed for function calls.There are 2 instances of this issue:
HomeFi.sol#L284-L297
Disputes.sol#L207-L223
[G-13]
public
functions toexternal
The following functions could be set external to save gas and improve code quality. External call cost is less expensive than of public functions.
There are 2 instances of this issue:
HomeFi.sol#L265
Project.sol#L726
[G-14]
x = x + y
is cheaper thanx += y
There are 4 instances of this issue:
HomeFi.sol#L289
Project.sol#L772
Community.sol#L423
Community.sol#L435
[G-15] Using bools for storage incurs overhead
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/58f635312aa21f947cae5f8578638a85aa2519f5/contracts/security/ReentrancyGuard.sol#L23-L27 Use
uint256(1)
anduint256(2)
for true/false to avoid a Gwarmaccess (100 gas) for the extra SLOAD, and to avoid Gsset (20000 gas) when changing fromfalse
totrue
, after having beentrue
in the pastThere are 4 instances of this issue:
HomeFi.sol#L50
Project.sol#L68
Project.sol#L78
Community.sol#L55
[G-16] Using
> 0
costs more gas than!= 0
when used in arequire()
statementThis change saves 6 gas per instance.
There are 2 instances of this issue:
Disputes.sol#L107
Community.sol#L764
[G-17] Using private rather than public for constants, saves gas
If needed, the value can be read from the verified contract source code. Savings are due to the compiler not having to create non-payable getter functions for deployment calldata, and not adding another entry to the method ID table
There is 1 instance of this issue:
Project.sol#L60
[G-18]
<array>.length
should not be looked up in every loop of afor
-loopThe overheads outlined below are PER LOOP, excluding the first loop
MLOAD
(3 gas)CALLDATALOAD
(3 gas)Caching the length changes each of these to a
DUP<N>
(3 gas), and gets rid of the extraDUP<N>
needed to store the stack offsetThere is 1 instance of this issue:
Project.sol#L603
The text was updated successfully, but these errors were encountered: