I'm trying to create clones of my implementation contract (EIP-1167) using the OpenZeppelin Clones library, however I keep getting a VM Exception Error.
This is the 'Initialize' function of my Implementation contract:
contract Whoopy is Initializable, VRFConsumerBaseV2, KeeperCompatible {
function initialize(address _whoopyCreator) public initializer {
VRFConsumerBaseV2.initialise(vrfCoordinatorV2);
i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
s_raffleState = RaffleState.CLOSED;
s_lastTimeStamp = block.timestamp;
whoopyCreator = _whoopyCreator;
i_vrfCoordinator.addConsumer(subscriptionId, address(this));
emit NewConsumerAdded(address(this));
}
This is my CloneFactory:
pragma solidity ^0.8.8;
import "@openzeppelin/contracts/proxy/Clones.sol";
contract WhoopyFactory {
address public implementationContract;
address[] public allClones;
event NewClone(address indexed _instance);
mapping(address => address) public whoopyList;
constructor(address _implementation) {
implementationContract = _implementation;
}
function createClone(address _whoopyCreator) payable external returns (address instance) {
instance = Clones.clone(implementationContract);
(bool success, ) = instance.call{value: msg.value}(abi.encodeWithSignature("initialize(address)", _whoopyCreator));
require(success==true, "initialize did not return true");
allClones.push(instance);
whoopyList[_whoopyCreator] = instance;
emit NewClone(instance);
return instance;
}
This is the test I am running:
const { assert, expect } = require("chai")
const { ethers, upgrades } = require("hardhat")
const { networkConfig } = require("../../helper-hardhat-config")
const fs = require("fs")
const path = require("path")
const { web3, Contract } = require("web3")
const getGas = async (tx) => {
const receipt = await ethers.provider.getTransactionReceipt(tx.hash)
return receipt.gasUsed.toString()
}
let whoopy,
Whoopy,
WhoopyFactory,
wf,
whoopyStandaloneGas,
whoopyFactoryGas,
clonedContract,
accountConnectedClone,
wCreator,
wallet,
addr1,
addr2
describe("Whoopy + WhoopyFactory", function () {
it("Initialises contract correctly", async function () {
provider = ethers.provider
addr1 = new ethers.Wallet("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", provider)
addr2 = new ethers.Wallet("0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", provider)
Whoopy = await ethers.getContractFactory("Whoopy", addr1)
whoopy = await Whoopy.deploy()
await whoopy.deployed()
const dir = path.resolve(
__dirname,
"/Users/boss/hardhat-smartcontract-lottery/artifacts/contracts/Whoopy.sol/Whoopy.json"
)
const file = fs.readFileSync(dir, "utf8")
const json = JSON.parse(file)
const abi = json.abi
WhoopyFactory = await ethers.getContractFactory("WhoopyFactory", addr1)
wf = await WhoopyFactory.deploy(whoopy.address)
await wf.deployed()
wf.connect(addr2)
const tx = await wf.createClone("0x70997970C51812dc3A010C7d01b50e0d17dc79C8", {
value: ethers.utils.parseUnits("1", "ether"),
})
console.log(tx)
const txReceipt = await tx.wait(1)
console.log(txReceipt)
})
})
When I run this test, I get the following error:
Error: VM Exception while processing transaction: reverted with reason string 'initialize did not return true'
This exact same code works perfectly when I try it in Remix, so I assume the issue has something to do with Hardhat.
Does anyone have any idea where the issue is? I've been racking my head for days but can't seem to figure out. I'd be extremely grateful if someone can point me in the right direction.
Thanks!
NOTE: Here is my hardhat config (in case it makes a difference):
require("@nomiclabs/hardhat-waffle")
require("@nomiclabs/hardhat-etherscan")
require("hardhat-deploy")
require("solidity-coverage")
require("hardhat-gas-reporter")
require("hardhat-contract-sizer")
require("dotenv").config()
require("@nomiclabs/hardhat-ethers");
// require('@openzeppelin/contracts');
const RINKEBY_RPC_URL = process.env.RINKEBY_RPC_URL
const PRIVATE_KEY = process.env.PRIVATE_KEY
const COINMARKETCAP_API_KEY = process.env.COINMARKETCAP_API_KEY
const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
defaultNetwork: "hardhat",
networks: {
hardhat: {
chainId: 31337,
blockConfirmations: 1
},
localhost: {
chainId: 31337,
},
rinkeby: {
chainId: 4,
blockConfirmations: 6,
url: RINKEBY_RPC_URL,
accounts: [PRIVATE_KEY]
}
},
solidity: "0.8.8",
gasReporter: {
enabled: true,
currency: "USD",
outputFile: "gas-report.txt",
noColors: true,
// coinmarketcap: process.env.COINMARKETCAP_API_KEY,
},
namedAccounts: {
deployer: {
default: 0,
},
player: {
default: 1,
}
},
mocha: {
timeout: 900000,
},
etherscan: {
apiKey: {
rinkeby: ETHERSCAN_API_KEY,
// kovan: ETHERSCAN_API_KEY,
// polygon: POLYGONSCAN_API_KEY,
},
},
};