PP2 UI: Swap -- "Price impact too high for this trade" hard-blocks all multi-hop swaps even with Expert Mode enabled; preflight incorrectly flags near-zero spread hops as exceeding max spread #341

Closed
opened 2026-06-08 13:42:43 +00:00 by totdking · 11 comments
totdking commented 2026-06-08 13:42:43 +00:00 (Migrated from gitlab.com)
No description provided.
totdking commented 2026-06-08 13:50:45 +00:00 (Migrated from gitlab.com)

Summary

On the swap page, after enabling Expert Mode to bypass the 90.88% cross-rate slippage warning, the swap button remains permanently disabled with the label "Price impact too high for this trade". This state is driven by routePreflight.anyHopExceedsMaxSpread = true, which is a hard block that Expert Mode does not bypass.

Direct hybrid_simulation contract queries run against both hops of the CORAL to JADE to TOPAZ route return near-zero spread on each hop, well below the 0.5% max spread threshold. The preflight is incorrectly computing anyHopExceedsMaxSpread = true when neither hop's actual on-chain spread exceeds the limit.

The same block appears on all other tested multi-hop routes including EMBER to CORAL (routed via EMBER to JADE to RUBY to CORAL by the solver), confirming this is not pair-specific.


Observed behavior

Route attempted Route solver output anyHopExceedsMaxSpread Swap executable
CORAL to TOPAZ (direct) CORAL to JADE to TOPAZ (2-hop) true No
EMBER to CORAL (direct) EMBER to JADE to RUBY to CORAL (3-hop) true No

On-chain hybrid_simulation verification for CORAL to JADE to TOPAZ:

Hop spread_amount spreadCmp / totalGrossOut Exceeds 0.5% threshold
CORAL to JADE 0 0 / 9,610 = 0.00% No
JADE to TOPAZ 2 2 / 431,777 = 0.00046% No

Both hops clear the threshold. anyHopExceedsMaxSpread should be false. It is true.


Reproduction steps

  1. Navigate to / (Swap page) on LocalTerra
  2. Connect Keplr wallet (funded test account)
  3. Select CORAL as token in, TOPAZ as token out
  4. Enter any amount
  5. Observe: "Slippage is too high" blocks the button (expected -- 90.88% expected slippage)
  6. Open Settings, enable Expert Mode
  7. Observe: button label changes to "Price impact too high for this trade" -- still disabled
  8. Confirm Expert Mode is active -- the slippage block is bypassed but the spread block is not
  9. Button cannot be enabled regardless of slippage tolerance or Expert Mode state

Expected behavior

When Expert Mode is enabled and the per-hop on-chain spread is below the configured max spread tolerance (0.5%), the swap button should become enabled. "Price impact too high" should only block when a hop's actual AMM spread ratio exceeds the max spread threshold.


Actual behavior

anyHopExceedsMaxSpread is true for all tested multi-hop routes even when direct contract simulation confirms near-zero spread on every hop. Expert Mode does not bypass this block. No multi-hop swap can be submitted.


Possible root cause area

The preflight logic is in frontend-dapp/src/services/terraclassic/swapRoutePreflight.ts. Three code paths can set anyExceeds = true:

  1. declaredMaterialReject.kind === 'insufficient_pool_leg'
  2. materialRejectAfterSim != null (from hybridNoBeliefMaterialPoolReject)
  3. spreadRatioStrictlyExceedsMax(spreadCmp, totalGrossOut, maxSpreadDecimalStr)

Path 3 is confirmed clear by direct simulation. Paths 1 and 2 require the hop to have a non-zero book leg, but both hops are pool-only (book_return_amount: 0), so hybridNoBeliefMaterialPoolReject returns null immediately. The exact trigger has not been conclusively identified from static analysis. A try-catch fallback or a different code path (e.g. isMultiHop vs indexer path at SwapPage.tsx:466-531) may be involved.


Impact assessment

  • Blocks: all multi-hop swap execution in the QA environment
  • PP-2 and all downstream checklist items requiring swap execution are untestable until resolved
  • Expert Mode is misleading: it appears to offer a bypass but the hard block fires immediately after

