max_slippage and max_impact_bps are both in basis points, both make a trade
safer, and both appear on the same swap step. Setting one does not do the other’s
job.
Slippage protects you from price moves other people cause. Price impact limits
the move your own trade causes.
Figures below were measured on a frozen copy of Base, minutes apart. The pool
moves between measurements, which is why each one names its own moment.
Slippage never changes the trade
The same 50,000 USDC into WETH, quoted twice, at 10 and at 50 basis points of slippage:
With five times the slippage, the input, output and impact are identical. Only
the floor moved.
Slippage is a statement about what you will still accept, not an instruction
about what to trade. It becomes the minimum output, the network enforces it, and
if the market moves past it before your transaction goes through, the swap fails.
A very wide slippage is refused. Before the agent signs, a check compares your
floor with an independent price source. A floor too far below that price is
refused, because a floor that low is what a sandwich needs. See
how transactions are sent.
The floor is worked out from the output after fees, not before. A floor
computed from the gross figure is one the router cannot meet, and it would fail
every swap for a reason that reads like slippage.
Price impact is the cost you cause
Price impact is what your own size does to the pool as it works through the available liquidity. It is already inside the quote. That 50,000 USDC trade moves the price 0.87 basis points, and no slippage setting changes that number.max_impact_bps is the limit on it. The service quotes your amount, and if the
impact exceeds the cap it shrinks the offer until it fits, then answers with the
smaller trade. The trade is not refused. You get less than you asked for, at a
better average price, and the answer says so.
Offering 450,000 USDC both times:
The cap cut the offer to 82% of itself and landed the impact exactly on the
boundary.
It searches for the largest size that fits rather than scaling down. Depth is
concentrated, so scaling by cap over impact overshoots badly. Measured on Base:
3,000,000 USDC capped at 5 basis points came back as 237,675 by that ratio, while
the true maximum was 2,317,948. The ratio gave a tenth of the volume, even
though each step of it looked reasonable.The answer also does not depend on how much you offer. Offer more than fits and
you get the same size back.
Neither one substitutes for the other
Slippage does not stop you causing impact. A trade with 12 basis points of impact and 50 of slippage goes through. The impact is inside the quote, so the floor is worked out from the already-worsened price. You paid the impact, and nothing flagged it. An impact cap does not protect you from time. It is measured at the moment of quoting, on a snapshot. If somebody else moves the market between your quote and your transaction going through, the cap does not react. Only the floor protects you from the new price.Setting both
They combine, and they apply in a fixed order.1
The impact cap acts first, on the amount you offered
The search settles on a smaller amount.
2
Slippage then prices that amount
The floor comes from the quote of the reduced trade, not of the one you asked
for.
The trades are identical. The cap decided the size, and slippage decided only
the floor.
Setting slippage alongside a limit price is refused. With a limit price, the
floor is already your own rate, so a tolerance would be a second and conflicting
guarantee. Slippage alongside an impact cap has no such conflict, which is why it
is allowed.
In a plan
Both are named in basis points on a swap step:max_slippage is required when the step states no price of its own. The
minimum has to come from what the venue would pay, and working it out from the
input amount is meaningless across two tokens with different scales.
State a limit_price instead and it becomes the floor, at which point
max_slippage has nothing left to do.
Under the hood
Read impact in pips, not basis points
The basis-point figure is rounded down. On the trade above it reads 0 while the finer figure reads 0.87. Comparing a cap against the rounded figure is wrong by up to a whole basis point. That is 2% of a 50 cap and 100% of a cap of 1, and a cap of 1 is exactly the request “fill me at near-zero impact”. The service enforces the cap on the finer figure for that reason. Show that figure to anybody who has to act on it.The two settings were also easy to confuse in the code. In the service, the impact setting and the
slippage setting were adjacent parameters of the same type until they were
bundled into a struct, because a caller could swap them and no compiler would
notice.
Where the cost limit fits
The cost limit is a third limit, and it answers a third question. It also bounds the size, like the impact cap, but measures a different thing: where the last unit trades, rather than the average the whole trade pays. A trade stopped at a marginal rate delivers an average about half as far from spot, so a cost limit of 25 is roughly an impact cap of 10.
→ Sizing a trade