full-blockchain-solidity-course-py icon indicating copy to clipboard operation
full-blockchain-solidity-course-py copied to clipboard

ValueError: Gas estimation failed: 'execution reverted: VM Exception while processing transaction: revert'. This transaction will likely revert. If you wish to broadcast, you must set the gas limit manually.

Open supercede opened this issue 2 years ago • 6 comments

  • When writing tests for the Brownie Fund Me application in the environments that make use of ganache (ganache-local), the test_only_owner_can_withdraw test fails even though the deploy fund_and_withdraw function runs perfectly. I get the error above when I run the test.
  • The test that fails for ganache-local:
def test_only_owner_can_withdraw():
   if network.show_active() not in LOCAL_ENVIRONMENTS:
       pytest.skip("This test only runs in local environments")
   bad_actor = accounts.add()
   print(f"bad actor ==> {bad_actor}")
   fund_me = deploy_fundme()
   print(f"priceeeeeeee {fund_me.getPrice()}")
   with pytest.raises(exceptions.VirtualMachineError):
       fund_me.withdraw({"from": bad_actor})
  • The fund and withdraw test functions (passes):
def test_funding_and_withdrawal():
    account = get_account()
    print(f"account ==> {account}")
    fund_me = deploy_fundme()
    print(f"fund_me ==> {fund_me}")
    entrance_fee = fund_me.getEntranceFee()
    print(f"entrance_fee ==> {entrance_fee}")

    tx = fund_me.fund({"from": account, "value": entrance_fee})
    tx.wait(1)
    assert fund_me.fundersMap(account.address) == entrance_fee

    tx2 = fund_me.withdraw({"from": account})
    tx2.wait(1)
    assert fund_me.fundersMap(account.address) == 0
  • The complete error log:
brownie test -k  test_only_owner_can_withdraw --network ganache-local -s
Brownie v1.18.1 - Python development framework for Ethereum

============================================================================================ test session starts ============================================================================================
platform linux -- Python 3.8.10, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- /home/d3st1ny/.local/pipx/venvs/eth-brownie/bin/python
cachedir: .pytest_cache
hypothesis profile 'brownie-verbose' -> verbosity=2, deadline=None, max_examples=50, stateful_step_count=10, report_multiple_bugs=False, database=DirectoryBasedExampleDatabase(PosixPath('/home/d3st1ny/.brownie/hypothesis'))
rootdir: /home/d3st1ny/projects/web3/brownie_fund_me
plugins: eth-brownie-1.18.1, forked-1.4.0, hypothesis-6.27.3, web3-5.27.0, xdist-1.34.0
collected 2 items / 1 deselected / 1 selected                                                                                                                                                               

tests/test_fund_me.py::test_only_owner_can_withdraw RUNNING
mnemonic: 'ensure weather acoustic oyster time release stock memory pink sudden regular photo'
bad actor ==> 0x848ec101C82F747CFa4B75262A28C055bF965FC4
using development environment
using mock aggregator at 0x3194cBDC3dbcd3E11a07892e7bA5c3394048Cc87
Contract deployed to 0xe692Cf21B12e0B2717C4bF647F9768Fa58861c8b
priceeeeeeee 2000000000000000000000
tests/test_fund_me.py::test_only_owner_can_withdraw FAILED

================================================================================================= FAILURES ==================================================================================================
_______________________________________________________________________________________ test_only_owner_can_withdraw ________________________________________________________________________________________

    def test_only_owner_can_withdraw():
        if network.show_active() not in LOCAL_ENVIRONMENTS:
            pytest.skip("This test only runs in local environments")
        bad_actor = accounts.add()
        print(f"bad actor ==> {bad_actor}")
        fund_me = deploy_fundme()
        print(f"priceeeeeeee {fund_me.getPrice()}")
        with pytest.raises(exceptions.VirtualMachineError):
>           fund_me.withdraw({"from": bad_actor})
E           ValueError: Gas estimation failed: 'execution reverted: VM Exception while processing transaction: revert'. This transaction will likely revert. If you wish to broadcast, you must set the gas limit manually.

tests/test_fund_me.py:32: ValueError
tests/test_fund_me.py::test_only_owner_can_withdraw ========================================================================================== short test summary info ==========================================================================================
FAILED tests/test_fund_me.py::test_only_owner_can_withdraw - ValueError: Gas estimation failed: 'execution reverted: VM Exception while processing transaction: revert'. This transaction will likely reve...
====================================================================================== 1 failed, 1 deselected in 0.32s ======================================================================================
  • When I add a gas limit as such:
