How To Reproduce A Simple MEV Attack

Immunefi
Immunefi
Published in
6 min readJul 20, 2023

--

Introduction

Exploits in the blockchain space are becoming more complex.

Before, smart contract developers and auditors mainly had to think about how to secure smart contracts against exploits that happen in a single transaction. But now, it’s much more common to see attacks that occur over multiple transactions.

Blackhats are also increasingly taking bold risks in the amount of personal funds they’re willing to invest in an attack in search of astronomical gains.

Just last week alone, a blackhat risked 50 ETH (~$96,000) to execute an attack against Rodeo Finance, resulting in a profit of about 472 ETH, valued at roughly ~$890,000. Cases like these solidify the principle that the “cost of attack” is not an effective security deterrent, and that any protocol relying on high attack costs to keep themselves safe should rethink their strategy.

In this article, we will be explaining one of the common ways that an blackhat can attack a vulnerable protocol using MEV. We will also be explaining how we as bug hunters can properly demonstrate an MEV attack vector with a PoC (proof of concept).

What is MEV

MEV (Miner Extractable Value or Maximal Extractable Value) allows miners to exclude, include, and order the transactions in the blockchain before the block gets mined. This has changed quite a bit in the aftermath of the Ethereum Merge, resulting in the transfer of this transaction ordering role to validators of the network. But nevertheless, the MEV attack vector is still common and relevant in the blockchain space.

There are multiple ways that MEV can be used by an attacker. We’re going to demonstrate what is known as a sandwich attack, which is accomplished by frontrunning and backrunning the victim’s swap transaction.

Frontrunning

Frontrunning is a technique where an attacker manages to place their transaction ahead of the victim’s transaction, so that the attacker’s transaction gets executed first. This can be done by inflating the gas price of the malicious transaction, so that it is prioritized over the victim transaction, which has a lower gas rate than the malicious transaction.

Backrunning

Backrunning is a technique where an attacker places their malicious transaction after the victim transaction gets executed. An attacker can accomplish this by lowering the gas price of the malicious transaction. This will make sure that the victim transaction is prioritized over the backrun transaction.

Sandwich Attack

In a sandwich attack scenario, the attacker monitors the mempool (a list of pending transactions) for a target transaction that they want to exploit. Once they identify the target, they submit two transactions — one before and one after the target transaction — surrounding it like the bread in a sandwich. The purpose of this sandwich is to manipulate the target transaction’s execution or outcome in the attacker’s favor.

Using the methods mentioned in the previous section, the attacker submits two transactions with higher and lower gas fees than the victim transaction in order to successfully execute the sandwich attack. Alternatively, they may submit a transaction bundle through specialized RPC providers which can guarantee the ordering of transactions for a fee.

This kind of attack can be particularly problematic in DeFi ecosystems, where transactions involving tokens, liquidity pools, or decentralized exchanges are highly susceptible to changes based on the order of the transactions. The aim of the attacker in these scenarios is usually to manipulate the prices of assets, profit from arbitrage opportunities, or exploit other vulnerabilities in the protocol for personal gain.

How To test An MEV Attack

In order to create a PoC to showcase an MEV attack, we can employ tools like Hardhat and Forge to create a local fork of a blockchain.

To prove a deterministic result between both of these tests, we will use the same Attacker contract, which can be accessed through this Github gist.

In this demonstration, we will intentionally make the victim invoke a swap transaction from WETH to USDC in UniswapV2 with 0 minimum amount. What makes this transaction vulnerable to a sandwich attack is the minimum amount that was set to 0, which means the transaction will not revert, even if the victim only receives 0 USDC or 99% slippage. That’s why it’s very crucial to set the minimum amount properly.

Hardhat

Hardhat is a framework for smart contract development, allowing a developer to use JavaScript/TypeScript as a way to interact with the smart contracts. Before Forge (a newer framework) was available, most whitehats made their PoCs by forking the blockchain using Hardhat.

Conveniently, Hardhat already provides a mechanism to hold the finalization of a transaction, so that the transaction that we invoke can be aggregated in the mempool before these transactions get finalized.

Step-by-step guide:

  1. Make sure you already have Hardhat installed on your machine (https://github.com/NomicFoundation/hardhat)
  2. Create a simple Hardhat project
  3. mkdir MEV-poc
  4. cd MEV-poc
  5. yarn add hardhat
  6. npx hardhat init
  7. Change the contract to the Attacker contract.
  8. Change the file in the scripts folder with sandwichAttack.js https://gist.github.com/GibranAkbaromiL/05020630475f4f2599f72b47e52c7949#file-sandwichattack-js
  9. Run npx hardhat run scripts/sandwichAttack.js

Output:

Forge

Forge is a smart contract development toolchain that allows you to test, deploy, and interact with the blockchain using Solidity scripts. This allows us to demonstrate an MEV attack simply by transaction ordering in the test file.

Step-by-step guide:

  1. Make sure you’ve already installed Forge on your machine (https://book.getfoundry.sh/getting-started/installation ).
  2. Create a simple forge project.
  3. mkdir MEV-poc
  4. cd MEV-poc
  5. forge init
  6. Change the contract in the src folder to the attacker contract.
  7. Change the test file in the test folder to Sandwich.t.sol. https://gist.github.com/GibranAkbaromiL/05020630475f4f2599f72b47e52c7949#file-sandwich-t-sol

Output:

From both of these test cases, we’ve managed to demonstrate an MEV sandwich attack using Hardhat and Forge. As we can see from the output of the test case, an attacker and victim started with 1000 WETH as the initial balance, and the attacker managed to frontrun and backrun the victim transaction, resulting in a profit of ~123 WETH for the attacker. The victim receives less USDC as a result.

What We’ve Learned

One of the most crucial parts in security research is creating a PoC based on the potential vulnerability that you’ve identified. Why is this so important? Because simply identifying a potential vulnerability doesn’t make the attack valid. The only way we can confirm whether the attack is valid or not is through the creation of a PoC, which has to be created uniquely for each identified vulnerability.

We’ve only discussed one of the many possible attack vectors that can occur with MEV, and the actual exploit scenario you discover as a researcher may differ greatly from the one shown here. In the example above, we only touched on one of the most common vectors, which is a sandwich attack of a swap with no slippage protection. If you would like to test your skills and attempt to reproduce some other attack vectors, do also check out: NFT mint front running, front running price updates from an off-chain oracle, and JIT (just in time) liquidity.

That’s it for this article. We hope that you were able to gain some new understanding or revise some existing knowledge in your mind palace, thanks to the few minutes you’ve spent here. Keep hunting bugs, and don’t stop learning. There are new exploits and bugs to discover every single day, and there is no shortage of rewards or opportunities for whitehats who put in the effort.

Happy hunting on Immunefi!

--

--

Immunefi
Immunefi

Immunefi is the premier bug bounty platform for smart contracts, where hackers review code, disclose vulnerabilities, get paid, and make crypto safer.