Skip to content

feat(DisputeKit): Dispute Kits abstraction for interfacing with KlerosCore #25

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@

pragma solidity ^0.8;

import "../IArbitrator.sol";
import "./IArbitrator.sol";

/**
* @title DisputeKit
* Dispute kit abstraction for Kleros v2.
* An abstraction of the Dispute Kits intended for interfacing with KlerosCore
* This is not intended for use by the front-end clients for voting or appeal funding to allow for implementation-specific differences in parameters.
*/
abstract contract DisputeKit {
interface IDisputeKit {
// ************************************* //
// * State Modifiers * //
// ************************************* //
Expand All @@ -31,63 +32,14 @@ abstract contract DisputeKit {
uint256 _disputeID,
uint256 _numberOfChoices,
bytes calldata _extraData
) external virtual;
) external;

/** @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.
* Note: Access restricted to Kleros Core only.
* @param _disputeID The ID of the dispute in Kleros Core.
* @return drawnAddress The drawn address.
*/
function draw(uint256 _disputeID) external virtual returns (address drawnAddress);

/** @dev Sets the caller's commit for the specified votes.
* `O(n)` where
* `n` is the number of votes.
* @param _disputeID The ID of the dispute.
* @param _voteIDs The IDs of the votes.
* @param _commit The commit.
*/
function castCommit(
uint256 _disputeID,
uint256[] calldata _voteIDs,
bytes32 _commit
) external virtual;

/** @dev Sets the caller's choices for the specified votes.
* `O(n)` where
* `n` is the number of votes.
* @param _disputeID The ID of the dispute.
* @param _voteIDs The IDs of the votes.
* @param _choice The choice.
* @param _salt The salt for the commit if the votes were hidden.
*/
function castVote(
uint256 _disputeID,
uint256[] calldata _voteIDs,
uint256 _choice,
uint256 _salt
) external virtual;

/** @dev Manages contributions, and appeals a dispute if at least two choices are fully funded.
* Note that the surplus deposit will be reimbursed.
* @param _disputeID Index of the dispute in Kleros Core contract.
* @param _choice A choice that receives funding.
*/
function fundAppeal(uint256 _disputeID, uint256 _choice) external payable virtual;

/** @dev Allows to withdraw any reimbursable fees or rewards after the dispute gets resolved.
* @param _disputeID Index of the dispute in Kleros Core contract.
* @param _beneficiary The address whose rewards to withdraw.
* @param _round The round the caller wants to withdraw from.
* @param _choice The ruling option that the caller wants to withdraw from.
* @return amount The withdrawn amount.
*/
function withdrawFeesAndRewards(
uint256 _disputeID,
address payable _beneficiary,
uint256 _round,
uint256 _choice
) external virtual returns (uint256 amount);
function draw(uint256 _disputeID) external returns (address drawnAddress);

// ************************************* //
// * Public Views * //
Expand All @@ -97,7 +49,7 @@ abstract contract DisputeKit {
* @param _disputeID The ID of the dispute in Kleros Core.
* @return ruling The current ruling.
*/
function currentRuling(uint256 _disputeID) public view virtual returns (uint256 ruling);
function currentRuling(uint256 _disputeID) external view returns (uint256 ruling);

/** @dev Gets the degree of coherence of a particular voter. This function is called by Kleros Core in order to determine the amount of the reward.
* @param _disputeID The ID of the dispute in Kleros Core.
Expand All @@ -109,14 +61,14 @@ abstract contract DisputeKit {
uint256 _disputeID,
uint256 _round,
uint256 _voteID
) external view virtual returns (uint256);
) external view returns (uint256);

/** @dev Gets the number of jurors who are eligible to a reward in this round.
* @param _disputeID The ID of the dispute in Kleros Core.
* @param _round The ID of the round.
* @return The number of coherent jurors.
*/
function getCoherentCount(uint256 _disputeID, uint256 _round) external view virtual returns (uint256);
function getCoherentCount(uint256 _disputeID, uint256 _round) external view returns (uint256);

/** @dev Returns true if the specified voter was active in this round.
* @param _disputeID The ID of the dispute in Kleros Core.
Expand All @@ -128,7 +80,7 @@ abstract contract DisputeKit {
uint256 _disputeID,
uint256 _round,
uint256 _voteID
) external view virtual returns (bool);
) external view returns (bool);

function getRoundInfo(
uint256 _disputeID,
Expand All @@ -137,7 +89,6 @@ abstract contract DisputeKit {
)
external
view
virtual
returns (
uint256 winningChoice,
bool tied,
Expand All @@ -154,7 +105,6 @@ abstract contract DisputeKit {
)
external
view
virtual
returns (
address account,
bytes32 commit,
Expand Down
16 changes: 8 additions & 8 deletions contracts/src/arbitration/KlerosCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pragma solidity ^0.8;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./IArbitrator.sol";
import "./dispute-kits/DisputeKit.sol";
import "./IDisputeKit.sol";
import {SortitionSumTreeFactory} from "../data-structures/SortitionSumTreeFactory.sol";

/**
Expand Down Expand Up @@ -49,7 +49,7 @@ contract KlerosCore is IArbitrator {
struct Dispute {
uint96 subcourtID; // The ID of the subcourt the dispute is in.
IArbitrable arbitrated; // The arbitrable contract.
DisputeKit disputeKit; // ID of the dispute kit that this dispute was assigned to.
IDisputeKit disputeKit; // ID of the dispute kit that this dispute was assigned to.
Period period; // The current period of the dispute.
bool ruled; // True if the ruling has been executed, false otherwise.
uint256 currentRound; // The index of the current appeal round. Note that 0 represents the default dispute round. Former votes.length - 1.
Expand Down Expand Up @@ -90,7 +90,7 @@ contract KlerosCore is IArbitrator {
Court[] public courts; // The subcourts.

//TODO: disputeKits forest.
DisputeKit[] public disputeKits; // All supported dispute kits.
IDisputeKit[] public disputeKits; // All supported dispute kits.

Dispute[] public disputes; // The disputes.
mapping(address => Juror) internal jurors; // The jurors.
Expand Down Expand Up @@ -138,7 +138,7 @@ contract KlerosCore is IArbitrator {
address _governor,
IERC20 _pinakion,
address _jurorProsecutionModule,
DisputeKit _disputeKit,
IDisputeKit _disputeKit,
bool _hiddenVotes,
uint256 _minStake,
uint256 _alpha,
Expand Down Expand Up @@ -211,7 +211,7 @@ contract KlerosCore is IArbitrator {
/** @dev Add a new supported dispute kit module to the court.
* @param _disputeKitAddress The address of the dispute kit contract.
*/
function addNewDisputeKit(DisputeKit _disputeKitAddress) external onlyByGovernor {
function addNewDisputeKit(IDisputeKit _disputeKitAddress) external onlyByGovernor {
// TODO: the dispute kit data structure. For now keep it a simple array.
// Also note that in current state this function doesn't take into account that the added address is actually new.
require(disputeKits.length <= 256); // Can't be more than 256 because the IDs are used in a bitfield.
Expand Down Expand Up @@ -375,7 +375,7 @@ contract KlerosCore is IArbitrator {
dispute.subcourtID = subcourtID;
dispute.arbitrated = IArbitrable(msg.sender);

DisputeKit disputeKit = disputeKits[disputeKitID];
IDisputeKit disputeKit = disputeKits[disputeKitID];
dispute.disputeKit = disputeKit;

dispute.lastPeriodChange = block.timestamp;
Expand Down Expand Up @@ -449,7 +449,7 @@ contract KlerosCore is IArbitrator {
function draw(uint256 _disputeID, uint256 _iterations) external {
Dispute storage dispute = disputes[_disputeID];
require(dispute.period == Period.evidence, "Should be evidence period.");
DisputeKit disputeKit = dispute.disputeKit;
IDisputeKit disputeKit = dispute.disputeKit;
uint256 startIndex = dispute.drawnJurors[dispute.currentRound].length;
uint256 endIndex = startIndex + _iterations <= dispute.nbVotes ? startIndex + _iterations : dispute.nbVotes;

Expand Down Expand Up @@ -652,7 +652,7 @@ contract KlerosCore is IArbitrator {
* @return ruling The current ruling.
*/
function currentRuling(uint256 _disputeID) public view returns (uint256 ruling) {
DisputeKit disputeKit = disputes[_disputeID].disputeKit;
IDisputeKit disputeKit = disputes[_disputeID].disputeKit;
return disputeKit.currentRuling(_disputeID);
}

Expand Down
68 changes: 68 additions & 0 deletions contracts/src/arbitration/dispute-kits/BaseDisputeKit.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: MIT

/**
* @authors: [@unknownunknown1, @jaybuidl]
* @reviewers: []
* @auditors: []
* @bounties: []
* @deployments: []
*/

pragma solidity ^0.8;

import "../IDisputeKit.sol";
import "../KlerosCore.sol";

/**
* @title BaseDisputeKit
* Provides common basic behaviours to the Dispute Kit implementations.
*/
abstract contract BaseDisputeKit is IDisputeKit {
// ************************************* //
// * Storage * //
// ************************************* //

address public governor; // The governor of the contract.
KlerosCore public core; // The Kleros Core arbitrator

// ************************************* //
// * Function Modifiers * //
// ************************************* //

modifier onlyByGovernor() {
require(governor == msg.sender, "Access not allowed: Governor only.");
_;
}

modifier onlyByCore() {
require(address(core) == msg.sender, "Access not allowed: KlerosCore only.");
_;
}

/** @dev Constructor.
* @param _governor The governor's address.
* @param _core The KlerosCore arbitrator.
*/
constructor(address _governor, KlerosCore _core) {
governor = _governor;
core = _core;
}

// ************************ //
// * Governance * //
// ************************ //

/** @dev Allows the governor to call anything on behalf of the contract.
* @param _destination The destination of the call.
* @param _amount The value sent with the call.
* @param _data The data sent with the call.
*/
function executeGovernorProposal(
address _destination,
uint256 _amount,
bytes memory _data
) external onlyByGovernor {
(bool success, ) = _destination.call{value: _amount}(_data);
require(success, "Unsuccessful call");
}
}
Loading