with pytest.raises(exceptions.VirtualMachineError):
        fund_me.withdraw({"from": bad_actor, "gas_limit": 6721975})

The error message turns into: ValueError: Execution reverted during call: 'VM Exception while processing transaction: revert'. This transaction will likely revert. If you wish to broadcast, include allow_revert:True as a transaction parameter.

Other useful files:

  • helpers.py
from brownie import network, accounts, config, MockV3Aggregator

DECIMALS = 8  # Price feed aggregator usually returns 8 decimals
STARTING_PRICE = 200000000000  # 2000 + 8 decimals
LOCAL_ENVIRONMENTS = ["development", "ganache-local"]
FORKED_LOCAL_ENVIRONMENTS = ["mainnet-fork", "mainnet-fork-dev"]


def get_account():
    if (
        network.show_active() in LOCAL_ENVIRONMENTS
        or network.show_active() in FORKED_LOCAL_ENVIRONMENTS
    ):
        return accounts[0]
    else:
        return accounts.add(config["wallets"]["from_key"])


def deploy_mocks():
    if len(MockV3Aggregator) <= 0:
        print("deploying mock aggregator")
        mock_aggregator = MockV3Aggregator.deploy(
            DECIMALS, STARTING_PRICE, {"from": get_account()}
        )
        print(f"deployed mock aggregator to address {mock_aggregator.address}")
  • deploy.py (works fine)
from brownie import FundMe, config, network, MockV3Aggregator
from scripts.helpers import get_account, deploy_mocks, LOCAL_ENVIRONMENTS


def deploy_fundme():
    account = get_account()
    if network.show_active() not in LOCAL_ENVIRONMENTS:

        print(f"using {network.show_active()} environment")

        price_feed_address = config["networks"][network.show_active()][
            "eth_usd_price_feed"
        ]
    else:
        print("using development environment")
        deploy_mocks()

        price_feed_address = MockV3Aggregator[-1].address
        print(f"using mock aggregator at {price_feed_address}")

    fund_me = FundMe.deploy(
        price_feed_address,
        {"from": account},
        publish_source=config["networks"][network.show_active()].get("verify"),
    )
    print(f"Contract deployed to {fund_me.address}")
    return fund_me


def main():
    deploy_fundme()

  • fund_and_withdraw.py (works fine)
from brownie import FundMe, accounts


def fund():
    fund_me = FundMe[-1]
    account = accounts[0]
    entrance_fee = fund_me.getEntranceFee()
    print("The current entrance fee is {entrance_fee}")
    fund_me.fund({"from": account, "value": entrance_fee})


def withdraw():
    fund_me = FundMe[-1]
    account = accounts[0]

    fund_me.withdraw({"from": account})


def main():
    fund()
    withdraw()

supercede avatar Apr 18 '22 21:04 supercede

Hi, I got the same issue and thanks to your post, I could manage a quick fix, which is however not completely satisfactory. I invite you to read the issue I posted today (it doesn't contain the quick fix, as I hadn't found it yet): https://github.com/smartcontractkit/full-blockchain-solidity-course-py/issues/1442

Quick fix

As you noted, when you fix the gas_limit parameter you then get the following error.

ValueError: Execution reverted during call: 'VM Exception while processing transaction: revert'. This transaction will likely revert. If you wish to broadcast, include allow_revert:True as a transaction parameter.

If you try to add the parameter allow_revert: true you'll have the following error: fund_me.withdraw({"from": bad_actor,"gas_limit":12000000,"allow_revert":True})

ValueError: sender doesn't have enough funds to send tx. The upfront cost is: 240000000000000000 and the sender's account only has: 0

Which is not surprising, because for some reason when you use the method accounts.add() to create the bad_actor, it generates an empty account with a balance of 0. I looked it up but don't know how to change that. Therefore, if you fix the gas_price to 0, the code should work. In other words the following line should solve your issue: fund_me.withdraw({"from": bad_actor,"gas_price":0,"gas_limit":12000000,"allow_revert":True})

Alternatively you can also replace bad_actor, by any other account in the accounts list (except account[0] the actual owner), for example, this line will also work: fund_me.withdraw({"from": accounts[3],"gas_limit":12000000,"allow_revert":True})

Note that the gas_limit has been fixed at 1200000 because above that, the test fails in the development network with the following message (this is linked to the default configuration of the development network) :

ValueError: Exceeds block gas limit

Exploring the problem

With regards to the sender's account only has: 0 error, it might be a property of the method accounts.add() that the account created has a balance of 0 or a property of the network on which it is created, I am not sure. It might be possible to redefine this in the network config, but I didn't find any way to do it.

