1

I have forked the polygone mainnet in hardhat and when I call the makeFlashLoan function in my test I get the following error. Error: Transaction reverted: function call to a non-contract account Here is my contract


// interfaces here
contract BalancerFlashLoan is IFlashLoanRecipient {
    address public vaultAddress = 0xBA12222222228d8Ba445958a75a0704d566BF2C8;
    IVault public VAULT = IVault(vaultAddress);
    address private constant Uniswap_v2_router =
        0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff;
    address public owner;

    constructor() {
        owner = payable(msg.sender);
    }
    function makeFlashLoan(
        IERC20[] memory tokens,
        uint256[] memory amounts,
        address[] memory arbTokens // bytes memory userData
    ) public {
        console.log("inside flashloan function");
        bytes memory userData = encodeAddressArray(arbTokens);
        // this call to vault contract results in failing error
        VAULT.flashLoan(this, tokens, amounts, userData);
    }

    function receiveFlashLoan(
        IERC20[] memory tokens,
        uint256[] memory amounts,
        uint256[] memory feeAmounts,
        bytes calldata userData
    ) external override {
        require(IVault(msg.sender) == VAULT, "Only Vault can call");
        console.log("inside the receive flashloan");

        address[] memory arbTokens = decodeAddressArray(userData);
       // returns the flashloan after some custom logic 
        _returnTokensToVault(tokens, amounts, feeAmounts);
    }
    // other internal functions here
   }

Here is my hardhat config

module.exports = {
  solidity: "0.8.19",
  networks: {
    forking: {
      url: "https://polygon-mainnet.g.alchemy.com/v2/{my-api-key-goes-here}",
      chainId: 137,
      blockNumber: 42001660,
    },
  },
};

here is my test

 describe("BalancerFlashLoan", async () => {
  const vaultAddress = "0xBA12222222228d8Ba445958a75a0704d566BF2C8";
  let BalancerFlashLoan;
  let balancerFlashLoan;

   beforeEach(async () => {
    BalancerFlashLoan = await ethers.getContractFactory("BalancerFlashLoan");
    balancerFlashLoan = await BalancerFlashLoan.deploy();
    await balancerFlashLoan.deployed();
  });

    it("should receive the flashloan", async () => {
    const VAULT = await balancerFlashLoan.VAULT();
    const regex = new RegExp(VAULT, "i");
    expect(vaultAddress).to.match(regex);

    await balancerFlashLoan.makeFlashLoan(
      ["0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6"],
      [20000],
      [
        "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",
        "0xee7666aACAEFaa6efeeF62ea40176d3eB21953B9",
        "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619",
        "0xB5C064F955D8e7F38fE0460C556a72987494eE17",
        "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",
      ]
    );
  });
 })

I am passing the correct vault addresses and you can check the docs here. I forked the polygon using npx hardhat node. The vault contract is present on the mainnet and it does not makes sense for the test to throw "non contract account" error Example showing how to take flashLoan: https://docs.balancer.fi/reference/contracts/flash-loans.html#example-code

1 Answer 1

0

There is a problem with the vault contract instance when you're forking the Polygon mainnet.

First set the live flag to true for the forking network

module.exports = {
  solidity: "0.8.19",
  networks: {
    forking: {
      url: "https://polygon-mainnet.g.alchemy.com/v2/{my-api-key-goes-here}",
      chainId: 137,
      blockNumber: 42001660,
      live: true,
    },
  },
};

then modify the test so that it it clearly use the forking network, also use ethers.provider.getContractAt() function, dont forget to replace the my-api-key-goes-here with your API.

const { ethers } = require("hardhat");

describe("BalancerFlashLoan", async () => {
  const vaultAddress = "0xBA12222222228d8Ba445958a75a0704d566BF2C8";
  let BalancerFlashLoan;
  let balancerFlashLoan;

  beforeEach(async () => {
    await network.provider.request({
      method: "hardhat_reset",
      params: [{
        forking: {
          jsonRpcUrl: "https://polygon-mainnet.g.alchemy.com/v2/{my-api-key-goes-here}",
          blockNumber: 42001660
        }
      }]
    });

    BalancerFlashLoan = await ethers.getContractFactory("BalancerFlashLoan");
    balancerFlashLoan = await BalancerFlashLoan.deploy();
    await balancerFlashLoan.deployed();

    // Create an instance of the vault contract
    balancerFlashLoan.VAULT = await ethers.getContractAt("IVault", vaultAddress);
  });

  // The rest of your test code
});
1

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.