Skip to content

Commit 068df77

Browse files
authored
Merge pull request #2114 from kleros/feat/dk-jump
KlerosCore to allow jumping to a non-classic DK
2 parents a7cfba0 + 1ba64db commit 068df77

15 files changed

+258
-50
lines changed

contracts/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ The format is based on [Common Changelog](https://common-changelog.org/).
1616
- **Breaking:** Apply the penalties to the stakes in the Sortition Tree ([#2107](https://github.com/kleros/kleros-v2/issues/2107))
1717
- **Breaking:** Make `SortitionModule.getJurorBalance().stakedInCourt` include the penalties ([#2107](https://github.com/kleros/kleros-v2/issues/2107))
1818
- **Breaking:** Add a new field `drawnJurorFromCourtIDs` to the `Round` struct in `KlerosCoreBase` and `KlerosCoreUniversity` ([#2107](https://github.com/kleros/kleros-v2/issues/2107))
19+
- **Breaking:** Add a new state variable `jumpDisputeKitID` to the `DisputeKitClassicBase` contract ([#2114](https://github.com/kleros/kleros-v2/issues/2114))
1920
- Make `IDisputeKit.draw()` and `ISortitionModule.draw()` return the court ID from which the juror was drawn ([#2107](https://github.com/kleros/kleros-v2/issues/2107))
2021
- Rename `SortitionModule.setJurorInactive()` to `SortitionModule.forcedUnstakeAllCourts()` ([#2107](https://github.com/kleros/kleros-v2/issues/2107))
2122
- Allow stake changes to by-pass delayed stakes when initiated by the SortitionModule by setting the `_noDelay` parameter to `true` in `SortitionModule.validateStake()` ([#2107](https://github.com/kleros/kleros-v2/issues/2107))
@@ -35,6 +36,7 @@ The format is based on [Common Changelog](https://common-changelog.org/).
3536
### Added
3637

3738
- Allow the dispute kits to force an early court jump and to override the number of votes after an appeal (future-proofing) ([#2110](https://github.com/kleros/kleros-v2/issues/2110))
39+
- Allow the dispute kits to specify which new dispute kit to use when a court jump occurs ([#2114](https://github.com/kleros/kleros-v2/issues/2114))
3840

3941
### Fixed
4042

contracts/deploy/00-home-chain-arbitration-neo.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
2828

2929
await deployUpgradable(deployments, "EvidenceModule", { from: deployer, args: [deployer], log: true });
3030

31+
const classicDisputeKitID = 1; // Classic DK
3132
const disputeKit = await deployUpgradable(deployments, "DisputeKitClassicNeo", {
3233
from: deployer,
3334
contract: "DisputeKitClassic",
34-
args: [deployer, ZeroAddress, weth.target],
35+
args: [deployer, ZeroAddress, weth.target, classicDisputeKitID],
3536
log: true,
3637
});
3738

@@ -124,24 +125,27 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
124125
// Extra dispute kits
125126
const disputeKitShutter = await deployUpgradable(deployments, "DisputeKitShutter", {
126127
from: deployer,
127-
args: [deployer, core.target, weth.target],
128+
args: [deployer, core.target, weth.target, classicDisputeKitID],
128129
log: true,
129130
});
130131
await core.addNewDisputeKit(disputeKitShutter.address);
132+
const disputeKitShutterID = (await core.getDisputeKitsLength()) - 1n;
131133

132134
const disputeKitGated = await deployUpgradable(deployments, "DisputeKitGated", {
133135
from: deployer,
134-
args: [deployer, core.target, weth.target],
136+
args: [deployer, core.target, weth.target, classicDisputeKitID],
135137
log: true,
136138
});
137139
await core.addNewDisputeKit(disputeKitGated.address);
140+
const disputeKitGatedID = (await core.getDisputeKitsLength()) - 1n;
138141

139142
const disputeKitGatedShutter = await deployUpgradable(deployments, "DisputeKitGatedShutter", {
140143
from: deployer,
141-
args: [deployer, core.target, weth.target],
144+
args: [deployer, core.target, weth.target, disputeKitShutterID], // Does not jump to DKClassic
142145
log: true,
143146
});
144147
await core.addNewDisputeKit(disputeKitGatedShutter.address);
148+
const disputeKitGatedShutterID = (await core.getDisputeKitsLength()) - 1n;
145149

146150
// Snapshot proxy
147151
await deploy("KlerosCoreSnapshotProxy", {

contracts/deploy/00-home-chain-arbitration.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
3434
log: true,
3535
});
3636

37+
const classicDisputeKitID = 1; // Classic DK
3738
const disputeKit = await deployUpgradable(deployments, "DisputeKitClassic", {
3839
from: deployer,
39-
args: [deployer, ZeroAddress, weth.target],
40+
args: [deployer, ZeroAddress, weth.target, classicDisputeKitID],
4041
log: true,
4142
});
4243

@@ -105,27 +106,30 @@ const deployArbitration: DeployFunction = async (hre: HardhatRuntimeEnvironment)
105106
// Extra dispute kits
106107
const disputeKitShutter = await deployUpgradable(deployments, "DisputeKitShutter", {
107108
from: deployer,
108-
args: [deployer, core.target, weth.target],
109+
args: [deployer, core.target, weth.target, classicDisputeKitID],
109110
log: true,
110111
});
111112
await core.addNewDisputeKit(disputeKitShutter.address);
112-
await core.enableDisputeKits(Courts.GENERAL, [2], true); // enable disputeKitShutter on the General Court
113+
const disputeKitShutterID = (await core.getDisputeKitsLength()) - 1n;
114+
await core.enableDisputeKits(Courts.GENERAL, [disputeKitShutterID], true); // enable disputeKitShutter on the General Court
113115

114116
const disputeKitGated = await deployUpgradable(deployments, "DisputeKitGated", {
115117
from: deployer,
116-
args: [deployer, core.target, weth.target],
118+
args: [deployer, core.target, weth.target, classicDisputeKitID],
117119
log: true,
118120
});
119121
await core.addNewDisputeKit(disputeKitGated.address);
120-
await core.enableDisputeKits(Courts.GENERAL, [3], true); // enable disputeKitGated on the General Court
122+
const disputeKitGatedID = (await core.getDisputeKitsLength()) - 1n;
123+
await core.enableDisputeKits(Courts.GENERAL, [disputeKitGatedID], true); // enable disputeKitGated on the General Court
121124

122125
const disputeKitGatedShutter = await deployUpgradable(deployments, "DisputeKitGatedShutter", {
123126
from: deployer,
124-
args: [deployer, core.target, weth.target],
127+
args: [deployer, core.target, weth.target, disputeKitShutterID], // Does not jump to DKClassic
125128
log: true,
126129
});
127130
await core.addNewDisputeKit(disputeKitGatedShutter.address);
128-
await core.enableDisputeKits(Courts.GENERAL, [4], true); // enable disputeKitGatedShutter on the General Court
131+
const disputeKitGatedShutterID = (await core.getDisputeKitsLength()) - 1n;
132+
await core.enableDisputeKits(Courts.GENERAL, [disputeKitGatedShutterID], true); // enable disputeKitGatedShutter on the General Court
129133

130134
// Snapshot proxy
131135
await deploy("KlerosCoreSnapshotProxy", {

contracts/src/arbitration/KlerosCoreBase.sol

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,8 +1091,12 @@ abstract contract KlerosCoreBase is IArbitratorV2, Initializable, UUPSProxiable
10911091
courtJump = true;
10921092

10931093
if (!courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {
1094-
// Switch to classic dispute kit if parent court doesn't support the current one.
1095-
newDisputeKitID = DISPUTE_KIT_CLASSIC;
1094+
// The current Dispute Kit is not compatible with the new court, jump to another Dispute Kit.
1095+
newDisputeKitID = disputeKits[_round.disputeKitID].getJumpDisputeKitID();
1096+
if (newDisputeKitID == NULL_DISPUTE_KIT || !courts[newCourtID].supportedDisputeKits[newDisputeKitID]) {
1097+
// The new Dispute Kit is not defined or still not compatible, fall back to `DisputeKitClassic` which is always supported.
1098+
newDisputeKitID = DISPUTE_KIT_CLASSIC;
1099+
}
10961100
disputeKitJump = true;
10971101
}
10981102
}

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {DisputeKitClassicBase, KlerosCore} from "./DisputeKitClassicBase.sol";
1111
/// - an incentive system: equal split between coherent votes,
1212
/// - an appeal system: fund 2 choices only, vote on any choice.
1313
contract DisputeKitClassic is DisputeKitClassicBase {
14-
string public constant override version = "0.12.0";
14+
string public constant override version = "0.13.0";
1515

1616
// ************************************* //
1717
// * Constructor * //
@@ -26,12 +26,18 @@ contract DisputeKitClassic is DisputeKitClassicBase {
2626
/// @param _owner The owner's address.
2727
/// @param _core The KlerosCore arbitrator.
2828
/// @param _wNative The wrapped native token address, typically wETH.
29-
function initialize(address _owner, KlerosCore _core, address _wNative) external reinitializer(1) {
30-
__DisputeKitClassicBase_initialize(_owner, _core, _wNative);
29+
/// @param _jumpDisputeKitID The ID of the dispute kit to switch to after the court jump.
30+
function initialize(
31+
address _owner,
32+
KlerosCore _core,
33+
address _wNative,
34+
uint256 _jumpDisputeKitID
35+
) external reinitializer(1) {
36+
__DisputeKitClassicBase_initialize(_owner, _core, _wNative, _jumpDisputeKitID);
3137
}
3238

33-
function reinitialize(address _wNative) external reinitializer(9) {
34-
wNative = _wNative;
39+
function reinitialize(uint256 _jumpDisputeKitID) external reinitializer(10) {
40+
jumpDisputeKitID = _jumpDisputeKitID;
3541
}
3642

3743
// ************************ //

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {KlerosCore, KlerosCoreBase, IDisputeKit, ISortitionModule} from "../Kler
66
import {Initializable} from "../../proxy/Initializable.sol";
77
import {UUPSProxiable} from "../../proxy/UUPSProxiable.sol";
88
import {SafeSend} from "../../libraries/SafeSend.sol";
9-
import {ONE_BASIS_POINT} from "../../libraries/Constants.sol";
9+
import {ONE_BASIS_POINT, DISPUTE_KIT_CLASSIC} from "../../libraries/Constants.sol";
1010

1111
/// @title DisputeKitClassicBase
1212
/// Abstract Dispute kit classic implementation of the Kleros v1 features including:
@@ -68,6 +68,7 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi
6868
public alreadyDrawn; // True if the address has already been drawn, false by default. To be added to the Round struct when fully redeploying rather than upgrading.
6969
mapping(uint256 coreDisputeID => bool) public coreDisputeIDToActive; // True if this dispute kit is active for this core dispute ID.
7070
address public wNative; // The wrapped native token for safeSend().
71+
uint256 public jumpDisputeKitID; // The ID of the dispute kit in Kleros Core disputeKits array that the dispute should switch to after the court jump, in case the new court doesn't support this dispute kit.
7172

7273
// ************************************* //
7374
// * Events * //
@@ -147,14 +148,17 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi
147148
/// @param _owner The owner's address.
148149
/// @param _core The KlerosCore arbitrator.
149150
/// @param _wNative The wrapped native token address, typically wETH.
151+
/// @param _jumpDisputeKitID The ID of the dispute kit to switch to after the court jump.
150152
function __DisputeKitClassicBase_initialize(
151153
address _owner,
152154
KlerosCore _core,
153-
address _wNative
155+
address _wNative,
156+
uint256 _jumpDisputeKitID
154157
) internal onlyInitializing {
155158
owner = _owner;
156159
core = _core;
157160
wNative = _wNative;
161+
jumpDisputeKitID = _jumpDisputeKitID;
158162
}
159163

160164
// ************************ //
@@ -182,6 +186,12 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi
182186
core = KlerosCore(_core);
183187
}
184188

189+
/// @dev Changes the dispute kit ID used for the jump.
190+
/// @param _jumpDisputeKitID The new value for the `jumpDisputeKitID` storage variable.
191+
function changeJumpDisputeKitID(uint256 _jumpDisputeKitID) external onlyByOwner {
192+
jumpDisputeKitID = _jumpDisputeKitID;
193+
}
194+
185195
// ************************************* //
186196
// * State Modifiers * //
187197
// ************************************* //
@@ -637,6 +647,13 @@ abstract contract DisputeKitClassicBase is IDisputeKit, Initializable, UUPSProxi
637647
return (_currentNbVotes * 2) + 1;
638648
}
639649

650+
/// @dev Returns the dispute kid ID be used after court jump by Kleros Core.
651+
/// @return The ID of the dispute kit in Kleros Core disputeKits array.
652+
function getJumpDisputeKitID() external view override returns (uint256) {
653+
// Fall back to classic DK in case the jump ID is not defined.
654+
return jumpDisputeKitID == 0 ? DISPUTE_KIT_CLASSIC : jumpDisputeKitID;
655+
}
656+
640657
/// @dev Returns true if the specified voter was active in this round.
641658
/// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.
642659
/// @param _coreRoundID The ID of the round in Kleros Core, not in the Dispute Kit.

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ interface IBalanceHolderERC1155 {
2727
/// - an incentive system: equal split between coherent votes,
2828
/// - an appeal system: fund 2 choices only, vote on any choice.
2929
contract DisputeKitGated is DisputeKitClassicBase {
30-
string public constant override version = "0.12.0";
30+
string public constant override version = "0.13.0";
3131

3232
// ************************************* //
3333
// * Constructor * //
@@ -42,12 +42,18 @@ contract DisputeKitGated is DisputeKitClassicBase {
4242
/// @param _owner The owner's address.
4343
/// @param _core The KlerosCore arbitrator.
4444
/// @param _wNative The wrapped native token address, typically wETH.
45-
function initialize(address _owner, KlerosCore _core, address _wNative) external reinitializer(1) {
46-
__DisputeKitClassicBase_initialize(_owner, _core, _wNative);
45+
/// @param _jumpDisputeKitID The ID of the dispute kit to switch to after the court jump.
46+
function initialize(
47+
address _owner,
48+
KlerosCore _core,
49+
address _wNative,
50+
uint256 _jumpDisputeKitID
51+
) external reinitializer(1) {
52+
__DisputeKitClassicBase_initialize(_owner, _core, _wNative, _jumpDisputeKitID);
4753
}
4854

49-
function reinitialize(address _wNative) external reinitializer(9) {
50-
wNative = _wNative;
55+
function reinitialize(uint256 _jumpDisputeKitID) external reinitializer(10) {
56+
jumpDisputeKitID = _jumpDisputeKitID;
5157
}
5258

5359
// ************************ //

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ interface IBalanceHolderERC1155 {
2828
/// - an incentive system: equal split between coherent votes,
2929
/// - an appeal system: fund 2 choices only, vote on any choice.
3030
contract DisputeKitGatedShutter is DisputeKitClassicBase {
31-
string public constant override version = "0.12.0";
31+
string public constant override version = "0.13.0";
3232

3333
// ************************************* //
3434
// * Events * //
@@ -61,12 +61,18 @@ contract DisputeKitGatedShutter is DisputeKitClassicBase {
6161
/// @param _owner The owner's address.
6262
/// @param _core The KlerosCore arbitrator.
6363
/// @param _wNative The wrapped native token address, typically wETH.
64-
function initialize(address _owner, KlerosCore _core, address _wNative) external reinitializer(1) {
65-
__DisputeKitClassicBase_initialize(_owner, _core, _wNative);
64+
/// @param _jumpDisputeKitID The ID of the dispute kit to switch to after the court jump.
65+
function initialize(
66+
address _owner,
67+
KlerosCore _core,
68+
address _wNative,
69+
uint256 _jumpDisputeKitID
70+
) external reinitializer(1) {
71+
__DisputeKitClassicBase_initialize(_owner, _core, _wNative, _jumpDisputeKitID);
6672
}
6773

68-
function reinitialize(address _wNative) external reinitializer(9) {
69-
wNative = _wNative;
74+
function reinitialize(uint256 _jumpDisputeKitID) external reinitializer(10) {
75+
jumpDisputeKitID = _jumpDisputeKitID;
7076
}
7177

7278
// ************************ //

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {DisputeKitClassicBase, KlerosCore} from "./DisputeKitClassicBase.sol";
1212
/// - an incentive system: equal split between coherent votes,
1313
/// - an appeal system: fund 2 choices only, vote on any choice.
1414
contract DisputeKitShutter is DisputeKitClassicBase {
15-
string public constant override version = "0.12.0";
15+
string public constant override version = "0.13.0";
1616

1717
// ************************************* //
1818
// * Events * //
@@ -45,12 +45,18 @@ contract DisputeKitShutter is DisputeKitClassicBase {
4545
/// @param _owner The owner's address.
4646
/// @param _core The KlerosCore arbitrator.
4747
/// @param _wNative The wrapped native token address, typically wETH.
48-
function initialize(address _owner, KlerosCore _core, address _wNative) external reinitializer(1) {
49-
__DisputeKitClassicBase_initialize(_owner, _core, _wNative);
48+
/// @param _jumpDisputeKitID The ID of the dispute kit to switch to after the court jump.
49+
function initialize(
50+
address _owner,
51+
KlerosCore _core,
52+
address _wNative,
53+
uint256 _jumpDisputeKitID
54+
) external reinitializer(1) {
55+
__DisputeKitClassicBase_initialize(_owner, _core, _wNative, _jumpDisputeKitID);
5056
}
5157

52-
function reinitialize(address _wNative) external reinitializer(9) {
53-
wNative = _wNative;
58+
function reinitialize(uint256 _jumpDisputeKitID) external reinitializer(10) {
59+
jumpDisputeKitID = _jumpDisputeKitID;
5460
}
5561

5662
// ************************ //

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ interface IProofOfHumanity {
1818
/// - an incentive system: equal split between coherent votes,
1919
/// - an appeal system: fund 2 choices only, vote on any choice.
2020
contract DisputeKitSybilResistant is DisputeKitClassicBase {
21-
string public constant override version = "0.12.0";
21+
string public constant override version = "0.13.0";
2222

2323
// ************************************* //
2424
// * Storage * //
@@ -40,13 +40,15 @@ contract DisputeKitSybilResistant is DisputeKitClassicBase {
4040
/// @param _core The KlerosCore arbitrator.
4141
/// @param _poh The Proof of Humanity registry.
4242
/// @param _wNative The wrapped native token address, typically wETH.
43+
/// @param _jumpDisputeKitID The ID of the dispute kit to switch to after the court jump.
4344
function initialize(
4445
address _owner,
4546
KlerosCore _core,
4647
IProofOfHumanity _poh,
47-
address _wNative
48+
address _wNative,
49+
uint256 _jumpDisputeKitID
4850
) external reinitializer(1) {
49-
__DisputeKitClassicBase_initialize(_owner, _core, _wNative);
51+
__DisputeKitClassicBase_initialize(_owner, _core, _wNative, _jumpDisputeKitID);
5052
poh = _poh;
5153
singleDrawPerJuror = true;
5254
}

0 commit comments

Comments
 (0)