Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Incorrect handling of revert with a message #3435

@barakman

Description

@barakman

Expected behavior

Function call should revert

Actual behavior

Function call completes successfully and returns an impossible value

Steps to reproduce the behavior

I have deployed the following contract to Ropsten, and verified its source-code on Etherscan:

pragma solidity 0.4.26;

contract MyContract {
    bool public x;
    function func() view public returns (bool) {
        require(x);
        return false;
    }
}

It is at address 0x23335ED6E550726D0bA881a3D1f5b5B1eF411A97.

I then deployed and verified an identical contract with one difference - require(x, "error");.
It is at address 0xc8A9f997098c81378A000bBa293567b20645EFD9.

Note that in both cases, calling function func should revert.

Here is a testing script (you'll need an Infura Project-ID):

const Web3 = require("web3");

const ADDR = "0x23335ED6E550726D0bA881a3D1f5b5B1eF411A97";

const ABI = [{
    "constant":true,
    "inputs":[],
    "name":"func",
    "outputs":[{"name":"","type":"bool"}],
    "payable":false,
    "stateMutability":"view",
    "type":"function"
}];

async function test() {
    const web3 = new Web3("https://ropsten.infura.io/v3/<Project-ID>");
    const contract = new web3.eth.Contract(ABI, ADDR);
    try {
        const retval = await contract.methods.func().call();
        console.log(retval);
    }
    catch (error) {
        console.log(error.message);
    }
}

test();

As expected, the result of running the above is an exception with the following error-message:

Returned values aren't valid, did it run Out of Gas?

As I've mentioned here in the past, you probably want to refine this message, but I've tested the above with web3.js v1.2.1, so perhaps you already have. In either case, that's not the main issue here.

The main issue is this:

When changing the value of ADDR in the script above from the address of the first contract to the address of the second contract, the (extremely odd) result is:

  1. The function-call completes successfully
  2. The returned value of it is true

And obviously, neither one of these aspects by itself could not have possibly taken place.

My analysis is that this is a bug in either Web3 or Infura.

But I tested the second contract also with ganache-cli (after deploying that contract on the local network of course), and I got:

Returned error: VM Exception while processing transaction: revert error

Which makes me more inclined to the "Infura option" (since web3.js seems to do the job well when using a different node).

Nevertheless, I am opening this issue here with a hope that you will look into it.

I have a wild speculation that while fetching the return-value of the function-call from the stack, you retrieve the first character of the message string ('e'), or perhaps the length of the message string, which you then cast to true. Perhaps the appearance of that string has "pushed" the REVERT opcode (0xfd if I remember correctly) deeper into the stack or something like that?

Thanks :)

Versions

Operating System: Windows 10:
node version: 10.16.0
npm version: 6.9.0
web3.js version: 1.2.1
ganache-cli version: 6.7.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions