Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing contract existence checks for low-level calls #116

Closed
code423n4 opened this issue Oct 11, 2022 · 3 comments
Closed

Missing contract existence checks for low-level calls #116

code423n4 opened this issue Oct 11, 2022 · 3 comments
Labels
bug Something isn't working duplicate This issue or pull request already exists QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2022-10-thegraph/blob/48e7c7cf641847e07ba07e01176cb17ba8ad6432/contracts/statechannels/GRTWithdrawHelper.sol#L56-L78

Vulnerability details

Impact

When doing low-level calls, it's necessary to not only check that the address is non-null, but that it has actual code. When a low-level call is made on a valid address that has no deployed code, the low level call always returns true. This may be the case of a create2() address hasn't yet had its contract deployed, or the contract has been destructed.

In this case, the code uses the low level call as a sort of check for approval, assuming that failure to approve will block the transfer of the tokens that comes after it. If tokenAddress does not have any code deployed, the call to APPROVE_SELECTOR will pass, and the COLLECT_SELECTOR transfer that comes afterwards will be done

Proof of Concept

// File: contracts/statechannels/GRTWithdrawHelper.sol : GRTWithdrawHelper.execute()   #1

56        function execute(WithdrawData calldata _wd, uint256 _actualAmount) external override {
57            require(_wd.assetId == tokenAddress, "GRTWithdrawHelper: !token");
58    
59            // Decode and validate collect data
60            CollectData memory collectData = abi.decode(_wd.callData, (CollectData));
61            require(collectData.staking != address(0), "GRTWithdrawHelper: !staking");
62            require(collectData.allocationID != address(0), "GRTWithdrawHelper: !allocationID");
63            require(collectData.returnAddress != address(0), "GRTWithdrawHelper: !returnAddress");
64    
65            // Approve the staking contract to pull the transfer amount
66 @>         (bool success1, ) = tokenAddress.call(
67 @>             abi.encodeWithSelector(APPROVE_SELECTOR, collectData.staking, _actualAmount)
68 @>         );
69    
70            // If the call fails return the funds to the return address and bail
71            if (!success1) {
72                _sendTokens(collectData.returnAddress, _actualAmount);
73                return;
74            }
75    
76            // Call the Staking contract to collect funds from this contract
77 @>         (bool success2, ) = collectData.staking.call(
78:@>             abi.encodeWithSelector(COLLECT_SELECTOR, _actualAmount, collectData.allocationID)

https://github.com/code-423n4/2022-10-thegraph/blob/48e7c7cf641847e07ba07e01176cb17ba8ad6432/contracts/statechannels/GRTWithdrawHelper.sol#L56-L78

Tools Used

Code inspection

Recommended Mitigation Steps

require() that the <address>.code.length is non-zero before each low-level call

@code423n4 code423n4 added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels Oct 11, 2022
code423n4 added a commit that referenced this issue Oct 11, 2022
@0xean
Copy link
Collaborator

0xean commented Oct 15, 2022

Given that the token in question is the graph token, which is immutably set in the constructor this seems very unlikely to be an issue here. I think at best this could be QA.

@0xean 0xean added the QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax label Oct 15, 2022
@0xean
Copy link
Collaborator

0xean commented Oct 15, 2022

closing as dupe of #118 - wardens QA

@0xean 0xean closed this as completed Oct 15, 2022
@0xean 0xean added duplicate This issue or pull request already exists and removed 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value labels Oct 15, 2022
@pcarranzav
Copy link

Also out of scope (GRTWithdrawHelper.sol)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working duplicate This issue or pull request already exists QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax
Projects
None yet
Development

No branches or pull requests

3 participants