Mempool, MEV and front-running explained

Mempool, MEV, Frontrun attack
Table of Contents

A mempool is the waiting area a blockchain node keeps for transactions it has checked and accepted but not yet put in a block. It is public, it is readable, and the order its contents execute in is for sale. Those three properties are the whole reason MEV, front-running, backrunning and sandwich attacks exist. Most trades no longer sit there: 92% of DEX volume now routes through private mempools instead, on Greenfield Capital’s August 2026 read of Ethereum block building. Your contract still has to survive the ones that do.

Picture a holding stack over a busy airport. Aircraft circle, a controller decides the landing order, and the radio is not encrypted, so anyone with a scanner knows which aircraft is low on fuel before it lands. A mempool is that stack with two changes. Everybody has a scanner. And the landing order is auctioned.

Quick answer

A mempool, short for memory pool, is the set of validated but unconfirmed transactions a blockchain node holds in memory while they wait to be included in a block. Because it is public and ordered by fee rather than by arrival, anyone can read your transaction before it executes and pay to be placed in front of it.

What is a mempool?

When you send a transaction it does not go to the chain. It goes to whichever node your RPC provider talks to. That node checks it, and if it passes, holds it in memory and gossips it to its peers. Hence the name.

The checks are cheap and local: the signature is valid, the nonce is the one expected from that account, the sender can cover the cost, and the fee clears the node’s own floor. Passing them means the transaction is worth propagating. It does not mean it will be included, and it does not mean it will do what you intended by the time it is.

Stage What happens What an observer can do at this point
Broadcast Your RPC hands the transaction to a node Read it in full, calldata included
Validation Signature, nonce, balance and fee floor are checked Learn that it will probably succeed
Gossip It propagates to peers See it seconds before it executes
Selection A builder orders the block by what each transaction pays Pay more to sit in front of it, behind it, or both
Inclusion It lands in a block and leaves the pool Nothing. It is settled

There is no single mempool

Every node keeps its own. They receive transactions at different times, apply different eviction rules and drop them at different points, so the pending list on an explorer is one node’s view rather than the network’s. Two nodes can disagree about what is pending and both be correct.

Position is bought, not queued

A mempool is not first come, first served. Builders select by what a transaction pays for its position, so the priority fee decides order, not arrival time. Replacing a pending transaction with a higher-paying one at the same nonce lets you overtake yourself. It also lets anybody else overtake you.

Why a queue becomes an attack surface

Two facts do all the damage. Your transaction is readable before it executes, and its position relative to everyone else’s is purchasable.

That is not a bug in any particular client. It is what a public, fee-ordered queue is. What matters is which parts of your protocol change behaviour when somebody else picks the order. That is a property of your code, not of the chain.

MEV, front-running, backrunning and sandwiching

MEV stands for maximal extractable value, originally miner extractable value. It is the value a block producer, or a searcher paying one, can capture by choosing what goes into a block and in what order. Front-running, backrunning and sandwiching are three ways of taking it.

Term Where the attacker’s transaction sits What it takes Typical target
Front-running Immediately before yours The opportunity you revealed A large swap, a claim, an auction bid, a profitable liquidation
Backrunning Immediately after yours The state change you created Arbitrage after a price move, a liquidation your trade enabled
Sandwich attack One either side of yours The slippage you allowed A swap with a loose or absent minimum output

Backrunning is the one worth separating out, because a lot of it is not an attack. Arbitrage that pulls a pool back to the market price after a large trade, and liquidations that keep a lending market solvent, are both backruns, and a healthy protocol wants both to happen quickly. The test is whether the value comes out of the user’s execution or out of a gap the protocol needed closed.

Sandwiching has no such ambiguity. The attacker buys ahead of your swap to move the price against you, then sells after it at the price your own trade created. Your loss is their profit, and it is bounded by nothing except the slippage tolerance you were willing to sign.

The public mempool is no longer where most trades sit

