Economically efficient transaction ordering and user preferences

Below, I try to outline what I think is an underexplored MEV research direction.

Often when blocks are built, the ordering doesn’t take retail users’ preferences over ordering into account. For example, in an ETH/USDC sandwich we know that what a sandwicher pays to the builder must be less than what the user lost in slippage. Simple heuristic changes don’t necessarily solve this (as I will show below), can we allow users to express preferences such that the final block is representative of the utility of all users involved?

Paying for better execution

In a permissionless system, we assume that actors are rational so we assume block builders order transactions maximise payment to coinbase (let’s leave aside the repeated game for now). So builders including sandwiches makes complete sense - users pay the same amount as long as their transaction is included, but sandwichers only pay if they are able to sandwich a user meaning that the builder is incentivised to think only about including the transaction and allowing for the sandwich.

This isn’t an consequence of the bundling abstraction either. Let’s imagine there are three transactions submitted to the builder:

  • A and B: two swaps buying ETH on Uniswap and only paying for inclusion
  • C: a swap selling ETH paying the coinbase address as an increasing function of the price at which the swap is executed

A rational builder orders the transactions (A,B,C) or (B,A,C) as this gives C the best possible price and consequently the builder the highest payment. Clearly, this gives B worse execution than orderings which place C before B.

image

Now let’s imagine B also expresses preference over execution, but pays a higher rate for price improvement than C (this time for lower prices of course).

image

The ordering would then end up being (C,B,A). This ordering is clearly worse for C than before. What one would expect is that B and C - aware that other swappers are also paying for execution - raise their rate of payment to the builder until almost all the surplus from price improvement goes to the validator.

The plus side is that this would mean that users don’t get sandwiched much (assuming everyone values the asset being traded into at roughly the same price). The down side is that users now end up with a net utility which is very close to their utility if they ended up being executed at their slippage limit so it’s like they’re being sandwiched anyway. This is particularly bad when you consider situations in which random ordering would have given a better price than the slippage limit even without payment for execution. (e.g. the swap is the only ETH/USD trade in the block and the trade is too small to warrant a sandwich because of gas & LP fees).

This is an intuitive argument. Did I miss something which means that users paying for execution is actually a feasible direction of research? What can be changes can be made to transactions and payments to make this feasible?

Sequencing rules

An interesting approach is something like what this paper proposes. That is, constraining builders to a sequencing rule in which swaps in the same direction can only follow each other if they are executing at a better price than what was available at the top of the block OR there are no swaps of the other direction following them (i.e. they are not being used to move the price for someone else).
This gives users a guarantee that they aren’t being given a worse price for someone else’s benefit.

image

Of course there are still are more less favourable orderings which users can pay for within this kind of rule and being in the long tail of same-direction swaps at the end isn’t desirable. There is definitely also room for multi-block MEV strats here. There is also the question of what happens when users submit more complicated orders like arbitrages touching multiple pools.

With ordering rules and payment for execution quality as a tool, what’s the best outcome we can achieve? (“Best outcome” for swappers that is :smile: ). What’s the best sequencing rule? (Edit: there is wider exploration of the space of ordering rules in this thread)

8 Likes

there might also be cases in which users aren’t really competing with each other and some payment for better execution goes a long way because there isn’t a race to the bottom, but I need to sit and think of some examples first.

Interesting observation that paying for better execution does not necessarily lead to better execution.

Just some small notes/questions:

  • Transaction ordering may not be completely arbitrary. The users’ txs will include some slippage parameter, which may restrict the freedom of the builder to order txs.
  • Sequencing rules are very application specific. Can they work if there exist multiple applications on a chain, and applications have different sequencing rules? If yes, what if a tx interacts with two applications such that it triggers contradicting sequencing rules?

Thank you for highlighting this area where we clearly need more research. Another challenge is the price impact in execution due to external price movements, which can lead to cases where “best” execution parameters change outside of ordering inside the block being considered. In the case where C is one leg of a trade whose other leg is on a CEX for example, the second case may be better execution for C even though it’s seemingly worse on chain: the price of the asset C is trading moves greater in the external world than the amount of value C would save by having A & B execute first.

Thus we need great flexibility in expressing execution preferences as the totality of the preference may encompass factors outside of blockchains that only the submitting party may know. To answer some of your followup questions, having a new transaction type (eg. type 3) where additional fields executionFee and executionInput are present might help address such cases, where execution fee can only be claimed if the submitted logic under executionInput is satisfied. I’m sure there’s some overlap here with the design intent of SUAVE, but this can be a single-domain way to express execution preferences before the presence of a greater marketplace or alternative mempool.

This also introduces new economical challenges around cost and value accrual, as executionFee likely comes from part of the trade opportunity, and likely goes to a builder or other entity like executor who satisfies the logic. In on-chain MEV cases this would create a value funnel that takes away from validator rewards and gives to builders to assure a better tx execution environment for end users. This sounds problematic but one could argue more value would accrue over time to a network that presents best execution opportunities. Alternative methods of using this fee for burns or democratizing can also be explored to mitigate this issue.

1 Like

I actually don’t think this is an issue. If you use the simple greedy algorithm:

for i, trade in enumerate(trades):
  if frontrunning_violation(trade, prev_trade, initial_prices):
     for j, later_trade in enumerate(trades[i + 1:]):
       if not frontrunning_violation(later_trade, prev_trade, initial_prices):
         trades.insert(i, trades.pop(i + 1 + j))
         break

You will have two properties:

  1. The trade that gets pushed back from i to i + 1 will always be price improved (since the inserted trade is going the other way), which means the insertion cannot trigger a slippage failure.
  2. The trade that gets inserted at i can be price worsened, but never beyond the initial price (due to the first if condition). Therefore if the user set the amountOutMin relative to the initial_price, they will not suffer a slippage failure. To put it another way, they will not have their transaction fail if it wouldn’t have failed at the top of block.

