Skip to content

Commit

Permalink
✨ feat: deploy init call
Browse files Browse the repository at this point in the history
  • Loading branch information
noyyyy committed Oct 30, 2022
1 parent 8c8dc83 commit 990064c
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 8 deletions.
10 changes: 8 additions & 2 deletions contracts/Create2Deployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,15 @@ contract Create2Deployer is Ownable, Pausable {
function deploy(
uint256 value,
bytes32 salt,
bytes memory code
bytes memory code,
bytes memory initCall
) public whenNotPaused {
Create2.deploy(value, salt, code);
address addr = Create2.deploy(value, salt, code);

if (initCall.length > 0) {
(bool success, bytes memory reason) = addr.call(initCall);
require(success, string(reason));
}
}

/**
Expand Down
11 changes: 11 additions & 0 deletions contracts/mocks/OwnableMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT
// Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/mocks/ERC20Mock.sol

pragma solidity ^0.8.9;

import "@openzeppelin/contracts/access/Ownable.sol";

// Mock class using ERC20
contract OwnableMock is Ownable {
constructor() {}
}
61 changes: 55 additions & 6 deletions test/Create2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const { expect } = require("chai");

const Create2Deployer = artifacts.require("Create2Deployer");
const ERC20Mock = artifacts.require("ERC20Mock");
const OwnableMock = artifacts.require("OwnableMock");
const ERC1820Implementer = artifacts.require("ERC1820Implementer");

contract("Create2", function (accounts) {
Expand Down Expand Up @@ -84,14 +85,62 @@ contract("Create2", function (accounts) {
constructorByteCode
);

await this.factory.deploy(0, saltHex, constructorByteCode);
await this.factory.deploy(0, saltHex, constructorByteCode, "0x");

const erc20 = await ERC20Mock.at(offChainComputed);
expect(await erc20.balanceOf(deployerAccount)).to.be.bignumber.equal(
new BN(100)
);
});

it("deploy a Ownable Mock with correct initial call", async function () {
const offChainComputed = computeCreate2Address(
this.factory.address,
saltHex,
OwnableMock.bytecode
);

const transferOwnershipAbi = OwnableMock.abi.filter(
(f: any) => f.name === "transferOwnership" && f.inputs.length === 1
)[0];

const transferOwnershipCall = web3.eth.abi.encodeFunctionCall(
transferOwnershipAbi,
[deployerAccount]
);

await this.factory.deploy(
0,
saltHex,
OwnableMock.bytecode,
transferOwnershipCall
);

const ownable = await OwnableMock.at(offChainComputed);
expect(await ownable.owner()).to.be.equal(deployerAccount);
});

it("deploy a Ownable Mock with wrong init call", async function () {
const transferOwnershipAbi = OwnableMock.abi.filter(
(f: any) => f.name === "transferOwnership" && f.inputs.length === 1
)[0];

const wrongTransferOwnershipCall = web3.eth.abi.encodeFunctionCall(
transferOwnershipAbi,
["0x0000000000000000000000000000000000000000"]
);

expectRevert(
this.factory.deploy(
0,
saltHex,
OwnableMock.bytecode,
wrongTransferOwnershipCall
),
"Ownable: caller is not the owner"
);
});

it("deploys a contract with funds deposited in the factory", async function () {
const deposit = ether("2");
await send.ether(deployerAccount, this.factory.address, deposit);
Expand All @@ -105,18 +154,18 @@ contract("Create2", function (accounts) {
this.factory.address
);

await this.factory.deploy(deposit, saltHex, constructorByteCode);
await this.factory.deploy(deposit, saltHex, constructorByteCode, "0x");
expect(await balance.current(onChainComputed)).to.be.bignumber.equal(
deposit
);
});

it("fails deploying a contract in an existent address", async function () {
await this.factory.deploy(0, saltHex, constructorByteCode, {
await this.factory.deploy(0, saltHex, constructorByteCode, "0x", {
from: deployerAccount,
});
await expectRevert(
this.factory.deploy(0, saltHex, constructorByteCode, {
this.factory.deploy(0, saltHex, constructorByteCode, "0x", {
from: deployerAccount,
}),
"Create2: Failed on deploy"
Expand All @@ -125,14 +174,14 @@ contract("Create2", function (accounts) {

it("fails deploying a contract if the bytecode length is zero", async function () {
await expectRevert(
this.factory.deploy(0, saltHex, "0x", { from: deployerAccount }),
this.factory.deploy(0, saltHex, "0x", "0x", { from: deployerAccount }),
"Create2: bytecode length is zero"
);
});

it("fails deploying a contract if factory contract does not have sufficient balance", async function () {
await expectRevert(
this.factory.deploy(1, saltHex, constructorByteCode, {
this.factory.deploy(1, saltHex, constructorByteCode, "0x", {
from: deployerAccount,
}),
"Create2: insufficient balance"
Expand Down

0 comments on commit 990064c

Please sign in to comment.