Crypto MEV sandwich attack risk arises when another participant places transactions before and after a pending swap, changing the pool state so the swap receives worse execution. A minimum-output or maximum-input constraint can reject an unacceptable result, but a successful transaction can still be sandwiched inside its permitted range. Review the quote, signed limits, submission path and final token amounts together.
The risk comes from the execution sequence
Maximal extractable value, or MEV, concerns value available through transaction inclusion, exclusion and ordering. Sandwiching is one form: a participant trades before a target swap in the same direction, the target executes against the changed state, and the participant then reverses its position. Ethereum's MEV documentation explains this mechanism and distinguishes it from other activities such as arbitrage and liquidations.
The problem does not require a stolen signing key. The target can authorize exactly the transaction that executes, including its price constraints, yet receive less than its earlier quote. The adversarial choice is the surrounding sequence.
Publicly visible pending intent can reveal the assets, amount, route and acceptable output boundary. That information helps another participant assess whether changing the state before execution could be worthwhile. Visibility and ordering arrangements differ across networks and submission services; an Ethereum public-mempool example does not describe every chain.
Price impact also exists without an attacker. Buying against an automated market maker changes its reserves and therefore the price along the trade. The relevant comparison is between the same user's swap with and without the surrounding transactions, starting from the same initial state. Comparing execution only with the initial spot rate would mix ordinary curve impact with the additional ordering effect.
Follow one hypothetical pool through three swaps
Consider a deliberately simplified, fee-free constant-product pool with 1,000 X and 1,000 Y. Its invariant is X reserve × Y reserve = 1,000,000. Tokens have ordinary transfer behavior, arithmetic uses continuous units, and there are no liquidity changes or unrelated trades. Gas, swap fees, builder payments and integer rounding are excluded. This is a constructed teaching model, not a live incident or an executable transaction plan.
For an X input, Y output equals the old Y reserve minus 1,000,000 ÷ new X reserve. This follows from the constant-product relationship described in Uniswap's AMM explanation. The fee-free assumption keeps the product exactly constant; an actual implementation needs its fee and rounding rules.
The user intends to spend 100 X. If that swap executes alone, the pool ends with 1,100 X and 909.090909 Y. The user receives approximately 1,000 − 909.090909 = 90.909091 Y.
Now place two surrounding swaps around the same 100 X instruction:
| Step | Transaction | Pool X afterward | Pool Y afterward | Output to that participant |
|---|---|---|---|---|
| Initial state | None | 1,000.000000 | 1,000.000000 | — |
| Before user | Other participant spends 50 X | 1,050.000000 | 952.380952 | 47.619048 Y |
| User | User spends 100 X | 1,150.000000 | 869.565217 | 82.815735 Y |
| After user | Other participant returns its 47.619048 Y | 1,090.293454 | 917.184265 | 59.706546 X |
The table rounds for display; each step uses unrounded values. The user's output is approximately 8.093356 Y below the standalone 90.909091 Y quote, a deterioration of 8.902692% relative to that quote. The original swap's own curve impact was already included in the standalone estimate.
The surrounding participant finishes with approximately 9.706546 more X than it initially spent. That is a gross model result before all omitted costs, with the assumed sequence supplied by construction. It does not establish net profitability, available opportunities or reliable inclusion. The user's Y shortfall and the participant's X surplus also use different units; they are not interchangeable loss and profit figures.
Concentrated liquidity needs a different state calculation as a swap crosses active ranges. The concentrated-liquidity execution guide develops that path. Do not apply this single-invariant reserve table to an entire concentrated-liquidity route.
A minimum output can permit a worse result
Suppose the user's hypothetical quote is 90.909091 Y and the interface converts a 10% output tolerance into a minimum of approximately 81.818182 Y. The reordered result of 82.815735 Y passes. The limit worked according to its stated comparison, while allowing substantially less output than the quote.
Now use an absolute minimum of 85 Y with the same input and initial quote. The standalone result passes, but the table's reordered user swap fails the minimum-output check. That rejects this particular execution. It does not prove that every smaller deterioration is impossible or that the desired trade will complete.
For a concrete implementation reference, Uniswap v2's Router02 checks the computed final output against amountOutMin for its standard exact-input token swap and rejects an insufficient amount. Its exact-output counterpart checks required input against amountInMax. These are explicit checks in the router source, rather than a promise that the quote stays available.
In the 85 Y rejection case, the user's 100 X swap does not apply its modeled reserve changes, so the table cannot continue through the same final row. Whether a separately submitted surrounding transaction lands is a separate inclusion question.
A useful approval rule is to inspect the actual token floor or spending ceiling before signing. A percentage alone omits its reference quote, direction and rounding. If the interface refreshes the quote and recalculates the floor, the resulting signed instruction may authorize a different outcome. Repeatedly widening tolerance after failures can progressively weaken the original boundary.
Private submission changes who receives the intent
A private transaction path can reduce exposure to public-mempool observers, but its configuration and trust assumptions matter. Flashbots Protect says it hides submitted transactions from the public mempool. Its documentation also states that sending a transaction to a builder involves trusting that builder not to front-run it or disclose it to other searchers. Flashbots Protect's quick start describes both the intended protection and that trust boundary.
Check the actual path used by the wallet or application. A setting selected earlier does not establish how the signed transaction was broadcast. Flashbots' RPC-switching warning says that switching RPCs in MetaMask before confirmation may cause the transaction to be resent to the public mempool. That warning concerns the documented MetaMask-and-Protect interaction.
Also examine recipients and information sharing. Protect's settings distinguish builder selection and the hints shared with searchers; fast mode shares transactions with additional builders. The Flashbots settings guide notes that adding builders expands the parties being trusted. A generic “MEV protection” label leaves these choices unresolved.
Retain the same output boundary when assessing an alternative submission path. Privacy does not repair a stale quote, create pool liquidity or make an unacceptable minimum acceptable. If comparing a quoted execution route, the firm versus indicative RFQ guide helps establish what the displayed quote actually commits to before comparing outcomes.
Expiry, smaller swaps and retries solve different problems
A deadline limits how late a swap may execute. It does not reserve a place before other transactions within that window. Uniswap's swap protection parameters separate deadline checks from minimum-output and maximum-input checks. Use both time and value constraints where the actual integration supports them.
An exchange heartbeat cancellation mechanism has another purpose. The dead man's switch order guide concerns what happens to outstanding orders when a client stops refreshing a timer. That mechanism should not be treated as evidence that a pending on-chain swap has expired or been canceled.
Reducing an individual swap's size can change its pool impact, but splitting an intention also creates more submissions, possible repeated exposure and additional costs. Evaluate the complete intended quantity against a common reference. A collection of small acceptable-looking children does not by itself establish better aggregate execution.
Likewise, a pending or missing transaction response is not proof of nonexecution. Reconcile its identity and status before submitting another economic instruction. Preserve any replacement relationship instead of counting every broadcast as a distinct completed trade.
Validate the constraint and reconcile the result
Before signing, build a compact receipt that can survive a quote refresh:
| Evidence | Validation question |
|---|---|
| Chain, token contracts and decimals | Are these the intended assets and units? |
| Quote block, route and input amount | Which observed state produced the estimate? |
| Final output minimum or input maximum | What exact result has been authorized? |
| Deadline and submission configuration | When can it execute, and who receives the intent? |
| Transaction identity and final receipt | Did it execute, revert, remain pending or get replaced? |
| Actual token amounts, fees and gas | What did the completed intention cost? |
Test the value constraint against an unchanged-state estimate and at least one adverse state, as the 85 Y comparison does above. A passing simulation describes the state simulated; it does not reserve that state for inclusion.
Afterward, compare actual amounts with the preserved quote and signed floor. Use the transaction-cost analysis worksheet to keep gas and other costs visible. A worse output alone cannot prove sandwiching: ordinary market movement, route changes and liquidity changes can also explain deterioration. Establishing an ordering claim requires the relevant surrounding transactions and pool-state sequence.
For the next swap review, write down the absolute minimum output, quote state and broadcast path before signing. Those three records make the permitted deterioration inspectable and make a later execution result possible to evaluate.