However, we should still think deeply about whether there are any unintended consequences. The inserted trade does get price worsened - we can say they shouldn’t complain since they are still receiving better than top-of-block price, but there are many reasons an honest user is paying gas - is there anything we’re missing, that would cause this user to complain?

This is the important question in my mind. We do have properties 1 and 2 above that would probably not break composability directly with the swap in question. But other orthogonal things that happen between i and i + j + 1 can be breaking. Also, honest users submit bundles too. Do we split their bundles to accommodate for the sequencing rule? If not, why wouldn’t frontrunners/sandwichers just include random dapp calls in their bundles to look benign?

Is this a proposed change to Ethereum itself?

It does present a similar question for the OP. Where should a sequencing rule be enforced?

There’s probably some leeway here, I’ll price out the sandwicher well before paying 100% of price improvement (sandwicher has overhead such as LP fees, etc). I’d be more concerned about the complexity it’d add to block-building. Agreed though that this is still MEV and that’s not ideal in terms of it going to validators instead of users/LPs.

Note that the sequencing rule solution catches sandwiching but necessarily plain frontrunning. That’s indistinguishable from honest activity, and ultimately, if you set a slippage, you are willing to take that slippage. To beat plain frontrunning IMO you need to privatize the orderflow.

1 Like

Yes you can definitely have preferences be conditioned on a lot more and like @ra mentioned there are some things I left out of the example I gave above because I was just trying to communicate the barebones concept. You might find Vlad’s talk on Smart Transactions interesting.

I’m not sure I follow your builder/validator point. If you are saying that a builder can implement this feature and therefore internalise this value themselves, one immediate response might be that other players in the market do the same thing and competition forces the value from this feature back to the validator. Of course, if you assume competition wanes, then we should be concerned about where the value does end up going (like into the pocket of the dominant builder).

To beat plain frontrunning IMO you need to privatize the orderflow.

private as in privacy or private as in Citadel’s?

this question comes up again and again, just yesterday in conversation with @barnabemonnot

i propose we use private orders for privacy (encrypted mempools)

and dark orders for citadel-like, like the dark matter is there but you don’t see it

3 Likes

it can be positioned as such, but you raise a good question on where it should be enforced. If complexity with blockbuilding is a concern, encrypted mempool and TEEs don’t help much on that front either. More encompassing blockbuilder rewards for preferred execution can account for the additional complexity in both cases, in or out of protocol. The executor role being introduced by SUAVE might also be better way to account for it.

It is not obvious to me that this role needs to be separate from a blockbuilder however, or if there’s a sustainable path for it to serve, given competition will trickle related rewards to the validator eventually as @Quintus points out.

Can be either! Anything that doesn’t leak it to untrustworthy parties. If you trust Citadel then you can use Citadel instead of cryptography. Otherwise then yeah you encrypt.

Anyways, the broader point of that remark (which was a bit off-topic) was that, if the information is out there, someone will trade on it, potentially even outside of the SUAVE ecosystem. Even if SUAVE somehow makes its block builders remove the frontruns from the executor’s payloads (I don’t think so, because there’s nothing wrong with being first), the executors can use a non-SUAVE builder and pay them more. In that sense, it is too late to fix the issue in post-processing.

As you pointed out in the OP, paying off the builder to remove the frontrunning transactions can defeat the point to a degree. Which leaves hiding the transactions from the executor, and dealing with the remaining problem of how the executor can execute when they cannot read the transaction.

2 Likes

I would add constraining builders as an additional route (e.g. the txn ordering rule I linked in the post).

What I meant is that this wouldn’t cover every case, because frontrunning and censorship are both plausibly deniable from the POV of a builder. Neither the builder nor the enforcing protocol know whether a transaction is first by accident or by intention (a discernable strategy like sandwiching might even be in the minority of generalized frontrunning strategies - the most general case might just be two green arrows rather than this sequence of green and red arrows that can be validated); same for whether a transaction is missing.

(The broader point being: plausible deniability means that knowing things about transaction contents pre-confirmation is fundamentally a vulnerability)

FYI: I wrote this post to explore the space of ordering rules a bit further.

1 Like

Another thing I want to add before I read the other thread is that “restricting block builders” can only be done to your own block builders. Otherwise you might end up reinventing the “bloxroute: ethical” builder; it’s great that many proposers choose that builder, but at least Ethereum has a culture of not wanting to rely on these altruists.

In the context of SUAVE, the first priority should be that it actually wins blocks (otherwise no impact is made); that means if it’s unwilling to capitalize on some MEV opportunity it must also prevent anyone in the pipeline from leaking / making an under-the-table deal with e.g. bloxroute. While such treachery could be caught socially, the network can’t detect it as it can’t distinguish between some searcher leaking the alpha vs the user themselves leaking the alpha in an attempt to get the searcher wrongly blacklisted.

2 Likes

I think it depends on the rules. If the delta is small between restricted and unrestricted blocks, more orderflow available to restricted blocks could make up for it.

I agree that there is probably some level of restricted block dominance for which it makes sense for users to send OF via restricted and unrestricted channels, although most OF originators tend not to be that strategic from what we’ve seen. Your point reminds me of this paper though (https://arxiv.org/pdf/2202.05779.pdf)

The worry is that restricted block builders launder the orderflow through unrestricted block builders for a kickback. It seems like DOFD might fix this though.

The current idea with SUAVE is that decryption would be subject to proof that certain properties were met, so OF can’t really be executed if the restrictions aren’t satisfied already.