A sandwich is not a hack. No key is compromised, no contract is exploited and no rule is broken. It is a trade about transaction order: someone buys ahead of you to move the pool price against you, your swap executes at that worse price, and a closing trade behind you unwinds the position. Understanding it as ordering rather than theft is what makes the mitigations legible.

The pattern, mechanically

Three transactions, one block, one pool. The first moves the pool along its curve in the direction your trade will push it. Your transaction arrives at that displaced point and receives less output than the untouched pool would have given. The third reverses the first position into the price your own trade created. The profit is the difference between the two, minus fees and minus whatever the price did on its own.

The reason this works on an automated market maker is that price is a deterministic function of reserves. There is no discretion and no counterparty judgement. Anyone who can compute where the curve sits after their own trade can compute exactly what your trade will then receive, and can size their front leg to consume as much of your acceptable range as they choose without pushing you into a revert.

That last clause is the whole game. A front leg that is too aggressive pushes your output below your enforced minimum, your transaction reverts, and there is nothing to sandwich. So the pattern is self-limiting in a specific and useful way: it is optimised against the floor you set, not against the price you hoped for. If you have not read why quotes and fills diverge in the first place, that piece explains the enforcement rule this section relies on.

A worse fill is not evidence of a sandwich. Ordinary competing flow produces an identical-looking outcome, and it is far more common.

Why the Solana version is not the Ethereum version

Most writing about sandwiching describes an Ethereum-shaped world: a broadly visible pending transaction pool, and a public fee auction that lets anyone outbid anyone for position within a block. In that setting the mechanism is close to a spectator sport. You can watch pending orders, compute the profitable response and pay for placement in the open.

Solana's transaction path works differently. There is no single global pending pool that every participant reads from. Blocks are produced by a known leader according to a schedule, and clients send transactions through RPC providers that forward them toward the current and upcoming leaders. The block producer's scheduler decides what gets processed and in what order. The Solana developer documentation describes this transaction processing and leader schedule model in detail.

Two consequences follow. First, visibility is uneven rather than universal: what you can see depends on which forwarding paths you are connected to, not on a shared public queue. Second, ordering advantage comes from access and placement rather than from a single open auction. Priority fees influence scheduling, but they are not a public English auction that every participant observes and bids into transaction by transaction.

Layered on top, bundle infrastructure lets a set of transactions be submitted together with ordering guarantees, so that either the whole sequence executes in the specified order or none of it does. That is precisely the primitive a three-leg pattern needs, because a front leg that executes without the corresponding back leg is an unhedged position. The practical effect is that the pattern concentrates where such guarantees are available.

The honest summary is that Solana changes the shape of the advantage without removing the incentive. Ordering is worth money wherever price is a function of reserves and someone can influence sequence. The defences that follow are therefore about making yourself a poor target, not about finding a venue where the incentive does not exist.

What makes an order worth targeting

An operator running this pattern faces a real cost structure: capital for the front leg, fees on both legs, and inventory risk between them. They select orders where the expected return clears that bar. Five properties do most of the selecting, and four of them are things you decide.

  • Size relative to pool depth. Not absolute size. A large order in a deep pool moves price very little and offers little to capture. A moderate order in a shallow pool moves it a lot.
  • A wide slippage tolerance. This defines the range of outcomes you have agreed to accept. It is the single most legible signal of how much room there is to work with.
  • Thin liquidity. In a shallow pool a small capital outlay displaces the price meaningfully, so the front leg is cheap to fund and the return on capital is high.
  • Predictable timing. Orders that arrive on a schedule, or in an obvious response to a public event, are easier to prepare for than orders that arrive irregularly.
  • Announced or inferable intent. Publicly stated plans, visible on-chain preparation and repeated identical clip sizes from the same wallet all reduce the guesswork.

Read that list as a scoring function rather than a set of alarms. An order that scores low on every line is usually not worth the effort, which is the actual defence: not invisibility, but insufficient reward. Most of the operational work described later is just moving your own orders down this list.

Your tolerance is the size of the prize

This is the part worth internalising, because it converts a vague fear into a number you set yourself. When you accept a quote, the interface computes a floor from your tolerance and writes it into the instruction. The swap program enforces that floor absolutely: any execution that would deliver less reverts.

minOut = expectedOut × (1 - s)where s is your slippage tolerance expressed as a decimal, so the largest amount you can give up relative to the quoted expected output is expectedOut × s

So the maximum extractable amount from your specific transaction, measured against the quote, is bounded by your own setting. Not by the attacker's capital, not by pool depth, not by how fast they are. Depth and capital determine whether the pattern is worth running at all; your tolerance determines the ceiling on what it can take once it is.

Worked example: bounding the worst case

Illustrative arithmetic only. Suppose a quote projects an expected output of 10,000 units of the token you are buying. The table below applies the formula above at several tolerance settings. The give-up column is the arithmetic ceiling on how much worse than the quote your fill can legally be, whatever the cause.

Illustrative: the enforced floor and the resulting worst case, for a quote of 10,000 output units
ToleranceMinimum outputMaximum give-upReading
0.1%9,99010Almost nothing to win; high revert rate on anything but a deep pool
0.5%9,95050Workable on deep pairs, rarely worth targeting at modest size
1.0%9,900100A common default; the prize now scales directly with your order size
3.0%9,700300Chosen to stop reverts, priced as if reverts were the only cost
5.0%9,500500A wide standing invitation on any pool shallow enough to move
10.0%9,0001,000Only defensible when the alternative is not trading at all

Two cautions about reading that table too confidently. It bounds your loss against the quote, not against fair value, so a stale or badly constructed quote can be wrong before the bound applies. And the ceiling is not the operator's profit: they pay fees on two legs and absorb the price impact of unwinding, so what leaves you is always larger than what reaches them. The trade-off behind choosing a number lives in our guide to setting slippage tolerance.

Mitigations, graded honestly

Every item below reduces exposure. None removes it, and each one has a cost that is usually left out of the recommendation. The fourth column is the one to read first, because a mitigation applied to the wrong problem simply adds cost without changing the outcome.

Illustrative: what each common mitigation reduces, what it costs, and what it leaves untouched
MitigationWhat it reducesWhat it costs youWhat it does not fix
Tighter slippage toleranceThe arithmetic ceiling on what any reordering can takeMore reverts, each consuming the base fee plus any priority feePrice impact from your own size, and ordinary competing flow
Smaller clip sizesBoth the price displacement you cause and the reward you offerMore transactions, more total fees, more elapsed time and hands-on effortExposure on the clips themselves; a series of small orders is still a pattern
Splitting the order over timePredictability of any single fill and the depth consumed at onceTiming risk while the remainder is unexecuted; the market may simply moveRegular intervals are themselves predictable and can be anticipated
Routing to deeper venuesDisplacement per unit of size, which shrinks the opportunity directlyPossibly longer routes, more compute, and a higher failure rate per attemptNothing about your tolerance setting or the timing of your order
Private or direct submission pathsHow early and how widely your pending transaction is visibleA trust and availability dependency on the operator of that pathPool depth, order size, and any inference drawn from your on-chain history
Avoiding the thinnest poolsThe return on capital available to a front leg, often decisivelyYou cannot trade some assets at all, or must accept a worse venueAnything that happens on the deeper pools you moved to
Not broadcasting intentAdvance preparation against a known and dated flowLittle directly, though it constrains how you communicateReal-time detection once the transaction is already in flight
Limit orders instead of market swapsAcceptance of any price inside a wide band; you name the price insteadNo guaranteed execution, and the order may rest unfilled indefinitelyThe fact that resting orders are themselves visible information

Notice that the first two rows point in opposite directions on cost. Tightening tolerance raises your revert bill; shrinking clips raises your fee and effort bill. Doing both aggressively can cost more than the exposure it removes, which is why this belongs in a cost model rather than in a rulebook. The wider accounting sits in the execution cost and quality section.

Two of those rows, smaller clips and splitting over time, also multiply the number of transactions you have to place, and the cost column understates how quickly that becomes unmanageable by hand. Traders who hold clips small at volume generally do it through a SOL volume bot rather than manually, which changes the effort cost of the mitigation without changing what it does, or does not, fix in the fourth column.

Can you tell after the fact?

