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

Should include non-existing contract check #9

Open
code423n4 opened this issue Nov 25, 2021 · 1 comment
Open

Should include non-existing contract check #9

code423n4 opened this issue Nov 25, 2021 · 1 comment
Labels
1 (Low Risk) Assets are not at risk. State handling, function incorrect as to spec, issues with comments bug Something isn't working sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")

Comments

@code423n4
Copy link
Contributor

Handle

jayjonah8

Vulnerability details

Impact

The executeTransaction() function in Timelock.sol does not include a check if the contract being called actually exists. The extcodesize is not used when using .call on addresses directly as per the solidity docs. This is important because the EVM allows calls to a non-existing contract to always succeed.

Proof of Concept

https://github.com/code-423n4/2021-11-malt/blob/main/src/contracts/Timelock.sol#L191

solidity docs: https://docs.soliditylang.org/en/v0.8.10/units-and-global-variables.html#address-related

"Due to the fact that the EVM considers a call to a non-existing contract to always succeed, Solidity includes an extra check using the extcodesize opcode when performing external calls. This ensures that the contract that is about to be called either actually exists (it contains code) or an exception is raised.
The low-level calls which operate on addresses rather than contract instances (i.e. .call(), .delegatecall(), .staticcall(), .send() and .transfer()) do not include this check, which makes them cheaper in terms of gas but also less safe."

Tools Used

Manual code review

Recommended Mitigation Steps

A check should be included to make sure the contract being called actually exists to avoid making possible errors in the executeTransaction() function

@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 Nov 25, 2021
code423n4 added a commit that referenced this issue Nov 25, 2021
@0xScotch 0xScotch added the sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") label Dec 10, 2021
@GalloDaSballo
Copy link
Collaborator

Am ambivalent on this finding.
All implementations I know of low level call do not perform the check the warden is suggesting:
https://github.com/Blockchains/badger-timelock/blob/master/contracts/Executor.sol
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/governance/TimelockController.sol

Thinking about it, an actual call to a non existing contract will revert when trying to run a function that doesn't exist.

While the industry seems to disagree, I think the warden has a point, will lower the severity to low

@GalloDaSballo GalloDaSballo added 1 (Low Risk) Assets are not at risk. State handling, function incorrect as to spec, issues with comments and removed 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value labels Jan 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1 (Low Risk) Assets are not at risk. State handling, function incorrect as to spec, issues with comments bug Something isn't working sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Projects
None yet
Development

No branches or pull requests

3 participants