Lesson 9: "Error: invalid BigNumber value (argument="value", value=undefined, code=INVALID_ARGUMENT," #1826
-
I'm trying to run Raffle.test and I'm running into this error: " ERROR processing /home/emmanuelf37/hh-fcc/hardhat-smartcontract-lottery-fcc/deploy/01-deploy-raffle.js: Error: invalid BigNumber value (argument="value", value=undefined, code=INVALID_ARGUMENT, " Raffle.test.js const { inputToConfig } = require("@ethereum-waffle/compiler")
const { assert } = require("chai")
const { getNamedAccounts, deployments, network, ethers } = require("hardhat")
const { developmentChains, networkConfig } = require("../../helper-hardhat-config")
!developmentChains.includes(network.name)
? describe.skip
: describe("Raffle Unit Tests", async function () {
let raffle, vrfCoordinatorV2Mock
const chainId = network.config.chainId
// ^^ chainId here returns undefined
beforeEach(async function () {
const { deployer } = await getNamedAccounts()
await deployments.fixture(["all"])
raffle = await ethers.getContract("Raffle", deployer)
vrfCoordinatorV2Mock = await ethers.getContract("VRFCoordinatorV2Mock", deployer)
})
describe("constructor", async function () {
it("initializes the raffle correctly", async function () {
const raffleState = await raffle.getRaffleState()
const interval = await raffle.getInterval()
assert.equal(raffleState.toString(), "0")
assert.equal(interval.toString(), networkConfig[chainId]["interval"])
// and also chainId here ^^
})
})
}) helper-hardhat.config.js const { network, ethers } = require("hardhat")
const networkConfig = {
default: {
name: "hardhat",
keepersUpdateInterval: "30",
},
31337: {
name: "localhost",
subscriptionId: "588",
gasLane: "0xd89b2bf150e3b9e13446986e571fb9cab24b13cea0a43ea20a6049a85cc807cc", // 30 gwei
keepersUpdateInterval: "30",
raffleEntranceFee: "100000000000000000", // 0.1 ETH
callbackGasLimit: "500000", // 500,000 gas
},
4: {
name: "rinkeby",
subscriptionId: "6926",
gasLane: "0xd89b2bf150e3b9e13446986e571fb9cab24b13cea0a43ea20a6049a85cc807cc", // 30 gwei
keepersUpdateInterval: "30",
raffleEntranceFee: "100000000000000000", // 0.1 ETH
callbackGasLimit: "500000", // 500,000 gas
vrfCoordinatorV2: "0x6168499c0cFfCaCD319c818142124B7A15E857ab",
},
1: {
name: "mainnet",
keepersUpdateInterval: "30",
},
}
const developmentChains = ["hardhat", "localhost"]
module.exports = {
networkConfig,
developmentChains,
} hardhat.config.js require("@nomiclabs/hardhat-waffle")
require("@nomiclabs/hardhat-etherscan")
require("hardhat-deploy")
require("solidity-coverage")
require("hardhat-gas-reporter")
require("hardhat-contract-sizer")
require("dotenv").config()
/** @type import('hardhat/config').HardhatUserConfig */
const COINMARKETCAP_API_KEY = process.env.COINMARKETCAP_API_KEY || ""
const KOVAN_RPC_URL =
process.env.KOVAN_RPC_URL ||
"https://eth-mainnet.alchemyapi.io/v2/your-api-key"
const RINKEBY_RPC_URL =
process.env.RINKEBY_RPC_URL ||
"https://eth-mainnet.alchemyapi.io/v2/your-api-key"
const PRIVATE_KEY =
process.env.PRIVATE_KEY ||
"0x11ee3108a03081fe260ecdc106554d09d9d1209bcafd46942b10e02943effc4a"
const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY || ""
const API_URL =
process.env.API_URL ||
"https://eth-rinkeby.alchemyapi.io/v2/UoxMYEe56_n36Ya5-uavkt_TjPOSgMF0"
module.exports = {
solidity: "0.8.7",
defaultNetwork: "hardhat",
networks: {
hardhat: {
chainId: 31337,
blockConfirmations: 1,
},
rinkeby: {
chainId: 4,
blockConfirmations: 6,
url: RINKEBY_RPC_URL,
accounts: [PRIVATE_KEY],
},
},
namedAccounts: {
deployer: {
default: 0,
1: 0,
},
player: {
default: 1,
},
},
};
Raffle.sol // Raffle
// Enter the lottery (paying some amount)
// pick a random winner (verifiably random)
// Winner to be selected every X minutes --> completely automated
// Chainlink Oracle --> Randomness, Automated Execution (Chainlink Keeper)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/KeeperCompatible.sol";
import "hardhat/console.sol";
error Raffle__NotEnoughETHEntered();
error Raffle__TransferFailed();
error Raffle__NotOpen();
error Raffle__UpkeepNotNeeded(uint256 currentBalance, uint256 numPlayers, uint256 RaffleState);
/** @title A sample Raffle Contract
* @author Patrick Collins
* @notice This contract is for creating an untamperable decentralized smart contract
* @dev This implements Chainlink VRF v2 and Chainlilnk Keepers
*/
contract Raffle is VRFConsumerBaseV2, KeeperCompatibleInterface {
/* Type declarations */
enum RaffleState {
OPEN,
CALCULATING
} //uint256 0 = OPEN, 1 = CALCULATING
/* State Variables */
uint256 private immutable i_entranceFee;
address payable[] private s_players;
VRFCoordinatorV2Interface private immutable i_vrfCoordinator;
bytes32 private immutable i_gasLane;
uint64 private immutable i_subscriptionId;
uint16 private constant REQUEST_CONFIRMATIONS = 3;
uint32 private immutable i_callbackGasLimit;
uint32 private constant NUM_WORDS = 1;
// Lottery Variables
address private s_recentWinner;
bool private s_state; // to pending, open, closed, calculating
RaffleState private s_raffleState;
uint256 private s_lastTimeStamp;
uint256 private immutable i_interval;
/* Events */
event RaffleEnter(address indexed player);
event RequestedRaffleWinner(uint256 indexed requestId);
event WinnerPicked(address indexed winner);
/* Functions */
constructor(
address vrfCoordinatorV2,
uint64 subscriptionId,
bytes32 gasLane, // keyHash
uint256 interval,
uint256 entranceFee,
uint32 callbackGasLimit
) VRFConsumerBaseV2(vrfCoordinatorV2) {
i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
i_subscriptionId = subscriptionId;
i_gasLane = gasLane;
i_interval = interval;
i_entranceFee = entranceFee;
i_callbackGasLimit = callbackGasLimit;
s_raffleState = RaffleState.OPEN;
s_lastTimeStamp = block.timestamp;
}
function enterRaffle() public payable {
if (msg.value < i_entranceFee) {
revert Raffle__NotEnoughETHEntered();
}
if (s_raffleState != RaffleState.OPEN) {
revert Raffle__NotOpen();
}
s_players.push(payable(msg.sender));
// Emit an event when we update a dynamic array or mapping
// Named events with the function name reversed
emit RaffleEnter(msg.sender);
}
/**
* @dev This is the function that the Chainlink Keeper nodes call
* they look for thhe `upkeepNeeded` to return true.
* The following should be true in order to return true:
* 1. Our time interval should have passed
* 2. The lottery should have at least 1 player, and have some ETH
* 3. Our subscription is funded with LINK
* 4. The lottery should be in an "open" state.
*/
function checkUpkeep(
bytes memory /*checkData */
)
public
view
override
returns (
bool upkeepNeeded,
bytes memory /* performData */
)
{
bool isOpen = (RaffleState.OPEN == s_raffleState);
bool timePassed = ((block.timestamp - s_lastTimeStamp) > i_interval);
bool hasPlayers = (s_players.length > 0);
bool hasBalance = address(this).balance > 0;
upkeepNeeded = (isOpen && timePassed && hasPlayers && hasBalance);
}
function performUpkeep(
bytes calldata /* performData */
) external override {
(bool upkeepNeeded, ) = checkUpkeep("");
if (!upkeepNeeded) {
revert Raffle__UpkeepNotNeeded(
address(this).balance,
s_players.length,
uint256(s_raffleState)
);
}
s_raffleState = RaffleState.CALCULATING;
uint256 requestId = i_vrfCoordinator.requestRandomWords(
i_gasLane, //gasLane
i_subscriptionId,
REQUEST_CONFIRMATIONS,
i_callbackGasLimit,
NUM_WORDS
);
emit RequestedRaffleWinner(requestId);
}
function fulfillRandomWords(
uint256, /* requestId */
uint256[] memory randomWords
) internal override {
uint256 indexOfWinner = randomWords[0] % s_players.length;
address payable recentWinner = s_players[indexOfWinner];
s_recentWinner = recentWinner;
s_raffleState = RaffleState.OPEN;
s_players = new address payable[](0);
s_lastTimeStamp = block.timestamp;
(bool success, ) = recentWinner.call{value: address(this).balance}("");
// require(success)
if (!success) {
revert Raffle__TransferFailed();
}
emit WinnerPicked(recentWinner);
}
/* View / Pure functions */
function getEntranceFee() public view returns (uint256) {
return i_entranceFee;
}
function getPlayer(uint256) public view returns (address) {
uint256 index;
return s_players[index];
}
function getRecentWinner() public view returns (address) {
return s_recentWinner;
}
function getRaffleState() public view returns (RaffleState) {
return s_raffleState;
}
function getNumWords() public pure returns (uint256) {
return NUM_WORDS;
}
function getNumberOfPlayers() public view returns (uint256) {
return s_players.length;
}
function getLatestTimestamp() public view returns (uint256) {
return s_lastTimeStamp;
}
function getRequestConfirmations() public pure returns (uint256) {
return REQUEST_CONFIRMATIONS;
}
function getInterval() public view returns(uint256) {
return i_interval;
}
} 01-deploy-raffle.js const { network, ethers } = require("hardhat")
const { developmentChains, networkConfig } = require("../helper-hardhat-config")
const { verify } = require("../helper-hardhat-config")
const VRF_SUB_FUND_AMOUNT = ethers.utils.parseEther("2")
module.exports = async ({ getNamedAccounts, deployments }) => {
const { deploy, log } = deployments
const { deployer } = await getNamedAccounts()
const chainId = network.config.chainId
let vrfCoordinatorV2Address, subscriptionId
if (developmentChains.includes(network.name)) {
const vrfCoordinatorV2Mock = await ethers.getContract("VRFCoordinatorV2Mock")
vrfCoordinatorV2Address = vrfCoordinatorV2Mock.address
const transactionResponse = await vrfCoordinatorV2Mock.createSubscription()
const transactionReceipt = await transactionResponse.wait(1)
subscriptionId = transactionReceipt.events[0].args.subId
// Fund the subscription
// Usually, you'd need the link token on a real network
await vrfCoordinatorV2Mock.fundSubscription(subscriptionId, VRF_SUB_FUND_AMOUNT)
} else {
vrfCoordinatorV2Address = networkConfig[chainId]["vrfCoordinatorV2"]
subscriptionId = networkConfig[chainId]["subscriptionId"]
}
const entranceFee = networkConfig[chainId]["entranceFee"]
const gasLane = networkConfig[chainId]["gasLane"]
const callbackGasLimit = networkConfig[chainId]["callbackGasLimit"]
const interval = networkConfig[chainId]["interval"]
const args = [
vrfCoordinatorV2Address,
entranceFee,
gasLane,
subscriptionId,
callbackGasLimit,
interval,
]
const raffle = await deploy("Raffle", {
from: deployer,
args: args,
log: true,
waitConfirmations: network.config.blockConfirmations || 1,
})
if (!developmentChains.includes(network.name) && process.env.ETHERSCAN_API_KEY) {
log("Verifying...")
await verify(raffle.address, args)
}
log("-----------------------------------------------------")
}
module.exports.tags = ["all", "raffle"] Please let me know if you need anything else from me! |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
I was getting the same error - here is how I fixed it This must follow the same order as the const args |
Beta Was this translation helpful? Give feedback.
-
First in helper-hardhat-config.js 31337: {
name: "localhost",
subscriptionId: "588",
gasLane: "0xd89b2bf150e3b9e13446986e571fb9cab24b13cea0a43ea20a6049a85cc807cc", // 30 gwei
keepersUpdateInterval: "30",
raffleEntranceFee: "100000000000000000", // 0.1 ETH
callbackGasLimit: "500000", // 500,000 gas
}, with 31337: {
name: "hardhat",
entranceFee: ethers.utils.parseEther("0.01"),
gasLane: "0xd89b2bf150e3b9e13446986e571fb9cab24b13cea0a43ea20a6049a85cc807cc",
subscriptionId: "0",
callbackGasLimit: "500000",
interval: "30",
}, the arguments in 01-deploy-raffle.js script should be in same order as specified in contract constructor in raffle.sol: constructor(
address vrfCoordinatorV2,
uint64 subscriptionId,
bytes32 gasLane, // keyHash
uint256 interval,
uint256 entranceFee,
uint32 callbackGasLimit
) in 01-deploy-raffle.js script change the arguments to const args = [
vrfCoordinatorV2Address,
subscriptionId,
gasLane,
interval,
entranceFee,
callbackGasLimit,
] |
Beta Was this translation helpful? Give feedback.
First in helper-hardhat-config.js
Replace this:
with
the arguments in 01-deploy-raffle.js script should be in same order as specified in contract constructor…