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: 18/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
ALL
l2/token/GraphTokenUpgradeable.sol
token/IGraphToken.sol
curation/ICuration.sol
upgrades/GraphProxyAdmin.sol
upgrades/GraphProxy.sol
governance/Managed.sol
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
🌟 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
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
l2/token/L2GraphToken.sol
upgrades/GraphProxyAdmin.sol
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
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.