14 min read
Overview
If you're curious about MEV (Maximal Extractable Value) or looking to deepen your understanding, you're in the right place!
In this guide, we will explore the subject of MEV and discover how it's shaping and impacting Ethereum today. Later on, we'll talk about how to protect yourself from MEV by using the Merkle.io add-on from the QuickNode Marketplace.
What You Will Do
- Learn about MEV (Maximal Extractable Value)
- See MEV in action with real-world examples
- Learn how to use the QuickNode add-on Merkle.io MEV Protection to send a private DeFi transaction
What You Will Need
- A basic understanding of blockchain concepts and Ethereum
- Some understanding of DeFi or TradFi
- Node.js (v18>) and Ethers.js installed
- A web3 wallet with access to your private key and ETH to pay for gas fees
Dependency | Version |
---|---|
node.js | 18.13.0 |
ethers | ^6.9.0 |
Transaction Process from User to Blockchain
Before we dive into MEV, let's cover some foundational concepts of how transactions and blocks are processed on Ethereum.
When a user initiates a blockchain transaction, such as transferring tokens or executing a function on a smart contract, they specify details like the recipient's address, transaction fee, and some arbitrary data. This transaction is then broadcasted to the blockchain network via a node (like QuickNode), where the network node validates its basic parameters. Upon validation, the transaction enters the node's mempool, a holding area for all unconfirmed transactions, and the node begins broadcasting that transaction to a subset of its peers.
From the mempool, miners (in Proof-of-Work systems), validators (in Proof-of-Stake systems), or builders (i.e., MEV opportunity searchers) select transactions to include in the next block, typically favoring those with higher fees. Once a set of transactions is included in a block and that block is mined, the block is broadcasted to other nodes in the network to be validated and will continue to be built on top of.
What is MEV (Maximum Extractable Value)?
MEV, also known as Maximum (or Miner) Extractable Value, is apparent in both Proof-of-Work or Proof-of-Stake blockchains today (e.g., Bitcoin and Ethereum). MEV, in simple terms, can be described as the measure of total value that may be extracted from transaction ordering permissionlessly (i.e., without any special privileges).
With this ability, a miner/validator (soon we'll find out who else participates) can extract additional economic gain on top of the fees and revenue generated when building a block. Where is the additional gain derived from? Well, by having the ability to reorder the block, insert their own transactions or exclude (censor) some transactions, you uncover arbitrage opportunities that can be taken advantage of.
You may be wondering, how are these block producers so smart to figure out these arbitrage opportunities? In most cases, it's not them. Instead, these opportunities are competitively fought for by other entities (i.e., third parties like "Searchers") who run automated bots (algorithms) on and off-chain and compute which transaction reordering will maximize their profits. Most of the arbitrage opportunities today are captured from individuals/entities interacting with DeFi protocols like Aave, Uniswap, Balancer, or similar forks.
Now, let's dig into the different arbitrage opportunities being captured by MEV today.
Types of MEV
Before diving into common MEV types we see today, we should note that not all MEV attempts are successful, and most of the time, opportunities are competed upon against other MEV searchers.
Frontrunning, Backrunning & Sandwiching
Suppose you are a trader planning to buy a significant amount of a certain cryptocurrency on a DEX (i.e., whatever coin your inner degen desired). Once your transaction is sent to a node which is then broadcasted, your transaction enters the mempool but still remains unconfirmed until a miner or validator includes it in a block. This waiting area for transactions is where an MEV searcher (or "searcher" for simplicity in this guide) comes into play. These searchers continuously monitor the mempool for potential arbitrage opportunities. When they spot your large trade that is a pending transaction, they can execute a strategy known as frontrunning. Here's how it unfolds technically:
- Identify: The searcher filters through the mempool to identify any large DEX transactions that they may be able to frontrun and profit from.
- Execution: The searcher quickly creates their own transaction to buy the same cryptocurrency. They ensure their transaction includes a higher gas fee, incentivizing block proposers to prioritize and process it before yours.
- Arbitrage Opportunity: After the large trader's transaction has been executed and the price has increased (to the predetermined price the searcher calculated their profit target), the searcher can either hold their unrealized gain or sell their unrealized profit (which in effect, is called "sandwiching").
This profit is essentially an arbitrage opportunity realized by capitalizing on the knowledge of your pending transaction. They leveraged the time difference between transaction initiation and confirmation to their advantage, often at the expense of regular users like you, who face bad trade exeuction in their trades. It is also likely that this searcher is one of many who's realized the potential profit and will need to compete with other searchers (lessening their profit as you can expect a gas bid war, reducing profits to potentially zero at the expense of profit).
Although the example above showcases the potential profit opportunity from a trade arbitrage, block proposers also search for other frontrunning opportunities to capture such as when a user calling a certain smart contract method ends up with more funds then they started with. This is done by simulating the transaction the user is calling (even if the block proposer doesn't fully understand the transaction), checking to see if the user will end up with more funds, and then trying to front run the user to capture the opportunity first.
You can also view real-time pending and queued transactions in the Ethereum mempool (or other blockchains that support Geth) by calling the RPC method - txpool_content.
Backrunning is the opposite of frontrunning, where block proposers position their transaction right after a significant one, exploiting the potential price discrepancies and arbitrage opportunities between exchanges.
Here is a case of a successful arbitrage trade where an investor converted 1,000 ETH into 1,045 ETH by exploiting the price discrepancy of the ETH/DAI pair between Uniswap and Sushiswap - Etherscan link.
Liquidations
On-chain lending protocols on Ethereum and other blockchains today are generally open-source and have liquidation engines that anyone can execute. The user helping facilitate the protocol's healthy workings generally gets some profit from the collateral needed to be paid off. With this, MEV searchers use the same techniques as frontrunning to search the mempool, analyze it, and try to capture this arbitrage opportunity first.
Just-in-Time Liquidity (JIT)
At its core, JIT liquidity refers to the strategy of providing liquidity to a DeFi protocol or liquidity pool only at the precise moment it is needed for a transaction rather than keeping funds locked in the pool indefinitely.
How does it work? This is similar to how a searcher filters through the mempool to find a large trade that could significantly impact a liquidity pool's price. Once identified, a searcher quickly executes a transaction to add liquidity to the relevant pool (hence the term "just-in-time"). Once the large transaction is executed using the liquidity provided by the searcher, the searcher can withdraw their liquidity from the pool and reap the benefits of transaction fees and/or slippage.
To see a real example of a JIT transaction, check out this set of transactions on Etherscan. 1. Add Liquidity 2. Swap 3. Remove Liquidity. In this scenario, the three transactions took place within the same block, Block 13733864, and were executed in a consecutive manner. The JIT liquidity provider grouped these transactions together and dispatched them using Flashbots. Given their foreknowledge of both the size of the swap and the liquidity distribution at that particular time, the JIT provider could have, and presumably did, accurately determine the expected fee income and the impact on their position from this trading activity.
The types of MEV mentioned above are a partial list, and other types of opportunities may still be discovered. With that being said, a big advantage to a searcher to take advantage of MEV is latency. Searchers or bots continue to minimize the latency, creating a competitive environment for those who want to profit from MEV.
Time Bandit Attack
Another type of MEV attack is called a "Time bandit attack". As the name suggests, this MEV arbitrage looks to rewrite history to take advantage of the EVM's state. If a miner/validator sees that the block they are proposing has far less revenue creation compared to the MEV the block can generate, the miner/validator can try to destabilize consensus and rewrite the block so they can take advantage of the MEV generated themselves.
Risks with MEV Today
Now, you may have already realized the risk in MEV today and how it affects the end-user, but let's recap.
Network Congestion and Increased Transaction Costs: MEV strategies often involve bidding wars for block space, as MEV actors compete to have their transactions included first. This can lead to network congestion and increased transaction fees, impacting all network users. There is a large percentage of failed MEV transactions that has wasted block space and high gas fees.
Centralization & Censorship Risks: MEV can contribute to the centralization of power among a few sophisticated actors (like miners, validators, or large-scale bots). This centralization is contrary to the decentralized ethos of blockchain. MEV has already extracted billions of dollars of value and will continue to do so. Although new research firms and protocols are developing solutions to mitigate this issue, problems persist today. For example, a large percent of validators today who run middleware (for maximizing their profits with MEV) have OFAC-sanctioned address lists, censoring transactions and compromising Ethereum’s neutrality. Check out this dashboard created by MEVWatch that shows the current validators censoring transactions.
Loss of Privacy: As MEV actors monitor the mempool for opportunities, there’s a risk of reduced privacy for users. Transaction details are exposed, and users intentions can be predicted and potentially exploited.
Although this all seems very dangerous, you may be thinking... I am done with crypto and Web3! Slow down; there are some solutions. Let's dig in.
Solutions & Tools to Protect against MEV
Flashbots
Flashbots, a research and development organization, is at the forefront of MEV, looking to mitigate its negative externalities.
Flashbots has built an RPC suite that allows Ethereum users frontrunning protection, configurable privacy and execution, and the ability to internalize the MEV they create. How do they do this? Well, they screen all transactions and check if they need MEV protection. If the type of transaction does not typically generate MEV, it will automatically be sent to the public mempool. Conversely, if the transaction has some probability to generate MEV, it is only shared with with the Flashbots Builder (which only builds a subset of all Ethereum blocks). Additionally, if there is any MEV generated from the transaction, you get up to 90% of it back through MEV-Share. MEV-Share is a product built by Flashbots that redistributes MEV back to the party that created it.
Flashbots also has built another important piece in securing MEV on Ethereum called SUAVE (Single Unifying Auction for Value Expression). SUAVE unbundles the mempool and block proposer roles from existing blockchains and offers a specialized and decentralized plug-and-play alternative. Over time, SUAVE will gradually decentralize, enhancing its trustworthiness and expanding its range of capabilities.
You can view and analyze the MEV generated on Ethereum with the following MEV-Explore dashboard. Explore the page, you can see that there has been many profitable MEV opportunities (with the all time high at $3 million +) but also realize that many searchers also compete for very little money (talking $5-10).
Flashbots also provides an open source client (forked from Geth) called MEV-boost, which enables validators to maximize their staking reward by selling blockspace to an open market of builders.
QuickNode + Merkle.io RPC Add-on
Luckily, QuickNode users can easily integrate MEV protection in their transaction workflow. The MEV protection & private reinforced transactions RPC add-on by Merkle.io on the QuickNode Marketplace is easy to integrate and abstracts away the complexity of sending transactions to a protected and private-sensitive transaction mempool. Simply add the RPC URL to your Web3 wallet (e.g., MetaMask, Coinbase Wallet, Rabby), and it will overwrite their eth_sendRawTransaction
RPC calls with its respective equivalent method (see the list of methods supported here).
Sign up here for free to use the QuickNode Merkle MEV Protection & Private Reinforced Transactions add-on
Additionally, some DeFi projects are developing smart contracts and backends that are resistant to MEV attacks. These protocols can include methods like transaction batching, randomized transaction ordering, or encrypted transactions to prevent frontrunning. Projects that have actually implemented MEV protection today include matcha.xyz and CowSwap.
Conduct a Private DeFi Swap with Merkle.io Add-on
The main purpose of using a private and MEV-protected transaction network (mempool) is to protect your transaction from negative externalities created by MEV. Not all transactions need MEV protection. For example, if you want to send ETH or transfer an NFT (or fungible token) to someone, you don't need to worry about MEV. However, as we discussed above, if you are conducting some financial activities (i.e., swapping tokens, or having funds lent out in a lending protocol), you should be protecting yourself (or your users).
Now, to put this into practice, let's demonstrate how one could create a transaction that swaps tokens on Uniswap and sends the transaction through Merkle.io via QuickNode for MEV protection. If you don't know how Uniswap works, I recommend checking out their documentation and this QuickNode guide.
First, make sure you have the add-on enabled. You can enable it by creating a new endpoint and adding the add-on during the endpoint creation process or by navigating to your endpoints Add-ons tab. Note that at the time of this writing, this add-on is currently only supported on Ethereum mainnet, BNB chain mainnet, and Polygon (PoS) mainnet.
Next, open up a terminal window and run the following set of bash commands:
mkdir defi-swap-protect && cd defi-swap-protect && echo > index.js
Initialize an npm ESM project:
npm init es6
Then, install the required dependencies. We'll be using the Ethers.js to help build our transaction and translate our blockchain-encoded values to readable format.
npm install ethers
Open the index.js file we previously created, and let's include the following code:
import { ethers } from 'ethers';
import link_abi from './link.json' assert { type: 'json' };
import swap_abi from './abi.json' assert { type: 'json' };
// Set up the provider
const provider = new ethers.JsonRpcProvider(QUICKNODE_HTTP_URL);
// Set up the wallet using a private key and provider
const wallet = new ethers.Wallet(PRIVATE_KEY, provider);
// Contract details
const swapContractAddress = '0xE592427A0AEce92De3Edee1F18E0157C05861564'; // // mainnet address
const wethAddress = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; // // mainnet address
const linkAddress = '0x514910771AF9Ca656af840dff83E8264EcF986CA'; // mainnet address
const swapContract = new ethers.Contract(swapContractAddress, swap_abi, wallet);
const linkContract = new ethers.Contract(linkAddress, link_abi, wallet);
// Transaction parameters
const fee = 3000;
const amountIn = ethers.parseEther('1');
const amountOutMin = 0
const deadline = Math.floor(Date.now() / 1000) + 60 * 10; // 10 minutes from now
const sqrtPriceLimitX96 = 0;
// Swap payload
const payload = {
tokenIn: linkAddress,
tokenOut: wethAddress,
fee: fee,
recipient: wallet.address,
deadline: deadline,
amountIn: amountIn,
amountOutMinimum: amountOutMin,
sqrtPriceLimitX96: sqrtPriceLimitX96
}
// Prepare swap and approval data
const transactionData = swapContract.interface.encodeFunctionData('exactInputSingle', [payload]);
const linkApprovalData = linkContract.interface.encodeFunctionData('approve', [
swapContractAddress,
amountIn
])
// Sending the transaction
async function sendTransaction() {
try {
let count = await provider.getTransactionCount(wallet.address)
const chainId = await provider._network.chainId
const approve_sign = await wallet.signTransaction({
to: linkAddress,
data: linkApprovalData,
gasPrice: ethers.parseUnits("25", 'gwei'), // Adjust this based on the networks current gas fee
gasLimit: 300000, // Hardcoded gas limit, may need to change
chainId: chainId,
nonce: count
})
await provider.send('eth_sendPrivateTransaction', [approve_sign])
console.log("Approve transaction sent")
count = await provider.getTransactionCount(wallet.address)
const swap_sign = await wallet.signTransaction({
to: swapContractAddress,
data: (transactionData),
gasPrice: ethers.parseUnits("25", 'gwei'), // Adjust this based on the networks current gas fee
gasLimit: 300000, // Hardcoded gas limit, may need to change
chainId: chainId,
nonce: count
})
await provider.send('eth_sendPrivateTransaction', [swap_sign])
console.log("Swap transaction sent")
} catch (error) {
console.error('Error sending transaction:', error);
}
}
sendTransaction();
Take a moment to review the code comments to better understand what is occurring. As mentioned before, check out our DeFi guides if you want to better understand trading on decentralized exchanges like Uniswap.
Later, replace the QUICKNODE_HTTP_URL and YOUR_PRIVATE_KEY with our actual endpoint and private key (that holds ETH to pay for gas fees). Take note of the ABI imports at the top of the script. You will need to add those files within the same directory and add the ABIs (in JSON format) to the file. You can retrieve an ABI from Etherscan's Contract tab. Plus, as previously stated, your QuickNode endpoint should have the Merkle.io MEV protection add-on enabled. Confirm this by navigating to your endpoints Add-ons tab and verifying it's in the list of "Installed Third-Party Add-ons".
Now, it's time to put the script into action. Run the following command in your terminal window within the project directory.
node index.js
You can verify the transaction was confirmed on a block explorer (like Etherscan or beaconch.in) by looking up the address the transaction was sent from.
If you want to learn more about DeFi, check out this curated list of guides.
Test Your Knowledge
Try attempting the short quiz to test your knowledge!
Final Thoughts
That's it for now! But I hope your MEV journey doesn't end here! If you're hungry for more, let us know. Whether it's a Part-2 deep dive or a hands-on guide to building your own MEV bot, your feedback shapes our future content <3
Subscribe to our newsletter for more articles and guides on Web3 and blockchain. If you have any questions or need further assistance, feel free to join our Discord server or provide feedback using the form below. Stay informed and connected by following us on Twitter (@QuickNode) and our Telegram announcement channel.
Additional Resources
- Flashboys 2.0 (This is the original research paper that studied in-depth the impact of MEV on Ethereum and smart contracts)
- Escaping the Dark Forest
- Frontrunning in DEXs, Miner Extractable Value, and Consensus Instability by Phil Daian at IEEE Symposium on Security and Privacy
- ETHOnline - Phil & Georgios Talk Miner Extractable Value
- Flashbots: Frontrunning the MEV Crisis by Flashbots
We ❤️ Feedback!
Let us know if you have any feedback or requests for new topics. We'd love to hear from you.