-
Notifications
You must be signed in to change notification settings - Fork 11.7k
/
GovernorWithParams.test.js
146 lines (129 loc) · 5.95 KB
/
GovernorWithParams.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
const { BN, expectEvent, expectRevert, time } = require('@openzeppelin/test-helpers');
const { web3 } = require('@openzeppelin/test-helpers/src/setup');
const Enums = require('../../helpers/enums');
const { runGovernorWorkflow } = require('../GovernorWorkflow.behavior');
const Token = artifacts.require('ERC20VotesCompMock');
const Governor = artifacts.require('GovernorWithParamsMock');
const CallReceiver = artifacts.require('CallReceiverMock');
contract('GovernorWithParams', function (accounts) {
const [owner, proposer, voter1, voter2, voter3, voter4] = accounts;
const name = 'OZ-Governor';
const tokenName = 'MockToken';
const tokenSymbol = 'MTKN';
const tokenSupply = web3.utils.toWei('100');
const votingDelay = new BN(4);
const votingPeriod = new BN(16);
beforeEach(async function () {
this.owner = owner;
this.token = await Token.new(tokenName, tokenSymbol);
this.mock = await Governor.new(name, this.token.address);
this.receiver = await CallReceiver.new();
await this.token.mint(owner, tokenSupply);
await this.token.delegate(voter1, { from: voter1 });
await this.token.delegate(voter2, { from: voter2 });
await this.token.delegate(voter3, { from: voter3 });
await this.token.delegate(voter4, { from: voter4 });
});
it('deployment check', async function () {
expect(await this.mock.name()).to.be.equal(name);
expect(await this.mock.token()).to.be.equal(this.token.address);
expect(await this.mock.votingDelay()).to.be.bignumber.equal(votingDelay);
expect(await this.mock.votingPeriod()).to.be.bignumber.equal(votingPeriod);
});
describe('nominal is unaffected', function () {
beforeEach(async function () {
this.settings = {
proposal: [
[this.receiver.address],
[0],
[this.receiver.contract.methods.mockFunction().encodeABI()],
'<proposal description>',
],
proposer,
tokenHolder: owner,
voters: [
{ voter: voter1, weight: web3.utils.toWei('1'), support: Enums.VoteType.For, reason: 'This is nice' },
{ voter: voter2, weight: web3.utils.toWei('7'), support: Enums.VoteType.For },
{ voter: voter3, weight: web3.utils.toWei('5'), support: Enums.VoteType.Against },
{ voter: voter4, weight: web3.utils.toWei('2'), support: Enums.VoteType.Abstain },
],
};
});
afterEach(async function () {
expect(await this.mock.hasVoted(this.id, owner)).to.be.equal(false);
expect(await this.mock.hasVoted(this.id, voter1)).to.be.equal(true);
expect(await this.mock.hasVoted(this.id, voter2)).to.be.equal(true);
await this.mock.proposalVotes(this.id).then((result) => {
for (const [key, value] of Object.entries(Enums.VoteType)) {
expect(result[`${key.toLowerCase()}Votes`]).to.be.bignumber.equal(
Object.values(this.settings.voters)
.filter(({ support }) => support === value)
.reduce((acc, { weight }) => acc.add(new BN(weight)), new BN('0')),
);
}
});
const startBlock = new BN(this.receipts.propose.blockNumber).add(votingDelay);
const endBlock = new BN(this.receipts.propose.blockNumber).add(votingDelay).add(votingPeriod);
expect(await this.mock.proposalSnapshot(this.id)).to.be.bignumber.equal(startBlock);
expect(await this.mock.proposalDeadline(this.id)).to.be.bignumber.equal(endBlock);
expectEvent(this.receipts.propose, 'ProposalCreated', {
proposalId: this.id,
proposer,
targets: this.settings.proposal[0],
// values: this.settings.proposal[1].map(value => new BN(value)),
signatures: this.settings.proposal[2].map(() => ''),
calldatas: this.settings.proposal[2],
startBlock,
endBlock,
description: this.settings.proposal[3],
});
this.receipts.castVote.filter(Boolean).forEach((vote) => {
const { voter } = vote.logs.filter(({ event }) => event === 'VoteCast').find(Boolean).args;
expectEvent(
vote,
'VoteCast',
this.settings.voters.find(({ address }) => address === voter),
);
});
expectEvent(this.receipts.execute, 'ProposalExecuted', { proposalId: this.id });
await expectEvent.inTransaction(this.receipts.execute.transactionHash, this.receiver, 'MockFunctionCalled');
});
runGovernorWorkflow();
});
describe('Voting with params is properly supported', function () {
const voter2Weight = web3.utils.toWei('1.0');
beforeEach(async function () {
this.settings = {
proposal: [
[this.receiver.address],
[0],
[this.receiver.contract.methods.mockFunction().encodeABI()],
'<proposal description>',
],
proposer,
tokenHolder: owner,
voters: [
{ voter: voter1, weight: web3.utils.toWei('0.2'), support: Enums.VoteType.Against },
{ voter: voter2, weight: voter2Weight }, // do not actually vote, only getting tokens
{ voter: voter3, weight: web3.utils.toWei('0.9') }, // do not actually vote, only getting tokens
],
steps: {
wait: { enable: false },
execute: { enable: false },
},
};
});
afterEach(async function () {
expect(await this.mock.state(this.id)).to.be.bignumber.equal(Enums.ProposalState.Active);
const uintParam = new BN(1);
const strParam = 'These are my params';
const reducedWeight = (new BN(voter2Weight)).sub(uintParam);
const params = web3.eth.abi.encodeParameters(['uint256', 'string'], [uintParam, strParam]);
const tx = await this.mock.castVoteWithReasonAndParams(this.id, Enums.VoteType.For, '', params, { from: voter2 });
expectEvent(tx, 'CountParams', { uintParam, strParam });
expectEvent(tx, 'VoteCast', {voter: voter2, weight: reducedWeight});
// TODO: Cast vote with voter3 using params & signature; confirm events exist in tx receipt
});
runGovernorWorkflow();
});
});