The Graph L2 bridge contest - fatherOfBlocks's results

A protocol for indexing and querying blockchain data.

General Information

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

The Graph

Findings Distribution

Researcher Performance

Rank: 18/62

Findings: 2

Award: $71.07

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

50.2765 USDC - $50.28

Labels

bug
QA (Quality Assurance)

External Links

ALL

  • SE A MORE RECENT VERSION OF SOLIDITY Use a solidity version of at least 0.8.13 to get the ability to use a list of free functions.

l2/token/GraphTokenUpgradeable.sol

  • L145 - If the input _l1Token can only have a single value, that is l1GRT, therefore that input could be saved and directly know that it is handled with that address.

token/IGraphToken.sol

  • L3/5 - The IERC20 import is in pragma 0.8 and the GraphToken interface is created with version 0.7.6, this generates compatibility conflicts.

curation/ICuration.sol

  • L5 - The IGraphCurationToken interface is imported, but is never used.

upgrades/GraphProxyAdmin.sol

  • L34/47/59 - If we perform a require and there is a chance that it will revert, it would be beneficial to have a message for that revert.

upgrades/GraphProxy.sol

  • L21/33 - Instead of the name ifAdmin or ifAdminOrPendingImpl for modifiers, the word "only" instead of if could be a better name.

governance/Managed.sol

  • L33 - An event, ParameterUpdated, is created and is never used. Therefore it should be removed.

gateway/L1GraphTokenGateway.sol

  • L142 - It is validated that _escrow != address(0) && Address.isContract(_escrow) but the second validation would already validate that _escrow is not the address(0), since that address is not a contract, therefore it could be just validate that escrow is a contract.

  • L200/270/271 - If the input _l1Token can only have a single value, that is graphToken(), therefore that input could be saved and directly know what is handled with that GraphToken.

#0 - pcarranzav

2022-10-19T17:49:52Z

If the input _l1Token can only have a single value, that is l1GRT, therefore that input could be saved and directly know that it is handled with that address.

We still need to validate that the input is correct to prevent users from trying to send a different token

L3/5 - The IERC20 import is in pragma 0.8 and the GraphToken interface is created with version 0.7.6, this generates compatibility conflicts.

The OZ version we use actually has pragma solidity >=0.6.0 <0.8.0;

L33 - An event, ParameterUpdated, is created and is never used. Therefore it should be removed.

This event is used by several contracts that inherit from Managed

L142 - It is validated that _escrow != address(0) && Address.isContract(_escrow) but the second validation would already validate that _escrow is not the address(0), since that address is not a contract, therefore it could be just validate that escrow is a contract.

Good idea, but I still prefer the explicit check

L200/270/271 - If the input _l1Token can only have a single value, that is graphToken(), therefore that input could be saved and directly know what is handled with that GraphToken.

Same as above, we still need to validate the input

upgrades/GraphUpgradeable

  • L24/32 - Instead of using a require you can use ifs and an error custom, this would generate a lower cost of gas.

  • L32 - REQUIRE()/REVERT() STRINGS LONGER THAN 32 BYTES COST EXTRA GAS

governance/Governed.sol

  • L24/41/54 - Instead of using a require you can use ifs and an error custom, this would generate a lower cost of gas.

  • L55 - In the require it is validated: pendingGovernor != address(0) && msg.sender == pendingGovernor, this generates an unnecessary cost of gas, since validating pendingGovernor != address(0) is not necessary since msg.sender cannot be address(0). This is because the second premise (msg.sender == pendingGovernor) does enough to validate both premises.

governance/Pausable.sol

  • L31/34/45/48/57/58 - Instead of validating the variable in storage in the if, it is less expensive to validate the input of the function, that is _toPause. The same thing happens when emitting the event, it is less expensive to use the input.

l2/token/L2GraphToken.sol

  • L36/49/60/70 - Instead of using a require you can use ifs and an error custom, this would generate a lower cost of gas.

upgrades/GraphProxyAdmin.sol

  • L34/47/59 - Instead of using a require you can use ifs and an error custom, this would generate a lower cost of gas.

upgrades/GraphProxy.sol

  • L105/141/142/157 - Instead of using a require you can use ifs and an error custom, this would generate a lower cost of gas.

  • L105/144 - REQUIRE()/REVERT() STRINGS LONGER THAN 32 BYTES COST EXTRA GAS

  • L143 - In the require it is validated: _pendingImplementation != address(0) && msg.sender == _pendingImplementation, this generates an unnecessary cost of gas, since validating _pendingImplementation != address(0) is not necessary since msg.sender cannot be address(0). This is because the second premise (msg.sender == _pendingImplementation) does enough to validate both premises.

governance/Managed.sol

  • L44/45/49/53/57/104 - Instead of using a require you can use ifs and an error custom, this would generate a lower cost of gas.

gateway/GraphTokenGateway

  • L19/31/40 - Instead of using a require you can use ifs and an error custom, this would generate a lower cost of gas.

  • L20 - It is less expensive in the require to execute first msg.sender == pauseGuardian, before msg.sender == controller.getGovernor(), since in the call to the controller function a different smart contract is consulted and in the first validation is just a check of a variable.

gateway/L1GraphTokenGateway.sol

  • L74/78/82/110/111/122/132/142/153/154/165/166/200/201/202/213/217/224/271/275 - Instead of using a require you can use ifs and an error custom, this would generate a lower cost of gas.

  • L77/78/81/82/223/224/229/242/353/354 - When a variable is created but only used once, less gas would be spent directly using it where it is needed.

  • L201/217 - With integers of type uint256 it is less expensive to validate _amount != 0, rather than validating _amount > 0.

  • L214 - When we want to validate bools, it is less expensive to validate require(!bool) or require(bool), instead of require(bool == false) or require(bool == true)

l2/token/GraphTokenUpgradeable.sol

  • L69/98/108/118/145/146/147/148/153/233/234 - Instead of using a require you can use ifs and an error custom, this would generate a lower cost of gas.

  • L146/238 - With integers of type uint256 it is less expensive to validate _amount != 0, rather than validating _amount > 0.

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter