UNPKG

@vechain/vebetterdao-contracts

Version:

Open-source repository that houses the smart contracts powering the decentralized VeBetterDAO on the VeChain Thor blockchain.

379 lines (378 loc) 28.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const chai_1 = require("chai"); const hardhat_1 = require("hardhat"); const mocha_1 = require("mocha"); const common_1 = require("../helpers/common"); const fixture_test_1 = require("./fixture.test"); (0, mocha_1.describe)("Governance - V8 Compatibility - @shard4h", function () { let governor; let vot3; let b3tr; let b3trContract; let minterAccount; let proposer; let owner; let emissions; let otherAccounts; let veBetterPassport; let xAllocationVoting; beforeEach(async function () { const fixture = await (0, fixture_test_1.setupGovernanceFixtureWithEmissions)(); governor = fixture.governor; vot3 = fixture.vot3; b3tr = fixture.b3tr; b3trContract = fixture.b3trContract; minterAccount = fixture.minterAccount; proposer = fixture.proposer; owner = fixture.owner; otherAccounts = fixture.otherAccounts; emissions = fixture.emissions; veBetterPassport = fixture.veBetterPassport; xAllocationVoting = fixture.xAllocationVoting; // Setup proposer for all tests await emissions.connect(minterAccount).start(); await (0, fixture_test_1.setupProposer)(proposer, b3tr, vot3, minterAccount); // Setup voters for all tests await (0, fixture_test_1.setupVoter)(otherAccounts[0], b3tr, vot3, minterAccount, owner, veBetterPassport); await (0, fixture_test_1.setupVoter)(otherAccounts[1], b3tr, vot3, minterAccount, owner, veBetterPassport); await (0, fixture_test_1.setupVoter)(otherAccounts[2], b3tr, vot3, minterAccount, owner, veBetterPassport); await (0, fixture_test_1.setupVoter)(otherAccounts[3], b3tr, vot3, minterAccount, owner, veBetterPassport); }); (0, mocha_1.describe)("Governance - V8 Compatibility - Cancellability", function () { (0, mocha_1.it)("Proposals in PENDING state should be cancellable in V8", async () => { const functionToCall = "tokenDetails"; const encodedFunctionCall = b3trContract.interface.encodeFunctionData(functionToCall, []); // Create a proposal using the old method (propose) const tx = await (0, common_1.createProposal)(b3tr, b3trContract, proposer, `description ${this.title}`, functionToCall, []); const proposalId = await (0, common_1.getProposalIdFromTx)(tx); const stateBeforeCancel = await governor.state(proposalId); (0, chai_1.expect)(stateBeforeCancel).to.equal(0); // pending await governor .connect(proposer) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Changed my mind about this proposal"); const stateAfterCancel = await governor.state(proposalId); (0, chai_1.expect)(stateAfterCancel).to.equal(2); // cancelled }); (0, mocha_1.it)("Cancel should emit ProposalCanceledWithReason event", async () => { const functionToCall = "tokenDetails"; const encodedFunctionCall = b3trContract.interface.encodeFunctionData(functionToCall, []); const description = `description cancel reason test ${Date.now()}`; const cancelReason = "Testing cancel reason feature"; const tx = await (0, common_1.createProposal)(b3tr, b3trContract, proposer, description, functionToCall, []); const proposalId = await (0, common_1.getProposalIdFromTx)(tx); const cancelTx = await governor .connect(proposer) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(description)), cancelReason); const receipt = await cancelTx.wait(); const cancelEvent = receipt?.logs.find(log => { try { const parsed = governor.interface.parseLog({ topics: [...log.topics], data: log.data }); return parsed?.name === "ProposalCanceledWithReason"; } catch { return false; } }); (0, chai_1.expect)(cancelEvent).to.not.be.undefined; const parsedEvent = governor.interface.parseLog({ topics: [...cancelEvent.topics], data: cancelEvent.data, }); (0, chai_1.expect)(parsedEvent?.args.proposalId).to.equal(proposalId); (0, chai_1.expect)(parsedEvent?.args.canceler).to.equal(proposer.address); (0, chai_1.expect)(parsedEvent?.args.reason).to.equal(cancelReason); }); (0, mocha_1.it)("Proposals in ACTIVE state should be cancellable only by admin in V8", async () => { const functionToCall = "tokenDetails"; const encodedFunctionCall = b3trContract.interface.encodeFunctionData(functionToCall, []); // Create a proposal using the old method (propose) const tx = await (0, common_1.createProposal)(b3tr, b3trContract, otherAccounts[2], `description ${this.title}`, functionToCall, []); const proposalId = await (0, common_1.getProposalIdFromTx)(tx); const proposalThreshold = await governor.proposalDepositThreshold(proposalId); await (0, fixture_test_1.setupSupporter)(otherAccounts[3], vot3, proposalThreshold, governor); await governor.connect(otherAccounts[3]).deposit(proposalThreshold, proposalId, { gasLimit: 10000000 }); await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); const stateBeforeCancel = await governor.state(proposalId); (0, chai_1.expect)(stateBeforeCancel).to.equal(1); // active await (0, chai_1.expect)(governor .connect(otherAccounts[2]) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "No longer needed")).to.be.reverted; const stateAfterCancel = await governor.state(proposalId); (0, chai_1.expect)(stateAfterCancel).to.equal(stateBeforeCancel); // cancelled //Now we should be able to cancel the proposal with the admin await governor .connect(owner) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Proposal contains errors that need fixing"); const stateAfterCancelAdmin = await governor.state(proposalId); (0, chai_1.expect)(stateAfterCancelAdmin).to.equal(2); // cancelled }); (0, mocha_1.it)("Proposals in SUCCEEDED state should be cancellable only by admin in V8", async () => { const functionToCall = "tokenDetails"; const encodedFunctionCall = b3trContract.interface.encodeFunctionData(functionToCall, []); // Create a proposal using the old method (propose) const tx = await (0, common_1.createProposal)(b3tr, b3trContract, otherAccounts[2], `description ${this.title}`, functionToCall, []); const proposalId = await (0, common_1.getProposalIdFromTx)(tx); const proposalThreshold = await governor.proposalDepositThreshold(proposalId); await (0, fixture_test_1.setupSupporter)(otherAccounts[3], vot3, proposalThreshold, governor); await governor.connect(otherAccounts[3]).deposit(proposalThreshold, proposalId, { gasLimit: 10000000 }); await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); //Vote for the proposal await governor.connect(otherAccounts[0]).castVote(proposalId, 1); await governor.connect(otherAccounts[1]).castVote(proposalId, 1); await governor.connect(otherAccounts[2]).castVote(proposalId, 1); //Start queue/execution round await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); const stateBeforeCancel = await governor.state(proposalId); (0, chai_1.expect)(stateBeforeCancel).to.equal(4); // succeeded await (0, chai_1.expect)(governor .connect(otherAccounts[2]) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "No longer needed")).to.be.reverted; const stateAfterCancel = await governor.state(proposalId); (0, chai_1.expect)(stateAfterCancel).to.equal(stateBeforeCancel); // succeeded //Now we should be able to cancel the proposal with the admin await governor .connect(owner) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Community raised security concerns"); const stateAfterCancelAdmin = await governor.state(proposalId); (0, chai_1.expect)(stateAfterCancelAdmin).to.equal(2); // cancelled }); (0, mocha_1.it)("Proposals in QUEUED state should be cancellable only by admin in V8", async () => { const functionToCall = "tokenDetails"; const encodedFunctionCall = b3trContract.interface.encodeFunctionData(functionToCall, []); // Create a proposal using the old method (propose) const tx = await (0, common_1.createProposal)(b3tr, b3trContract, proposer, `description ${this.title}`, functionToCall, []); const proposalId = await (0, common_1.getProposalIdFromTx)(tx); const proposalThreshold = await governor.proposalDepositThreshold(proposalId); await (0, fixture_test_1.setupSupporter)(otherAccounts[3], vot3, proposalThreshold, governor); await governor.connect(otherAccounts[3]).deposit(proposalThreshold, proposalId, { gasLimit: 10000000 }); //Start voting round await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); //Vote for the proposal await governor.connect(otherAccounts[0]).castVote(proposalId, 1); await governor.connect(otherAccounts[1]).castVote(proposalId, 1); await governor.connect(otherAccounts[2]).castVote(proposalId, 1); //Start queue/execution round await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); //Queue the proposal await governor.queue([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`))); //Proposal should be in queued state const stateBeforeCancel = await governor.state(proposalId); (0, chai_1.expect)(stateBeforeCancel).to.equal(5); // queued //Proposer should NOT be able to cancel the proposal in queued state await (0, chai_1.expect)(governor .connect(proposer) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Found issue before execution")).to.be.reverted; //Now we should be able to cancel the proposal with the admin await governor .connect(owner) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Critical bug discovered in implementation"); const stateAfterCancelAdmin = await governor.state(proposalId); (0, chai_1.expect)(stateAfterCancelAdmin).to.equal(2); // cancelled }); (0, mocha_1.it)("Proposals in EXECUTED state should NOT be cancellable in V8", async () => { const functionToCall = "tokenDetails"; const encodedFunctionCall = b3trContract.interface.encodeFunctionData(functionToCall, []); // Create a proposal using the old method (propose) const tx = await (0, common_1.createProposal)(b3tr, b3trContract, proposer, `description ${this.title}`, functionToCall, []); const proposalId = await (0, common_1.getProposalIdFromTx)(tx); const proposalThreshold = await governor.proposalDepositThreshold(proposalId); await (0, fixture_test_1.setupSupporter)(otherAccounts[3], vot3, proposalThreshold, governor); await governor.connect(otherAccounts[3]).deposit(proposalThreshold, proposalId, { gasLimit: 10000000 }); //Start voting round await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); //Vote for the proposal await governor.connect(otherAccounts[0]).castVote(proposalId, 1); await governor.connect(otherAccounts[1]).castVote(proposalId, 1); await governor.connect(otherAccounts[2]).castVote(proposalId, 1); //Start queue/execution round await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); //Queue the proposal await governor.queue([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`))); //Execute the proposal await governor.execute([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`))); //Proposal should be in executed state const stateBeforeCancel = await governor.state(proposalId); (0, chai_1.expect)(stateBeforeCancel).to.equal(6); // executed //Proposer should NOT be able to cancel the proposal in executed state await (0, chai_1.expect)(governor .connect(proposer) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Want to undo this")).to.be.reverted; //Admin also should NOT be able to cancel the proposal in executed state await (0, chai_1.expect)(governor .connect(owner) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Need to reverse this decision")).to.be.reverted; //State should remain in executed state const stateAfterCancel = await governor.state(proposalId); (0, chai_1.expect)(stateAfterCancel).to.equal(stateBeforeCancel); // executed }); (0, mocha_1.it)("Proposals in IN DEVELOPMENT state should NOT be cancellable in V8", async () => { const functionToCall = "tokenDetails"; const encodedFunctionCall = b3trContract.interface.encodeFunctionData(functionToCall, []); // Create a proposal using the old method (propose) const tx = await (0, common_1.createProposal)(b3tr, b3trContract, proposer, `description ${this.title}`, functionToCall, []); const proposalId = await (0, common_1.getProposalIdFromTx)(tx); const proposalThreshold = await governor.proposalDepositThreshold(proposalId); await (0, fixture_test_1.setupSupporter)(otherAccounts[3], vot3, proposalThreshold, governor); await governor.connect(otherAccounts[3]).deposit(proposalThreshold, proposalId, { gasLimit: 10000000 }); //Start voting round await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); //Vote for the proposal await governor.connect(otherAccounts[0]).castVote(proposalId, 1); await governor.connect(otherAccounts[1]).castVote(proposalId, 1); await governor.connect(otherAccounts[2]).castVote(proposalId, 1); //Start queue/execution round await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); //Queue the proposal await governor.queue([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`))); //Execute the proposal await governor.execute([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`))); //Mark the proposal as in development await governor.connect(owner).markAsInDevelopment(proposalId); //Proposal should be in in development state const stateBeforeCancel = await governor.state(proposalId); (0, chai_1.expect)(stateBeforeCancel).to.equal(8); // in development //Proposer should NOT be able to cancel the proposal in in development state await (0, chai_1.expect)(governor .connect(proposer) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Project direction changed")).to.be.reverted; //Admin also should NOT be able to cancel the proposal in in development state await (0, chai_1.expect)(governor .connect(owner) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Development blocked by external factors")).to.be.reverted; //State should remain in in development state const stateAfterCancel = await governor.state(proposalId); (0, chai_1.expect)(stateAfterCancel).to.equal(stateBeforeCancel); // in development }); (0, mocha_1.it)("Proposals in COMPLETED state should NOT be cancellable in V8", async () => { const functionToCall = "tokenDetails"; const encodedFunctionCall = b3trContract.interface.encodeFunctionData(functionToCall, []); // Create a proposal using the old method (propose) const tx = await (0, common_1.createProposal)(b3tr, b3trContract, proposer, `description ${this.title}`, functionToCall, []); const proposalId = await (0, common_1.getProposalIdFromTx)(tx); const proposalThreshold = await governor.proposalDepositThreshold(proposalId); await (0, fixture_test_1.setupSupporter)(otherAccounts[3], vot3, proposalThreshold, governor); await governor.connect(otherAccounts[3]).deposit(proposalThreshold, proposalId, { gasLimit: 10000000 }); //Start voting round await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); //Vote for the proposal await governor.connect(otherAccounts[0]).castVote(proposalId, 1); await governor.connect(otherAccounts[1]).castVote(proposalId, 1); await governor.connect(otherAccounts[2]).castVote(proposalId, 1); //Start queue/execution round await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); //Queue the proposal await governor.queue([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`))); //Execute the proposal await governor.execute([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`))); //Mark the proposal as in development await governor.connect(owner).markAsInDevelopment(proposalId); //Mark the proposal as completed await governor.connect(owner).markAsCompleted(proposalId); //Proposal should be in completed state const stateBeforeCancel = await governor.state(proposalId); (0, chai_1.expect)(stateBeforeCancel).to.equal(9); // completed //Proposer should NOT be able to cancel the proposal in completed state await (0, chai_1.expect)(governor .connect(proposer) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Want to revert completed work")).to.be.reverted; //Admin also should NOT be able to cancel the proposal in completed state await (0, chai_1.expect)(governor .connect(owner) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Completed proposal needs to be undone")).to.be.reverted; //State should remain in completed state const stateAfterCancel = await governor.state(proposalId); (0, chai_1.expect)(stateAfterCancel).to.equal(stateBeforeCancel); // completed }); (0, mocha_1.it)("Proposals in CANCELED state should NOT be cancellable in V8", async () => { const functionToCall = "tokenDetails"; const encodedFunctionCall = b3trContract.interface.encodeFunctionData(functionToCall, []); // Create a proposal using the old method (propose) const tx = await (0, common_1.createProposal)(b3tr, b3trContract, proposer, `description ${this.title}`, functionToCall, []); const proposalId = await (0, common_1.getProposalIdFromTx)(tx); const stateBeforeCancel = await governor.state(proposalId); (0, chai_1.expect)(stateBeforeCancel).to.equal(0); // pending await governor .connect(proposer) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Duplicate proposal submitted by mistake"); const stateAfterFirstCancel = await governor.state(proposalId); (0, chai_1.expect)(stateAfterFirstCancel).to.equal(2); // cancelled //Try to cancel again await (0, chai_1.expect)(governor .connect(proposer) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Trying to cancel again")).to.be.reverted; //State should remain in canceled state const stateAfterSecondCancel = await governor.state(proposalId); (0, chai_1.expect)(stateAfterSecondCancel).to.equal(stateAfterFirstCancel); // cancelled }); (0, mocha_1.it)("Proposals in DEFEATED state should NOT be cancellable in V8", async () => { const functionToCall = "tokenDetails"; const encodedFunctionCall = b3trContract.interface.encodeFunctionData(functionToCall, []); // Create a proposal using the old method (propose) const tx = await (0, common_1.createProposal)(b3tr, b3trContract, proposer, `description ${this.title}`, functionToCall, []); const proposalId = await (0, common_1.getProposalIdFromTx)(tx); const proposalThreshold = await governor.proposalDepositThreshold(proposalId); await (0, fixture_test_1.setupSupporter)(otherAccounts[3], vot3, proposalThreshold, governor); await governor.connect(otherAccounts[3]).deposit(proposalThreshold, proposalId, { gasLimit: 10000000 }); //Start voting round await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); //Vote for the proposal await governor.connect(otherAccounts[0]).castVote(proposalId, 1); await governor.connect(otherAccounts[1]).castVote(proposalId, 0); await governor.connect(otherAccounts[2]).castVote(proposalId, 0); //Start queue/execution round await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); //Proposal should be in defeated state const stateBeforeCancel = await governor.state(proposalId); (0, chai_1.expect)(stateBeforeCancel).to.equal(3); // defeated //Proposer should NOT be able to cancel the proposal in defeated state //Proposer should NOT be able to cancel the proposal in completed state await (0, chai_1.expect)(governor .connect(proposer) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Want to withdraw defeated proposal")).to.be.reverted; //Admin also should NOT be able to cancel the proposal in completed state await (0, chai_1.expect)(governor .connect(owner) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Cleanup of defeated proposal")).to.be.reverted; const stateAfterCancel = await governor.state(proposalId); (0, chai_1.expect)(stateAfterCancel).to.equal(stateBeforeCancel); // defeated }); (0, mocha_1.it)("Proposals in DEPOSIT NOT MET state should NOT be cancellable in V8", async () => { const functionToCall = "tokenDetails"; const encodedFunctionCall = b3trContract.interface.encodeFunctionData(functionToCall, []); // Create a proposal using the old method (propose) const tx = await (0, common_1.createProposal)(b3tr, b3trContract, proposer, `description ${this.title}`, functionToCall, []); const proposalId = await (0, common_1.getProposalIdFromTx)(tx); //Wait for the voting round to end and start a new round await (0, common_1.waitForCurrentRoundToEnd)({ emissions, xAllocationVoting }); await (0, fixture_test_1.startNewRoundAndGetRoundId)(emissions, xAllocationVoting); //Proposal should be in deposit not met state const stateBeforeCancel = await governor.state(proposalId); (0, chai_1.expect)(stateBeforeCancel).to.equal(7); // deposit not met //Proposer should NOT be able to cancel the proposal in deposit not met state await (0, chai_1.expect)(governor .connect(proposer) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Proposal failed to get enough support")).to.be.reverted; //Admin also should NOT be able to cancel the proposal in deposit not met state await (0, chai_1.expect)(governor .connect(owner) .cancel([await b3tr.getAddress()], [0], [encodedFunctionCall], hardhat_1.ethers.keccak256(hardhat_1.ethers.toUtf8Bytes(`description ${this.title}`)), "Cleaning up unsupported proposal")).to.be.reverted; //State should remain in deposit not met state const stateAfterCancel = await governor.state(proposalId); (0, chai_1.expect)(stateAfterCancel).to.equal(stateBeforeCancel); // deposit not met }); }); });