Slippage & Price Impact

The price a taker receives differs from the oracle mark by four separate quantities, and only one of them is what most traders mean by price impact. This page factors that difference term by term, separates the terms a quote already knows from the stochastic remainder, and gives the bounds a caller can set against that remainder.


1. The decomposition

Every AIMM quote is a product of four factors applied to the oracle mark, for a single leg with q the trade size:

execmark=Pskewinventorylevel·Γ(q)curvetraversal·(1-t(q))coveragetoll·(1-s2)halfpathspread

TermDefinitionDepends on sizeOwned by
Pskew=r/m, mid over markInventory skew offset, evaluated at zero volumeNoInventory Management §3, Liquidity Shaping §5
Γ(q)=p¯/midCurve traversal, the VWAP over the interval the trade sweepsYesLiquidity Shaping §8
t(q)=covToll/grossConvex coverage toll on the drained output legYesInventory Management §6
s = SwapQuote.spreadPbpsPath spread; the realized fee is s/2 of the pre-fee outputNoSpread & Fees

Price impact in the AIMM sense is Γ(q) alone, together with t(q) when the output leg is under-covered. Everything else is a level or a fee and is present at zero size.

The pool publishes both the mark and the mid (SwapQuote.markPrice, midPrice, both exact WAD (1e18), tokenOut per tokenIn, chained across every leg). Deliberate: it lets an indexer split (exec-mid), the genuinely extractable value, from (mid-mark), the inventory skew, instead of conflating them into one execution-versus-oracle number. See IPool.sol.

1.1. What each term is, and what it is not

Canonical vocabulary. Each word names exactly one object; none is a synonym for another.

TermIsKindSymmetric in direction?Site
markthe oracle price, as attested by the keeper in the child’s anchor unitlevelyesFeedMathLib.mark, consumed at Pricing.sol
skewthe signed dimensionless inventory index, int8 in [-100,+100], a function of coverage alone. An input, never a priceindexn/acomputeInventorySkew, Pricing.sol
skew offsetthe price displacement that index produces, (mid-mark)/mark in bpslevelyes: one number, both directions quote off it, and it cancels on a round trip_legMid, Pricing.sol; surfaced at IPool.sol and by @btr-protocol/sdk
midthe mark carrying that offset, evaluated at zero volumelevelyes_legMid, Pricing.sol
price impact (= curve traversal)the cost of traversing the liquidity shape from the skew anchor, Γ(q)one-directional costno, see §1.2_traverseCurve, Pricing.sol
spreadthe round-trip fee width, SwapQuote.spreadPbps, symmetric about the midwidthyes, by construction (Spread & Fees §4)_pathSpread, Pricing.sol
feewhat a swap actually pays: half the spread, once, on the outputchargeyesPricing.sol
coverage tollthe convex charge on a drained output legone-directional, charge-onlyno_covToll, Pricing.sol
slippagethe stochastic gap between the quote and the fill (§3), not a pool term at allriskn/aminAmountOut, §4.1

Four usages to reject on sight:

  • “spread” for total cost. The spread is one of four terms and is usually not the largest. Total cost is the whole product above.
  • “fee” for the spread. minFeePbps is a floor on the spread, not on the fee; the fee is half the spread. Nothing caps the spread from above (Spread & Fees §3.1).
  • “premium”, for anything. The word carries three objects at once: the mid displacement, a generic price-versus-mark ratio, and a component of the spread - the level-versus-width collision this table exists to stop. The mid displacement is the skew offset (a level); the spread’s parts are bands and surcharges (widths). “Premium” and “discount” are admissible only as informal words for the sign of a skew offset, never as a quantity and never as a parameter.
  • “skew” for a price. skew is the dimensionless index; the price effect is the skew offset. One map, two objects, two names.

Naming, settled: the Avellaneda-Stoikov reservation price is this codebase’s mid, and “mid” is the only name used for it. AIMM carries no absolute price band on an asset; the depeg gate is the feed-relative refFeedId / refBandBps pair plus the base parity halt (Anchor Path Pricing §7.1).

1.2. Total cost is direction-asymmetric; the width and the level are not

The spread is direction-invariant: both sides quote the same width about the same mid (Spread & Fees §4). The skew offset is a level: the same number for both directions, and it cancels on a round trip. Price impact is neither, so total cost is not.

Measured on an exact integer port of Pricing.sol + NUQuartic.sol, bit-verified against forge on shipped preset 5. WETH: dispRefPbps 500, σ=0 so dispersion is the minDispersionPbps of 2034 PBPS — still WETH’s live floor — spread 1032 PBPS (half-spread 5.16 bps), mark 1. The leg’s minFeePbps has since been raised, so the absolute spread column reads low against the chain today; the impact and skew columns, which is what the table is for, do not depend on it. Notional is a fixed percentage of liabilities, held constant across coverage states, so the rows are comparable. slip is |p_-mid| in bps. The skew column is the shipped fixed law, +200(1-c) draining and -100(c-1) filling, saturating at c0.5 and c2; 50% and 200% are where the law clamps, not a configurable band, and no per-asset dial enters these rows.

Measurement note: the c=1.15 row reads -14 / x0=4300 from the fixture. The shipped law gives exactly -15 and x0=4250 at c=1.15. One skew unit of fixture drift, worth 50 bps of the spline domain; the slippage figures either side of it are unaffected at this resolution.

cskewx0skew offsetnotionalslip sellslip buygap (buy - sell)
0.70+608000+10.880 bps1%0.2900.280-0.010
0.7010%2.7703.050+0.280
0.7025%6.6004.420-2.180 (buy clipped)
0.85+306500+5.200 bps1%0.2100.2100.000
0.8510%2.0702.160+0.090
0.8525%5.1005.710+0.610
1.00050000.0001%0.1700.1700.000
1.0010%1.7101.7100.000
1.0025%4.3604.3600.000
1.15-144300-2.390 bps25%3.8903.720-0.170
1.30-303500-5.200 bps25%3.6103.350-0.260
  • At c=1 the gap is exactly zero at every size. The shipped wQ vectors are perfectly antisymmetric about x=5000, so their density median is x*=5000, the traverse starts there at ψ=0, and a symmetric inventory state gives symmetric slippage by construction. The asymmetry is a property of being off par, not of the machine. On an asymmetric preset x* moves and the zero-gap point moves with it, since the anchor is the median and not the domain midpoint (Liquidity Shaping §5.1).
  • Off-center and unclipped, it is real and correctly signed. At c=0.85 and 25% of liabilities, the direction that worsens inventory pays 5.710 bps against 5.100 bps for the direction that heals it. The 0.610 bps gap is about 12% of the 5.16 bps half-spread.
  • Above parity the sign flips, as it must: at c=1.15 and 1.30 the buy side is now the healing direction and pays less.
  • The -2.180 row is not a discount, it is the buy-side traverse hitting the domain clip at x=BPS. Past that point marginal impact is zero. See §2.5.
  • The level dominates. At c=0.70 and 1% of liabilities the skew offset is 10.880 bps against 0.29 bps of traverse, so the mid, not the curve, is what moves the executed price off the mark.
  • A round trip costs the same whichever way you start: 10.663, 10.700 and 10.669 bps across the inventory states above. That is the proof that the skew offset is a level that cancels, and that what remains is the spread plus two traverse terms.
The mechanism, stated correctly. The intuitive version (“the depleted side traverses further”) is wrong for a single leg, because depth is per-asset, not per-side: `profileAsset = isUpward ? fromto (Pricing.sol`), so both directions of one edge use the same child, the same curve and the same depth. Single-leg asymmetry comes from three things instead:
  1. the off-center start x0=clamp(x*+50ψ,0,BPS), where x* is the curve’s density median from the header and equals 5000 on every shipped preset (_skewToDepth, Pricing.sol);
  2. the convexity of the shape either side of that start, since a sell integrates [x0-v,x0] and a buy integrates [x0,x0+v] over a curve that is not locally linear;
  3. domain clipping at x=0 and x=BPS (Pricing.sol).

The “depleted side traverses further” intuition does hold one level up, on a two-leg spoke-to-spoke path, where the two directions traverse different assets’ curves at different depths.

So a round trip is not two halves of one number: it pays the full spread S once (Spread & Fees §5.5) plus two traverse terms that differ off par, plus the toll on whichever direction drains a walled leg.

1.3. Worked, verified on chain

A shipped stable pool (addresses: 2. Deployments), USDT to USDC, one leg. Read from Pool.getSwapQuote at capture time. spreadPbps = 177, covToll = 0 on all three, because the USDC output leg read κcov=0 at that block. That is not the shipped state: every Arc leg carries κcov>0 (600 stables / 1,500 FX / 1,800 metals / 2,000 crypto / 2,500 equities, hub at the maximum of its own spokes), so the toll column of a quote taken today is non-zero the moment the output leg sits below parity — Parametrization §6.2.

