NomicFoundation / hardhat

Hardhat is a development environment to compile, deploy, test, and debug your Ethereum software.
https://hardhat.org
Other
7.32k stars 1.42k forks source link

Ethers doesn't throw when an eth_call sent to Hardhat fails with empty return data #3446

Open fvictorio opened 1 year ago

fvictorio commented 1 year ago

This is the main issue for a recurring problem related to static calls from ethers.js to Hardhat that revert without return data (for example, by hitting a require(false)).

Reproduction

Deploy this contract in Hardhat:

contract Foo {
  function f() public {
    require(false);
  }
}

and call foo.callStatic.f(). This should throw an error, but it doesn't.

The reason is that the plain RPC response from Hardhat is this:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32603,
    "message": "Error: Transaction reverted without a reason string",
    "data": {
      "message": "Error: Transaction reverted without a reason string",
      "data": "0x"
    }
  }
}

The "data": "0x" part causes ethers to not throw. I reported this in the ethers.js repo six months ago (https://github.com/ethers-io/ethers.js/issues/3038) and assumed it would be fixed, but it hasn't yet.

For reference, this does work in geth. The raw response for the same call is:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32000,
    "message": "execution reverted"
  }
}

Decision to make

Our options are:

  1. Wait until this is fixed in ethers, and close this issue when/if that happens.
  2. Change our response to omit the data field if it's empty. This is technically a breaking change, but I think it's better than ethers not working correctly for these scenarios.
  3. Finally, we could consider adapting our EthersProviderWrapper in the hardhat-ethers plugin to somehow intercept eth_call responses and remove the data field if it's 0x. I gave this a quick try to see if it was possible but it wasn't immediately obvious how to do it.

To-do

art1313 commented 1 year ago

Has it been solved/fixed? I am having similar issue right now.

fvictorio commented 1 year ago

It's kind of blocked by https://github.com/ethers-io/ethers.js/issues/3038, but we might fix it on our side if that issue takes too long to be solved. The problem is that the easiest fix on our side is technically a small breaking change, so we'd rather have this fixed in ethers itself.