Dissecting the JIT Liquidity Attack

Alex Zaidelson
16 min readJan 12, 2023

--

Also known as the LP Sandwich

Do robots eat electric sandwiches? Dall-e

Intro

Several weeks ago, we published Dissecting MEV Arbitrage, an article about various kinds of MEV arbitrage. We covered CEX Arbitrage, Positional DEX Arbitrage and Sandwich Arbitrage. We also talked briefly about the “LP Sandwich” arbitrage, promising to cover that kind of arbitrage in the future. And the time has come.

Intro: How do Liquidity Providers make profit on AMM?

This question may sound trivial — well, obviously, Liquidity Providers profit from the fees generated by traders.

In some protocols, LPs are also rewarded by protocol tokens.

There is a third, often disregarded component, namely the Price Impact.

Here’s how it works, using basic Constant Product AMM as example:

  • Alice sets up a pool between two perfect US dollar stablecoins — USDX and USDY, puts 1000 coins on each side and sets the fee to 0.3%. The total locked value of the pool (TVL) is of course $2000.
  • Bob comes in and sells 10 USDX coins to the pool. According to the classic constant product AMM formula, he receives the following amount of USDX:

So, Alice’s pool now has 1010 USDX and (1000–9.8715) = 990.1285 USDY, so the total TVL is… $2000.1285. Alice just became 12.85 cents richer. 3 cents of that comes from the fee paid by Bob, the rest comes from Price Impact.

Indeed, Bob paid 10 USDX and got only 9.8715 USDY, so Alice sold her USDY at a high price and made a profit.

Usually, the price impact profits are immediately snatched by MEV arbitrage bots, so the ratio between the two coins in the pool comes back to what it was before the trade, and Alice is left only with the fees.

In addition, LPs notoriously suffer from Impermanent Loss which occurs when arbitrageurs make profits by adjusting the price in the pool to the external price. There’s been a lot of discussion recently about low (or no) profitability of liquidity provision.

But what if Alice could run away with her money right after the trade is done? Moreover, what if Alice could do that for every trade?

That’s exactly what an LP sandwich (or Just-in-Time Liquidity Provision) attack is.

How does an LP Sandwich work?

Alice grows iron tentacles and becomes an MEV bot.

The LP sandwich attack works in the following manner:

  1. Searchers identify a large swap that is about to happen on an AMM Pool
  2. A large liquidity deposit transaction is inserted right before the swap
  3. A transaction withdrawing the liquidity is inserted right after the swap

The attacker benefits from transaction fees and from the price impact paid by the trader. Note however, that our Robot Alice is not alone — there are other LPs in the pool (otherwise the trader would not have sent her transaction to that pool in the first place), and the revenue is split proportionately between all the LPs according to the amount of liquidity they put in — therefore the more liquidity Alice deposits, the higher her share of the revenue.

Turns out that UniSwap V3 with its Concentrated Liquidity AMM model is just ideal for that. It can be said that a V3 pool actually consists of multiple smaller pools, each covering a particular price range. Overall liquidity is distributed between those smaller pools, making it easier for an attacker to get the majority in one of them.

Statistics on LP Sandwich/JIT Liquidity Attacks

In this section, we will present some statistics on the LP Sandwich phenomenon.

All the subsequent discussion is only related to Ethereum blockchain.

Methodology

We detect a JIT Liquidity attack as a set of 3 transactions, strictly following one another and addressing the same Uniswap V3 pool, as follows:

  1. Provision of Liquidity (minting)
  2. Swap
  3. Removal of liquidity (burning)

Transactoins 1 and 3 must be from same address (the attacker), while transaction 2 must be from a different address (the victim).

For each transaction, we determine the following data points:

  1. Amount of liquidity provided
  2. Volume of the trade that was “sandwiched”
  3. Attacker’s revenue, coming from two sources — transaction fees and price impact. The calculation is relatively involved, especially for cases where the price moves between tick intervals. See Appendix A for details.
  4. Success/failure. In very few cases, the price does not pass through the tick interval where the attacker provided liquidity.

We are using VirtuSwap Research database derived from blockchain_etl Ethereum tables.

How Many?

The first sightings of LP Sanwich attacks happened in June 2021. For about one year, the attacks were relatively rare, but starting July 2022 the total number shows sustained growth, with average weekly count raising from 200 June to 1500 in November, as show in the chart below.

Number of JIT Liquidity Attacks per weekx

At the time of writing, the total number of attacks has reached 31 thousands.

How Much?

Since Jun 2021, the total trading volume affected by JIT Liquidity attacks sums up at $4.5B, and the total amount of liquidity used in those attacks amounts to $477B.

The charts below show the weekly amount of trading volumes attacked and the total dollar amount of liquidity used in the attacks.

Note the million scale in the Trade Volume and the Billion scale in Liquidity.

