Explorations in Same-block Arbitrage
I took advantage of the 7 day premium credit after Snowsight launched to try my hand at Avalanche mempool backrunning. I had some success with the approach in the first two days, but sadly had to pause the experiment while I attended to some family business (letting a bot run wild for a week was a recipe for trouble).
I will keep experimenting and refining, but the results were encouraging enough to present the approach here.
What is Backrunning?
When you have access to the mempool, you gain access to a special class of MEV: same-block arbitrage. Same-block arbitrage is secured by submitting and confirming a transaction in the same block that an arbitrage opportunity becomes available. This is a preferred option for several reasons:
Access to the mempool is limited, so the number of competing searchers is lower.
There is (ideally) no time delay between the arbitrage opportunity being created and captured by your transaction.
Because of the nature of the backrunning strategy, there is no need to fight and win a priority gas auction or overpay to execute your transaction.
The term “backrunning” is similar to the idea of “frontrunning”, except that your transaction is crafted to be recorded in the block after your opportunity is created.
What is the key difference between a frontrun and a backrun? The gas fee.
How Do Miners Order Transactions?
Consider the mempool from the perspective of a miner. They are tasked with performing a great deal of CPU-intensive work (processing, confirming, propagating transactions, and maintaining synchronization of the blockchain network).
They are incentivized to perform this work by means of the block reward, which is a credit given to the miner who proposed the eventual successful block that is added to the chain.
In the case of EIP-1559 (type 2) transactions, the miner is doubly incentivized to include certain transactions by means of a priority fee, which is given directly to them in addition to the block reward.
Each block has a limit amount of space, so not all mempool transactions can be included in every block. There is also a target block time, which is managed via consensus adjustment of block difficulty.
With this environment, the miner is therefore incentivized to order transactions starting with the highest gas fees first, and to fill as much of the block as possible before the block must be “finalized”, hashed, proposed and propagated to the network for consensus.
In the case of geth, the default ordering of transactions is by gas fee first, then by time received in the case of matching gas fees. You can review the original pull request HERE.
How Do I Actually Perform a Backrun?
Observe a pending transaction in the mempool
Simulate the effect that pending transaction will have on the block state
Calculate arbitrage opportunity at that future state
If an opportunity is found, prepare a transaction that captures that opportunity
Submit that transaction at the same gas price as the pending transaction
Hope that you are first 🙏
OK, maybe not so simple. There’s a fair amount of luck involved with this approach, and it’s very latency-sensitive. If you haven’t already done so, I recommend setting up a dedicated botting VPS for this purpose.
Luckily we have all the parts we need to build a mempool bot. Because I’ve been on the Snowsight train lately, this will take the structure of the Snowsight bot project and modify it to exclusively capture mempool arbitrage.
This will use the premium tier on Snowsight via their transaction propagator relay. If you prefer to use an RPC instead, rewrite the transaction execution section to submit a regular transaction via web3.py or Brownie.
This will watch the same token pair I presented earlier, CRA-WAVAX. I did not have time to extend this out to more token pairs, but I am working on making the configuration more generic and searching for arbitrary token pairs.