Historical capture, before the 2026-08-21 adaptive-dispersion change. Pskew of -54.00 pbps is the old κ=161 / x0=3050 state. At HEAD the same live inputs give κ=237, x0=4050 and a mid offset near -38 pbps (Liquidity Shaping §8.6). The rows are kept because they are the measured verification of the decomposition, not today’s quote.

amountIn (USDT)Pskew-1Γ-1t-s/2Total exec/mark -1
1-54.00 pbps0.0 pbps0-88.5 pbps-142.50 pbps
1,000-54.00 pbps-2.0 pbps0-88.5 pbps-144.50 pbps
10,000-54.00 pbps-25.0 pbps0-88.5 pbps-167.49 pbps

Read off: the fee is 62% of the total cost at 1 USDT and 53% at 10,000 USDT. The skew offset is 38% and 32%. The curve, the term most people mean by “price impact”, is 0% to 15%: on a tight stable leg it is the smallest of the four terms.


2. Price impact: deterministic

Impact is knowable before execution: a pure function of on-chain state the quote already reads.

2.1. AIMM

Γ(q)=PBPS+y¯PBPS+y(x0),y¯=1x1-x0x0x1yscaled(x)dx

with x0=clamp(x*+50ψ,0,BPS) (x*=5000 on every shipped preset), x1=x0vf, and vf=min(BPS,q·BPS/D), all as defined in Liquidity Shaping §8.

D is the leg’s raw reserves. uint256 depth = reserves == 0 ? 1 : uint256(reserves) in Pricing.quoteSwap and _priceEdgeHop: the zero-guard exists only because the traverse divides by it. There is no coverage-dependent adjustment on top, and no “effective” or “virtual” depth anywhere in the decomposition. Impact therefore scales with 1/R and nothing else: at a given size, a thinner leg is a deeper traverse, with no state-dependent discount in either direction. A denominator that grew as coverage fell would shorten the traverse on exactly the leg an informed flow is draining, which is how a two-block round trip becomes trader-positive: an LP leak, not a depth benefit.

Three structural consequences:

  • Impact is bounded. The whole book spans ±Hκ/dispRef, with H the preset’s half-swing at its reference dispersion. No trade of any size can move the price beyond that edge, because x clamps at the domain edge and vf clamps at BPS.
  • Impact is zero below the quantum. vf is an integer count of bps, so any trade smaller than D/BPS executes exactly at the mid. Live USDT: 6.0036 USDT.
  • Impact is asymmetric. x0x* on every live leg, so the sell side and the buy side of the same leg have different remaining room. See Liquidity Shaping §5.2.

2.2. Against a constant-product pool

For x·y=k, executing q against reserve R gives exec/spot=1/(1+q/R), so impact is q/(R+q) and grows without bound. AIMM’s impact is a traversal of a bounded offset curve. Measured on the USDT leg at preset 2, selling. These rows are a pre-adaptive-dispersion capture (κ=161 pbps, x0=3050): the band sat at the bare floor and the skew read the old symmetric slope. Under the current law the same live inputs give κ=237 and x0=4050 (§2.6, and Liquidity Shaping §8.6). The ratio the table is making, bounded traversal against unbounded curvature, is unchanged by that:

Size as % of depthvf (bps)AIMM Γ-1Constant-product impact
0.1%10-0.15 pbps-10.0 bp
0.5%50-0.73 pbps-49.8 bp
1%100-1.46 pbps-99.0 bp
5%500-7.39 pbps-476.2 bp
10%1000-14.99 pbps-909.1 bp
20%2000-30.98 pbps-1666.7 bp

At 10% of depth AIMM charges 0.15 bp of curve impact where a constant-product pool charges 909 bp, a factor of about 6,000. That is not a free lunch: USDT’s half-swing at this capture is 1.61 bp, so the whole book spans 3.22 bp end to end and it cannot charge more. The defense against adverse selection sits in the spread, the coverage toll and the oracle push policy rather than in curvature. A constant-product pool prices size; AIMM prices information, and lets size run cheap until the reserve itself binds.

2.3. When the reserve binds

