Nouns DAO tested a $1M trade with less than 1/5th the liquidity (~$185k) and validated TWAMM for large on-chain swaps that need MEV protection and optimized price execution.
The proposal was split into two separate trades. The first
500 wstETH (~$1M)
swap was a trial trade to ensure the protocol operates as expected. A follow-up trade for the remaining7000 wstETH (~$15M)
will happen in the upcoming weeks.
Before getting into the specifics of the trade, let’s look at the current landscape of DeFi tools available for swaps -- DEX & aggregators. DEXs are the purest form of DeFi since routing, settlement, and interaction can all happen via smart contracts. Aggregators are a hybrid model because although trades settle on-chain, routing and interaction usually happen off-chain.
DAOs require
on-chain (smart contract) interactions
since treasuries are controlled by multi-sig wallets and require governance voting triggered execution.
There are a few options when it comes to DEXs, mainly Uniswap, Curve, and Balancer. Below you can see how each of these exchanges performs with the 7500 wstETH to rETH
trade.
Clearly, an atomic DEX is unable to process a trade of this size because they rely on localized on-chain liquidity
and process trades in a single block.
Balancer offers the most reasonable execution with
-1.51% slippage
because it has over 10x the trade size in liquidity available for this specific token pair.
We can use CowSwap’s price quote here since it’s a meta-aggregator and sources the best execution from all the venues on-chain and off-chain. Although CowSwap offers an unbeatable price quote, it’s important to note the nuances here.
The only way for DAOs to interact with CowSwap at the smart contract layer is via Milkman which is a feature & not a full-fledged product. The execution depends on the best quote offered by a solver, and that quote might not always be the best return for the trader. For example, in the case of the ENS DAO swap cost them roughly $110k.
With large trades, the general best practice is to spread the trade over time to capture favorable price movements and not take on timing risks, something TWAMMs do naturally. Also, a very clear advantage TWAMM has is transparency in pricing during the trade and zero reliance on “honest” solvers. The trader can see the execution on-chain over 1000s of blocks and has the time to decide to cancel or continue the trade.
A key thing to note is the differentiation in how we measure trade execution in a CPAMM (atomic) vs TWAMM (non-atomic) DEX.
In a CPAMM, the primary losses on a swap are “slippage” and fees
. Slippage occurs when the amount of liquidity is insufficient to absorb the trade amount.
In a TWAMM, a large trade amount is not a problem because it is executed over time in many blocks via small trades. Thus the primary losses on a trade where the duration has been chosen appropriately are “price movements” and fees
.
Price movements are the changes in the value of the pool’s two assets with respect to each other. For instance, if you trade $1M Token A for Token B at block N and the price of Token A significantly increases at block > N, then you will receive more Token B (which would look like negative slippage—i.e. profit).
Now let’s talk about the actual trade. Below, we recap the results we got for the trial trade, our projections for the full trade, and our arbitrage bot performance and liquidity provider returns. Here’s a snapshot of what’s happening during a single order block interval (OBI) with the reserves, arbitrages, trade execution, and gas usage.
Because TWAMMs are a complex system with multiple moving parts (arbs, LPs, traders) and long trade durations, we built an end-to-end simulator to stress test and understand the trade execution given different variables like liquidity, arbitrage (frequency, sister pool), gas fees, trade size, etc
.
Based on the simulations, in the original DAO proposal, we projected a return of
532.372 rETH <> 514.025 wstETH
, roughly1.0357
in price execution with average gas price of 20 gwei.
We achieved a better result than projected (+.125%) even with higher-than-expected gas prices because of the additional liquidity. Before comparing the trial trade
to other DEX quotes, it’s important to note the total liquidity in the pool was ~$185,000!
Token In: Wrapped Staked ETH (wstETH)
Token Out: Rocket Pool ETH (rETH)
Amount In: 499999999999999984940 (500)
Duration: 50,400 blocks (1 week)
Start Block: 17676550
End Block: 17727000
Liquidity: 43.73 (wstETH), 45.79 (rETH) ~$185,000
--------------------------------------------------------------------
Amount Out: 518509211336926411137 (518.51)
Price Execution: 1.0370 (amountOut/amountIn)
Price Ratio: 1.0501 (ratio @ block 17676550)
Difference: -1.25%
The below chart describes what is happening in 300 blocks of TWAMM interactions. The callouts show the arbitrageur paying the gas to correct the reserves in the pool. So the long-term trader executed 50k+ small trades and only paid $100 to start the trade & withdraw proceeds -- $12,725
in gas fees savings!
The solid green line is the proceeds amount of the long-term order in the blockchain state. The reason it’s a staircase instead of a smooth line is that we only write the state of the order when someone interacts with the pool (calls a function that executes virtual orders).
The dashed yellow line is the virtual proceeds amount and is a smooth line because it is a view function that tells you what the value of proceeds is at a block if you were to execute virtual orders at that block.
TWAMM executed a ~$1,068,055 swap with $185,000 --
~17%
capital to trade size! You can see the trade transaction & withdrawal transaction on Etherscan.
How does this compare to the competition?
Uniswap: Slippage (0.2-0.3%), Liquidity Ratio (2,060%)
Curve: Slippage (~0.42%), Liquidity Ratio (1,685%)
Balancer: Slippage (~0%), Liquidity Ratio (16,385%)
As you can see below, TWAMMs perform orders of magnitude better (1.0425 price execution)
with more liquidity & even on par or better than CowSwap! The larger trade was simulated with 15%
of trade size in capital ($2M)
and over 2 weeks
.
TWAMMs require frequent arbitraging to ensure the swap price for the long-term trader stays accurate and up to date. Therefore, we built an entire suite of services ranging from arbitrage bots, monitoring, data collection, notification, and a barebones UX
to ensure the trade was executed optimally.
With the liquidity constraint of the first trade, we had to ensure there was frequent arbitraging and did not want to rely on the market to arbitrage the protocol. Interestingly, by day 2 there was a competitor bot who started arbitraging the pools as well, and even beat us to the punch a couple of times (123
)! However, with a few upgrades on our bot, we were able to get ~88% (891)
off the 1014
arbitrages.
This definitively answers why it’s better to do a
partner
swap and share revenues with LPs than paying miners.
In the above chart, you can see how our bot (green) did versus the market bot (red). There are a few interesting data points to take away from the chart:
Block 0 - 10k: we were the sole arbitrageur, and other MEV bots weren’t aware of the opportunity
Block 10k - 20k: copy bot enters, uses a better price oracle, lowers gas usage, and lands more arbitrages
Block 20k - end: we optimize our bot and win the majority of the opportunities. Some optimizations we made:
Flatten input parameter data structures to save gas
Swap out on-chain price oracle from Balancer to Uniswap V3
Storing arbitrage profits as internal balance instead of transferring them to a wallet
Use flash bots for backup arb bots to curb failed transactions
Here’s what that amounted to in terms of MEV collection:
Successful Arbitrages: 1014
Regular Swaps (Market Bot): 123
Partner Swaps (CronFi Bot): 891
- Failed Transactions: 54
Gas Used: $12,725.60
Arbitrage Profits: $13,746.81
Total Net Profits: $1,478.37
--------------------------------------------------------------------
Maret Bot Profits: -$260.24
Cron Fi Profits: $1,218.13
Gas Cost of Failed TX: -$457.17
Infrastructure/Tax Costs: -$400
--------------------------------------------------------------------
MEV Returned to LPs: ~$361
It was important for us to win the majority of the arbitrages because we had a fee discount to capture MEV from back-running and donate part of the profits back to the LPs. You can see a code sample of our arbitrage bot that leveraged Balancer Flash Swaps for higher gas savings and zero capital outlay.
Our protocol continued to operate smoothly under different liquidity conditions during a large liquidity infusion (join transaction) and even when liquidity exited the system (exit transaction). Below is a timeline of the major events:
17676551: Trade starts, ~$72k
: 16.80 (wstETH), 17.65 (rETH)
17676709: 158 blocks (0.527 hours) later, ~$10k enters pool
: 19.25 (+2.23 wstETH), 19.70 (+2.27 rETH)
17678512: 1803 blocks (6.010 hours) later, ~$114k enters pool
: 46.09 (+26.96 wstETH), 47.82 (+27.99 rETH)
17702103: 23591 blocks (78.637 hours) later, ~$10k leaves pool
: 43.68 (-2.18 wstETH), 45.79 (-2.31 rETH)
17727000: 50,450 blocks (7 days) later, Trade ends
: 43.73 (wstETH), 45.79 (rETH)
In the above chart, you can see how liquidity movements affected arbitrage behavior.
Bottom left: trade begins, liquidity is low compared to trade size, so frequent arbs and arbitrage value is relatively small.
Block 1803: liquidity increases 2x, arbitrage happens less frequently, and arbitrage value increases as well
Outlier arbitrage amounts: there are a few yellow dots that are significantly higher and this is because of really high gas prices. The higher gas price equates to arbitrage profit being delayed
Finally, let’s see how much value the LP received from the trade. Below, you see a breakdown of the various swap fees collected by LPs: long term, short term
. As we were the primary arbitrageur, we are able to share the profits with LPs, thus offsetting some of the impermanent loss.
Long Term Fees: 0.03% one long term swap fee
- 0.14 wstETH, ~$326, (trader: Nouns DAO)
Short Term Fees: 0.005% partner swap fee & 0.01% short term swap fee
- 0.0226 rETH, ~$46.92 (partner: CronFi)
- 0.0065 rETH, ~$13.61 (arb bot: market)
MEV Share: 30% of profits minus transaction, infra, tax costs
- 0.087 wstETH, 0.091 rETH, ~$360
--------------------------------------------------------------------
Total Fees: 0.227 wstETH, 0.1201 rETH, ~$770
The MEV captured and returned to the LPs is almost as much as the cumulative fees collected and would have been higher without the failed transactions!