// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IArbitrable, IArbitrator} from "@kleros/erc-792/contracts/IArbitrator.sol";
import {IEvidence} from "@kleros/erc-792/contracts/erc-1497/IEvidence.sol";
contract SimpleArbitrableV1 is IArbitrable, IEvidence {
IArbitrator public immutable arbitrator;
uint256 public constant META_EVIDENCE_ID = 0;
uint256 public constant CHOICES = 2;
struct Dispute {
address payable partyA;
address payable partyB;
uint256 amount;
bool ruled;
}
mapping(uint256 => Dispute) public disputes;
constructor(IArbitrator _arbitrator, string memory _metaEvidence) {
arbitrator = _arbitrator;
emit MetaEvidence(META_EVIDENCE_ID, _metaEvidence);
}
function createDispute(
address payable _partyB
) external payable returns (uint256) {
// Calculate arbitration cost
bytes memory extraData = abi.encodePacked(
uint256(0), // General Court (subcourt 0)
uint256(3) // 3 jurors
);
uint256 arbitrationCost = arbitrator.arbitrationCost(extraData);
require(msg.value >= arbitrationCost, "Insufficient fee");
uint256 disputeID = arbitrator.createDispute{value: arbitrationCost}(
CHOICES,
extraData
);
disputes[disputeID] = Dispute({
partyA: payable(msg.sender),
partyB: _partyB,
amount: msg.value - arbitrationCost,
ruled: false
});
// Link dispute to meta-evidence and evidence group
emit Dispute(arbitrator, disputeID, META_EVIDENCE_ID, disputeID);
return disputeID;
}
function submitEvidence(
uint256 _disputeID,
string calldata _evidenceURI
) external {
require(!disputes[_disputeID].ruled, "Already ruled");
emit Evidence(arbitrator, _disputeID, msg.sender, _evidenceURI);
}
function rule(uint256 _disputeID, uint256 _ruling) external override {
require(msg.sender == address(arbitrator), "Only arbitrator");
Dispute storage dispute = disputes[_disputeID];
require(!dispute.ruled, "Already ruled");
dispute.ruled = true;
if (_ruling == 1) {
dispute.partyA.transfer(dispute.amount);
} else if (_ruling == 2) {
dispute.partyB.transfer(dispute.amount);
} else {
uint256 half = dispute.amount / 2;
dispute.partyA.transfer(half);
dispute.partyB.transfer(dispute.amount - half);
}
emit Ruling(arbitrator, _disputeID, _ruling);
}
}