Private routing has changed the shape of the problem. Users and frontends increasingly hand transactions straight to builders instead of gossiping them, through a protected RPC such as Flashbots Protect or MEV Blocker, through an orderflow auction, or through an intent system where a solver executes on the user’s behalf. Greenfield Capital’s August 2026 analysis puts 92% of DEX volume through private mempools in recent months, and finds MEV-related flow accounting for 66% to 80% of weekly priority fees.

It has not ended sandwiching. The same analysis records sandwich strategies back up at 35% to 51% of MEV-related priority fee spending in recent weeks.

Two things follow for a protocol team, and both are easy to get wrong.

  • Private routing is a property of the sender, not of your contract. It protects the users who happen to use a protected endpoint. Integrators, bots, other contracts and anyone on a default RPC arrive by the public path.
  • You do not control the route your users take. Your frontend’s default binds nobody. Your contract is the only surface you own end to end, which is the part a manual smart contract audit is reading.

Solana has no mempool, and that does not make it safe

The Solana documentation is unambiguous: “In Solana, there is no concept of a mempool. All transactions, whether they are initiated programmatically or by an end-user, are efficiently routed to leaders so that they can be processed into a block.” Transactions go straight to the validator scheduled to produce the next slot, and the leader schedule is published an epoch in advance.

Ordering is still adversarial. It is simply decided somewhere else, by who reaches the leader first and what they are willing to tip. The proof is what happened when a mempool did appear: Jito’s Block Engine offered one, sandwich attacks on Solana climbed, and Jito suspended it in March 2024 citing the harm to users.

So ‘this chain has no mempool’ is a statement about how transactions propagate, not about whether ordering can hurt you. Fidesium audits both EVM and Solana programs. Ordering dependence is a property of the code in either case, and the patterns below apply on both.

What ordering dependence looks like in your own contract

This is the half the definitions leave out, and it is the half you can change.

Pattern Why ordering breaks it What a reviewer looks for
Slippage bound missing or self-referential A minimum output of 0 accepts any price. Worse, deriving the bound on-chain from the pool you are about to trade against reads a price the attacker already moved in the same transaction bundle A bound supplied by the caller, computed off-chain against a reference price with an explicit tolerance
A deadline that cannot bind Passing block.timestamp as the deadline satisfies the check in every block, so a transaction can sit pending and execute at a price nobody saw An absolute deadline chosen by the caller
Spot price used as an oracle Any single-block price, raw pool reserve or router quote can be moved by the transaction in front of yours Manipulation-resistant pricing anywhere you value collateral, mint, or liquidate
Randomness from chain attributes blockhash, block.timestamp and block.prevrandao are known or influenceable at the moment the deciding transaction is selected An external source, or a commit-reveal where the reveal cannot be withheld
The first deposit into an empty vault The ERC-4626 inflation attack. The attacker deposits a token, donates a large amount to the vault, and front-runs the first real deposit, which then rounds down to zero shares Virtual shares and a decimals offset, as OpenZeppelin implements, or a seeded first deposit
An allowance moved from one non-zero value to another EIP-20 flags this in its own text: a spender can front-run the change and spend both allowances Allowance increments, or permit with a nonce
Anything settled by who is first Unprotected initialisers, one-shot claims, auction bids and mints are decided by ordering rather than by your logic Access control, commit-reveal, or a design where being first is not worth paying for

The first row is the one that catches careful teams, and only its second half. A router call with both bounds passed in looks like this:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IRouter {
    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);
}

// Token approvals are omitted for brevity. The point is the two bounds.
contract Treasury {
    IRouter public immutable router;

    constructor(IRouter router_) {
        router = router_;
    }

    // Sandwichable. A minimum output of 0 accepts any price, and block.timestamp
    // as the deadline is satisfied in every block, so neither bound can ever bind.
    function swapUnsafe(uint256 amountIn, address[] calldata path) external {
        router.swapExactTokensForTokens(amountIn, 0, path, msg.sender, block.timestamp);
    }

    // Both bounds come from the caller, who computed them off-chain, and both
    // are enforced on-chain by the router.
    function swap(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        uint256 deadline
    ) external returns (uint256 amountOut) {
        require(amountOutMin > 0, "min out unset");
        uint256[] memory amounts = router.swapExactTokensForTokens(
            amountIn, amountOutMin, path, msg.sender, deadline
        );
        amountOut = amounts[amounts.length - 1];
    }
}

