ethereum-optimism / ethereum-optimism/actions
Optimize getQuote to skip calldata encoding when wallet is not needed
- Dominant language
- TypeScript
- Stars
- 32
- Forks
- 25
- Avg merge
- 10h 20m
- Merged PRs (30d)
- 16
Description
## Problem
`getQuote()` currently builds both pricing data and swap calldata (via `_getQuote` in each provider). When called from the `ActionsSwapNamespace` (read-only, no wallet), the calldata is wasted — no one can execute it without a wallet.
This is especially costly with price routing (`settings.routing: 'price'`), where `getQuote()` fetches quotes from all eligible providers in parallel. Each quote encodes calldata that will never be used except for the winning quote — and even that won't be used if the caller only needs display data.
The same pattern now exists in borrow: read-only preview flows can call `actions.borrow.getQuote(...)`, but the current implementation still builds the full executable quote, including the pre-built transaction bundle, even when the caller only needs `positionAfter`, fees, and the safe-ceiling LTV.
## Proposed Solution
Add an internal `includeCalldata` / `includeExecution` flag to read-only quoting flows:
1. **`ActionsSwapNamespace.getQuote()`** — calls provider with `includeCalldata: false`. Returns a `SwapQuote` with `execution` omitted or set to a sentinel. Faster because it skips `encodeSwap()` / `encodeCLSwap()` / `encodeUniversalRouterSwap()`.
2. **`WalletSwapNamespace.getQuote()`** — calls provider with `includeCalldata: true` (default). Returns a full `SwapQuote` ready for `execute()`.
3. **Provider `_getQuote()`** — accepts the flag and conditionally skips the encoding step. The quoting step (RPC calls to get amounts) still runs in both cases.
4. **Borrow parity** — apply the same pattern to borrow quote building so read-only borrow preview paths can skip execution-bundle construction while wallet-bound borrow quotes still return full executable data.
The quote types could make execution optional, or we could have two internal return paths with a shared base.
## Why This Matters
- With 2+ providers and price routing, every swap `getQuote()` call currently does N encoding operations. Only 1 is ever used.
- The `ActionsSwapNamespace` is explicitly read-only — encoding calldata for it is pure waste.
- The encoding involves `encodeFunctionData`, `encodeAbiParameters`, `encodePacked` — non-trivial compute per call.
- Borrow has the same avoidable overhead for preview-only callers that do not need executable transactions.
## Scope
- Add `includeCalldata?: boolean` to `SwapQuoteParams` or as an internal-only param
- Update `_getQuote` in `VelodromeSwapProvider` and `UniswapSwapProvider` to skip encoding when false
- Override `getQuote` in `ActionsSwapNamespace` to pass `includeCalldata: false`
- Ensure `WalletSwapNamespace` defaults to `includeCalldata: true`
- Extend the same approach to borrow quote building, likely with an internal `includeExecution` flag or a parallel quote builder path
- Update tests to cover both paths
Contributor guide
Assessment
This issue has not been assessed yet.