From 78b7c2fc2e8b57050b7926d3b4f357bbda6b51ab Mon Sep 17 00:00:00 2001 From: unknownunknown1 Date: Mon, 20 Jun 2022 17:48:08 +1000 Subject: [PATCH 1/3] feat(DisputeResolver): add contract --- .../arbitrables/DisputeResolver.sol | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 contracts/src/arbitration/arbitrables/DisputeResolver.sol diff --git a/contracts/src/arbitration/arbitrables/DisputeResolver.sol b/contracts/src/arbitration/arbitrables/DisputeResolver.sol new file mode 100644 index 000000000..ff7287f5d --- /dev/null +++ b/contracts/src/arbitration/arbitrables/DisputeResolver.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MIT + +/** + * @authors: [@ferittuncer, @unknownunknown1] + * @reviewers: [] + * @auditors: [] + * @bounties: [] + */ + +import "../IArbitrable.sol"; +import "../../evidence/IMetaEvidence.sol"; + +pragma solidity ^0.8; + +/** + * @title DisputeResolver + * DisputeResolver contract adapted for V2 https://github.com/kleros/arbitrable-proxy-contracts/blob/master/contracts/ArbitrableProxy.sol. + */ +contract DisputeResolver is IArbitrable, IMetaEvidence { + struct DisputeStruct { + bytes arbitratorExtraData; // Extra data for the dispute. + bool isRuled; // True if the dispute has been ruled. + uint256 ruling; // Ruling given to the dispute. + uint256 numberOfRulingOptions; // The number of choices the arbitrator can give. + } + + IArbitrator public immutable arbitrator; // Arbitrator is set in constructor and never changed. + + DisputeStruct[] public disputes; // Local disputes. + mapping(uint256 => uint256) public externalIDtoLocalID; // Maps external (arbitrator side) dispute IDs to local dispute IDs. + + /** @dev Constructor + * @param _arbitrator Target global arbitrator for any disputes. + */ + constructor(IArbitrator _arbitrator) { + arbitrator = _arbitrator; + } + + /** @dev Allows to submit evidence for a given dispute. + * @param _localDisputeID Index of the dispute in disputes array. + * @param _evidenceURI Link to evidence. + */ + function submitEvidence(uint256 _localDisputeID, string calldata _evidenceURI) external { + DisputeStruct storage dispute = disputes[_localDisputeID]; + require(!dispute.isRuled, "Cannot submit evidence to a resolved dispute."); + + emit Evidence(arbitrator, _localDisputeID, msg.sender, _evidenceURI); + } + + /** @dev TRUSTED. Calls createDispute function of the specified arbitrator to create a dispute. + Note that we don’t need to check that msg.value is enough to pay arbitration fees as it’s the responsibility of the arbitrator contract. + * @param _arbitratorExtraData Extra data for the arbitrator of the dispute. + * @param _metaevidenceURI Link to metaevidence of the dispute. + * @param _numberOfRulingOptions Number of ruling options. + * @return disputeID Dispute id (on arbitrator side) of the created dispute. + */ + function createDispute( + bytes calldata _arbitratorExtraData, + string calldata _metaevidenceURI, + uint256 _numberOfRulingOptions + ) external payable returns (uint256 disputeID) { + require(_numberOfRulingOptions > 1, "Should be at least 2 ruling options."); + + disputeID = arbitrator.createDispute{value: msg.value}(_numberOfRulingOptions, _arbitratorExtraData); + uint256 localDisputeID = disputes.length; + disputes.push( + DisputeStruct({ + arbitratorExtraData: _arbitratorExtraData, + isRuled: false, + ruling: 0, + numberOfRulingOptions: _numberOfRulingOptions + }) + ); + + externalIDtoLocalID[disputeID] = localDisputeID; + + emit MetaEvidence(localDisputeID, _metaevidenceURI); + emit Dispute(arbitrator, disputeID, localDisputeID, localDisputeID); + } + + /** @dev To be called by the arbitrator of the dispute, to declare winning ruling. + * @param _externalDisputeID ID of the dispute in arbitrator contract. + * @param _ruling The ruling choice of the arbitration. + */ + function rule(uint256 _externalDisputeID, uint256 _ruling) external override { + uint256 localDisputeID = externalIDtoLocalID[_externalDisputeID]; + DisputeStruct storage dispute = disputes[localDisputeID]; + require(msg.sender == address(arbitrator), "Only the arbitrator can execute this."); + require(_ruling <= dispute.numberOfRulingOptions, "Invalid ruling."); + require(!dispute.isRuled, "This dispute has been ruled already."); + + dispute.isRuled = true; + dispute.ruling = _ruling; + + emit Ruling(IArbitrator(msg.sender), _externalDisputeID, dispute.ruling); + } +} From f3c0ac6d933968a8a3fe75a90f5e8fa7efaffc6f Mon Sep 17 00:00:00 2001 From: unknownunknown1 Date: Mon, 20 Jun 2022 20:23:44 +1000 Subject: [PATCH 2/3] fix(DR): remove submitEvidence --- .../src/arbitration/arbitrables/DisputeResolver.sol | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/contracts/src/arbitration/arbitrables/DisputeResolver.sol b/contracts/src/arbitration/arbitrables/DisputeResolver.sol index ff7287f5d..d52d4935c 100644 --- a/contracts/src/arbitration/arbitrables/DisputeResolver.sol +++ b/contracts/src/arbitration/arbitrables/DisputeResolver.sol @@ -36,17 +36,6 @@ contract DisputeResolver is IArbitrable, IMetaEvidence { arbitrator = _arbitrator; } - /** @dev Allows to submit evidence for a given dispute. - * @param _localDisputeID Index of the dispute in disputes array. - * @param _evidenceURI Link to evidence. - */ - function submitEvidence(uint256 _localDisputeID, string calldata _evidenceURI) external { - DisputeStruct storage dispute = disputes[_localDisputeID]; - require(!dispute.isRuled, "Cannot submit evidence to a resolved dispute."); - - emit Evidence(arbitrator, _localDisputeID, msg.sender, _evidenceURI); - } - /** @dev TRUSTED. Calls createDispute function of the specified arbitrator to create a dispute. Note that we don’t need to check that msg.value is enough to pay arbitration fees as it’s the responsibility of the arbitrator contract. * @param _arbitratorExtraData Extra data for the arbitrator of the dispute. From 8a73904c2c2fec1fbad8aa597a1f4da2a016c53d Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Tue, 21 Jun 2022 00:23:25 +0100 Subject: [PATCH 3/3] refactor: moved ArbitrableExample to sub-folder --- .../src/arbitration/{ => arbitrables}/ArbitrableExample.sol | 4 ++-- contracts/src/arbitration/arbitrables/DisputeResolver.sol | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename contracts/src/arbitration/{ => arbitrables}/ArbitrableExample.sol (97%) diff --git a/contracts/src/arbitration/ArbitrableExample.sol b/contracts/src/arbitration/arbitrables/ArbitrableExample.sol similarity index 97% rename from contracts/src/arbitration/ArbitrableExample.sol rename to contracts/src/arbitration/arbitrables/ArbitrableExample.sol index be01642df..b7b46bb48 100644 --- a/contracts/src/arbitration/ArbitrableExample.sol +++ b/contracts/src/arbitration/arbitrables/ArbitrableExample.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8; -import "./IArbitrable.sol"; -import "../evidence/IMetaEvidence.sol"; +import "../IArbitrable.sol"; +import "../../evidence/IMetaEvidence.sol"; /** * @title ArbitrableExample diff --git a/contracts/src/arbitration/arbitrables/DisputeResolver.sol b/contracts/src/arbitration/arbitrables/DisputeResolver.sol index d52d4935c..dde97799b 100644 --- a/contracts/src/arbitration/arbitrables/DisputeResolver.sol +++ b/contracts/src/arbitration/arbitrables/DisputeResolver.sol @@ -67,7 +67,7 @@ contract DisputeResolver is IArbitrable, IMetaEvidence { emit Dispute(arbitrator, disputeID, localDisputeID, localDisputeID); } - /** @dev To be called by the arbitrator of the dispute, to declare winning ruling. + /** @dev To be called by the arbitrator of the dispute, to declare the winning ruling. * @param _externalDisputeID ID of the dispute in arbitrator contract. * @param _ruling The ruling choice of the arbitration. */