diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz deleted file mode 100644 index 24ac74d86..000000000 Binary files a/.yarn/install-state.gz and /dev/null differ diff --git a/tests/hardhat/Governance/GovernanceBravo/castVoteTest.ts b/tests/hardhat/Governance/GovernanceBravo/castVoteTest.ts deleted file mode 100644 index a6bf53d8a..000000000 --- a/tests/hardhat/Governance/GovernanceBravo/castVoteTest.ts +++ /dev/null @@ -1,260 +0,0 @@ -import { FakeContract, MockContract, smock } from "@defi-wonderland/smock"; -import { loadFixture, mine } from "@nomicfoundation/hardhat-network-helpers"; -import chai from "chai"; -import { BigNumber, Signer } from "ethers"; -import { ethers, network } from "hardhat"; - -import { convertToUnit } from "../../../../helpers/utils"; -import { GovernorBravoDelegate, GovernorBravoDelegate__factory, XVS, XVSStore, XVSVault } from "../../../../typechain"; -import { ProposalType } from "../../util/Proposals"; - -const { expect } = chai; -chai.use(smock.matchers); - -const { encodeParameters } = require("../../../Utils/BSC"); - -let root: Signer; -let customer: Signer; -let accounts: Signer[]; -let governorBravoDelegate: MockContract; -let xvsVault: FakeContract; -let xvsToken: FakeContract; - -type GovernorBravoDelegateFixture = { - governorBravoDelegate: MockContract; - xvsVault: FakeContract; - xvsStore: FakeContract; - xvsToken: FakeContract; -}; - -const proposalConfigs = { - // ProposalType.NORMAL - 0: { - votingDelay: 1, - votingPeriod: 4, - proposalThreshold: convertToUnit("150000", 18), - }, - // ProposalType.FASTTRACK - 1: { - votingDelay: 1, - votingPeriod: 8, - proposalThreshold: convertToUnit("200000", 18), - }, - // ProposalType.CRITICAL - 2: { - votingDelay: 1, - votingPeriod: 16, - proposalThreshold: convertToUnit("250000", 18), - }, -}; - -async function governorBravoFixture(): Promise { - const GovernorBravoDelegateFactory = await smock.mock("GovernorBravoDelegate"); - const governorBravoDelegate = await GovernorBravoDelegateFactory.deploy(); - const xvsVault = await smock.fake("XVSVault"); - const xvsStore = await smock.fake("XVSStore"); - const xvsToken = await smock.fake("XVS"); - return { governorBravoDelegate, xvsVault, xvsStore, xvsToken }; -} - -describe("Governor Bravo Cast Vote Test", () => { - beforeEach(async () => { - [root, customer, ...accounts] = await ethers.getSigners(); - const contracts = await loadFixture(governorBravoFixture); - ({ governorBravoDelegate, xvsVault, xvsToken } = contracts); - await governorBravoDelegate.setVariable("admin", await root.getAddress()); - await governorBravoDelegate.setVariable("initialProposalId", 1); - await governorBravoDelegate.setVariable("proposalCount", 1); - await governorBravoDelegate.setVariable("xvsVault", xvsVault.address); - await governorBravoDelegate.setVariable("proposalMaxOperations", 10); - await governorBravoDelegate.setVariable("proposalConfigs", proposalConfigs); - }); - describe("We must revert if:", () => { - let customerAddress; - it("We cannot propose without enough voting power by depositing xvs to the vault", async () => { - customerAddress = await customer.getAddress(); - xvsVault.getPriorVotes.returns(convertToUnit("249999", 18)); - await expect( - governorBravoDelegate.propose( - [customerAddress], - ["0"], - ["getBalanceOf(address)"], - [encodeParameters(["address"], [customerAddress])], - "do nothing", - ProposalType.CRITICAL, - ), - ).to.be.revertedWith("GovernorBravo::propose: proposer votes below proposal threshold"); - }); - describe("after we deposit xvs to the vault", () => { - let proposalId: BigNumber; - beforeEach(async () => { - customerAddress = await customer.getAddress(); - const rootAddress = await root.getAddress(); - xvsToken.balanceOf.whenCalledWith(rootAddress).returns(400001); - xvsVault.getPriorVotes.returns(convertToUnit("300000", 18)); - await governorBravoDelegate.setVariable("proposalConfigs", proposalConfigs); - await governorBravoDelegate.propose( - [customerAddress], - ["0"], - ["getBalanceOf(address)"], - [encodeParameters(["address"], [customerAddress])], - "do nothing", - ProposalType.CRITICAL, - ); - proposalId = await governorBravoDelegate.latestProposalIds(await root.getAddress()); - }); - - it("There does not exist a proposal with matching proposal id where the current block number is between the proposal's start block (exclusive) and end block (inclusive)", async () => { - await expect(governorBravoDelegate.castVote(proposalId, 1)).to.be.revertedWith( - "GovernorBravo::castVoteInternal: voting is closed", - ); - }); - - it("Such proposal already has an entry in its voters set matching the sender", async () => { - await mine(); - await mine(); - - await governorBravoDelegate.connect(accounts[4]).castVote(proposalId, 1); - await governorBravoDelegate.connect(accounts[3]).castVoteWithReason(proposalId, 1, ""); - await expect(governorBravoDelegate.connect(accounts[4]).castVote(proposalId, 1)).to.be.revertedWith( - "GovernorBravo::castVoteInternal: voter already voted", - ); - }); - describe("Otherwise", () => { - it("we add the sender to the proposal's voters set", async () => { - let receipt = await governorBravoDelegate.getReceipt(proposalId, await accounts[2].getAddress()); - expect(receipt.hasVoted).to.be.false; - //Mine a block to make the proposal in Active State - await mine(); - await governorBravoDelegate.connect(accounts[2]).castVote(proposalId, 1); - receipt = await governorBravoDelegate.getReceipt(proposalId, await accounts[2].getAddress()); - expect(receipt.hasVoted).to.be.true; - }); - }); - - describe("and we take the balance returned by GetPriorVotes for the given sender and the proposal's start block, which may be zero,", () => { - let actor; // an account that will propose, deposit token to be franchised - - it("and we add that ForVotes", async () => { - actor = accounts[1]; - const actorAddress = await actor.getAddress(); - - await governorBravoDelegate - .connect(actor) - .propose( - [actorAddress], - ["0"], - ["getBalanceOf(address)"], - [encodeParameters(["address"], [actorAddress])], - "do nothing", - ProposalType.NORMAL, - ); - - proposalId = await governorBravoDelegate.latestProposalIds(actorAddress); - - let proposal = await governorBravoDelegate.proposals(proposalId); - const beforeFors = proposal.forVotes; - await mine(); - await governorBravoDelegate.connect(actor).castVote(proposalId, 1); - proposal = await governorBravoDelegate.proposals(proposalId); - const afterFors = proposal.forVotes; - - expect(beforeFors.add(convertToUnit("300000", 18))).to.equal(afterFors); - }); - - it("or AgainstVotes corresponding to the caller's support flag.", async () => { - actor = accounts[3]; - const actorAddress = await actor.getAddress(); - - await governorBravoDelegate - .connect(actor) - .propose( - [actorAddress], - ["0"], - ["getBalanceOf(address)"], - [encodeParameters(["address"], [actorAddress])], - "do nothing", - ProposalType.NORMAL, - ); - - proposalId = await governorBravoDelegate.latestProposalIds(actorAddress); - - let proposal = await governorBravoDelegate.proposals(proposalId); - const beforeAgainsts = proposal.againstVotes; - await mine(); - await governorBravoDelegate.connect(actor).castVote(proposalId, 0); - proposal = await governorBravoDelegate.proposals(proposalId); - const afterAgainsts = proposal.againstVotes; - - expect(beforeAgainsts.add(convertToUnit("300000", 18))).to.equal(afterAgainsts); - }); - }); - describe("castVoteBySig", () => { - it("reverts if the signatory is invalid", async () => { - await expect( - governorBravoDelegate.castVoteBySig( - proposalId, - 0, - 0, - ethers.utils.formatBytes32String("r"), - ethers.utils.formatBytes32String("s"), - ), - ).to.be.revertedWith("GovernorBravo::castVoteBySig: invalid signature"); - }); - - it("casts vote on behalf of the signatory", async () => { - const actor = accounts[1]; - const actorAddress = await actor.getAddress(); - await governorBravoDelegate - .connect(actor) - .propose( - [actorAddress], - ["0"], - ["getBalanceOf(address)"], - [encodeParameters(["address"], [actorAddress])], - "do nothing", - ProposalType.NORMAL, - ); - - let proposal = await governorBravoDelegate.proposals(proposalId); - const beforeFors = proposal.forVotes; - await mine(); - - const proposalIdNum: number = proposalId.toNumber(); - - const data = { - types: { - Ballot: [ - { name: "proposalId", type: "uint256" }, - { name: "support", type: "uint8" }, - ], - }, - primaryType: "Ballot", - domain: { - name: "Venus Governor Bravo", - chainId: 1, // await web3.eth.net.getId(); See: https://github.com/trufflesuite/ganache-core/issues/515 - verifyingContract: governorBravoDelegate.address, - }, - message: { - proposalId: proposalIdNum, - support: 1, - }, - }; - - const signatureLike = await network.provider.send("eth_signTypedData_v4", [actorAddress, data]); - - const signature = await ethers.utils.splitSignature(signatureLike); - - const tx = await governorBravoDelegate.castVoteBySig(proposalId, 1, signature.v, signature.r, signature.s); - - const receipt = await tx.wait(); - expect(receipt.gasUsed.toNumber() < 80000); - - proposal = await governorBravoDelegate.proposals(proposalId); - const afterFors = proposal.forVotes; - expect(beforeFors.add(convertToUnit("300000", 18))).to.equal(afterFors); - }); - }); - }); - }); -}); diff --git a/tests/hardhat/Governance/GovernanceBravo/intializeTests.ts b/tests/hardhat/Governance/GovernanceBravo/intializeTests.ts deleted file mode 100644 index 1c2f212ec..000000000 --- a/tests/hardhat/Governance/GovernanceBravo/intializeTests.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { FakeContract, MockContract, smock } from "@defi-wonderland/smock"; -import { loadFixture } from "@nomicfoundation/hardhat-network-helpers"; -import chai from "chai"; -import { Signer } from "ethers"; -import { ethers } from "hardhat"; - -import { GovernorBravoDelegate, GovernorBravoDelegate__factory, XVSVault } from "../../../../typechain"; - -const { expect } = chai; -chai.use(smock.matchers); - -let root: Signer; -let customer: Signer; -let accounts: Signer[]; -let governorBravoDelegate: MockContract; -let xvsVault: FakeContract; - -type GovernorBravoDelegateFixture = { - governorBravoDelegate: MockContract; - xvsVault: FakeContract; -}; - -async function governorBravoFixture(): Promise { - const GovernorBravoDelegateFactory = await smock.mock("GovernorBravoDelegate"); - const governorBravoDelegate = await GovernorBravoDelegateFactory.deploy(); - const xvsVault = await smock.fake("XVSVault"); - return { governorBravoDelegate, xvsVault }; -} - -describe("Governor Bravo Initializing Test", () => { - beforeEach(async () => { - [root, customer, ...accounts] = await ethers.getSigners(); - const contracts = await loadFixture(governorBravoFixture); - ({ governorBravoDelegate, xvsVault } = contracts); - await governorBravoDelegate.setVariable("admin", await root.getAddress()); - }); - - describe("initilizer", () => { - it("should revert if not called by admin", async () => { - await expect( - governorBravoDelegate - .connect(customer) - .initialize(ethers.constants.AddressZero, [], [], ethers.constants.AddressZero), - ).to.be.revertedWith("GovernorBravo::initialize: admin only"); - }); - it("should revert if invalid xvs address", async () => { - await expect( - governorBravoDelegate.initialize(ethers.constants.AddressZero, [], [], ethers.constants.AddressZero), - ).to.be.revertedWith("GovernorBravo::initialize: invalid xvs address"); - }); - it("should revert if invalid guardian address", async () => { - await expect( - governorBravoDelegate.initialize(xvsVault.address, [], [], ethers.constants.AddressZero), - ).to.be.revertedWith("GovernorBravo::initialize: invalid guardian"); - }); - it("should revert if timelock adress count differs from governance routes count", async () => { - const guardianAddress = await accounts[0].getAddress(); - - const timelocks = [accounts[0].getAddress(), accounts[1].getAddress()]; - await expect( - governorBravoDelegate.initialize(xvsVault.address, [], timelocks, guardianAddress), - ).to.be.revertedWith("GovernorBravo::initialize:number of timelocks should match number of governance routes"); - }); - it("should revert if proposal config count differs from governance routes count", async () => { - const guardianAddress = await accounts[0].getAddress(); - const proposalConfigs = [ - { votingDelay: 0, votingPeriod: 1, proposalThreshold: 2 }, - { votingDelay: 0, votingPeriod: 2, proposalThreshold: 3 }, - { votingDelay: 0, votingPeriod: 3, proposalThreshold: 4 }, - { votingDelay: 0, votingPeriod: 4, proposalThreshold: 5 }, - ]; - - const timelocks = [accounts[0].getAddress(), accounts[1].getAddress(), accounts[2].getAddress()]; - await expect( - governorBravoDelegate.initialize(xvsVault.address, proposalConfigs, timelocks, guardianAddress), - ).to.be.revertedWith( - "GovernorBravo::initialize:number of proposal configs should match number of governance routes", - ); - }); - - it("should revert if initialized twice", async () => { - const guardianAddress = await accounts[0].getAddress(); - const minVotingDelay = await governorBravoDelegate.MIN_VOTING_DELAY(); - const minVotingPeriod = await governorBravoDelegate.MIN_VOTING_PERIOD(); - const minProposalThreshold = await governorBravoDelegate.MIN_PROPOSAL_THRESHOLD(); - const proposalConfigs = [ - { - votingDelay: minVotingDelay.add(10), - votingPeriod: minVotingPeriod.add(100), - proposalThreshold: minProposalThreshold.add(100), - }, - { - votingDelay: minVotingDelay.add(10), - votingPeriod: minVotingPeriod.add(100), - proposalThreshold: minProposalThreshold.add(100), - }, - { - votingDelay: minVotingDelay.add(10), - votingPeriod: minVotingPeriod.add(100), - proposalThreshold: minProposalThreshold.add(100), - }, - ]; - - const timelocks = [accounts[0].getAddress(), accounts[1].getAddress(), accounts[2].getAddress()]; - await governorBravoDelegate.initialize(xvsVault.address, proposalConfigs, timelocks, guardianAddress); - await expect( - governorBravoDelegate.initialize(xvsVault.address, proposalConfigs, timelocks, guardianAddress), - ).to.be.revertedWith("GovernorBravo::initialize: cannot initialize twice"); - }); - - //TODO: implement tests for min, max value validation of voting period, voting delay, proposal threshold - }); -}); diff --git a/tests/hardhat/Governance/GovernanceBravo/proposeTest.ts b/tests/hardhat/Governance/GovernanceBravo/proposeTest.ts deleted file mode 100644 index 0b0717679..000000000 --- a/tests/hardhat/Governance/GovernanceBravo/proposeTest.ts +++ /dev/null @@ -1,249 +0,0 @@ -import { FakeContract, MockContract, smock } from "@defi-wonderland/smock"; -import { loadFixture, mine } from "@nomicfoundation/hardhat-network-helpers"; -import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; -import chai from "chai"; -import { BigNumber } from "ethers"; -import { ethers } from "hardhat"; - -import { convertToUnit } from "../../../../helpers/utils"; -import { GovernorBravoDelegate, GovernorBravoDelegate__factory, XVS, XVSStore, XVSVault } from "../../../../typechain"; -import { ProposalType } from "../../util/Proposals"; - -const { expect } = chai; -chai.use(smock.matchers); - -const { encodeParameters } = require("../../../Utils/BSC"); - -let root: SignerWithAddress; -let customer: SignerWithAddress; -let accounts: SignerWithAddress[]; -let governorBravoDelegate: MockContract; -let xvsVault: FakeContract; -let xvsToken: FakeContract; - -type GovernorBravoDelegateFixture = { - governorBravoDelegate: MockContract; - xvsVault: FakeContract; - xvsStore: FakeContract; - xvsToken: FakeContract; -}; - -async function governorBravoFixture(): Promise { - const GovernorBravoDelegateFactory = await smock.mock("GovernorBravoDelegate"); - const governorBravoDelegate = await GovernorBravoDelegateFactory.deploy(); - const xvsVault = await smock.fake("XVSVault"); - const xvsStore = await smock.fake("XVSStore"); - const xvsToken = await smock.fake("XVS"); - return { governorBravoDelegate, xvsVault, xvsStore, xvsToken }; -} - -const proposalConfigs = { - // ProposalType.NORMAL - 0: { - votingDelay: 1, - votingPeriod: 4, - proposalThreshold: convertToUnit("150000", 18), - }, - // ProposalType.FASTTRACK - 1: { - votingDelay: 1, - votingPeriod: 8, - proposalThreshold: convertToUnit("200000", 18), - }, - // ProposalType.CRITICAL - 2: { - votingDelay: 1, - votingPeriod: 16, - proposalThreshold: convertToUnit("250000", 18), - }, -}; - -let targets: any[], values: string | any[], signatures: string | any[], callDatas: string | any[]; - -describe("Governor Bravo Propose Tests", () => { - let proposalId: BigNumber; - let trivialProposal: any; - let proposalBlock: number; - beforeEach(async () => { - [root, customer, ...accounts] = await ethers.getSigners(); - targets = [root.address]; - values = ["0"]; - signatures = ["getBalanceOf(address)"]; - callDatas = [encodeParameters(["address"], [root.address])]; - const contracts = await loadFixture(governorBravoFixture); - ({ governorBravoDelegate, xvsVault, xvsToken } = contracts); - await governorBravoDelegate.setVariable("admin", root.address); - await governorBravoDelegate.setVariable("initialProposalId", 1); - await governorBravoDelegate.setVariable("proposalCount", 1); - await governorBravoDelegate.setVariable("xvsVault", xvsVault.address); - await governorBravoDelegate.setVariable("proposalMaxOperations", 10); - xvsToken.balanceOf.returns(400001); - xvsVault.getPriorVotes.returns(convertToUnit("300000", 18)); - await governorBravoDelegate.setVariable("proposalConfigs", proposalConfigs); - await governorBravoDelegate.propose(targets, values, signatures, callDatas, "do nothing", ProposalType.CRITICAL); - proposalBlock = (await ethers.provider.getBlock("latest")).number; - proposalId = await governorBravoDelegate.latestProposalIds(root.address); - trivialProposal = await governorBravoDelegate.proposals(proposalId); - }); - - describe("simple initialization", () => { - it("ID is set to a globally unique identifier", async () => { - expect(trivialProposal.id).to.equal(proposalId); - }); - - it("Proposer is set to the sender", async () => { - expect(trivialProposal.proposer).to.equal(root.address); - }); - - it("Start block is set to the current block number plus vote delay", async () => { - expect(trivialProposal.startBlock).to.equal(proposalBlock + 1 + ""); - }); - - it("End block is set to the current block number plus the sum of vote delay and vote period", async () => { - expect(trivialProposal.endBlock).to.equal( - proposalBlock + proposalConfigs[2].votingDelay + proposalConfigs[2].votingPeriod, - ); - }); - - it("ForVotes and AgainstVotes are initialized to zero", async () => { - expect(trivialProposal.forVotes).to.equal("0"); - expect(trivialProposal.againstVotes).to.equal("0"); - }); - - it("Executed and Canceled flags are initialized to false", async () => { - expect(trivialProposal.canceled).to.equal(false); - expect(trivialProposal.executed).to.equal(false); - }); - - it("ETA is initialized to zero", async () => { - expect(trivialProposal.eta).to.equal("0"); - }); - - it("Targets, Values, Signatures, Calldatas are set according to parameters", async () => { - const dynamicFields = await governorBravoDelegate.getActions(trivialProposal.id); - expect(dynamicFields.targets).to.deep.equal([root.address]); - // values cannot be get with .values since it is reserved word and returns function - expect(dynamicFields[1]).to.deep.equal(values); - expect(dynamicFields.signatures).to.deep.equal(signatures); - expect(dynamicFields.calldatas).to.deep.equal(callDatas); - }); - - describe("This function must revert if", () => { - it("the length of the values, signatures or calldatas arrays are not the same length,", async () => { - await expect( - governorBravoDelegate.propose( - targets.concat(root.address), - values, - signatures, - callDatas, - "do nothing", - ProposalType.CRITICAL, - ), - ).to.be.revertedWith("GovernorBravo::propose: proposal function information arity mismatch"); - - await expect( - governorBravoDelegate.propose( - targets, - values.concat(root.address.toString()), - signatures, - callDatas, - "do nothing", - ProposalType.CRITICAL, - ), - ).to.be.revertedWith("GovernorBravo::propose: proposal function information arity mismatch"); - - await expect( - governorBravoDelegate.propose( - targets, - values, - signatures.concat(root.address.toString()), - callDatas, - "do nothing", - ProposalType.CRITICAL, - ), - ).to.be.revertedWith("GovernorBravo::propose: proposal function information arity mismatch"); - - await expect( - governorBravoDelegate.propose( - targets.concat(root.address.toString()), - values, - signatures, - callDatas, - "do nothing", - ProposalType.CRITICAL, - ), - ).to.be.revertedWith("GovernorBravo::propose: proposal function information arity mismatch"); - }); - - it("or if that length is zero or greater than Max Operations.", async () => { - await expect( - governorBravoDelegate.propose([], [], [], [], "do nothing", ProposalType.CRITICAL), - ).to.be.revertedWith("GovernorBravo::propose: must provide actions"); - }); - - describe("Additionally, if there exists a pending or active proposal from the same proposer, we must revert.", () => { - it("reverts with pending", async () => { - await expect( - governorBravoDelegate.propose(targets, values, signatures, callDatas, "do nothing", ProposalType.CRITICAL), - ).to.be.revertedWith( - "GovernorBravo::propose: one live proposal per proposer, found an already pending proposal", - ); - }); - it("reverts with active", async () => { - await mine(); - await mine(); - - await expect( - governorBravoDelegate.propose(targets, values, signatures, callDatas, "do nothing", ProposalType.CRITICAL), - ).to.be.revertedWith( - "GovernorBravo::propose: one live proposal per proposer, found an already active proposal", - ); - }); - }); - }); - - it("This function returns the id of the newly created proposal. # proposalId(n) = succ(proposalId(n-1))", async () => { - await mine(); - - await governorBravoDelegate - .connect(customer) - .propose(targets, values, signatures, callDatas, "yoot", ProposalType.CRITICAL); - - const nextProposalId = await governorBravoDelegate.latestProposalIds(customer.address); - expect(+nextProposalId).to.be.equal(+trivialProposal.id + 1); - }); - - it("emits log with id and description", async () => { - await mine(); - await governorBravoDelegate - .connect(accounts[3]) - .propose(targets, values, signatures, callDatas, "yoot", ProposalType.CRITICAL); - - const lastProposalId = await governorBravoDelegate.latestProposalIds(accounts[3].address); - const nextProposalId = lastProposalId.add(1); - - const submissionBlockNumber = (await ethers.provider.getBlock("latest")).number + 1; - const proposeStartBlock = submissionBlockNumber + proposalConfigs[2].votingDelay; - const proposeEndBlock = proposeStartBlock + proposalConfigs[2].votingPeriod; - - await expect( - await governorBravoDelegate - .connect(customer) - .propose(targets, values, signatures, callDatas, "second proposal", ProposalType.CRITICAL), - ) - .to.emit(governorBravoDelegate, "ProposalCreated") - .withArgs( - nextProposalId, - customer.address, - targets, - values, - signatures, - callDatas, - proposeStartBlock, - proposeEndBlock, - "second proposal", - ProposalType.CRITICAL, - ); - }); - }); -}); diff --git a/tests/hardhat/Governance/GovernanceBravo/queueTest.ts b/tests/hardhat/Governance/GovernanceBravo/queueTest.ts deleted file mode 100644 index d64c63870..000000000 --- a/tests/hardhat/Governance/GovernanceBravo/queueTest.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { FakeContract, MockContract, smock } from "@defi-wonderland/smock"; -import { loadFixture, mine } from "@nomicfoundation/hardhat-network-helpers"; -import chai from "chai"; -import { BigNumber, Signer } from "ethers"; -import { ethers } from "hardhat"; - -import { convertToUnit } from "../../../../helpers/utils"; -import { - GovernorBravoDelegate, - GovernorBravoDelegate__factory, - Timelock, - XVS, - XVSStore, - XVSVault, -} from "../../../../typechain"; -import { ProposalType } from "../../util/Proposals"; - -const { expect } = chai; -chai.use(smock.matchers); - -const { encodeParameters } = require("../../../Utils/BSC"); - -let root: Signer; -let customer: Signer; -let accounts: Signer[]; -let governorBravoDelegate: MockContract; -let xvsVault: FakeContract; -let xvsToken: FakeContract; -let timelock: FakeContract; - -type GovernorBravoDelegateFixture = { - governorBravoDelegate: MockContract; - xvsVault: FakeContract; - xvsStore: FakeContract; - xvsToken: FakeContract; - timelock: FakeContract; -}; - -async function governorBravoFixture(): Promise { - const GovernorBravoDelegateFactory = await smock.mock("GovernorBravoDelegate"); - const governorBravoDelegate = await GovernorBravoDelegateFactory.deploy(); - const xvsVault = await smock.fake("XVSVault"); - const xvsStore = await smock.fake("XVSStore"); - const xvsToken = await smock.fake("XVS"); - const timelock = await smock.fake("TimelockInterface"); - return { governorBravoDelegate, xvsVault, xvsStore, xvsToken, timelock }; -} - -const proposalConfigs = { - // ProposalType.NORMAL - 0: { - votingDelay: 1, - votingPeriod: 4, - proposalThreshold: convertToUnit("150000", 18), - }, - // ProposalType.FASTTRACK - 1: { - votingDelay: 1, - votingPeriod: 8, - proposalThreshold: convertToUnit("200000", 18), - }, - // ProposalType.CRITICAL - 2: { - votingDelay: 1, - votingPeriod: 16, - proposalThreshold: convertToUnit("250000", 18), - }, -}; - -describe("Governor Bravo Queue Tests", () => { - let rootAddress: string; - let proposalId: BigNumber; - beforeEach(async () => { - [root, customer, ...accounts] = await ethers.getSigners(); - rootAddress = await root.getAddress(); - const contracts = await loadFixture(governorBravoFixture); - ({ governorBravoDelegate, xvsVault, xvsToken, timelock } = contracts); - - await governorBravoDelegate.setVariable("admin", await root.getAddress()); - await governorBravoDelegate.setVariable("initialProposalId", 1); - await governorBravoDelegate.setVariable("proposalCount", 1); - await governorBravoDelegate.setVariable("xvsVault", xvsVault.address); - await governorBravoDelegate.setVariable("proposalMaxOperations", 10); - xvsToken.balanceOf.returns(400001); - xvsVault.getPriorVotes.returns(convertToUnit("600000", 18)); - await governorBravoDelegate.setVariable("proposalConfigs", proposalConfigs); - await governorBravoDelegate.setVariable("proposalTimelocks", { - 2: timelock.address, - }); - }); - describe("overlapping actions", () => { - it("reverts on queueing overlapping actions in same proposal", async () => { - await mine(); - const targets = [xvsToken.address, xvsToken.address]; - const values = ["0", "0"]; - const signatures = ["getBalanceOf(address)", "getBalanceOf(address)"]; - const calldatas = [encodeParameters(["address"], [rootAddress]), encodeParameters(["address"], [rootAddress])]; - await governorBravoDelegate - .connect(customer) - .propose(targets, values, signatures, calldatas, "do nothing", ProposalType.CRITICAL); - proposalId = await governorBravoDelegate.latestProposalIds(await customer.getAddress()); - await mine(); - - await governorBravoDelegate.connect(customer).castVote(proposalId, 1); - await advanceBlocks(17); - timelock.queuedTransactions.returns(true); - await expect(governorBravoDelegate.queue(proposalId)).to.be.revertedWith( - "GovernorBravo::queueOrRevertInternal: identical proposal action already queued at eta", - ); - }); - - it("reverts on queueing overlapping actions in different proposals", async () => { - await mine(); - - const targets = [xvsToken.address]; - const values = ["0"]; - const signatures = ["getBalanceOf(address)"]; - const calldatas = [encodeParameters(["address"], [rootAddress])]; - - await governorBravoDelegate - .connect(customer) - .propose(targets, values, signatures, calldatas, "do nothing1", ProposalType.CRITICAL); - - const proposalId1 = await governorBravoDelegate.latestProposalIds(await customer.getAddress()); - - await governorBravoDelegate - .connect(accounts[3]) - .propose(targets, values, signatures, calldatas, "do nothing", ProposalType.CRITICAL); - - const proposalId2 = await governorBravoDelegate.latestProposalIds(await accounts[3].getAddress()); - await mine(); - - await governorBravoDelegate.connect(customer).castVote(proposalId1, 1); - await governorBravoDelegate.connect(accounts[3]).castVote(proposalId2, 1); - await advanceBlocks(17); - timelock.queuedTransactions.returns(false); - await governorBravoDelegate.queue(proposalId1); - timelock.queuedTransactions.returns(true); - await expect(governorBravoDelegate.queue(proposalId2)).to.be.revertedWith( - "GovernorBravo::queueOrRevertInternal: identical proposal action already queued at eta", - ); - }); - }); -}); - -async function advanceBlocks(blocks: number) { - await mine(blocks); -} diff --git a/tests/hardhat/Governance/GovernanceBravo/stateTest.ts b/tests/hardhat/Governance/GovernanceBravo/stateTest.ts deleted file mode 100644 index 6206861e3..000000000 --- a/tests/hardhat/Governance/GovernanceBravo/stateTest.ts +++ /dev/null @@ -1,227 +0,0 @@ -import { FakeContract, MockContract, smock } from "@defi-wonderland/smock"; -import { loadFixture, mine } from "@nomicfoundation/hardhat-network-helpers"; -import chai from "chai"; -import { BigNumber, Signer } from "ethers"; -import { ethers, network } from "hardhat"; - -import { convertToUnit } from "../../../../helpers/utils"; -import { - GovernorBravoDelegate, - GovernorBravoDelegate__factory, - Timelock, - XVS, - XVSStore, - XVSVault, -} from "../../../../typechain"; -import { ProposalState, ProposalType } from "../../util/Proposals"; - -const { expect } = chai; -chai.use(smock.matchers); - -const { encodeParameters } = require("../../../Utils/BSC"); - -let root: Signer; -let customer: Signer; -let governorBravoDelegate: MockContract; -let xvsVault: FakeContract; -let xvsToken: FakeContract; -let timelock: FakeContract; - -type GovernorBravoDelegateFixture = { - governorBravoDelegate: MockContract; - xvsVault: FakeContract; - xvsStore: FakeContract; - xvsToken: FakeContract; - timelock: FakeContract; -}; - -async function governorBravoFixture(): Promise { - const GovernorBravoDelegateFactory = await smock.mock("GovernorBravoDelegate"); - const governorBravoDelegate = await GovernorBravoDelegateFactory.deploy(); - const xvsVault = await smock.fake("XVSVault"); - const xvsStore = await smock.fake("XVSStore"); - const xvsToken = await smock.fake("XVS"); - const timelock = await smock.fake("TimelockInterface"); - return { governorBravoDelegate, xvsVault, xvsStore, xvsToken, timelock }; -} - -const proposalConfigs = { - // ProposalType.NORMAL - 0: { - votingDelay: 1, - votingPeriod: 4, - proposalThreshold: convertToUnit("150000", 18), - }, - // ProposalType.FASTTRACK - 1: { - votingDelay: 1, - votingPeriod: 8, - proposalThreshold: convertToUnit("200000", 18), - }, - // ProposalType.CRITICAL - 2: { - votingDelay: 1, - votingPeriod: 16, - proposalThreshold: convertToUnit("250000", 18), - }, -}; - -describe("Governor Bravo State Tests", () => { - let rootAddress: string; - let proposalId: BigNumber; - let trivialProposal: any; - let targets: string[]; - let values: string[]; - let signatures: string[]; - let calldatas: string[] = []; - - beforeEach(async () => { - [root, customer] = await ethers.getSigners(); - rootAddress = await root.getAddress(); - const contracts = await loadFixture(governorBravoFixture); - ({ governorBravoDelegate, xvsVault, xvsToken, timelock } = contracts); - await governorBravoDelegate.setVariable("admin", await root.getAddress()); - await governorBravoDelegate.setVariable("initialProposalId", 1); - await governorBravoDelegate.setVariable("proposalCount", 1); - await governorBravoDelegate.setVariable("xvsVault", xvsVault.address); - await governorBravoDelegate.setVariable("proposalMaxOperations", 10); - xvsToken.balanceOf.returns(400001); - xvsVault.getPriorVotes.returns(convertToUnit("600000", 18)); - await governorBravoDelegate.setVariable("proposalConfigs", proposalConfigs); - await governorBravoDelegate.setVariable("proposalTimelocks", { - 2: timelock.address, - }); - - targets = [rootAddress]; - values = ["0"]; - signatures = ["getBalanceOf(address)"]; - calldatas = [encodeParameters(["address"], [rootAddress])]; - await governorBravoDelegate.propose(targets, values, signatures, calldatas, "do nothing", ProposalType.CRITICAL); - proposalId = await governorBravoDelegate.latestProposalIds(rootAddress); - trivialProposal = await governorBravoDelegate.proposals(proposalId); - await mineBlock(); - }); - - it("Invalid for proposal not found", async () => { - await expect(governorBravoDelegate.state(5)).to.be.revertedWith("GovernorBravo::state: invalid proposal id"); - }); - - it("Pending", async () => { - expect(await governorBravoDelegate.state(trivialProposal.id)).to.equal(ProposalState.Pending); - }); - it("Active", async () => { - await mineBlock(); - expect(await governorBravoDelegate.state(trivialProposal.id)).to.equal(ProposalState.Active); - }); - it("Canceled", async () => { - await governorBravoDelegate - .connect(customer) - .propose(targets, values, signatures, calldatas, "do nothing", ProposalType.CRITICAL); - xvsVault.getPriorVotes.returns(convertToUnit("200000", 18)); - - const newProposalId = await governorBravoDelegate.proposalCount(); - await governorBravoDelegate.cancel(newProposalId); - - expect(await governorBravoDelegate.state(newProposalId)).to.equal(ProposalState.Canceled); - }); - it("Canceled by Guardian", async () => { - await governorBravoDelegate.setVariable("guardian", rootAddress); - await governorBravoDelegate - .connect(customer) - .propose(targets, values, signatures, calldatas, "do nothing", ProposalType.CRITICAL); - const newProposalId = await governorBravoDelegate.proposalCount(); - await governorBravoDelegate.cancel(newProposalId); - - expect(await governorBravoDelegate.state(newProposalId)).to.equal(ProposalState.Canceled); - }); - it("Defeated", async () => { - // travel to end block - await advanceBlocks(18); - expect(await governorBravoDelegate.state(trivialProposal.id)).to.equal(ProposalState.Defeated); - }); - it("Succeeded", async () => { - xvsVault.getPriorVotes.returns(convertToUnit("300000", 18)); - await governorBravoDelegate - .connect(customer) - .propose(targets, values, signatures, calldatas, "do nothing", ProposalType.CRITICAL); - const newProposalId = await governorBravoDelegate.proposalCount(); - await mineBlock(); - await governorBravoDelegate.castVote(newProposalId, 1); - await governorBravoDelegate.connect(customer).castVote(newProposalId, 1); - await advanceBlocks(18); - expect(await governorBravoDelegate.state(newProposalId)).to.equal(ProposalState.Succeeded); - }); - it("Expired", async () => { - xvsVault.getPriorVotes.returns(convertToUnit("300000", 18)); - await governorBravoDelegate - .connect(customer) - .propose(targets, values, signatures, calldatas, "do nothing", ProposalType.CRITICAL); - const newProposalId = await governorBravoDelegate.proposalCount(); - await mineBlock(); - await governorBravoDelegate.castVote(newProposalId, 1); - await governorBravoDelegate.connect(customer).castVote(newProposalId, 1); - await advanceBlocks(16); - await governorBravoDelegate.queue(newProposalId); - expect(await governorBravoDelegate.state(newProposalId)).to.equal(ProposalState.Expired); - }); - it("Queued", async () => { - timelock.delay.returns(100); - await mineBlock(); - xvsVault.getPriorVotes.returns(convertToUnit("300000", 18)); - await governorBravoDelegate - .connect(customer) - .propose(targets, values, signatures, calldatas, "do nothing", ProposalType.CRITICAL); - const newProposalId = await governorBravoDelegate.proposalCount(); - await mineBlock(); - await governorBravoDelegate.castVote(newProposalId, 1); - await governorBravoDelegate.connect(customer).castVote(newProposalId, 1); - await advanceBlocks(16); - await governorBravoDelegate.queue(newProposalId); - expect(await governorBravoDelegate.state(newProposalId)).to.equal(ProposalState.Queued); - }); - - it("Executed", async () => { - xvsVault.getPriorVotes.returns(convertToUnit("300000", 18)); - timelock.delay.returns(100); - await governorBravoDelegate - .connect(customer) - .propose(targets, values, signatures, calldatas, "do nothing", ProposalType.CRITICAL); - const newProposalId = await governorBravoDelegate.proposalCount(); - await mineBlock(); - await governorBravoDelegate.castVote(newProposalId, 1); - await governorBravoDelegate.connect(customer).castVote(newProposalId, 1); - await advanceBlocks(16); - await governorBravoDelegate.queue(newProposalId); - - const proposal = await governorBravoDelegate.proposals(newProposalId); - - expect(await governorBravoDelegate.state(newProposalId)).to.equal(ProposalState.Queued); - await governorBravoDelegate.connect(customer).execute(newProposalId); - expect(await governorBravoDelegate.state(newProposalId)).to.equal(ProposalState.Executed); - // still executed even though would be expired - await minewWithTimestamp(proposal.eta.toNumber() + 10); - - expect(await governorBravoDelegate.state(newProposalId)).to.equal(ProposalState.Executed); - }); -}); - -async function mineBlock() { - await mine(); -} - -// NOTE: very dirty solution -//for bigger block to advance it will throw timeout -async function advanceBlocks(blocks: number) { - await mine(blocks); -} - -/** - * Sets the timestamp for the new block and mines it - * @param timestamp Number of seconds to increase time by - */ -async function minewWithTimestamp(timestamp: number) { - // First we increase the time - // Time travelling to the future! - await network.provider.send("evm_setNextBlockTimestamp", [timestamp]); - await mine(); -} diff --git a/tests/hardhat/Governance/XVSVaultGovernanceTest.ts b/tests/hardhat/Governance/XVSVaultGovernanceTest.ts deleted file mode 100644 index 57010645d..000000000 --- a/tests/hardhat/Governance/XVSVaultGovernanceTest.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { FakeContract, MockContract, smock } from "@defi-wonderland/smock"; -import { loadFixture } from "@nomicfoundation/hardhat-network-helpers"; -import chai from "chai"; -import { Signer } from "ethers"; -import { ethers, network } from "hardhat"; - -import { IAccessControlManagerV5, XVS, XVSStore, XVSVault, XVSVault__factory } from "../../../typechain"; - -const { expect } = chai; -chai.use(smock.matchers); - -let root: Signer; -let xvsVault: MockContract; - -const typedData = (delegatee: string, nonce: number, expiry: number, vaultAddress: string) => ({ - types: { - Delegation: [ - { name: "delegatee", type: "address" }, - { name: "nonce", type: "uint256" }, - { name: "expiry", type: "uint256" }, - ], - }, - primaryType: "Delegation", - domain: { - name: "XVS Vault", - chainId: 1, // await web3.eth.net.getId(); See: https://github.com/trufflesuite/ganache-core/issues/515 - verifyingContract: vaultAddress, - }, - message: { delegatee, nonce, expiry }, -}); - -type XVSVaultFixture = { - xvsVault: MockContract; - xvsStore: FakeContract; - xvsToken: FakeContract; -}; - -async function xvsVaultFixture(): Promise { - const XVSVault = await smock.mock("XVSVault"); - const xvsVault = await XVSVault.deploy(); - const xvsStore = await smock.fake("XVSStore"); - const xvsToken = await smock.fake("XVS"); - const accessControl = await smock.fake("IAccessControlManagerV5"); - accessControl.isAllowedToCall.returns(true); - await xvsVault.setAccessControl(accessControl.address); - return { xvsVault, xvsStore, xvsToken }; -} - -describe("XVS Vault Tests", () => { - let rootAddress: string; - - beforeEach(async () => { - [root] = await ethers.getSigners(); - rootAddress = await root.getAddress(); - const contracts = await loadFixture(xvsVaultFixture); - ({ xvsVault } = contracts); - }); - - describe("delegateBySig", () => { - it("reverts if the market is paused", async () => { - await xvsVault.pause(); - - const signatureLike = await network.provider.send("eth_signTypedData_v4", [ - rootAddress, - typedData(rootAddress, 0, 0, xvsVault.address), - ]); - const signature = ethers.utils.splitSignature(signatureLike); - - await expect( - xvsVault.delegateBySig( - rootAddress, - 0, - 0, - signature.v, - ethers.utils.formatBytes32String("r"), - ethers.utils.formatBytes32String("s"), - ), - ).to.be.revertedWith("Vault is paused"); - }); - - it("reverts if the signatory is invalid", async () => { - const signatureLike = await network.provider.send("eth_signTypedData_v4", [ - rootAddress, - typedData(rootAddress, 0, 0, xvsVault.address), - ]); - const signature = ethers.utils.splitSignature(signatureLike); - - await expect( - xvsVault.delegateBySig( - rootAddress, - 0, - 0, - signature.v, - ethers.utils.formatBytes32String("r"), - ethers.utils.formatBytes32String("s"), - ), - ).to.be.revertedWith("ECDSA: invalid signature"); - }); - it("reverts if the nonce is bad ", async () => { - const signatureLike = await network.provider.send("eth_signTypedData_v4", [ - rootAddress, - typedData(rootAddress, 1, 1, xvsVault.address), - ]); - const signature = ethers.utils.splitSignature(signatureLike); - - await expect(xvsVault.delegateBySig(rootAddress, 1, 0, signature.v, signature.r, signature.s)).to.be.revertedWith( - "XVSVault::delegateBySig: invalid nonce", - ); - }); - it("reverts if the signature has expired", async () => { - const signatureLike = await network.provider.send("eth_signTypedData_v4", [ - rootAddress, - typedData(rootAddress, 1, 1, xvsVault.address), - ]); - const signature = ethers.utils.splitSignature(signatureLike); - - await expect(xvsVault.delegateBySig(rootAddress, 0, 0, signature.v, signature.r, signature.s)).to.be.revertedWith( - "XVSVault::delegateBySig: signature expired", - ); - }); - // NOTE: Couldn't mock any mapping with address as a key using smock - // TODO: investigate why we couldn't mock this - // it("delegates on behalf of the signatory", async () => { - // const xvsAddress = xvsToken.address; - - // await xvsVault.setVariable("xvsAddress", xvsToken.address); - // await xvsVault.setVariable("xvsStore", xvsStore.address); - // await xvsVault.add(xvsAddress,100,xvsAddress,10,100); - - // await xvsVault.deposit(xvsAddress,0,100); - - // await xvsVault.setVariable('userInfos',[{ - // xvsAddress: { - // 0: { - // rootAddress: { - // amount: 100, - // rewardDebt: 10, - // pendingWithdrawals: 10 - // } - // } - // } - // } - // ]); - // const customerAddress = await customer.getAddress(); - // const signatureLike = await network.provider.send( - // "eth_signTypedData_v4", - // [rootAddress, typedData(customerAddress, 1, 10e9, xvsVault.address)] - // ); - // const signature = ethers.utils.splitSignature(signatureLike); - - // expect(await xvsVault.delegates(customerAddress)).to.equal( - // ethers.constants.AddressZero - // ); - // //TODO: add gas used when smock has this feature - // // expect(tx.gasUsed < 80000); - - // await xvsVault.delegateBySig( - // customerAddress, - // 0, - // 10e9, - // signature.v, - // signature.r, - // signature.s - // ); - // expect(await xvsVault.delegates(customerAddress)).to.equal( - // customerAddress - // ); - // // expect(await call(xvsVault, "delegates", [a1])).toEqual(root); - // }); - }); -});