'Transaction reverts when I run a contract function on mainnet-fork-dev
For reproducing the error, the code can be taken from https://github.com/Binoy-John/brownie_fund_me
So I have a contract FundMe.sol, which has several functions one of them being getEntranceFee(). It is as shown below:
// SPDX-License-Identifier: MIT
// Smart contract that lets anyone deposit ETH into the contract
// Only the owner of the contract can withdraw the ETH
pragma solidity ^0.8.0;
// Get the latest ETH/USD price from chainlink price feed
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract FundMe {
// safe math library check uint256 for integer overflows
// using SafeMathChainlink for uint256;
//mapping to store which address depositeded how much ETH
mapping(address => uint256) public addressToAmountFunded;
// array of addresses who deposited
address[] public funders;
//address of the owner (who deployed the contract)
address public owner;
//creating interface variable for use with parameterized constructor
AggregatorV3Interface public priceFeed;
// the first person to deploy the contract is
// the owner
constructor(address _priceFeed) {
owner = msg.sender;
priceFeed = AggregatorV3Interface(_priceFeed);
}
function fund() public payable {
// 18 digit number to be compared with donated amount
uint256 minimumUSD = 50 * 10**18;
//is the donated amount less than 50USD?
require(
getConversionRate(msg.value) >= minimumUSD,
"You need to spend more ETH!"
);
//if not, add to mapping and funders array
addressToAmountFunded[msg.sender] += msg.value;
funders.push(msg.sender);
}
function getEntranceFee() public view returns (uint256) {
// minimumUSD
uint256 minimumUSD = 50 * 10**18;
uint256 price = getPrice();
uint256 precision = 1 * 10**18;
return (minimumUSD * precision) / price;
}
//function to get the version of the chainlink pricefeed
function getVersion() public view returns (uint256) {
return priceFeed.version();
}
function getPrice() public view returns (uint256) {
(, int256 answer, , , ) = priceFeed.latestRoundData();
// ETH/USD rate in 18 digit
return uint256(answer * 10000000000);
}
// 1000000000
function getConversionRate(uint256 ethAmount)
public
view
returns (uint256)
{
uint256 ethPrice = getPrice();
uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;
// the actual ETH/USD conversation rate, after adjusting the extra 0s.
return ethAmountInUsd;
}
//modifier: https://medium.com/coinmonks/solidity-tutorial-all-about-modifiers-a86cf81c14cb
modifier onlyOwner() {
//is the message sender owner of the contract?
require(msg.sender == owner);
_;
}
// onlyOwner modifer will first check the condition inside it
// and
// if true, withdraw function will be executed
function withdraw() public payable onlyOwner {
// If you are using version eight (v0.8) of chainlink aggregator interface,
// you will need to change the code below to
payable(msg.sender).transfer(address(this).balance);
//msg.sender.transfer(address(this).balance);
//iterate through all the mappings and make them 0
//since all the deposited amount has been withdrawn
for (
uint256 funderIndex = 0;
funderIndex < funders.length;
funderIndex++
) {
address funder = funders[funderIndex];
addressToAmountFunded[funder] = 0;
}
//funders array will be initialized to 0
funders = new address[](0);
}
}
I use a script called deploy.py to deploy this contract and run some of its functions. It is as shown below :
from brownie import FundMe, accounts, config, network, MockV3Aggregator
from scripts.helpful_scripts import (
deploy_mocks,
get_account,
LOCAL_BLOCKCHAIN_ENVIRONMENT,
)
from web3 import Web3
def deploy_fund_me():
account = get_account()
print("account used is ", account)
if network.show_active() not in LOCAL_BLOCKCHAIN_ENVIRONMENT:
price_feed_address = config["networks"][network.show_active()][
"eth_usd_priceFeed"
]
else:
deploy_mocks()
price_feed_address = MockV3Aggregator[-1].address
fund_me = FundMe.deploy(
price_feed_address,
{"from": account},
publish_source=config["networks"][network.show_active()].get("verify"),
)
print("contract deployed to ", fund_me.address)
print("entree fee is ", fund_me.getEntranceFee())
return fund_me
def main():
deploy_fund_me()
It uses another script called helpful_scripts.py to create account and deploy mock. It is as follows:
from brownie import config, network, accounts, MockV3Aggregator
from web3 import Web3
FORKED_LOCAL_ENVIRONMENT = ["mainnet-fork", "mainnet-fork-dev"]
LOCAL_BLOCKCHAIN_ENVIRONMENT = ["development", "ganache-local"]
DECIMALS = 8
STARTING = 2000000000000000000000
def get_account():
if (
network.show_active() in LOCAL_BLOCKCHAIN_ENVIRONMENT
or network.show_active() in FORKED_LOCAL_ENVIRONMENT
):
return accounts[0]
else:
# accounts.add(config["wallets"]["from_key"])
# return config["wallets"]["from_key"]
# print(accounts.add(config["wallets"]["from_key"]))
return accounts.add(config["wallets"]["from_key"])
def deploy_mocks():
account = get_account()
print("from deploy ")
print("the active network is ", network.show_active())
print("deploying the contract")
if len(MockV3Aggregator) <= 0:
MockV3Aggregator.deploy(DECIMALS, STARTING, {"from": account})
print("Deployed a new Mock because the length of MockV3Aggregator was 0")
# print("mock aggregator is ", mock_aggregator)
print("Mock deployed!")
# print("Mocks deployed on ", mock_aggregator)
When I run deploy.py on rinkeby and ganache-cli network using $ brownie run deploy.py --network rinkeby or $ brownie run deploy.py I get the correct output as:
Attached to local RPC client listening at '127.0.0.1:8545'...
Running 'scripts\deploy.py::main'...
account used is 0xFF3c899C61625bF772bA029C50D27E33db52f2D9
from deploy
the active network is development
deploying the contract
Transaction sent: 0x9d6896cc8b2ea9ce24615a4bc6c069ab8b30e2ed44fb321677f5ffde30816338
Gas price: 0.0 gwei Gas limit: 12000000 Nonce: 104
MockV3Aggregator.constructor confirmed Block: 113 Gas used: 437447 (3.65%)
MockV3Aggregator deployed at: 0x3eD74772c3403fa96826c38D94Ad67685B25f2D0
Deployed a new Mock because the length of MockV3Aggregator was 0
Mock deployed!
Transaction sent: 0x3cffbacb081fd70860783e497a3dbf293c0d03e2a9cf78335d67ae021b209615
Gas price: 0.0 gwei Gas limit: 12000000 Nonce: 105
FundMe.constructor confirmed Block: 114 Gas used: 515717 (4.30%)
FundMe deployed at: 0xDeFd78dC7D60132FEaa39AD3f31E20738471cD08
contract deployed to 0xDeFd78dC7D60132FEaa39AD3f31E20738471cD08
entree fee is 2500000
but when I run the deploy.py using $ brownie run deploy.py --network mainnet-fork-dev It gives me the following error:
$ brownie run deploy.py --network mainnet-fork-dev
INFO: Could not find files for the given pattern(s).
Brownie v1.16.4 - Python development framework for Ethereum
BrownieFundMeProject is the active project.
C:\Users\91989\AppData\Roaming\Python\Python310\site-packages\brownie\network\main.py:44: BrownieEnvironmentWarning: Development network has a block height of 114
warnings.warn(
Attached to local RPC client listening at '127.0.0.1:8545'...
Running 'scripts\deploy.py::main'...
account used is 0xFF3c899C61625bF772bA029C50D27E33db52f2D9
Transaction sent: 0xbb0c1ab97868e2851a586fddd4b64d23ec317dbba05efd35ff9fe04e03f54e3a
Gas price: 0.0 gwei Gas limit: 12000000 Nonce: 106
FundMe.constructor confirmed Block: 115 Gas used: 515717 (4.30%)
FundMe deployed at: 0x948E3BA0dE6FADCE5e1459F5432A48Ef3DC7F70b
contract deployed to 0x948E3BA0dE6FADCE5e1459F5432A48Ef3DC7F70b
File "C:\Users\91989\AppData\Roaming\Python\Python310\site-packages\brownie\_cli\run.py", line 49,
in main
return_value, frame = run(
File "C:\Users\91989\AppData\Roaming\Python\Python310\site-packages\brownie\project\scripts.py", line 103, in run
return_value = f_locals[method_name](*args, **kwargs)
File ".\scripts\deploy.py", line 32, in main
deploy_fund_me()
File ".\scripts\deploy.py", line 27, in deploy_fund_me
print("entree fee is ", fund_me.getEntranceFee())
File "C:\Users\91989\AppData\Roaming\Python\Python310\site-packages\brownie\network\multicall.py",
line 115, in _proxy_call
result = ContractCall.__call__(*args, **kwargs) # type: ignore
File "C:\Users\91989\AppData\Roaming\Python\Python310\site-packages\brownie\network\contract.py", line 1729, in __call__
return self.call(*args, block_identifier=block_identifier)
File "C:\Users\91989\AppData\Roaming\Python\Python310\site-packages\brownie\network\contract.py", line 1533, in call
raise VirtualMachineError(e) from None
File "C:\Users\91989\AppData\Roaming\Python\Python310\site-packages\brownie\exceptions.py", line 104, in __init__
raise ValueError(exc["message"]) from None
ValueError: VM Exception while processing transaction: revert
So I am facing this issue only when running it on the mainnet-fork-dev and nowhere else. I am confused about how to solve this problem, so any help would be appreciated!
Please let me know if you need more info.
Thanks in advance!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|