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

Off-chain order generation by smart contracts #1

Closed
willwarren89 opened this issue Apr 24, 2017 · 22 comments
Closed

Off-chain order generation by smart contracts #1

willwarren89 opened this issue Apr 24, 2017 · 22 comments

Comments

@willwarren89
Copy link
Contributor

willwarren89 commented Apr 24, 2017

Motivation:
In the current version of 0x protocol, Ethereum accounts can both generate and fill orders. Smart contracts are not capable of generating 0x orders as they do not possess a private key with which to produce an ECDSA signature; however, smart contracts are capable of filling 0x orders that are passed to them as args. This limitation prevents Ethereum smart contracts that hold a balance of ERC20 tokens from generating liquidity via 0x protocol.

Example:
Melonport is a platform for creating and operating investment funds. Limited partners (LPs) invest their
Ethereum-based assets with a fund manager (GP) who may then invest LP funds in a set of ERC20 tokens. To prevent the GP from simply stealing LP funds, they are stored within an Ethereum smart contract that places a set of constraints on how the GP moves the assets. As a result, the GP is unable to generate an order to trade LP funds via 0x protocol but they are capable of filling 0x orders generated by others.

Proposed Solution:
Allow the owner of a smart contract to generate 0x orders on behalf of the smart contract.

zerc1 diagram

Draft pseudo-code, going to provide more detail later.

@willwarren89 willwarren89 changed the title 0xRC 1: Ethereum accounts generate orders on behalf of smart contracts 0xRC 1: Support order generation by smart contracts Apr 24, 2017
@willwarren89 willwarren89 changed the title 0xRC 1: Support order generation by smart contracts ZERC 1: Support order generation by smart contracts May 4, 2017
@abandeali1 abandeali1 changed the title ZERC 1: Support order generation by smart contracts ZERC1: Support order generation by smart contracts Jul 6, 2017
@abandeali1 abandeali1 changed the title ZERC1: Support order generation by smart contracts Support order generation by smart contracts Jul 11, 2017
@abandeali1 abandeali1 changed the title Support order generation by smart contracts Order generation by smart contracts Jul 11, 2017
@kingcocomango
Copy link

I believe a better solution would be allow contracts to define their own verify function, that the 0x protocol could use to verify their consent. I think this is a better solution because it allows contract logic to handle transfers entirely, and because this future-proofs against contract and EOA being merged.

@Eugenpaul
Copy link

What is the status of this issue? Any plans to implement this?

@willwarren89
Copy link
Contributor Author

willwarren89 commented Aug 29, 2017

@kingcocomango Can you provide a reference that explains what you mean by this future-proofs against contract and EOA being merged? It would also be informative if you could explain how you envision a contract's verify function working. Diagrams are encouraged.

@Eugenpaul I'm not satisfied with the solution outlined in the OP and would like to do further research before any implementation is considered. I think implementing a naive solution could do more harm than good as it may eventually need to be replaced, creating unnecessary work for those that are building on top of the protocol.

@kingcocomango
Copy link

As far as I understand, at some point with or after metropolis "regular" accounts will also be contract accounts, and can use any arbitrary cryptographic method or functions to secure their funds and decide what is a valid transfer from them etc.

The OP relies on the current standard ECDSA setup, which won't be required for regular accounts in the future, that's what I meant by future-proofing.

As for the verify function, I imagined where 0x currently tries to verify a ECDSA signature it instead checked the code size of that party, and if it has code called a verify function to see if it consents to the trade. Probably with a more unique name to avoid any collision.

I'll add diagrams in an edit.

@gusevda
Copy link

gusevda commented Aug 30, 2017

I am interested in this feature as well. From your site:

0x protocol will act as a critical piece of infrastructure for the token economy, allowing Ethereum smart contracts to programmatically and seamlessly exchange Ethereum-based assets.

But it's not possible at the moment, so are there any real plans?

@abandeali1
Copy link
Member

@kingcocomango I think that allowing contracts to define their own verification process introduces too much unpredictability (potentially some attack vectors as well). This also makes it such that traders and relayers would have to verify each order with its own custom logic, rather than a universal verification algorithm.

I think the initial proposal works well for this very specific use case (managing a fund), but not necessarily for more general use cases (like a deposit contract). It's efficient -- I don't see how you would ever be able to sign on behalf of a contract without at least one on-chain transaction. With a few tweaks, this proposal could allow a signer to trade an unlimited amount of tokens on a contract's behalf with exactly one on-chain transaction.

My concerns are that this would introduce a race condition (a contract can disallow a signer before a trade is settled) and that it would be difficult to upgrade. If we ever upgraded the API for this functionality, we would have to assume that any contracts using it are also able to upgrade.

@kingcocomango
Copy link

I agree that allowing custom verification logic is more complicated, but ethereum is already preparing to move away from a universal verification algorithm.

I also agree that the initially proposed solution is limited in scope, it wouldn't allow , for example, a situation where a contract has a voting system and the trading has conditions other than just volume of trade. It also means that issuing an order can't be a side affect, such as for example some contract that issues trades once a quorum has been reached, with the last vote triggering a trade.

This locks out organizations, groups and projects that are trying to keep the gurantees and controls on-chain.

@abandeali1
Copy link
Member

abandeali1 commented Sep 15, 2017

I know that Ethereum is moving away from ECDSA only, but it will probably take a good deal of time for new standards to take hold. It also does not mean that 0x has to move away from ECDSA or support other cryptographic schemes. I think it's probably too early to make decisions around standards that might come to be. We need to add features with upgradeability and backwards compatibility in mind, though.

I also agree that the initially proposed solution is limited in scope, it wouldn't allow , for example, a situation where a contract has a voting system and the trading has conditions other than just volume of trade. It also means that issuing an order can't be a side affect, such as for example some contract that issues trades once a quorum has been reached, with the last vote triggering a trade.

