0

When trying to run the test at 6:29:30 in the FreeCodeCamp tutorial with Patrick Collins, I get a brownie.exceptions.VirtualMachineError: revert when it tries to call my Lottery.getEntranceFee function. The issue has to do with the way it calls the price feed contract - simpler functions which just return numbers work fine, but when it needs to call ethUsdPriceFeed, it falls over with the uninformative VirtualMachineError: revert.

Output from failed test

I'm running this on mainnet-fork-dev as set up using the tutorial instructions, but it also doesn't work on mainnet-fork. It must be some problem with my local fork, but I don't know how to diagnose the issue, nor how to reset and start again.

Test script is:


from brownie import Lottery, accounts, network, config
from web3 import Web3


def test_get_entrance_fee():
    account = accounts[0]
    print(f"active network is {network.show_active()}")
    lottery = Lottery.deploy(
        config["networks"][network.show_active()]["eth_usd_price_feed"],
        {"from": account},
    )

    assert lottery.getVerySimplePrice().return_value > 0
    assert lottery.getSimplePrice().return_value > 0
    # assert lottery.getEntranceFee() > Web3.toWei(0.019, "ether")
    # assert lottery.getEntranceFee() < Web3.toWei(0.022, "ether")

Lottery.sol looks like:

// SPDX-License-Identifier: MIT

pragma solidity ^0.6.6;

import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";

contract Lottery {
    address payable[] public players;
    uint256 public usdEntryFee;
    uint256 internal uint256adjustedPrice;
    AggregatorV3Interface internal ethUsdPriceFeed;

    constructor(address _priceFeedAddress) public {
        usdEntryFee = 50 * (10**18); //"get everything in wei"
        ethUsdPriceFeed = AggregatorV3Interface(_priceFeedAddress);
    }

    function enter() public payable {
        //$50 minimum

        players.push(msg.sender);
    }

    function getVerySimplePrice() public returns (uint256) {
        uint256 price = 10;
        return 10;
    }

    function getSimplePrice() public returns (uint256) {
        (, int256 price, , , ) = ethUsdPriceFeed.latestRoundData();
        uint256adjustedPrice = uint256(price);

        return uint256adjustedPrice;
    }

    function getEntranceFee() public returns (uint256) {
        (, int256 price, , , ) = ethUsdPriceFeed.latestRoundData();
        uint256adjustedPrice = uint256(price) * 10**10; //"18 decimals" apparently but then why 10?

        uint256 costToEnter = (usdEntryFee * 10**18) / uint256adjustedPrice;
        return costToEnter;
    }

    function startLottery() public {}

    function endLottery() public {}
}

brownie-config.yaml looks like

dependencies:
  - smartcontractkit/chainlink-brownie-contracts@1.1.1
compiler:
  solc:
    remappings:
      - '@chainlink=smartcontractkit/chainlink-brownie-contracts@1.1.1'
networks:
  mainnet-fork-dev:
    eth_usd_price_feed: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419'
  mainnet-fork:
    eth_usd_price_feed: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419'
  development:
    eth_usd_price_feed: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419'
0

Several issues:

  1. uint256adjustedPrice should be uint256 adjustedPrice
  2. uint256 costToEnter = (usdEntryFee * 10**18) / uint256adjustedPrice should be

uint256 costToEnter = (usdEntryFee * 10**18) / adjustedPrice

  1. The assertion is failing. ETH/USD price is around $3850 as of Jan 4, 2022. $50/3850 is 0.013 . So your assert statements should be slightly below(0.012) and above(0.014) the 0.013 eter value.
3
  • Thank you for the corrections. Unfortunately core issue remains: to confirm this, I wrote a simpler function: function getSimplePrice() public returns (uint256) { (, int256 price, , , ) = ethUsdPriceFeed.latestRoundData(); uint256 adjustedPrice = uint256(price); return adjustedPrice; } assert lottery.getSimplePrice().return_value > 0 still throws the same error, and the highlighted text in the console is the ethUsdPriceFeed.latestRoundData(), suggesting that the error is being thrown when I try to access the ethUsdPriceFeed contract.
    – Nik Shah
    Jan 6 at 13:59
  • Try running the brownie test ... command with the -vs flags. Any print statements will show up. If that fails, try the brownie console command to get a live python shell, and execute your python script lines one by one until you find the offending line. Jan 7 at 15:16
  • If you're using Infura, your WEB3_INFURA_PROJECT_ID should be in the .env file and your brownie-config.yaml should have dotenv: .env in it. Jan 7 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.