Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERC 792: Arbitration Standard #792

Closed
clesaege opened this issue Dec 6, 2017 · 44 comments
Closed

ERC 792: Arbitration Standard #792

clesaege opened this issue Dec 6, 2017 · 44 comments
Labels

Comments

@clesaege
Copy link
Contributor

clesaege commented Dec 6, 2017

  EIP: 792
  Title: Arbitration Standard
  Status: Draft
  Type: Informational
  Category: ERC
  Author: Clément Lesaege <clement@kleros.io>
  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:

@clesaege clesaege changed the title ERC 783: Arbitration Standard ERC 792: Arbitration Standard Dec 6, 2017
@Samyoul
Copy link

Samyoul commented Dec 7, 2017

Good work, I really like the look of this. I am very interested in this standard as I am also currently developing platform functionality for arbitration of contracts : https://github.com/TiiQu-Network/TiiQu-Network/wiki/White-Paper#crowd-sourced-arbitrage

@wanderingstan
Copy link

Seconding the good work. We are developing a marketplace at www.originprotocol.com and arbitration will be important. I'll share this with our team.

@clesaege
Copy link
Contributor Author

clesaege commented Dec 19, 2017

About

Before any ruling is available, it should return the value 0.

I was wondering that the 0 could both mean "No ruling yet" or "Refused to give a ruling", distinction which in some cases may be relevant.
What do you think about using uint(-1) for "No ruling yet" to separate those?

@clesaege
Copy link
Contributor Author

Another solution would be to add a disputeStatus function returning an enum {awaiting, appealable, final}.
I like better the second solution.

@SerpentChris
Copy link

I really don't like the _extra_data bytes argument. Languages are typed to make code easier to analyze, and this feature forces developers to obscure type information. This could make bugs harder to catch. One way to fix this would be to remove _extra_data and force Arbitrator contracts to store relevant custom data using the disputeID, and to have their own functions for providing details about each stage of dispute resolution.

@clesaege
Copy link
Contributor Author

clesaege commented Dec 27, 2017

@SerpentChris
Well the thing is that when we create an Arbitrable contract, we don't know what other parameters the Arbitrator may need.
In my usecase: https://github.com/kleros/kleros/blob/master/contracts/KlerosPOC.sol#L396 , this _extraData is used to define the amount of jurors which will be drawn. In further versions it could also contains the ID of a specialized subcourt.
And I guess other Arbitrator will have other parameters we can't forecast.

If you let Arbitrator have their own non standardized functions which should be called by the Arbitrator contract. You remove the benefit of a standard, because you would need to know to which Arbitrator contract you will have to interact with in order to write the Arbitrable one.

You can see that other standards took the same approach, for example ERC777: #777 .

@clesaege
Copy link
Contributor Author

@SerpentChris
I looked more into it and we may be able to have better typing when ethereum/solidity#1707
will be implemented.
This way the Arbitrator contract functions could use types and the Arbitrable contract use a bytes which would be formatted using the encode method offchain.
Note that this would not break backward compatibility with the current proposal.

@clesaege
Copy link
Contributor Author

I added the disputeStatus to the standard.

@mbeylin
Copy link
Contributor

mbeylin commented Apr 12, 2018

Wanted to add some more concrete thoughts on this EIP after our call @clesaege