The averages in the chart below also present an interesting picture:

In 2022, the average size of attacked transactions was huge, reaching $1.5 million in November 2021. In 2022, the average size dropped to around $90K. On the other hand, the average amount of liquidity used in an attack dropped much less — from about $25M in Novemner to about $15M on average.

How big is our phenomenon in comparison to overall trading? The charts below demonstrate total trading and liquidity provision volumes on all Uniswap V3 pools.

While the percentage of trading volume attacked by JIT Liquidity attacks is small, the share of JIT Liquidity attacks out of total LP activity is gargantuan. The percentage charts below show it even more eloquently:

The trend is clear — the JIT liquidity attacks are growing, both in absolute and relative terms. In the end of 2022, JIT liquidity attacks accounted for over 90% of all the LP activity on Uniswap V3. It should be noted, however, that the percentage of time-weighed liquidity provided by JIT attackers out of total time-weighed liquidity is 0 as this liquidity is deployed for 0-duration.

Where?

It appears that most of the attacks are happening on one particular WETH-USDC pool, specifically on Uniswap V3: USDC 3, followed by another WETH-USDC pool, Uniswap V3: USDC 2.

All the rest account for less than 25% of attacked trading and liquidity volumes.

The rationale between the pool choice can be explained as follows:

  1. Uniswap V3: USDC 3 has the highest trading volume of all Uniswap pools, providing most opportunities for attacks.
  2. Pools with higher volatility are much more suitable for JIT Liquidity attacks — it is more probable to catch a situation where little liquidity provided by existing LPs. Therefore, stablecoin pools are less suitable.
  3. A JIT Liquidity Attack requires a significant amount of funds (millions to tens of millions of dollars worth of assets). Borrowing would add costs, so attackers use their own funds, which implies constant holding of large amounts. Therefore, WETH and USDC are preferred to more volatile assets.

Who?

The following chart shows the breakdown of revenue and activity between wallets and MEV bot contracts on a quarterly basis.

Overall, the 0xa57bd00134b2850b2a1c55860c9e9ea100fdd6cf bot contract dominates the landscape, taking over 88% of all the revenue to date. There is however a bold newcomer — 0x57c1e0c2adf6eecdb135bcf9ec5f23b319be2c94 is taking the space by storm and generating almost half of the revenue in Q4 2022.

In terms of wallets addresses, there are multiple wallets interacting with the 0xa57bd contract, but there is only a single wallet interacting with 0x57c1e0, namely 0x479bc00624e58398f4cf59d78884d12fb515790a. That particular wallet entered the game on August 24 this year and has made over $400K in revenue since then.

Economic Modeling

Revenue and Gross Profit

As discussed above, the attacker’s revenue is composed of fees and price impact (cf. Appendix A for details on the calculation details).

The chart below shows attackers’ weekly revenue over time, broken down by source (fee vs. price impact), as well as average revenue per transaction.

Fee component dominates the attacker revenue. While price impact revenue was somewhat significant in late 2021, its share of the overall revenue became negligible as of late. This can clearly be attributed to the decrease in the average volume of attacked trades — smaller transactions result in smaller price impact.

Also, the average revenue per transaction dropped dramatically from over $1000 in the beginning of 2022, down to around $60.

In total, over $5.4M in revenue has been generated by this attack strategy over time, out of which $5.2M in fees and $250K in price impact.

Arguably, the existing LPs would not have benefitted from Price Impact (it would be arbitraged out), but the $5.4M in fees is clearly taken from the LPs.

While this amount is not yet significant compared to $1.2B total fees collected by Uniswap V3 LPs since June 2021, it is growing.

Attackers must pay the gas fees for the minting and burning tramnsactions, therefor their gross profit is calculated as follows:

The total gas fee volume paid by JIT attackers reached almost $1M, resulting in total gross profit of $4.5M.

Minimum Trade Size for Attack

In order for an attack to be profitable, the attacker’s revenue should be higher than the gas fee paid for the minting and burning transactions. We will focus only on the fee component of the revenue, discarding the price impact.

The fee revenue from an attack can be calculated as follows:

Here, Δx is the amount of input asset that was swapped inside the attacked tick, fee is the fee percentage charged by the pool, L_attacker is the amount of liquidity provided by the attacker, L_total is the total liquidity in the interval and P_usdx is the dollar price of the input asset. The L_attacker/L_total ratio defines the attacker’s share of the fees (and price impact) generated by trades in the interval.

Obviously, the attack can only be profitable if R_fee is greater than the gas cost, so attacking trades below a certain amount cannot be profitable even if the attacker takes 100% of the fee revenue.

For example, the minimum gas cost of a JIT attack in December 2022 was about $7.22, so for an attack to be successful on the Uniswap V3: USDC 3 pool with 0.05% fee, the input volume must be greater than $14,400.

The chart below shows the minimal observed size of the attacked trades and the minimal observed gas costs of the attack on a monthly basis.

Minimum attacked volumes and minimum gas costs per month

As expected, we can see a strong correlation between the two — as gas cost decreases, so does the minimum size of the trade that is worth attacking.

Share of Liquidity

Theoretically, the optimal ratio for an attacker is such that the marginal cost is equaling or exceeding the marginal benefit. The marginal cost can be linear (if the liquidity comes from AAVE or another lender) or a step function (if the attacker uses own funds with opportunity cost of 0) but these funds are limited.

The chart below shows the distribution of the attacker’s share of liquidity vs. the size of the attacked trade.

We observe that the attackers strive to achieve maximum (over 98% share) regardless of the size of the trade, indicating that they deploy all their available liquidity. This indicates that the attackers consider the cost of liquidity to be zero. Indeed, we failed to observe any borrowing of funds on-chain.

The plot below shows the behavior of three different bot contracts in this regard. Each dot represents the share of the attacker’s liquidity in each individual transaction for the 3 bots that have shown most activity.

The bot 0x57c1e seems to have a clear boundary of liquidity share at 99%, while the 0xa57bd bot seems to use as much liquidity as it has available most of the time, striving for 100%.

Net Profit

The previous discussion disregarded the elephant in the room — MEV costs. If the reader is not familiar with MEV, there is a great primer here. In short, those are the costs the attackers need to pay to the block builders, and through them to validators to have their sandwiches included in the blocks.

In this section, we will estimate the MEV costs associated with JIT Liquidity attacks, and the net profitability of those attacks.

In post-merge Ethereum MEV ecosystem, arbitrageurs (aka searchers) compete in an auction against the Block Builder to have their transaction bundles included into a block. The bids (also known as MEV Rewards) are submitted in the form of direct transfers to the coinbase address, and sum of all arbitrageur bids can be observed as the value of last transaction in the block.

However, there is a difficulty — most blocks have more than one MEV attack in them, and it is not possible to deduce what share of the total MEV reward should be attributed to a specific attack.

In order to estimate the MEV rewards paid by JIT Liquidity attackers, we picked the instances of JIT attacks where the MEV reward paid in the block was lower than the estimated revenue from trade fees. We assume that the attacker can precisely calculate the revenue they are expected to receive from the attack, and that they are rational, so they won’t propose an MEV reward that is higher than the expected fee revenue.

Out of the total 16,655 attacks that occurred post-merge, only 1,922 satisfied that condition. The chart below shows the average share of the attacker’s gross profit paid out as MEV reward.

Monthly average ratio of MEV Reward to Attacker Gross Profit

The percentage is surprisingly stable. Based on this finding, we can assume the average share of the attacker’s revenue paid in MEV Rewards to be 65%. This is an upward-biased estimation, as there may still be other MEV attacks in those blocks.

ROI

Incorporating the estimation of MEV costs, we can now calculate the ROI of JIT Liquidity attacks.

This can be done using the average amount of liquidity employed in an attack, or, more conservatively, using the maximum amount used by the attacker. We estimate the attackers’ net profit at 35% of the gross profit.

Looking at the data for three full months from October to December 2022, and considering the two MEV contracts as separate entities with their own P&L, we get the following ROI estimations:

In case the two MEV contracts are considered as one entity, the average and maximum liquidity-based ROIs go up to 10.26% and 2.26% respectively.

The ROI estimations based on average liquidity appear quite good, especially taking into account the zero risk on principal. In light of our evidence that the attackers tend to deploy close-to-all their available liquidity at the time of the JIT attack, it seems more reasonable to estimate their returns relative to the average liquidity deployed, i.e. at around 5%.

Since the funds are only used for a fraction the time, the attackers might employ them in other activities to increase overall returns. Validating this hypothesis is out of scope of the present research, but it is quite likely.

Unrealized Potential for JIT Attacks

Do the arbitrageurs use all the available attack opportunities?

We have analyzed the historical trading information on Uniswap V3 to assess the amount of attack opportunities that were not used by JIT attackers, and the data shows that the attack potential is barely scratched.

Looking at all the trades over $20,000 that occurred on the Uniswap V3: USDC 3 pool between July 2022 and Jan 2023 (any trade of over $20K was a good candidate for attack due to low gas costs), we see that the percentage of attacked trades is rising sharply, but is still below 10%.

What happens to LP revenue if this percentage continues to rise?

The chart below shows the distribution of total fees earned by LPs of the Uniswap V3: USDC 3 pool broken down by trade size binned in $10K

With only 5% of fees generated by trades below $20K, LPs in the pool may be losing a large part of their revenue as the number of attacks continues to grow. In the long run, it may lead to decrease in TVLs leading to higher slippages leading to lower organic trading volumes, essentially killing the pools. This scenario is more likely for pools holding major assets such as WETH, WBTC and the main stablecoins.