Beyond the curve, two hard limits apply and neither is a smooth impact term:

  • Pricing._legScaleOut (Pricing.sol) clamps a leg’s output to the destination asset’s reserves and sets a clamped flag. When it fires, SwapQuote.amountOut reports the clamped number and the per-hop execution price is suppressed. This is visible live: a 100,000 USDT quote returns hopAmounts equal exactly to the USDC reserve balance (66,369.84), so the quoted rate silently degrades to a partial fill at full price rather than reverting. Read hopAmounts against reserves before trusting a large quote.
  • PoolIOLib.settle (PoolIOLib.sol) reverts InsufficientAmount when Rliq=R-invested cannot cover amountOut + protoFee + minLiquidity. This is the failure that governs at settlement.

2.4. The coverage toll

When the output leg is coverage-walled (κcov>0; on the reference roster that is every spoke) a drain below parity pays

t·gross=min(gross,(Q(c0)-Q(c1))κcovLBPS·WAD),Q(c)=lnc-c+1

evaluated at c clamped to 1. It is convex and it diverges as c10, so the marginal cost of the last of a reserve is unbounded even though the curve impact is bounded. This, not the spline, is what stops a drain. Full statement: Inventory Management §6.

2.5. The buy-side traverse saturates, and depth cannot stop a drain

A consequence of the bounded book, not a defect, and not to be fixed inside the traverse.

Pricing._traverseCurve clamps the volume fraction at BPS and the buy-side end depth at BPS. Once x1 reaches BPS the averaged offset over [x0,BPS] stops changing with size, so marginal price impact past that clip is exactly zero, and the saturated value falls as the pool depletes, because a higher x0 leaves a shorter interval to average over. The clip is on the spline domain, not on liquidity, so the clip percentages below are percentages of raw reserves (§2.1), the only depth quantity there is.

CoverageClips at (% of reserves)Saturated slippage
c=1.0050%9.29 bps
c=0.8535%6.96 bps
c=0.7020%4.42 bps

Draining the entire WETH reserve costs about 14.45 bps at c=1.0 and 20.46 bps at c=0.7 in traverse plus half-spread, and those two terms alone can never exceed +20.46 bps at any size. That is a bound on the bounded terms, not on the price. The coverage toll sits on top of it and is unbounded: Pricing._covToll charges ΔQ·κcov·L/(BPS·WAD) on the drained output leg once c1<1, and Q(c)=lnc-c+1- as c0, so at the shipped κcov=300 the marginal cost of the last of the reserve diverges (§2.4). A drain that stays above parity pays the 20.46 bps ceiling; one that crosses the peg does not. Same numbers as the -2.180 row in §1.2, which is that clip and not a discount.

The ceiling is correct for an oracle AMM. A pool that quotes the external mark must not price-discover; if size could move its quote without bound, the quote would stop being the mark. The consequence:

Depth cannot stop a drain. The curve is a bounded offset book, so no amount of size exhausts it. The only two mechanisms that stop one are the convex coverage toll (§2.4) and the hard reserve floor minLiquidity (§2.3), which initAsset writes as 0 and no deploy script raises (PoolConfig.sol).

A leg left with the wall off is a config defect, not a design choice:

  • any leg carrying kappaCovBps = 0 has only minLiquidity and the reserve clip as its whole outflow defense. Operator rule: every listed asset including the hub must have κ>0 (Invariants §I-9).
  • Where the wall is on it dominates everything else by orders of magnitude: USDT at c=0.80 charged 43.84 bps of toll against a 0.61 bps spread on a pre-Arc reference-roster capture at κcov=100. The toll is linear in κcov, so at the live stable value of 600 the same drain costs 263 bps, and 1,053 bps on an equity leg at 2,500.

The saturation offers no atomic profit: what bounds a drain is the coverage toll of §2.4 and the reserve clamp of §2.3, plus minLiquidity wherever a deploy config raises it above the initAsset zero.

2.6. Dispersion

Dispersion κ sets the vertical scale of the curve and therefore the magnitude of Γ:

κ=min(MAX_DISPERSION_PBPS,κmin+σνBPS)

Pricing._calculateDispersion (Pricing.sol; adaptive dispersion since the 2026-08-21 adaptive-dispersion change). κmin = minDispersionPbps is the additive base, not a post-hoc clamp; only the protocol-wide MAX_DISPERSION_PBPS = 900000 ceiling clamps - there is no per-asset ceiling field.

