Align hybrid swap quotes with hybrid on-chain execution #418

Closed
opened 2026-06-25 14:12:55 +00:00 by PlasticDigits · 10 comments
PlasticDigits commented 2026-06-25 14:12:55 +00:00 (Migrated from gitlab.com)

Parent

#411 — Updated Gap Analysis (recommendation 11 — parent clarification: hybrid quote must match hybrid execution; not a disclosure/acknowledgment UX)

Current codebase

Quote vs execution mismatch is the core gap:

  • SwapPage.tsx documents that receive line can be pool-only while tx submits hybrid Pattern C when useHybridBook is set.
  • TradeMarketOrderPanel.tsx sets quoteDisclosure: 'Direct pair · hybrid_simulation (pool-only leg; book not in quote).' when book leg omitted from quote path.
  • Indexer GET /api/v1/route/solve runs global best execution with hybrid grid (best_execution.rs, hybrid_route_opt.rs, db_orderbook_sim.rs) but frontend paths sometimes fall back to LCD hybrid_simulation pool-only or client-side pool sim.
  • Contract invariant (L8): hybrid fill can differ from pool-only quote — docs/contracts-security-audit.md.

Parent #411 comment (2026-06-25): do not add acknowledgment/disclosure UX — make the quote hybrid when execution is hybrid (indexer changes likely required).

Why needed

Users migrating from Uniswap/CEX expect quoted output ≈ executed output. Showing pool-only receive while submitting hybrid routes is a critical trust defect and support burden.

