Skip to content
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

Refactor: no coupling between dispute kit and sortition (WIP) #1621

Draft
wants to merge 4 commits into
base: dev
Choose a base branch
from
Draft
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
20 changes: 19 additions & 1 deletion contracts/src/arbitration/KlerosCoreBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ abstract contract KlerosCoreBase is IArbitratorV2 {
uint256 startIndex = round.drawIterations; // for gas: less storage reads
uint256 i;
while (i < _iterations && round.drawnJurors.length < round.nbVotes) {
address drawnAddress = disputeKit.draw(_disputeID, startIndex + i++);
address drawnAddress = disputeKit.drawOne(_disputeID, startIndex + i++);
if (drawnAddress == address(0)) {
continue;
}
Expand All @@ -617,6 +617,16 @@ abstract contract KlerosCoreBase is IArbitratorV2 {
round.drawIterations += i;
}

function drawOne(uint256 _disputeID, uint256 _nonce) public view returns (address drawnAddress) {
Dispute storage dispute = disputes[_disputeID];
Round storage round = dispute.rounds[dispute.rounds.length - 1];
if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();

bytes32 key = bytes32(uint256(dispute.courtID)); // Get the ID of the tree.

drawnAddress = sortitionModule.draw(key, _disputeID, _nonce);
}

/// @dev Appeals the ruling of a specified dispute.
/// Note: Access restricted to the Dispute Kit for this `disputeID`.
/// @param _disputeID The ID of the dispute.
Expand Down Expand Up @@ -1034,6 +1044,14 @@ abstract contract KlerosCoreBase is IArbitratorV2 {
return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;
}

function isJurorSolvent(uint256 _disputeID, address _account) external view returns (bool) {
Dispute storage dispute = disputes[_disputeID];
Round storage round = dispute.rounds[dispute.rounds.length - 1];
uint256 lockedAmountPerJuror = round.pnkAtStakePerJuror;
(uint256 totalStaked, uint256 totalLocked, , ) = sortitionModule.getJurorBalance(_account, dispute.courtID);
return totalStaked >= totalLocked + lockedAmountPerJuror;
}

// ************************************* //
// * Internal * //
// ************************************* //
Expand Down
18 changes: 4 additions & 14 deletions contracts/src/arbitration/dispute-kits/DisputeKitClassic.sol
Original file line number Diff line number Diff line change
Expand Up @@ -222,24 +222,19 @@ contract DisputeKitClassic is IDisputeKit, Initializable, UUPSProxiable {
emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);
}

/// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.
/// @dev Draws one juror. The drawn address is picked up by Kleros Core.
/// Note: Access restricted to Kleros Core only.
/// @param _coreDisputeID The ID of the dispute in Kleros Core.
/// @param _nonce Nonce of the drawing iteration.
/// @return drawnAddress The drawn address.
function draw(
function drawOne(
uint256 _coreDisputeID,
uint256 _nonce
) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {
Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];
Round storage round = dispute.rounds[dispute.rounds.length - 1];

ISortitionModule sortitionModule = core.sortitionModule();
(uint96 courtID, , , , ) = core.disputes(_coreDisputeID);
bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.

// TODO: Handle the situation when no one has staked yet.
drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);
drawnAddress = core.drawOne(_coreDisputeID, _nonce);

if (_postDrawCheck(_coreDisputeID, drawnAddress)) {
round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));
Expand Down Expand Up @@ -604,11 +599,6 @@ contract DisputeKitClassic is IDisputeKit, Initializable, UUPSProxiable {
/// @param _juror Chosen address.
/// @return Whether the address can be drawn or not.
function _postDrawCheck(uint256 _coreDisputeID, address _juror) internal view returns (bool) {
(uint96 courtID, , , , ) = core.disputes(_coreDisputeID);
uint256 lockedAmountPerJuror = core
.getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)
.pnkAtStakePerJuror;
(uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);
return totalStaked >= totalLocked + lockedAmountPerJuror;
return core.isJurorSolvent(_coreDisputeID, _juror);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -239,24 +239,19 @@ contract DisputeKitSybilResistant is IDisputeKit, Initializable, UUPSProxiable {
emit DisputeCreation(_coreDisputeID, _numberOfChoices, _extraData);
}

/// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.
/// @dev Draws one juror. The drawn address is picked up by Kleros Core.
/// Note: Access restricted to Kleros Core only.
/// @param _coreDisputeID The ID of the dispute in Kleros Core.
/// @param _nonce Nonce of the drawing iteration.
/// @return drawnAddress The drawn address.
function draw(
function drawOne(
uint256 _coreDisputeID,
uint256 _nonce
) external override onlyByCore notJumped(_coreDisputeID) returns (address drawnAddress) {
Dispute storage dispute = disputes[coreDisputeIDToLocal[_coreDisputeID]];
Round storage round = dispute.rounds[dispute.rounds.length - 1];

ISortitionModule sortitionModule = core.sortitionModule();
(uint96 courtID, , , , ) = core.disputes(_coreDisputeID);
bytes32 key = bytes32(uint256(courtID)); // Get the ID of the tree.

// TODO: Handle the situation when no one has staked yet.
drawnAddress = sortitionModule.draw(key, _coreDisputeID, _nonce);
drawnAddress = core.drawOne(_coreDisputeID, _nonce);

if (_postDrawCheck(_coreDisputeID, drawnAddress) && !round.alreadyDrawn[drawnAddress]) {
round.votes.push(Vote({account: drawnAddress, commit: bytes32(0), choice: 0, voted: false}));
Expand Down Expand Up @@ -622,16 +617,7 @@ contract DisputeKitSybilResistant is IDisputeKit, Initializable, UUPSProxiable {
/// @param _juror Chosen address.
/// @return Whether the address can be drawn or not.
function _postDrawCheck(uint256 _coreDisputeID, address _juror) internal view returns (bool) {
(uint96 courtID, , , , ) = core.disputes(_coreDisputeID);
uint256 lockedAmountPerJuror = core
.getRoundInfo(_coreDisputeID, core.getNumberOfRounds(_coreDisputeID) - 1)
.pnkAtStakePerJuror;
(uint256 totalStaked, uint256 totalLocked, , ) = core.sortitionModule().getJurorBalance(_juror, courtID);
if (totalStaked < totalLocked + lockedAmountPerJuror) {
return false;
} else {
return _proofOfHumanity(_juror);
}
return core.isJurorSolvent(_coreDisputeID, _juror) && _proofOfHumanity(_juror);
}

/// @dev Checks if an address belongs to the Proof of Humanity registry.
Expand Down
4 changes: 2 additions & 2 deletions contracts/src/arbitration/interfaces/IDisputeKit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ interface IDisputeKit {
uint256 _nbVotes
) external;

/// @dev Draws the juror from the sortition tree. The drawn address is picked up by Kleros Core.
/// @dev Draws one juror. The drawn address is picked up by Kleros Core.
/// Note: Access restricted to Kleros Core only.
/// @param _coreDisputeID The ID of the dispute in Kleros Core, not in the Dispute Kit.
/// @param _nonce Nonce.
/// @return drawnAddress The drawn address.
function draw(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);
function drawOne(uint256 _coreDisputeID, uint256 _nonce) external returns (address drawnAddress);

// ************************************* //
// * Public Views * //
Expand Down
20 changes: 19 additions & 1 deletion contracts/src/arbitration/university/KlerosCoreUniversity.sol
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ contract KlerosCoreUniversity is IArbitratorV2, UUPSProxiable, Initializable {
{
IDisputeKit disputeKit = disputeKits[round.disputeKitID];
uint256 iteration = round.drawIterations + 1;
address drawnAddress = disputeKit.draw(_disputeID, iteration);
address drawnAddress = disputeKit.drawOne(_disputeID, iteration);
if (drawnAddress == address(0)) {
revert NoJurorDrawn();
}
Expand All @@ -607,6 +607,16 @@ contract KlerosCoreUniversity is IArbitratorV2, UUPSProxiable, Initializable {
sortitionModule.setTransientJuror(address(0));
}

function drawOne(uint256 _disputeID, uint256 _nonce) public view returns (address drawnAddress) {
Dispute storage dispute = disputes[_disputeID];
Round storage round = dispute.rounds[dispute.rounds.length - 1];
if (msg.sender != address(disputeKits[round.disputeKitID])) revert DisputeKitOnly();

bytes32 key = bytes32(uint256(dispute.courtID)); // Get the ID of the tree.

drawnAddress = sortitionModule.draw(key, _disputeID, _nonce);
}

/// @dev Appeals the ruling of a specified dispute.
/// Note: Access restricted to the Dispute Kit for this `disputeID`.
/// @param _disputeID The ID of the dispute.
Expand Down Expand Up @@ -1023,6 +1033,14 @@ contract KlerosCoreUniversity is IArbitratorV2, UUPSProxiable, Initializable {
return (_amountInEth * 10 ** currencyRates[_toToken].rateDecimals) / currencyRates[_toToken].rateInEth;
}

function isJurorSolvent(uint256 _disputeID, address _account) external view returns (bool) {
Dispute storage dispute = disputes[_disputeID];
Round storage round = dispute.rounds[dispute.rounds.length - 1];
uint256 lockedAmountPerJuror = round.pnkAtStakePerJuror;
(uint256 totalStaked, uint256 totalLocked, , ) = sortitionModule.getJurorBalance(_account, dispute.courtID);
return totalStaked >= totalLocked + lockedAmountPerJuror;
}

// ************************************* //
// * Internal * //
// ************************************* //
Expand Down
Loading