fix(indexer): skip zero-reserve path candidates in DB-hybrid route/solve (#369) #885
No reviewers
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:implement
agent:implement
agent:open_issues
agent:ready
agent:research
agent:security_audit
agent:verify
architecture
backend
blocker:hybrid
blocker:launch
blocker:limit-orders
blocker:v2
block:log_only
block:security
bug
ci
contracts
correctness
deploy
dev
devops
docs
documentation
duplicate
e2e
enhancement
epic
feature
frontend
functional-completion
gas
good first issue
governance
help wanted
high-risk
hooks
hybrid
indexer
infra
infrastructure
integrators
invalid
launch-blocker
limit-orders
localnet
localterra
low priority
missing-implementation
needs-design
ops
performance
priority
high
priority
medium
product
qa
QA
question
ready
ready
research
scripts
security
security-hardening
smartcontracts
tech-debt
testing
ux
UX
v2
verification
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/cl8y-dex-terraclassic!885
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/indexer-route-solve-zero-reserve-path-369"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
route/solveno longer returns 502 "Route mirror simulation failed" when a path candidate touches a zero-reserve pair but a viable direct route exists.evaluate_candidateskips candidates whose mirror sim hitsInsufficientLiquidity(empty pool); fatal errors still fail-fast per #324.make verify-issue-369, and QA scriptscripts/qa/verify-issue-369.sh.Verification checklist
make verify-issue-369→ integration test seeds multi-path with zero B↔C reserves, healthy direct A↔C;GET /api/v1/route/solvereturns 200, 1-hop direct pair,estimated_amount_out > 0/route/solve/bestsame class of fix (shared solver)best_executionpath; concurrent fail-fast preserved for non-skippable errorsmake verify-issue-369→cargo test concurrent_solve --lib(7 tests)cd indexer && cargo test --test api_route_solve_db_hybrid -- --test-threads=1(4 tests)Test plan
make setup-indexer-postgresmake verify-issue-369cd indexer && cargo test --test api_route_solve_db_hybrid -- --test-threads=1Related to #369 (issue stays open until merge).
changed the description
changed the description
Security review — MR !885
Commit reviewed:
6b08868396af3f8ab12e13bbcedc73c9b16acbbdScope: DB-hybrid route/solve error-handling change in
indexer/src/api/best_execution.rs—evaluate_candidatenow returnsOk(None)when mirror simulation hitsDbSimError::InsufficientLiquidity(zero-reserve pool leg withpool_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-369QA script.Method: Traced attacker-controlled inputs (
token_in,token_out,amount_in, trader/sender) throughenumerate_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 otherDbSimErrorvariants and LCD failures still fail-fast to 502 (#324). Winning candidate still passesmaybe_simulateandapply_fidelity_guard.Outcome:
FINDINGS: 0medium+Security review: no medium+ findings on this diff.
No inline security threads — nothing to block on.
added 55 commits
main0e834707- Merge origin/main into fix/indexer-route-solve-zero-reserve-path-369Compare with previous version
Resolved merge conflicts with
main:PathUnusable/ zerogrid_outcandidate skip and partial gateway-error handling; retained MRInsufficientLiquidityskip for zero-reserve pool legs.route_solve_db_hybrid_skips_zero_reserve_path_candidatewithseed_route_solve_zero_reserve_poison).Pushed merge commit
0e83470.changed the description
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
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.Trade notice state not cleared
Medium Severity
After an invalid or unknown pair redirect, notices live in
location.stateinstead of local state. Choosing a valid pair viaonPairChangeor loading a known factory deep link updatespairAddrbut leavesinvalidPair/unknownPairinlocation.state, so alerts stay visible andshouldShowTradeWorkspacekeeps the book/chart/ticket hidden.Additional Locations (1)
frontend-dapp/src/pages/TradePage.tsx#L321-L328Reviewed by Cursor Bugbot for commit
0e83470773. Configure here.Security review — MR !885
Commit reviewed:
0e83470773e8d9855f91b1b477a4d5ec81ac1b93Scope: DB-hybrid route/solve candidate evaluation in
indexer/src/api/best_execution.rs—evaluate_candidatenow returnsOk(None)onHybridSimError::Db(DbSimError::InsufficientLiquidity)(zero-reserve pool leg), matching existingPathUnusableskip semantics; concurrent fan-out continues evaluating remaining candidates; all-skipped paths yield 404 instead of whole-request 502. Test/QA harness updates inindexer/tests/api_route_solve_db_hybrid.rsandscripts/qa/verify-issue-369.sh.Method: Traced attacker-controlled inputs (
token_in,token_out,amount_in, optionaltrader/sender) throughenumerate_path_candidates→run_concurrent_candidate_evaluations→evaluate_candidate→optimize_multihop_hybrid_joint→simulate_pool_leg/ mirror load. ConfirmedInsufficientLiquidityis only raised for literal zero reserves (reserve_0 == 0 || reserve_1 == 0) withpool_input > 0, orMirrorFreshness::EmptyPoolinside mirror sim; book-only grid splits (pool_input == 0) are unaffected. Verified otherDbSimErrorvariants (StaleMirror,MissingMirror,InvalidNumeric, etc.) and LCD infra failures still propagate viahybrid_sim_gateway_err→ 502 when every evaluated candidate fails fatally (#324). Winning candidate still passesmaybe_simulate(router LCD) andapply_fidelity_guard.Outcome:
FINDINGS: 0medium+Security review: no medium+ findings on this diff.
No inline security threads — nothing to block on.
added 1 commit
19dce4fa- fix(frontend): clear trade link notices when selecting valid pairCompare with previous version
changed the description
added 1 commit
ca588549- test(frontend): cover trade link notice clearing on valid pairCompare with previous version
resolved all threads
Fix bugfix — review thread resolution
19dce4f:onPairChangepasses{ state: null }; known-factory deep-link effect replaces history withstate: nullwhen staleinvalidPair/unknownPairnotices are present. Added regression tests inca58854(TradePage.test.tsx: pair select after unknown link; deep link with stale notice).Tests:
TradePage.test.tsx(24/24 pass). Indexer lib checks fromverify-issue-369pass; integration step skipped here (Postgres pool unavailable in this VM).Thread resolved;
agent:fix_bugfixlabel removed.changed the description
Security review — MR !885
Commit reviewed:
ca588549dc27f853ca0db1795fe492e947de371eScope: Indexer DB-hybrid route/solve (
evaluate_candidateskipsDbSimError::InsufficientLiquidityzero-reserve path candidates; concurrent fan-out unchanged for fatal errors). Trade page UX (TradePage.tsx): clear staleinvalidPair/unknownPairrouter location state viastate: nullwhen 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— bothFINDINGS: 0). Traced attacker-controlled inputs on/api/v1/route/solve(token_in,token_out,amount_in,trader,sender) throughenumerate_path_candidates→run_concurrent_candidate_evaluations→evaluate_candidate→optimize_multihop_hybrid_joint→simulate_pool_leg/ mirror load. ConfirmedInsufficientLiquidityis only raised for literal zero reserves (reserve_0 == 0 || reserve_1 == 0) withpool_input > 0, orMirrorFreshness::EmptyPoolinside mirror sim; otherDbSimErrorvariants and LCD infra failures still fail-fast to 502 when every evaluated candidate is fatal (#324). Winning candidate still passesmaybe_simulateandapply_fidelity_guard. Reviewed new frontend navigation:routePair/addrgated byisKnownFactoryTradePair/isTradePairRouteParam(isValidTerraAddress); no open redirect, injection, or XSS introduced bystate: nullclears (notice values remain React text nodes).Outcome:
FINDINGS: 0medium+Security review: no medium+ findings on this diff.
No inline security threads — nothing to block on.
mentioned in commit
d269d11312