Motivation
The fallback is a single fallbackSwapRouter + fallbackQuoter pair, and every call to it goes through src/libraries/UniV3Router.sol, which speaks the Uniswap V3 SwapRouter02 / QuoterV2 ABI. That covers Uniswap V3 and its forks (PancakeSwap V3 is being handled in the BNB Chain deployment issue), but nothing else:
- Uniswap V4 routes through the Universal Router or the
PoolManager unlock-callback flow, and keys pools by PoolKey rather than a fee tier.
- PancakeSwap Infinity CL pools are different again.
- There is exactly one fallback per deployment. On BNB Chain we would like to try PancakeSwap V3 first and Uniswap V3 second; today that is not expressible.
Adding each of these as another if branch inside _coreSwap and the _quote* helpers, with one wrapper library per DEX family, would keep growing the router's core paths.
Current state
fallbackSwapRouter does double duty: it is both the fallback implementation address and the venue identity returned as executedVenue and accepted by swapViaVenueV1 / quoteVenueV1 / swapViaSelectedVenuesV1.
- Fee-tier selection (
resolvedFee, setPairFee(s), fallbackFee) is a V3 concept living in the router.
Proposal, to be discussed
- Introduce an
IFallbackAdapter (or similar) with quoteExactIn, quoteExactOut, swapExactIn, swapExactOut, implemented by one small contract per DEX family (UniV3Adapter, PancakeV3Adapter, UniV4Adapter, PancakeInfinityCLAdapter, ...). The router talks only to the adapter.
- Allow more than one fallback adapter per deployment, ordered or quoted best-of. The existing
executedVenue semantics keep working if each adapter is its own venue address.
- Move pool-selection config (V3 fee tiers, V4
PoolKeys) into the adapter, so the router does not need to know how a given venue keys its pools.
- Keep the Uniswap V3 adapter's behaviour byte-for-byte equivalent to today's
UniV3Router path so the migration can be validated by the existing test suite.
Constraints
- This changes the storage layout (adapter registry replaces the two fallback addresses) and the upgrade path, so it goes through
Upgrades.prepareUpgrade validation in scripts/Upgrade.s.sol and needs a reinitializer that migrates the current fallbackSwapRouter / fallbackQuoter into the first adapter.
- One extra external call per fallback quote and swap. Worth measuring against
docs/gas_report.md before committing to the shape.
- Should land after the BNB Chain deployment issue so the first BNB Chain deployment is not blocked on it.
Motivation
The fallback is a single
fallbackSwapRouter+fallbackQuoterpair, and every call to it goes throughsrc/libraries/UniV3Router.sol, which speaks the Uniswap V3SwapRouter02/QuoterV2ABI. That covers Uniswap V3 and its forks (PancakeSwap V3 is being handled in the BNB Chain deployment issue), but nothing else:PoolManagerunlock-callback flow, and keys pools byPoolKeyrather than a fee tier.Adding each of these as another
ifbranch inside_coreSwapand the_quote*helpers, with one wrapper library per DEX family, would keep growing the router's core paths.Current state
fallbackSwapRouterdoes double duty: it is both the fallback implementation address and the venue identity returned asexecutedVenueand accepted byswapViaVenueV1/quoteVenueV1/swapViaSelectedVenuesV1.resolvedFee,setPairFee(s),fallbackFee) is a V3 concept living in the router.Proposal, to be discussed
IFallbackAdapter(or similar) withquoteExactIn,quoteExactOut,swapExactIn,swapExactOut, implemented by one small contract per DEX family (UniV3Adapter,PancakeV3Adapter,UniV4Adapter,PancakeInfinityCLAdapter, ...). The router talks only to the adapter.executedVenuesemantics keep working if each adapter is its own venue address.PoolKeys) into the adapter, so the router does not need to know how a given venue keys its pools.UniV3Routerpath so the migration can be validated by the existing test suite.Constraints
Upgrades.prepareUpgradevalidation inscripts/Upgrade.s.soland needs a reinitializer that migrates the currentfallbackSwapRouter/fallbackQuoterinto the first adapter.docs/gas_report.mdbefore committing to the shape.