Auction Intelligence: Optimizing Dutch Auctions at Scale for MEV Mitigation on L2s

EthCC[8] · 3 Jul 2025 · 20:45

Brad Bachu and Alan Wu examine Dutch-auction optimization for short block times. They combine reinforcement learning with economic modeling and present simulations and measurements of adaptive auction designs.

Speakers

Topics

From EthCC[8], hosted by Ethereum France.

Transcript

Hi everyone, my name is Alan. I'm a protocol engineer at Uniswap Labs. And my name is Brad. I'm a protocol researcher at Uniswap Labs. And today we'll be talking about auction intelligence, which is our approach to optimizing Dutch auctions at scale for MEV mitigation on layer 2s. You'll see how we turn auctions into datadriven experiments and let reinforcement learning decide not only how but when to use auctions. Let's start with our goals for the talk.

First, we'll talk about intents and how they're cleaner than trading directly against AMMs and how Dutch auctions map cleanly to intent in intentbased systems. Um, and by treating each auction as an experiment, we can apply reinforcement learning to adapt in real time with no RFQS, no oracles or reputation layers. And at the end, you'll see how this scales execution quality across both tokens and chains. So, with traditional AMM swaps, a routing algorithm is going to give you a um set of call data that encodes the path of pools to trade through. and you take all this call data and you send a

transaction with it and that's going to execute your swap. Intents are a shift away from users specifying these parameters. So you can just say for example, I want to swap one ETH for at least 2500 USDC. Then you will have fillers come up with a way of giving you that USDC. And if they can do that, they can get one ETH from you in the same transaction. And this pattern naturally induces competition um that will yield the best execution path when those fillers fill trades for swappers. And this is a powerful mechanism because it allows us to innovate on the way pricing is done behind the scenes while keeping the UX the same and simple.

Here's how it works. This is an intense journey where the user signs a simple message like I want to swap one ETH for USDC. then they broadcast it out. Then there's going to be some filler somewhere in the world that's going to compete on chain to execute it. And this is all made possible by permit 2 because what you're part of what you're signing over in this message is a permit 2 message that lets fillers take your funds if they meet your conditions. And so these conditions would look something like giving you a minimum amount and doing it before some kind of deadline at which after a deadline your intent would expire. So, if someone tries to use your message signature to take your money without giving you the output you want,

then their transaction would revert. You may have seen this before where at the bottom of your swap it says that it's using Uniswap X and that it's gasless where you don't need to pay money for gas. We just showed that what actually happens when you swap with this transaction is that it uses Uniswap X. And the reason why there's no gas is because you are not the one sending a transaction. You are simply signing a message and a filler would send the real transaction on your behalf. So once you click swap, the filler will take your assigned message and then if they can give you 4.1 ETH, then they can take 10,000 USDC from you. And we have been live with the Uniswap X protocol

since July 2023. So intense can basically decouple what you want from how it's done. So unlock unlike amm where you lock in the price and the slippage level and stuff intense will let you set price at execution. And this feature is the bedrock that's going to enable us to run complex um and different kinds of auctions when we want to execute trades. Here's two examples. On the priority ordered chain, we can code a me tax into an intent by saying that the higher priority fee a filler uses to fill your transaction, the more output that they need to give you. So price is actually determined at execution time and the

price will be determined by what priority fee the filler uses. And for Dutch auctions, we can set the token price based on it starting high and getting lower and lower over time until a filler jumps in to fill it before others. And in this one, the price is determined by the block number at the time of execution or the time stamp. It's even possible that we can run an auction that uses both a MEV tax and a Dutch auction. And this flexibility is what makes intentbased execution so powerful. Here's an example of a Dutch auction that uses a simple price decay. It's linear, but we can actually use more expressive curves. Like nothing is going to stop us from encoding our price to be

based on a curve or peacewise or anything that we feel might match market dynamics better. And if we want to scale these auctions, there's two fundamental questions that we think about. First one is, is it worth routing this order through an auction instead of trading directly against an AMM? This is because there's a trade-off. When you run a Dutch auction, it's not instantaneous like swapping on an AMM. And there's a chance that maybe the fillers out there in the world don't want to fill your order, so it could possibly expire. And if there's more complexity to an auction, then if we choose to run it, we better get a better better result than what we would have gotten through an AMM.

Second question is if we do use an auction, how do we choose to parameterize it? So, how do we start the price at the Dutch auction begins? How do we set the end price, the decay rate, and the duration of the auction? And this question is especially challenging because we need to find optimal parameters that may be different across tokens and across chains. And it'd be kind of infeasible to do it at scale manually. And this is why we turn to an automated learning approach. So reinforcement learning will give us a simple feedback loop based on an action an outcome and updating based on that outcome that can continuously adapt to auction. They can continuously adapt to

onchain results to give us better auction parameters. So this allows us to not need manual tuning per token or per chain and our model would learn directly from onchain market behavior. And why is re reinforcement learning the right tool? Well, first, auction parameterization is inherently dynamic. It's token specific, chain specific, and there's no one-sizefits-all formula for it. And second, market conditions are always changing. So reinforcement learning will allow us to adapt to unknown filler strategies, tokens having different liquidity and volatility and also um it's still going to work in the

absence of off-chain anchors like a sex price feed. Ideally, we'd like to reward our model based on price improvement, which is the difference between the auctions fill price and what the AMM price was at order submission. And this makes sense. If we choose to spend time and effort to run an auction, it better be better than the AMM. We can compute price improvement by comparing the um actual execution price to a single benchmark, which is the onchain AMM price at the time of order submission. And that's going to be our ground truth for measuring whether an auction actually performs a simple

outperforms a simple AMM swap. But price improvement is very hard to observe and Brad has written a paper about this so I'll let him discuss. Okay, thanks Alan. Um so yeah this paper was with Shin who's in the back and Cia Mack who is a professor at Columbia University. Okay, so um as Alan said in this paper, we measured price improvement and um what this paper taught us is that price improvement is hard to measure um because you need to benchmark and a the relevant benchmark in our case is a counterfactual execution of a routing algorithm on an AMM. So you need to simulate this it's

and it's costly, it's time consuming. Um so uh what makes it difficult also it's because the prices change over time um the gas price can fluctuate and the underlying liquidity distribution can change right which affects the routing algorithm. So because of all these problems it makes reinforcement learning a challenge to use this metric. Um so it' be great if we had a simpler onchain signal. That's where my claim now is that we can use um sort of two objective truths that are easy to observe. That's the key thing. They're very easy to observe when you run an auction. That is the wait

time of your auction. How long did it take for your auction to get filled and the success rate? Meaning if you have a repeated set of auctions, what is the um how many of them have filled before the expiry time? And these again these two signals are universally observable on chain um require no external data feed and fully capture filler willingness and market volatility. Okay. So um if we start thinking about auctions having observable quantities we can also upgrade how we think about auctions. Auctions aren't just pricing mechanisms. We can think of them as little experiments. Every time we run an

auction, we set parameters, we run an experiment, we observe the outcome. And this is how the reinforcement learning is going to work. And this way, again, you don't need any external quotes or oracles. Um, it's just pure openbook feedback because of DI. Okay. So um simply put weight time can encode uh filler willingness to pay a certain price and success rate can encode the market volatility. Um so I'm kind of just jumping and telling you this in a like trust me way. But let me give you some intuition about the first part why wait time can encode filler will filler

willingness. Uh, imagine I wanted to sell you my laptop and I say, um, I'm going to use a Dutch auction and I start at $1. You would pro, someone would probably jump in and buy it instantly. What did I learn? I learned that I set my starting price too low. Let's suppose I started at a million dollars and decayed by $1 every minute. It would take me a long time to get to the price that someone is willing to pay. So, what did I learn by the fact that the auction took very long to fill? I learned that I set my price too high. So in that way you can see how you can use time as a signal to understand filler willingness.

Um in that same way if you do some math you can see that uh success rate can also encode the market volatility. So when you combine those two feedbacks with your auction parameters you can learn not only these things mark filler willingness and market volatility but additional features of the underlying asset. Okay. Okay, so how does this work? Well, on your left hand side are the parameters of the auction and the green dot represent our starting point. So if we start with these parameters and we run a set of auctions on the right hand side, we can see our observed weight time and observed success rate. Now the goal is to reach a certain success rate

and certain fill time. But the problem is that we do not know what are the best parameters to get us there. And this is where stochcastic gradient descent can be used. And the idea is that uh by using this gradient descent on the right hand side we can um every time we run an auction we can look at the feedback and we can walk on the left hand side to to the target success rate and wait time. So this is what it would look like if we were to do um say like you pick I say I want to run 50 auctions and at the end of those 50 auctions I measure what was the average weight time what was the average fill rate and I can use that to update my parameters so that the next

time I get closer to my target wait time and my target success rate. Um, and then, you know, just to make make sure you know that we've we're actually trying these things out. Um, this is a results of an experiment that uh Allan ran with a bot. And what this bot did was that it it wanted to swap um a certain token pair of roughly the same trade size uh frequently. And it did this in a open filler uh network that we have no idea who the fillers are. This thing is completely open. Um and on the left side you see how the parameters are moving around. And you can see from the um I didn't show you what is what. It's