function arbitrationCost(bytes _extraData) constant returns(uint fees)
What would the suggested functionality be if people decide to pay higher fees than the minimum (so as to better incentivize arbiters?

function appealCost(uint _disputeID, bytes _extraData) constant returns(uint fees)
I believe this is not needed, as appeals should not be a necessary element of all disputes.

function createDispute(bytes _extraData) payable returns(uint disputeID)
Is it necessary to return the new dispute ID here? This would only be useful if a contract was making that create dispute call. For Delphi, the way we have implemented this is function openClaim(address _claimant, uint _amount, uint _fee, string _data) (where the string serves the same purpose as the data), the _amount is the value of the claim, and the _fee is the value of the fee the claimant desires to pay (greater than the min fee).

function appeal(uint _disputeID, bytes _extraData) payable
As mentioned above, I don't believe this should be a part of the standard, since in no way is an appeals process a necessary element of a dispute.

function disputeStatus(uint _disputeID) constant returns (DisputeStatus status) I feel that this function is not needed, in the absence of an appeals process in the standard, a dispute is either ruled or un-ruled, which could easily be checked by the currentRuling(uint _disputeID) function.

In addition to the DisputeCreation(uint indexed _disputeID, Arbitrable _arbitrable) event, I would suggest adding a DisputeRuled(uint indexed _disputeID) event. It is also unclear to me why the Dispute Creation event would include a reference to the Arbitrable contract, since that is the contract which is emitting the event in the first place (right?).

In addition to this, I want to formally advocate for a settlements process that is on-chain, allowing people to settle disputes for a lower amount without having to pay arbiter fees. However, I would be open to settlement functionality not being included in the standard since I understand you (Kleros) don't include that functionality in your mechanism as of right now.

@mbeylin
Copy link
Contributor

mbeylin commented Apr 13, 2018

I also want to formally share my opinion that I believe it is premature for us to create an ERC for this when we have minimal evidence of the validity of our assumptions. Standards historically have evolved out of market successes (or based on user data about previous versions of a product), however the lack of decentralized dispute resolution mechanism in the market precludes us from making any assertions about what should be in the standard without including some of our own assumptions. I believe we should align on what a general standard for this would look like, and begin employing it, well before we pursue a finalization of this EIP (similarly to how ERC20 was used well before it was finalized).

@clesaege
Copy link
Contributor Author

clesaege commented Apr 13, 2018

function arbitrationCost(bytes _extraData) constant returns(uint fees)
What would the suggested functionality be if people decide to pay higher fees than the minimum (so as to better incentivize arbiters?

The standard is not about functionalities, it's about interoperability. The Arbitrator contracts can decide what to do with the extra fees. I guess in most cases, it will be paying more the arbitrators.


function appealCost(uint _disputeID, bytes _extraData) constant returns(uint fees)
I believe this is not needed, as appeals should not be a necessary element of all disputes.
function appeal(uint _disputeID, bytes _extraData) payable
As mentioned above, I don't believe this should be a part of the standard, since in no way is an appeals process a necessary element of a dispute.

With the exception of the centralized arbitrators and Delphi proposals, all dispute resolution proposal I'm aware of (Kleros, Juris, Jury.Online, Aragon, TiiQu) includes an appeal system. If a contract does not allow appeals, it just has to return a high value to forbid it. But when the overwhelming majority of dispute resolution systems off-chain (state court system, ADR which even when they don't include an intra-ADR appeal system, can then be "appealed" by state courts), and on-chain proposals. It seems that the appeal system must belong to the standard.
For dispute resolution systems which don't have appeal possibility the extra implementation cost is minimal (a single function which indicates that appeals are not possible).
I think we have 3 possible choice:

  • Having appeals in the standard: Current proposal. It has the advantage of being simple and not requiring tailoring of Arbitrable contracts to Arbitrator ones. It has a disadvantage of slightly increasing the deployment cost of contracts due to the arbitrationCost function.
  • Putting appeal as optional: It has the advantage of saving gas in the deployment of some Arbitrator. It has the disadvantage that Arbitrable contracts would need different implementations depending if they interact with an appealable Arbitrator. This increases overall interaction complexity.
  • Have both BasicArbitrator/BasicArbitrable and AppealableArbitrator/AppealableArbitrable standards. We can get the best of both worlds in term of gas and contract logic this way, but interoperability will be impacted as the Basic would not be able to interact with the Appealable without wrappers. It would be a solution which would not take considerable amount of time to Appealable systems developers nor Basic system developers as they would both develop strictly what they need.

function createDispute(bytes _extraData) payable returns(uint disputeID)
Is it necessary to return the new dispute ID here?

Yes, for cases where an Arbitrable contract has multiple disputes in the same Arbitrator contract, there must be an identifier to know which on to refer to.


In addition to the DisputeCreation(uint indexed _disputeID, Arbitrable _arbitrable) event, I would suggest adding a DisputeRuled(uint indexed _disputeID) event. It is also unclear to me why the Dispute Creation event would include a reference to the Arbitrable contract, since that is the contract which is emitting the event in the first place (right?).

No, the DisputeCreation event is emitted by the Arbitrator contract. This allows to know from the logs which dispute is related to which Arbitrable contracts.


In addition to this, I want to formally advocate for a settlements process that is on-chain, allowing people to settle disputes for a lower amount without having to pay arbiter fees. However, I would be open to settlement functionality not being included in the standard since I understand you (Kleros) don't include that functionality in your mechanism as of right now.

An on-chain settlement process is not included in the standard as this standard is about standardization of interactions between Arbitrator and Arbitrable contracts. Pre-arbitration settlement is a part of a mediation process and an Arbitrator contract not need to be involved. It is perfectly possible to make contracts with a settlement mechanism implementing this standard (for example https://github.com/kleros/kleros-interaction/blob/master/contracts/standard/arbitration/Rental.sol ).
For now we haven't identified a need of settlement standardization due to it (in the usecases we have in mind) being well handled by the Arbitrable contract alone. If they were to be need of standardization (I can imagine, some contract making insurance payment depending of results of settlement and mediators paid on result, i.e only when settlement occurs and the dispute is not raised to arbitration), we would be please to collaborate on it.


I also want to formally share my opinion that I believe it is premature for us to create an ERC for this when we have minimal evidence of the validity of our assumptions. Standards historically have evolved out of market successes (or based on user data about previous versions of a product), however the lack of decentralized dispute resolution mechanism in the market precludes us from making any assertions about what should be in the standard without including some of our own assumptions. I believe we should align on what a general standard for this would look like, and begin employing it, well before we pursue a finalization of this EIP (similarly to how ERC20 was used well before it was finalized).

When speaking with projects needing dispute resolution, the contrary opinion has emerged. There a lot of teams building products which need dispute resolution and a handful of teams working on it. The projects which need dispute resolution generally don't want to have to integrate with each dispute resolution provider, especially knowing that those projects are early stage (the whole industry is) and most of them will have failed within a few years. Integration with a standard, instead of a particular project, allows them to let their users choose their dispute resolution system instead of locking them on a particular one.
In the absence of standard of interoperability, monopolies could emerge as dapps developers would have to take a specific action to support a dispute resolution mechanism and they would obviously only do it for systems having significant uses. This would provides significant first-mover advantage and barriers of entry.
The only assumption being made is that a significant portion of dispute resolution mechanism will include an appeal possibility. Assumption being supported by thousands of years of off-chain disputes resolution process allowing appeals. This does not prevent the standard from working with disputes resolution systems which do not have the possibility of appeals while not including it would prevent the use of dispute resolution systems with an appeal possibility. The possibility for projects to interact with (up to my knowledge) dispute resolution mechanisms which includes appeals, far outweigh the extra unique (you only need to deploy each contract once, as you can use libraries) gas cost of arround 0.01$.

@mbeylin
Copy link
Contributor

mbeylin commented Apr 14, 2018

Have both BasicArbitrator/BasicArbitrable and AppealableArbitrator/AppealableArbitrable standards.

In my opinion this would be best, similar to how there was a HumanStandardToken which added increased functionality to the StandardToken functionality.

Yes, for cases where an Arbitrable contract has multiple disputes in the same Arbitrator contract, there must be an identifier to know which on to refers to.

Correct, but this information is entirely useless unless it is being returned to another contract for storage since it's impossible for the returned value to be passed to the sender of the original transaction (if the claim is opened by a user). This information should be emitted in an event. I would also like for the claim amount and fee information to be passed as parameters to this function as well (remember when I asked about what happens if a fee is greater than the arbitrationCost? It's because functions like this one now need to know how much you're paying as a fee)

No, the DisputeCreation event is emitted by the Arbitrator contract.

Could you please explain this to me? If a contract is arbitrable, it means it is a contract requiring arbitration, i.e. requiring the opening of claims against it. For our staking mechanism, these arbitrable contracts are the stakes which can have claims opened against them.

When speaking with projects needing dispute resolution, the contrary opinion has emerged. There a lot of teams building products which need dispute resolution and a handful of teams working on it. The projects which need dispute resolution generally don't want to have to integrate with each dispute resolution provider, especially knowing that those projects are early stage (the whole industry is) and most of them will have failed within a few years. Integration with a standard, instead of a particular project, allows them to let their users choose their dispute resolution system instead of locking them on a particular one.

This viewpoint is admirable, and I am largely behind it, however I worry that trying to formalize this standard too early as an officially accepted EIP (instead of it simply serving as a reference for dispute resolution providers and recipients), we'll be screwing ourselves over in the future by requiring new standards to be backwards compatible. Having competitors and collaborators come together on a standard is an important part of the Ethereum developer community, however it requires a light touch, where developers are open to having their ideas questioned and overturned when the market (their users) provides them feedback that their assumptions are wrong.

In terms of including the appeals process in the standard as an extra function (which may revert for implementations without appeals), I believe this is a fine solution for the short term as we test out our implementations and figure out where they break.

It is non-trivial for all disputes to be implemented using the same contract standard, with there generally being various approaches to the dispute resolution problem which don't necessarily mirror the adjudication methods we see in the real world right now. In an effort to encourage this exploration of new and unique methods, we should try to be fluid in our development of this standard, and open to seeing it challenged and amended as we discover what works in practise.

@clesaege
Copy link
Contributor Author

clesaege commented Apr 15, 2018

Correct, but this information is entirely useless unless it is being returned to another contract for storage since it's impossible for the returned value to be passed to the sender of the original transaction (if the claim is opened by a user).

This information is always being returned to another contract. It is returned to the Arbitrable contract per

It should be called by the Arbitrable contract. It must pay at least arbitrationCost(bytes _extraData) weis.

External accounts don't create dispute. Arbitrable contracts do.


This information should be emitted in an event.

This is the case per

This method must fire the DisputeCreation event.


I would also like for the claim amount and fee information to be passed as parameters to this function as well

This is a general dispute resolution standard, claims not need to be monetary. A claim can for example be about blacklisting something (malicious ENS address, irrelevant item, spam) (see this contract for example https://github.com/kleros/kleros-interaction/blob/master/contracts/standard/permission/ArbitrableBlacklist.sol ). Thus the claimed amount cannot be part of the standard.
The fee is passed by being send from the Arbitrable contract to the Arbitrator one. It is accessible using msg.value and there obviously no need to repeat that in a parameter.


No, the DisputeCreation event is emitted by the Arbitrator contract.

Could you please explain this to me? If a contract is arbitrable, it means it is a contract requiring arbitration, i.e. requiring the opening of claims against it. For our staking mechanism, these arbitrable contracts are the stakes which can have claims opened against them.

This standard is only about interaction between Arbitrator and Arbitrable contract. External accounts interactions with the Arbitrable contract are out of scope. You can initiate a dispute at the Arbitrable level as you wish, the DisputeCreation is only emitted when this dispute is raised to the Arbitrator contract (for example if you require both parties to deposit the fees, consider parties not deposit the fee to automatically lose, if only one party deposits the fee, no dispute should be raised to the Arbitrator, thus no DisputeCreation event to be emitted).


This viewpoint is admirable, and I am largely behind it, however I worry that trying to formalize this standard too early as an officially accepted EIP (instead of it simply serving as a reference for dispute resolution providers and recipients), we'll be screwing ourselves over in the future by requiring new standards to be backwards compatible.

That's why this ERC has been put in the issue section before making a pull request per the EIP Work Flow described by EIP1 https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1.md :

In particular, the Issues section of this repository is an excellent place to discuss your proposal with the community and start creating more formalized language around your EIP.


In terms of including the appeals process in the standard as an extra function (which may revert for implementations without appeals), I believe this is a fine solution for the short term as we test out our implementations and figure out where they break.

The possibility off appeals cannot break anything. If you don't need it, don't allow appeals. At worse you lost 0.01$ when deploying your contract (only once if using a library). At best you avoided duplicating your Arbitrable contract development code.


It is non-trivial for ***all disputes *** to be implemented using the same contract standard, with there generally being various approaches to the dispute resolution problem which don't necessarily mirror the adjudication methods we see in the real world right now.

When there is no interaction between dapps (for example in the case of Augur where they both deal with dispute resolution and enforcement), there is no need to follow a standard.
Removing appeals would have the opposite effect of discouraging the exploration of new methods by locking dapps developers to dispute resolution systems where appeals are not possible.


In an effort to encourage this exploration of new and unique methods, we should try to be fluid in our development of this standard, and open to seeing it challenged and amended as we discover what works in practise.

For sure, but in the other way around (not preventing usages but allowing some). If someone were to show a dispute resolution method which could not fit in the standard, I would support modifying it (as long as it would only incurs limited extra gas cost and code complexity) in order to allow this new dispute resolution method.
Up to my knowledge, all dispute resolution systems which were proposed so far fits in the standard. If you have a reasonable usecases not fitting, feel free point toward it.
The goal of this standard is to provide the minimum number of standardized functions required for interactions between all reasonably imaginable Arbitrator and Arbitrable contracts.

@mbeylin
Copy link
Contributor

mbeylin commented Apr 15, 2018

It seems we have again found another strong difference in opinion.

For Delphi, claims are opened by people, against particular stakes. Claims ARE for monetary amounts (units of tokens, for what else could be administered on-chain otherwise?) Are you proposing that certain byte code would execute based on these claims? Is that what you intend to store in the bytes array, and not a content hash?

My desire here isn't to simply "remove appeals". We are approaching arbitration in very different manners and assuming that either approach is right from the outset is incorrect. I will apologize that I've had a bit of trouble understanding this architecture you've designed (the flow of actions between the arbitrable contract and the arbitrator contract).

Here is a list of reasons why this standard doesn't currently conform to the dispute resolution mechanism we've outlined with our arbitration mechanism:

  • our interface requires sending a claim amount, fee amount, and is generalized for people to be able to open claims on behalf of others. The current claim creation interface does not allow for this.
  • why are arbitrator fees fixed, and not simply allowed to move freely? With our design, claims can be created at any price above the minimum set by the arbitrable contract, and sit in a pool of open claims until they are ruled upon. The value of the fee (relative to the size of the claim) determines the speed with which it is adjudicated.
  • why are claims opened for an arbiter, and not just in the arbitrable contract (which is the one who must know about the claims, to determine when they may be paid out) . All of the functions pertaining to a particular dispute (its current status) should be implemented in the Arbitrable contract.
  • An arbitrable contract should be decoupled from the arbitrator, which should be no more than an address which is allowed to make rulings on particular claims

Like I said above, there are many differences in our designs, and that should be encouraged, in order to test the assumptions underlying each of them. Trying to create one standard for all possible usecases of arbitration will be very difficult, owing to the variety of instances in life where arbitration is currently used (and the many new ones which are being ideated such as the blacklisting of accounts, or other new on-chain actions).

@clesaege
Copy link
Contributor Author

clesaege commented Apr 15, 2018

for what else could be administered on-chain otherwise?

Items in lists, Oracle answers, Cryptokitties...


Are you proposing that certain byte code would execute based on these claims?

I'm proposing a system which allows the Arbitrable contracts to decide what should be done when a particular ruling is made. If you want to make and Arbitrable contract which execute a byte code of the claimer when the Arbitrator contract rules in its favor, it's perfectly possible within the standard.


Is that what you intend to store in the bytes array, and not a content hash?

No, the bytes contains specific information for the Arbitrator, this allows the arbitration process of one Arbitrator to be specific depending of the _extraData he receives. Thus an arbitration process depends of the (Arbitrator,_extraData) couple. In my example usecase, the _extraData contains the amount of jurors required and default to a particular value if no _extraData is given.


We are approaching arbitration in very different manners and assuming that either approach is right from the outset is incorrect.

That is not the case. I'm approaching arbitration from a general manner to allow every possible usecases (including yours) while you approach arbitration from a particular approach. Your approach (do you have code to link to so I can verify?) seems to be perfectly compatible with the standard.


our interface requires sending a claim amount, fee amount, and is generalized for people to be able to open claims on behalf of others. The current claim creation interface does not allow for this.

The standard interface perfectly allows this. You have to implement this in the Arbitrable contract. The interaction between external accounts and the Arbitrable contracts are out of scope of this standard. Thus nothing prevents what you do.


why are arbitrator fees fixed, and not simply allowed to move freely?

Having arbitration fees not fixed is perfectly possible within the standard. If you want the Arbitrator contract not to require a particular fee, you can make arbitrationCost to return 0. Since the Arbitrable contract must send *** at least *** the value returned by arbitrationCost, it will be able to freely decide which value to send.


why are claims opened for an arbiter, and not just in the arbitrable contract (which is the one who must know about the claims, to determine when they may be paid out) . All of the functions pertaining to a particular dispute (its current status) should be implemented in the Arbitrable contract.

You are speaking about claims, the standard does not deal with claims (this does not mean claims are impossible, just that the Arbitrable contract can implement them as the developer wishes).
The Arbitrable contract can (and in a lot of cases will) keep note of information about a particular dispute. This part is not about interactions between Arbitrable and Arbitrator contracts, thus out of scope of this standard.


An arbitrable contract should be decoupled from the arbitrator, which should be no more than an address which is allowed to make rulings on particular claims

That the particular point of this standard, decoupling Arbitrable and Arbitrator contracts.
However, arbitrators contracts, if more complex than an external account, need to make some particular actions when disputes are brought to them. Thus, they need to know when a dispute arise and if the fees are properly paid. If you want to restrict arbitrator to external accounts, you obviously don't need an kind of standardization.


Like I said above, there are *** many differences in our designs ***, and that should be encouraged, in order to test the assumptions underlying each of them.

No, there is not design difference, as the standardization of interactions between Arbitrable and Arbitrator contracts should not care about the design of those. You are making a particular dispute resolution system, I'm making a standard to allow interoperability of those (I'm also making a dispute resolution system, but that not about what this standard is for and I don't try to push the specifics of the dispute resolution system I'm working on to standardization). You are comparing a set (a standard which allow dispute resolution systems) and one element (a particular dispute resolution system). Saying that there is a design difference between a set and one of its element does not make sens.

This abstraction allows Arbitrable contract developers not to have to know the internal process of the Arbitrator contracts.

There is standard framework for interoperability which is perfectly compatible with your design (from what I understood, but again, for me to verify that I'd need to see your code).


Trying to create one standard for all possible usecases of arbitration will be very difficult, owing to the variety of instances in life where arbitration is currently used (and the many new ones which are being ideated such as the blacklisting of accounts, or other new on-chain actions).

Again, feel free to give me a usecase which will not fit in. But note that the standard is about interactions between Arbitrator and Arbitrable contracts and not about the internal specifics of those, nor about their interactions with external accounts.

@mbeylin
Copy link
Contributor

mbeylin commented Apr 16, 2018

Here is a link to the stake contract, which will be the "arbitrable" contract in the end. This work is still very much WIP and undocumented, but I think you'll quickly see that our implementation of arbitration is not the same as yours. (or maybe it is, and I've simply misunderstood)

https://github.com/Bounties-Network/Delphi/blob/develop/contracts/DelphiStake.sol

@clesaege
Copy link
Contributor Author

clesaege commented Apr 16, 2018

our implementation of arbitration is not the same as yours

Our respective implementations do not matter for standardization. Only the interaction needs to be standardized, not the implementation. I think that a lot of your previous comments are based on the wrong premise that the standard was about implementation.


(or maybe it is, and I've simply misunderstood)
https://github.com/Bounties-Network/Delphi/blob/develop/contracts/DelphiStake.sol

I effectively think you misunderstood as your implementation can be slightly modified to fit in the standard.
To do so, you need to call createDispute of the Arbitrator contract after it's sure that a dispute would arise, i.e. in settlementFailed https://github.com/Bounties-Network/Delphi/blob/develop/contracts/DelphiStake.sol#L328
You also need to transfer the fee when calling createDispute and not when the ruling is given (but note that the Arbitrator can pay the human arbitrators only when the ruling in given, so in practice, it does not change what the contract is doing from an external observer point of view). Transferring the fee after a ruling is made would lead potential of DDOS of the Arbitrator by creating disputes he has to rule while the Arbitrable contract would never pay the fees.
I however see a point where it would not fit. This is that the fees are paid in tokens, not ETH. For Arbitrator and Arbitrable contracts to be inter-operable, they must obviously accept the same currency. If you think it's worthy, you could work on standardizing payment of fees in tokens.

@mbeylin
Copy link
Contributor

mbeylin commented Apr 16, 2018

You also need to transfer the fee when calling createDispute and not when the ruling is given (but note that the Arbitrator can pay the human arbitrators only when the ruling in given, so in practice, it does not change what the contract is doing from an external observer point of view).

Why are arbiters being paid in advance when we can trustlessly pay them when they rule?

Transferring the fee after a ruling is made would lead potential of DDOS of the Arbitrator by creating disputes he has to rule while the Arbitrable contract would never pay the fees.

If arbiters simply sort their bounties by the value of their fees instead of by their time of creation (or some weighted combination), the spammy bounties will be the lowest value disputes, and can therefore trivially be ignored. Otherwise if spammy claims have a meaningful supply of fees attached, they can choose to rule on them as they please.

@clesaege
Copy link
Contributor Author

clesaege commented Apr 16, 2018

Why are arbiters being paid in advance when we can trustlessly pay them when they rule?

It's not arbiters which are paid in advance, it's the Arbitrator contract. The Arbitrator contract can pay the humans arbitrators when they rule (see for example https://github.com/kleros/kleros-interaction/blob/master/contracts/standard/arbitration/CentralizedArbitrator.sol).
Paying only after ruling would require the Arbitrator contract to vet all Arbitrable to verify that they will pay. Otherwise, Arbitrable contract could start disputes consuming resources and never pay.
The Arbitrable contracts users choose their Arbitrator contract, so they can choose non-malicious ones. So it's better to ask the Arbitrable contract to pay before engaging the procedure.


If arbiters simply sort their bounties by the value of their fees instead of by their time of creation (or some weighted combination), the spammy bounties will be the lowest value disputes, and can therefore trivially be ignored. Otherwise if spammy claims have a meaningful supply of fees attached, they can choose to rule on them as they please.

Because

  • They would need to verify that the Arbitrable contract is effectively going to pay them after they made a ruling.
  • This will trigger a dispute resolution process which can be resource consuming.

@mbeylin
Copy link
Contributor

mbeylin commented Apr 17, 2018

Paying only after ruling would require the Arbitrator contract to vet all Arbitrable to verify that they will pay

This is why the arbitrable contracts shouldn't be coupled to the arbitrators, who can choose to rule on claims they desire to (and trust) and ignore ones they don't.

The Arbitrable contracts users choose their Arbitrator contract

Why do you assume that the arbitrator must be another contract and can't simply be an individual?

They would need to verify that the Arbitrable contract is effectively going to pay them after they made a ruling.

This is trivially done on the front end by comparing byte code / the master copy which proxies point to.

This will trigger a dispute resolution process which can be resource consuming.

Again, it only triggers that process if arbiters want it to.

As you can see, a number of design differences are beginning to show themselves, and these are fine. However, trying to declare that one design should be STANDARD without any PROOF would be a terrible decision.

@clesaege
Copy link
Contributor Author

clesaege commented Apr 17, 2018

This is why the arbitrable contracts shouldn't be coupled to the arbitrators, who can choose to rule on claims they desire to (and trust) and ignore ones they don't.

That's the precise goal of this standard, providing a standard interface for coupling Arbitrator contracts and Arbitrable contracts.
By paying in the createDispute and appeal the Arbitrator can be sure that the arbitration fee is paid before engaging a dispute resolution procedure (in my usecase drawing jurors which will lock some of their tokens, in some other cases, creating a prediction market, in some cases, doing nothing in particular). By potentially consuming resources, it's important that the contract can be assured that it will be paid.
We had a choice between requiring Arbitrable contracts to be vetted or Arbitrator one. We choose the Arbitrator because:

  • Arbitrable contract must choose their Arbitrator but Arbitrator contracts (by being deployed before) don't necessarily need to choose their Arbitrable.
  • It is reasonably likely that there will be way more Arbitrable contract than Arbitrator ones.

Why do you assume that the arbitrator must be another contract and can't simply be an individual?

Another individual can be trivially put as a contract (cf: https://github.com/kleros/kleros-interaction/blob/master/contracts/standard/arbitration/CentralizedArbitrator.sol and we can do even better by using only a unique contract for centralized arbitrators which specifies the address of the centralized arbitrator in _extraData). While a smart contract based dispute resolution system need to be called for the dispute resolution process to be started.


This is trivially done on the front end by comparing byte code / the master copy which proxies point to.

They would need a list of all accepted Arbitrable contract. Would one not paying be included in the list (by fooling the reviewers), the DDOS would happen.
A front-end control would not be sufficient as when the Arbitrator contract is called, actions can be done (locking tokens of jurors, creating markets, etc).


Again, it only triggers that process if arbiters want it to.

Dispute resolution systems do not necessarily have people acting as watchdogs of what a dispute could be.


As you can see, a number of design differences are beginning to show themselves, and these are fine. However, trying to declare that one design should be STANDARD without any PROOF would be a terrible decision.

Mark, this is a standard to allow interoperability between Arbitrator and Arbitrable contract. I think you made it clear you were against standardization and that you see "design difference" (even if the only part of your system which would not fit in the standard is the payment in token on which I invite you to also standardize it) while the standard is not about design but interoperability.
When we want to let two particular types of components to interact interchangeably which each others, standardization is required.
Without standardization, interoperability is not possible.
If you are not interested by standardization of interoperability, which by your previous posts seems to be the case, I don't really know what you are doing in this discussion except being rude (shouting, because that is what the use of capitals means in writing), opposing everything and trying to promote your project (you mentioned your project 4 time while I just mentioned mine along a list of others competitors once). The issue section of ERC is not a place to talk about project specifics and standardization should be project independent.
If you think you have some constructive input which can be used toward the goal of the ERC and express them in a polite manner feel free to do so. Otherwise I think you can have a better use of your time than trying to prevent people working for interoperability.

@mbeylin
Copy link
Contributor

mbeylin commented Apr 17, 2018

That's the precise goal of this standard, providing a standard interface for coupling Arbitrator contracts and Arbitrable contracts.

Then this should not be promoted as an "arbitration standard", when it only covers specific cases of arbitration.

I think you made it clear you were against standardization and that you see "design difference" (even if the only part of your system which would not fit in the standard is the payment in token on which I invite you to also standardize it) while the standard is not about design but interoperability.

I am absolutely not against standardization, I have spent the last year pushing for standardization among bounty implementations on Ethereum, which is why I can tell you first hand that standards should evolve and not be enforced in a heavy handed manner. I resent any implication that my hesitation here is because I don't want a standard to exist, since my goal is very much the opposite. But standards must be administered in a prudent manner.

When we want to let two particular types components to interact interchangeably which each others, standardization is required.

This is true, but a standard for arbitration doesn't need to know anything about who is adjudicating the claims (similarly to how the ERC20 contract doesn't know anything about which contract or individual is transacting with tokens).

If you would like to have a standard for Arbitrable contracts, then it should not be coupled to any Arbiter contract. A second standard for Arbiters may be developed independently, and the Arbiters can make sure they are compatible with the Arbitrable contract, but there's no reason for the bidirectional coupling.

Without standardization, interoperability is not possible.

This is only half true, it's entirely possible to pursue interoperability in the short term by working with select groups on connecting Kleros to their dispute resolution needs (and competitors can do so similarly, either following the same interface or a different one). Then, once we have a better understanding of user needs, we can develop a standard. Trying to develop a standard for your product before you have any users is opposite to every product development best practise that exists in the world, and entirely ignores the needs of your future users as they arise.

If you think you have some constructive input which can be used toward the goal of the ERC and express them in a polite manner feel free to do so.

I have tried repeatedly to explain to you why the standard you are developing differs from the way we have built and architected arbitrable contracts (stakes).

Otherwise I think you can have a better use of your time than trying to prevent people working for interoperability to do.

I am not intending to prevent you from rushing into interoperability, I am attempting to prevent an ERC from being formally proposed which not only doesn't agree with other implementations for Arbitration on Ethereum, but is based on no user data about what actual needs will be when launched into production. As I said above, interoperability can be pursued with partners without proposing an ERC; we've done this fruitfully with standard bounties for over a year, and as it turns out, our initial implementation was not complete, and as we gained users, we learned why it was lacking. If we had proposed a standard from the outset, there would be significant complexity from having to support multiple versions simultaneously (and in perpetuity).

As I stated from the outset, we have significant differences in our implementations, and either one of us calling our ideas for Arbitration "complete" would be foolish. I wish you the best of luck with exploring an architecture of tight coupling between arbitrable and arbiter contracts, while we desire to decouple these components as much as possible. Neither of us has hard evidence about why our design pattern is best, so we should wait and collect that evidence before pushing an ERC forward.

@mbeylin
Copy link
Contributor

mbeylin commented Apr 17, 2018

And for the record, my mention of "my product 4 times" in no way is meant to promote it (who am I promoting it to? other developers who browse EIPs? Those are unlikely going to make up the bulk of an arbitration user base).

I mentioned our product because we have implemented a version of Arbitration that differs very strongly from yours. Not only does your design require high coupling between projects (dApp smart contracts) and arbitrators, it assumes that one single interface for arbitration can be used in all cases where dispute resolution is required.

I apologize that my comments to you seem rude, I've tried to express my disagreement with your view on multiple occasions, and instead of attempting to understand my point of view, you ignore it. We spent 45 minutes on a call during which you repeatedly tried to explain to me about the importance of an "appeals" process, instead of looking at our design differences from a broader perspective. I really don't intend to stunt your growth or hinder your efforts towards interoperability, but there are real-life, long term consequences of building and pushing EIPs forward. For a component as critical to trust transactions as arbitration, we should make sure we get it right.

Also for the record, my use of bold text and upper case letters is meant to serve to emphasize certain points, not to "shout" at you.

@clesaege
Copy link
Contributor Author

We spent 45 minutes on a call during which you repeatedly tried to explain to me about the importance of an "appeals" process, instead of looking at our design differences from a broader perspective.

Mark, since you are misreporting our interactions, I would not interact with you anymore. The issue section of an ERC is not a place for personal attacks. Your point of view has been understood. Good luck on your ventures. Further off topic comments will be reported to an EIP editor.

@mbeylin
Copy link
Contributor

mbeylin commented Apr 17, 2018

The issue section of an ERC is not a place for personal attacks.

Was your above comment not littered with personal attacks on my character?

If you decide you are interested in actually collaborating on a standard for Arbitration on Ethereum (and not simply formalizing your teams approach into a standard that others must conform to), I would be happy to help.

@clesaege
Copy link
Contributor Author

Coming back to improvement proposals, what do you think of adding the possibility to pay in tokens?

@clesaege
Copy link
Contributor Author

You can review the evidence standard proposal https://docs.google.com/document/d/1AsGt_Am2rbZwCd6FULfl4ssMIlo_WZVhjo8V7ZFztmo/ . If there is no issues found we'll submit it as an ERC.

@TimDaub
Copy link
Contributor

TimDaub commented Feb 6, 2019

Great standard. A minor thing:

function rule(uint _dispute, uint _ruling)

Why is uint _dispute not called uint _disputeID?

@clesaege
Copy link
Contributor Author

clesaege commented Feb 6, 2019

Thanks @TimDaub for the remark, I just fixed this (note that it does not lead to any backward compatibility issues as variable names are not used when creating the function signature).

@greenlucid
Copy link
Contributor

I propose adding the following to IArbitrable:

function changeArbitrator(address _newArbitrator) external;

This would change the Arbitrator the Arbitrable calls to a new one. I am a bit conflicted with this, as it might be limiting to Arbitrables that do not wish to add this function, but it's too common of an use case to simply ignore. Arbitrables lacking this function will be forced to die or migrate to a new contract if:

  • Arbitrator is compromised
  • Arbitrator is deprecated and jurors migrate to a new one
  • Arbitrable decides Arbitrator no longer can cover its needs
  • Better Arbitrators are available (cheaper, faster, or bigger quality) and Arbitrable wants to swap

In practice, it would be accompanied by an onlyGovernor modifier. What do you think? Is this limiting?

@cbruguera
Copy link

@clesaege Has there been any updates to this proposal with the option to pay fees in tokens? I was checking the Kleros implementation but I think fees are paid in ETH. I was wondering if the standard as it's been currently proposed can easily allow the pay-in-tokens possibility or it would need some changes. I think this is important if aiming to become an interoperable standard.

@cbruguera
Copy link

I propose adding the following to IArbitrable:

function changeArbitrator(address _newArbitrator) external;

This would change the Arbitrator the Arbitrable calls to a new one. I am a bit conflicted with this, as it might be limiting to Arbitrables that do not wish to add this function, but it's too common of an use case to simply ignore. Arbitrables lacking this function will be forced to die or migrate to a new contract if:

* Arbitrator is compromised

* Arbitrator is deprecated and jurors migrate to a new one

* Arbitrable decides Arbitrator no longer can cover its needs

* Better Arbitrators are available (cheaper, faster, or bigger quality) and Arbitrable wants to swap

In practice, it would be accompanied by an onlyGovernor modifier. What do you think? Is this limiting?

I think your idea assumes that an Arbitrable contract only has one Arbitrator, which (as the proposal makes clear) is not necessarily the case. Arbitrable contracts could have a list of multiple arbitrarors and their own complex logic for choosing or changing those according to the case. What needs to be standardized is the interface of function calls between Arbitrable and Arbitrator, which this proposal seems to cover IMO.

@cbruguera
Copy link

@clesaege In case you check this, I'm dealing with the question of how does an Arbitrator provide additional data specific to a ruling?... For example, Arbiter is deciding on a dispute over staked tokens, therefore should be able to execute rule for slashing a specific amount. The current ruling parameter only offers discrete options, and there's no "extraData" proposed for the rule function... Any ideas?

@github-actions
Copy link

There has been no activity on this issue for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added the stale label Dec 19, 2021
@github-actions
Copy link

github-actions bot commented Jan 2, 2022

This issue was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment.

@github-actions github-actions bot closed this as completed Jan 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants