Coordinator Discussion

A rough spec for our upcoming Coordinator release is available here. The Coordinator is an alternative to the open order book model and matching model we currently have today. This new mechanism for order discovery will allow for shareable, contract-fillable liquidity as well as off-chain cancellations to improve market making UX and allow for tighter spreads. Questions and comments welcome.

Hey Rahul, I reviewed the coordinator spec and wanted to start a discussion about some possible issues / questions…

[Risk] approval spam

Since the approval step is separate from tx execution and “free”, but a signed approvalHash is needed to execute a coordinator order, this creates an incentive for takers to spam the coordinator server for approvals, even if the taker doesn’t fill the order. This blocks others from filling these orders while giving the taker an exclusive option to fill these orders during a span of time = min(remaining approval expiration time, remaining order expiration time)

[Risk] reduced atomicity

Coordinator model improves reliability (reduced collisions) and liquidity (benefits MMs who need free cancels) at the expense of atomicity (tx success depends strictly on blockchain state) and speed (need to request/receive approval before submitting tx)

[Question] Market orders?

Design should consider impact for takers of market orders and the corresponding incentives. If a marker order taker needs to get a batch of orders approved by the coordinator contract, the taker runs the risk that a subset of the orders are rejected. Therefore, market order takers have a natural incentive to get a larger amount approved than they need, so that even if 1-2 orders are not approved by the coordinator, the taker can still submit the approved tx to the exchange contract (see approval spam).

[Question] Coordinator fees

Does the coordinator receive the tx fee paid to feeRecipient specified in an 0x order?

Possible alternate model?

This tries to combine the approval and coordination execution parts of the process, in order to mitigate approval spam risk and improve atomicity and speed:

  • Coordinator server watches mempool for incoming taker orders
  • Server uses price/time priority to publish updates to a public orderState dictionary (i.e. state[orderId] := [expired, cancelled, filled])
  • Coordinator contract uses oracle to check orderState to determine whether to execute an order

(the idea is that speed of updates to orderState are not constrained by block time, so if Bob submits a taker tx after Alice has submitted a taker tx for the same order, Bob’s tx will fail no matter how much additional gas he pays)

1 Like

Great questions!

Since the approval step is separate from tx execution and “free”, but a signed approvalHash is needed to execute a coordinator order, this creates an incentive for takers to spam the coordinator server for approvals, even if the taker doesn’t fill the order. This blocks others from filling these orders while giving the taker an exclusive option to fill these orders during a span of time = min(remaining approval expiration time, remaining order expiration time)

See the 3rd bullet of the handling fills section of the spec for how this is handled. Essentially, a fill will not be approved if the taker has already requested a fill on that particular order before. This means that a taker can only request a fill once and prevents that taker from continuously spamming the coordinator with approval requests. This is not a perfect solution since the taker can still prevent a soft cancel for a short period of time, but it does limit the damage that can be done.

There are a few other factors to consider:

  • Makers can still easily perform an on-chain cancel if they are not able to soft cancel an order.
  • The coordinator server can always submit a taker’s approval to the chain, making it actually binding (this is possible at the contract level but not built into the reference server at this time).
  • Even in the worst case scenario (order approvals being spammed 100% of the time), this is still a strict improvement over open orderbook with respect to cancellations.

Coordinator model improves reliability (reduced collisions) and liquidity (benefits MMs who need free cancels) at the expense of atomicity (tx success depends strictly on blockchain state) and speed (need to request/receive approval before submitting tx)

This is a fair assessment. The feedback we’ve gotten so far from developers of protocols that consume 0x orders is that this probably won’t be much of an issue, but it’s worth getting more feedback. I’m especially interested in how the 1 second selective delay affects things, which is probably much longer than roundtrip response times to get an approval. Ultimately this is a parameter that can be tweaked.

Design should consider impact for takers of market orders and the corresponding incentives. If a marker order taker needs to get a batch of orders approved by the coordinator contract, the taker runs the risk that a subset of the orders are rejected. Therefore, market order takers have a natural incentive to get a larger amount approved than they need, so that even if 1-2 orders are not approved by the coordinator, the taker can still submit the approved tx to the exchange contract (see approval spam).

Trying to get a larger batch of orders approved actually decreases the chances of approval (a single soft cancelled order will cause the entire batch to be rejected). I agree that there are some edge cases here and that selecting orders could be a bit tricky. Perhaps there should be an endpoint that returns suggested orders?

Does the coordinator receive the tx fee paid to feeRecipient specified in an 0x order?

Yes. This simplified the design in the initial version, but can be changed in v2 if it is a sticking point. I can definitely see use cases where multiple relayers use a single coordinator service and fees are charged separately.

This tries to combine the approval and coordination execution parts of the process, in order to mitigate approval spam risk and improve atomicity and speed:

This is an interesting idea, but I’m not sure how practical it is for a few reasons:

  • It is difficult to setup efficient mempool watching infrastructure.
  • From my understanding, rejected fills would still consume gas?
  • The oracle submission would need to be mined before the fill transaction, essentially front-running any requests. This also has pretty complex infrastructure requirements.
  • Where is the dictionary stored? Just a local DB?
  • Using an oracle this frequently doesn’t seem very robust or reliable.

I think this approach could be simplified if the dictionary is just an on-chain mapping that can be updated by the coordinator, in which case the last 2 points can be ignored.

the idea is that speed of updates to orderState are not constrained by block time

Is this actually true, given that oracle submissions are constrained by block time?

2 Likes