At ν=10000 — the live value on stable legs and on every hub — this reduces to κ=κmin+σ pbps: impact IS volatility-adaptive, one-for-one with the feed’s σ above the floor (live stable σ=76 PBPS widens USDT from 161 to 237 pbps). The volatile classes run ν below 1.0x (0.30x FX, 0.40x crypto, 0.45x metals, 0.35x equities), so there the slope is that fraction of σ, deliberately: it is what keeps their book inside the interior swing cap (Parametrization §4.2). Full argument with numbers: Liquidity Shaping §6.4.


3. Slippage: stochastic

Slippage is the difference between the quote a taker saw and the price they got: the part that is not a function of the state the quote read.

3.1. Sources

SourceMechanismDirectionAIMM-specific note
Mark updateA keeper push lands between quote and inclusionEitherThe pool quotes off the keeper mark (FeedMathLib.mark), so a push moves the whole quote, not just the tail
Inventory driftAnother swap changes R, hence ψ and x0EitherDiscrete: x0 moves in steps of 50 bps of the domain
Coverage driftAnother swap changes c on the output legNegative if worsenedChanges t(q) convexly
Staleness rampFeed ages past the keeper grace, widening sNegativeDeterministic given the age; see §3.2
Front-runningSearcher trades aheadNegativeBounded by the book: they cannot push you past ±Hκ/dispRef
SandwichBot trades both sidesNegativeRound trips lose (Liquidity Shaping §8.3), so the sandwicher pays too
Reserve clampOutput reserve drained by an earlier txNegative§2.3
HaltFeed goes stale, confident, or depeggedRevertFails closed, never degrades silently

3.2. The staleness ramp is not random

The spread carries a keeper-lag term (Pricing._staleTerm, Pricing.sol):

Ustale=zστBPS,z=100,τ=max(0,a-min(T/2,30))

with a the feed’s age in seconds, T its ttl, and z = STALE_Z (Pricing.sol). τ is 0 inside the grace and the surcharge grows as τ beyond it. The observed live USDT spread of 177 pbps decomposes as 61 (path floor) + 0 (volatility term, σ truncates to zero at ν=10000) + 100 (1 bp of feed confidence) + 16 (staleness, about 470 s of age against a 30 s grace). USDT anchors to the base, so this is a one-leg path and the floor is USDT’s own 61 alone; a two-leg cross sums both spokes’ floors (Spread & Fees §9). A taker who quotes and then waits sees the spread widen, predictably.

Past the hard TTL the feed does not widen further: FeedMathLib.gate reverts, and the leg does not quote at all.

3.3. Positive slippage

Slippage can be favorable if the market moves your way between quote and inclusion. On a public mempool it rarely reaches the trader: searchers monitor pending transactions, favorable movements are captured by backrunners, and the unfavorable ones pass through. That asymmetry is the whole argument for private order flow.


4. Protections

4.1. minAmountOut