Environment

  • Chain: localterra
  • LCD: http://localhost:1317
  • Wallet: Keplr (Terra Classic)
  • Browser: Chromium
  • Page: / (Swap)
  • Pairs tested: CORAL/TOPAZ, EMBER/CORAL
  • Slippage tolerance: 0.5%
  • Expert Mode: enabled
  • Network throttle applied: No

Severity: ~"blocker:launch" Blocker: no multi-hop swap can execute; blocks PP-2 and all swap-dependent checklist items.

cc: @PlasticDigits

### Summary On the swap page, after enabling Expert Mode to bypass the 90.88% cross-rate slippage warning, the swap button remains permanently disabled with the label "Price impact too high for this trade". This state is driven by `routePreflight.anyHopExceedsMaxSpread = true`, which is a hard block that Expert Mode does not bypass. Direct `hybrid_simulation` contract queries run against both hops of the CORAL to JADE to TOPAZ route return near-zero spread on each hop, well below the 0.5% max spread threshold. The preflight is incorrectly computing `anyHopExceedsMaxSpread = true` when neither hop's actual on-chain spread exceeds the limit. The same block appears on all other tested multi-hop routes including EMBER to CORAL (routed via EMBER to JADE to RUBY to CORAL by the solver), confirming this is not pair-specific. --- ### Observed behavior | Route attempted | Route solver output | anyHopExceedsMaxSpread | Swap executable | |-----------------|---------------------|------------------------|-----------------| | CORAL to TOPAZ (direct) | CORAL to JADE to TOPAZ (2-hop) | true | No | | EMBER to CORAL (direct) | EMBER to JADE to RUBY to CORAL (3-hop) | true | No | On-chain `hybrid_simulation` verification for CORAL to JADE to TOPAZ: | Hop | spread_amount | spreadCmp / totalGrossOut | Exceeds 0.5% threshold | |-----|---------------|---------------------------|------------------------| | CORAL to JADE | 0 | 0 / 9,610 = 0.00% | No | | JADE to TOPAZ | 2 | 2 / 431,777 = 0.00046% | No | Both hops clear the threshold. `anyHopExceedsMaxSpread` should be false. It is true. --- ### Reproduction steps 1. Navigate to `/` (Swap page) on LocalTerra 2. Connect Keplr wallet (funded test account) 3. Select CORAL as token in, TOPAZ as token out 4. Enter any amount 5. Observe: "Slippage is too high" blocks the button (expected -- 90.88% expected slippage) 6. Open Settings, enable Expert Mode 7. Observe: button label changes to "Price impact too high for this trade" -- still disabled 8. Confirm Expert Mode is active -- the slippage block is bypassed but the spread block is not 9. Button cannot be enabled regardless of slippage tolerance or Expert Mode state --- ### Expected behavior When Expert Mode is enabled and the per-hop on-chain spread is below the configured max spread tolerance (0.5%), the swap button should become enabled. "Price impact too high" should only block when a hop's actual AMM spread ratio exceeds the max spread threshold. --- ### Actual behavior `anyHopExceedsMaxSpread` is true for all tested multi-hop routes even when direct contract simulation confirms near-zero spread on every hop. Expert Mode does not bypass this block. No multi-hop swap can be submitted. --- ### Possible root cause area The preflight logic is in `frontend-dapp/src/services/terraclassic/swapRoutePreflight.ts`. Three code paths can set `anyExceeds = true`: 1. `declaredMaterialReject.kind === 'insufficient_pool_leg'` 2. `materialRejectAfterSim != null` (from `hybridNoBeliefMaterialPoolReject`) 3. `spreadRatioStrictlyExceedsMax(spreadCmp, totalGrossOut, maxSpreadDecimalStr)` Path 3 is confirmed clear by direct simulation. Paths 1 and 2 require the hop to have a non-zero book leg, but both hops are pool-only (`book_return_amount: 0`), so `hybridNoBeliefMaterialPoolReject` returns null immediately. The exact trigger has not been conclusively identified from static analysis. A try-catch fallback or a different code path (e.g. isMultiHop vs indexer path at `SwapPage.tsx:466-531`) may be involved. --- ### Impact assessment - Blocks: all multi-hop swap execution in the QA environment - PP-2 and all downstream checklist items requiring swap execution are untestable until resolved - Expert Mode is misleading: it appears to offer a bypass but the hard block fires immediately after --- ### Environment - Chain: localterra - LCD: [http://localhost:1317](http://localhost:1317) - Wallet: Keplr (Terra Classic) - Browser: Chromium - Page: `/` (Swap) - Pairs tested: CORAL/TOPAZ, EMBER/CORAL - Slippage tolerance: 0.5% - Expert Mode: enabled - Network throttle applied: No --- **Severity:** ~"blocker:launch" Blocker: no multi-hop swap can execute; blocks PP-2 and all swap-dependent checklist items. cc: @PlasticDigits
Brouie commented 2026-06-09 02:17:30 +00:00 (Migrated from gitlab.com)

