AMM swap bounds: What to Know Before You Integrate
Before integrating an AMM swap, set a minimum acceptable output and a short transaction deadline from a fresh quote. Those bounds control what happens if pool state changes between quoting and execution; they do not guarantee the quoted price or protect a contract from every form of price manipulation.
What does the minimum output actually constrain?
amountOutMin is a hard lower bound on the output received by the swap recipient. In a v2-style router, the contract calculates output from the reserves it sees during execution and reverts if the final amount is below this bound. The Uniswap v2-periphery router and library are useful primary references for this pattern, though another DEX may use different interfaces or pool math.
That distinction matters when integrating across venues: Blackhole Swap gives the Avalanche context, while your integration still needs to derive bounds from the specific route and execution interface it calls. Do not assume a quote endpoint’s output is itself a safe minimum, or that every router uses the same parameter names.
For a v2 constant-product pool, one hop’s fee-adjusted output is commonly calculated as amountIn × 997 × reserveOut / (reserveIn × 1000 + amountIn × 997), reflecting a 0.30% fee. The 997/1000 factor is specific to that fee model; use the pool’s actual fee and formula. A multi-hop route applies the calculation at each hop, using each pool’s reserves and token order.
How should you calculate the bound?
Start with the route’s expected output, then apply your chosen tolerance: minOut = floor(quotedOut × (1 − tolerance)). For example, if a quote is 2.5 AVAX and your tolerance is 1%, set the minimum to 2.475 AVAX, or 2,475,000,000,000,000,000 wei if AVAX is represented with 18 decimals. Use integer arithmetic in the token’s base units; never round the minimum upward.
Slippage tolerance is the permitted shortfall from the quote, not the pool’s price impact. Price impact is already reflected in the route quote; tolerance covers additional movement before execution. A fixed percentage is simple but has a poor trade-off: a tight bound can cause ordinary failures in volatile or thin pools, while a loose bound accepts worse execution and can expose users to sandwiching.
For a user-facing transaction, choose tolerance per route and trade size, then show the implied minimum clearly. For a protocol swap, I would prefer an oracle or strategy-defined price limit where feasible, because a percentage against a stale quote does not establish fair value. If the route includes transfer-tax tokens, check whether the router supports them: the amount received by a pool can differ from the nominal input, making ordinary quote calculations or router methods revert or misstate output.
When should the transaction expire?
The deadline is a Unix timestamp checked by the router; it rejects execution after that time. It limits how long a signed transaction can remain valid, but it does not stop execution at an unfavorable price before expiry. Uniswap’s developer documentation describes the deadline and minimum-output check as separate protections, and they should be treated that way in your integration.
For a wallet-submitted transaction, a short window such as a few minutes is a reasonable starting point, adjusted for the chain’s congestion and the application’s confirmation flow. A very long deadline leaves an old quote executable; an extremely short one turns ordinary inclusion delays into reverts. Contract-to-contract swaps often use different controls: if execution occurs atomically in one transaction, enforce a price bound at that call rather than relying on a long-lived deadline.
What should you validate before submitting?
Re-fetch or validate the quote close to submission, confirm the chain and token addresses, and pass the intended recipient and route unchanged. Ensure the allowance covers the input amount, account for the router’s exact token-handling behavior, and simulate the call against current state when possible. Simulation can catch stale reserves and reverts, but it cannot guarantee the state will remain unchanged until inclusion.
On failure, distinguish an expired deadline from an output-bound revert and from allowance, liquidity, or token-transfer failures. Refresh the quote and recalculate the minimum rather than blindly increasing tolerance; inspect each hop’s liquidity if the same route repeatedly fails. Your next step is to implement the bound in base units, test the exact router method against both a normal token and any fee-on-transfer token your product supports, and expose the resulting minimum to the caller.
Questions integrators ask next
Does a tighter slippage tolerance reduce price impact?
No. Price impact comes from trading against finite pool reserves and is included in the route’s expected output. A tighter tolerance only lowers the maximum shortfall you accept between that quote and execution. It may cause more transactions to revert when reserves move, but it does not improve the pool’s quoted rate or make a shallow route deeper.
Should I set the deadline when I quote or submit?
Set it when constructing the transaction for submission, using the current time plus the application’s chosen validity window. A deadline calculated when the user first opens a swap screen may already be stale by confirmation time. For contract integrations, prefer the shortest window compatible with the transaction flow and enforce an independent price bound where the strategy needs one.
Why can a swap revert even when the quote looked valid?
The quote describes a particular pool state; another swap can change reserves before your transaction executes. The resulting output may fall below amountOutMin, or the deadline may pass. Other causes include insufficient allowance, a changed route, low liquidity, or tokens that deduct fees during transfer. Refresh state and identify the revert cause before retrying.