Skip to content

ERC 792: Arbitration Standard #792

Closed
@clesaege

Description

@clesaege
  EIP: 792
  Title: Arbitration Standard
  Status: Draft
  Type: Informational
  Category: ERC
  Author: Clément Lesaege <[email protected]>
  Created: 2017-12-06

Abstract

The following describes a standard of Arbitrable and Arbitrator contracts. Every Arbitrable contract can be adjudicated by every Arbitrator contract. Arbitrator contracts give rulings and Arbitrable contracts enforce them.

Motivation

Using two contracts allows separation between the ruling and its enforcement. This abstraction allows Arbitrable contract developers not to have to know the internal process of the Arbitrator contracts. Neither do Arbitrator contract developers with Arbitrable ones.
It allows dapps to easily switch from one arbitration service to another one. Or to allow their users to choose themselves their arbitration services.

Specification

Arbitrable

This contract enforces decisions given by the Arbitrator contract.
It must calls the functions createDispute and appeal of the Arbitrator contract and pay the required fee. It is its responsability to determine in which case a dispute occurs and when an appeal is possible.
It must track the disputes by their (arbitrator,disputeID) unique key. If the contract only has a unique arbitrator which can't be changed, the arbitrator part can be omitted internally.
This contract must implement enforcements of ruling. For ruling, the value 0 is reserved to indicate that no ruling has been given.

Methods

rule

To be called by the Arbitrator contract.
Enforces the ruling _ruling for dispute (msg.sender,_dispute).
Arbitrators should only call rule when all appeals are exhausted.
It must reverts in case of failure.
It must fire the Ruling event.

function rule(uint _disputeID, uint _ruling)

NOTE: The Arbitrator contract should not assume that rule will be successfully executed. A malicious (or buggy) Arbitrable contract could make rule revert.

Events

Ruling

Must trigger when a final ruling is given.

event Ruling(Arbitrator indexed _arbitrator, uint indexed _disputeID, uint _ruling)

Arbitrator

This contract makes rulings. It must call the rule function when a decision is final.

Methods

NOTE: The variable _extraData can contains information to require a custom arbitration (resp. appeal) behaviour of the contract. The format of this variable is determined by the Arbitrator contract creator. In case _extraData is void or invalid, functions should act according to a default arbitration (resp. appeal) behaviour.
NOTE: The variable _extraData SHOULD be formatted the same way for both dispute creation and appeal.
NOTE: Different _extraData values can be used by a same Arbitrable contract, even during the same dispute. Therefore Arbitrator contracts MUST NOT assume _extraData to be constant across disputes and appeals.
NOTE: Arbitration (resp. appeal) fee can change, therefore Arbitrable contracts should call this function each time it is relevant and not assume the fee are the same as in the last call.
NOTE: If the Arbitrable contract does not pay enough fee, the functions should revert. However, if it pays too much fee, the contract should not revert and accept the higher fee.

arbitrationCost

Returns the cost of arbitration fee in wei required to create a dispute.

function arbitrationCost(bytes _extraData) view returns(uint fee)

appealCost

Returns the cost of appeal fee in wei required to appeal the dispute (arbitrator,_disputeID).

function appealCost(uint _disputeID, bytes _extraData) view returns(uint fee)

createDispute

Create a dispute.
It should be called by the Arbitrable contract. It must pay at least arbitrationCost(bytes _extraData) weis.
The parameter _choices indicates the maximum value _ruling can take. So for a binary ruling, _choices should be 2 (0 to refuse to give a ruling, 1 for giving the first ruling and 2 for the second).
This method must fire the DisputeCreation event.
The Arbitrator contract should assign a unique disputeID identifier to the dispute and return it.

function createDispute(uint _choices, bytes _extraData) payable returns(uint disputeID)

appeal

Appeal the dispute (arbitrator,_disputeID).
It should be called by the Arbitrable contract. It must pay at least appealCost(uint _disputeID, bytes _extraData) weis.
This method must fire the AppealDecision event.

function appeal(uint _disputeID, bytes _extraData) payable

appealPeriod

Return the [start,end] time windown for appealing a ruling if known in advance.
If those time are not known or appeal is not possible, returns (0,0).

function appealPeriod(uint _disputeID) public view returns(uint start, uint end)

currentRuling

Return the ruling which will be given if there is no appeal or which has been given.

function currentRuling(uint _disputeID) view returns (uint ruling)

disputeStatus

Return the status of the ruling.

function disputeStatus(uint _disputeID) view returns (DisputeStatus status)

with

enum DisputeStatus {Waiting, Appealable, Solved}

NOTE: The value solved does not necessarily means that the function rule was called. It means that the ruling is final and that it won't change.

Events

DisputeCreation

Must trigger when a dispute is created.

event DisputeCreation(uint indexed _disputeID, Arbitrable indexed _arbitrable)

AppealDecision

Must trigger when the current ruling is appealed.

event AppealDecision(uint indexed _disputeID, Arbitrable indexed _arbitrable)

AppealPossible

Must trigger when appealing a dispute becomes possible.

event AppealPossible(uint indexed _disputeID, Arbitrable indexed _arbitrable);

Rationale

  • An arbitration standard allows interoperability between dapps needing and requiring arbitration.
  • Not putting a standard function returning the Arbitrator of an Arbitrable contract allows Arbitrable contracts to have multiple arbitrators and to change them.
  • Requiring the Arbitrable contract to pay the fee (opposed to requiring users to directly interact with the Arbitrator contract) allows it to determine who should pay the fee. It can choose to split them, or require parties to deposit ether to pay fee and reimburse the winners.
  • For ruling, reserving the value 0 for absence of ruling allows arbitrators to refuse to rule.
  • The variable extraData allows arbitrary customization of arbitration processes. For example, the amount of jurors which will participate in a ruling and the time allowed. The way a dispute is handled is determined by the (arbitrator,extraData) pair.
  • We don't need a method to indicates if appeal is possible, as the Arbitrator contract just has to return an arbitrary high value in appealCost to indicate that appeals are not possible.
  • Accepting higher fee instead of reverting generally provides more security. If the Arbitrable contract has a bug which makes it pay too much, it's better to accept the higher fee, than to prevent disputes and appeals which could stuck the contract forever. It also allows Arbitrable contracts to choose to give higher fee than required, for example if those fee are used as an incentive for arbitrators, in order to provide incentives higher than the minimum.
  • The method disputeStatus allows contract and users to know if a ruling has been given and if it is final.
  • The method currentRuling allows contracts and users to know which ruling would be given if there is no appeal and make their appeal decisions accordingly.
    Combined with disputeStatus, it allows other contracts to take actions depending of the result of a dispute. This can be used to enforce contingency fee payouts.
  • This ERC is just about rulings and enforcement, handling of evidence is described in ERC1497: Evidence Standard.
  • About community consensus, we published this article including the previous version of the proposed standard and talked about the standard during Devcon3. After feedback, we modified the standard to include events and to split it into two standards: one about ruling and enforcement (this one) and one about handling of evidence (to come).

Implementations

Example implementations are available at

Presentation on how to make your own implementation:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions