Closed clesaege closed 2 years ago
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
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.
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?
Another solution would be to add a disputeStatus
function returning an enum {awaiting, appealable, final}
.
I like better the second solution.
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.
@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: https://github.com/ethereum/EIPs/issues/777 .
@SerpentChris
I looked more into it and we may be able to have better typing when https://github.com/ethereum/solidity/issues/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.
I added the disputeStatus
to the standard.
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.
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).
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:
Arbitrable
contracts to Arbitrator
ones. It has a disadvantage of slightly increasing the deployment cost of contracts due to the arbitrationCost function.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.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 aDisputeRuled(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$.
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.
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 leastarbitrationCost(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.
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:
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).
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 theArbitrator
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.
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
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.
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.
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
Arbitrable
contract is effectively going to pay them after they made a ruling.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.
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
.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.
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.
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.
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.
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.
Two strong opinions, we need an arbitration standard for that...
By the way, for those who want to participate in the initial discussions and write-up of the evidence standard feel free to list your usecases and comments there: https://docs.google.com/document/d/1QaCSTZoTjd63q7pt4wne6Mj62p8Ru8xOrxYE5Skyd3c/edit?usp=sharing
While speaking with developers of origin @wanderingstan , came the proposal to extend this standard to allow payments to be made in token.
It would involve adding a function to return which token is accepted (or 0x0 is the Arbitrator
accept ETH) by an arbitrator and the possibility of Arbitrator
contracts to use transferFrom
in createDispute
and appeal
instead of checking the amount of wei sent.
In case the Arbitrable
contract and the Arbitrator
one do not want to deal with the same kind of tokens, an Arbitrator Currency Middleware could be used to make on the fly conversion.
@clesaege now that some time has passed, I want to enquire again whether you'd be interested in generalizing this EIP/ breaking it up into two separate EIPs: one for arbitrable contracts and one for arbitrator contracts, whereby the arbitrable contracts never make calls to the arbitrator contract (only storing the arbitrator to validate when they make decisions). This would allow both of our approaches to potentially rely on the same standard (with some overlap), rather than pursuing these different approaches entirely independently.
@mbeylin I stated in the previous posts, what you do can perfectly be done with this standard and there is no different approaches, your approach is included in this standard (except the payment in tokens that my previous post proposed to add).
We can however discuss about moving the createDispute
and appeal
to the level of the Arbitrable
contract.
The advantage of this proposal I see are:
Arbitrator
contracts get the freedom to choose who pay the fees.The disadvantage:
Arbitrator
contracts would need to know the parties in the dispute who have the right to create a dispute and appeal. This seems quite complicated in practice as the parties may not be known in advance. And the only way I would see this if everyone were able to create a dispute. But then, there would be competing disputes and the Arbitrable
would follow the first to resolve.Arbitrator
contract all the time, even there is no dispute.Arbitrator
contract in addition to the Arbitrable
ones. For example in a simple payment dispute, they would need to create a dispute in the Arbitrable
contract (to make sure that the payment is delayed up to the result of the arbitrators) and in the Arbitrator
one this lead to more gas spending and higher code complexity (thus risk of bugs).Arbitrable
contracts would loose the freedom to determine the fees.Overall, this proposal seem to fit only the case where an external account is the arbitrator but not the cases where the arbitrator is a more complex smart contract.
@clesaege by putting the createDispute function into the arbitrable contract, aren't there significant benefits around:
It's also unclear to me why the fee is paid to arbiters when a dispute is created- wouldn't it make more sense for the fees to be sent to the arbiter at the time when they properly rule on the claim?
It's also unclear to me why moving createDispute into the arbitrable contract would require the arbitrator to know anything about who is capable of creating the dispute or what happens to funds in the interim (this logic may live in the arbitrable contract).
Contracts may enforce the notion of only one dispute being opened at a time, rather than allowing competing disputes (again its unclear to me why this logic is at all related to the arbiters themselves).
It would require an interaction with the Arbitrator contract all the time, even there is no dispute.
Could you explain this a bit more? I'm not sure I follow.
Interaction complexity and quantity would increase, the parties in the dispute would need to interact with the Arbitrator contract in addition to the Arbitrable ones. For example in a simple payment dispute, they would need to create a dispute in the Arbitrable contract (to make sure that the payment is delayed up to the result of the arbitrators) and in the Arbitrator one this lead to more gas spending and higher code complexity (thus risk of bugs).
Again you allude to the need for users to interact with the arbitrator contract in-protocol, but again it's not clear why.
Arbitrable contracts would loose the freedom to determine the fees.
This is categorically false: if arbitrable contracts are creating disputes with a given fee, and communicate this dispute to arbiters out-of-protocol, then arbiters may freely decide to rule on claims which provides a sufficient fee to satisfy them, and ignore those which don't. This allows the prices for dispute resolution to move much more freely than in your current implementation (where the price must for some reason be set in the contact). The problem of pricing is compounded when you start to think about fees paid in a myriad of tokens: how many units of a given token that will be sufficient to incentivize arbiters may change over time, and allowing arbiters to ignore claims which are insufficient is a great solution. Since the initiators of claims are always incentivized to get their claims resolved as quickly as possible, we know they'll always seek pricing information on current arbiter fees (out of protocol), and pay the necessary fees.
This fee structure begins to resemble the way transaction markets work on Ethereum: the protocol doesn't reject transactions which are below a fee which is explicitly set by miners, they simply wait in a pool of txns until the volume is such that they get picked up.
@clesaege by putting the createDispute function into the arbitrable contract, aren't there significant benefits around:
- limiting who may create disputes for a given type of smart contract
- freezing assets/state in the contract pending a ruling
I think you mean requiring parties in a dispute to interact with the Arbitrable
contract instead of the Arbitrator
one. And that exactly what the standard requires. Parties in a dispute interact with Arbitrable
contracts and never with the Arbitrator
one. So when they start the process to create a dispute, the Arbitrator
contract could freeze fund. The standard has the behaviour you want.
It's also unclear to me why the fee is paid to arbiters when a dispute is created- wouldn't it make more sense for the fees to be sent to the arbiter at the time when they properly rule on the claim?
The fee is not paid directly to the arbiters when a dispute is created, it is paid to the Arbitrator
contract which can then pay the individuals doing the arbitration work when it's done. See https://github.com/kleros/kleros-interaction/blob/master/contracts/standard/arbitration/CentralizedArbitrator.sol and https://github.com/kleros/kleros/blob/master/contracts/Kleros.sol as examples. So again the standard has the behaviour you want.
It's also unclear to me why moving createDispute into the arbitrable contract would require the arbitrator to know anything about who is capable of creating the dispute or what happens to funds in the interim (this logic may live in the arbitrable contract).
Because the Arbitrator
would need to know who can can create a dispute. While in the current proposal, this logic is given to the Arbitrable
contract.
If the parties where to interact directly with the Arbitrator
, the Arbitrable
contract would not be aware that a dispute is raised and could not freeze assets (unless there is other interactions).
Contracts may enforce the notion of only one dispute being opened at a time, rather than allowing competing disputes (again its unclear to me why this logic is at all related to the arbiters themselves).
Yeah, they can do so with the current proposal: since creating disputes must go through the Arbitrable
contract, it can restrict dispute creation to only one per X. If it was possible to create them directly through the Arbitrator
one, it could not restrict the amount of disputes (or would need to restrict it to one per Arbitrable
contract which would cause issues when an Arbitrable
contract can handle multiple disputes).
Again you allude to the need for users to interact with the arbitrator contract in-protocol, but again it's not clear why.
No I don't, my previous post was just a though experiment of what would happen if we were to move the createDispute
to the Arbitrable
contract. It is not what I propose. So again, the proposal seem to be conform to you wishes.
Arbitrable contracts would loose the freedom to determine the fees.
This is categorically false: if arbitrable contracts are creating disputes with a given fee, and communicate this dispute to arbiters out-of-protocol, then arbiters may freely decide to rule on claims which provides a sufficient fee to satisfy them, and ignore those which don't.
Sorry for the confusion, I mean determine who pays the fee. In the current proposal Arbitrator
determines the amount of the fees. So it still behave as you wish.
This allows the prices for dispute resolution to move much more freely than in your current implementation (where the price must for some reason be set in the contact).
No, the Arbitrator
contract determines a minimum, it's possible to pay more and it is possible for arbitrators to change the amount required. It then allow you to do what you just explained.
Overall everything can behave as you declared you wish it to behave (except paying in token, thus my previous post proposing to add it).
The fee is not paid directly to the arbiters when a dispute is created, it is paid to the Arbitrator contract which can then pay the individuals doing the arbitration work when it's done.
But why bother putting the funds in the arbitrator contract in the first place ahead of time, why not just pay out when the decision is submitted? Why is this extra trust being placed on the arbitrator contract (to not allow funds to be taken without ever submitting a ruling) instead of just programming the arbitrable contract to remove this problem altogether?
I think the key in my mind, as a developer who would rely on this standard for only the arbitrable
contract (and not the arbitrator
contract), is that the contract should not be required to make any assumptions about the address which acts as an arbiter- whether it be an individual or a group. Right now the two contracts are tightly coupled: the arbitrable
contract must be calling the arbitrator
to discover minimum fees and to notify them (for instance). Do you think it would be possible for us to relax these assumptions to support this use case?
But why bother putting the funds in the arbitrator contract in the first place ahead of time, why not just pay out when the decision is submitted?
Because otherwise, malicious parties could start an expensive process without paying.
But why bother putting the funds in the arbitrator contract in the first place ahead of time, why not just pay out when the decision is submitted?
Because the parties trust the Arbitrator
contract as they would not have chosen it otherwise.
Note that requiring to have a ruling would not provide anymore protection as malicious arbitrator could just rule randomly.
I think the key in my mind, as a developer who would rely on this standard for only the
arbitrable
contractThis standard is for interoperability between
Arbitrable
andArbitrator
contracts, if you don't have anyArbitrator
contract, you don't need to use this standard.Do you think it would be possible for us to relax these assumptions to support this use case?
No, the purpose of this standard is to have this coupling. We discussed previously the effects removing this coupling would have and your previous post showed that you wanted property only possible with this coupling.
@mbeylin Your posts show that you are not interested nor needing what this standard is doing. That's completely fine and we do not try to force you to do anything. I think it would be better to start some other discussion (on the Ethereum forum for instance) in order to keep the comments there for people working to improve this standard. And come back to the previous discussion topic.
Coming back to improvement proposals, what do you think of adding the possibility to pay in tokens?
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.
Great standard. A minor thing:
function rule(uint _dispute, uint _ruling)
Why is uint _dispute
not called uint _disputeID
?
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).
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:
In practice, it would be accompanied by an onlyGovernor modifier. What do you think? Is this limiting?
@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.
I propose adding the following to IArbitrable:
function changeArbitrator(address _newArbitrator) external;
This would change the
Arbitrator
theArbitrable
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.
@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?
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.
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.
Abstract
The following describes a standard of
Arbitrable
andArbitrator
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 theArbitrator
contracts. Neither doArbitrator
contract developers withArbitrable
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 functionscreateDispute
andappeal
of theArbitrator
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 uniquearbitrator
which can't be changed, thearbitrator
part can be omitted internally. This contract must implement enforcements ofruling
. Forruling
, the value0
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 callrule
when all appeals are exhausted. It must reverts in case of failure. It must fire theRuling
event.NOTE: The
Arbitrator
contract should not assume thatrule
will be successfully executed. A malicious (or buggy)Arbitrable
contract could makerule
revert.Events
Ruling
Must trigger when a final ruling is given.
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 theArbitrator
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 sameArbitrable
contract, even during the same dispute. ThereforeArbitrator
contracts MUST NOT assume_extraData
to be constant across disputes and appeals. NOTE: Arbitration (resp. appeal)fee
can change, thereforeArbitrable
contracts should call this function each time it is relevant and not assume thefee
are the same as in the last call. NOTE: If theArbitrable
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.appealCost
Returns the cost of appeal
fee
in wei required to appeal the dispute(arbitrator,_disputeID)
.createDispute
Create a dispute. It should be called by the
Arbitrable
contract. It must pay at leastarbitrationCost(bytes _extraData)
weis. The parameter_choices
indicates the maximum value_ruling
can take. So for a binary ruling,_choices
should be2
(0
to refuse to give a ruling,1
for giving the first ruling and2
for the second). This method must fire theDisputeCreation
event. TheArbitrator
contract should assign a uniquedisputeID
identifier to the dispute and return it.appeal
Appeal the dispute
(arbitrator,_disputeID)
. It should be called by theArbitrable
contract. It must pay at leastappealCost(uint _disputeID, bytes _extraData)
weis. This method must fire theAppealDecision
event.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)
.currentRuling
Return the
ruling
which will be given if there is no appeal or which has been given.disputeStatus
Return the
status
of the ruling.with
NOTE: The value
solved
does not necessarily means that the functionrule
was called. It means that the ruling is final and that it won't change.Events
DisputeCreation
Must trigger when a dispute is created.
AppealDecision
Must trigger when the current ruling is appealed.
AppealPossible
Must trigger when appealing a dispute becomes possible.
Rationale
Arbitrator
of anArbitrable
contract allowsArbitrable
contracts to have multiple arbitrators and to change them.Arbitrable
contract to pay the fee (opposed to requiring users to directly interact with theArbitrator
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.ruling
, reserving the value0
for absence of ruling allows arbitrators to refuse to rule.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.appeal
is possible, as theArbitrator
contract just has to return an arbitrary high value inappealCost
to indicate that appeals are not possible.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 allowsArbitrable
contracts to choose to give higherfee
than required, for example if thosefee
are used as an incentive for arbitrators, in order to provide incentives higher than the minimum.disputeStatus
allows contract and users to know if a ruling has been given and if it is final.currentRuling
allows contracts and users to know whichruling
would be given if there is no appeal and make their appeal decisions accordingly. Combined withdisputeStatus
, it allows other contracts to take actions depending of the result of a dispute. This can be used to enforce contingency fee payouts.Implementations
Example implementations are available at
Presentation on how to make your own implementation: