Road to Sleuth: Mastering JIT MEV Bots’ Internal Accounting on Uniswap with EigenTx
With Uniswap V4's coming, you a better toolkit to DYOR.
According to @jphackworth42, the revenue of JIT MEV on Unswap V3 has reached $7.3 million as of Jun 8.
The newly released spec of Uniswap V4 brings novel development to the field. Our poll showed that almost half of the participants predicted that there would be more JITs with Uniswap V4 coming.
Uniswap V3’s concentrated liquidity created Just-In-Time MEV bots that extract fees from liquidity pools, with risks for passive providers. JIT involves 3 or more transactions, whose detailed steps inside are hard to read. Let's dissect one of these JIT bots.
Internal Accounting: The Key to Figure Out JIT
There are 3 key types of transaction involved in a JIT trade: adding liquidity, swapping, and removing liquidity.
Take a look at the adding liquidity transaction of this JIT first.
Steps 0-1: The liquidity provider added $7.8 million $USDC and 98 $WBTC as liquidity to a Uniswap V3 pool.
Here are some key things to know if you want to crack JIT.
To keep the balance of the bookkeeping in Uniswap V3, EigenTx marked the internal liquidity share changes using virtualLiquidity, a placeholder. and we also added 2 virtual contracts: virtualLiquidity & virtualLiquidity-350101.
Uniswap V3 uses position NFTs as vouchers issued to liquidity providers. These NFTs record the number of liquidity tokens and liquidity shares provided by liquidity providers. In this transaction, the NFT is UNI-V3-POS-350101.
In the chart, you can regard the UNI-V3-POS contract as being used internally by Uniswap to match the internal record of liquidity providers. Like when each of us opens an account at a bank, the bank's internal database has corresponding account data.
On the other hand, NFTs like UNI-V3-POS-350101 are mainly for external uses, i.e.; liquidity providers and other external users. It's like our own bank account after opening an account at the bank.
Hence, we use two virtual contracts: virtualLiquidity and virtualLiquidity-350101, to help balance the liquidity changes of Uniswap V3.
And this is the UniswapV3Pool contract, representing the overall liquidity pool, stores liquidity tokens, and keeps records of the overall liquidity, identified as a virtual contract - virtualLiquidity - in the token flow chart.
All right, time to move on to the liquidity-adding transaction.
Adding Liquidity Transaction
Step 2: Uniswap V3 records the liquidity tokens added by the liquidity provider internally, being marked as minting 228,594,721,898,820 virtualLiquidity sending to UNI-V3-POS contract. Internal share changes were added.
Step 3: 228,594,721,898,820 virtualLiquidy-350101 was minted as a placeholder for the sake of bookkeeping on the virtual external account contract: virtualLiquidity-350101 and sending to UNI-V3-POS-350101. "External" share changes were added.
To summarize, the JIT bot added 97.925989 WBTC and 7,793,784.212848 USDC in the first two steps and got a position NFT identified as 350101.
Then, in step 4, representing the corresponding liquidity share, 228,594,721,898,820 it added.
Next is the user swap.
The JIT bot successfully bundled a user's swap transaction following its add-liquidity transaction within the same Uniswap V3 pool. The user was swapping a substantial USDC to WBTC using an aggregator.
Removing Liquidity Transaction
In the last transaction, the JIT bot effectively burned the position NFT to claim the entire liquidity share as well as the fee revenue. EigenTx's token flow chart ensures balanced token transfers with the support of complete internal accounting details.
In the liquidity removing process, we use virtualOwed0WBTC and virtualOwed1USDC to represent the “internal“ account balance of UNI-V3-POS, virtualOwed0WBTC-350101 and virtualOwed1USDC-350101 for “external“ UNI-V3-POS-350101.
NOW, about the last transaction.
Steps 0-2: Created the internal account balances, virtualOwed0WBTC and virtualOwed1USDC, for UNI-V3-POS, and burned the JIT bot's corresponding liquidity share, virtualLiquidity. The lines indicating the transfers 0-1 intersected with others.
You can read these internal share changes in the transfer list table beneath the token flow chart. Think of these 3 steps as balances moving from the liquidity of the pool to the internal account representation of the liquidity provider.
Steps 3-5: Similarly, we created the internal account balances for UNI-V3-POS-350101 and burned the corresponding liquidity share, virtualLiquidity-350101.
Think of these 3 steps as balances moving from the internal account representation of the LP to the external one.
Steps 6-7: UniswapV3Pool removed 89.0881 WBTC and 7,975,062 USDC and sent them to the JIT bot's contract.
Steps 8-11: Now that both the internal and external representation of the liquidity provider account should have no balance. UNI-V3-POS and UNI-V3-POS-350101 burned the corresponding balances of virtual liquidity tokens created in Steps 0-5.
Step 12: The JIT bot burned the position NFT, UNI-V3-POS-350101.
Step 13: The JIT bot paid a tip to the block builder. Eventually, the JIT bot profited about $285.5 from this trade.
As you can see, EigenTx presents a flow chart that perfectly aligns with every stage of a resource's lifecycle! And the best part? Internal bookkeeping syncs with this flow so that you can keep track of all cash flows in one precise database!
It's clear that EigenTx is crucial to discover the strategy we mentioned in this post. Please feel free to try it out on the EVM-compatible chains. And find more use cases here: https://docsend.com/view/ce853cukgp9xyhiu.
Follow us via these to dig more hidden wisdom of DeFi:
Website | Discord | Twitter | YouTube | Substack | Medium | Telegram
Nice piece of information sir. Impressive explanation about JIT and the core knowledge about it. Thanks for sharing this.
awesome!