Skip to content

Commit 02c20ce

Browse files
fix(IArbitrator): appeals removed from the standard
1 parent 4770b1f commit 02c20ce

File tree

3 files changed

+45
-85
lines changed

3 files changed

+45
-85
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## 0.1.0 (2021-11-23)
1+
## 0.1.0 (2021-11-25)
22

3+
- fix(Arbitrator): memory to calldata ([4770b1f](https://github.com/kleros/kleros-v2/commit/4770b1f))
34
- fix(IArbitrator): replaced appealCost with fundingStatus ([f189dd9](https://github.com/kleros/kleros-v2/commit/f189dd9))
45
- feat: modern toolchain setup and simple RNG smart contracts ([17f6a76](https://github.com/kleros/kleros-v2/commit/17f6a76))
56
- feat(Arbitration): standard update ([ed930de](https://github.com/kleros/kleros-v2/commit/ed930de))

contracts/src/arbitration/CentralizedArbitrator.sol

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ pragma solidity ^0.8;
55
import "./IArbitrator.sol";
66

77
/** @title Centralized Arbitrator
8-
* @dev This is a centralized arbitrator deciding alone on the result of disputes. It allows to appeal the rulings by crowdfunding a desired choice.
8+
* @dev This is a centralized arbitrator deciding alone on the result of disputes. It illustrates how the appeals can be handled on the arbitrator level.
9+
* In this particular contract the rulings can be appealed by crowdfunding a desired choice.
910
* Note that normally the arbitrator should use a Dispute Kit contract which will define the algorithm for appeals/withdrawals.
1011
* However to avoid complexity the code of the Dispute Kit is inlined within this contract.
11-
* Also note that to avoid complexity funding the subset of choices is not possible in this contract.
1212
*/
1313
contract CentralizedArbitrator is IArbitrator {
1414
/* Constants */
@@ -52,6 +52,20 @@ contract CentralizedArbitrator is IArbitrator {
5252

5353
/* Events */
5454

55+
/**
56+
* @dev To be emitted when a dispute can be appealed.
57+
* @param _disputeID ID of the dispute.
58+
* @param _arbitrable The contract which created the dispute.
59+
*/
60+
event AppealPossible(uint256 indexed _disputeID, IArbitrable indexed _arbitrable);
61+
62+
/**
63+
* @dev To be emitted when the current ruling is appealed.
64+
* @param _disputeID ID of the dispute.
65+
* @param _arbitrable The contract which created the dispute.
66+
*/
67+
event AppealDecision(uint256 indexed _disputeID, IArbitrable indexed _arbitrable);
68+
5569
/** @dev Raised when a contribution is made, inside fundAppeal function.
5670
* @param _disputeID ID of the dispute.
5771
* @param _round The round the contribution was made to.
@@ -168,24 +182,20 @@ contract CentralizedArbitrator is IArbitrator {
168182
/** @dev TRUSTED. Manages contributions, and appeals a dispute if at least two choices are fully funded. This function allows the appeals to be crowdfunded.
169183
* Note that the surplus deposit will be reimbursed.
170184
* @param _disputeID Index of the dispute to appeal.
171-
* @param _choices Subset of choices that can be funded. Note that this contract only allows to fund one choice at a time.
185+
* @param _choice A choice that receives funding.
172186
*/
173-
function fundAppeal(uint256 _disputeID, uint256[] calldata _choices) external payable override {
174-
require(_choices.length == 1, "Can only fund 1 ruling.");
175-
187+
function fundAppeal(uint256 _disputeID, uint256 _choice) external payable {
176188
DisputeStruct storage dispute = disputes[_disputeID];
177189
require(dispute.status == DisputeStatus.Appealable, "Dispute not appealable.");
178-
179-
uint256 contributedChoice = _choices[0];
180-
require(contributedChoice <= dispute.choices, "There is no such ruling to fund.");
190+
require(_choice <= dispute.choices, "There is no such ruling to fund.");
181191

182192
(uint256 appealPeriodStart, uint256 appealPeriodEnd) = appealPeriod(_disputeID);
183193
require(block.timestamp >= appealPeriodStart && block.timestamp < appealPeriodEnd, "Appeal period is over.");
184194

185195
uint256 multiplier;
186196
{
187197
uint256 winner = currentRuling(_disputeID);
188-
if (winner == contributedChoice) {
198+
if (winner == _choice) {
189199
multiplier = WINNER_STAKE_MULTIPLIER;
190200
} else {
191201
require(
@@ -200,26 +210,26 @@ contract CentralizedArbitrator is IArbitrator {
200210
Round[] storage rounds = disputeIDtoRoundArray[_disputeID];
201211
uint256 lastRoundIndex = rounds.length - 1;
202212
Round storage lastRound = rounds[lastRoundIndex];
203-
require(!lastRound.hasPaid[contributedChoice], "Appeal fee is already paid.");
213+
require(!lastRound.hasPaid[_choice], "Appeal fee is already paid.");
204214

205215
uint256 totalCost = appealFee + (appealFee * multiplier) / MULTIPLIER_DIVISOR;
206216

207217
// Take up to the amount necessary to fund the current round at the current costs.
208218
uint256 contribution;
209-
if (totalCost > lastRound.paidFees[contributedChoice]) {
210-
contribution = totalCost - lastRound.paidFees[contributedChoice] > msg.value // Overflows and underflows will be managed on the compiler level.
219+
if (totalCost > lastRound.paidFees[_choice]) {
220+
contribution = totalCost - lastRound.paidFees[_choice] > msg.value // Overflows and underflows will be managed on the compiler level.
211221
? msg.value
212-
: totalCost - lastRound.paidFees[contributedChoice];
213-
emit Contribution(_disputeID, lastRoundIndex, contributedChoice, msg.sender, contribution);
222+
: totalCost - lastRound.paidFees[_choice];
223+
emit Contribution(_disputeID, lastRoundIndex, _choice, msg.sender, contribution);
214224
}
215225

216-
lastRound.contributions[msg.sender][contributedChoice] += contribution;
217-
lastRound.paidFees[contributedChoice] += contribution;
218-
if (lastRound.paidFees[contributedChoice] >= totalCost) {
219-
lastRound.feeRewards += lastRound.paidFees[contributedChoice];
220-
lastRound.fundedChoices.push(contributedChoice);
221-
lastRound.hasPaid[contributedChoice] = true;
222-
emit ChoiceFunded(_disputeID, lastRoundIndex, contributedChoice);
226+
lastRound.contributions[msg.sender][_choice] += contribution;
227+
lastRound.paidFees[_choice] += contribution;
228+
if (lastRound.paidFees[_choice] >= totalCost) {
229+
lastRound.feeRewards += lastRound.paidFees[_choice];
230+
lastRound.fundedChoices.push(_choice);
231+
lastRound.hasPaid[_choice] = true;
232+
emit ChoiceFunded(_disputeID, lastRoundIndex, _choice);
223233
}
224234

225235
if (lastRound.fundedChoices.length > 1) {
@@ -322,28 +332,20 @@ contract CentralizedArbitrator is IArbitrator {
322332
return arbitrationFee;
323333
}
324334

325-
/** @dev Return the funded amount and funding goal for one (or the subset) of choices.
335+
/** @dev Return the funded amount and funding goal for one of the choices.
326336
* @param _disputeID The ID of the dispute to appeal.
327-
* @param _choices The one (or the subset) of choices to check the funding status of.
328-
* @return funded The amount funded so far for this subset in wei.
329-
* @return goal The amount to fully fund this subset in wei.
337+
* @param _choice The choice to check the funding status of.
338+
* @return funded The amount funded so far for this choice in wei.
339+
* @return goal The amount to fully fund this choice in wei.
330340
*/
331-
function fundingStatus(uint256 _disputeID, uint256[] calldata _choices)
332-
external
333-
view
334-
override
335-
returns (uint256 funded, uint256 goal)
336-
{
337-
require(_choices.length == 1, "Can only fund 1 ruling.");
338-
uint256 contributedChoice = _choices[0];
339-
341+
function fundingStatus(uint256 _disputeID, uint256 _choice) external view returns (uint256 funded, uint256 goal) {
340342
DisputeStruct storage dispute = disputes[_disputeID];
341-
require(contributedChoice <= dispute.choices, "There is no such ruling to fund.");
343+
require(_choice <= dispute.choices, "There is no such ruling to fund.");
342344
require(dispute.status == DisputeStatus.Appealable, "Dispute not appealable.");
343345

344346
uint256 multiplier;
345347
uint256 winner = currentRuling(_disputeID);
346-
if (winner == contributedChoice) {
348+
if (winner == _choice) {
347349
multiplier = WINNER_STAKE_MULTIPLIER;
348350
} else {
349351
multiplier = LOSER_STAKE_MULTIPLIER;
@@ -354,15 +356,15 @@ contract CentralizedArbitrator is IArbitrator {
354356
Round[] storage rounds = disputeIDtoRoundArray[_disputeID];
355357
Round storage lastRound = rounds[rounds.length - 1];
356358

357-
return (lastRound.paidFees[contributedChoice], goal);
359+
return (lastRound.paidFees[_choice], goal);
358360
}
359361

360362
/** @dev Compute the start and end of the dispute's appeal period, if possible. If the dispute is not appealble return (0, 0).
361363
* @param _disputeID ID of the dispute.
362364
* @return start The start of the period.
363365
* @return end The end of the period.
364366
*/
365-
function appealPeriod(uint256 _disputeID) public view override returns (uint256 start, uint256 end) {
367+
function appealPeriod(uint256 _disputeID) public view returns (uint256 start, uint256 end) {
366368
DisputeStruct storage dispute = disputes[_disputeID];
367369
if (dispute.status == DisputeStatus.Appealable) {
368370
start = dispute.appealPeriodStart;

contracts/src/arbitration/IArbitrator.sol

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ import "./IArbitrable.sol";
77
/**
88
* @title Arbitrator
99
* Arbitrator interface for CourtV2.
10-
* This interface follows the ERC-792 standard but also allows the appeal crowdfunding on arbitrator's side.
10+
* Unlike the ERC-792 this standard doesn't have anything related to appeals, so each arbitrator can implement an appeal system that suits it the most.
1111
* When developing arbitrator contracts we need to:
1212
* - Define the functions for dispute creation (createDispute). Don't forget to store the arbitrated contract and the disputeID (which should be unique, may nbDisputes).
13-
* - Define the function for appeal crowdfunding (fundAppeal) in order to appeal the ruling.
14-
* - Define the functions for cost display (arbitrationCost and fundingStatus).
13+
* - Define the functions for cost display (arbitrationCost).
1514
* - Allow giving rulings. For this a function must call arbitrable.rule(disputeID, ruling).
1615
*/
1716
interface IArbitrator {
@@ -28,20 +27,6 @@ interface IArbitrator {
2827
*/
2928
event DisputeCreation(uint256 indexed _disputeID, IArbitrable indexed _arbitrable);
3029

31-
/**
32-
* @dev To be emitted when a dispute can be appealed.
33-
* @param _disputeID ID of the dispute.
34-
* @param _arbitrable The contract which created the dispute.
35-
*/
36-
event AppealPossible(uint256 indexed _disputeID, IArbitrable indexed _arbitrable);
37-
38-
/**
39-
* @dev To be emitted when the current ruling is appealed.
40-
* @param _disputeID ID of the dispute.
41-
* @param _arbitrable The contract which created the dispute.
42-
*/
43-
event AppealDecision(uint256 indexed _disputeID, IArbitrable indexed _arbitrable);
44-
4530
/**
4631
* @dev Create a dispute. Must be called by the arbitrable contract.
4732
* Must pay at least arbitrationCost(_extraData).
@@ -58,34 +43,6 @@ interface IArbitrator {
5843
*/
5944
function arbitrationCost(bytes calldata _extraData) external view returns (uint256 cost);
6045

61-
/**
62-
* @dev Return the funded amount and funding goal for one (or the subset) of choices.
63-
* Note that the status info may not be available if the dispute is not currently appealable.
64-
* @param _disputeID The ID of the dispute to appeal.
65-
* @param _choices The one (or the subset) of choices to check the funding status of.
66-
* @return funded The amount funded so far for this subset in wei.
67-
* @return goal The amount to fully fund this subset in wei.
68-
*/
69-
function fundingStatus(uint256 _disputeID, uint256[] calldata _choices)
70-
external
71-
view
72-
returns (uint256 funded, uint256 goal);
73-
74-
/**
75-
* @dev Compute the start and end of the dispute's appeal period, if possible. If appeal is impossible: should return (0, 0).
76-
* @param _disputeID ID of the dispute.
77-
* @return start The start of the period.
78-
* @return end The end of the period.
79-
*/
80-
function appealPeriod(uint256 _disputeID) external view returns (uint256 start, uint256 end);
81-
82-
/**
83-
* @dev Make a contribution to fund one (or the subset) of possible choices in order to appeal the ruling.
84-
* @param _disputeID The ID of the dispute to appeal.
85-
* @param _choices The choices to contribute to.
86-
*/
87-
function fundAppeal(uint256 _disputeID, uint256[] calldata _choices) external payable;
88-
8946
/**
9047
* @dev Return the status of a dispute.
9148
* @param _disputeID ID of the dispute to rule.

0 commit comments

Comments
 (0)