Skip to content

Commit

Permalink
Merge pull request #25 from kleros/feat/dispute-kit-interface
Browse files Browse the repository at this point in the history
feat(DisputeKit): Dispute Kits abstraction for interfacing with KlerosCore
  • Loading branch information
jaybuidl authored Jan 20, 2022
2 parents 0c2a9a0 + 429d9d9 commit b7f13c1
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 154 deletions.
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

0 comments on commit b7f13c1

Please sign in to comment.