[G-01] msg.sender CAN BE USED INSTEAD OF STATE VARIABLE IF POSSIBLE
Reading msg.sender costs 2 gas, which is much cheaper than reading a state variable because an sload operation costs 100 or 2100 gas depending on whether the accessed address is warm or not.
[G-04] STATE VARIABLE THAT IS ACCESSED FOR MULTIPLE TIMES CAN BE CACHED IN MEMORY
A state variable that is accessed for multiple times can be cached in memory, and the cached variable value can then be used. This can replace multiple sload operations with one sload, one mstore, and multiple mload operations to save gas.
[G-06] require REASON STRINGS CAN BE SHORTENED TO FIT IN 32 BYTES
require reason strings that are longer than 32 bytes need more memory space and more mstore operations than these that are shorter than 32 bytes when reverting. Please consider shortening the following require reason strings.
contracts\gateway\GraphTokenGateway.sol
21: "Only Governor or Guardian can call"
contracts\governance\Managed.sol
53: require(msg.sender == controller.getGovernor(), "Caller must be Controller governor");
contracts\upgrades\GraphUpgradeable.sol
32: require(msg.sender == _implementation(), "Caller must be the implementation");
contracts\upgrades\GraphProxy.sol
141: require(Address.isContract(_pendingImplementation), "Implementation must be a contract");
144: "Caller must be the pending implementation"
[G-07] NEWER VERSION OF SOLIDITY CAN BE USED
The protocol can benefit from more gas-efficient features, such as custom errors starting from Solidity v0.8.4, by using a newer version of Solidity. For the following contracts, please consider using a newer Solidity version.
[G-01]
msg.sender
CAN BE USED INSTEAD OF STATE VARIABLE IF POSSIBLEReading
msg.sender
costs 2 gas, which is much cheaper than reading a state variable because ansload
operation costs 100 or 2100 gas depending on whether the accessed address is warm or not.In the following
acceptOwnership
function,msg.sender
can be used instead ofpendingGovernor
for settingoldPendingGovernor
and updatinggovernor
.msg.sender
can also be used instead ofgovernor
for emitting theNewOwnership
event. https://github.com/code-423n4/2022-10-thegraph/blob/main/contracts/governance/Governed.sol#L53-L67[G-02]
address(0)
CAN BE USED INSTEAD OF STATE VARIABLE IF POSSIBLEExecuting
address(0)
instead of reading a state variable saves gas by avoiding the costlysload
operation.In the following
acceptOwnership
function,address(0)
can be used instead ofpendingGovernor
for emitting theNewPendingOwnership
event. https://github.com/code-423n4/2022-10-thegraph/blob/main/contracts/governance/Governed.sol#L53-L67[G-03] MEMORY VARIABLES CAN BE USED INSTEAD OF STATE VARIABLES IF POSSIBLE
Accessing a memory variable instead of a state variable replaces an
sload
operation with anmload
operation. When this is possible, gas is saved.In the following
transferOwnership
function,_newGovernor
can be used instead ofpendingGovernor
for emitting theNewPendingOwnership
event. https://github.com/code-423n4/2022-10-thegraph/blob/main/contracts/governance/Governed.sol#L40-L47In the following
setGateway
function,_gw
can be used instead ofgateway
for emitting theGatewaySet
event. https://github.com/code-423n4/2022-10-thegraph/blob/main/contracts/l2/token/L2GraphToken.sol#L59-L63In the following
_setPaused
function,_toPause
can be used instead of_paused
for emitting thePauseChanged
event. https://github.com/code-423n4/2022-10-thegraph/blob/main/contracts/governance/Pausable.sol#L40-L49In the following
_setPauseGuardian
function,newPauseGuardian
can be used instead ofpauseGuardian
for emitting theNewPauseGuardian
event. https://github.com/code-423n4/2022-10-thegraph/blob/main/contracts/governance/Pausable.sol#L55-L59[G-04] STATE VARIABLE THAT IS ACCESSED FOR MULTIPLE TIMES CAN BE CACHED IN MEMORY
A state variable that is accessed for multiple times can be cached in memory, and the cached variable value can then be used. This can replace multiple
sload
operations with onesload
, onemstore
, and multiplemload
operations to save gas.In the following
permit
function,nonces[_owner]
can be cached, and the cached value can then be used for settingdigest
and updatingnonces[_owner]
. https://github.com/code-423n4/2022-10-thegraph/blob/main/contracts/l2/token/GraphTokenUpgradeable.sol#L74-L99[G-05] BOOLEAN EXPRESSION CAN BE USED INSTEAD OF COMPARING BOOLEAN VALUE TO BOOLEAN LITERAL
Comparing a boolean value to a boolean literal needs the
iszero
operation and costs more gas than using a boolean expression.callhookWhitelist[msg.sender]
can be used instead ofcallhookWhitelist[msg.sender] == true
in the following code.https://github.com/code-423n4/2022-10-thegraph/blob/main/contracts/gateway/L1GraphTokenGateway.sol#L214
[G-06]
require
REASON STRINGS CAN BE SHORTENED TO FIT IN 32 BYTESrequire
reason strings that are longer than 32 bytes need more memory space and moremstore
operations than these that are shorter than 32 bytes when reverting. Please consider shortening the followingrequire
reason strings.[G-07] NEWER VERSION OF SOLIDITY CAN BE USED
The protocol can benefit from more gas-efficient features, such as custom errors starting from Solidity v0.8.4, by using a newer version of Solidity. For the following contracts, please consider using a newer Solidity version.