Constraints / guardrails

  • Execution path remains source of truth — quote must use same book fraction / hop split as submit payload.
  • Preserve pool_only query flag for integrators who want pool quotes explicitly.
  • Indexer ROUTE_SOLVER_DB_HYBRID / mirror freshness rules (#319) must be respected — stale mirror → honest error, not silent pool fallback.
  • Multihop: align with enrichSwapOperationsWithHopMinReturns and swapRoutePreflight.ts (#334).
  • Do not implement "acknowledge mismatch before submit" — parent rejected that approach.

Relevant files

Frontend

  • frontend-dapp/src/pages/SwapPage.tsx
  • frontend-dapp/src/components/trade/TradeMarketOrderPanel.tsx
  • frontend-dapp/src/services/terraclassic/pair.ts (hybrid_simulation)
  • frontend-dapp/src/services/terraclassic/swapRoutePreflight.ts
  • frontend-dapp/src/services/indexer/client.ts
  • skills/AGENTS_FRONTEND_SWAP_ROUTE_DISPLAY.md

Indexer

  • indexer/src/api/best_execution.rs
  • indexer/src/api/hybrid_route_opt.rs
  • indexer/src/api/db_orderbook_sim.rs
  • indexer/src/api/route_solver.rs
  • docs/route-solver.md, docs/adr/0002-global-best-execution-route-solver.md

Contracts

  • smartcontracts/contracts/pair/src/orderbook.rs, execute_swap
  1. Single source of truth: when submit uses hybrid (book leg > 0 or indexer hybrid split), quote path must call indexer hybrid sim or LCD hybrid_simulation with identical book_input / operations.
  2. Trade market panel: remove pool-only quote path when hybrid routing is enabled; use indexer solve response estimated_amount_out + on-chain attrs.
  3. Swap page: when useHybridBook, receive line uses hybrid sim (indexer or LCD), not pool-only simulate_swap.
  4. Indexer: ensure solve response includes execution-aligned operation list + book fractions for frontend display (#158, #302).
  5. Add integration test: quote amount == executed return within tolerance on LocalTerra hybrid swap.

Acceptance criteria

  • Hybrid-enabled swap/trade market quotes include book leg in simulation.
  • No user-visible "pool-only quote / hybrid execution" mismatch on default paths.
  • quoteDisclosure strings reflect actual sim path (or removed after jargon cleanup sibling).
  • Indexer + frontend agree on hop-level hybrid split for direct and multihop.
  • Screenshot: Swap with hybrid book leg — receive line matches pre-submit summary.
  • Screenshot: Trade market panel — quote output with hybrid routing on.

Test plan

  • make test-frontend — SwapPage.test.tsx, TradeMarketOrderPanel.submitSnapshot.test.tsx
  • make test-indexer-integration — route solve hybrid cases
  • skills/AGENTS_E2E_HYBRID_SWAP.md — strict on-chain hybrid spec
  • make test-e2e — fee-discount-quote-245.spec.ts, hybrid swap specs
  • Manual LocalTerra: hybrid swap quote vs executed return_amount

Attack / abuse test plan

  • Stale indexer mirror must not over-quote vs on-chain fill (under-quote safer).
  • Manipulated client book fraction must not pass if chain enforces different split.
  • Fuzz: zero book liquidity → honest pool-only quote when execution is pool-only.

Verification criteria

  • E2E: "executed return matches quote" path in fee-discount-quote-245.spec.ts extended to hybrid book walk.
  • Remove or obsolete hybridQuoteMismatch / pool-only warning flags in SwapPage.tsx sim data.
## Parent [#411 — Updated Gap Analysis](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/411) (recommendation 11 — **parent clarification:** hybrid quote must match hybrid execution; not a disclosure/acknowledgment UX) ## Current codebase **Quote vs execution mismatch** is the core gap: - `SwapPage.tsx` documents that receive line can be **pool-only** while tx submits **hybrid** Pattern C when `useHybridBook` is set. - `TradeMarketOrderPanel.tsx` sets `quoteDisclosure: 'Direct pair · hybrid_simulation (pool-only leg; book not in quote).'` when book leg omitted from quote path. - Indexer `GET /api/v1/route/solve` runs global best execution with hybrid grid (`best_execution.rs`, `hybrid_route_opt.rs`, `db_orderbook_sim.rs`) but frontend paths sometimes fall back to LCD `hybrid_simulation` pool-only or client-side pool sim. - Contract invariant (L8): hybrid fill can differ from pool-only quote — `docs/contracts-security-audit.md`. Parent #411 comment (2026-06-25): **do not** add acknowledgment/disclosure UX — **make the quote hybrid when execution is hybrid** (indexer changes likely required). ## Why needed Users migrating from Uniswap/CEX expect quoted output ≈ executed output. Showing pool-only receive while submitting hybrid routes is a critical trust defect and support burden. ## Constraints / guardrails - Execution path remains source of truth — quote must use same book fraction / hop split as submit payload. - Preserve `pool_only` query flag for integrators who want pool quotes explicitly. - Indexer `ROUTE_SOLVER_DB_HYBRID` / mirror freshness rules (#319) must be respected — stale mirror → honest error, not silent pool fallback. - Multihop: align with `enrichSwapOperationsWithHopMinReturns` and `swapRoutePreflight.ts` (#334). - Do **not** implement "acknowledge mismatch before submit" — parent rejected that approach. ## Relevant files **Frontend** - `frontend-dapp/src/pages/SwapPage.tsx` - `frontend-dapp/src/components/trade/TradeMarketOrderPanel.tsx` - `frontend-dapp/src/services/terraclassic/pair.ts` (`hybrid_simulation`) - `frontend-dapp/src/services/terraclassic/swapRoutePreflight.ts` - `frontend-dapp/src/services/indexer/client.ts` - `skills/AGENTS_FRONTEND_SWAP_ROUTE_DISPLAY.md` **Indexer** - `indexer/src/api/best_execution.rs` - `indexer/src/api/hybrid_route_opt.rs` - `indexer/src/api/db_orderbook_sim.rs` - `indexer/src/api/route_solver.rs` - `docs/route-solver.md`, `docs/adr/0002-global-best-execution-route-solver.md` **Contracts** - `smartcontracts/contracts/pair/src/orderbook.rs`, `execute_swap` ## Recommended direction 1. **Single source of truth:** when submit uses hybrid (book leg > 0 or indexer hybrid split), quote path must call indexer hybrid sim or LCD `hybrid_simulation` with **identical** `book_input` / operations. 2. **Trade market panel:** remove pool-only quote path when hybrid routing is enabled; use indexer solve response `estimated_amount_out` + on-chain attrs. 3. **Swap page:** when `useHybridBook`, receive line uses hybrid sim (indexer or LCD), not pool-only `simulate_swap`. 4. **Indexer:** ensure solve response includes execution-aligned operation list + book fractions for frontend display (#158, #302). 5. Add integration test: quote amount == executed return within tolerance on LocalTerra hybrid swap. ## Acceptance criteria - [ ] Hybrid-enabled swap/trade market quotes include book leg in simulation. - [ ] No user-visible "pool-only quote / hybrid execution" mismatch on default paths. - [ ] `quoteDisclosure` strings reflect actual sim path (or removed after jargon cleanup sibling). - [ ] Indexer + frontend agree on hop-level hybrid split for direct and multihop. - [ ] **Screenshot:** Swap with hybrid book leg — receive line matches pre-submit summary. - [ ] **Screenshot:** Trade market panel — quote output with hybrid routing on. ## Test plan - `make test-frontend` — `SwapPage.test.tsx`, `TradeMarketOrderPanel.submitSnapshot.test.tsx` - `make test-indexer-integration` — route solve hybrid cases - `skills/AGENTS_E2E_HYBRID_SWAP.md` — strict on-chain hybrid spec - `make test-e2e` — `fee-discount-quote-245.spec.ts`, hybrid swap specs - Manual LocalTerra: hybrid swap quote vs executed `return_amount` ## Attack / abuse test plan - Stale indexer mirror must not over-quote vs on-chain fill (under-quote safer). - Manipulated client book fraction must not pass if chain enforces different split. - Fuzz: zero book liquidity → honest pool-only quote when execution is pool-only. ## Verification criteria - E2E: "executed return matches quote" path in `fee-discount-quote-245.spec.ts` extended to hybrid book walk. - Remove or obsolete `hybridQuoteMismatch` / pool-only warning flags in `SwapPage.tsx` sim data.
PlasticDigits commented 2026-06-25 14:13:22 +00:00 (Migrated from gitlab.com)

mentioned in issue #411

mentioned in issue #411
PlasticDigits commented 2026-06-25 20:00:11 +00:00 (Migrated from gitlab.com)

Hybrid should be enabled by default

Hybrid should be enabled by default
PlasticDigits commented 2026-06-25 20:09:47 +00:00 (Migrated from gitlab.com)

mentioned in commit 2e19887e65

mentioned in commit 2e19887e654d90f37365774856e1bc4a51601a9e
PlasticDigits commented 2026-06-25 20:10:14 +00:00 (Migrated from gitlab.com)

mentioned in merge request !938

mentioned in merge request !938
PlasticDigits commented 2026-06-25 20:36:20 +00:00 (Migrated from gitlab.com)

mentioned in commit 476b5f6e43

mentioned in commit 476b5f6e43e626e6a56bf58238b4f26cddef3743
PlasticDigits commented 2026-06-26 06:50:04 +00:00 (Migrated from gitlab.com)

mentioned in commit a58948b6cb

mentioned in commit a58948b6cbd6ea74a485f3d369cab2253aa4327d
PlasticDigits commented 2026-06-26 06:50:19 +00:00 (Migrated from gitlab.com)

mentioned in merge request !947

mentioned in merge request !947
PlasticDigits commented 2026-06-26 07:57:08 +00:00 (Migrated from gitlab.com)

mentioned in commit 3de656052a

mentioned in commit 3de656052a3a34d35eb10f86fc02abee291cc761
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-26 07:57:09 +00:00
PlasticDigits commented 2026-08-22 03:10:04 +00:00 (Migrated from gitlab.com)

mentioned in issue #589

mentioned in issue #589
PlasticDigits commented 2026-08-22 12:26:35 +00:00 (Migrated from gitlab.com)

mentioned in issue #597

mentioned in issue #597
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#418
No description provided.