Use safeTransfer/safeTransferFrom consistently instead of transfer/transferFrom
2
Q-2
USE SAFEAPPROVE INSTEAD OF APPROVE
1
Q-3
The nonReentrant modifier should occur before all other modifiers
2
Q-4
_safeMint() should be used rather than _mint() wherever possible
3
Q-5
Avoid using Floating Pragma
20
Q-6
Use of Block.Timestamp
3
Q-7
Multiple initialization due to initialize function not having initializer modifier
8
Total instances found in this contest: 39 | Among all files in scope
1. Use safeTransfer/safeTransferFrom consistently instead of transfer/transferFrom
It is good to add a require() statement that checks the return value of token transfers or to use something like OpenZeppelin’s safeTransfer/safeTransferFrom unless one is sure the given token reverts in case of a failure. Failure to do so will cause silent failures of transfers and affect token accounting in contract.
Consider using safeTransfer/safeTransferFrom or require() consistently.
2. USE SAFEAPPROVE INSTEAD OF APPROVE
This is probably an oversight since SafeERC20 was imported and safeTransfer() was used for ERC20 token transfers. Nevertheless, note that approve() will fail for certain token implementations that do not return a boolean value (). Hence it is recommend to use safeApprove().
using the nonReentrant modifier before onlyWhileActive modifier
4. _safeMint() should be used rather than _mint() wherever possible
Description:
_mint() is discouraged in favor of _safeMint() which ensures that the recipient is either an EOA or implements IERC721Receiver. Both open OpenZeppelin and solmate have versions of this function so that NFTs aren’t lost if they’re minted to contracts that cannot transfer them back out.
Contracts should be deployed with the same compiler version and flags that they have been tested with thoroughly. Locking the pragma helps to ensure that contracts do not accidentally get deployed using, for example, an outdated compiler version that might introduce bugs that affect the contract system negatively.
Block timestamps have historically been used for a variety of applications, such as entropy for random numbers (see the Entropy Illusion for further details), locking funds for periods of time, and various state-changing conditional statements that are time-dependent. Miners have the ability to adjust timestamps slightly, which can prove to be dangerous if block timestamps are used incorrectly in smart contracts.
Low and Non-Critical
Total instances found in this contest: 39 | Among all files in scope
1. Use safeTransfer/safeTransferFrom consistently instead of transfer/transferFrom
It is good to add a require() statement that checks the return value of token transfers or to use something like OpenZeppelin’s safeTransfer/safeTransferFrom unless one is sure the given token reverts in case of a failure. Failure to do so will cause silent failures of transfers and affect token accounting in contract.
Instances:
L1GraphTokenGateway.sol:L235
L1GraphTokenGateway.sol:L276
Reference:
This similar medium-severity finding from Consensys Diligence Audit of Fei Protocol.
Recommended Mitigation Steps:
Consider using safeTransfer/safeTransferFrom or require() consistently.
2. USE SAFEAPPROVE INSTEAD OF APPROVE
This is probably an oversight since SafeERC20 was imported and safeTransfer() was used for ERC20 token transfers. Nevertheless, note that approve() will fail for certain token implementations that do not return a boolean value (). Hence it is recommend to use safeApprove().
Instances:
BridgeEscrow.sol:L29
Recommended Mitigation Steps
Update to safeapprove in the function.
3. The nonReentrant modifier should occur before all other modifiers
Description
The nonReentrant modifier should occur before all other modifiers This is a best-practice to protect against re-entrancy in other modifiers
Instances
L2GraphTokenGateway.sol:L144
L2GraphTokenGateway.sol:L232
Recommended Mitigation Steps
using the nonReentrant modifier before onlyWhileActive modifier
4. _safeMint() should be used rather than _mint() wherever possible
Description:
_mint()
is discouraged in favor of_safeMint()
which ensures that the recipient is either an EOA or implementsIERC721Receiver
. Both open OpenZeppelin and solmate have versions of this function so that NFTs aren’t lost if they’re minted to contracts that cannot transfer them back out.Instances
GraphTokenUpgradeable.sol:L133
GraphTokenUpgradeable.sol:L155
L2GraphToken.sol:L81
Recommendations:
Use _safeMint() instead of _mint().
5. Avoid using Floating Pragma:
Contracts should be deployed with the same compiler version and flags that they have been tested with thoroughly. Locking the pragma helps to ensure that contracts do not accidentally get deployed using, for example, an outdated compiler version that might introduce bugs that affect the contract system negatively.
Instances:
ICuration.sol:L3
IGraphCurationToken.sol:L3
L2GraphTokenGateway.sol:L3
L2GraphToken.sol:L3
GraphTokenUpgradeable.sol:L3
IGraphProxy.sol:L3
GraphProxyAdmin.sol:L3
GraphProxy.sol:L3
GraphUpgradeable.sol:L3
GraphProxyStorage.sol:L3
L1GraphTokenGateway.sol:L3
ICallhookReceiver.sol:L9
BridgeEscrow.sol:L3
GraphTokenGateway.sol:L3
IEpochManager.sol:L3
IRewardsManager.sol:L3
Pausable.sol:L3
Managed.sol:L3
Governed.sol:L3
IGraphToken.sol:L3
Recomended Mitigation Step
Recommend using fixed solidity version
References:
https://code4rena.com/reports/2022-04-phuture#g-20-use-a-more-recent-version-of-solidity
6. Use of Block.Timestamp
Block timestamps have historically been used for a variety of applications, such as entropy for random numbers (see the Entropy Illusion for further details), locking funds for periods of time, and various state-changing conditional statements that are time-dependent. Miners have the ability to adjust timestamps slightly, which can prove to be dangerous if block timestamps are used incorrectly in smart contracts.
Instances:
GraphTokenUpgradeable.sol:L95
Pausable.sol:L32
Pausable.sol:L46
References:
https://github.com/code-423n4/2022-04-dualityfocus-findings/issues/33
7. Multiple initialization due to initialize function not having initializer modifier
Description
The attacker can initialize the contract, take malicious actions, and allow it to be re-initialized by the project without any error being noticed.
instances:
Governed.sol:L31
Managed.sol:L87
IGraphCurationToken.sol:L8
L1GraphTokenGateway.sol:L99
BridgeEscrow.sol:L20
L2GraphTokenGateway.sol:L87
GraphTokenUpgradeable.sol:L150
L2GraphToken.sol:L48