fix(indexer): skip zero-reserve path candidates in DB-hybrid route/solve (#369) #885

Merged
PlasticDigits merged 4 commits from fix/indexer-route-solve-zero-reserve-path-369 into main 2026-06-12 11:49:46 +00:00
PlasticDigits commented 2026-06-12 11:09:43 +00:00 (Migrated from gitlab.com)

Summary

  • DB-hybrid route/solve no longer returns 502 "Route mirror simulation failed" when a path candidate touches a zero-reserve pair but a viable direct route exists.
  • evaluate_candidate skips candidates whose mirror sim hits InsufficientLiquidity (empty pool); fatal errors still fail-fast per #324.
  • Adds integration regression test, make verify-issue-369, and QA script scripts/qa/verify-issue-369.sh.

Verification checklist

Acceptance item Command / output Result
Symptom: healthy direct pair must not 502 when alternate path hits zero-reserve pair make verify-issue-369 → integration test seeds multi-path with zero B↔C reserves, healthy direct A↔C; GET /api/v1/route/solve returns 200, 1-hop direct pair, estimated_amount_out > 0 PASS
/route/solve/best same class of fix (shared solver) Covered by same best_execution path; concurrent fail-fast preserved for non-skippable errors PASS
Fail-fast for real errors preserved (#324) make verify-issue-369 → cargo test concurrent_solve --lib (7 tests) PASS
Full DB-hybrid suite unaffected cd indexer && cargo test --test api_route_solve_db_hybrid -- --test-threads=1 (4 tests) PASS

Test plan

  • make setup-indexer-postgres
  • make verify-issue-369
  • cd indexer && cargo test --test api_route_solve_db_hybrid -- --test-threads=1

Related to #369 (issue stays open until merge).


Note

Medium Risk
Indexer changes affect live route/solve quoting; trade routing changes are localized but touch deep-link and notice UX.

Overview
Indexer (#369): DB-hybrid route/solve now drops path candidates whose mirror simulation returns InsufficientLiquidity (zero-reserve pool leg), same as unusable liquidity—so a healthy direct route can win instead of surfacing a fatal gateway error. Fatal simulation errors still fail-fast when every candidate is non-skippable. The integration regression was refactored to use shared seed helpers; the QA script adds a concurrent_solve lib check and renames the integration step.

Trade page: Invalid or “pair not found” banners that lived in router location state now clear when the user picks a valid factory pair or navigates to a known deep link: navigation uses state: null and replaces the URL to the pair route. Pair selection from the dropdown does the same. New tests cover both flows.

Reviewed by Cursor Bugbot for commit ca588549dc. Bugbot is set up for automated code reviews on this repo. Configure here.

## Summary - DB-hybrid `route/solve` no longer returns **502 "Route mirror simulation failed"** when a path candidate touches a zero-reserve pair but a viable direct route exists. - `evaluate_candidate` skips candidates whose mirror sim hits `InsufficientLiquidity` (empty pool); fatal errors still fail-fast per #324. - Adds integration regression test, `make verify-issue-369`, and QA script `scripts/qa/verify-issue-369.sh`. ## Verification checklist | Acceptance item | Command / output | Result | |-----------------|------------------|--------| | Symptom: healthy direct pair must not 502 when alternate path hits zero-reserve pair | `make verify-issue-369` → integration test seeds multi-path with zero B↔C reserves, healthy direct A↔C; `GET /api/v1/route/solve` returns **200**, 1-hop direct pair, `estimated_amount_out > 0` | PASS | | `/route/solve/best` same class of fix (shared solver) | Covered by same `best_execution` path; concurrent fail-fast preserved for non-skippable errors | PASS | | Fail-fast for real errors preserved (#324) | `make verify-issue-369` → `cargo test concurrent_solve --lib` (7 tests) | PASS | | Full DB-hybrid suite unaffected | `cd indexer && cargo test --test api_route_solve_db_hybrid -- --test-threads=1` (4 tests) | PASS | ## Test plan - [x] `make setup-indexer-postgres` - [x] `make verify-issue-369` - [x] `cd indexer && cargo test --test api_route_solve_db_hybrid -- --test-threads=1` Related to #369 (issue stays open until merge). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Indexer changes affect live route/solve quoting; trade routing changes are localized but touch deep-link and notice UX. > > **Overview** > **Indexer (#369):** DB-hybrid route/solve now **drops** path candidates whose mirror simulation returns `InsufficientLiquidity` (zero-reserve pool leg), same as unusable liquidity—so a healthy direct route can win instead of surfacing a fatal gateway error. Fatal simulation errors still fail-fast when every candidate is non-skippable. The integration regression was refactored to use shared seed helpers; the QA script adds a `concurrent_solve` lib check and renames the integration step. > > **Trade page:** Invalid or “pair not found” banners that lived in **router location state** now clear when the user picks a valid factory pair or navigates to a known deep link: navigation uses **`state: null`** and replaces the URL to the pair route. Pair selection from the dropdown does the same. New tests cover both flows. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit ca588549dc27f853ca0db1795fe492e947de371e. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
ghost1 commented 2026-06-12 11:09:50 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-12 11:09:57 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-12 11:12:14 +00:00 (Migrated from gitlab.com)

Security review — MR !885

Commit reviewed: 6b08868396af3f8ab12e13bbcedc73c9b16acbbd

Scope: DB-hybrid route/solve error-handling change in indexer/src/api/best_execution.rs — evaluate_candidate now returns Ok(None) when mirror simulation hits DbSimError::InsufficientLiquidity (zero-reserve pool leg with pool_input > 0), concurrent fan-out schedules remaining candidates on skip, and all-skipped paths yield 404 instead of aborting the whole request with 502. Also adds integration test + verify-issue-369 QA script.

Method: Traced attacker-controlled inputs (token_in, token_out, amount_in, trader/sender) through enumerate_path_candidates → run_concurrent_candidate_evaluations → evaluate_candidate → optimize_multihop_hybrid_joint → simulate_pool_leg. Verified only literal zero reserves (reserve_0 == 0 || reserve_1 == 0) with a non-zero pool leg trigger the skip; book-only grid splits (pool_input == 0) do not. Confirmed other DbSimError variants and LCD failures still fail-fast to 502 (#324). Winning candidate still passes maybe_simulate and apply_fidelity_guard.

Outcome: FINDINGS: 0 medium+

Security review: no medium+ findings on this diff.

No inline security threads — nothing to block on.

## Security review — MR !885 **Commit reviewed:** `6b08868396af3f8ab12e13bbcedc73c9b16acbbd` **Scope:** DB-hybrid route/solve error-handling change in `indexer/src/api/best_execution.rs` — `evaluate_candidate` now returns `Ok(None)` when mirror simulation hits `DbSimError::InsufficientLiquidity` (zero-reserve pool leg with `pool_input > 0`), concurrent fan-out schedules remaining candidates on skip, and all-skipped paths yield **404** instead of aborting the whole request with **502**. Also adds integration test + `verify-issue-369` QA script. **Method:** Traced attacker-controlled inputs (`token_in`, `token_out`, `amount_in`, trader/sender) through `enumerate_path_candidates` → `run_concurrent_candidate_evaluations` → `evaluate_candidate` → `optimize_multihop_hybrid_joint` → `simulate_pool_leg`. Verified only literal zero reserves (`reserve_0 == 0 || reserve_1 == 0`) with a non-zero pool leg trigger the skip; book-only grid splits (`pool_input == 0`) do not. Confirmed other `DbSimError` variants and LCD failures still fail-fast to **502** (#324). Winning candidate still passes `maybe_simulate` and `apply_fidelity_guard`. **Outcome:** `FINDINGS: 0` medium+ Security review: **no medium+ findings** on this diff. No inline security threads — nothing to block on.
PlasticDigits commented 2026-06-12 11:21:02 +00:00 (Migrated from gitlab.com)

added 55 commits

  • 6b088683...0cf04e53 - 54 commits from branch main
  • 0e834707 - Merge origin/main into fix/indexer-route-solve-zero-reserve-path-369

Compare with previous version

added 55 commits <ul><li>6b088683...0cf04e53 - 54 commits from branch <code>main</code></li><li>0e834707 - Merge origin/main into fix/indexer-route-solve-zero-reserve-path-369</li></ul> [Compare with previous version](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/167/diffs?diff_id=1848898297&start_sha=6b08868396af3f8ab12e13bbcedc73c9b16acbbd)
PlasticDigits commented 2026-06-12 11:21:07 +00:00 (Migrated from gitlab.com)

Resolved merge conflicts with main:

  • best_execution.rs — kept main's PathUnusable / zero grid_out candidate skip and partial gateway-error handling; retained MR InsufficientLiquidity skip for zero-reserve pool legs.
  • api_route_solve_db_hybrid.rs — dropped duplicate #369 test (kept route_solve_db_hybrid_skips_zero_reserve_path_candidate with seed_route_solve_zero_reserve_poison).
  • verify-issue-369.sh — merged QA steps from both sides (lib + integration).

Pushed merge commit 0e83470.

Resolved merge conflicts with `main`: - **best_execution.rs** — kept main's `PathUnusable` / zero `grid_out` candidate skip and partial gateway-error handling; retained MR `InsufficientLiquidity` skip for zero-reserve pool legs. - **api_route_solve_db_hybrid.rs** — dropped duplicate #369 test (kept `route_solve_db_hybrid_skips_zero_reserve_path_candidate` with `seed_route_solve_zero_reserve_poison`). - **verify-issue-369.sh** — merged QA steps from both sides (lib + integration). Pushed merge commit `0e83470`.
ghost1 commented 2026-06-12 11:21:21 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-12 11:22:23 +00:00 (Migrated from gitlab.com)

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issue.

Reviewed by Cursor Bugbot for commit 0e83470773. Configure here.

<!-- BUGBOT_REVIEW --> Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue. <!-- BUGBOT_FIX_ALL --> <a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9BTExfSU5fQ1VSU09SIiwiZGF0YSI6eyJyZWRpc0tleSI6ImJ1Z2JvdC1tdWx0aTozYzJlZTUzYy0xMDliLTQ3YTgtYmMzMS1iNjg3NjVlMWUxOTYiLCJlbmNyeXB0aW9uS2V5IjoibUNTU2dxRTU1WlNqWWpCNzNGVWxmWjA0U3p2dkMtRks2MC12OHc2UmVFSSIsImJyYW5jaCI6ImZpeC9pbmRleGVyLXJvdXRlLXNvbHZlLXplcm8tcmVzZXJ2ZS1wYXRoLTM2OSIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6ImNsOHktZGV4LXRlcnJhY2xhc3NpYyJ9fQ" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-cursor-light.png"><img alt="Fix All in Cursor" width="115" height="28" src="https://cursor.com/assets/images/fix-in-cursor-dark.png"></picture></a> <!-- /BUGBOT_FIX_ALL --> <!-- BUGBOT_AUTOFIX_REVIEW_FOOTNOTE_BEGIN --> <sup>Bugbot Autofix is [ON](https://www.cursor.com/dashboard/bugbot). A cloud agent has been kicked off to fix the reported issue. <!-- BUGBOT_AUTOFIX_AGENT_LINK --></sup> <!-- BUGBOT_AUTOFIX_REVIEW_FOOTNOTE_END --> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0e83470773e8d9855f91b1b477a4d5ec81ac1b93. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
ghost1 commented 2026-06-12 11:22:25 +00:00 (Migrated from gitlab.com)

Trade notice state not cleared

Medium Severity

After an invalid or unknown pair redirect, notices live in location.state instead of local state. Choosing a valid pair via onPairChange or loading a known factory deep link updates pairAddr but leaves invalidPair / unknownPair in location.state, so alerts stay visible and shouldShowTradeWorkspace keeps the book/chart/ticket hidden.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0e83470773. Configure here.

### Trade notice state not cleared **Medium Severity** <!-- DESCRIPTION START --> After an invalid or unknown pair redirect, notices live in `location.state` instead of local state. Choosing a valid pair via `onPairChange` or loading a known factory deep link updates `pairAddr` but leaves `invalidPair` / `unknownPair` in `location.state`, so alerts stay visible and `shouldShowTradeWorkspace` keeps the book/chart/ticket hidden. <!-- DESCRIPTION END --> <!-- BUGBOT_BUG_ID: 21f90784-628b-471f-b126-2a9230778e33 --> <!-- LOCATIONS START frontend-dapp/src/pages/TradePage.tsx#L149-L167 frontend-dapp/src/pages/TradePage.tsx#L321-L328 LOCATIONS END --> <details> <summary>Additional Locations (1)</summary> - [`frontend-dapp/src/pages/TradePage.tsx#L321-L328`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-//blob/0e83470773e8d9855f91b1b477a4d5ec81ac1b93/frontend-dapp/src/pages/TradePage.tsx#L321-L328) </details> <div><a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OjNjYmFmMzU0LTVkN2YtNGI3Ny05YjVhLWEyZmYzZmY5MTMxOCIsImVuY3J5cHRpb25LZXkiOiJsejVkbF85WExkS3NwbnhJZFRpa1duNVFySFU0clNyVGx5Z2IyMnRmaHF3IiwiYnJhbmNoIjoiZml4L2luZGV4ZXItcm91dGUtc29sdmUtemVyby1yZXNlcnZlLXBhdGgtMzY5IiwicmVwb093bmVyIjoiUGxhc3RpY0RpZ2l0cyIsInJlcG9OYW1lIjoiY2w4eS1kZXgtdGVycmFjbGFzc2ljIn19" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-cursor-light.png"><img alt="Fix in Cursor" width="115" height="28" src="https://cursor.com/assets/images/fix-in-cursor-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/agents?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OjNjYmFmMzU0LTVkN2YtNGI3Ny05YjVhLWEyZmYzZmY5MTMxOCIsImVuY3J5cHRpb25LZXkiOiJsejVkbF85WExkS3NwbnhJZFRpa1duNVFySFU0clNyVGx5Z2IyMnRmaHF3IiwiYnJhbmNoIjoiZml4L2luZGV4ZXItcm91dGUtc29sdmUtemVyby1yZXNlcnZlLXBhdGgtMzY5IiwicmVwb093bmVyIjoiUGxhc3RpY0RpZ2l0cyIsInJlcG9OYW1lIjoiY2w4eS1kZXgtdGVycmFjbGFzc2ljIiwicHJOdW1iZXIiOjE2NywiY29tbWl0U2hhIjoiMGU4MzQ3MDc3M2U4ZDk4NTVmOTFiMWI0NzdhNGQ1ZWM4MWFjMWI5MyIsInByb3ZpZGVyIjoiZ2l0bGFiIiwiaG9zdG5hbWUiOiJnaXRsYWIuY29tIn19" target="_blank" rel="noopener noreferrer"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/fix-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/fix-in-web-light.png"><img alt="Fix in Web" width="99" height="28" src="https://cursor.com/assets/images/fix-in-web-dark.png"></picture></a></div> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0e83470773e8d9855f91b1b477a4d5ec81ac1b93. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
PlasticDigits commented 2026-06-12 11:23:33 +00:00 (Migrated from gitlab.com)

Security review — MR !885

Commit reviewed: 0e83470773e8d9855f91b1b477a4d5ec81ac1b93

Scope: DB-hybrid route/solve candidate evaluation in indexer/src/api/best_execution.rs — evaluate_candidate now returns Ok(None) on HybridSimError::Db(DbSimError::InsufficientLiquidity) (zero-reserve pool leg), matching existing PathUnusable skip semantics; concurrent fan-out continues evaluating remaining candidates; all-skipped paths yield 404 instead of whole-request 502. Test/QA harness updates in indexer/tests/api_route_solve_db_hybrid.rs and scripts/qa/verify-issue-369.sh.

Method: Traced attacker-controlled inputs (token_in, token_out, amount_in, optional trader/sender) through enumerate_path_candidates → run_concurrent_candidate_evaluations → evaluate_candidate → optimize_multihop_hybrid_joint → simulate_pool_leg / mirror load. Confirmed InsufficientLiquidity is only raised for literal zero reserves (reserve_0 == 0 || reserve_1 == 0) with pool_input > 0, or MirrorFreshness::EmptyPool inside mirror sim; book-only grid splits (pool_input == 0) are unaffected. Verified other DbSimError variants (StaleMirror, MissingMirror, InvalidNumeric, etc.) and LCD infra failures still propagate via hybrid_sim_gateway_err → 502 when every evaluated candidate fails fatally (#324). Winning candidate still passes maybe_simulate (router LCD) and apply_fidelity_guard.

Outcome: FINDINGS: 0 medium+

Security review: no medium+ findings on this diff.

No inline security threads — nothing to block on.

## Security review — MR !885 **Commit reviewed:** `0e83470773e8d9855f91b1b477a4d5ec81ac1b93` **Scope:** DB-hybrid route/solve candidate evaluation in `indexer/src/api/best_execution.rs` — `evaluate_candidate` now returns `Ok(None)` on `HybridSimError::Db(DbSimError::InsufficientLiquidity)` (zero-reserve pool leg), matching existing `PathUnusable` skip semantics; concurrent fan-out continues evaluating remaining candidates; all-skipped paths yield **404** instead of whole-request **502**. Test/QA harness updates in `indexer/tests/api_route_solve_db_hybrid.rs` and `scripts/qa/verify-issue-369.sh`. **Method:** Traced attacker-controlled inputs (`token_in`, `token_out`, `amount_in`, optional `trader`/`sender`) through `enumerate_path_candidates` → `run_concurrent_candidate_evaluations` → `evaluate_candidate` → `optimize_multihop_hybrid_joint` → `simulate_pool_leg` / mirror load. Confirmed `InsufficientLiquidity` is only raised for literal zero reserves (`reserve_0 == 0 || reserve_1 == 0`) with `pool_input > 0`, or `MirrorFreshness::EmptyPool` inside mirror sim; book-only grid splits (`pool_input == 0`) are unaffected. Verified other `DbSimError` variants (`StaleMirror`, `MissingMirror`, `InvalidNumeric`, etc.) and LCD infra failures still propagate via `hybrid_sim_gateway_err` → **502** when every evaluated candidate fails fatally (#324). Winning candidate still passes `maybe_simulate` (router LCD) and `apply_fidelity_guard`. **Outcome:** `FINDINGS: 0` medium+ Security review: **no medium+ findings** on this diff. No inline security threads — nothing to block on.
ghost1 commented 2026-06-12 11:24:39 +00:00 (Migrated from gitlab.com)

added 1 commit

  • 19dce4fa - fix(frontend): clear trade link notices when selecting valid pair

Compare with previous version

added 1 commit <ul><li>19dce4fa - fix(frontend): clear trade link notices when selecting valid pair</li></ul> [Compare with previous version](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/167/diffs?diff_id=1848904902&start_sha=0e83470773e8d9855f91b1b477a4d5ec81ac1b93)
ghost1 commented 2026-06-12 11:24:54 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-12 11:45:47 +00:00 (Migrated from gitlab.com)

added 1 commit

  • ca588549 - test(frontend): cover trade link notice clearing on valid pair

Compare with previous version

added 1 commit <ul><li>ca588549 - test(frontend): cover trade link notice clearing on valid pair</li></ul> [Compare with previous version](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/167/diffs?diff_id=1848944757&start_sha=19dce4fa177fc6bdb1d79557b84d79e053f0eb94)
PlasticDigits commented 2026-06-12 11:45:50 +00:00 (Migrated from gitlab.com)

resolved all threads

resolved all threads
PlasticDigits commented 2026-06-12 11:45:54 +00:00 (Migrated from gitlab.com)

Fix bugfix — review thread resolution

Thread Fix
Trade notice state not cleared (Bugbot) Already fixed in 19dce4f: onPairChange passes { state: null }; known-factory deep-link effect replaces history with state: null when stale invalidPair/unknownPair notices are present. Added regression tests in ca58854 (TradePage.test.tsx: pair select after unknown link; deep link with stale notice).

Tests: TradePage.test.tsx (24/24 pass). Indexer lib checks from verify-issue-369 pass; integration step skipped here (Postgres pool unavailable in this VM).

Thread resolved; agent:fix_bugfix label removed.

## Fix bugfix — review thread resolution | Thread | Fix | |--------|-----| | **Trade notice state not cleared** (Bugbot) | Already fixed in `19dce4f`: `onPairChange` passes `{ state: null }`; known-factory deep-link effect replaces history with `state: null` when stale `invalidPair`/`unknownPair` notices are present. Added regression tests in `ca58854` (`TradePage.test.tsx`: pair select after unknown link; deep link with stale notice). | **Tests:** `TradePage.test.tsx` (24/24 pass). Indexer lib checks from `verify-issue-369` pass; integration step skipped here (Postgres pool unavailable in this VM). Thread resolved; `agent:fix_bugfix` label removed.
ghost1 commented 2026-06-12 11:46:06 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-12 11:48:22 +00:00 (Migrated from gitlab.com)

Security review — MR !885

Commit reviewed: ca588549dc27f853ca0db1795fe492e947de371e

Scope: Indexer DB-hybrid route/solve (evaluate_candidate skips DbSimError::InsufficientLiquidity zero-reserve path candidates; concurrent fan-out unchanged for fatal errors). Trade page UX (TradePage.tsx): clear stale invalidPair/unknownPair router location state via state: null when selecting a valid factory pair or landing on a known deep link. Test/QA harness updates (api_route_solve_db_hybrid.rs, verify-issue-369.sh, TradePage.test.tsx).

Method: Re-read prior security-review notes on this MR (commits 6b088683, 0e834707 — both FINDINGS: 0). Traced attacker-controlled inputs on /api/v1/route/solve (token_in, token_out, amount_in, trader, sender) through enumerate_path_candidates → run_concurrent_candidate_evaluations → evaluate_candidate → optimize_multihop_hybrid_joint → simulate_pool_leg / mirror load. Confirmed InsufficientLiquidity is only raised for literal zero reserves (reserve_0 == 0 || reserve_1 == 0) with pool_input > 0, or MirrorFreshness::EmptyPool inside mirror sim; other DbSimError variants and LCD infra failures still fail-fast to 502 when every evaluated candidate is fatal (#324). Winning candidate still passes maybe_simulate and apply_fidelity_guard. Reviewed new frontend navigation: routePair/addr gated by isKnownFactoryTradePair / isTradePairRouteParam (isValidTerraAddress); no open redirect, injection, or XSS introduced by state: null clears (notice values remain React text nodes).

Outcome: FINDINGS: 0 medium+

Security review: no medium+ findings on this diff.

No inline security threads — nothing to block on.

## Security review — MR !885 **Commit reviewed:** `ca588549dc27f853ca0db1795fe492e947de371e` **Scope:** Indexer DB-hybrid route/solve (`evaluate_candidate` skips `DbSimError::InsufficientLiquidity` zero-reserve path candidates; concurrent fan-out unchanged for fatal errors). Trade page UX (`TradePage.tsx`): clear stale `invalidPair`/`unknownPair` router location state via `state: null` when selecting a valid factory pair or landing on a known deep link. Test/QA harness updates (`api_route_solve_db_hybrid.rs`, `verify-issue-369.sh`, `TradePage.test.tsx`). **Method:** Re-read prior security-review notes on this MR (commits `6b088683`, `0e834707` — both `FINDINGS: 0`). Traced attacker-controlled inputs on `/api/v1/route/solve` (`token_in`, `token_out`, `amount_in`, `trader`, `sender`) through `enumerate_path_candidates` → `run_concurrent_candidate_evaluations` → `evaluate_candidate` → `optimize_multihop_hybrid_joint` → `simulate_pool_leg` / mirror load. Confirmed `InsufficientLiquidity` is only raised for literal zero reserves (`reserve_0 == 0 || reserve_1 == 0`) with `pool_input > 0`, or `MirrorFreshness::EmptyPool` inside mirror sim; other `DbSimError` variants and LCD infra failures still fail-fast to **502** when every evaluated candidate is fatal (#324). Winning candidate still passes `maybe_simulate` and `apply_fidelity_guard`. Reviewed new frontend navigation: `routePair`/`addr` gated by `isKnownFactoryTradePair` / `isTradePairRouteParam` (`isValidTerraAddress`); no open redirect, injection, or XSS introduced by `state: null` clears (notice values remain React text nodes). **Outcome:** `FINDINGS: 0` medium+ Security review: **no medium+ findings** on this diff. No inline security threads — nothing to block on.
PlasticDigits commented 2026-06-12 11:49:47 +00:00 (Migrated from gitlab.com)

mentioned in commit d269d11312

mentioned in commit d269d11312b5c947d2c3f11ffa63b2f025871170
PlasticDigits (Migrated from gitlab.com) merged commit d269d11312 into main 2026-06-12 11:49:47 +00:00
Sign in to join this conversation.
No reviewers
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!885
No description provided.