Skip to content

Commit 208e009

Browse files
committed
feat: let the dispute kit force an early court jump and override the next round nbVotes
1 parent 9618a6f commit 208e009

File tree

4 files changed

+76
-20
lines changed

4 files changed

+76
-20
lines changed

contracts/hardhat.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const config: HardhatUserConfig = {
3131
viaIR: process.env.VIA_IR !== "false", // Defaults to true
3232
optimizer: {
3333
enabled: true,
34-
runs: 10000,
34+
runs: 2000,
3535
},
3636
outputSelection: {
3737
"*": {

contracts/src/arbitration/KlerosCoreBase.sol

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -639,24 +639,17 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
639639
Round storage round = dispute.rounds[dispute.rounds.length - 1];
640640
if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();
641641

642-
uint96 newCourtID = dispute.courtID;
643-
uint256 newDisputeKitID = round.disputeKitID;
644-
645642
// Warning: the extra round must be created before calling disputeKit.createDispute()
646643
Round storage extraRound = dispute.rounds.push();
647644

648-
if (round.nbVotes >= courts[newCourtID].jurorsForCourtJump) {
649-
// Jump to parent court.
650-
newCourtID = courts[newCourtID].parent;
651-
652-
if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {
653-
// Switch to classic dispute kit if parent court doesn't support the current one.
654-
newDisputeKitID = DISPUTE_KIT_CLASSIC;
655-
}
656-
657-
if (newCourtID != dispute.courtID) {
658-
emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);
659-
}
645+
(uint96 newCourtID, uint256 newDisputeKitID, bool courtJump, ) = _getCourtAndDisputeKitJumps(
646+
dispute,
647+
round,
648+
courts[dispute.courtID],
649+
_disputeID
650+
);
651+
if (courtJump) {
652+
emit CourtJump(_disputeID, dispute.rounds.length - 1, dispute.courtID, newCourtID);
660653
}
661654

662655
dispute.courtID = newCourtID;
@@ -934,17 +927,22 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
934927
Dispute storage dispute = disputes[_disputeID];
935928
Round storage round = dispute.rounds[dispute.rounds.length - 1];
936929
Court storage court = courts[dispute.courtID];
937-
if (round.nbVotes >= court.jurorsForCourtJump) {
930+
931+
(, uint256 newDisputeKitID, bool courtJump, ) = _getCourtAndDisputeKitJumps(dispute, round, court, _disputeID);
932+
933+
uint256 nbVotesAfterAppeal = disputeKits[newDisputeKitID].getNbVotesAfterAppeal(round.nbVotes);
934+
935+
if (courtJump) {
938936
// Jump to parent court.
939937
if (dispute.courtID == GENERAL_COURT) {
940938
// TODO: Handle the forking when appealed in General court.
941939
cost = NON_PAYABLE_AMOUNT; // Get the cost of the parent court.
942940
} else {
943-
cost = courts[court.parent].feeForJuror * ((round.nbVotes * 2) + 1);
941+
cost = courts[court.parent].feeForJuror * nbVotesAfterAppeal;
944942
}
945943
} else {
946944
// Stay in current court.
947-
cost = court.feeForJuror * ((round.nbVotes * 2) + 1);
945+
cost = court.feeForJuror * nbVotesAfterAppeal;
948946
}
949947
}
950948

@@ -1033,7 +1031,7 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
10331031
Round storage round = dispute.rounds[dispute.rounds.length - 1];
10341032
Court storage court = courts[dispute.courtID];
10351033

1036-
if (round.nbVotes < court.jurorsForCourtJump) {
1034+
if (!_isCourtJumping(round, court, _disputeID)) {
10371035
return false;
10381036
}
10391037

@@ -1053,6 +1051,41 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
10531051
// * Internal * //
10541052
// ************************************* //
10551053

1054+
/// @dev Returns true if the round is jumping to a parent court.
1055+
/// @param _round The round to check.
1056+
/// @param _court The court to check.
1057+
/// @return Whether the round is jumping to a parent court or not.
1058+
function _isCourtJumping(
1059+
Round storage _round,
1060+
Court storage _court,
1061+
uint256 _disputeID
1062+
) internal view returns (bool) {
1063+
return
1064+
disputeKits[_round.disputeKitID].earlyCourtJump(_disputeID) || _round.nbVotes >= _court.jurorsForCourtJump;
1065+
}
1066+
1067+
function _getCourtAndDisputeKitJumps(
1068+
Dispute storage _dispute,
1069+
Round storage _round,
1070+
Court storage _court,
1071+
uint256 _disputeID
1072+
) internal view returns (uint96 newCourtID, uint256 newDisputeKitID, bool courtJump, bool disputeKitJump) {
1073+
newCourtID = _dispute.courtID;
1074+
newDisputeKitID = _round.disputeKitID;
1075+
1076+
if (!_isCourtJumping(_round, _court, _disputeID)) return (newCourtID, newDisputeKitID, false, false);
1077+
1078+
// Jump to parent court.
1079+
newCourtID = courts[newCourtID].parent;
1080+
courtJump = true;
1081+
1082+
if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {
1083+
// Switch to classic dispute kit if parent court doesn't support the current one.
1084+
newDisputeKitID = DISPUTE_KIT_CLASSIC;
1085+
disputeKitJump = true;
1086+
}
1087+
}
1088+
10561089
/// @dev Internal function to transfer fee tokens (ETH or ERC20)
10571090
/// @param _feeToken The token to transfer (NATIVE_CURRENCY for ETH).
10581091
/// @param _recipient The recipient address.

contracts/src/arbitration/dispute-kits/DisputeKitClassicBase.sol

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,19 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi
627627
((appealPeriodEnd - appealPeriodStart) * LOSER_APPEAL_PERIOD_MULTIPLIER) / ONE_BASIS_POINT);
628628
}
629629

630+
/// @dev Returns true if the dispute is jumping to a parent court.
631+
/// @return Whether the dispute is jumping to a parent court or not.
632+
function earlyCourtJump(uint256 /* _coreDisputeID */) external pure override returns (bool) {
633+
return false;
634+
}
635+
636+
/// @dev Returns the number of votes after the appeal.
637+
/// @param _currentNbVotes The number of votes before the appeal.
638+
/// @return The number of votes after the appeal.
639+
function getNbVotesAfterAppeal(uint256 _currentNbVotes) external pure override returns (uint256) {
640+
return (_currentNbVotes * 2) + 1;
641+
}
642+
630643
/// @dev Returns true if the specified voter was active in this round.
631644
/// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.
632645
/// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.

contracts/src/arbitration/interfaces/IDisputeKit.sol

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,16 @@ interface IDisputeKit {
113113
/// @return Whether the appeal funding is finished.
114114
function isAppealFunded(uint256 _coreDisputeID) external view returns (bool);
115115

116+
/// @dev Returns true if the dispute is jumping to a parent court.
117+
/// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.
118+
/// @return Whether the dispute is jumping to a parent court or not.
119+
function earlyCourtJump(uint256 _coreDisputeID) external view returns (bool);
120+
121+
/// @dev Returns the number of votes after the appeal.
122+
/// @param _currentNbVotes The number of votes before the appeal.
123+
/// @return The number of votes after the appeal.
124+
function getNbVotesAfterAppeal(uint256 _currentNbVotes) external view returns (uint256);
125+
116126
/// @dev Returns true if the specified voter was active in this round.
117127
/// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.
118128
/// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.

0 commit comments

Comments
 (0)