From 87bc6c0a1a71b1124e42339a46d3a539c364f4ab Mon Sep 17 00:00:00 2001 From: unknownunknown1 Date: Wed, 17 Jul 2024 19:14:51 +1000 Subject: [PATCH 1/2] feat(DisputeKit): add flushing feature --- contracts/src/arbitration/KlerosCoreBase.sol | 4 ++++ .../dispute-kits/DisputeKitSybilResistant.sol | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/contracts/src/arbitration/KlerosCoreBase.sol b/contracts/src/arbitration/KlerosCoreBase.sol index ce6ed6202..c1cce81d6 100644 --- a/contracts/src/arbitration/KlerosCoreBase.sol +++ b/contracts/src/arbitration/KlerosCoreBase.sol @@ -101,6 +101,7 @@ abstract contract KlerosCoreBase is IArbitratorV2 { Court[] public courts; // The courts. IDisputeKit[] public disputeKits; // Array of dispute kits. Dispute[] public disputes; // The disputes. + mapping(IDisputeKit => uint256) public disputeKitIDs; // Maps dispute kit's address to its index. mapping(IERC20 => CurrencyRate) public currencyRates; // The price of each token in ETH. bool public paused; // Whether asset withdrawals are paused. @@ -216,6 +217,7 @@ abstract contract KlerosCoreBase is IArbitratorV2 { // DISPUTE_KIT_CLASSIC disputeKits.push(_disputeKit); + disputeKitIDs[_disputeKit] = DISPUTE_KIT_CLASSIC; emit DisputeKitCreated(DISPUTE_KIT_CLASSIC, _disputeKit); @@ -316,6 +318,7 @@ abstract contract KlerosCoreBase is IArbitratorV2 { function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor { uint256 disputeKitID = disputeKits.length; disputeKits.push(_disputeKitAddress); + disputeKitIDs[_disputeKitAddress] = disputeKitID; emit DisputeKitCreated(disputeKitID, _disputeKitAddress); } @@ -479,6 +482,7 @@ abstract contract KlerosCoreBase is IArbitratorV2 { uint256 _newStake, bool _alreadyTransferred ) external { + // TODO: generalize this function so it can be used by DK too. Rename to setStakeWhitelist or something. So it can be done for someone not just for sender. if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly(); _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return); } diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol b/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol index 40b805c05..f20986c4d 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol @@ -465,6 +465,21 @@ contract DisputeKitSybilResistant is IDisputeKit, Initializable, UUPSProxiable { } } + /// @dev Unstakes the jurors who are not eligible for drawing, so they don't interfere with the drawing process. + /// Can be called by anyone. The juror will be unstaked if he doesn't pass the check specific to this DK. + /// @param _juror The juror to unstake. + /// @param _courts The courts to unstake from. Note that each court must support this DK. + function flush(address _juror, uint96[] memory _courts) external { + require(!_proofOfHumanity(_juror), "The juror is eligible"); + uint256 disputeKitID = core.disputeKitIDs(this); + for (uint256 i = 0; i < _courts.length; i++) { + uint96 courtID = _courts[i]; + require(core.isSupported(courtID, disputeKitID), "DK not supported by court"); + // TODO: generalize the function name and its permission. + core.setStakeBySortitionModule(_juror, courtID, 0, false); + } + } + // ************************************* // // * Public Views * // // ************************************* // From 748c9b0a551bae9a395b0f4531b3e8da61ebee8f Mon Sep 17 00:00:00 2001 From: unknownunknown1 Date: Wed, 31 Jul 2024 18:51:15 +1000 Subject: [PATCH 2/2] feat(DK): add permission for flushing --- contracts/src/arbitration/KlerosCoreBase.sol | 10 +++++----- contracts/src/arbitration/SortitionModuleBase.sol | 4 ++-- .../dispute-kits/DisputeKitSybilResistant.sol | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/contracts/src/arbitration/KlerosCoreBase.sol b/contracts/src/arbitration/KlerosCoreBase.sol index c1cce81d6..ce1e60d03 100644 --- a/contracts/src/arbitration/KlerosCoreBase.sol +++ b/contracts/src/arbitration/KlerosCoreBase.sol @@ -471,19 +471,19 @@ abstract contract KlerosCoreBase is IArbitratorV2 { _setStake(msg.sender, _courtID, _newStake, false, OnError.Revert); } - /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive jurors. + /// @dev Sets the stake of a specified account in a court, typically to apply a delayed stake or unstake inactive/ineligible jurors. /// @param _account The account whose stake is being set. /// @param _courtID The ID of the court. /// @param _newStake The new stake. /// @param _alreadyTransferred Whether the PNKs have already been transferred to the contract. - function setStakeBySortitionModule( + function setStakeBySortitionModuleOrDK( address _account, uint96 _courtID, uint256 _newStake, bool _alreadyTransferred ) external { - // TODO: generalize this function so it can be used by DK too. Rename to setStakeWhitelist or something. So it can be done for someone not just for sender. - if (msg.sender != address(sortitionModule)) revert SortitionModuleOnly(); + if (msg.sender != address(sortitionModule) && disputeKitIDs[IDisputeKit(msg.sender)] == 0) + revert SortitionModuleOrDKOnly(); _setStake(_account, _courtID, _newStake, _alreadyTransferred, OnError.Return); } @@ -1148,7 +1148,7 @@ abstract contract KlerosCoreBase is IArbitratorV2 { error GovernorOnly(); error GuardianOrGovernorOnly(); error DisputeKitOnly(); - error SortitionModuleOnly(); + error SortitionModuleOrDKOnly(); error UnsuccessfulCall(); error InvalidDisputKitParent(); error DepthLevelMax(); diff --git a/contracts/src/arbitration/SortitionModuleBase.sol b/contracts/src/arbitration/SortitionModuleBase.sol index 24e32e6ea..8872f90dc 100644 --- a/contracts/src/arbitration/SortitionModuleBase.sol +++ b/contracts/src/arbitration/SortitionModuleBase.sol @@ -206,7 +206,7 @@ abstract contract SortitionModuleBase is ISortitionModule { DelayedStake storage delayedStake = delayedStakes[i]; // Delayed stake could've been manually removed already. In this case simply move on to the next item. if (delayedStake.account != address(0)) { - core.setStakeBySortitionModule( + core.setStakeBySortitionModuleOrDK( delayedStake.account, delayedStake.courtID, delayedStake.stake, @@ -433,7 +433,7 @@ abstract contract SortitionModuleBase is ISortitionModule { function setJurorInactive(address _account) external override onlyByCore { uint96[] memory courtIDs = getJurorCourtIDs(_account); for (uint256 j = courtIDs.length; j > 0; j--) { - core.setStakeBySortitionModule(_account, courtIDs[j - 1], 0, false); + core.setStakeBySortitionModuleOrDK(_account, courtIDs[j - 1], 0, false); } } diff --git a/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol b/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol index f20986c4d..d61d9fc41 100644 --- a/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol +++ b/contracts/src/arbitration/dispute-kits/DisputeKitSybilResistant.sol @@ -475,8 +475,7 @@ contract DisputeKitSybilResistant is IDisputeKit, Initializable, UUPSProxiable { for (uint256 i = 0; i < _courts.length; i++) { uint96 courtID = _courts[i]; require(core.isSupported(courtID, disputeKitID), "DK not supported by court"); - // TODO: generalize the function name and its permission. - core.setStakeBySortitionModule(_juror, courtID, 0, false); + core.setStakeBySortitionModuleOrDK(_juror, courtID, 0, false); } }