0x v4 specs feedback (WIP)

UPDATED WITH FINALIZED SPECS

Opening a forum thread on the upcoming v4 release.
The goal is to collect early feedback from all the integrators and market makers that we couldn’t reach in the last few weeks of ideations.

As specified in November (slides, post recording video), 0x v4 proposes to make the Exchange Proxy design used by Matcha and other 0x API /swap/v1 integrators (Metamask Zapper.fi) the canonical v4 entry point and architectural foundation for all subsequent releases.

We changed the location of the protocol specs, which are going to be hosted here

Relevant sections to formulate feedback and get ready for the release:

  • Orders
    • limitOrder
    • rfqOrder
  • Architecture. This section highlights the high-level architecture of the v4 pipeline, and its different components (Proxy, Features, Transformers, FlashWallet…)
  • Events
  • Functions
    • Roughly same interfaces as v3, notable changes
      • Vanilla Fill(), Vanilla FillOrKill() available
      • FQT to perform MarketSell/Buy (and aggregation)
      • No matchOrders - no significant usage
      • No batchFillsX - no significant usage
      • batchCancels, batchCancelPairOrdersUpTo(pair)
  • Advanced topics such as using meta-transactions, setting affiliate fees, combining ERC20 transformations.
  • Releases (mainly used for 0x API and RFQ upgrades)

Some notable changes vs v3:

  • there are going to be two separate order types, with their own set of functions compatibilities (check them here)

    • limitOrder notable changes vs V3
      • no asset data encoding necessary - just token addresses
      • Removed makerFee
      • takerFee always paid in taker asset
    • rfqOrder notable changes vs V3
      • no protocol fees charged
      • no asset data encoding necessary - just token addresses
      • No taker/maker fees
      • No sender field
      • Uses txOrigin to enforce check on txn.origin
  • this release is ERC20-only. 0x V3 and 0x stack (Mesh, 0x API /swap, /meta-txn and /sra) will still have instances/(frozen) codes compatible with v3. 0x V3 contracts will not be discontinued

  • the new architecture allows for a multitude of upgrades to be introduced without requiring breaking changes, removing the need of yearly monolithic upgrades. In particular, Transformers allow operations on exchanged assets (for example, it is used for WETH unwrapping) without introducing risk factors (no audits needed).

I like what you guys have done with gas efficiencies and slimming up the order data.

Just to clarify, anyone could use the rfqOrder data, right? Even if they’re not necessarily using it for the RFQ service.

I like the concept of the txOrigin as opposed to the taker. Could you illustrate some examples of txOrigin in action? Does the txOrigin always pay for the gas for the trade even if theyr’e trading on someone else’s behalf?

1 Like

I’m also liking the idea of supporting multiple txOrigins. It sounds like you guys have may have chatted about this internally and may even already have solutions:

  • A whitelisted on-chain registry of txOrigins
  • having txOrigins be an address array

I personally would find this very useful right away in the scenario where I want to allow a known set of users/traders/operators to submit the trade for a system. Below are examples of why I’d want multiple txOrigins:

  • The one who’s submitting the tx on chain may be chosen from a pool of individuals/participants.
  • If the participant who’s supposed to submit the tx, fails to within x seconds, a pre-selected backup participate could submit it. The backup will also be whitelisted.
  • Each participant may have multiple addresses.
1 Like

confirming that anyone could use rfqOrder. In fact, it might be useful also for very basic marketplaces where there’s no need to set fees or any other specific use cases other than enforcing who’s signing the txn and submitting it onchain (tx.origin).

Regarding the gas question, I think the answer is yes. Even in case of a executeTransaction (meta-txn), a tx.origin field would have to be set on the address that is broadcasting the txn. @hysz do you confirm?

Interesting concepts, so far I understand v4 will focus more on ERC20 trading being the strategy focusing on limit and rfq orders. How hard it will be to expand this to stop limit orders using Uniswap oracle pricing (or ZRX create one oracle integrated pricing as well) expanding these type of orders to be used in almost every available pair, this will be included on transformer feature? Or can be a primitive as is limit and rfq order.

Why deprecate match orders? There is any alternative to fill an arbitrage opportunity without using match Orders? Or we need to call market buy and sell using FQT?

What about the future of coordinator pattern, these pattern will be replaced by rfqt? Or there is plans to push it later?

I’m not sure whether the stop-limit order would be something achievable with transformers? @dorothy-zbornak what’s your take? Would that be possible to verify the validity of an order within certain price bounds via Transformer, or does that require a feature?

FYI we introduced a mvp of stop-limit orders with Chainlink oracles (but could be plugged into Uniswap oracles I believe) but got little traction so far.

Coordinator: correct, we at 0x Labs see much more value in pursuing the RFQ model VS coordinator. This latter (or rather, the coordinator-server pattern) is definitely pluggable into 0x V4 in case some other teams wanted to add it and wanted to take advantage of the gas savings in v4.

Regarding match orders…I guess you could achieve a similar ‘match’ functionality via a Transformer, but even on this one I’d defer to the matchOrder mastermind @hysz
But, again, almost zero use of matchOrder on v3 500 calls all time VS 183000 of fillOrder (see here )

Updated the post with the updated, finalized specs.
Contracts are currently being audited.

Notable change since last time (apart from more complete specs):

  • added taker field into rfqOrder
  • rfqOrder will not be charged protocol fees. LimitOrder will continue being charged the usual 70,000 * gas_price fee. There’s been quite a lot of thinking around this decision internally in the 0x Labs team, and finally believe this is the best way forward to guarantee protocol alignment and the success of the RFQ model, which has proven great value in Tokenlon and 1Inch’s PMM (they’re both on v2 and still serving 50-60% of total 0x volume). The impact in the total protocol fee will be minimal as they represent a minimum share of fees generated (~2%). Based on the discussions with Tokenlon and the MMers serving RFQ liquidity on 0x API, it became clear that the fixed-gas fee model doesn’t work well for the RFQ flow. In fact, with a RFQ model, the arb protection feature of the current v3 protocol fees isn’t useful and also introduces revert risk when users bump up gas prices (this happened on ~350 trades in the investigation period, for a $4M RFQ volume missed opportunity). The topic requires more research and we are planning to take that on in 2021, hoping for participation and contribution from the community.
  • with that in mind, we ran estimates of gas costs of a fillOrder() on testnets (assume ±10% error). The new architecture brings significant improvements over V3 and v2. 0x API RFQ orders will enjoy a 3X gas efficiency improvement, limit orders a ~10-20% vs V3.
    • V4
      • rfqOrder direct fill ~ 95-115k
      • rfqOrder aggregated and/or fallback ~ 100-120k
      • limitOrder direct fill ~ 105-125k + 70k pf
      • limitOrder aggregated and/or fallback ~ 130-150k + 70k pf
    • V3 direct fill ~ 135k + 70k pf
    • V3 aggregated and/or fallback ~ 155k + 70k pf
    • V3 0xAPI RFQ flow (aggregated and using EP) ~ 250k + 70k pf
    • V2 fillOrder (only direct fill available) ~135k

Approximate gas costs comparison (in '000 gas)

| Order type              | v2  | v3  | v4  |
|-------------------------|-----|-----|-----|
| RFQ direct fill         | 135 | 295 | 105 |
| RFQ aggregated          | -   | 320 | 110 |
| Limit order direct fill | 135 | 205 | 185 |
| Limit order aggregated  | -   | 225 | 210 |

AFAIK there’s really no clean way to do a stop-limit order with these order types or transformers. There is no callback mechanism during validation or settlement for these orders because they are so lean. Transformers probably won’t be much help because someone could just remove/replace the transformer that does the oracle check.

I suppose with LimitOrders you can do it with a meta-transaction if you route fills through your contract. You set the order’s sender to your contract that does the oracle check then calls executeMetaTransaction() -> fillOrder() on the taker’s behalf. The UX is kind of ugly though since the taker has to sign an mtx object + send the transaction. And this does not work with aggregation/transformers.

Could a arbitrage smart contract replace match orders using the contract fillable liquidity? In my case I want to users run in future an arbitrage bot to fill more faster orders instead of waiting by third party arbitrage bots to fill it. It will be like arbitrage as service. So likely the bot will pass two crossed orders and at final, the balance in ETH needs to be positive to contract fill both orders. If yes, in that case match orders it will be not necessary to the use case I am looking for that needs match orders.

So this means, that stop limit orders and other advanced orders could not be acomplished by Transformers and only with a dedicated type of orders? Maybe could be added a new type of order, like limitOrder with conditionals, that way 0x is versatile enough to gather different types of orders.