2021-04-20 21:40:47 +00:00
|
|
|
import { ethers } from "hardhat";
|
2021-04-22 18:30:51 +00:00
|
|
|
import { Contract } from "ethers";
|
2021-04-20 21:40:47 +00:00
|
|
|
import { expect } from "chai";
|
|
|
|
import { soliditySha3 } from "web3-utils";
|
2021-04-22 18:30:51 +00:00
|
|
|
import deploy from "../common/deployment";
|
2021-04-20 21:40:47 +00:00
|
|
|
|
|
|
|
describe("DioneDispute", function () {
|
|
|
|
let dioneDispute: Contract;
|
|
|
|
let dioneStaking: Contract;
|
|
|
|
|
|
|
|
beforeEach(async function () {
|
2021-04-22 18:30:51 +00:00
|
|
|
const contracts = await deploy({
|
|
|
|
reward: 100,
|
|
|
|
minStake: 5000,
|
|
|
|
voteWindowTime: 2,
|
|
|
|
randomizeStake: false,
|
|
|
|
maxStake: 0, // don't use this deployment feature
|
|
|
|
actualStake: 9000,
|
2021-04-27 15:52:28 +00:00
|
|
|
nodeCount: 4,
|
2021-04-27 18:24:24 +00:00
|
|
|
logging: false,
|
|
|
|
minStakeForDisputeVotes: 100
|
2021-04-22 18:30:51 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
dioneDispute = contracts.dioneDispute;
|
|
|
|
dioneStaking = contracts.dioneStaking;
|
2021-04-20 21:40:47 +00:00
|
|
|
});
|
|
|
|
|
2021-04-27 18:24:24 +00:00
|
|
|
it("should create dispute, vote it by various eth addresses and then finish", async function () {
|
|
|
|
const addresses = await (await ethers.getSigners()).slice(0, 4);
|
2021-04-20 21:40:47 +00:00
|
|
|
|
2021-04-27 18:24:24 +00:00
|
|
|
const dhash = soliditySha3(addresses[1].address, 1);
|
2021-04-20 21:40:47 +00:00
|
|
|
|
2021-04-27 18:24:24 +00:00
|
|
|
await expect(dioneDispute.beginDispute(addresses[1].address, 1))
|
2021-04-20 21:40:47 +00:00
|
|
|
.to.emit(dioneDispute, 'NewDispute')
|
2021-04-27 18:24:24 +00:00
|
|
|
.withArgs(dhash, 1, addresses[1].address, addresses[0].address);
|
2021-04-20 21:40:47 +00:00
|
|
|
|
2021-04-27 18:24:24 +00:00
|
|
|
for (const x of addresses) {
|
|
|
|
if (x == addresses[1] || x == addresses[0]) continue;
|
|
|
|
await expect(dioneDispute.connect(x).vote(dhash, true))
|
|
|
|
.to.emit(dioneDispute, 'NewVote')
|
|
|
|
.withArgs(dhash, x.address);
|
|
|
|
}
|
2021-04-20 21:40:47 +00:00
|
|
|
|
2021-04-26 22:01:20 +00:00
|
|
|
await ethers.provider.send("evm_increaseTime", [2]);
|
2021-04-20 21:40:47 +00:00
|
|
|
|
|
|
|
await expect(dioneDispute.finishDispute(dhash))
|
|
|
|
.to.emit(dioneDispute, 'DisputeFinished')
|
|
|
|
.withArgs(dhash, true);
|
|
|
|
|
2021-04-27 18:24:24 +00:00
|
|
|
expect(await dioneStaking.minerStake(addresses[1].address))
|
2021-04-20 21:40:47 +00:00
|
|
|
.to.equal(0);
|
2021-04-27 18:24:24 +00:00
|
|
|
|
|
|
|
for (const x of addresses) {
|
|
|
|
if (x == addresses[1]) continue;
|
|
|
|
expect(await dioneStaking.minerStake(x.address))
|
|
|
|
.to.equal(ethers.constants.WeiPerEther.mul(12000));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should fail voting on non-existing dispute", async function() {
|
|
|
|
const [addr1] = await ethers.getSigners();
|
|
|
|
|
|
|
|
const dhash = soliditySha3(addr1.address, 1);
|
|
|
|
|
|
|
|
await expect(dioneDispute.vote(dhash, true))
|
|
|
|
.to.be.revertedWith("dispute doesn't exist");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should fail finishing non-existing dispute", async function() {
|
|
|
|
const [addr1] = await ethers.getSigners();
|
|
|
|
|
|
|
|
const dhash = soliditySha3(addr1.address, 1);
|
|
|
|
|
|
|
|
await expect(dioneDispute.finishDispute(dhash))
|
|
|
|
.to.be.revertedWith("dispute doesn't exist");
|
|
|
|
})
|
|
|
|
|
|
|
|
it("should finish dispute with \"false\" result", async function () {
|
|
|
|
const addresses = await (await ethers.getSigners()).slice(0, 4);
|
|
|
|
|
|
|
|
const dhash = soliditySha3(addresses[1].address, 1);
|
|
|
|
await dioneDispute.beginDispute(addresses[1].address, 1);
|
|
|
|
await dioneDispute.connect(addresses[2]).vote(dhash, false);
|
|
|
|
await dioneDispute.connect(addresses[3]).vote(dhash, false);
|
|
|
|
await ethers.provider.send("evm_increaseTime", [2]);
|
|
|
|
await expect(dioneDispute.finishDispute(dhash))
|
|
|
|
.to.emit(dioneDispute, 'DisputeFinished')
|
|
|
|
.withArgs(dhash, false);
|
2021-04-20 21:40:47 +00:00
|
|
|
|
2021-04-27 18:24:24 +00:00
|
|
|
// check if stakes of miners is same as initial
|
|
|
|
for (const x of addresses) {
|
|
|
|
expect(await dioneStaking.minerStake(x.address))
|
|
|
|
.to.be.equal(ethers.constants.WeiPerEther.mul(9000));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should fail when finishing dispute before exceeding vote window time", async () => {
|
|
|
|
const [, addr1 ] = await ethers.getSigners();
|
|
|
|
|
|
|
|
const dhash = soliditySha3(addr1.address, 1);
|
|
|
|
await dioneDispute.beginDispute(addr1.address, 1);
|
|
|
|
await expect(dioneDispute.finishDispute(dhash))
|
|
|
|
.to.be.revertedWith("vote window hasn't passed yet");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should fail when voting as dispute initiator", async () => {
|
|
|
|
const [, addr1 ] = await ethers.getSigners();
|
|
|
|
|
|
|
|
const dhash = soliditySha3(addr1.address, 1);
|
|
|
|
await dioneDispute.beginDispute(addr1.address, 1);
|
|
|
|
await expect(dioneDispute.vote(dhash, true))
|
|
|
|
.to.be.revertedWith("dispute initiator isn't allowed to vote");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should fail when voting as miner against whom dispute has beginned", async () => {
|
|
|
|
const [, addr1 ] = await ethers.getSigners();
|
|
|
|
|
|
|
|
const dhash = soliditySha3(addr1.address, 1);
|
|
|
|
await dioneDispute.beginDispute(addr1.address, 1);
|
|
|
|
await expect(dioneDispute.connect(addr1).vote(dhash, true))
|
|
|
|
.to.be.revertedWith("the miner against whom dispute has beginned isn't allowed to vote");
|
|
|
|
});
|
2021-04-20 21:40:47 +00:00
|
|
|
|
2021-04-27 19:11:34 +00:00
|
|
|
it("should fail when beginning dispute on the same miner", async () => {
|
|
|
|
const [, addr1 ] = await ethers.getSigners();
|
|
|
|
|
|
|
|
await dioneDispute.beginDispute(addr1.address, 1);
|
|
|
|
await expect(dioneDispute.beginDispute(addr1.address, 1))
|
|
|
|
.to.be.revertedWith("dispute already exists");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should fail when voting finished dispute", async () => {
|
|
|
|
const [, addr1, addr2 ] = await ethers.getSigners();
|
|
|
|
|
|
|
|
const dhash = soliditySha3(addr1.address, 1);
|
|
|
|
await dioneDispute.beginDispute(addr1.address, 1);
|
|
|
|
await ethers.provider.send("evm_increaseTime", [2]);
|
|
|
|
await dioneDispute.finishDispute(dhash);
|
|
|
|
|
|
|
|
await expect(dioneDispute.connect(addr2).vote(dhash, true))
|
|
|
|
.to.be.revertedWith("dispute already finished");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should fail when dispute beginner isn't dione miner", async () => {
|
|
|
|
const [ ,addr1,,,addr4 ] = await ethers.getSigners();
|
|
|
|
await expect(dioneDispute.connect(addr4).beginDispute(addr1.address, 1))
|
|
|
|
.to.be.revertedWith("caller isn't dione miner");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should fail when voter isn't dione miner", async () => {
|
|
|
|
const [ ,addr1,,,addr4 ] = await ethers.getSigners();
|
|
|
|
|
|
|
|
const dhash = soliditySha3(addr1.address, 1);
|
|
|
|
await dioneDispute.beginDispute(addr1.address, 1);
|
|
|
|
await expect(dioneDispute.connect(addr4).vote(dhash, true))
|
|
|
|
.to.be.revertedWith("caller isn't dione miner");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should fail when finishing already finished dispute", async () => {
|
|
|
|
const [, addr1 ] = await ethers.getSigners();
|
|
|
|
|
|
|
|
const dhash = soliditySha3(addr1.address, 1);
|
|
|
|
await dioneDispute.beginDispute(addr1.address, 1);
|
|
|
|
await ethers.provider.send("evm_increaseTime", [2]);
|
|
|
|
await dioneDispute.finishDispute(dhash);
|
|
|
|
await expect(dioneDispute.finishDispute(dhash))
|
|
|
|
.to.be.revertedWith("dispute already finished");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should fail when finishing dispute as not dispute initiator", async () => {
|
|
|
|
const [, addr1 ] = await ethers.getSigners();
|
|
|
|
|
|
|
|
const dhash = soliditySha3(addr1.address, 1);
|
|
|
|
await dioneDispute.beginDispute(addr1.address, 1);
|
|
|
|
await ethers.provider.send("evm_increaseTime", [2]);
|
|
|
|
await expect(dioneDispute.connect(addr1).finishDispute(dhash))
|
|
|
|
.to.be.revertedWith("only dispute initiator can call this function");
|
|
|
|
});
|
|
|
|
|
2021-04-27 18:24:24 +00:00
|
|
|
describe("DioneDispute - insufficient funds", () => {
|
|
|
|
let dioneDispute: Contract;
|
|
|
|
before(async () => {
|
|
|
|
const contracts = await deploy({
|
|
|
|
reward: 100,
|
|
|
|
minStake: 0,
|
|
|
|
voteWindowTime: 2,
|
|
|
|
randomizeStake: false,
|
|
|
|
maxStake: 0, // don't use this deployment feature
|
|
|
|
actualStake: 50,
|
|
|
|
nodeCount: 1,
|
|
|
|
logging: false,
|
|
|
|
minStakeForDisputeVotes: 100
|
|
|
|
});
|
|
|
|
|
|
|
|
dioneDispute = contracts.dioneDispute;
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should fail when voting with insufficient funds", async () => {
|
|
|
|
const [, addr1, addr2] = await ethers.getSigners();
|
|
|
|
|
|
|
|
const dhash = soliditySha3(addr1.address, 1);
|
|
|
|
await dioneDispute.beginDispute(addr1.address, 1);
|
|
|
|
await expect(dioneDispute.connect(addr2).vote(dhash, true))
|
|
|
|
.to.be.revertedWith("miner doesn't have minimum stake to vote");
|
|
|
|
});
|
2021-04-20 21:40:47 +00:00
|
|
|
});
|
2021-04-26 22:01:20 +00:00
|
|
|
});
|