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

Due to behavior of ERC165, supportsinterface query might consume more gas than available thereby returning false even though it would've returned true if it had enough gas. #365

Closed
c4-submissions opened this issue Nov 10, 2023 · 3 comments
Labels
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 insufficient quality report This report is not of sufficient quality unsatisfactory does not satisfy C4 submission criteria; not eligible for awards

Comments

@c4-submissions
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2023-10-party/blob/b23c65d62a20921c709582b0b76b387f2bb9ebb5/contracts/party/PartyGovernanceNFT.sol#L113
https://github.com/code-423n4/2023-10-party/blob/b23c65d62a20921c709582b0b76b387f2bb9ebb5/contracts/party/PartyGovernance.sol#L333

Vulnerability details

Impact

ERC165 estimates that supportinterface can consume upto 30,000 gas, http://eips.ethereum.org/EIPS/eip-165. However, this is not enforced in the openzepplin implementation . As a result, the check whether a contract implements an interface might return false giving a wrong interpretation of the contract. This applies to partygovernance and partygovernancNft contracts.

Proof of Concept

 partyGovernanceNFT.sol
     ''/// @inheritdoc EIP165
function supportsInterface(
    bytes4 interfaceId
) public pure override(PartyGovernance, ERC721, IERC165) returns (bool) {
    return
        PartyGovernance.supportsInterface(interfaceId) ||
        ERC721.supportsInterface(interfaceId) ||
        interfaceId == type(IERC2981).interfaceId;
}''
  partyGovernance.sol
    ''function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {
    return
        interfaceId == type(IERC721Receiver).interfaceId ||
        interfaceId == type(ERC1155TokenReceiverBase).interfaceId ||
        // ERC4906 interface ID
        interfaceId == 0x49064906;
      }''

This shows how openzepplin implements supportsinterface query. .https://github.com/OpenZeppelin/openzeppelin-contracts/blob/fa004a7f5de572b3dbcde1a8a81f9a87e353e799/contracts/introspection/ERC165Checker.sol#L110-L119

       '' success := staticcall(
            30000,                   // 30k gas
            account,                 // To addr
            encodedParams_data,
            encodedParams_size,
            output,
            0x20                     // Outputs are 32 bytes long
        )


        result := mload(output)      // Load the result''

As you can see there is no check to ensure that contract has more than the required 30,000 gas and because of the behavior of EIP150 ,http://eips.ethereum.org/EIPS/eip-150, it is possible that supportinterface query receives less gas than required. Therefore, the calls in both functions above will trow an out of gas error and in the process return false giving an incorrect interpretation of the contracts in check. The issue is detailed here OpenZeppelin/openzeppelin-contracts#1750.

Tools Used

Recommended Mitigation Steps

It is worth noting that there is no fix for this issue yet. However, it is recommended to ensure that partygovernance and partygovernancenft contracts have enough gas before supportsinterface call.

Assessed type

Other

@c4-submissions c4-submissions 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 10, 2023
c4-submissions added a commit that referenced this issue Nov 10, 2023
@ydspa
Copy link

ydspa commented Nov 12, 2023

No proof that supportInterface implemented in the specified codes costs more than 30k gas

Invalid

@c4-pre-sort c4-pre-sort added the insufficient quality report This report is not of sufficient quality label Nov 12, 2023
@c4-pre-sort
Copy link

ydspa marked the issue as insufficient quality report

@c4-judge
Copy link
Contributor

gzeon-c4 marked the issue as unsatisfactory:
Insufficient proof

@c4-judge c4-judge added the unsatisfactory does not satisfy C4 submission criteria; not eligible for awards label Nov 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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 insufficient quality report This report is not of sufficient quality unsatisfactory does not satisfy C4 submission criteria; not eligible for awards
Projects
None yet
Development

No branches or pull requests

4 participants