just think about hyperparameter space. Um on the x- axis you can see that they sort of converged um in on that parameter. On the yaxis it was still climbing a bit but we figured that was like it's not the end of the experiment. I'm just showing you the data. And um if you look at the outcomes, you can see that it did hit this weight time that we were aiming to get, which was like between two and three blocks. Um so you want to follow the yellow color, so dark to yellow, black to yellow. Um so it it was able to hit the weight time. Um and the success rate, note that this is between uh 84% and 100% and what we aimed to get was something like 90%. Um and you can see the yellow dot started

to get in that region. Um, and again, you know, this not perfect. There's noise in this. And um, how precise this is is the trade-off with how long how many auctions you want to run in every batch. And, you know, these are all trade-off decisions in um, gradient descent. Um, but the point is that you can you can use this strategy to achieve a target weight time and a target success rate. Okay, but how does this come back to price improvement? I'm going to skip the math and just show you the result. Um this is the result. So the clever thing about all of this just focusing on these two signals is that you can actually increase your price improvement over time. You can figure out what is

the well in other words you can maximize the price improvement that you get for the user. And not only that you also solve the problem of measuring price improvement. Um I'm not telling you exactly how he did that. We can talk about that often if you want. But the fact that I'm I'm I'm showing you right I'm you measure it it's there. Um and what this means is that we can now uh sort of like in real time predict what the price improvement of a certain trade is going to be. This is actually super useful because not only have we figured out how to maximize the price improvement for the user, but by being able to predict the expected price improvement, we can go back to this original problem that Alan

mentioned. The first problem when you run an auction is should you even run an auction right when you have a alternative path which is to send the user to the AMM. So this is how how this um auction intelligence or what we're we're calling for fun internally uni mind works right um right now it can when a user comes in to do a trade what it can do first is it can it can determine if I am going to send the user to an auction what is the price improvement that they're going to get relative to an AMM if that value is negative then it says you're better off going to AMM if that value is positive it can set the price, it can set the parameters for that Dutch auction. Note

that it's not actually submitting the transaction. It's just setting the parameters to for open set of fillers to to then fill on. Okay, so behind the scenes um uni chain is our sort of unified onchain layer um hosting both the unis swap amm and the unis swap x Dutch auction protocol. Well, not just Dutch auction, but it can be MEF tax also. Um, and because we built this auction intelligence layer across this whole pipeline, um, it makes this integration really seamless. Um, from intents to auction logic to execution.

Okay. So, looking ahead, um, this is sort of the vision is that uni mine can become a universal pricing layer sitting beneath the intent infrastructure. So anytime you have a new chain and a new token, we can just plug Uni Mind in to provide adaptive datadriven execution um without any extra trust assumptions. So just to compare to today's infrastructure and remind you um the alternatives are quotes like RFQS or oracles. Quotes require permission permission participants um reputations slashings and so forth. Um, and oracles don't tell you the price a filler is willing to pay. They just tell you sort

of like the the market price. Um, and oracles have latency issues and also manipulation risks. Um, and both of these, the core thing is that both of these assume an external price authority. By contrast, our mechanism of using reinforcement learning um, only uses onchain feedback. So there are no extra trust layers um no manual tuning and it's sort of truly uh decentralized price discovery. So um to end I want to remind you that in DeFi everything is public. So the goal is that we should build systems that learn from this public data rather than bottleneck it behind private coordination.

This uni mine strategy using reinforcement learning is sort of the first step in showing how using Dutch auctions um we can get scalable decentralized execution across any chain and any token pair. Uh so that's it. Thank you. If you have any questions we can answer them now or after. [Applause] Can we can we take any or no? After one minute. Yeah. Uh thank you for the talk. Um I just had a question about how this happens uh under the hood. So do you have some sort

of like back end or something that continuously uh try to optimize the stoastic gradient descent for both the the success rate and the and the time it takes and basically like take that data. How that does the does does that happen? Do you just run it once in a while or Yeah. So, we basically have a backend service that keeps track of all of the orders that have gone through unis swap x and for each one we can observe the onchain metrics that happened for that order. So, how long it took to fill and um how what percentage of them are successful. So, if fillers are willing to fill them as well. And once we have

enough of a sample size for a particular um trade pair like ETHUSDC, it's able to look at those metrics across some window into the past, say like 30 orders or 50 or 100 orders. And then based on how that performed, then we can compute the next set of parameters we should try for ETHUSDC. And and and then you put this parameter like on chain like what do you do with this parameter? You give them them to solvers. Yeah. So it's not on chain yet. We give these parameters to the solvers. So the solvers will see the intent with these parameters and they can choose when to fill.

Thank you. Thank you very much. [Applause]