mentioned in issue #337

mentioned in issue #337
PlasticDigits commented 2026-06-09 06:50:53 +00:00 (Migrated from gitlab.com)

mentioned in commit 76723cf513

mentioned in commit 76723cf51316b9b2fa03e813a170bf8fd8363606
PlasticDigits commented 2026-06-09 06:53:30 +00:00 (Migrated from gitlab.com)

mentioned in merge request !847

mentioned in merge request !847
PlasticDigits commented 2026-06-09 06:53:44 +00:00 (Migrated from gitlab.com)

MR !847 opened

Changes: Removed pre-sim #307 reject; preflight uses enriched submit ops; Expert Mode copy + hop-spread button label.

Verify

  • npm test -- swapRoutePreflight.test.ts
  • CORAL→TOPAZ multihop: Expert Mode on, hop spread < 0.5% → button enabled
## MR !847 opened **Changes:** Removed pre-sim #307 reject; preflight uses enriched submit ops; Expert Mode copy + hop-spread button label. ### Verify - [ ] `npm test -- swapRoutePreflight.test.ts` - [ ] CORAL→TOPAZ multihop: Expert Mode on, hop spread < 0.5% → button enabled
ghost1 commented 2026-06-09 06:53:50 +00:00 (Migrated from gitlab.com)

mentioned in merge request !849

mentioned in merge request !849
ghost1 commented 2026-06-09 06:53:52 +00:00 (Migrated from gitlab.com)

mentioned in merge request !848

mentioned in merge request !848
PlasticDigits commented 2026-06-09 07:08:37 +00:00 (Migrated from gitlab.com)

mentioned in commit a6c43cab31

mentioned in commit a6c43cab31221f526b743236f3ad3ec7bf9f0284
PlasticDigits commented 2026-06-09 08:32:45 +00:00 (Migrated from gitlab.com)

Verification complete — #341

All acceptance and verification criteria PASS on main (83dc192).

Results

Criterion Result Evidence
swapRoutePreflight.test.ts PASS pool-only multihop anyHopExceedsMaxSpread=false (#341 test)
Multihop + Expert Mode on chain PASS EMBER→CORAL 3-hop: Expert Mode on, hop spread < 0.5% → Swap button enabled (not "Price impact too high")

Merged fix: !847.

Re-verify checklist

  • npm test -- swapRoutePreflight.test.ts
  • Multihop route with Expert Mode: button enabled when per-hop spread < max spread tolerance
## Verification complete — #341 All acceptance and verification criteria **PASS** on `main` (`83dc192`). ### Results | Criterion | Result | Evidence | |-----------|--------|----------| | `swapRoutePreflight.test.ts` | **PASS** | pool-only multihop `anyHopExceedsMaxSpread=false` (#341 test) | | Multihop + Expert Mode on chain | **PASS** | EMBER→CORAL 3-hop: Expert Mode on, hop spread < 0.5% → Swap button enabled (not "Price impact too high") | Merged fix: !847. ### Re-verify checklist - [ ] `npm test -- swapRoutePreflight.test.ts` - [ ] Multihop route with Expert Mode: button enabled when per-hop spread < max spread tolerance
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-09 08:32:47 +00:00
Brouie commented 2026-06-10 02:07:14 +00:00 (Migrated from gitlab.com)

mentioned in issue #353

mentioned in issue #353
Brouie commented 2026-06-11 02:14:24 +00:00 (Migrated from gitlab.com)

mentioned in merge request !864

mentioned in merge request !864
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#341
No description provided.