0

Error Received:

Error: ERROR processing /Users/ty/blockchainLearning/Lottery-Smart-Contract/deploy/01-deploy-raffle.ts:
Error: No Contract deployed with name VRFCoordinatorV2Mock
    at Object.getContract (/Users/ty/blockchainLearning/Lottery-Smart-Contract/node_modules/@nomiclabs/hardhat-ethers/src/internal/helpers.ts:447:11)

My hunch is that Mocks is not being deployed properly in 00-deploy-mocks.ts. When I deploy the the mocks and and raffle.ts file, they run perfectly fine however when I run yarn hardhat deploy --network rinkeby I run into this error.

My 00-deploy-mocks.ts:

import { getNamedAccounts, deployments, network, ethers } from "hardhat"
import { DeployFunction } from "hardhat-deploy/types"
import { HardhatRuntimeEnvironment } from "hardhat/types"

const BASE_FEE = "250000000000000000" // 0.25 is this the premium in LINK?
const GAS_PRICE_LINK = 1e9 // link per gas, is this the gas lane? // 0.000000001 LINK per gas

const deployMocks: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
    const { deployments, getNamedAccounts, network } = hre
    const { deploy, log } = deployments
    const { deployer } = await getNamedAccounts()
    const chainId = network.config.chainId
    // If we are on a local development network, we need to deploy mocks!
    if (chainId == 31337) {
        log("Local network detected! Deploying mocks...")
        await deploy("VRFCoordinatorV2Mock", {
            from: deployer,
            log: true,
            args: [BASE_FEE, GAS_PRICE_LINK],
        })

        log("Mocks Deployed!")
        log("----------------------------------")

        log("You are deploying to a local network, you'll need a local network running to interact")
        log(
            "Please run `yarn hardhat console --network localhost` to interact with the deployed smart contracts!"
        )
        log("----------------------------------")
    }
}
export default deployMocks
deployMocks.tags = ["all", "mocks"]

My 01-deploy-raffle.ts:

import { LogDescription } from "@ethersproject/abi"
import { ethers, network } from "hardhat"
import { DeployFunction } from "hardhat-deploy/dist/types"
import { HardhatRuntimeEnvironment } from "hardhat/types"
import {
    developmentChains,
    networkConfig,
    VERIFICATION_BLOCK_CONFIRMATIONS,
} from "../helper-hardhat-config"

import verify from "../utils/verify"

const VRF_SUB_FUND_AMOUNT = "1000000000000000000000"

const deployRaffle: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
    const { deployments, getNamedAccounts, network, ethers } = hre
    const { deploy, log } = deployments
    const { deployer } = await getNamedAccounts()
    // const chainID = network.config.chainId
    const chainID = 31337
    let vrfCoordinatorV2Address, subscriptionID

    // if on developement chain
    if (chainID == 31337) {
        const vrfCoordinatorV2Mock = await ethers.getContract("VRFCoordinatorV2Mock")
        vrfCoordinatorV2Address = vrfCoordinatorV2Mock.address
        const txnResponse = await vrfCoordinatorV2Mock.createSubscription()
        const txnReceipt = await txnResponse.wait()
        subscriptionID = txnReceipt.events[0].args.subId

        // Fund the subscription
        await vrfCoordinatorV2Mock.fundSubscription(subscriptionID, VRF_SUB_FUND_AMOUNT)
    } else {
        // else if not on local network
        vrfCoordinatorV2Address = networkConfig[network.config.chainId!]["vrfCoordinatorV2"]
        subscriptionID = networkConfig[network.config.chainId!]["subscriptionId"]
    }

    const waitBlockConfirmations = developmentChains.includes(network.name)
        ? 1
        : VERIFICATION_BLOCK_CONFIRMATIONS
    log("----------------------------------------------------")

    const entranceFee = networkConfig[network.config.chainId!]["entranceFee"]
    const gasLane = networkConfig[network.config.chainId!]["gasLane"]
    const callbackGasLimit = networkConfig[network.config.chainId!]["callbackGasLimit"]
    const interval = networkConfig[network.config.chainId!]["interval"]

    const args = [
        vrfCoordinatorV2Address,
        entranceFee,
        gasLane,
        subscriptionID,
        callbackGasLimit,
        interval,
    ]

    const raffle = await deploy("Raffle", {
        from: deployer,
        args: args,
        log: true,
        waitConfirmations: waitBlockConfirmations,
    })

    if (!developmentChains.includes(network.name) && process.env.ETHERSCAN_API_KEY) {
        log("Verifying...")
        await verify(raffle.address, args)
    }
    log("------------------------------------------")
}