The require is a floor against the obvious case and nothing more. A minimum of 1 wei passes it and protects nobody. What protects the second function is that the number comes from outside the transaction, so it reflects a price the attacker did not set. Code that computes the same bound on-chain, by quoting the pool it is about to trade against, passes its own check at exactly the moment it should fail, and it survives review precisely because it was clearly written with slippage in mind.

What a protocol team can actually do about it

Layer The lever What it gets you What it does not do
Your contract Caller-supplied slippage and deadline arguments, manipulation-resistant pricing, access control on one-shot functions, virtual shares on vaults Removes ordering dependence from the code, for every caller, on every route, permanently Stop MEV existing
Your design Batch settlement, commit-reveal, intents and solver execution, auctions that do not reward being first Makes position worth less to buy Come free. Each adds latency, complexity and its own failure modes
Your users’ route A protected RPC as the frontend default, orderflow auctions Protects the transactions that use it Reach anyone who does not use it

MEV cannot be removed. It is a property of a public chain with an ordered ledger, and any protocol claiming otherwise is selling something. What can be removed is the part where ordering changes what your code does, and that is testable.

Fidesium’s manual smart contract audits are line-by-line human review, chain agnostic with an EVM specialism, covering logic and economic risk, with two rounds of fix verification included. They start at $5,000, and the reports are public: the audit portfolio is the work, not a summary of it.

One last thing, because it is the whole point of doing this properly. An audit is a snapshot of a commit. The ordering assumptions you verified on the day still have to hold after the next merge, which is what continuous scanning on every commit and post-deployment monitoring are for. And if you want the stronger version, “a swap can never return less than the caller’s stated minimum” is an invariant, and an invariant is the kind of thing formal analysis proves rather than tests.

Frequently asked questions

What is a mempool, in one sentence?

A mempool is the pool of validated but unconfirmed transactions that a blockchain node keeps in memory while they wait to be included in a block.

Is there one mempool or many?

Many. Every node keeps its own, and they receive transactions at different times and apply different eviction rules, so no single view of what is pending is authoritative.

What is MEV?

MEV stands for maximal extractable value, originally miner extractable value. It is the value that can be captured by choosing which transactions go into a block and in what order.

What is the difference between front-running, backrunning and a sandwich attack?

Position. A front-run goes immediately before your transaction, a backrun immediately after it, and a sandwich is both at once, one either side. Front-running takes the opportunity you revealed, backrunning takes the state change you created, and sandwiching takes the slippage you allowed.

Can you be front-run on Solana if there is no mempool?

Yes. Solana’s documentation states there is no mempool and that transactions route straight to the slot leader, but ordering is still decided by who reaches the leader first and what they tip. Jito’s Block Engine offered a mempool and suspended it in March 2024 after sandwich attacks on Solana climbed.

Does a private RPC stop sandwich attacks?

It protects the transactions that use it. It does nothing for callers who arrive by the public path, and it is a property of the sender rather than of your contract, so it cannot be relied on as a protocol-level control.

Does slippage protection stop front-running?

It bounds the loss rather than preventing the attack, and only if the bound is real. A minimum output of zero, or one derived on-chain from the pool you are about to trade against, protects nobody.

Can a smart contract audit find MEV problems?

It can find ordering dependence, which is the part that lives in your code: missing or self-referential slippage bounds, deadlines that cannot bind, spot prices used as oracles, weak randomness, and functions whose outcome is decided by whoever calls them first. It cannot stop MEV existing on a public chain.

Share:

More Posts

Scan your project now for free

Tell us your security needs