Platform: Code4rena
Start Date: 07/10/2022
Pot Size: $50,000 USDC
Total HM: 4
Participants: 62
Period: 5 days
Judge: 0xean
Total Solo HM: 2
Id: 169
League: ETH
Rank: 26/62
Findings: 2
Award: $71.07
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: 0xSmartContract
Also found by: 0x1f8b, 0x4non, 0xNazgul, Bnke0x0, Chom, IllIllI, Josiah, Rahoz, RaymondFam, Trust, Waze, ajtra, bobirichman, brgltd, bulej93, c3phas, cccz, chrisdior4, delfin454000, fatherOfBlocks, gogo, ladboy233, mcwildy, mics, nicobevi, oyc_109, rbserver, rotcivegaf, zzzitron
50.2765 USDC - $50.28
Severity: Low
Context: Governed.sol#L32
, GraphTokenupgradeable.sol#L150
, GraphProxyStorage.sol#L80
, GraphProxyStorage.sol#L115
Description: Lack of zero-address validation on address parameters may lead to transaction reverts, waste gas, require resubmission of transactions and may even force contract redeployments in certain cases within the protocol.
Recommendation: Consider adding explicit zero-address validation on input parameters of address type.
DOMAIN_TYPEHASH
Can ChangeSeverity: Low
Context: GraphTokenUpgradeable.sol#L34
Description:
The variable DOMAIN_TYPEHASH
is hard coded and will not change after being initialized. However, if a hard fork happens after the contract deployment, the domain would become invalid on one of the forked chains due to the block.chainid
has changed. Also, you don't need an assmebly to retrieve chainid
, you can get it from a built in variable block.chainid
.
Recommendation: Consider the solution from Sushi Trident.
Severity: Low
Context: BridgeEscrow.sol#L29
Description: Giving max/infinite approvals to contracts are dangerous because if those contracts are exploited then they can remove all the funds from the approving addresses.
Recommendation: Consider checking allowance and approve as much as required.
Severity: Low
Context: Governed.sol#L31
, GraphTokenUpgradeable.sol#L150
, L2GraphTokenGateway.sol#L89
, L1GraphTokenGateway.sol#L99
Description: None of the initialize functions emit emit init-specific events. They all however have the initializer modifier (from Initializable) so that they can be called only once. Off-chain monitoring of calls to these critical functions is not possible.
Recommendation: It is recommended to emit events in your initialization functions.
Severity Informational
Context: GraphUpgradeable.sol#L17
, L1GraphTokenGateway.sol#L290
Description:
The linked variables do not conform to the standard naming convention of Solidity whereby functions and variable names(local and state) utilize the mixedCase
format unless variables are declared as constant
in which case they utilize the UPPER_CASE_WITH_UNDERSCORES
format. Private variables and functions should lead with an _underscore
.
Recommendation: Consider naming conventions utilized by the linked statements are adjusted to reflect the correct type of declaration according to the Solidity style guide.
Severity: Informational
Context: GraphUpgradeable.sol#L50
, Governed.sol#L40
, L1GraphTokenGateway.sol#L326
Description: The best-practice layout for a contract should follow the following order: state variables, events, modifiers, constructor and functions. Function ordering helps readers identify which functions they can call and find constructor and fallback functions easier. Functions should be grouped according to their visibility and ordered as: constructor, receive function (if exists), fallback function (if exists), external, public, internal, private. Functions should then further be ordered with view functions coming after the non-view labeled ones.
Recommendation: Consider adopting recommended best-practice for code structure and layout.
Severity Informational
Context: GraphProxyAdmin.sol#L34
, GraphProxyAdmin.sol#L47
, GraphProxyAdmin.sol#L59
, GraphProxy.sol#L133
Description: Some revert messages are unclear which can lead to confusion. Unclear revert messages may cause misunderstandings on reverted transactions.
Recommendation: Consider making revert messages more clear.
Severity: Informational
Context: L1GraphTokenGateway.sol#L260 (Recepient => Recipient)
Description: Spelling errors in comments can cause confusion to both users and developers.
Recommendation: Consider checking all misspellings to ensure they are corrected.
Severity: Informational
Context: All Contracts
Description: Some functions are missing @notice/@dev NatSpec comments for the function, @param for all/some of their parameters and @return for return values. Given that NatSpec is an important part of code documentation, this affects code comprehension, auditability and usability.
Recommendation: Consider adding in full NatSpec comments for all functions to have complete code documentation for future use.
Severity: Informational
Context: All Contracts
Description: 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.
Recommendation: Consider locking the pragma version.
🌟 Selected for report: IllIllI
Also found by: 0x1f8b, 0xNazgul, 0xSmartContract, 0xdeadbeef, B2, Bnke0x0, Deivitto, ElKu, Jujic, KoKo, Pheonix, RaymondFam, RedOneN, RockingMiles, Rolezn, Saintcode_, Shinchan, TomJ, Tomio, __141345__, ajtra, aysha, c3phas, carlitox477, catchup, delfin454000, emrekocak, erictee, fatherOfBlocks, gerdusx, gianganhnguyen, gogo, martin, mcwildy, medikko, oyc_109, pedr02b2, rbserver, ret2basic, rotcivegaf, saian, sakman, zishansami
20.7905 USDC - $20.79
require()
, Use != 0
Instead of > 0
With Uint ValuesContext: L2GraphTokenGateway.sol#L146
, L1GraphTokenGateway.sol#L201
, L1GraphTokenGateway.sol#L217
Description:
In a require, when checking a uint, using != 0
instead of > 0
saves 6 gas. This will jump over or avoid an extra ISZERO
opcode.
Recommendation:
Use != 0
instead of > 0
with uint values but only in require()
statements.
2**256 - 1 && type(uint256).max
When 2**255
Can Be UsedContext: BridgeEscrow.sol#L29
Description:
Infinity can also be represented via ``2255, it's hex representation is
0x8000000000000000000000000000000000000000000000000000000000000000while
2256 - 1is
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`. Then main difference is and where the gas savings come from is, zeros are cheaper than non-zero values in hex representation.
Recommendation:
Use 2**255
instead of 2**256 - 1
to save gas on deployment.
Context: GraphProxyAdmin.sol
, GraphProxy.sol
Description:
You can cut out 10 opcodes in the creation-time EVM bytecode if you declare a constructor payable. Making the constructor payable eliminates the need for an initial check of msg.value == 0
and saves 21 gas on deployment with no security risks.
Recommendation: Set the constructor to payable.
Context: All Contracts
Description:
Contracts most called functions could simply save gas by function ordering via Method ID. Calling a function at runtime will be cheaper if the function is positioned earlier in the order (has a relatively lower Method ID) because 22 gas are added to the cost of a function for every position that came before it. The caller can save on gas if you prioritize most called functions. One could use This tool
to help find alternative function names with lower Method IDs while keeping the original name intact.
Recommendation:
Find a lower method ID name for the most called functions for example mostCalled()
vs. mostCalled_41q()
is cheaper by 44 gas.