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}`]
}
}
},
};
Best Answer
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.