/
CentralizedArbitrator.sol
123 lines (105 loc) · 4.62 KB
/
CentralizedArbitrator.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
* @authors: [@clesaege, @n1c01a5, @epiqueras, @ferittuncer]
* @reviewers: [@clesaege*, @unknownunknown1*]
* @auditors: []
* @bounties: []
* @deployments: []
* @tools: [MythX]
*/
pragma solidity ^0.4.15;
import "./Arbitrator.sol";
/** @title Centralized Arbitrator
* @dev This is a centralized arbitrator deciding alone on the result of disputes. No appeals are possible.
*/
contract CentralizedArbitrator is Arbitrator {
address public owner = msg.sender;
uint arbitrationPrice; // Not public because arbitrationCost already acts as an accessor.
uint constant NOT_PAYABLE_VALUE = (2**256-2)/2; // High value to be sure that the appeal is too expensive.
struct DisputeStruct {
Arbitrable arbitrated;
uint choices;
uint fee;
uint ruling;
DisputeStatus status;
}
modifier onlyOwner {require(msg.sender==owner, "Can only be called by the owner."); _;}
DisputeStruct[] public disputes;
/** @dev Constructor. Set the initial arbitration price.
* @param _arbitrationPrice Amount to be paid for arbitration.
*/
constructor(uint _arbitrationPrice) public {
arbitrationPrice = _arbitrationPrice;
}
/** @dev Set the arbitration price. Only callable by the owner.
* @param _arbitrationPrice Amount to be paid for arbitration.
*/
function setArbitrationPrice(uint _arbitrationPrice) public onlyOwner {
arbitrationPrice = _arbitrationPrice;
}
/** @dev Cost of arbitration. Accessor to arbitrationPrice.
* @param _extraData Not used by this contract.
* @return fee Amount to be paid.
*/
function arbitrationCost(bytes _extraData) public view returns(uint fee) {
return arbitrationPrice;
}
/** @dev Cost of appeal. Since it is not possible, it's a high value which can never be paid.
* @param _disputeID ID of the dispute to be appealed. Not used by this contract.
* @param _extraData Not used by this contract.
* @return fee Amount to be paid.
*/
function appealCost(uint _disputeID, bytes _extraData) public view returns(uint fee) {
return NOT_PAYABLE_VALUE;
}
/** @dev Create a dispute. Must be called by the arbitrable contract.
* Must be paid at least arbitrationCost().
* @param _choices Amount of choices the arbitrator can make in this dispute. When ruling ruling<=choices.
* @param _extraData Can be used to give additional info on the dispute to be created.
* @return disputeID ID of the dispute created.
*/
function createDispute(uint _choices, bytes _extraData) public payable returns(uint disputeID) {
super.createDispute(_choices, _extraData);
disputeID = disputes.push(DisputeStruct({
arbitrated: Arbitrable(msg.sender),
choices: _choices,
fee: msg.value,
ruling: 0,
status: DisputeStatus.Waiting
})) - 1; // Create the dispute and return its number.
emit DisputeCreation(disputeID, Arbitrable(msg.sender));
}
/** @dev Give a ruling. UNTRUSTED.
* @param _disputeID ID of the dispute to rule.
* @param _ruling Ruling given by the arbitrator. Note that 0 means "Not able/wanting to make a decision".
*/
function _giveRuling(uint _disputeID, uint _ruling) internal {
DisputeStruct storage dispute = disputes[_disputeID];
require(_ruling <= dispute.choices, "Invalid ruling.");
require(dispute.status != DisputeStatus.Solved, "The dispute must not be solved already.");
dispute.ruling = _ruling;
dispute.status = DisputeStatus.Solved;
msg.sender.send(dispute.fee); // Avoid blocking.
dispute.arbitrated.rule(_disputeID,_ruling);
}
/** @dev Give a ruling. UNTRUSTED.
* @param _disputeID ID of the dispute to rule.
* @param _ruling Ruling given by the arbitrator. Note that 0 means "Not able/wanting to make a decision".
*/
function giveRuling(uint _disputeID, uint _ruling) public onlyOwner {
return _giveRuling(_disputeID, _ruling);
}
/** @dev Return the status of a dispute.
* @param _disputeID ID of the dispute to rule.
* @return status The status of the dispute.
*/
function disputeStatus(uint _disputeID) public view returns(DisputeStatus status) {
return disputes[_disputeID].status;
}
/** @dev Return the ruling of a dispute.
* @param _disputeID ID of the dispute to rule.
* @return ruling The ruling which would or has been given.
*/
function currentRuling(uint _disputeID) public view returns(uint ruling) {
return disputes[_disputeID].ruling;
}
}