Skip to content

Commit 602120e

Browse files
committed
refactor: split the KlerosCore foundry tests into several files as it was over 3000 lines
1 parent f734873 commit 602120e

10 files changed

+3270
-0
lines changed

contracts/test/foundry/KlerosCore_Appeals.t.sol

Lines changed: 361 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.24;
3+
4+
import {KlerosCore_TestBase} from "./KlerosCore_TestBase.sol";
5+
import {KlerosCoreBase} from "../../src/arbitration/KlerosCoreBase.sol";
6+
import {IArbitratorV2} from "../../src/arbitration/KlerosCoreBase.sol";
7+
import {DisputeKitClassicBase} from "../../src/arbitration/dispute-kits/DisputeKitClassicBase.sol";
8+
import {IArbitrableV2} from "../../src/arbitration/arbitrables/ArbitrableExample.sol";
9+
import "../../src/libraries/Constants.sol";
10+
11+
/// @title KlerosCore_DisputesTest
12+
/// @dev Tests for KlerosCore dispute creation and management
13+
contract KlerosCore_DisputesTest is KlerosCore_TestBase {
14+
function test_createDispute_eth() public {
15+
// Create a new court and DK to test non-standard extra data
16+
uint256 newFee = 0.01 ether;
17+
uint96 newCourtID = 2;
18+
uint256 newNbJurors = 4;
19+
uint256 newDkID = 2;
20+
uint256[] memory supportedDK = new uint256[](1);
21+
supportedDK[0] = DISPUTE_KIT_CLASSIC;
22+
bytes memory newExtraData = abi.encodePacked(uint256(newCourtID), newNbJurors, newDkID);
23+
24+
vm.prank(owner);
25+
core.addNewDisputeKit(disputeKit); // Just add the same dk to avoid dealing with initialization
26+
vm.prank(owner);
27+
core.createCourt(
28+
GENERAL_COURT,
29+
true, // Hidden votes
30+
2000, // min stake
31+
20000, // alpha
32+
newFee, // fee for juror
33+
50, // jurors for jump
34+
[uint256(10), uint256(20), uint256(30), uint256(40)], // Times per period
35+
abi.encode(uint256(4)), // Sortition extra data
36+
supportedDK
37+
);
38+
39+
arbitrable.changeArbitratorExtraData(newExtraData);
40+
41+
vm.expectRevert(KlerosCoreBase.ArbitrationFeesNotEnough.selector);
42+
vm.prank(disputer);
43+
arbitrable.createDispute{value: newFee * newNbJurors - 1}("Action");
44+
45+
vm.expectRevert(KlerosCoreBase.DisputeKitNotSupportedByCourt.selector);
46+
vm.prank(disputer);
47+
arbitrable.createDispute{value: 0.04 ether}("Action");
48+
49+
vm.prank(owner);
50+
supportedDK = new uint256[](1);
51+
supportedDK[0] = newDkID;
52+
core.enableDisputeKits(newCourtID, supportedDK, true);
53+
54+
uint256 disputeID = 0;
55+
uint256 nbChoices = 2;
56+
vm.prank(disputer);
57+
vm.expectEmit(true, true, true, true);
58+
emit DisputeKitClassicBase.DisputeCreation(disputeID, nbChoices, newExtraData);
59+
vm.expectEmit(true, true, true, true);
60+
emit IArbitratorV2.DisputeCreation(disputeID, arbitrable);
61+
arbitrable.createDispute{value: 0.04 ether}("Action");
62+
63+
assertEq(sortitionModule.disputesWithoutJurors(), 1, "Wrong disputesWithoutJurors count");
64+
(
65+
uint96 courtID,
66+
IArbitrableV2 arbitrated,
67+
KlerosCoreBase.Period period,
68+
bool ruled,
69+
uint256 lastPeriodChange
70+
) = core.disputes(disputeID);
71+
72+
assertEq(courtID, newCourtID, "Wrong court ID");
73+
assertEq(address(arbitrated), address(arbitrable), "Wrong arbitrable");
74+
assertEq(uint256(period), uint256(KlerosCoreBase.Period.evidence), "Wrong period");
75+
assertEq(ruled, false, "Should not be ruled");
76+
assertEq(lastPeriodChange, block.timestamp, "Wrong lastPeriodChange");
77+
78+
KlerosCoreBase.Round memory round = core.getRoundInfo(disputeID, 0);
79+
assertEq(round.disputeKitID, newDkID, "Wrong DK ID");
80+
assertEq(round.pnkAtStakePerJuror, 4000, "Wrong pnkAtStakePerJuror"); // minStake * alpha / divisor = 2000 * 20000/10000
81+
assertEq(round.totalFeesForJurors, 0.04 ether, "Wrong totalFeesForJurors");
82+
assertEq(round.nbVotes, 4, "Wrong nbVotes");
83+
assertEq(round.repartitions, 0, "repartitions should be 0");
84+
assertEq(round.pnkPenalties, 0, "pnkPenalties should be 0");
85+
assertEq(round.sumFeeRewardPaid, 0, "sumFeeRewardPaid should be 0");
86+
assertEq(round.sumPnkRewardPaid, 0, "sumPnkRewardPaid should be 0");
87+
assertEq(address(round.feeToken), address(0), "feeToken should be 0");
88+
assertEq(round.drawIterations, 0, "drawIterations should be 0");
89+
90+
(uint256 numberOfChoices, bool jumped, bytes memory extraData) = disputeKit.disputes(disputeID);
91+
92+
assertEq(numberOfChoices, 2, "Wrong numberOfChoices");
93+
assertEq(jumped, false, "jumped should be false");
94+
assertEq(extraData, newExtraData, "Wrong extra data");
95+
assertEq(disputeKit.coreDisputeIDToLocal(0), disputeID, "Wrong local disputeID");
96+
assertEq(disputeKit.coreDisputeIDToActive(0), true, "Wrong disputes length");
97+
98+
(
99+
uint256 winningChoice,
100+
bool tied,
101+
uint256 totalVoted,
102+
uint256 totalCommited,
103+
uint256 nbVoters,
104+
uint256 choiceCount
105+
) = disputeKit.getRoundInfo(0, 0, 0);
106+
assertEq(winningChoice, 0, "winningChoice should be 0");
107+
assertEq(tied, true, "tied should be true");
108+
assertEq(totalVoted, 0, "totalVoted should be 0");
109+
assertEq(totalCommited, 0, "totalCommited should be 0");
110+
assertEq(nbVoters, 0, "nbVoters should be 0");
111+
assertEq(choiceCount, 0, "choiceCount should be 0");
112+
}
113+
114+
function test_createDispute_tokens() public {
115+
feeToken.transfer(disputer, 1 ether);
116+
vm.prank(disputer);
117+
feeToken.approve(address(arbitrable), 1 ether);
118+
119+
vm.expectRevert(KlerosCoreBase.TokenNotAccepted.selector);
120+
vm.prank(disputer);
121+
arbitrable.createDispute("Action", 0.18 ether);
122+
123+
vm.prank(owner);
124+
core.changeAcceptedFeeTokens(feeToken, true);
125+
vm.prank(owner);
126+
core.changeCurrencyRates(feeToken, 500, 3);
127+
128+
vm.expectRevert(KlerosCoreBase.ArbitrationFeesNotEnough.selector);
129+
vm.prank(disputer);
130+
arbitrable.createDispute("Action", 0.18 ether - 1);
131+
132+
vm.expectRevert(KlerosCoreBase.TransferFailed.selector);
133+
vm.prank(address(arbitrable)); // Bypass createDispute in arbitrable to avoid transfer checks there and make the arbitrable call KC directly
134+
core.createDispute(2, arbitratorExtraData, feeToken, 0.18 ether);
135+
136+
assertEq(core.arbitrationCost(arbitratorExtraData, feeToken), 0.18 ether, "Wrong token cost");
137+
vm.prank(disputer);
138+
arbitrable.createDispute("Action", 0.18 ether);
139+
140+
KlerosCoreBase.Round memory round = core.getRoundInfo(0, 0);
141+
assertEq(round.totalFeesForJurors, 0.18 ether, "Wrong totalFeesForJurors");
142+
assertEq(round.nbVotes, 3, "Wrong nbVotes");
143+
assertEq(address(round.feeToken), address(feeToken), "Wrong feeToken");
144+
145+
assertEq(feeToken.balanceOf(address(core)), 0.18 ether, "Wrong token balance of the core");
146+
assertEq(feeToken.balanceOf(disputer), 0.82 ether, "Wrong token balance of the disputer");
147+
}
148+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.24;
3+
4+
import {KlerosCore_TestBase} from "./KlerosCore_TestBase.sol";
5+
import {KlerosCoreBase} from "../../src/arbitration/KlerosCoreBase.sol";
6+
import {SortitionModuleBase} from "../../src/arbitration/SortitionModuleBase.sol";
7+
import {ISortitionModule} from "../../src/arbitration/interfaces/ISortitionModule.sol";
8+
import "../../src/libraries/Constants.sol";
9+
10+
/// @title KlerosCore_DrawingTest
11+
/// @dev Tests for KlerosCore jury drawing and selection mechanisms
12+
contract KlerosCore_DrawingTest is KlerosCore_TestBase {
13+
function test_draw() public {
14+
uint256 disputeID = 0;
15+
uint256 roundID = 0;
16+
17+
vm.prank(staker1);
18+
core.setStake(GENERAL_COURT, 1500);
19+
vm.prank(disputer);
20+
arbitrable.createDispute{value: feeForJuror * DEFAULT_NB_OF_JURORS}("Action");
21+
vm.warp(block.timestamp + minStakingTime);
22+
sortitionModule.passPhase(); // Generating
23+
vm.warp(block.timestamp + rngLookahead);
24+
sortitionModule.passPhase(); // Drawing phase
25+
26+
vm.expectEmit(true, true, true, true);
27+
emit SortitionModuleBase.StakeLocked(staker1, 1000, false);
28+
vm.expectEmit(true, true, true, true);
29+
emit KlerosCoreBase.Draw(staker1, disputeID, roundID, 0); // VoteID = 0
30+
31+
core.draw(disputeID, DEFAULT_NB_OF_JURORS); // Do 3 iterations and see that the juror will get drawn 3 times despite low stake.
32+
33+
(uint256 totalStaked, uint256 totalLocked, uint256 stakedInCourt, ) = sortitionModule.getJurorBalance(
34+
staker1,
35+
GENERAL_COURT
36+
);
37+
assertEq(totalStaked, 1500, "Wrong amount total staked");
38+
assertEq(totalLocked, 3000, "Wrong amount locked"); // 1000 per draw
39+
assertEq(stakedInCourt, 1500, "Wrong amount staked in court");
40+
assertEq(sortitionModule.disputesWithoutJurors(), 0, "Wrong disputesWithoutJurors count");
41+
42+
for (uint256 i = 0; i < DEFAULT_NB_OF_JURORS; i++) {
43+
(address account, bytes32 commit, uint256 choice, bool voted) = disputeKit.getVoteInfo(0, 0, i);
44+
assertEq(account, staker1, "Wrong drawn account");
45+
assertEq(commit, bytes32(0), "Commit should be empty");
46+
assertEq(choice, 0, "Choice should be empty");
47+
assertEq(voted, false, "Voted should be false");
48+
}
49+
}
50+
51+
function test_draw_noEmptyAddresses() public {
52+
uint256 disputeID = 0;
53+
uint256 roundID = 0;
54+
55+
vm.prank(disputer);
56+
arbitrable.createDispute{value: feeForJuror * DEFAULT_NB_OF_JURORS}("Action");
57+
vm.warp(block.timestamp + minStakingTime);
58+
sortitionModule.passPhase(); // Generating
59+
vm.warp(block.timestamp + rngLookahead);
60+
sortitionModule.passPhase(); // Drawing phase
61+
62+
core.draw(disputeID, DEFAULT_NB_OF_JURORS); // No one is staked so check that the empty addresses are not drawn.
63+
64+
KlerosCoreBase.Round memory round = core.getRoundInfo(disputeID, roundID);
65+
assertEq(round.drawIterations, 3, "Wrong drawIterations number");
66+
67+
(, , , , uint256 nbVoters, ) = disputeKit.getRoundInfo(disputeID, roundID, 0);
68+
assertEq(nbVoters, 0, "nbVoters should be 0");
69+
}
70+
71+
function test_draw_parentCourts() public {
72+
uint96 newCourtID = 2;
73+
uint256 disputeID = 0;
74+
uint256 roundID = 0;
75+
76+
// Create a child court and stake exclusively there to check that parent courts hold drawing power.
77+
vm.prank(owner);
78+
uint256[] memory supportedDK = new uint256[](1);
79+
supportedDK[0] = DISPUTE_KIT_CLASSIC;
80+
core.createCourt(
81+
GENERAL_COURT,
82+
true, // Hidden votes
83+
1000, // min stake
84+
10000, // alpha
85+
0.03 ether, // fee for juror
86+
50, // jurors for jump
87+
[uint256(10), uint256(20), uint256(30), uint256(40)], // Times per period
88+
sortitionExtraData, // Sortition extra data
89+
supportedDK
90+
);
91+
92+
uint256[] memory children = core.getCourtChildren(GENERAL_COURT);
93+
assertEq(children.length, 1, "Wrong children count");
94+
assertEq(children[0], 2, "Wrong child ID");
95+
96+
vm.prank(staker1);
97+
core.setStake(newCourtID, 3000);
98+
vm.prank(disputer);
99+
arbitrable.createDispute{value: feeForJuror * DEFAULT_NB_OF_JURORS}("Action"); // Dispute uses general court by default
100+
vm.warp(block.timestamp + minStakingTime);
101+
sortitionModule.passPhase(); // Generating
102+
vm.warp(block.timestamp + rngLookahead);
103+
sortitionModule.passPhase(); // Drawing phase
104+
105+
(uint96 courtID, , , , ) = core.disputes(disputeID);
106+
assertEq(courtID, GENERAL_COURT, "Wrong court ID of the dispute");
107+
108+
vm.expectEmit(true, true, true, true);
109+
emit KlerosCoreBase.Draw(staker1, disputeID, roundID, 0);
110+
vm.expectEmit(true, true, true, true);
111+
emit KlerosCoreBase.Draw(staker1, disputeID, roundID, 1);
112+
vm.expectEmit(true, true, true, true);
113+
emit KlerosCoreBase.Draw(staker1, disputeID, roundID, 2);
114+
core.draw(disputeID, DEFAULT_NB_OF_JURORS);
115+
116+
assertEq(sortitionModule.disputesWithoutJurors(), 0, "Wrong disputesWithoutJurors count");
117+
118+
KlerosCoreBase.Round memory round = core.getRoundInfo(disputeID, roundID);
119+
assertEq(round.drawIterations, 3, "Wrong drawIterations number");
120+
121+
(, , , , uint256 nbVoters, ) = disputeKit.getRoundInfo(disputeID, roundID, 0);
122+
assertEq(nbVoters, 3, "nbVoters should be 3");
123+
}
124+
}

0 commit comments

Comments
 (0)