Skip to content

Commit 9093a58

Browse files
committed
feat: extracted CourtRegistry from KlerosCore (wip)
1 parent 41a5b77 commit 9093a58

File tree

3 files changed

+318
-164
lines changed

3 files changed

+318
-164
lines changed
Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
// SPDX-License-Identifier: MIT
2+
3+
pragma solidity ^0.8.24;
4+
5+
import {Initializable} from "../proxy/Initializable.sol";
6+
import {UUPSProxiable} from "../proxy/UUPSProxiable.sol";
7+
import "../libraries/Constants.sol";
8+
9+
// ************************************* //
10+
// * Enums / Structs * //
11+
// ************************************* //
12+
13+
struct Court {
14+
uint96 parent; // The parent court.
15+
bool hiddenVotes; // Whether to use commit and reveal or not.
16+
uint256[] children; // List of child courts.
17+
uint256 minStake; // Minimum PNKs needed to stake in the court.
18+
uint256 alpha; // Basis point of PNKs that are lost when incoherent.
19+
uint256 feeForJuror; // Arbitration fee paid per juror.
20+
uint256 jurorsForCourtJump; // The appeal after the one that reaches this number of jurors will go to the parent court if any.
21+
uint256[4] timesPerPeriod; // The time allotted to each dispute period in the form `timesPerPeriod[period]`.
22+
uint256[10] __gap; // Reserved slots for future upgrades.
23+
}
24+
25+
contract CourtRegistry is Initializable, UUPSProxiable {
26+
string public constant override version = "2.0.0";
27+
28+
// ************************************* //
29+
// * Storage * //
30+
// ************************************* //
31+
32+
address public owner; // The owner of the contract.
33+
address public core; // The core contract.
34+
Court[] public courts; // The courts.
35+
mapping(uint96 courtID => mapping(uint256 disputeKitId => bool)) supportedDisputeKits; // True if DK with this ID is supported by the court. Note that each court must support classic dispute kit.
36+
37+
// ************************************* //
38+
// * Events * //
39+
// ************************************* //
40+
41+
event CourtCreated(
42+
uint96 indexed _courtID,
43+
uint96 indexed _parent,
44+
bool _hiddenVotes,
45+
uint256 _minStake,
46+
uint256 _alpha,
47+
uint256 _feeForJuror,
48+
uint256 _jurorsForCourtJump,
49+
uint256[4] _timesPerPeriod,
50+
uint256[] _supportedDisputeKits
51+
);
52+
event CourtModified(
53+
uint96 indexed _courtID,
54+
bool _hiddenVotes,
55+
uint256 _minStake,
56+
uint256 _alpha,
57+
uint256 _feeForJuror,
58+
uint256 _jurorsForCourtJump,
59+
uint256[4] _timesPerPeriod
60+
);
61+
event DisputeKitEnabled(uint96 indexed _courtID, uint256 indexed _disputeKitID, bool indexed _enable);
62+
63+
// ************************************* //
64+
// * Function Modifiers * //
65+
// ************************************* //
66+
67+
modifier onlyByOwner() {
68+
if (owner != msg.sender) revert OwnerOnly();
69+
_;
70+
}
71+
72+
modifier onlyByCore() {
73+
if (address(core) != msg.sender) revert KlerosCoreOnly();
74+
_;
75+
}
76+
77+
// ************************************* //
78+
// * Constructor * //
79+
// ************************************* //
80+
81+
/// @custom:oz-upgrades-unsafe-allow constructor
82+
constructor() {
83+
_disableInitializers();
84+
}
85+
86+
/// @dev Initializer (constructor equivalent for upgradable contracts).
87+
/// @param _owner The owner's address.
88+
/// @param _core The core contract.
89+
function initialize(address _owner, address _core) external initializer {
90+
owner = _owner;
91+
core = _core;
92+
93+
// FORKING_COURT
94+
// TODO: Fill the properties for the Forking court, emit CourtCreated.
95+
courts.push();
96+
}
97+
98+
// ************************************* //
99+
// * Governance * //
100+
// ************************************* //
101+
102+
/// @dev Access Control to perform implementation upgrades (UUPS Proxiable)
103+
function _authorizeUpgrade(address) internal view override onlyByOwner {
104+
// NOP
105+
}
106+
107+
// ************************************* //
108+
// * State Modifiers * //
109+
// ************************************* //
110+
111+
/// @dev Creates a court under a specified parent court.
112+
/// @param _parent The `parent` property value of the court.
113+
/// @param _hiddenVotes The `hiddenVotes` property value of the court.
114+
/// @param _minStake The `minStake` property value of the court.
115+
/// @param _alpha The `alpha` property value of the court.
116+
/// @param _feeForJuror The `feeForJuror` property value of the court.
117+
/// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.
118+
/// @param _timesPerPeriod The `timesPerPeriod` property value of the court.
119+
/// @param _supportedDisputeKits Indexes of dispute kits that this court will support.
120+
function createCourt(
121+
uint96 _parent,
122+
bool _hiddenVotes,
123+
uint256 _minStake,
124+
uint256 _alpha,
125+
uint256 _feeForJuror,
126+
uint256 _jurorsForCourtJump,
127+
uint256[4] memory _timesPerPeriod,
128+
uint256[] memory _supportedDisputeKits
129+
) external onlyByCore returns (uint96 courtID) {
130+
if (courts[_parent].minStake > _minStake) revert MinStakeLowerThanParentCourt();
131+
if (_supportedDisputeKits.length == 0) revert UnsupportedDisputeKit();
132+
if (_parent == FORKING_COURT) revert InvalidForkingCourtAsParent();
133+
134+
courtID = uint96(courts.length);
135+
Court storage court = courts.push();
136+
137+
// Check that Classic DK support was added.
138+
if (!supportedDisputeKits[courtID][DISPUTE_KIT_CLASSIC]) revert MustSupportDisputeKitClassic();
139+
140+
court.parent = _parent;
141+
court.children = new uint256[](0);
142+
court.hiddenVotes = _hiddenVotes;
143+
court.minStake = _minStake;
144+
court.alpha = _alpha;
145+
court.feeForJuror = _feeForJuror;
146+
court.jurorsForCourtJump = _jurorsForCourtJump;
147+
court.timesPerPeriod = _timesPerPeriod;
148+
149+
// Update the parent.
150+
courts[_parent].children.push(courtID);
151+
emit CourtCreated(
152+
uint96(courtID),
153+
_parent,
154+
_hiddenVotes,
155+
_minStake,
156+
_alpha,
157+
_feeForJuror,
158+
_jurorsForCourtJump,
159+
_timesPerPeriod,
160+
_supportedDisputeKits
161+
);
162+
}
163+
164+
/// @notice Changes the parameters of the court.
165+
/// @param _courtID ID of the court.
166+
/// @param _hiddenVotes The `hiddenVotes` property value of the court.
167+
/// @param _minStake The `minStake` property value of the court.
168+
/// @param _alpha The `alpha` property value of the court.
169+
/// @param _feeForJuror The `feeForJuror` property value of the court.
170+
/// @param _jurorsForCourtJump The `jurorsForCourtJump` property value of the court.
171+
/// @param _timesPerPeriod The `timesPerPeriod` property value of the court.
172+
function changeCourtParameters(
173+
uint96 _courtID,
174+
bool _hiddenVotes,
175+
uint256 _minStake,
176+
uint256 _alpha,
177+
uint256 _feeForJuror,
178+
uint256 _jurorsForCourtJump,
179+
uint256[4] memory _timesPerPeriod
180+
) external onlyByCore {
181+
Court storage court = courts[_courtID];
182+
if (_courtID != GENERAL_COURT && courts[court.parent].minStake > _minStake) {
183+
revert MinStakeLowerThanParentCourt();
184+
}
185+
for (uint256 i = 0; i < court.children.length; i++) {
186+
if (courts[court.children[i]].minStake < _minStake) {
187+
revert MinStakeLowerThanParentCourt();
188+
}
189+
}
190+
court.minStake = _minStake;
191+
court.hiddenVotes = _hiddenVotes;
192+
court.alpha = _alpha;
193+
court.feeForJuror = _feeForJuror;
194+
court.jurorsForCourtJump = _jurorsForCourtJump;
195+
court.timesPerPeriod = _timesPerPeriod;
196+
emit CourtModified(
197+
_courtID,
198+
_hiddenVotes,
199+
_minStake,
200+
_alpha,
201+
_feeForJuror,
202+
_jurorsForCourtJump,
203+
_timesPerPeriod
204+
);
205+
}
206+
207+
/// @notice Toggles the dispute kit support for a given court.
208+
/// @param _courtID The ID of the court to toggle the support for.
209+
/// @param _disputeKitID The ID of the dispute kit to toggle the support for.
210+
/// @param _enable Whether to enable or disable the support. Note that classic dispute kit should always be enabled.
211+
function enableDisputeKit(uint96 _courtID, uint256 _disputeKitID, bool _enable) external onlyByCore {
212+
supportedDisputeKits[_courtID][_disputeKitID] = _enable;
213+
emit DisputeKitEnabled(_courtID, _disputeKitID, _enable);
214+
}
215+
216+
// ************************************* //
217+
// * Public Views * //
218+
// ************************************* //
219+
220+
/// @dev Gets a court by its ID.
221+
/// @param _courtID The ID of the court to get.
222+
/// @return The court.
223+
function get(uint96 _courtID) external view returns (Court memory) {
224+
return courts[_courtID];
225+
}
226+
227+
/// @dev Gets the children of a given court.
228+
/// @param _courtID The ID of the court to get the children from.
229+
/// @return children The children of the given court.
230+
function getChildren(uint96 _courtID) external view returns (uint256[] memory) {
231+
return courts[_courtID].children;
232+
}
233+
234+
/// @notice Gets the timesPerPeriod array for a given court.
235+
/// @param _courtID The ID of the court to get the times from.
236+
/// @return timesPerPeriod The timesPerPeriod array for the given court.
237+
function getTimesPerPeriod(uint96 _courtID) external view returns (uint256[4] memory) {
238+
return courts[_courtID].timesPerPeriod;
239+
}
240+
241+
/// @notice Checks if a given dispute kit is supported by a given court.
242+
/// @param _courtID The ID of the court to check the support for.
243+
/// @param _disputeKitID The ID of the dispute kit to check the support for.
244+
/// @return Whether the dispute kit is supported or not.
245+
function isSupported(uint96 _courtID, uint256 _disputeKitID) external view returns (bool) {
246+
return supportedDisputeKits[_courtID][_disputeKitID];
247+
}
248+
249+
/// @dev Gets the number of courts.
250+
/// @return The number of courts.
251+
function getNumberOfCourts() external view returns (uint256) {
252+
return courts.length;
253+
}
254+
255+
// ************************************* //
256+
// * Errors * //
257+
// ************************************* //
258+
259+
error OwnerOnly();
260+
error KlerosCoreOnly();
261+
error MinStakeLowerThanParentCourt();
262+
error UnsupportedDisputeKit();
263+
error InvalidForkingCourtAsParent();
264+
error MustSupportDisputeKitClassic();
265+
}

0 commit comments

Comments
 (0)