4

I have a contract I'm testing using hardhat.

What is a good approach to fund that contract with an arbitrary ERC20 token (WETH in this case)?

I am testing using a hardhat mainnet fork, my approach is to impersonate an account which has lots of that token and send from that account to my contract; This is not working, seems like I am not successful in impersonating that account. Also, it seems like there might be a better way.

MyTest.js

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

const IERC20_SOURCE = "@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20";

const WETH_WHALE = "0xF04a5cC80B1E94C69B48f5ee68a08CD2F09A7c3E";
const WETH_ADDRESS = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";


describe("Test Contract", async () => {

  let contractToTest, wethContract;
  let admin;

  beforeEach(async () => {
        ([admin] = await ethers.getSigners());

        // Deploy contract
        const MyContract = await ethers.getContractFactory("MyContract");
        contractToTest = await MyContract.deploy();
        await contractToTest.deployed();
       
        // ~~~~~~~~~~~~~ HERE LIES THE ISSUE ~~~~~~~~~~~~

        // Send some ERC20 to my contract
        // by trying to impersonate a whale and sending stuff from their accounts
        await hre.network.provider.request({
            method: "hardhat_impersonateAccount",
            params: [WETH_WHALE],
        });
        const signer = await ethers.provider.getSigner(WETH_WHALE);
        signer.address = signer._address;
        wethContract = await hre.ethers.getContractAt(IERC20_SOURCE, WETH_ADDRESS, signer);
        wethContract = wethContract.connect(signer);

        console.log("Signer WETH balance", await wethContract.balanceOf(signer.address))
        // Signer WETH balance BigNumber { value: "480881976480357719815777" }

        // ~~~~~~~~~~~~~~~ ERROR AFTER THIS LINE :
        await wethContract.transfer(contractToTest.address, ethers.utils.parseEther("10"));
        //  InvalidInputError: sender doesn't have enough funds to send tx. 
        // The max upfront cost is: 3311216806566865328 and the sender's account only has: 0

        // WE DON'T GET HERE: 
        // check that contractToTest actually holds the 10 WETH
        expect(await wethContract.balanceOf(contractToTest.address)).to.equal(
            ethers.utils.parseEther("10"), 
            "Contract to test should hold 10 WETH!");
  });

});

hardhat.config.js


require("@nomiclabs/hardhat-waffle");
require('dotenv').config();
require("@nomiclabs/hardhat-ethers");

/**
 * @type import('hardhat/config').HardhatUserConfig
 */
const { ALCHEMY_MAINNET_URL, PRIVATE_KEY } = process.env;
module.exports = {
  solidity: "0.6.12",
  defaultNetwork: "hardhat",
  networks: {
      hardhat: {
        forking: {
          url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_MAINNET_URL}`,
          // accounts: [`0x${PRIVATE_KEY}`]
        }
      }
  },
};


2
  • Hi Tudor, I am learning how to use solidity. May I ask what this means, the :IERC20 after .sol? Thanks! const IERC20_SOURCE = "@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20";
    – Bill
    Mar 17, 2022 at 3:29
  • I means that we use the Interface called IERC20 located inside the IERC20.sol file
    – Tudor B
    Mar 21, 2022 at 3:26

1 Answer 1

0

I think your problem is not that you did not send tokens into the contract, but that you do not have enough gas in the contract to cover the transaction cost. When deploying, send some value with this transaction so your contract can pay for their own transactions.

3
  • You're correct man! The contract that I was impersonating did not hold any ETH, so I could not interact with the blockchain at all from it. Thank you.
    – Tudor B
    Feb 24, 2022 at 3:02
  • possible to add the solution here? how do you send value?
    – p0pps
    Sep 2, 2022 at 14:31
  • @p0pps you can send ether to another address like this: await this.yourContract.yourFunction({from: depositorABC, value: depositAmount}); Sep 13, 2022 at 19:16

Your Answer

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

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