You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am completely stuck at testing my raffle contract at the "doesn't allow entrance when raffle is calculating" unit test. I am using the Ethers V6, which is probably the reason why it is not working, but I would like to figure out the v6 since I already did the v5 version.
Since other tests are working, I am assuming that the error has something to do with the performUpkeep function, but I don't know how to solve it after scouring the internet for days.
This is the error: Error: Transaction reverted: function returned an unexpected amount of data at Raffle.performUpkeep
Testscript:
const{ deployments, ethers, getNamedAccounts, network }=require("hardhat")const{ assert, expect }=require("chai")const{ developmentChains, networkConfig }=require("../../helper-hardhat-config")// depends on level in test script?!developmentChains.includes(network.name)
? describe.skip
: describe("Raffle Unit Tests",function(){letraffle,signer,vrfCoordinatorV2Mock,raffleEntranceFee,intervalconstchainId=network.config.chainIdbeforeEach(async()=>{constaccounts=awaitethers.getSigners()signer=accounts[0]awaitdeployments.fixture(["all"])constraffleDeployment=awaitdeployments.get("Raffle")raffle=awaitethers.getContractAt(raffleDeployment.abi,raffleDeployment.address,signer,)constvrfCoordinatorV2MockDeployment=awaitdeployments.get("VRFCoordinatorV2Mock")vrfCoordinatorV2Mock=awaitethers.getContractAt(vrfCoordinatorV2MockDeployment.abi,vrfCoordinatorV2MockDeployment.address,signer,)raffleEntranceFee=awaitraffle.getEntranceFee()interval=awaitraffle.getInterval()})// The xx.getxx functions refer to the viewing functions created in the contractdescribe("constructor",function(){it("Initializes the raffle correctly",async()=>{constraffleState=awaitraffle.getRaffleState()assert.equal(raffleState.toString(),"0")assert.equal(interval.toString(),networkConfig[chainId]["interval"])})})describe("enterRaffle",function(){it("Reverts when you don't pay enough",async()=>{awaitexpect(raffle.enterRaffle()).to.be.revertedWithCustomError(raffle,"Raffle__NotEnoughETHEntered",)})it("Records players when they enter",async()=>{awaitraffle.enterRaffle({value: raffleEntranceFee})constplayerFromContract=awaitraffle.getPlayers(0)assert.equal(playerFromContract,signer.address)})it("Emits event on enter",async()=>{awaitexpect(raffle.enterRaffle({value: raffleEntranceFee})).to.emit(raffle,"raffleEnter",)})it("Doesn't allow entrance when raffle is calculating",async()=>{awaitraffle.enterRaffle({value: raffleEntranceFee})awaitnetwork.provider.send("evm_increaseTime",[Number(interval)+1])awaitnetwork.provider.send("evm_mine",[])// We pretend to be a Chainlink keeperawaitraffle.performUpkeep("0x")awaitexpect(raffle.enterRaffle({value: raffleEntranceFee}),).to.be.revertedWithCustomError(raffle,"Raffle__NotOpen")})})
Deploy script:
const{ networkConfig, developmentChains }=require("../helper-hardhat-config")const{ network, ethers }=require("hardhat")const{ verify }=require("../utils/verify")constVRF_SUB_FUND_AMOUNT=ethers.parseEther("2")module.exports=async({ getNamedAccounts, deployments })=>{const{ deploy, log }=deploymentsconst{ deployer }=awaitgetNamedAccounts()constchainId=network.config.chainIdletvrfCoordinatorV2Address,subscriptionIdif(developmentChains.includes(network.name)){// --> this means: IF the currently used network name is in de development chains array (i.e., if we are on a development chain:)constvrfCoordinatorV2Mock=awaitethers.getContractAt("VRFCoordinatorV2Mock",deployer)vrfCoordinatorV2Address=vrfCoordinatorV2Mock.target// ^^ this means, do this if we are on a local network (deploy mock). Or else, do this beneath (deploy real contract)consttransactionResponse=awaitvrfCoordinatorV2Mock.createSubscription()consttransactionReceipt=awaittransactionResponse.wait(1)subscriptionId=1// transactionReceipt.events[0].args.subId --> Not sure why// Now, we need to fund the subscription, for which we usually need the link token (on a real network)awaitvrfCoordinatorV2Mock.fundSubscription(subscriptionId,VRF_SUB_FUND_AMOUNT)}else{vrfCoordinatorV2Address=networkConfig[chainId]["vrfCoordinatorV2"]subscriptionId=networkConfig[chainId]["subscriptionId"]}constentranceFee=networkConfig[chainId]["entranceFee"]constgasLane=networkConfig[chainId]["gasLane"]constcallbackGasLimit=networkConfig[chainId]["callbackGasLimit"]constinterval=networkConfig[chainId]["interval"]constargs=[vrfCoordinatorV2Address,entranceFee,gasLane,subscriptionId,callbackGasLimit,interval,]constraffle=awaitdeploy("Raffle",{from: deployer,args: args,log: true,waitConfirmations: network.config.blockConfirmations||1,})if(!developmentChains.includes(network.name)&&process.env.ETHERSCAN_API_KEY){log("Verifying...")awaitverify(raffle.address,args)}log("------------------------------------------------")}module.exports.tags=["all","raffle"]
Contract:
// Raffle// Enter the lottery (paying some amount)// Pick a random winner (verifiable random)// Winner to be selected every X minutes -> completely automated// Chainlink Oracle -> Randomness, Automated execution (Chainlink Keepers)// SPDX-License-Identifier: MITpragma solidity^0.8.8;
// Importsimport"@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
import"@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import"@chainlink/contracts/src/v0.8/automation/AutomationCompatible.sol";
// Errorserror Raffle__NotEnoughETHEntered();
error Raffle__TransferFailed();
error Raffle__NotOpen();
error Raffle__UpkeepNotNeeded(uint256currentBalance, uint256numPlayers, uint256raffleState);
/** * @title A sample Raffle Contract * @author Dylan Maas, based on Patrick Collins (FCC) * @notice This contract is for creating an untamperable decentralized smart contract * @dev This implements Chainlink VRF v2 and Chainlink Keepers (automation) */contractRaffleisVRFConsumerBaseV2, AutomationCompatible {
/* Type declarations*/enum RaffleState {
OPEN,
CALCULATING
} // uint256, where 0 = OPEN and 1 = Calculating/* State Variables*/uint256privateimmutable i_entranceFee;
address payable[] private s_players;
VRFCoordinatorV2Interface privateimmutable i_vrfCoordinator;
bytes32privateimmutable i_gasLane;
uint64privateimmutable i_subscriptionId;
uint32privateimmutable i_callbackGasLimit;
uint16private constant REQUEST_CONFIRMATIONS =3;
uint32private constant NUM_WORDS =1;
//Lottery (State) Variablesaddressprivate s_recentWinner;
RaffleState private s_raffleState;
uint256private s_lastTimeStamp;
uint256privateimmutable i_interval;
/*Events*/event raffleEnter(addressindexedplayer);
event requestedRaffleWinner(uint256indexedrequestId);
event winnerPicked(addressindexedWinner);
/*functions*/constructor(
addressvrfCoordinatorV2,
uint256entranceFee,
bytes32gasLane,
uint64subscriptionId,
uint32callbackGasLimit,
uint256interval
) VRFConsumerBaseV2(vrfCoordinatorV2) {
i_entranceFee = entranceFee;
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() publicpayable {
if (msg.value< i_entranceFee) {
revertRaffle__NotEnoughETHEntered();
}
if (s_raffleState != RaffleState.OPEN) {
revertRaffle__NotOpen();
}
s_players.push(payable(msg.sender));
emitraffleEnter(msg.sender);
}
/** * @dev This is the function that the Chainlink Keeper nodes call * They look for the "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 some ETH * 3. Our subscription is funded with LINK * 4. The lottery should be in an "open" state */function checkUpkeep(
bytesmemory/*checkData*/
) publicoverridereturns (boolupkeepNeeded, bytesmemory/*perform Data*/) {
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(bytescalldata/* performData */) externaloverride {
(boolupkeepNeeded, ) =checkUpkeep("");
if (!upkeepNeeded) {
revertRaffle__UpkeepNotNeeded(
address(this).balance,
s_players.length,
uint256(s_raffleState)
);
}
s_raffleState = RaffleState.CALCULATING;
uint256 requestId = i_vrfCoordinator.requestRandomWords(
i_gasLane, // keyHash
i_subscriptionId,
REQUEST_CONFIRMATIONS,
i_callbackGasLimit,
NUM_WORDS
);
emitrequestedRaffleWinner(requestId);
}
function fulfillRandomWords(
uint256/* requestId */,
uint256[] memoryrandomWords
) internaloverride {
uint256 indexOfWinner = randomWords[0] % s_players.length;
address payable recentWinner = s_players[indexOfWinner];
s_recentWinner = recentWinner;
s_raffleState = RaffleState.OPEN;
s_players =newaddress payable[](0); // empties the array
s_lastTimeStamp =block.timestamp;
(boolsucces, ) = recentWinner.call{value: address(this).balance}("");
if (!succes) {
revertRaffle__TransferFailed();
}
emitwinnerPicked(recentWinner);
}
/* view / Pure functions*/function getEntranceFee() publicviewreturns (uint256) {
return i_entranceFee;
}
function getPlayers(uint256index) publicviewreturns (address) {
return s_players[index];
}
function getRecentWinner() publicviewreturns (address) {
return s_recentWinner;
}
function getRaffleState() publicviewreturns (RaffleState) {
return s_raffleState;
}
function getNumWords() publicpurereturns (uint256) {
return NUM_WORDS;
}
function getNumberOfPlayers() publicviewreturns (uint256) {
return s_players.length;
}
function getLatestTimestamp() publicviewreturns (uint256) {
return s_lastTimeStamp;
}
function getRequestConfirmations() publicpurereturns (uint256) {
return REQUEST_CONFIRMATIONS;
}
function getInterval() publicviewreturns (uint256) {
return i_interval;
}
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi all,
I am completely stuck at testing my raffle contract at the "doesn't allow entrance when raffle is calculating" unit test. I am using the Ethers V6, which is probably the reason why it is not working, but I would like to figure out the v6 since I already did the v5 version.
Since other tests are working, I am assuming that the error has something to do with the performUpkeep function, but I don't know how to solve it after scouring the internet for days.
This is the error: Error: Transaction reverted: function returned an unexpected amount of data at Raffle.performUpkeep

Testscript:
Deploy script:
Contract:
Thanks in advance!
Beta Was this translation helpful? Give feedback.
All reactions