1

I'm testing my contracts, where I use Chainlink's VRF. I use the mainnet forking in a hardhat. I deployed VRFCoordinatorV2Mock, although it doesn't seem to work. Is VRFCoordinatorV2Mock supposed to work on the mainnet forking, or only in the local network? When I do call the requestrandomwords(), I get: Error: Transaction reverted: function returned an unexpected amount of data

How I'm deploying VRFCoordinatorV2Mock :


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

module.exports = async ({ getNamedAccounts, deployments }) => {
  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...");
    log(deployer);
    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("----------------------------------------------------------");
  }
};
module.exports.tags = ["all", "mocks"];

I use this to fund my VRFCoordinatorV2Mock, and add the consumer :


// create VRFV2 Subscription
  vrfCoordinatorV2Mock = await ethers.getContract("VRFCoordinatorV2Mock");
  vrfCoordinatorV2Address = vrfCoordinatorV2Mock.address;
  log(vrfCoordinatorV2Address);
  const transactionResponse = await vrfCoordinatorV2Mock.createSubscription();
  const transactionReceipt = await transactionResponse.wait();
  subscriptionId = transactionReceipt.events[0].args.subId;
  // Fund the subscription
  // Our mock makes it so we don't actually have to worry about sending fund
  await vrfCoordinatorV2Mock.fundSubscription(subscriptionId, FUND_AMOUNT);


 mytrx = await vrfCoordinatorV2Mock.addConsumer(
    subscriptionId,
    MyContract.address
  );
  await mytrx.wait();

The arguments I use, when i call requestRandomWords:

 function requestRandomNumber(
    uint256 _epoch
  ) public onlyOperator returns (uint256) {
    require(epochPeriods[_epoch] != ROLL_IN_PROGRESS, "In progress");

    uint256 requestId = COORDINATOR.requestRandomWords(
      s_keyHash,// 0x474e34a077df58807dbe9c96d3c009b23b3c6d0cce433e59bbf5b34f823bc56c
      s_subscriptionId,
      requestConfirmations,//1
      callbackGasLimit,//500000
      numWords //3
    );

    randRequests[requestId] = _epoch;
    epochPeriods[_epoch] = ROLL_IN_PROGRESS;
    emit RequestRandomnessFulfilled(bytes32(requestId), numWords);
    return requestId;
  } 

And thats the constructor I'm using on the consumer contract.

constructor(
    address _vrfcoordinator,
    uint64 _subscriptionId
  ) VRFConsumerBaseV2(_vrfcoordinator) {
    s_subscriptionId = _subscriptionId;

    COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
  }

The rest of the values, i pass them earlier inside my contrat.

The mainnet forking i'm doing is in polygon mainnet.

Edit : Here is my fullfillRandomWords():

 function fulfillRandomWords(
    uint256 requestId,
    uint256[] memory randomWords
  ) internal override {
    uint256 randVal = (randomWords[0] % (randmax - randmin + 1)) + randmin;
    epochPeriods[randRequests[requestId]] = randVal;
    uint256 randVal2 = ((randomWords[1] % (randmaxboost - randminboost + 1)) +
      randminboost) / 10;

    uint256 randVal3 = ((randomWords[2] % (randmaxperiod - randminperiod + 1)) +
      randminperiod);

    periodcounter--;
    if (periodcounter <= 0 && day_checker >= 24) {
      Boost = randVal2;
      periodcounter = randVal3;
      day_checker = 0;
    }
    day_checker.add(epochPeriods[epoch]);
  }

The vars periodcounter , Boost,randmax,randmin,randmaxperiod etc, are already initialized and uint256.

5
  • 1
    Either one should work. Could you update your question with more context? For example, how you deployed it and how you called it. Otherwise, It would be near to impossible to help you. For the VRFCoordinatorMockV2 to be used, you must create a subscription, fund it, and add a consumer. It seems that it needs to be clarified from your question if you did all that.
    – PSS
    Commented Mar 24, 2023 at 21:51
  • 1
    @PSS Thanks, updated the question with more context. Commented Mar 25, 2023 at 6:00
  • 1
    How do you implement fulfillRandomWords()?
    – PSS
    Commented Mar 25, 2023 at 14:07
  • @PSS Updated the post with my implementation of the function. Thanks for the time you are spending to help me brother <3 Commented Mar 25, 2023 at 19:11
  • 1
    No problem, I really don’t see anything incorrect in your snippets. Do you have a repo you could share with me? I will clone it and see if I can replicate your issue.
    – PSS
    Commented Mar 26, 2023 at 0:37

0

Your Answer

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