-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: Add comprehensive test suite for MultisigFactory contract
- Loading branch information
1 parent
4e590c2
commit e402ed9
Showing
1 changed file
with
169 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
import { expect } from "chai"; | ||
import { ethers, upgrades } from "hardhat"; | ||
import { MultisigFactory, Multisig, MasterMultisig } from "../../typechain-types"; | ||
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; | ||
|
||
describe("MultisigFactory", function () { | ||
let multisigFactory: MultisigFactory; | ||
let owner: SignerWithAddress; | ||
let addr1: SignerWithAddress; | ||
let addr2: SignerWithAddress; | ||
let ecosystemMaster: SignerWithAddress; | ||
let commonMaster: SignerWithAddress; | ||
|
||
beforeEach(async function () { | ||
[owner, addr1, addr2, ecosystemMaster, commonMaster] = await ethers.getSigners(); | ||
|
||
const MultisigFactoryFactory = await ethers.getContractFactory("MultisigFactory"); | ||
multisigFactory = await upgrades.deployProxy(MultisigFactoryFactory, [ | ||
ecosystemMaster.address, | ||
commonMaster.address | ||
]) as MultisigFactory; | ||
await multisigFactory.deployed(); | ||
}); | ||
|
||
describe("initialization", function () { | ||
it("should initialize with correct masters", async function () { | ||
await expect( | ||
upgrades.deployProxy(await ethers.getContractFactory("MultisigFactory"), [ | ||
ethers.constants.AddressZero, | ||
commonMaster.address | ||
]) | ||
).to.be.revertedWith("Invalid ecosystem master"); | ||
|
||
await expect( | ||
upgrades.deployProxy(await ethers.getContractFactory("MultisigFactory"), [ | ||
ecosystemMaster.address, | ||
ethers.constants.AddressZero | ||
]) | ||
).to.be.revertedWith("Invalid common master"); | ||
}); | ||
|
||
it("should set correct roles", async function () { | ||
expect(await multisigFactory.hasRole(await multisigFactory.DEFAULT_ADMIN_ROLE(), owner.address)).to.be.true; | ||
expect(await multisigFactory.hasRole(await multisigFactory.CREATOR_ROLE(), owner.address)).to.be.true; | ||
}); | ||
}); | ||
|
||
describe("createMultisig", function () { | ||
it("should create new multisig with correct parameters", async function () { | ||
const settings = { | ||
signers: [addr1.address, addr2.address], | ||
isInitiatorFlags: [true, false], | ||
threshold: 100, | ||
owner: owner.address | ||
}; | ||
|
||
await expect(multisigFactory.createMultisig(settings)) | ||
.to.emit(multisigFactory, "MultisigCreated"); | ||
|
||
expect(await multisigFactory.getMultisigsCount()).to.equal(1); | ||
|
||
const multisigAddresses = await multisigFactory.getMultisigsAddresses(); | ||
expect(multisigAddresses).to.have.length(1); | ||
|
||
const multisig = await ethers.getContractAt("Multisig", multisigAddresses[0]); | ||
const [signers, flags] = await multisig.getSigners(); | ||
expect(signers).to.deep.equal(settings.signers); | ||
expect(flags).to.deep.equal(settings.isInitiatorFlags); | ||
expect(await multisig.owner()).to.equal(settings.owner); | ||
}); | ||
|
||
it("should fail if caller doesn't have CREATOR_ROLE", async function () { | ||
const settings = { | ||
signers: [addr1.address], | ||
isInitiatorFlags: [true], | ||
threshold: 100, | ||
owner: owner.address | ||
}; | ||
|
||
await expect( | ||
multisigFactory.connect(addr1).createMultisig(settings) | ||
).to.be.revertedWith( | ||
`AccessControl: account ${addr1.address.toLowerCase()} is missing role ${await multisigFactory.CREATOR_ROLE()}` | ||
); | ||
}); | ||
}); | ||
|
||
describe("registerMultisigs", function () { | ||
let existingMultisig: Multisig; | ||
|
||
beforeEach(async function () { | ||
const MultisigFactory = await ethers.getContractFactory("Multisig"); | ||
existingMultisig = await MultisigFactory.deploy( | ||
[addr1.address], | ||
[true], | ||
100, | ||
owner.address | ||
); | ||
}); | ||
|
||
it("should register existing multisigs", async function () { | ||
await expect(multisigFactory.registerMultisigs([existingMultisig.address])) | ||
.to.emit(multisigFactory, "MultisigRegistered") | ||
.withArgs(existingMultisig.address); | ||
|
||
expect(await multisigFactory.isRegisteredMultisig(existingMultisig.address)).to.be.true; | ||
expect(await multisigFactory.getMultisigsCount()).to.equal(1); | ||
}); | ||
|
||
it("should fail to register zero address", async function () { | ||
await expect( | ||
multisigFactory.registerMultisigs([ethers.constants.AddressZero]) | ||
).to.be.revertedWith("Invalid multisig address"); | ||
}); | ||
|
||
it("should fail to register same multisig twice", async function () { | ||
await multisigFactory.registerMultisigs([existingMultisig.address]); | ||
await expect( | ||
multisigFactory.registerMultisigs([existingMultisig.address]) | ||
).to.be.revertedWith("Already registered"); | ||
}); | ||
|
||
it("should fail if caller doesn't have CREATOR_ROLE", async function () { | ||
await expect( | ||
multisigFactory.connect(addr1).registerMultisigs([existingMultisig.address]) | ||
).to.be.revertedWith( | ||
`AccessControl: account ${addr1.address.toLowerCase()} is missing role ${await multisigFactory.CREATOR_ROLE()}` | ||
); | ||
}); | ||
}); | ||
|
||
describe("view functions", function () { | ||
it("should return correct counts and addresses", async function () { | ||
expect(await multisigFactory.getMultisigsCount()).to.equal(0); | ||
expect(await multisigFactory.getMultisigsAddresses()).to.deep.equal([]); | ||
|
||
// Create a multisig | ||
const settings = { | ||
signers: [addr1.address], | ||
isInitiatorFlags: [true], | ||
threshold: 100, | ||
owner: owner.address | ||
}; | ||
|
||
await multisigFactory.createMultisig(settings); | ||
|
||
expect(await multisigFactory.getMultisigsCount()).to.equal(1); | ||
const addresses = await multisigFactory.getMultisigsAddresses(); | ||
expect(addresses).to.have.length(1); | ||
expect(await multisigFactory.isRegisteredMultisig(addresses[0])).to.be.true; | ||
}); | ||
}); | ||
|
||
describe("upgrade control", function () { | ||
it("should allow admin to upgrade", async function () { | ||
const MultisigFactoryV2 = await ethers.getContractFactory("MultisigFactory"); | ||
await expect( | ||
upgrades.upgradeProxy(multisigFactory.address, MultisigFactoryV2) | ||
).to.not.be.reverted; | ||
}); | ||
|
||
it("should not allow non-admin to upgrade", async function () { | ||
const MultisigFactoryV2 = await ethers.getContractFactory("MultisigFactory", addr1); | ||
await expect( | ||
upgrades.upgradeProxy(multisigFactory.address, MultisigFactoryV2) | ||
).to.be.reverted; | ||
}); | ||
}); | ||
}); |