function swap( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, // slippage bound address recipient, uint256 deadline // staleness bound; type(uint256).max opts out ) external payable returns (uint256 out);

Pool.sol. The single state-mutating swap entry is Pricing.swap, and the check is the last thing it does before pushing the output:

if (out < minAmountOut) revert Err.ThresholdViolation(out, minAmountOut);

Two ordering facts:

  • The threshold check runs after PoolIOLib.settle. That is state-identical in an all-or-nothing transaction, but it means a violated threshold burns the full settlement gas.
  • A zero-delivery swap reverts first (Pricing.swap, Err.ZeroValue), before the threshold. A fully-tolled coverage-wall drain therefore reverts as ZeroValue, not as ThresholdViolation.

Sizing the bound, given §1.1: for a stable leg the fee and skew are already about 145 pbps (1.45 bp) at zero size and are visible in the quote, so a bound set from the quote rather than from the mark can be tight.

Tolerance below quoteUse
0.05% to 0.1%Stable legs, fresh feed, private order flow
0.1% to 0.5%Stable legs, public mempool
0.5% to 1%Volatile legs, normal conditions
1% to 3%Volatile legs, stressed tape; expect the spread term to move, not the curve

4.2. deadline

Pool.beforeDeadline (Pool.sol) reverts Err.Expired when block.timestamp > deadline. The deadline is inclusive (equality succeeds), there is no zero sentinel, and the opt-out is type(uint256).max. Every value-moving entry point carries it: swap, withdraw, withdrawTo, swapLiability. deposit and donate do not, because they mint at the current index against no minimum output.

4.3. MEV-protected RPCs

Hide the transaction from the public mempool. The endpoints below are examples of widely used public providers, not a complete or endorsed list; verify any endpoint before routing value through it.

Ethereum L1

ProviderEndpointNotes
MEV Blockerhttps://rpc.mevblocker.ioCoW Protocol
Flashbots Protecthttps://rpc.flashbots.net/fastFast mode trades some protection for inclusion
Merklehttps://eth.merkle.ioFree tier
Llama Nodeshttps://eth.llamarpc.comFree tier
BlockRazorhttps://eth.blockrazor.xyzProtection on by default

BNB Chain: https://rpc.48.club, https://bsc.merkle.io, https://binance.llamarpc.com, https://bsc.blockrazor.xyz. Base: https://base.llamarpc.com.

Multi-chain private networks

ProviderCoverageMEV protection
AlchemyEthereum, Polygon, Arbitrum, Optimism, BaseAlways on
BlockPIMulti-chainEnable in dashboard
dRPCMulti-chainEnable in dashboard
HeliusSolanaOptional Jito integration

4.4. Timing and sizing

StrategyEffectTrade-off
Trade shortly after a keeper pushMinimizes Ustale and mark driftRequires watching the feed
Keep size below D/BPSExactly zero curve impactOnly useful for small orders
Split across blocksLets ψ and c recover between clipsHigher gas; each clip pays s/2 again
Trade the coverage-restoring directionFavorable side of Pskew, near-zero tDirection is dictated by pool state, not preference
Avoid draining a walled leg below parityAvoids the convex toll entirelyCheck c on the output asset first

Splitting is not a free win: the spread s is charged per swap and is size-independent, while the curve impact is the small term. On a stable leg, splitting a trade into n clips multiplies the dominant cost by n and only saves the minor one.


5. Chain-specific ordering

5.1. Ethereum L1

Public mempool: every pending transaction is visible. Ordering is a gas auction. Protection is a private RPC to a trusted builder.

5.2. Arbitrum and OP Stack

Transactions go to a centralized sequencer with full visibility, expected to order fairly. Original ordering was FCFS; Arbitrum now runs a Timeboost auction for the priority lane, Base and OP run FCFS with priority-fee escalation. Third-party MEV is limited by the sequencer’s control of ordering.

5.3. Solana

No public mempool; transactions go directly to slot leaders, who control ordering. Jito provides bundle auctions at the validator level. Helius offers optional Jito integration.

5.4. Sui

DAG mempool with object-based execution. MEV concentrates on shared objects such as AMM pools. Parallel execution of independent transactions removes ordering MEV for simple transfers but not for contended pool state.


6. Practical guidance

6.1. Takers

  1. Set minAmountOut from the quote, not from the mark. The gap between them is the skew plus the fee and is legitimate, not slippage.
  2. Set a real deadline. type(uint256).max opts out of the only staleness bound the caller controls.
  3. Check the output leg’s coverage before a large trade. The convex toll is the term that grows without bound.
  4. Compare hopAmounts to the destination reserves on large quotes (§2.3).
  5. Use a private RPC on L1 and BNB Chain.

6.2. Integrators

  1. Quote at display time with Pool.getSwapQuote; it is a view and takes no cache writes.
  2. Show the decomposition, not one number: skew, curve, toll and fee are four different things with four different risk profiles. SwapQuote exposes markPrice, midPrice, covToll, spreadPbps, protoFee and lpFee precisely so this is possible without re-deriving anything.
  3. Credit 100% of the fee to tokenOut. There is no input-leg fee (IPool.sol).
  4. The realized fee is spreadPbps/2 of the pre-fee output, not spreadPbps.
  5. Handle Err.Expired, Err.ThresholdViolation, Err.ZeroValue, Err.InsufficientAmount, Err.BaseDepegged and Err.FeatureDisabled distinctly. They mean different things and only two of them are worth retrying.

6.3. Large traders

  1. Intent-based systems (CoW Protocol, UniswapX) for execution above the reserve scale.
  2. Private mempools or direct builder connections.
  3. Time-weight across blocks only if the spread cost of extra clips is smaller than the impact saved, which on a stable leg it usually is not (§4.4).
  4. Monitor markout against midPrice, not against markPrice. The mid is where the book was.

7. Research and further reading