export default deployRaffle

deployRaffle.tags = ["all", "raffle"]

My Raffle.test.ts

import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"
import { assert, expect } from "chai"
import { BigNumber, Contract } from "ethers"
import { deployments, ethers, getNamedAccounts, network } from "hardhat"
import { developmentChains, networkConfig } from "../../helper-hardhat-config"

// This runs only on a local network
!developmentChains.includes(network.name)
    ? describe.skip
    : describe("Raffle", async function () {
          let raffle: Contract
          let vrfCoordinatorV2Mock: Contract
          let entranceFee: BigNumber
          let player: SignerWithAddress
          let accounts: SignerWithAddress[]
          let raffleContract: Contract
          let interval: number

          const chainId = network.config.chainId

          beforeEach(async function () {
              accounts = await ethers.getSigners()
              player = accounts[1] // can't use accounts[0] because that is a deployer
              await deployments.fixture(["all"])
              vrfCoordinatorV2Mock = await ethers.getContract("VRFCoordinatorV2Mock")
              raffleContract = await ethers.getContract("Raffle")
              raffle = raffleContract.connect(player)
              entranceFee = await raffle.getEntranceFee()
              interval = (await raffle.getInterval()).toNumber()
          })

          describe("constructor", function () {
              it("initalizes the raffle correctly", async () => {
                  console.log(`Network chainId: ${network.config.chainId}`)

                  const raffleState = (await raffle.getRaffleState()).toString()
                  assert.equal(raffleState, "0")
                  assert.equal(interval.toString(), networkConfig[chainId!]["interval"])
              })
          })

          describe("enterRaffle", () => {
              it("reverts when you don't pay enough", async () => {
                  await expect(raffle.enterRaffle()).to.be.revertedWith(
                      "Raffle__NotEnoughETHEntered"
                  )
              })

              it("records player when they enter", async () => {
                  await raffle.enterRaffle({ value: entranceFee })
                  const contractPlayer = await raffle.getPlayer(0)
                  assert.equal(player.address, contractPlayer)
              })

              it("emits event on enter", async () => {
                  await expect(raffle.enterRaffle({ value: entranceFee })).to.emit(
                      raffle,
                      "RaffleEnter"
                  )
              })

              it("doesn't allow entrance when raffle is calculating", async () => {
                  await raffle.enterRaffle({ value: entranceFee })

                  //   Force some time to pass
                  await network.provider.send("evm_increaseTime", [interval + 1])
                  await network.provider.request({ method: "evm_mine", params: [] })

                  // pretending to be a chainlink keeper and put raffleState in CALCULATING mode
                  await raffle.performUpkeep([])
                  await expect(raffle.enterRaffle({ value: entranceFee })).to.be.revertedWith(
                      "Raffle_NotOpen"
                  )
              })
          })

          describe("checkUpKeep", () => {
              it("returns false if people haven't sent any ETH", async () => {
                  await network.provider.send("evm_increaseTime", [interval + 1])
                  await network.provider.request({ method: "evm_mine", params: [] })

                  // Simulate calling checkUpKeep()
                  const { upkeepNeeded } = await raffle.callStatic.checkUpkeep("0x")

                  // upkeepNeeded should be false because we didn't send any ETH
                  assert(!upkeepNeeded)
              })

              it("returns false if raffle isn't open", async () => {
                  await raffle.enterRaffle({ value: entranceFee })
                  await network.provider.send("evm_increaseTime", [interval + 1])
                  await network.provider.request({ method: "evm_mine", params: [] })

                  // Calling this func manke raffleState go to CALCULATING
                  await raffle.performUpkeep([])
                  const raffleState = await raffle.getRaffleState()
                  const { upkeepNeeded } = await raffle.callStatic.checkUpkeep("0x")
                  assert.equal(raffleState.toString() == "1", upkeepNeeded == false)
              })

              it("returns false if enough time hasn't passed", async () => {
                  await raffle.enterRaffle({ value: entranceFee })

                  // Enough time hasn't passed - this leads to returned false
                  await network.provider.send("evm_increaseTime", [interval - 1])
                  await network.provider.request({ method: "evm_mine", params: [] })

                  const { upkeepNeeded } = await raffle.callStatic.checkUpkeep("0x")
                  assert(!upkeepNeeded)
              })
              it("returns true if enough time has passed, has players, eth, and is open", async () => {
                  await raffle.enterRaffle({ value: entranceFee })
                  await network.provider.send("evm_increaseTime", [interval + 1])
                  await network.provider.request({ method: "evm_mine", params: [] })
                  const { upkeepNeeded } = await raffle.callStatic.checkUpkeep("0x")

                  assert(upkeepNeeded)
              })
          })

          describe("performUpKeep", () => {
              it("can only run if checkupkeep is true", async () => {
                  await raffle.enterRaffle({ value: entranceFee })
                  await network.provider.send("evm_increaseTime", [interval + 1])
                  await network.provider.request({ method: "evm_mine", params: [] })
                  const tx = await raffle.performUpkeep("0x")
                  assert(tx)
              })

              it("reverts when checkupkeep is false", async () => {
                  await expect(raffle.performUpkeep("0x")).to.be.revertedWith(
                      "Raffle__UpkeepNotNeeded"
                  )
              })

              it("updates the raffle state and emits a requestId", async () => {
                  await raffle.enterRaffle({ value: entranceFee })
                  await network.provider.send("evm_increaseTime", [interval + 1])
                  await network.provider.request({ method: "evm_mine", params: [] })

                  // Make call to performUpKeep
                  const txnResponse = await raffle.performUpkeep("0x")
                  const txnReceipt = await txnResponse.wait(1)

                  // Get raffle state
                  const raffleState = await raffle.getRaffleState()
                  // Get requestId
                  const requestId = txnReceipt!.events![1].args!.requestId

                  // Check if reqestIf is emmited
                  assert(requestId.toNumber() > 0)
                  // Check if raffe state is updated
                  assert(raffleState == 1)
              })
          })

          describe("fulfilRandomWords", () => {
              beforeEach(async () => {
                  await raffle.enterRaffle({ value: entranceFee })
                  await network.provider.send("evm_increaseTime", [interval + 1])
                  await network.provider.request({ method: "evm_mine", params: [] })
              })

              it("picks a winner, resets, and sends money", async () => {
                  const additionalEntrances = 3
                  const startingIndex = 2

                  for (let i = startingIndex; i < startingIndex + additionalEntrances; i++) {
                      raffle = raffleContract.connect(accounts[i])
                      await raffle.enterRaffle({ value: entranceFee })
                  }

                  const startingTimeStamp = await raffle.getLastTimeStamp()

                  await new Promise<void>(async (resolve, reject) => {
                      // Subscribe once to event calling listener when the event occurs.
                      raffle.once("WinnerPicked", async () => {
                          console.log("WinnerPicked even fired!")
                          try {
                              const recentWinner = await raffle.getRecentWinner()
                              const raffleState = await raffle.getRaffleState()
                              const winnerBalance = await accounts[2].getBalance()
                              const endingTimeStamp = await raffle.getLastTimeStamp()
                              await expect(raffle.getPlayer(0)).to.be.reverted
                              assert.equal(recentWinner.toString(), accounts[2].address)
                              assert.equal(raffleState.toString(), "0")
                              assert(endingTimeStamp > startingTimeStamp)
                              assert.equal(
                                  winnerBalance.toString(),
                                  startingBalance
                                      .add(entranceFee.mul(additionalEntrances).add(entranceFee))
                                      .toString()
                              )
                              resolve()
                          } catch (e) {
                              reject(e)
                          }
                      })

                      const tx = await raffle.performUpkeep("0x")
                      const txReceipt = await tx.wait(1)
                      const startingBalance = await accounts[2].getBalance()
                      await vrfCoordinatorV2Mock.fulfillRandomWords(
                          txReceipt!.events![1].args!.requestId,
                          raffle.address
                      )
                  })
              })
          })
      })

I am following Patrick's solidity+Typescript course on YouTube. So, id this works for you let me know. ;)

1 Answer 1

0

In your 00-deploy-mocks.ts you are only deploying Mocks if it is a local network:

if (chainId == 31337) {....}

which makes sense.

You hardcoded the chainID to be 31337 however, so the 01-deploy-raffle script tries to get the Mock contract. Uncomment the following line:

// const chainID = network.config.chainId // Uncomment this
    const chainID = 31337 // Comment this

And that should fix your woes :) Hope that helps!

2
  • 1
    Ha! It worked. Thanks for catching that.
    – Ty Facey
    Jul 26, 2022 at 5:05
  • Awesome haha sometimes you just need another pair of eyes to catch the trivial things :D Jul 26, 2022 at 6:28

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.