Skip to content

Commit 590d800

Browse files
committed
test: add evidence contract tests
1 parent 47a1623 commit 590d800

File tree

3 files changed

+283
-5
lines changed

3 files changed

+283
-5
lines changed

CHANGELOG.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
## 0.1.0 (2021-12-13)
22

3+
- refactor: add arbitrator data index getter ([47a1623](https://github.com/kleros/kleros-v2/commit/47a1623))
4+
- refactor: add evidence contracts ([09a34f3](https://github.com/kleros/kleros-v2/commit/09a34f3))
5+
- refactor: add interfaces + capped math ([e25b21f](https://github.com/kleros/kleros-v2/commit/e25b21f))
6+
- refactor: remove foreign evidence interface ([ff8c50c](https://github.com/kleros/kleros-v2/commit/ff8c50c))
7+
- refactor(sdk): rename ([3241d10](https://github.com/kleros/kleros-v2/commit/3241d10))
38
- test: added a test for IncrementalNG ([65a996b](https://github.com/kleros/kleros-v2/commit/65a996b))
49
- test(EvidenceModule): add test file ([9f00f98](https://github.com/kleros/kleros-v2/commit/9f00f98))
510
- chore: added GitHub code scanning ([4a70475](https://github.com/kleros/kleros-v2/commit/4a70475))
@@ -14,10 +19,6 @@
1419
- fix(IArbitrator): change name to arbitration cost ([0ba4f29](https://github.com/kleros/kleros-v2/commit/0ba4f29))
1520
- fix(IArbitrator): interface simplification ([e81fb8b](https://github.com/kleros/kleros-v2/commit/e81fb8b))
1621
- fix(IArbitrator): replaced appealCost with fundingStatus ([f189dd9](https://github.com/kleros/kleros-v2/commit/f189dd9))
17-
- refactor: add evidence contracts ([09a34f3](https://github.com/kleros/kleros-v2/commit/09a34f3))
18-
- refactor: add interfaces + capped math ([e25b21f](https://github.com/kleros/kleros-v2/commit/e25b21f))
19-
- refactor: remove foreign evidence interface ([ff8c50c](https://github.com/kleros/kleros-v2/commit/ff8c50c))
20-
- refactor(sdk): rename ([3241d10](https://github.com/kleros/kleros-v2/commit/3241d10))
2122
- feat: modern toolchain setup and simple RNG smart contracts ([17f6a76](https://github.com/kleros/kleros-v2/commit/17f6a76))
2223
- feat(Arbitration): standard update ([ed930de](https://github.com/kleros/kleros-v2/commit/ed930de))
2324
- docs: initial commit ([23356e7](https://github.com/kleros/kleros-v2/commit/23356e7))

contracts/test/evidence/index.ts

Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
import { use, expect } from "chai";
2+
import { ethers } from "hardhat";
3+
import { BigNumber } from "ethers";
4+
import { solidity } from 'ethereum-waffle';
5+
const hre = require('hardhat')
6+
7+
use(solidity)
8+
9+
const Party = {
10+
None: 0,
11+
Submitter: 1,
12+
Moderator: 2
13+
}
14+
15+
function getEmittedEvent(eventName: any, receipt: any) {
16+
return receipt.events.find(({ event }) => event === eventName)
17+
}
18+
19+
describe('Home Evidence contract', async () => {
20+
const arbitrationFee = 1000
21+
const appealFee = arbitrationFee
22+
const arbitratorExtraData = '0x85'
23+
const appealTimeout = 100
24+
const bondTimeout = 60 * 10
25+
const totalCostMultiplier = 15000
26+
const initialDepositMultiplier = 625
27+
const metaEvidenceUri = 'https://kleros.io'
28+
const MULTIPLIER_DIVISOR = BigNumber.from(10000)
29+
const totalCost = BigNumber.from(arbitrationFee).mul(BigNumber.from(totalCostMultiplier)).div(MULTIPLIER_DIVISOR)
30+
const minRequiredDeposit = totalCost.mul(BigNumber.from(initialDepositMultiplier)).div(MULTIPLIER_DIVISOR)
31+
const ZERO = BigNumber.from(0)
32+
33+
let deployer
34+
let user1
35+
let user2
36+
let user3
37+
let user4
38+
let evidenceID
39+
40+
let arbitrator
41+
let evidenceModule
42+
43+
beforeEach('Setup contracts', async () => {
44+
;[
45+
deployer,
46+
user1,
47+
user2,
48+
user3,
49+
user4
50+
] = await ethers.getSigners()
51+
52+
const Arbitrator = await ethers.getContractFactory('CentralizedArbitrator')
53+
arbitrator = await Arbitrator.deploy(
54+
String(arbitrationFee),
55+
appealTimeout,
56+
String(appealFee)
57+
)
58+
59+
const EvidenceModule = await ethers.getContractFactory('EvidenceModule')
60+
evidenceModule = await EvidenceModule.deploy(
61+
arbitrator.address,
62+
deployer.address, // governor
63+
totalCostMultiplier,
64+
initialDepositMultiplier,
65+
bondTimeout,
66+
arbitratorExtraData,
67+
metaEvidenceUri
68+
)
69+
})
70+
71+
describe("Governance", function () {
72+
it("Should change parameters correctly", async function () {
73+
const newGovernor = await user2.getAddress()
74+
await evidenceModule.changeGovernor(newGovernor)
75+
expect(await evidenceModule.governor()).to.equal(newGovernor)
76+
await evidenceModule.connect(user2).changeGovernor(await deployer.getAddress())
77+
78+
await evidenceModule.changeInitialDepositMultiplier(1)
79+
expect(await evidenceModule.initialDepositMultiplier()).to.equal(1)
80+
81+
await evidenceModule.changeTotalCostMultiplier(1)
82+
expect(await evidenceModule.totalCostMultiplier()).to.equal(1)
83+
84+
await evidenceModule.changeBondTimeout(1)
85+
expect(await evidenceModule.bondTimeout()).to.equal(1)
86+
87+
const newMetaEvidenceUri = 'https://kleros.io/new'
88+
let tx = await evidenceModule.changeMetaEvidence(newMetaEvidenceUri)
89+
let receipt = await tx.wait()
90+
let lastArbitratorIndex = await evidenceModule.getCurrentArbitratorIndex()
91+
let newArbitratorData = await evidenceModule.arbitratorDataList(lastArbitratorIndex)
92+
let oldArbitratorData = await evidenceModule.arbitratorDataList(lastArbitratorIndex.sub(BigNumber.from(1)))
93+
94+
expect(
95+
newArbitratorData.metaEvidenceUpdates
96+
).to.equal(oldArbitratorData.metaEvidenceUpdates.add(BigNumber.from(1)))
97+
expect(
98+
newArbitratorData.arbitratorExtraData
99+
).to.equal(oldArbitratorData.arbitratorExtraData)
100+
const [newMetaEvidenceUpdates ,newMetaEvidence] = getEmittedEvent('MetaEvidence', receipt).args
101+
expect(newMetaEvidence).to.equal(newMetaEvidenceUri, 'Wrong MetaEvidence.')
102+
expect(newMetaEvidenceUpdates).to.equal(newArbitratorData.metaEvidenceUpdates, 'Wrong MetaEvidence ID.')
103+
104+
const newArbitratorExtraData = '0x86'
105+
await evidenceModule.changeArbitratorExtraData(newArbitratorExtraData)
106+
newArbitratorData = await evidenceModule.arbitratorDataList(lastArbitratorIndex.add(BigNumber.from(1)))
107+
expect(
108+
newArbitratorData.arbitratorExtraData
109+
).to.equal(newArbitratorExtraData, 'Wrong extraData')
110+
});
111+
112+
it("Should revert if the caller is not the governor", async function () {
113+
await expect(evidenceModule.
114+
connect(user2).changeGovernor(await user2.getAddress())
115+
).to.be.revertedWith('The caller must be the governor')
116+
117+
await expect(evidenceModule.
118+
connect(user2).changeInitialDepositMultiplier(0)
119+
).to.be.revertedWith('The caller must be the governor')
120+
121+
await expect(evidenceModule.
122+
connect(user2).changeTotalCostMultiplier(0)
123+
).to.be.revertedWith('The caller must be the governor')
124+
125+
await expect(evidenceModule.
126+
connect(user2).changeBondTimeout(0)
127+
).to.be.revertedWith('The caller must be the governor')
128+
129+
await expect(evidenceModule.
130+
connect(user2).changeMetaEvidence(metaEvidenceUri)
131+
).to.be.revertedWith('The caller must be the governor')
132+
133+
await expect(evidenceModule.
134+
connect(user2).changeArbitratorExtraData(arbitratorExtraData)
135+
).to.be.revertedWith('The caller must be the governor')
136+
});
137+
});
138+
139+
describe('Evidence Submission', () => {
140+
it('Should submit evidence correctly.', async () => {
141+
const newEvidence = 'Irrefutable evidence'
142+
const tx = await evidenceModule.connect(user1).submitEvidence(1234, newEvidence, {
143+
value: minRequiredDeposit
144+
}) // id: 0
145+
const receipt = await tx.wait()
146+
const evidenceID = ethers.utils.solidityKeccak256(["uint", "string"], [1234, newEvidence]);
147+
148+
const [
149+
arbitratorAddress,
150+
evidenceGroupID,
151+
submitter,
152+
evidenceStr
153+
] = getEmittedEvent('Evidence', receipt).args
154+
expect(arbitratorAddress).to.equal(arbitrator.address, 'Wrong arbitrator.')
155+
expect(evidenceGroupID).to.equal(1234, 'Wrong evidence group ID.')
156+
expect(submitter).to.equal(user1.address, 'Wrong submitter.')
157+
expect(evidenceStr).to.equal(newEvidence, 'Wrong evidence message.')
158+
159+
let contributions = await evidenceModule.getContributions(evidenceID, 0, user1.address)
160+
expect(contributions).to.deep.equal([ZERO,minRequiredDeposit,ZERO], 'Wrong contributions.')
161+
})
162+
163+
it('Should not allowed the same evidence twice for the same evidence group id.', async () => {
164+
const newEvidence = 'Irrefutable evidence'
165+
await evidenceModule.submitEvidence(1234, newEvidence, {
166+
value: minRequiredDeposit
167+
})
168+
await expect(evidenceModule.
169+
submitEvidence(1234, newEvidence, {
170+
value: minRequiredDeposit
171+
})).to.be.revertedWith('Evidence already submitted.')
172+
})
173+
174+
it('Should revert if deposit is too low.', async () => {
175+
const newEvidence = 'Irrefutable evidence'
176+
await expect(evidenceModule.
177+
submitEvidence(1234, newEvidence, {
178+
value: minRequiredDeposit.sub(BigNumber.from(1))
179+
})).to.be.revertedWith('Insufficient funding.')
180+
})
181+
})
182+
183+
describe('Moderation', () => {
184+
beforeEach('Initialize posts and comments', async () => {
185+
const newEvidence = 'Irrefutable evidence'
186+
await evidenceModule.connect(user1).submitEvidence(1234, newEvidence, {
187+
value: minRequiredDeposit
188+
})
189+
evidenceID = ethers.utils.solidityKeccak256(["uint", "string"], [1234, newEvidence]);
190+
})
191+
192+
it('Should not allow moderation after bond timeout passed.', async () => {
193+
await expect(evidenceModule.
194+
resolveModerationMarket(evidenceID)
195+
).to.be.revertedWith('Moderation still ongoing.')
196+
197+
await hre.ethers.provider.send('evm_increaseTime', [60 * 10]);
198+
199+
// Moderate
200+
await expect(evidenceModule.
201+
moderate(evidenceID, Party.Moderator, {
202+
value: totalCost
203+
})).to.be.revertedWith('Moderation market is closed.')
204+
205+
await evidenceModule.resolveModerationMarket(evidenceID)
206+
207+
// After market has been closed, moderation can re-open.
208+
await evidenceModule.moderate(evidenceID, Party.Submitter, {
209+
value: totalCost
210+
})
211+
})
212+
213+
it('Should create dispute after moderation escalation is complete.', async () => {
214+
await evidenceModule.connect(user2).moderate(evidenceID, Party.Moderator, {
215+
value: minRequiredDeposit.mul(2)
216+
})
217+
218+
let moderationInfo = await evidenceModule.getModerationInfo(evidenceID, 0)
219+
let paidFees = moderationInfo.paidFees
220+
let depositRequired = paidFees[Party.Moderator].mul(2).
221+
sub(paidFees[Party.Submitter])
222+
await evidenceModule.connect(user4).moderate(evidenceID, Party.Submitter, {
223+
value: depositRequired
224+
})
225+
226+
moderationInfo = await evidenceModule.getModerationInfo(evidenceID, 0)
227+
paidFees = moderationInfo.paidFees
228+
depositRequired = paidFees[Party.Submitter].mul(2).
229+
sub(paidFees[Party.Moderator])
230+
await evidenceModule.connect(user2).moderate(evidenceID, Party.Moderator, {
231+
value: depositRequired
232+
})
233+
234+
moderationInfo = await evidenceModule.getModerationInfo(evidenceID, 0)
235+
paidFees = moderationInfo.paidFees
236+
depositRequired = paidFees[Party.Moderator].mul(2).
237+
sub(paidFees[Party.Submitter])
238+
await evidenceModule.connect(user4).moderate(evidenceID, Party.Submitter, {
239+
value: depositRequired
240+
})
241+
242+
moderationInfo = await evidenceModule.getModerationInfo(evidenceID, 0)
243+
paidFees = moderationInfo.paidFees
244+
depositRequired = paidFees[Party.Submitter].mul(2).
245+
sub(paidFees[Party.Moderator])
246+
await evidenceModule.connect(user2).moderate(evidenceID, Party.Moderator, {
247+
value: depositRequired
248+
})
249+
250+
moderationInfo = await evidenceModule.getModerationInfo(evidenceID, 0)
251+
paidFees = moderationInfo.paidFees
252+
depositRequired = paidFees[Party.Moderator].mul(2).
253+
sub(paidFees[Party.Submitter])
254+
let tx = await evidenceModule.connect(user4).moderate(evidenceID, Party.Submitter, {
255+
value: depositRequired // Less is actually needed. Overpaid fees are reimbursed
256+
})
257+
let receipt = await tx.wait()
258+
259+
let [_arbitrator, disputeID, metaEvidenceID, _evidenceID] = getEmittedEvent('Dispute', receipt).args
260+
expect(_arbitrator).to.equal(arbitrator.address, 'Wrong arbitrator.')
261+
expect(disputeID).to.equal(0, 'Wrong dispute ID.')
262+
expect(metaEvidenceID).to.equal(0, 'Wrong meta-evidence ID.')
263+
expect(_evidenceID).to.equal(evidenceID, 'Wrong evidence ID.')
264+
265+
await expect(evidenceModule.
266+
connect(user2).moderate(evidenceID, Party.Moderator, {
267+
value: totalCost
268+
})
269+
).to.be.revertedWith('Evidence already disputed.')
270+
271+
await expect(evidenceModule.
272+
connect(user2).resolveModerationMarket(evidenceID)
273+
).to.be.revertedWith('Evidence already disputed.')
274+
})
275+
})
276+
})

contracts/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"esModuleInterop": true,
77
"outDir": "dist",
88
"declaration": true,
9-
"sourceMap": true
9+
"sourceMap": true,
10+
"noImplicitAny": false
1011
},
1112
"include": [
1213
"./src",

0 commit comments

Comments
 (0)