Posting the draft spec for a small ERC. It reuses ERC-7726 for the reference price, so it stays intentionally narrow. Feedback welcome, especially on the open questions at the end.
requires: ERC-165, ERC-7726
Abstract
This proposal defines an interface for reference-relative slippage protection on token swaps. Instead of committing to a static minAmountOut at signing time, the caller supplies a slippage policy, an ERC-7726 quote oracle and a maximum deviation, and the executing contract derives the acceptable output floor from the reference price read at execution time, reverting if the realized output deviates beyond tolerance.
By moving the slippage floor from a stale, sign-time constant to a live, execution-time bound, this shrinks the window a sandwich attacker can extract, and lets wallets and aggregators express slippage protection in a single interoperable way, reusing the existing ERC-7726 oracle API rather than inventing another price source.
Motivation
Today a swap is protected by a single minAmountOut chosen when the transaction is built. This is the exact lever MEV extraction exploits:
- Staleness.
minAmountOutis set against a quote from block N, but the swap executes at block N+k. A sandwich bot moves the pool price inside that gap; as long as realized output stays above the stale floor, the sandwich is profitable and the victim cannot tell. - Over-wide tolerance. To avoid failed transactions during volatility, wallets default slippage high (1 to 3 percent). That headroom is precisely the extractable surface.
- No standard. Every router, aggregator, and wallet encodes slippage differently, so protection cannot be reasoned about or improved uniformly.
A reference-relative floor addresses the first two: the floor is computed at execution against a fresh reference, so it tracks real market conditions rather than a number already stale when signed. Standardizing the interface addresses the third. This is not a claim to eliminate MEV; it narrows the extractable band and makes slippage protection legible and composable.
Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHOULD”, “SHOULD NOT”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Slippage policy
struct SlippagePolicy {
address quoteOracle; // an ERC-7726 oracle for (tokenIn, tokenOut)
uint32 maxDeviationBps; // max allowed shortfall vs the reference output, in basis points
uint256 hardFloor; // absolute minimum output accepted regardless of the reference
}
quoteOracleMUST implement ERC-7726 (getQuote).maxDeviationBpsis a shortfall tolerance: realized output MAY be at mostmaxDeviationBpsbelow the reference-implied output. It MUST be<= 10_000.hardFlooris an absolute floor; the effective floor ismax(referenceFloor, hardFloor).- Reference freshness and manipulation resistance are the oracle’s responsibility (ERC-7726 implementations are expected to revert when they cannot provide a reliable quote). Callers select an oracle whose freshness SLA and manipulation cost fit the trade.
Guarded swap interface
interface ISlippageBoundedSwap {
error SlippageExceeded(uint256 realizedOut, uint256 floor);
error InvalidDeviation(uint32 maxDeviationBps);
function swapWithPolicy(
address tokenIn,
address tokenOut,
uint256 amountIn,
SlippagePolicy calldata policy,
bytes calldata routeData
) external returns (uint256 amountOut);
}
An executor implementing ISlippageBoundedSwap:
- MUST obtain the reference at execution time by calling
IERC7726(policy.quoteOracle).getQuote(amountIn, tokenIn, tokenOut). It MUST NOT accept a reference output supplied by the caller. - MUST revert
InvalidDeviationifpolicy.maxDeviationBps > 10_000. - MUST compute
floor = max(referenceOut * (10_000 - policy.maxDeviationBps) / 10_000, policy.hardFloor). - MUST perform the swap via
routeDataand measure the realizedamountOut. - MUST revert
SlippageExceeded(amountOut, floor)ifamountOut < floor.
Implementers MUST support ERC-165 and return true for the ISlippageBoundedSwap interface id.
Rationale
Why reference-relative instead of a static minimum? A static minAmountOut encodes the market as of signing; the attacker operates in the delta to execution. Recomputing the floor against a fresh reference collapses that delta into whatever the oracle’s freshness and manipulation cost allow.
Why reuse ERC-7726? A quote oracle is exactly ERC-7726’s remit (getQuote returns an explicit token amount for a (base, quote) pair), and it already has adapters across venues. Defining another oracle interface here would fragment the ecosystem and duplicate a standard; this proposal fixes only the slippage contract on top of it.
Why a shortfall tolerance (maxDeviationBps) rather than the caller passing a floor? So protection scales with size and live price automatically, and wallets can express one policy (“never more than 0.5 percent below the reference”) rather than recomputing a number per trade.
Why keep hardFloor? Oracles fail. hardFloor guarantees a worst case the caller pre-accepts even if the reference is unavailable within tolerance.
Relationship to ERC-5143. ERC-5143 defines slippage-protected variants of the ERC-4626 vault entrypoints with a caller-supplied static minimum, scoped to tokenized vaults. This proposal is scoped to general swaps and derives the bound from a live ERC-7726 reference rather than a static input. They are complementary.
Backwards Compatibility
Additive. Routers that do not implement ISlippageBoundedSwap are unaffected, and callers can keep using static-minAmountOut entrypoints. A router MAY implement both.
Security Considerations
- The oracle is the trust root. A manipulable reference makes the floor manipulable. Because the reference comes from an ERC-7726 oracle, manipulation resistance and freshness are that oracle’s responsibility; callers SHOULD select an oracle (for example a TWAP window sized so moving it costs more than the sandwich it would enable) appropriate to the trade, and a spot price from the pool being traded MUST NOT be used as the reference.
- Not an MEV eliminator. This narrows the sandwich band; it does not remove reordering, back-running, or extraction that stays within
maxDeviationBps. It composes with private mempools and PBS-level protections rather than replacing them. - Oracle failure. If the oracle reverts or cannot quote within tolerance, the swap reverts or falls to the
hardFloorpath; callers sethardFlooras the accepted worst case. - Reference and venue divergence. If the reference and the execution venue diverge legitimately (thin liquidity, real moves), honest trades can revert. Callers SHOULD size
maxDeviationBpsfor the venue’s normal basis.
Open questions
- Reference source. Is a TWAP the right default, or should the interface stay agnostic and let the ERC-7726 adapter decide, as it does now?
- Should
maxDeviationBpsbe per-call only, or also expressible as a signed policy a wallet reuses across trades? - Is
hardFloorworth keeping, or does relying on the oracle to revert when it cannot quote cover the failure case cleanly enough?
I have a reference implementation with the negative tests (the interface, an abstract base with the floor logic, and a mock ERC-7726 oracle) and will link the repo in a reply.