3

While testing the Raffle contract, I am getting error in the line written "await network.provider.send("evm_increaseTime", [Number(interval) + 1]); await network.provider.send("evm_mine", []);"

Here is Raffle.sol contract

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.15;

import "@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";

error Raffle__EntranceFeeNotEnough();
error Raffle__TransferFailed();
error Raffle__NotOpen();
error Raffle_UpkeepNotNeeded(uint256 currentBalance, uint256 numPlayers, uint256 raffleState);

/**
 * @title A sample Raffle Contract
 * @author nik_arjun
 * @notice This contract is for creating untamperable decentralized smart contract
 * @dev This implements Chainlink VRF v2 and Chainlink Keepers
 */

contract Raffle is VRFConsumerBaseV2, AutomationCompatibleInterface {
   /* Type Declaration */
   enum RaffleState {
      OPEN,
      CALCULATING
   } // Equivalent to uint256 =  0: OPEN, 1:CALCULATING

   /* State Variable */
   uint256 private i_entranceFee;
   address payable[] private s_players;
   VRFCoordinatorV2Interface private immutable i_vrfCoordinator;
   bytes32 private immutable i_gasLane;
   uint64 private immutable i_subscriptionId;
   uint32 private immutable i_callbackGasLimit;
   uint16 private constant REQUEST_CONFIRMATIONS = 3;
   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;
      i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
      i_gasLane = gasLane;
      i_subscriptionId = subscriptionId;
      i_callbackGasLimit = callbackGasLimit;
      s_raffleState = RaffleState.OPEN; // or RaffleState(0)
      s_lastTimeStamp = block.timestamp;
      i_interval = interval;
   }

   function enterRaffle() public payable {
      if (msg.value < i_entranceFee) {
         revert Raffle__EntranceFeeNotEnough();
      }

      if (s_raffleState != RaffleState.OPEN) {
         revert Raffle__NotOpen();
      }

      s_players.push(payable(msg.sender));
      // Emit a event when we update the dynamic array or mapping
      // Named event with function name reversed
      emit RaffleEnter(msg.sender);
   }

   /**
    * @dev This is the function that the Chainlink Keeper nodes call
    * they look for `upkeepNeeded` to return True.
    * the following should be true for this to return true:
    * 1. The time interval has passed between raffle runs.
    * 2. The lottery is open.
    * 3. The contract has atleast 1 player and some ETH.
    * 4. Implicity, your subscription is funded with LINK.
    */

   function checkUpkeep(
      bytes memory /* performData */
   ) public override returns (bool upkeepNeeded, bytes memory /* performData */) {
      bool isOpen = (s_raffleState == RaffleState.OPEN);
      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 {
      // Request Random Number
      // Once we get it, we will do something
      // 2 transaction process
      (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_lastTimeStamp = block.timestamp;
      s_raffleState = RaffleState.OPEN;
      s_players = new address payable[](0);
      (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 (uint32) {
      return NUM_WORDS;
   }

   function getNumberOfPlayers() public view returns (uint256) {
      return s_players.length;
   }

   function getTimeStamp() public view returns (uint256) {
      return s_lastTimeStamp;
   }

   function getInterval() public view returns (uint256) {
      return i_interval;
   }

   function getRequestConfirmations() public pure returns (uint16) {
      return REQUEST_CONFIRMATIONS;
   }
}

Here is Raffle.test.js

const { network, deployments, ethers, getNamedAccounts, getChainId } = require("hardhat");
const { developementChains, networkConfig } = require("../../helper-hardhat-config");
const { assert, expect } = require("chai");

!developementChains.includes(network.name)
   ? describe.skip
   : describe("Raffle Unit Test", async function () {
        let raffle, VRFCoordinatorV2Mock, raffleEntranceFee, deployer, interval;

        beforeEach(async function () {
           deployer = (await getNamedAccounts()).deployer;
           await deployments.fixture(["all"]);
           const raffleAddress = (await deployments.get("Raffle")).address;
           const vrfCoordinatorV2Address = (await deployments.get("VRFCoordinatorV2Mock")).address;
           raffle = await ethers.getContract("Raffle", deployer);
           VRFCoordinatorV2Mock = await ethers.getContract("VRFCoordinatorV2Mock", deployer);
           raffleEntranceFee = await networkConfig[await getChainId()]["entranceFee"];
           interval = await raffle.getInterval();
        });

        describe("constructor", function () {
           it("Initializes Raffle Correctly", async function () {
              const raffleState = await raffle.getRaffleState();
              assert.equal(raffleState.toString(), "0");
              assert.equal(interval.toString(), networkConfig[await getChainId()]["interval"]);
           });
        });

        describe("Enter Raffle", function () {
           it("Reverts if you don't have enough ETH", async function () {
              await expect(raffle.enterRaffle()).to.be.revertedWithCustomError(
                 raffle,
                 "Raffle__EntranceFeeNotEnough()"
              );
           });

           it("Records player when it enters the Raffle", async function () {
              await raffle.enterRaffle({ value: raffleEntranceFee });
              const player_zero = await raffle.getPlayer(0);

              assert.equal(player_zero, deployer);
           });

           it("Doesn't allow entrance if Raffle State is close", async function () {
              await raffle.enterRaffle({ value: raffleEntranceFee });
              await network.provider.send("evm_increaseTime", [Number(interval) + 1]);
              await network.provider.send("evm_mine", []);
              // Perform upkeep by pretending as a Chainlink keeper
              await raffle.performUpkeep([]);

              await expect(
                 raffle.enterRaffle({ value: raffleEntranceFee })
              ).to.be.revertedWithCustomError(raffle, Raffle__NotOpen);
           });

           it("Emits an event on entering the raffle", async function () {
              await expect(await raffle.enterRaffle({ value: raffleEntranceFee })).to.emit(
                 raffle,
                 "RaffleEnter"
              );
           });
        });
     });

And this is the error I am getting while running it :

TypeError: invalid BytesLike value (argument="value", value=[  ], code=INVALID_ARGUMENT, version=6.10.0)
      at makeError (node_modules/ethers/src.ts/utils/errors.ts:687:21)
      at assert (node_modules/ethers/src.ts/utils/errors.ts:715:25)
      at assertArgument (node_modules/ethers/src.ts/utils/errors.ts:727:5)
      at _getBytes (node_modules/ethers/src.ts/utils/data.ts:44:19)
      at getBytesCopy (node_modules/ethers/src.ts/utils/data.ts:66:12)
      at BytesCoder.encode (node_modules/ethers/src.ts/abi/coders/bytes.ts:21:29)
      at /home/nraj07054/hardhat-fcc/hardhat-smartcontract-lottery-fcc/node_modules/ethers/src.ts/abi/coders/array.ts:55:19
      at Array.forEach (<anonymous>)
      at pack (node_modules/ethers/src.ts/abi/coders/array.ts:47:12)
      at TupleCoder.encode (node_modules/ethers/src.ts/abi/coders/tuple.ts:62:20)

2 Answers 2

2

The empty array you're passing "" is not a valid BytesLike value. You need to pass a valid hexadecimal string or an array of bytes.

Try this:

await raffle.performUpkeep("0x");
0

I think that you're not supposed to use that syntax here:

    await network.provider.send("evm_increaseTime", [Number(interval) + 1]);
    await network.provider.send("evm_mine", []);

Can you try the following:

    await network.provider.request({
       method: 'evm_increaseTime',
       params: [Number(interval) + 1],
    });

?

1
  • It is giving me same error after correction. I think the problem is with the line "await raffle.performUpkeep([]);" but don't know how to resolve it.
    – Nikhil Raj
    Feb 2 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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