BopAmmRouter.swapWithFallback() is BopAMM’s safety net for high-value flow that can’t tolerate a same-block-execution failure or insufficient on-chain liquidity. The function tries the BopAMM leg in a try/catch and falls through on any revert to an allowlisted fallback adapter with pre-encoded calldata. The standard fallback adapter executes against Bebop RFQ settlement.
You don’t compose this calldata yourself. The BopAMM /quote endpoint builds the whole thing: it prepares the BopAMM leg, fetches a matching RFQ quote, and returns a ready swapWithFallback(...) call in the response tx. You sign and submit it like any other transaction. There’s no separate RFQ request, no EIP-712 signature, and no calldata splicing on your side.
You burn more gas than a plain swapWithAllowance(), but you trade reliably even when the BopAMM leg can’t land or the book is too thin.
When to use it
- High-value flow where a single revert is more expensive than the gas overhead of carrying a fallback.
- Long-tail assets with sparse maker coverage on BopAMM where the on-chain book may not always reach
minAmountOut. - Bursty traffic where you want to avoid coordinating around builder windows for every swap.
swapWithAllowance() is cheaper. Use swapWithFallback selectively rather than as the default.
Get the fallback calldata
Request a quote from the BopAMM/quote endpoint. When your partner key has the RFQ fallback feature, the response’s tx.data is a complete BopAmmRouter.swapWithFallback(...) call.
Submit it
Approve the BopAMM router fortokenIn if you haven’t already (see Approve the BopAMM router), then build, sign, and submit tx. Unlike a plain swapWithAllowance(), you don’t have to route this through a builder: the fallback is caught inside the same transaction, so a public-mempool submission can still settle via RFQ when the BopAMM leg can’t land.
What the calldata encodes
You don’t assemble this yourself, but it helps to know whattx.data decodes to. The on-chain function is:
Fees
To have the endpoint encode a router fee, pass bothfee and fee_recipient to /quote. The endpoint packs the fee into the returned swapWithFallback calldata and returns buyTokens[].amount / minimumAmount net of the BopAMM router fee.
fee_recipient. Fallback output is not charged by the BopAMM router.
Caveats
A few BopAMM-specific behaviors to be aware of:minAmountOutprotects both paths. On the BopAMM path it is checked after router fees. On the fallback path it is checked against fallback output.- Fallback output is not router-fee charged. Any RFQ terms or fees are part of the embedded RFQ calldata.
- One shared
deadline. The endpoint sets the BopAMM leg’sdeadlineto the RFQ quote’s expiry and reports it as the responseexpiry. Your whole transaction must land before then. - Native ETH is router-only. The router maps the native ETH sentinel to WETH internally and unwraps WETH for native output. Pairs that normalize to the same token are invalid.
- Residual sweep. If the fallback leg consumes less than
amountIn, any residualtokenInor ETH is swept back tomsg.senderautomatically.
Events
The events emitted depend on which leg actually settled:
Off-chain, watch for
SwapFallback to detect when your fallback paths are firing. A spike in fallback usage on a specific asset usually means the BopAMM book is too thin for your typical size on that pair - either size down, route elsewhere, or contact the team to broaden maker coverage.