Skip to content

Commit

Permalink
add testing of new governor against legacy voting tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
Amxx committed Jan 12, 2023
1 parent 0981e95 commit f0ccbfb
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 83 deletions.
2 changes: 1 addition & 1 deletion contracts/mocks/token/VotesTimestamp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ abstract contract ERC721VotesTimestampMock is ERC721Votes {
function clock() public view override returns (uint256) {
return block.timestamp;
}
}
}
20 changes: 12 additions & 8 deletions test/governance/Governor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ const CallReceiver = artifacts.require('CallReceiverMock');
const ERC721 = artifacts.require('$ERC721');
const ERC1155 = artifacts.require('$ERC1155');

const TOKENS = {
blockNumber: artifacts.require('$ERC20Votes'),
timestamp: artifacts.require('$ERC20VotesTimestampMock'),
};
const TOKENS = [
{ Token: artifacts.require('$ERC20Votes'), mode: 'blockNumber' },
{ Token: artifacts.require('$ERC20VotesTimestampMock'), mode: 'timestamp' },
{ Token: artifacts.require('$ERC20VotesLegacyMock'), mode: 'blockNumber' },
];

contract('Governor', function (accounts) {
const [owner, proposer, voter1, voter2, voter3, voter4] = accounts;
Expand All @@ -32,8 +33,8 @@ contract('Governor', function (accounts) {
const votingPeriod = web3.utils.toBN(16);
const value = web3.utils.toWei('1');

for (const [mode, Token] of Object.entries(TOKENS)) {
describe(`using ${mode} voting token`, function () {
for (const { mode, Token } of TOKENS) {
describe(`using ${Token._json.contractName}`, function () {
beforeEach(async function () {
this.chainId = await web3.eth.getChainId();
this.token = await Token.new(tokenName, tokenSymbol, tokenName);
Expand Down Expand Up @@ -81,7 +82,7 @@ contract('Governor', function (accounts) {
});

it('clock is correct', async function () {
expect(await this.token.clock()).to.be.bignumber.equal(await clock[mode]().then(web3.utils.toBN));
expect(await this.mock.clock()).to.be.bignumber.equal(await clock[mode]().then(web3.utils.toBN));
});

it('nominal workflow', async function () {
Expand All @@ -103,7 +104,10 @@ contract('Governor', function (accounts) {
signatures: this.proposal.signatures,
calldatas: this.proposal.data,
startBlock: web3.utils.toBN(await clockFromReceipt[mode](txPropose.receipt)).add(votingDelay),
endBlock: web3.utils.toBN(await clockFromReceipt[mode](txPropose.receipt)).add(votingDelay).add(votingPeriod),
endBlock: web3.utils
.toBN(await clockFromReceipt[mode](txPropose.receipt))
.add(votingDelay)
.add(votingPeriod),
description: this.proposal.description,
});

Expand Down
34 changes: 23 additions & 11 deletions test/governance/compatibility/GovernorCompatibilityBravo.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ function makeContractAddress(creator, nonce) {
);
}

const TOKENS = {
blockNumber: artifacts.require('$ERC20VotesComp'),
timestamp: artifacts.require('$ERC20VotesCompTimestampMock'),
};
const TOKENS = [
{ Token: artifacts.require('$ERC20VotesComp'), mode: 'blockNumber' },
{ Token: artifacts.require('$ERC20VotesCompTimestampMock'), mode: 'timestamp' },
];

contract('GovernorCompatibilityBravo', function (accounts) {
const [owner, proposer, voter1, voter2, voter3, voter4, other] = accounts;
Expand All @@ -36,8 +36,8 @@ contract('GovernorCompatibilityBravo', function (accounts) {
const proposalThreshold = web3.utils.toWei('10');
const value = web3.utils.toWei('1');

for (const [mode, Token] of Object.entries(TOKENS)) {
describe(`using ${mode} voting token`, function () {
for (const { mode, Token } of TOKENS) {
describe(`using ${Token._json.contractName}`, function () {
beforeEach(async function () {
const [deployer] = await web3.eth.getAccounts();

Expand Down Expand Up @@ -164,7 +164,10 @@ contract('GovernorCompatibilityBravo', function (accounts) {
signatures: this.proposal.signatures.map(() => ''), // this event doesn't contain the proposal detail
calldatas: this.proposal.fulldata,
startBlock: web3.utils.toBN(await clockFromReceipt[mode](txPropose.receipt)).add(votingDelay),
endBlock: web3.utils.toBN(await clockFromReceipt[mode](txPropose.receipt)).add(votingDelay).add(votingPeriod),
endBlock: web3.utils
.toBN(await clockFromReceipt[mode](txPropose.receipt))
.add(votingDelay)
.add(votingPeriod),
description: this.proposal.description,
});
expectEvent(txExecute, 'ProposalExecuted', { proposalId: this.proposal.id });
Expand Down Expand Up @@ -207,14 +210,23 @@ contract('GovernorCompatibilityBravo', function (accounts) {

await expectEvent.inTransaction(txExecute.tx, this.receiver, 'MockFunctionCalled');
await expectEvent.inTransaction(txExecute.tx, this.receiver, 'MockFunctionCalled');
await expectEvent.inTransaction(txExecute.tx, this.receiver, 'MockFunctionCalledWithArgs', { a: '17', b: '42' });
await expectEvent.inTransaction(txExecute.tx, this.receiver, 'MockFunctionCalledWithArgs', { a: '18', b: '43' });
await expectEvent.inTransaction(txExecute.tx, this.receiver, 'MockFunctionCalledWithArgs', {
a: '17',
b: '42',
});
await expectEvent.inTransaction(txExecute.tx, this.receiver, 'MockFunctionCalledWithArgs', {
a: '18',
b: '43',
});
});

describe('should revert', function () {
describe('on propose', function () {
it('if proposal does not meet proposalThreshold', async function () {
await expectRevert(this.helper.propose({ from: other }), 'Governor: proposer votes below proposal threshold');
await expectRevert(
this.helper.propose({ from: other }),
'Governor: proposer votes below proposal threshold',
);
});
});

Expand Down Expand Up @@ -249,4 +261,4 @@ contract('GovernorCompatibilityBravo', function (accounts) {
});
});
}
});
});
14 changes: 7 additions & 7 deletions test/governance/extensions/GovernorComp.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ const { GovernorHelper } = require('../../helpers/governance');
const Governor = artifacts.require('$GovernorCompMock');
const CallReceiver = artifacts.require('CallReceiverMock');

const TOKENS = {
blockNumber: artifacts.require('$ERC20VotesComp'),
timestamp: artifacts.require('$ERC20VotesCompTimestampMock'),
};
const TOKENS = [
{ Token: artifacts.require('$ERC20VotesComp'), mode: 'blockNumber' },
{ Token: artifacts.require('$ERC20VotesCompTimestampMock'), mode: 'timestamp' },
];

contract('GovernorComp', function (accounts) {
const [owner, voter1, voter2, voter3, voter4] = accounts;
Expand All @@ -22,8 +22,8 @@ contract('GovernorComp', function (accounts) {
const votingPeriod = web3.utils.toBN(16);
const value = web3.utils.toWei('1');

for (const [mode, Token] of Object.entries(TOKENS)) {
describe(`using ${mode} voting token`, function () {
for (const { mode, Token } of TOKENS) {
describe(`using ${Token._json.contractName}`, function () {
beforeEach(async function () {
this.owner = owner;
this.token = await Token.new(tokenName, tokenSymbol, tokenName);
Expand Down Expand Up @@ -85,4 +85,4 @@ contract('GovernorComp', function (accounts) {
});
});
}
});
});
14 changes: 7 additions & 7 deletions test/governance/extensions/GovernorERC721.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ const { GovernorHelper } = require('../../helpers/governance');
const Governor = artifacts.require('$GovernorVoteMocks');
const CallReceiver = artifacts.require('CallReceiverMock');

const TOKENS = {
blockNumber: artifacts.require('$ERC721Votes'),
timestamp: artifacts.require('$ERC721VotesTimestampMock'),
};
const TOKENS = [
{ Token: artifacts.require('$ERC721Votes'), mode: 'blockNumber' },
{ Token: artifacts.require('$ERC721VotesTimestampMock'), mode: 'timestamp' },
];

contract('GovernorERC721', function (accounts) {
const [owner, voter1, voter2, voter3, voter4] = accounts;
Expand All @@ -27,8 +27,8 @@ contract('GovernorERC721', function (accounts) {
const votingPeriod = web3.utils.toBN(16);
const value = web3.utils.toWei('1');

for (const [mode, Token] of Object.entries(TOKENS)) {
describe(`using ${mode} voting token`, function () {
for (const { mode, Token } of TOKENS) {
describe(`using ${Token._json.contractName}`, function () {
beforeEach(async function () {
this.owner = owner;
this.token = await Token.new(tokenName, tokenSymbol, tokenName, '1');
Expand Down Expand Up @@ -112,4 +112,4 @@ contract('GovernorERC721', function (accounts) {
});
});
}
});
});
28 changes: 18 additions & 10 deletions test/governance/extensions/GovernorPreventLateQuorum.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { BN, expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
const { expectEvent, expectRevert } = require('@openzeppelin/test-helpers');
const { expect } = require('chai');
const Enums = require('../../helpers/enums');
const { GovernorHelper } = require('../../helpers/governance');
Expand All @@ -7,10 +7,10 @@ const { clockFromReceipt } = require('../../helpers/time');
const Governor = artifacts.require('$GovernorPreventLateQuorumMock');
const CallReceiver = artifacts.require('CallReceiverMock');

const TOKENS = {
blockNumber: artifacts.require('$ERC20Votes'),
timestamp: artifacts.require('$ERC20VotesTimestampMock'),
};
const TOKENS = [
{ Token: artifacts.require('$ERC20Votes'), mode: 'blockNumber' },
{ Token: artifacts.require('$ERC20VotesTimestampMock'), mode: 'timestamp' },
];

contract('GovernorPreventLateQuorum', function (accounts) {
const [owner, proposer, voter1, voter2, voter3, voter4] = accounts;
Expand All @@ -26,8 +26,8 @@ contract('GovernorPreventLateQuorum', function (accounts) {
const quorum = web3.utils.toWei('1');
const value = web3.utils.toWei('1');

for (const [mode, Token] of Object.entries(TOKENS)) {
describe(`using ${mode} voting token`, function () {
for (const { mode, Token } of TOKENS) {
describe(`using ${Token._json.contractName}`, function () {
beforeEach(async function () {
this.owner = owner;
this.token = await Token.new(tokenName, tokenSymbol, tokenName);
Expand Down Expand Up @@ -97,7 +97,10 @@ contract('GovernorPreventLateQuorum', function (accounts) {
});

const startBlock = web3.utils.toBN(await clockFromReceipt[mode](txPropose.receipt)).add(votingDelay);
const endBlock = web3.utils.toBN(await clockFromReceipt[mode](txPropose.receipt)).add(votingDelay).add(votingPeriod);
const endBlock = web3.utils
.toBN(await clockFromReceipt[mode](txPropose.receipt))
.add(votingDelay)
.add(votingPeriod);
expect(await this.mock.proposalSnapshot(this.proposal.id)).to.be.bignumber.equal(startBlock);
expect(await this.mock.proposalDeadline(this.proposal.id)).to.be.bignumber.equal(endBlock);

Expand All @@ -119,7 +122,10 @@ contract('GovernorPreventLateQuorum', function (accounts) {

// compute original schedule
const startBlock = web3.utils.toBN(await clockFromReceipt[mode](txPropose.receipt)).add(votingDelay);
const endBlock = web3.utils.toBN(await clockFromReceipt[mode](txPropose.receipt)).add(votingDelay).add(votingPeriod);
const endBlock = web3.utils
.toBN(await clockFromReceipt[mode](txPropose.receipt))
.add(votingDelay)
.add(votingPeriod);
expect(await this.mock.proposalSnapshot(this.proposal.id)).to.be.bignumber.equal(startBlock);
expect(await this.mock.proposalDeadline(this.proposal.id)).to.be.bignumber.equal(endBlock);

Expand All @@ -131,7 +137,9 @@ contract('GovernorPreventLateQuorum', function (accounts) {
expect(await this.mock.state(this.proposal.id)).to.be.bignumber.equal(Enums.ProposalState.Active);

// compute new extended schedule
const extendedDeadline = web3.utils.toBN(await clockFromReceipt[mode](txVote.receipt)).add(lateQuorumVoteExtension);
const extendedDeadline = web3.utils
.toBN(await clockFromReceipt[mode](txVote.receipt))
.add(lateQuorumVoteExtension);
expect(await this.mock.proposalSnapshot(this.proposal.id)).to.be.bignumber.equal(startBlock);
expect(await this.mock.proposalDeadline(this.proposal.id)).to.be.bignumber.equal(extendedDeadline);

Expand Down
29 changes: 20 additions & 9 deletions test/governance/extensions/GovernorTimelockCompound.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ function makeContractAddress(creator, nonce) {
);
}

const TOKENS = {
blockNumber: artifacts.require('$ERC20Votes'),
timestamp: artifacts.require('$ERC20VotesTimestampMock'),
};
const TOKENS = [
{ Token: artifacts.require('$ERC20Votes'), mode: 'blockNumber' },
{ Token: artifacts.require('$ERC20VotesTimestampMock'), mode: 'timestamp' },
];

contract('GovernorTimelockCompound', function (accounts) {
const [owner, voter1, voter2, voter3, voter4, other] = accounts;
Expand All @@ -36,8 +36,8 @@ contract('GovernorTimelockCompound', function (accounts) {
const votingPeriod = web3.utils.toBN(16);
const value = web3.utils.toWei('1');

for (const [mode, Token] of Object.entries(TOKENS)) {
describe(`using ${mode} voting token`, function () {
for (const { mode, Token } of TOKENS) {
describe(`using ${Token._json.contractName}`, function () {
beforeEach(async function () {
const [deployer] = await web3.eth.getAccounts();

Expand All @@ -48,7 +48,15 @@ contract('GovernorTimelockCompound', function (accounts) {
const predictGovernor = makeContractAddress(deployer, nonce + 1);

this.timelock = await Timelock.new(predictGovernor, 2 * 86400);
this.mock = await Governor.new(name, votingDelay, votingPeriod, 0, this.timelock.address, this.token.address, 0);
this.mock = await Governor.new(
name,
votingDelay,
votingPeriod,
0,
this.timelock.address,
this.token.address,
0,
);
this.receiver = await CallReceiver.new();

this.helper = new GovernorHelper(this.mock, mode);
Expand Down Expand Up @@ -134,7 +142,10 @@ contract('GovernorTimelockCompound', function (accounts) {
await this.helper.waitForSnapshot();
await this.helper.vote({ support: Enums.VoteType.For }, { from: voter1 });
await this.helper.waitForDeadline();
await expectRevert(this.helper.queue(), 'GovernorTimelockCompound: identical proposal action already queued');
await expectRevert(
this.helper.queue(),
'GovernorTimelockCompound: identical proposal action already queued',
);
await expectRevert(this.helper.execute(), 'GovernorTimelockCompound: proposal not yet queued');
});
});
Expand Down Expand Up @@ -338,4 +349,4 @@ contract('GovernorTimelockCompound', function (accounts) {
});
});
}
});
});
31 changes: 22 additions & 9 deletions test/governance/extensions/GovernorTimelockControl.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ const Timelock = artifacts.require('TimelockController');
const Governor = artifacts.require('$GovernorTimelockControlMock');
const CallReceiver = artifacts.require('CallReceiverMock');

const TOKENS = {
blockNumber: artifacts.require('$ERC20Votes'),
timestamp: artifacts.require('$ERC20VotesTimestampMock'),
};
const TOKENS = [
{ Token: artifacts.require('$ERC20Votes'), mode: 'blockNumber' },
{ Token: artifacts.require('$ERC20VotesTimestampMock'), mode: 'timestamp' },
];

contract('GovernorTimelockControl', function (accounts) {
const [owner, voter1, voter2, voter3, voter4, other] = accounts;
Expand All @@ -31,14 +31,22 @@ contract('GovernorTimelockControl', function (accounts) {
const votingPeriod = web3.utils.toBN(16);
const value = web3.utils.toWei('1');

for (const [mode, Token] of Object.entries(TOKENS)) {
describe(`using ${mode} voting token`, function () {
for (const { mode, Token } of TOKENS) {
describe(`using ${Token._json.contractName}`, function () {
beforeEach(async function () {
const [deployer] = await web3.eth.getAccounts();

this.token = await Token.new(tokenName, tokenSymbol, tokenName);
this.timelock = await Timelock.new(3600, [], [], deployer);
this.mock = await Governor.new(name, votingDelay, votingPeriod, 0, this.timelock.address, this.token.address, 0);
this.mock = await Governor.new(
name,
votingDelay,
votingPeriod,
0,
this.timelock.address,
this.token.address,
0,
);
this.receiver = await CallReceiver.new();

this.helper = new GovernorHelper(this.mock, mode);
Expand Down Expand Up @@ -335,7 +343,12 @@ contract('GovernorTimelockControl', function (accounts) {

describe('updateTimelock', function () {
beforeEach(async function () {
this.newTimelock = await Timelock.new(3600, [this.mock.address], [this.mock.address], constants.ZERO_ADDRESS);
this.newTimelock = await Timelock.new(
3600,
[this.mock.address],
[this.mock.address],
constants.ZERO_ADDRESS,
);
});

it('is protected', async function () {
Expand Down Expand Up @@ -396,4 +409,4 @@ contract('GovernorTimelockControl', function (accounts) {
});
});
}
});
});

0 comments on commit f0ccbfb

Please sign in to comment.