My gut feeling is that the primary issue is linked to the default network config.
https://eth-brownie.readthedocs.io/en/stable/config.html#config I believe that our ganache-local network has the default properties of a live network since it is not natively a development network. And as you can see in the link development and live network have differing properties such including the following:

gas_limit
gas_buffer
gas_price
reverting_tx_gas_limit

My guess is that one or several of them are responsible for the problem. I tried to change the brownie-config.yaml to play with these parameters, but I am not sure if I am operating correctly.

It is possible that it is linked to the version of Ganache we work with. I work with Ganache 7.0.5, while I think the video was made with Ganache 6.x.x

Other useful advice

If you haven't try already, I suggest that you try to explore a bit with a debugger, it makes it easier to understand your issues. You might be luckier than me in finding a more satisfactory solution.

If you work with vscode you can create .vscode folder in your working folder (brownie_fund_me) and create the launch.json with the code below in it. It will allow you to debug your python code, and run some inline command to check your variables and all during code execution. Pretty useful for troubleshooting. You need to adapt "pythonPath" and "program" to your ownenvironment. Also, you may need to copy brownie.exe to be in the same folder as your brownie package folder. Let me know if you have any problem with that.

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Brownie Test",
            "type": "python",
            "request": "launch",
            "pythonPath": "D:/Anaconda3/envs/blockchain/python.exe",
            "program":"D:/Anaconda3/envs/blockchain/lib/site-packages/brownie.exe",
            "console": "integratedTerminal",
            "args": ["test","-s","--network","ganache-local"],
        },

        {
            "name": "Brownie Debug",
            "type": "python",
            "request": "launch",
            "pythonPath": "D:/Anaconda3/envs/blockchain/python.exe",
            "program":"D:/Anaconda3/envs/blockchain/lib/site-packages/brownie.exe",
            "console": "integratedTerminal",
            "args": ["run","scripts/deploy.py","--network","ganache-local"],
        }
    ]
}

Main questions

How to create a bad_actor account that is prefunded? Is the problem linked to the Ganache version? Is the error linked to the properties of the network, and if it is the case how to change them?

kthibault77 avatar Apr 25 '22 08:04 kthibault77

You need to use the addresses from Chainlink VRF v1 NOT v2 in your .yaml, remember to re-deploy your contract with these newly updated addresses. Please see the link below for the addresses: https://docs.chain.link/docs/vrf/v1/supported-networks/ https://stackoverflow.com/questions/71194882/execution-reverted-during-call-this-transaction-will-likely-revert-if-you-wish

Ed-Marcavage avatar Oct 02 '22 03:10 Ed-Marcavage

The same issue. Relly weird behavior, has two different types of errors raised by require in developement and local ganache chain.

T1murKO avatar Oct 02 '22 09:10 T1murKO

Try deploying to Goerli

Ed-Marcavage avatar Oct 02 '22 22:10 Ed-Marcavage

You need to use the addresses from Chainlink VRF v1 NOT v2 in your .yaml, remember to re-deploy your contract with these newly updated addresses. Please see the link below for the addresses: https://docs.chain.link/docs/vrf/v1/supported-networks/ https://stackoverflow.com/questions/71194882/execution-reverted-during-call-this-transaction-will-likely-revert-if-you-wish

I have checked everything, my addresses are from v1. Still have the error. I am using Goerli

Actually, my error is slightly different: Gas estimation failed: 'execution reverted: 2'. This transaction will likely revert. If you wish to broadcast, you must set the gas limit manually.

Cosmodude avatar Oct 22 '22 02:10 Cosmodude

Hi, I got the same issue and thanks to your post, I could manage a quick fix, which is however not completely satisfactory. I invite you to read the issue I posted today (it doesn't contain the quick fix, as I hadn't found it yet): #1442

Quick fix

As you noted, when you fix the gas_limit parameter you then get the following error.

ValueError: Execution reverted during call: 'VM Exception while processing transaction: revert'. This transaction will likely revert. If you wish to broadcast, include allow_revert:True as a transaction parameter.

If you try to add the parameter allow_revert: true you'll have the following error: fund_me.withdraw({"from": bad_actor,"gas_limit":12000000,"allow_revert":True})

ValueError: sender doesn't have enough funds to send tx. The upfront cost is: 240000000000000000 and the sender's account only has: 0

