- 1Start simulating cUSD → PathUSD → USDT0.
- 2The first Tempo hook asks PoolManager to transfer cUSD.
- !Input is not prepared. The token transfer reverts here.
- 4No output amount is returned for route comparison.
The route under investigation
Quote-Execution Mismatch in Tempo Multi-Hop Swaps
The question: Can a swap system fail to estimate a route that would execute successfully and therefore be unable to compare it with other routes? We tested route lengths, hook types, input amounts, and liquidity conditions. For certain inputs on cUSD → PathUSD → USDT0, V4Quoter returns no quote even though a fork transaction succeeds when input is prepared first.
cUSD / PathUSD
PathUSD / USDT0
How the two paths diverge
The affected quote simulation can reach the hook before the required input balance is prepared. A funded transaction supplies the input first, then runs the same route.
- 1Transfer the user's cUSD into PoolManager first.
- 2Input is prepared. The hook's transfer succeeds.
- 3Run both Tempo conversions through PathUSD.
- 4Transfer USDT0 to the recipient.
What we tested
We varied route length, hook placement, input amount, and liquidity to separate possible explanations:
| Cases | Purpose | Reported result |
|---|---|---|
| 01-02: Ordinary pools, one and two hops | Is multi-hop routing itself the cause? | Quotes match execution. |
| 03: Two fee hooks | Does the quoter skip custom hooks? | Both hooks run; quote matches execution. |
| 04-05: Tempo-style hook first versus last | Does token availability at the hook matter? | The first-hop case fails without prepared input; the last-hop control works. |
| 06-08: Deployed Tempo pools, small inputs | Do all real Tempo routes fail? | The documented small-input routes work. |
| 09-10: Input above PoolManager's cUSD balance | Can funding order explain a failed quote? | V4Quoter fails; funded execution completes. |
| 11: Extremely large input | Can we distinguish this gap from genuine illiquidity? | Both quote and execution reject the swap. |
Experiment cases
Open a case to see the full path, input and starting balance, quote, funded execution, and interpretation.
What the evidence supports
For certain multi-hop Tempo routes, the examined UniRoute quote path can fail to prepare the balance required by hook execution. An executable route may therefore have no usable quote for route comparison. A fix must produce both an accurate quote and a compatible funded execution plan.
This dashboard does not claim measured production impact, user loss, or better prices. Those claims require production traffic data and same-block comparisons against other executable routes, including gas.
Implemented and validated on a pinned Tempo fork
Recover the quote. Prove the execution. Admit only when both match.
For verified Tempo routes, the new path quotes each hop at the same block, builds the funded transaction, validates the complete Universal Router execution, and only then adds the route to comparison.
Recorded Anvil fork experiment
Three inputs. Before and after QuoteBridge.
These are measured results from three independent runs at the same Tempo block. Select a case to inspect its quote, funded transaction, and receipt. No local setup is needed to view the results.
Choose a measured case
The route and fork block stay the same. Only the cUSD input changes.
V4Quoter could not return an amount.
The recipient received the quoted amount.
Before: V4Quoter quote
The existing quote path's result for this input.
Loading the recorded result.
After: QuoteBridge quote
Each Tempo hook is quoted in route order at the same block.
The output of the first hook becomes the input of the second.
SETTLE → SWAP_EXACT_IN → TAKEAfter: funded execution
The complete Universal Router transaction was sent on the local fork.
Loading the recorded receipt.
Did quote match what arrived?
Compare QuoteBridge's output with the recipient's USDT0 balance change.
Loading the recorded comparison.
The baseline could not compare this route; QuoteBridge produced a quote and verified that the corresponding swap executes.
The admission pipeline
A quote is a candidate, not a result.
Select a step to see what the boundary proves before a Tempo route becomes eligible.
Accept only a verified route shape.
The dispatcher checks the Tempo hook deployment, pool IDs, token direction, fee, tick spacing, chain, and pinned block before using the specialized path.
Previously recorded fork proof
25 cUSD: from no quote to validated comparison input
Direct hook quotes compose the candidate at the pinned block.
The plan transfers input before the hooks request it.
The recipient's USDT0 transfer equals the candidate exactly.
Route, amount, block, and complete plan are bound before admission.
{
"quotePath": "tempo_hook",
"quoteStatus": "candidate",
"validationStatus": "validated",
"amountIn": 25000000,
"amountOut": 24997499,
"gasUsed": 316216,
"hookCalls": 2,
"planDigest": "f5d7fcf6...f598"
}
A second validation trap
Gross swap output is not always the wallet increase.
Tempo can charge transaction gas in PathUSD. The validator reads the receipt instead of treating the smaller wallet delta as a bad quote.
Wallet rises by 999,479 because the receipt charges that wallet 321 PathUSD gas.
The payer separately pays 332 PathUSD gas, proving the swap output was not reduced.
No fixed 321-unit adjustment. Gas is reconciled only when the receipt proves the fee payer, token, collector, and amount.
Fail-closed routing
What is allowed into comparison?
| Observed state | Decision | Why |
|---|---|---|
| Quote and complete execution match | Admit | The candidate is executable as quoted. |
| Candidate exists, but no validator is available | Keep out | A number alone is not execution evidence. |
| Executed output differs from the quote | Keep out | The candidate failed validation. |
| Route, input, block, or plan differs | Keep out | Evidence belongs to another execution context. |
| Output-token gas cannot be proven | Indeterminate | Ambiguous token flow is not admitted. |
| Tempo Exchange reports insufficient liquidity | Reject | Funding order cannot repair real illiquidity. |
| Ordinary no-hook route | Standard path | It stays with the normal quoter. |
| Unknown custom hook | Unsupported | It is never silently promoted. |
Regression protection
What the tests protect
python -m unittest discover -s tests -vguard suite coveredIntegration boundary
Implemented proof, explicit production boundary.
- Runnable standalone dispatcher
- Public UniRoute dispatch patch
- Full Router validation for supported routes
- Receipt-based gas reconciliation
- Private service must inject the real boundary
- Arbitrary blocks and hook deployments remain unsupported
- No measured better-price or user-impact claim
- No claim of production deployment
We do not admit a route because we found a number. We admit it only when the same bound execution plan proves that number.