Sometimes, and less often than people assume. The honest position is that a single bad fill is not diagnostic. Your transaction records what you received; it does not record why. To form a view you have to look at the block your transaction landed in and at the trades around it on the same pool, and even then you are inferring intent from sequence.

What raises confidence is structure rather than magnitude: a trade in the same pool immediately before yours and an opposing trade immediately after, both from related accounts, sized so that your output landed just above your enforced minimum. That last detail is the strongest signal, because ordinary flow has no reason to stop precisely at your floor.

What lowers confidence is everything else. A fill several percent below the quote during a volatile period, on a pair with many active participants, is fully explained by competing flow. Treating that as an attack leads to the wrong fix, usually a tolerance change that makes the next hundred trades worse. Diagnose the mechanism before you change a setting.

The residual risk nobody removes

State it plainly: none of the mitigations above make sandwiching impossible. They make it unprofitable at your size, in your pools, at your tolerance, most of the time. Those qualifiers are load-bearing. Change any of them and the calculation changes with them.

The reason is structural. Public pools price from reserves, sequence determines which reserves you read, and sequence is influenced by parties whose interests are not yours. As long as those three things hold, ordering has value and someone will price it. A trader who understands that will build habits that keep the value low rather than searching for a setting that makes it zero.

There is also a quieter cost that never appears in a post-trade review: the trades you did not make, the sizes you cut, and the pairs you avoided. Those are real costs of the same risk. Managing this well means keeping both the extraction and the avoidance small, which is a balance rather than a target.

An operating checklist

Use this before size trades on pairs you do not trade daily. It is deliberately short, and each item corresponds to a row in the mitigation table rather than to a feeling about risk.

  • Check pool depth before you decide size, and express your clip as a share of reserves rather than as a round number.
  • Set tolerance from the depth you just measured, and treat every extra point of tolerance as money you have offered.
  • Split anything that would move the pool noticeably, and vary the timing rather than trading on a metronome.
  • Prefer the deeper venue when the quoted difference is small, since depth cuts both impact and opportunity.
  • Keep your intent out of public channels ahead of execution, including predictable identical clips from one wallet.
  • Review a sample of fills against the block they landed in, so your conclusions come from sequence rather than from disappointment.

Done consistently, this moves you from an order that is worth someone's capital to one that is not, which is the only defence available at the level a trader operates. The mechanism does not care who you are; it responds to depth, size and the range you agreed to accept. Two of those three are yours to set on every single trade.

Frequently asked questions

What is a sandwich attack on Solana?

It is an ordering strategy in which a trade is placed immediately before yours to push the pool price against you, your swap executes at that worse price, and a closing trade immediately after yours unwinds the position. Nothing is stolen and no key is compromised; the entire result comes from transaction order.

Can a sandwich take more than my slippage tolerance?

Not relative to the quoted expected output. Your minimum output is enforced by the swap program, so any outcome below it reverts. The worst case is therefore bounded at expected output multiplied by your tolerance. That bound says nothing about how wrong the expected output itself was.

Does Solana have a public mempool like Ethereum?

Not in the same form. There is no single global queue of pending transactions that everyone reads. Transactions are forwarded toward the validator scheduled to produce the next blocks, so visibility and ordering advantage come from access and placement rather than from a public gas auction that anyone can observe and outbid.

Does a low slippage setting prevent sandwiching?

It shrinks the prize, which makes small orders unattractive, but it does not prevent anything. A tight setting also raises your revert rate, and each revert still costs the base signature fee plus any priority fee. The correct setting balances those two costs rather than minimising one.

Are private submission paths a complete solution?

No. They reduce how early and how widely your transaction is visible, which removes one class of opportunity. They do not change pool depth, they do not make your order smaller, and they introduce a trust and availability dependency on whoever operates the path you are using.

Should small traders worry about this?

Mostly no, in the direct sense. A tiny order in a deep pool offers too little to be worth the capital and fees required. The same trader is still exposed indirectly through habit: wide default tolerances and thin pools become expensive as soon as size increases.

Filed under Cost model by The SolSpread Desk. Worked examples on this page are illustrative arithmetic, not observed market data. Read how we handle numbers in the editorial policy.