@@ -43,7 +43,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
4343 uint256 feeForJuror; // Arbitration fee paid per juror.
4444 uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.
4545 uint256 [4 ] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.
46- mapping (uint256 => bool ) supportedDisputeKits; // True if DK with this ID is supported by the court.
46+ mapping (uint256 => bool ) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.
4747 bool disabled; // True if the court is disabled. Unused for now, will be implemented later.
4848 }
4949
@@ -77,14 +77,6 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
7777 mapping (uint96 => uint256 ) stakedPnkByCourt; // The amount of PNKs the juror has staked in the court in the form `stakedPnkByCourt[courtID]`.
7878 }
7979
80- struct DisputeKitNode {
81- uint256 parent; // Index of the parent dispute kit. If it's 0 then this DK is a root.
82- uint256 [] children; // List of child dispute kits.
83- IDisputeKit disputeKit; // The dispute kit implementation.
84- uint256 depthLevel; // How far this DK is from the root. 0 for root DK.
85- bool disabled; // True if the dispute kit is disabled and can't be used. This parameter is added preemptively to avoid storage changes in the future.
86- }
87-
8880 // Workaround "stack too deep" errors
8981 struct ExecuteParams {
9082 uint256 disputeID; // The ID of the dispute to execute.
@@ -107,14 +99,13 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
10799
108100 uint256 private constant ALPHA_DIVISOR = 1e4 ; // The number to divide `Court.alpha` by.
109101 uint256 private constant NON_PAYABLE_AMOUNT = (2 ** 256 - 2 ) / 2 ; // An amount higher than the supply of ETH.
110- uint256 private constant SEARCH_ITERATIONS = 10 ; // Number of iterations to search for suitable parent court before jumping to the top court.
111102
112103 address public governor; // The governor of the contract.
113104 IERC20 public pinakion; // The Pinakion token contract.
114105 address public jurorProsecutionModule; // The module for juror's prosecution.
115106 ISortitionModule public sortitionModule; // Sortition module for drawing.
116107 Court[] public courts; // The courts.
117- DisputeKitNode [] public disputeKitNodes ; // The list of DisputeKitNode, indexed by DisputeKitID .
108+ IDisputeKit [] public disputeKits ; // Array of dispute kits .
118109 Dispute[] public disputes; // The disputes.
119110 mapping (address => Juror) internal jurors; // The jurors.
120111 mapping (IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH.
@@ -149,11 +140,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
149140 uint256 _jurorsForCourtJump ,
150141 uint256 [4 ] _timesPerPeriod
151142 );
152- event DisputeKitCreated (
153- uint256 indexed _disputeKitID ,
154- IDisputeKit indexed _disputeKitAddress ,
155- uint256 indexed _parent
156- );
143+ event DisputeKitCreated (uint256 indexed _disputeKitID , IDisputeKit indexed _disputeKitAddress );
157144 event DisputeKitEnabled (uint96 indexed _courtID , uint256 indexed _disputeKitID , bool indexed _enable );
158145 event CourtJump (
159146 uint256 indexed _disputeID ,
@@ -228,20 +215,13 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
228215 jurorProsecutionModule = _jurorProsecutionModule;
229216 sortitionModule = _sortitionModuleAddress;
230217
231- // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a node has no parent .
232- disputeKitNodes .push ();
218+ // NULL_DISPUTE_KIT: an empty element at index 0 to indicate when a dispute kit is not supported .
219+ disputeKits .push ();
233220
234221 // DISPUTE_KIT_CLASSIC
235- disputeKitNodes.push (
236- DisputeKitNode ({
237- parent: Constants.NULL_DISPUTE_KIT,
238- children: new uint256 [](0 ),
239- disputeKit: _disputeKit,
240- depthLevel: 0 ,
241- disabled: false
242- })
243- );
244- emit DisputeKitCreated (Constants.DISPUTE_KIT_CLASSIC, _disputeKit, Constants.NULL_DISPUTE_KIT);
222+ disputeKits.push (_disputeKit);
223+
224+ emit DisputeKitCreated (Constants.DISPUTE_KIT_CLASSIC, _disputeKit);
245225
246226 // FORKING_COURT
247227 // TODO: Fill the properties for the Forking court, emit CourtCreated.
@@ -326,33 +306,10 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
326306
327307 /// @dev Add a new supported dispute kit module to the court.
328308 /// @param _disputeKitAddress The address of the dispute kit contract.
329- /// @param _parent The ID of the parent dispute kit. It is left empty when root DK is created.
330- /// Note that the root DK must be supported by the general court.
331- function addNewDisputeKit (IDisputeKit _disputeKitAddress , uint256 _parent ) external onlyByGovernor {
332- uint256 disputeKitID = disputeKitNodes.length ;
333- if (_parent >= disputeKitID) revert InvalidDisputKitParent ();
334- uint256 depthLevel;
335- if (_parent != Constants.NULL_DISPUTE_KIT) {
336- depthLevel = disputeKitNodes[_parent].depthLevel + 1 ;
337- // It should be always possible to reach the root from the leaf with the defined number of search iterations.
338- if (depthLevel >= SEARCH_ITERATIONS) revert DepthLevelMax ();
339- }
340- disputeKitNodes.push (
341- DisputeKitNode ({
342- parent: _parent,
343- children: new uint256 [](0 ),
344- disputeKit: _disputeKitAddress,
345- depthLevel: depthLevel,
346- disabled: false
347- })
348- );
349-
350- disputeKitNodes[_parent].children.push (disputeKitID);
351- emit DisputeKitCreated (disputeKitID, _disputeKitAddress, _parent);
352- if (_parent == Constants.NULL_DISPUTE_KIT) {
353- // A new dispute kit tree root should always be supported by the General court.
354- _enableDisputeKit (Constants.GENERAL_COURT, disputeKitID, true );
355- }
309+ function addNewDisputeKit (IDisputeKit _disputeKitAddress ) external onlyByGovernor {
310+ uint256 disputeKitID = disputeKits.length ;
311+ disputeKits.push (_disputeKitAddress);
312+ emit DisputeKitCreated (disputeKitID, _disputeKitAddress);
356313 }
357314
358315 /// @dev Creates a court under a specified parent court.
@@ -384,11 +341,13 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
384341 Court storage court = courts.push ();
385342
386343 for (uint256 i = 0 ; i < _supportedDisputeKits.length ; i++ ) {
387- if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKitNodes .length ) {
344+ if (_supportedDisputeKits[i] == 0 || _supportedDisputeKits[i] >= disputeKits .length ) {
388345 revert WrongDisputeKitIndex ();
389346 }
390347 court.supportedDisputeKits[_supportedDisputeKits[i]] = true ;
391348 }
349+ // Check that Classic DK support was added.
350+ if (! court.supportedDisputeKits[Constants.DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic ();
392351
393352 court.parent = _parent;
394353 court.children = new uint256 [](0 );
@@ -458,16 +417,14 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
458417 function enableDisputeKits (uint96 _courtID , uint256 [] memory _disputeKitIDs , bool _enable ) external onlyByGovernor {
459418 for (uint256 i = 0 ; i < _disputeKitIDs.length ; i++ ) {
460419 if (_enable) {
461- if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKitNodes .length ) {
420+ if (_disputeKitIDs[i] == 0 || _disputeKitIDs[i] >= disputeKits .length ) {
462421 revert WrongDisputeKitIndex ();
463422 }
464423 _enableDisputeKit (_courtID, _disputeKitIDs[i], true );
465424 } else {
466- if (
467- _courtID == Constants.GENERAL_COURT &&
468- disputeKitNodes[_disputeKitIDs[i]].parent == Constants.NULL_DISPUTE_KIT
469- ) {
470- revert CannotDisableRootDKInGeneral ();
425+ // Classic dispute kit must be supported by all courts.
426+ if (_disputeKitIDs[i] == Constants.DISPUTE_KIT_CLASSIC) {
427+ revert CannotDisableClassicDK ();
471428 }
472429 _enableDisputeKit (_courtID, _disputeKitIDs[i], false );
473430 }
@@ -547,7 +504,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
547504 dispute.arbitrated = IArbitrableV2 (msg .sender );
548505 dispute.lastPeriodChange = block .timestamp ;
549506
550- IDisputeKit disputeKit = disputeKitNodes [disputeKitID].disputeKit ;
507+ IDisputeKit disputeKit = disputeKits [disputeKitID];
551508 Court storage court = courts[dispute.courtID];
552509 Round storage round = dispute.rounds.push ();
553510
@@ -587,15 +544,15 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
587544 } else if (dispute.period == Period.commit) {
588545 if (
589546 block .timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256 (dispute.period)] &&
590- ! disputeKitNodes [round.disputeKitID].disputeKit .areCommitsAllCast (_disputeID)
547+ ! disputeKits [round.disputeKitID].areCommitsAllCast (_disputeID)
591548 ) {
592549 revert CommitPeriodNotPassed ();
593550 }
594551 dispute.period = Period.vote;
595552 } else if (dispute.period == Period.vote) {
596553 if (
597554 block .timestamp - dispute.lastPeriodChange < court.timesPerPeriod[uint256 (dispute.period)] &&
598- ! disputeKitNodes [round.disputeKitID].disputeKit .areVotesAllCast (_disputeID)
555+ ! disputeKits [round.disputeKitID].areVotesAllCast (_disputeID)
599556 ) {
600557 revert VotePeriodNotPassed ();
601558 }
@@ -623,7 +580,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
623580 Round storage round = dispute.rounds[currentRound];
624581 if (dispute.period != Period.evidence) revert NotEvidencePeriod ();
625582
626- IDisputeKit disputeKit = disputeKitNodes [round.disputeKitID].disputeKit ;
583+ IDisputeKit disputeKit = disputeKits [round.disputeKitID];
627584
628585 uint256 startIndex = round.drawIterations; // for gas: less storage reads
629586 uint256 i;
@@ -654,7 +611,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
654611 if (dispute.period != Period.appeal) revert DisputeNotAppealable ();
655612
656613 Round storage round = dispute.rounds[dispute.rounds.length - 1 ];
657- if (msg .sender != address (disputeKitNodes [round.disputeKitID].disputeKit )) revert DisputeKitOnly ();
614+ if (msg .sender != address (disputeKits [round.disputeKitID])) revert DisputeKitOnly ();
658615
659616 uint96 newCourtID = dispute.courtID;
660617 uint256 newDisputeKitID = round.disputeKitID;
@@ -666,22 +623,9 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
666623 // Jump to parent court.
667624 newCourtID = courts[newCourtID].parent;
668625
669- for (uint256 i = 0 ; i < SEARCH_ITERATIONS; i++ ) {
670- if (courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {
671- break ;
672- } else if (disputeKitNodes[newDisputeKitID].parent != Constants.NULL_DISPUTE_KIT) {
673- newDisputeKitID = disputeKitNodes[newDisputeKitID].parent;
674- } else {
675- // DK's parent has 0 index, that means we reached the root DK (0 depth level).
676- // Jump to the next parent court if the current court doesn't support any DK from this tree.
677- // Note that we don't reset newDisputeKitID in this case as, a precaution.
678- newCourtID = courts[newCourtID].parent;
679- }
680- }
681- // We didn't find a court that is compatible with DK from this tree, so we jump directly to the top court.
682- // Note that this can only happen when disputeKitID is at its root, and each root DK is supported by the top court by default.
683626 if (! courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {
684- newCourtID = Constants.GENERAL_COURT;
627+ // Switch to classic dispute kit if parent court doesn't support the current one.
628+ newDisputeKitID = Constants.DISPUTE_KIT_CLASSIC;
685629 }
686630
687631 if (newCourtID != dispute.courtID) {
@@ -704,7 +648,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
704648 // Dispute kit was changed, so create a dispute in the new DK contract.
705649 if (extraRound.disputeKitID != round.disputeKitID) {
706650 emit DisputeKitJump (_disputeID, dispute.rounds.length - 1 , round.disputeKitID, extraRound.disputeKitID);
707- disputeKitNodes [extraRound.disputeKitID].disputeKit .createDispute (
651+ disputeKits [extraRound.disputeKitID].createDispute (
708652 _disputeID,
709653 _numberOfChoices,
710654 _extraData,
@@ -725,7 +669,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
725669 if (dispute.period != Period.execution) revert NotExecutionPeriod ();
726670
727671 Round storage round = dispute.rounds[_round];
728- IDisputeKit disputeKit = disputeKitNodes [round.disputeKitID].disputeKit ;
672+ IDisputeKit disputeKit = disputeKits [round.disputeKitID];
729673
730674 uint256 start = round.repartitions;
731675 uint256 end = round.repartitions + _iterations;
@@ -765,7 +709,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
765709 function _executePenalties (ExecuteParams memory _params ) internal returns (uint256 ) {
766710 Dispute storage dispute = disputes[_params.disputeID];
767711 Round storage round = dispute.rounds[_params.round];
768- IDisputeKit disputeKit = disputeKitNodes [round.disputeKitID].disputeKit ;
712+ IDisputeKit disputeKit = disputeKits [round.disputeKitID];
769713
770714 // [0, 1] value that determines how coherent the juror was in this round, in basis points.
771715 uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence (
@@ -833,7 +777,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
833777 function _executeRewards (ExecuteParams memory _params ) internal {
834778 Dispute storage dispute = disputes[_params.disputeID];
835779 Round storage round = dispute.rounds[_params.round];
836- IDisputeKit disputeKit = disputeKitNodes [round.disputeKitID].disputeKit ;
780+ IDisputeKit disputeKit = disputeKits [round.disputeKitID];
837781
838782 // [0, 1] value that determines how coherent the juror was in this round, in basis points.
839783 uint256 degreeOfCoherence = disputeKit.getDegreeOfCoherence (
@@ -988,7 +932,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
988932 function currentRuling (uint256 _disputeID ) public view returns (uint256 ruling , bool tied , bool overridden ) {
989933 Dispute storage dispute = disputes[_disputeID];
990934 Round storage round = dispute.rounds[dispute.rounds.length - 1 ];
991- IDisputeKit disputeKit = disputeKitNodes [round.disputeKitID].disputeKit ;
935+ IDisputeKit disputeKit = disputeKits [round.disputeKitID];
992936 (ruling, tied, overridden) = disputeKit.currentRuling (_disputeID);
993937 }
994938
@@ -1015,13 +959,6 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
1015959 return courts[_courtID].supportedDisputeKits[_disputeKitID];
1016960 }
1017961
1018- /// @dev Gets non-primitive properties of a specified dispute kit node.
1019- /// @param _disputeKitID The ID of the dispute kit.
1020- /// @return children Indexes of children of this DK.
1021- function getDisputeKitChildren (uint256 _disputeKitID ) external view returns (uint256 [] memory ) {
1022- return disputeKitNodes[_disputeKitID].children;
1023- }
1024-
1025962 /// @dev Gets the timesPerPeriod array for a given court.
1026963 /// @param _courtID The ID of the court to get the times from.
1027964 /// @return timesPerPeriod The timesPerPeriod array for the given court.
@@ -1056,14 +993,8 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
1056993 return ! courts[court.parent].supportedDisputeKits[round.disputeKitID];
1057994 }
1058995
1059- function getDisputeKitNodesLength () external view returns (uint256 ) {
1060- return disputeKitNodes.length ;
1061- }
1062-
1063- /// @dev Gets the dispute kit for a specific `_disputeKitID`.
1064- /// @param _disputeKitID The ID of the dispute kit.
1065- function getDisputeKit (uint256 _disputeKitID ) external view returns (IDisputeKit) {
1066- return disputeKitNodes[_disputeKitID].disputeKit;
996+ function getDisputeKitsLength () external view returns (uint256 ) {
997+ return disputeKits.length ;
1067998 }
1068999
10691000 /// @dev Gets the court identifiers where a specific `_juror` has staked.
@@ -1083,7 +1014,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
10831014 /// @dev Toggles the dispute kit support for a given court.
10841015 /// @param _courtID The ID of the court to toggle the support for.
10851016 /// @param _disputeKitID The ID of the dispute kit to toggle the support for.
1086- /// @param _enable Whether to enable or disable the support.
1017+ /// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.
10871018 function _enableDisputeKit (uint96 _courtID , uint256 _disputeKitID , bool _enable ) internal {
10881019 courts[_courtID].supportedDisputeKits[_disputeKitID] = _enable;
10891020 emit DisputeKitEnabled (_courtID, _disputeKitID, _enable);
@@ -1197,7 +1128,7 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
11971128 if (minJurors == 0 ) {
11981129 minJurors = Constants.DEFAULT_NB_OF_JURORS;
11991130 }
1200- if (disputeKitID == Constants.NULL_DISPUTE_KIT || disputeKitID >= disputeKitNodes .length ) {
1131+ if (disputeKitID == Constants.NULL_DISPUTE_KIT || disputeKitID >= disputeKits .length ) {
12011132 disputeKitID = Constants.DISPUTE_KIT_CLASSIC; // 0 index is not used.
12021133 }
12031134 } else {
@@ -1219,12 +1150,13 @@ contract KlerosCore is IArbitratorV2, UUPSProxiable, Initializable {
12191150 error UnsupportedDisputeKit ();
12201151 error InvalidForkingCourtAsParent ();
12211152 error WrongDisputeKitIndex ();
1222- error CannotDisableRootDKInGeneral ();
1153+ error CannotDisableClassicDK ();
12231154 error ArraysLengthMismatch ();
12241155 error StakingFailed ();
12251156 error WrongCaller ();
12261157 error ArbitrationFeesNotEnough ();
12271158 error DisputeKitNotSupportedByCourt ();
1159+ error MustSupportDisputeKitClassic ();
12281160 error TokenNotAccepted ();
12291161 error EvidenceNotPassedAndNotAppeal ();
12301162 error DisputeStillDrawing ();
0 commit comments