Which is not surprising, because for some reason when you use the method accounts.add() to create the bad_actor, it generates an empty account with a balance of 0. I looked it up but don't know how to change that. Therefore, if you fix the gas_price to 0, the code should work. In other words the following line should solve your issue: fund_me.withdraw({"from": bad_actor,"gas_price":0,"gas_limit":12000000,"allow_revert":True})

Alternatively you can also replace bad_actor, by any other account in the accounts list (except account[0] the actual owner), for example, this line will also work: fund_me.withdraw({"from": accounts[3],"gas_limit":12000000,"allow_revert":True})

Note that the gas_limit has been fixed at 1200000 because above that, the test fails in the development network with the following message (this is linked to the default configuration of the development network) :

ValueError: Exceeds block gas limit

Exploring the problem

With regards to the sender's account only has: 0 error, it might be a property of the method accounts.add() that the account created has a balance of 0 or a property of the network on which it is created, I am not sure. It might be possible to redefine this in the network config, but I didn't find any way to do it.

My gut feeling is that the primary issue is linked to the default network config. https://eth-brownie.readthedocs.io/en/stable/config.html#config I believe that our ganache-local network has the default properties of a live network since it is not natively a development network. And as you can see in the link development and live network have differing properties such including the following:

gas_limit
gas_buffer
gas_price
reverting_tx_gas_limit

My guess is that one or several of them are responsible for the problem. I tried to change the brownie-config.yaml to play with these parameters, but I am not sure if I am operating correctly.

It is possible that it is linked to the version of Ganache we work with. I work with Ganache 7.0.5, while I think the video was made with Ganache 6.x.x

Other useful advice

If you haven't try already, I suggest that you try to explore a bit with a debugger, it makes it easier to understand your issues. You might be luckier than me in finding a more satisfactory solution.

If you work with vscode you can create .vscode folder in your working folder (brownie_fund_me) and create the launch.json with the code below in it. It will allow you to debug your python code, and run some inline command to check your variables and all during code execution. Pretty useful for troubleshooting. You need to adapt "pythonPath" and "program" to your ownenvironment. Also, you may need to copy brownie.exe to be in the same folder as your brownie package folder. Let me know if you have any problem with that.

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Brownie Test",
            "type": "python",
            "request": "launch",
            "pythonPath": "D:/Anaconda3/envs/blockchain/python.exe",
            "program":"D:/Anaconda3/envs/blockchain/lib/site-packages/brownie.exe",
            "console": "integratedTerminal",
            "args": ["test","-s","--network","ganache-local"],
        },

        {
            "name": "Brownie Debug",
            "type": "python",
            "request": "launch",
            "pythonPath": "D:/Anaconda3/envs/blockchain/python.exe",
            "program":"D:/Anaconda3/envs/blockchain/lib/site-packages/brownie.exe",
            "console": "integratedTerminal",
            "args": ["run","scripts/deploy.py","--network","ganache-local"],
        }
    ]
}

Main questions

How to create a bad_actor account that is prefunded? Is the problem linked to the Ganache version? Is the error linked to the properties of the network, and if it is the case how to change them?

Thanks, @kthibault77 One of these two works for me.

fund_me.withdraw({"from": bad_actor,"gas_price":0,"gas_limit":12000000,"allow_revert":True})

OR

fund_me.withdraw({"from": accounts[3],"gas_limit":12000000,"allow_revert":True})

BTW, the ENV version for me as following:

  • OS Distributor ID: Ubuntu Description: Ubuntu 22.04.1 LTS Release: 22.04 Codename: jammy

  • Python3 Python 3.10.6

  • Pip pip 22.0.2

  • Brownie Brownie v1.19.2

  • Ganache-cli Ganache CLI v6.12.2

My codes

def test_only_owner_can_withdraw():
    if network.show_active() not in LOCAL_BLOCKCHAIN_ENVIRONMENTS:
        pytest.skip("only for local testing")
    fund_me = deploy_fund_me()
    bad_actor = accounts.add()
    with pytest.raises(exceptions.VirtualMachineError):
        fund_me.withdraw(
            {
                "from": bad_actor,
                "gas_price": 0,
                "gas_limit": 12000000,
                "allow_revert": True,
            }
        )

OR

def test_only_owner_can_withdraw():
    if network.show_active() not in LOCAL_BLOCKCHAIN_ENVIRONMENTS:
        pytest.skip("only for local testing")
    fund_me = deploy_fund_me()
    bad_actor = accounts[1]
    with pytest.raises(exceptions.VirtualMachineError):
        fund_me.withdraw(
            {"from": bad_actor, "gas_limit": 12000000, "allow_revert": True}
        )

denchance avatar Nov 05 '22 12:11 denchance