Conclusions

JIT Attack is a highly sophisticated DeFi MEV attack. Properly performing such attack requires an ability to immediately deploy a significant amount of capital, which creates a serious barrier to entry into this market, compared, for example, to positional arbitrage which can be done using flash loans.

In addition to large amounts of capital, such attacks require detailed information on the state of liquidity in all the tick intervals of the attacked pools, which also requires sophistication and infrastructure to collect the relevant information from the blockchain.

The phenomenon of JIT attacks is on the rise, and as we have shown, there is still a serious potential to be realized in this space.

While JIT Liquidity attacks are beneficial to the traders — they greatly decrease the price impact , — they are largely detrimental to the existing LPs in concentrated liquidity AMM pools. It can be said that the LPs are penalized for inefficient deployment of liquidity, leaving intervals with shallow liquidity where they can be deprived of the fees.

A possible solution to the problem would be to prevent minting and burning the liquidity in the same block , or requiring a certain minimum number of blocks between the two actions— such restriction would make the JIT liquidity attacks impossible. Kyber has implemented such mechanism (“Antisniping Attack”) by introducing vesting of LP rewards. We hope that Uniswap v4 roadmap also addresses this issue.

JIT Liquidity Attacks aka LP Sandwiches are a fascinating phenomenon. We will continue following it in our weekly #talesfromthedarkforest series and sharing our insights with the community.

Appendix A — Calculating Attacker Revenue

The following explanation assumes familiarity with the basics of Uniswap V3. We recommend reading LIQUIDITY MATH IN UNISWAP V3 and the Uniswap V3 Whitepaper.

In JIT Liquidity Provision attacks, the attacker’s revenue comes from two sources — swap fees and the price impact paid by the trader.

The revenue is distributed between all LPs inside a tick according to the amount of liquidity they provided.

Therefore, in order to determine the revenue of the attacking LP, we need to know the ratio between the amount of liquidity they provided to the tick interval in which the trade was executed, and total liquidity L in that interval.

Sometimes a trade is executed in more than one tick interval. In such cases, the LP receives fees and price impact revenue only for the amount that was traded in the tick interval in which they provided liquidity. Here’s as sample diagram:

The trade starts at the previous price, corresponding to Previous Tick. During the execution, the price grows, reaches the next tick interval and stops at some point inside that interval. The attacker only receives revenue for the fraction of input amount that fell into the price range serviced by her liquidity. That amount can be calculated using formulas (6.14) and (6.16) from Uniswap V3 whitepaper:

Liquidity L in the trade interval, as well as the tick (and thus the price) are reported by UniswapV3Pool contract in Swap event log, and the tick interval boundaries can be easily calculated. Square root of price corresponding to tick i can be calculated using formula (6.2) from the Whitepaper:

Knowing the previous price and the borders of the final tick interval, we can determine ΔP and Δ(1/√P) as follows:

Here, P_l and P_u are the prices corresponding to the lower and upper boundaries of the tick interval, respectively, and P_prev is the price at which the previous trade completed.

The calculated Δx and Δy values represent the actual amounts that were swapped inside the tick interval covered by the attacking LP.

The fee revenue in us dollars can be calculated according to the following formula:

Here, Pusd_x is the USD price of the input asset x.

Price Impact can be calculated according to the following formula:

Here, P_prev is the previous (or implied) price, Δx is the input amount, Δy is the output amount, Pusd_y is the dollar price of the output asset, and L_attacker/L is the LP’s share of liquidity in the trade intevral.

In case the trade crosses the tick interval where liquidity is provided, P_prev should be replaced by P_u if previous price was higher or P_l if previous price was lower, respectively.

Acknowledgements

  • Thanks to Alex Romanov of Beam for providing invaluable insights into the MEV ecosystem
  • Thanks to Xin Wan of Uniswap for his kind help in debugging the initial queries

References

  1. Just-in-time Liquidity on the Uniswap Protocol by Xin Wan
  2. Just-In-Time Liquidity: How MEV Can Enhance DeFi on Ethereum by Edward Oosterbaan, Coindesk
  3. Uniswap V3 Whitepaper
  4. LIQUIDITY MATH IN UNISWAP V3 by Atis Elsts
  5. Flashbot Auction Overview

VirtuSwap is a new kind of DEX with unrivaled efficiency.

VirtuSwap team is comprised of finance professors and crypto veterans, and backed by industry heavyweights.

We are on a mission to make DEXes dominate the crypto trading landscape, and we are accomplishing it through research, financial engineering and data science.

Don’t forget to like and share.

Follow us on: Twitter | Discord | LinkedIn | Telegram | Medium| Website

--

--

Alex Zaidelson

CEO at SCRT Labs, Adviser at VirtuSwap, former CEO at Beam. Researcher, Builder, Believer.