I think this is a slightly different issue, because it essentially requires the voting system to approve an order on-chain (ideally an account could sign on behalf of a contract off-chain). I do think it has value though, and I will create a separate ZEIP for this.

EDIT: I'm going to modify the name of this ZEIP. The focus of discussion will be on how a valid order can be generated by a smart contract off-chain.

@abandeali1 abandeali1 changed the title Order generation by smart contracts Off-chain order generation by smart contracts Sep 15, 2017
@kingcocomango
Copy link

Ah. From my understanding of how contract style user accounts would work, either 0x would need to support alternate schemes or it would only work with accounts that stuck with ECDSA as otherwise the actors actually controlling the account and the ones with the ECDSA keys for the account might not be the same.

@abandeali1
Copy link
Member

Yeah, I've had a bit of a change of heart on this after digging into account abstraction more. It seems that all accounts will contain some validation code, so I'm assuming there will be some standard way to verify them as well. If this is the case, this ZEIP might just become obsolete by default.

@MicahZoltu
Copy link

MicahZoltu commented Oct 30, 2017

At the moment, one of the fields in an order is the maker address and when the order is validated require(maker == signer). This change talks about how the approval will work, but I don't see it mention how order signing would work. Would the logic simply change to require(maker == signer || approvals[maker][signer])? This way the signer (trader) can set the maker to anyone who has approved him as a signer?

@abandeali1
Copy link
Member

@MicahZoltu That's the gist of it. Alice would call some function within the Exchange contract that approves Bob to sign on her behalf. Now Bob can create valid orders with Alice as the maker.

@AntonioJuliano
Copy link

For the deposit contract case we want contract C to hold funds for Alice. When Alice wants to trade, we want her to be able to generate orders off-chain that use her as the signer but C as the maker.

I think the first step (as people have been mentioning) is to split out the maker field into maker and signer. The second step (as @kingcocomango mentioned) is to add an interface which any contract can implement to verify an order. Then add a check:

// Interface a contract would need to implement to verify an off-chain order
contract OrderVerifier {
    function verifyOrder(
         address[6] orderAddresses, // Add one more address for the signer field
         uint[6] orderValues
         // Signature unnecessary as it is checked by exchange contract
    ) returns (bool _isValid) { // However the contract wants to verify the order }
 ...

contract Exchange {
   function fillOrder(...) {
        ...
        require(
            order.maker == order.signer
            || OrderVerifier(order.maker).verifyOrder(// order args)
        );
    ...

In a deposit contract, verifyOrder would just check that the maker has enough deposited balance, and would then update its internal balances to reflect the result of the trade. I think this approach is quite general, and would allow for other types of verification as well.

The initial example by @willwarren89 of a Melonport GP creating off-chain orders could be achieved by simply checking require(isApprovedGP(signer)); in Melonport's verifyOrder function. Or, if they wanted to get fancy and impose restrictions on the amounts or prices at which the GP could offer trades, they could implement more complex logic checking their contract's state in verifyOrder.

@abandeali1
Copy link
Member

@AntonioJuliano, this is one of the approaches we are considering. I think to truly take advantage of deposit contracts though, the deposit contract would need to be able to update the internal balance of order.signer as well (unless each user is required to have their own wallet contract).

I think the end solution involves something like your proposal in combination with support for trading tokens internally in deposit contracts with a standard interface.

@svechinsky
Copy link

@abandeali1 doesn't the proposed solution already support it? It already passes the signer address so I don't see why the contracts fill order function wouldn't be able to update it's internal balance.

@abandeali1
Copy link
Member

The issue is that token balances are updated within the token contracts, not within the deposit contract. So the deposit contract (currently) has no way of knowing that a trade occurred.

BTW when I reference deposit contracts, I mean a contract with an internal mapping of owner => token => balance, in case that's not clear.

@svechinsky
Copy link

@abandeali1
I understand . I think that this is can be easily solved inside the verify function by checking that the message sender is the 0x exchange contract and then performing the internal update. There is no reason for the 0x contract to call the deposit contract aside from trying to execute an order so the deposit contract can assume that if it this function gets called from the exchange and the return value is true then an order is going to be executed.

The same mechanism holds for on chain orders if the on chain place order contract is separate from the exchange contract and they have different addresses.

Only possible issue is that this forces the maker signature validation to be the last step before trade execution.

@AusIV
Copy link

AusIV commented Jan 30, 2018

I've been pondering this over the last few hours since the vide conference. One idea that crossed my mind was that contracts could register an authorized signing address with the 0x exchange contract, along with an expiration. Relayers could watch for events logged so they know what contracts have authorized what addresses. Authorizations would be irrevocable, but the expiration timestamp would mean contracts don't have to trust the signer indefinitely. This avoids race conditions around revocation of authorization vs trying to fill orders, and since the 0x contracts keeps the list of authorizations, the contracts can't deny authorizations after the fact.

I still think I hold the opinion that this should wait to see how account abstraction shakes out, but I wanted to throw the idea of an expiration date for the authorization into the mix.

@svechinsky
Copy link

@AusIV I think this is preventing a lot of potential use cases of 0x and should be solved asap.
Changes can always be made later when the account abstraction is done.

@AusIV
Copy link

AusIV commented Feb 2, 2018

@svechinsky - There had been a video conference a few hours before I made that post, in which the sentiment was that on chain order generation by smart contracts should be in the next release, but off chain order generation had a number of additional challenges, and it made sense to see how some of those challenges were addressed by other projects as account abstraction came up.

@sahil107
Copy link

#376

@sahil107
Copy link

#376 Signature generalisation in 0xProject/0x-monorepo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants