@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
JavaScript
;
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
});
});
});