-
Hi community 👋, I am getting an error while trying to run a checkUpkeep() unit test on hardhat. My Raffle.test.js file: const { assert, expect } = require("chai");
const { network, getNamedAccounts, ethers, deployments } = require("hardhat");
const {
developmentChains,
networkConfig,
} = require("../../helper-hardhat-config");
!developmentChains.includes(network.name)
? describe.skip
: describe("Raffle", async function () {
let raffle, vrfCoordinatorV2Mock, raffleEntranceFee, deployer, interval;
const chainId = network.config.chainId;
beforeEach(async function () {
deployer = (await getNamedAccounts()).deployer;
await deployments.fixture(["all"]);
raffle = await ethers.getContract("Raffle", deployer);
vrfCoordinatorV2Mock = await ethers.getContract(
"VRFCoordinatorV2Mock",
deployer
);
raffleEntranceFee = await raffle.getEntranceFee();
interval = await raffle.getInterval();
});
describe("constructor", async function () {
it("initializes the raffle correctly", async function () {
const raffleState = await raffle.getRaffleState();
assert.equal(raffleState.toString(), "0");
assert.equal(interval.toString(), networkConfig[chainId]["interval"]);
});
});
describe("enterRaffle", async function () {
it("Reverts if you don't pay enough", async function () {
await expect(raffle.enterRaffle()).to.be.revertedWith(
"Raffle__NotEnoughETHEntered"
);
});
it("Records player when they enter", async function () {
await raffle.enterRaffle({ value: raffleEntranceFee });
const playerFromContract = await raffle.getPlayer(0);
assert.equal(playerFromContract, deployer);
});
it("Emits event on enter", async function () {
await expect(
raffle.enterRaffle({ value: raffleEntranceFee })
).to.emit(raffle, "RaffleEnter");
});
it("Doesn't allow entrance when Raffle is calculating", async function () {
await raffle.enterRaffle({ value: raffleEntranceFee });
await network.provider.send("evm_increaseTime", [
interval.toNumber() + 1,
]);
await network.provider.send("evm_mine", []);
// We pretend to be a Chainlink keeper
await raffle.performUpkeep([]);
await expect(
raffle.enterRaffle({ value: raffleEntranceFee })
).to.be.revertedWith("Raffle__NotOpen");
});
});
describe("checkUpkeep", async function () {
it("Returns false if people haven't sent any ETH", async function () {
await network.provider.send("evm_increaseTime", [
interval.toNumber() + 1,
]);
await network.provider.send("evm_mine", []);
const { upKeepNeeded } = await raffle.callStatic.checkUpkeep([]);
assert(!upKeepNeeded);
});
it("Returns false if raffle isn't open", async function () {
await raffle.enterRaffle({ value: raffleEntranceFee });
await network.provider.send("evm_increaseTime", [
interval.toNumber() + 1,
]);
await network.provider.send("evm_mine", []);
await raffle.performUpkeep([]);
const raffleState = await raffle.getRaffleState();
const { upKeepNeeded } = await raffle.callStatic.checkUpkeep();
assert.equal(raffleState.toString(), "1");
assert.equal(upKeepNeeded, false);
});
});
}); My Raffle.sol file: // 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";
error Raffle__NotEnoughETHEntered();
error Raffle__TransferFailed();
error Raffle__NotOpen();
error Raffle__UpkeepNotNeeded(
uint256 currentBalance,
uint256 numPlayers,
uint256 raffleState
);
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;
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);
constructor(
address vrfCoordinatorV2,
uint256 entranceFee,
bytes32 gasLane,
uint64 subscriptionId,
uint32 callbackGasLimit,
uint256 interval
) VRFConsumerBaseV2(vrfCoordinatorV2) {
i_entranceFee = entranceFee; //set entrance fee
i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
i_gasLane = gasLane;
i_subscriptionId = subscriptionId;
i_callbackGasLimit = callbackGasLimit;
s_raffleState = RaffleState.OPEN;
s_lastTimeStamp = block.timestamp;
i_interval = interval;
}
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 The following should be true in order to return true:
* 1. Our time interval should have passed
* 2. The lottery should have atleast 1 player, and have some ETH
* 3. Our subscription is funded with LINK
* 4. Lottery should be in "open" state
*/
function checkUpkeep(
bytes memory /* checkData */
)
public
override
returns (
bool upKeepNeeded,
bytes memory /* performData */
)
{
bool isOpen = (RaffleState.OPEN == s_raffleState);
// (block.timestamp - last block timestamp) > interval
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)
);
}
// Request random number
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}("");
if (!success) {
revert Raffle__TransferFailed();
}
emit WinnerPicked(recentWinner);
}
/* View / Pure functions */
function getEntranceFee() public view returns (uint256) {
return i_entranceFee;
}
function getPlayer(uint256 index) public view returns (address) {
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;
}
} |
Beta Was this translation helpful? Give feedback.
Answered by
Rishi860
Jul 23, 2022
Replies: 1 comment 1 reply
-
This const { upKeepNeeded } = await raffle.callStatic.checkUpkeep([]); instead of const { upKeepNeeded } = await raffle.callStatic.checkUpkeep(); |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
LucidJoy
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
checkUpkeep()
function requires a bytes type value. Use[]
or"0x"
.This
instead of