AMM Lab and the mechanics of swap execution
AMM Lab breaks swap execution into three inspectable parts: the curve, the fee, and sandwich extraction. It is a useful model for anyone who builds or audits on-chain swap flows.
Practitioners who build on-chain products need a clear mental model of swap mechanics. A constant-product pool looks simple on paper. In use, small design choices around fees, trade size, and transaction ordering shape what users pay and what adversaries extract.
AMM Lab focuses on one narrow problem. It shows how the bonding curve sets price movement, how the pool fee changes execution, and how a sandwich sequence captures value from a user trade. This matters if you ship a wallet, an aggregator, a token launch flow, or any interface that quotes a swap before it lands on-chain.
The engineering value is in the decomposition. You are not asked to trust a black box. You can inspect the inputs, vary them, and see how each piece changes the output. That is the right way to reason about AMM behavior, because many failures start with hidden assumptions in quoting, slippage handling, or mempool exposure.
Start with the invariant, not the UI
At the core of this class of AMM is the constant-product rule. Two reserves sit in a pool. A trade pushes one reserve up and the other down. The product anchors the new state after each swap. Price is not a fixed field in storage. It emerges from the reserve ratio.
For engineering work, this framing matters more than any chart. If your interface shows a quote without showing how reserve depth changes execution, users read the number as a promise. It is not a promise. It is a point on a curve before other state changes land.
What to inspect:
- Initial reserve sizes
- Input trade amount relative to reserves
- Output amount before and after fees
- Marginal price versus average execution price
- Price impact as trade size grows
A good way to verify the model is to change one variable at a time. Keep reserves fixed. Increase the input amount. You should see non-linear deterioration in execution, because larger trades walk further along the curve. Then hold trade size fixed and change reserves. Deeper pools should reduce price movement for the same order.
This is where many implementations go wrong. They treat slippage as a loose front-end tolerance instead of a function of pool depth. Or they quote from a stale reserve snapshot and fail to account for intervening transactions. In production, those errors show up as failed swaps, poor fills, or user confusion over why a quoted rate moved.
Fees are part of execution, not a postscript
Pool fees often get presented as a simple percentage. In practice, the fee changes the effective input before the invariant applies. That means the fee affects both trader output and the pool state transition.
This distinction matters if you are comparing venues, routing across pools, or estimating expected output. A fee is not only a line item. It changes where the trade lands on the curve.
What to inspect:
- Whether the fee is removed from input before output calculation
- How the post-trade reserves are updated
- How the effective execution price changes as fee changes
- Whether the quoted amount and minimum received reflect the same fee logic
You can verify the claim with a simple experiment. Hold reserves constant. Hold trade size constant. Vary the fee. Output should decline, but not as a flat subtraction from proceeds. The change comes through the state transition itself.
This class of system often fails in the seams between pricing and display. One component computes expected output with the fee applied correctly. Another rounds differently, or displays a pre-fee intuition. A router mixes pools with different fee tiers but compares them on an incomplete basis. Those mistakes do not require an adversary. They are enough to produce misleading estimates.
If you build user-facing swap flows, align three things tightly:
- The math used for the quote
- The math used for slippage protection
- The math used in route selection
Any mismatch among those three creates edge cases users pay for.
Sandwich extraction starts with ordering visibility
The phrase in the description, “what a sandwich bot takes,” points to a practical issue in open transaction ordering. If an attacker sees a pending swap with enough expected price movement, they place one trade before it and one after it. The first trade moves the price against the user. The user executes at a worse rate. The final trade closes the attacker position and captures the spread created by the user order.
This is worth understanding as a state transition problem, not a morality play. The attacker does not need your keys. They need visibility into pending intent and enough room between the user quote and the user protection bounds.
What to inspect:
- The user trade size relative to pool depth
- The slippage tolerance on the user transaction
- The fee paid on all legs of the sequence
- The attacker profit after fees
- The final user execution versus a no-attack baseline
To verify the mechanism, compare two runs. In the first, execute the user trade alone. In the second, insert an attacker buy before it and an attacker sell after it. Track reserve changes step by step. The user should receive less in the second run. The attacker profit is the difference between proceeds on the closing leg and cost on the opening leg, net of fees.
Common mistakes in public discussion come from skipping constraints. Not every visible trade supports profitable extraction. Fees eat into the spread. Small trades do not move price enough. Tight slippage settings reduce available room. Deep liquidity reduces the effect. A useful simulator surfaces those dependencies instead of flattening them into a slogan.
For product teams, the actionable lesson is plain. If your system exposes pending swaps and sets wide execution bounds, you create room for extraction. If your quote path ignores expected ordering risk, you understate total execution cost.
Read the right signal, not one headline number
People often compress swap quality into one metric. That is a mistake. Curve impact, fee drag, and ordering risk each explain different parts of the result.
A better inspection flow separates them:
- Compute the baseline output from reserves alone.
- Apply the fee logic and recompute output.
- Model one or more intervening trades and compare the changed state.
- Measure the user delta versus baseline.
- Attribute the delta to curve movement, fee, and adversarial ordering.
This decomposition helps you debug both code and policy. If user complaints cluster around large orders in shallow pools, liquidity depth is the first signal. If losses appear across all sizes, check fee application and quote consistency. If losses spike during visible pending periods, ordering exposure deserves attention.
Where systems commonly go wrong:
- Treating slippage tolerance as user preference alone, instead of risk budget
- Using spot price instead of executable price in UI or analytics
- Ignoring rounding behavior at token decimal boundaries
- Simulating one swap in isolation when real execution occurs in a sequence
- Reporting gross attacker spread without netting fees
If you test your own implementation, keep a written ledger of each state change. Reserve in, reserve out, fee removed, output delivered. This catches many errors faster than a chart does.
Verification should be reproducible
A tool in this category earns trust when a reader can recreate the outputs with plain arithmetic. The model should be inspectable enough for spot checks.
A practical verification routine looks like this:
- Pick starting reserves.
- Choose an input amount.
- Apply the fee to the input.
- Compute the output from the invariant.
- Update reserves.
- Repeat for each trade in sequence.
- Compare final balances across scenarios.
You do not need a large framework for this. A spreadsheet is enough. A short script is enough. What matters is the discipline of reproducing a scenario independently from the interface.
This also guards against a common engineering blind spot. Teams test single-swap math and assume the system is sound. Production failures often live in composition. Rounding across sequential trades. Mismatch between displayed quote and contract path. Incorrect assumptions about when state is sampled. A reproducible lab makes those issues visible early.
What to watch next
The next step for this class of tool is broader execution context. Single-pool math is the base layer. Real systems add route splitting, multi-hop paths, private order flow, and different fee tiers. Those features change where extraction appears and how it is measured.
If you build or audit swap flows, keep your attention on inspectable mechanics. Reserve depth. Fee application. Ordering assumptions. Reproducible arithmetic. Those signals tell you more than a headline quote.