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: 31/62
Findings: 1
Award: $50.28
🌟 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
https://github.com/code-423n4/2022-10-thegraph/blob/7ea88cc41f17f2d49961aafec7ebe72daeaad3f9/contracts/gateway/L1GraphTokenGateway.sol#L212-L214 https://github.com/code-423n4/2022-10-thegraph/blob/7ea88cc41f17f2d49961aafec7ebe72daeaad3f9/contracts/gateway/L1GraphTokenGateway.sol#L152-L157
If l1Router
is added to the callhookWhitelist
, anybody who is using the router can use the call hook.
There is no safe guard against adding l1Router
to the callhookWhitelist
In the L1GraphTokenGateway::outboundTransfer
function, it checks whether the msg.sender
is in the whitelist. If the msg.sender
is whitelisted, it allows to use the callhook on the L2 side.
When someone is using the router to send graph token, the transaction will always have the router as msg.sender
. Therefore, if the router is added as a callhookWhitelist
, it allows anybody who uses the router to use the callhook, which is not the intended usage based on the specification.
In the L1GraphTokenGateway::addToCallhookWhitelist
(line 152), it does not check the _newWhitelisted
against the l1Router
, therefore the l1Router
.
// L1GraphTokenGateway // outboundTransfer 212 (from, maxSubmissionCost, extraData) = parseOutboundData(_data); 213 require( 214 extraData.length == 0 || callhookWhitelist[msg.sender] == true,
// L1GraphTokenGateway 152 function addToCallhookWhitelist(address _newWhitelisted) external onlyGovernor { 153 require(_newWhitelisted != address(0), "INVALID_ADDRESS"); 154 require(!callhookWhitelist[_newWhitelisted], "ALREADY_WHITELISTED"); 155 callhookWhitelist[_newWhitelisted] = true; 156 emit AddedToCallhookWhitelist(_newWhitelisted); 157 }
Manual review
Add the check require(_newWhitelisted != l1Router);
. To be really sure, when l1Router
is updated, check whether l1Router
is in the whitelist.
#0 - trust1995
2022-10-12T21:28:01Z
Seems like a very unlikely mistake to make, to add router to the whitelist. The project mentioned only very few contracts like Rewarder would get in.
#1 - 0xean
2022-10-16T16:36:32Z
I think this comes down to QA, there could be any number of potential addresses that would allow someone to do something that is unexpected, which is why the whitelist exists.
So this issue seems to boil down to if address X is accidentally added to the whitelist, address X can use the hook.... well yes, that is true.
#2 - pcarranzav
2022-10-19T16:38:15Z
Agree this is more QA than Med, but good find nonetheless