feat(#293): route-based expected slippage + Expert Mode retail guard #828
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!828
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "cursor/gitlab-issue-workflow-3ed3"
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
Implements GitLab #293 follow-up: classify excessive route slippage as a retail UX bug, show expected slippage from best-route token valuations, and gate high-slippage swaps behind Expert Mode (default off).
Indexer
route_slippagemodule values each token via global best-execution solve → USTC-C/LUNC-C quote asset (30s cache).GET/POST /api/v1/route/solveresponses now include optionalspot_amount_out,slippage_percent,token_in_price_quote,token_out_price_quote.Frontend (Swap)
Docs
docs/swap-max-spread-ux.mdinvariant #7 + cross-links.skills/AGENTS_FRONTEND_SWAP_ROUTE_DISPLAY.mdupdated.Acceptance checklist
cd indexer && cargo test --lib route_slippagecd indexer && cargo test --libcd frontend-dapp && npm run test:run -- src/utils/swapRouteSlippage.test.ts src/pages/SwapPage.test.tsxblocks swap above 30% route slippagemake dev, enter 1 EMBER→CORALmake verify-issue-293swarm quotesmake verify-issue-293Verification for third parties
make setup-cloud-localterra(or existing LocalTerra + indexer).1.curl 'http://127.0.0.1:3001/api/v1/route/solve?token_in=<EMBER>&token_out=<CORAL>&amount_in=1000000'includesslippage_percentandspot_amount_out.Issue left open pending live QA on LocalTerra.
changed the description
mentioned in issue #293
changed the description
Stale Security Review comment
Cursor Bugbot has reviewed your changes and found 4 potential issues.
Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issues.
Reviewed by Cursor Bugbot for commit
081e80e940. Configure here.Token price cache ignores trader
Medium Severity
Reference token prices are cached under only
token→quote, buttoken_price_in_quoteruns best-execution with the requestquote_trader(fee tier / discount). Later requests with a different trader reuse the first price for 30s, soslippage_percentand Expert Mode blocking can be wrong for discounted wallets.Reviewed by Cursor Bugbot for commit
081e80e940. Configure here.Indexer slippage, wallet receive
Medium Severity
The trade summary shows
return_amountfrom walletsimulateMultiHopSwap, but Expected slippage and Expert Mode blocking useidx.slippage_percentfrom the indexer, which is computed against the indexer’sestimated_amount_out. If LCD wallet sim and indexer output diverge, users see one receive amount while guards and labels reflect another quote.Reviewed by Cursor Bugbot for commit
081e80e940. Configure here.Token prices use fixed makers
Low Severity
Token reference prices always call best execution with
max_maker_fillshardcoded to8, while the user’s swap solve useshybridMaxMakersfrom Settings. Different maker-fill limits change hybrid quotes, so expected slippage can disagree with the route actually being priced.Reviewed by Cursor Bugbot for commit
081e80e940. Configure here.Cached slippage wrong trade size
Medium Severity
Hybrid
GET /api/v1/route/solvecaches the full solve JSON (including newslippage_percent/spot_amount_out) by coarseamount_inbucket. Cache hits return slippage computed for a different raw amount than the request, so Expected slippage and the >30% Expert Mode block can be incorrect.Additional Locations (1)
indexer/src/api/route_solver.rs#L725-L727Reviewed by Cursor Bugbot for commit
081e80e940. Configure here.Security review
Commit reviewed:
081e80e9403f3171322ed060a6c66614c0a2f3e5Scope: MR !828 — route-based expected slippage (
indexer/src/api/route_slippage.rs,route_solver.rs,best_execution.rs) and Swap Expert Mode retail guard (SwapPage.tsx,expertMode.ts,swapRouteSlippage.ts).Outcome:
FINDINGS: 0medium+Summary: No medium, high, or critical vulnerabilities identified on this diff.
Reviewed areas:
enrich_route_slippageadds up to two cached (30s)solve_global_best_execution_innercalls per/api/v1/route/solverequest (enrich_slippage: falseprevents recursion). This increases LCD work within the existing LCD-heavy rate limit (RATE_LIMIT_LCD_HEAVY_RPS, default 10) already applied to route solve; no bypass or unbounded amplification path found.max_spread/min_returnenforcement unchanged. Not a security boundary — direct contract interaction remains possible by design.slippage_percentis parsed withparseFloat+Number.isFinitebefore display; React text rendering (nodangerouslySetInnerHTML). No XSS or injection sink.Cargo.toml/package.jsonchanges in this diff.Inline threads: None (no findings to anchor).
Prior security-review comments on this MR: none to re-report.
changed this line in version 2 of the diff
added 1 commit
977adae9- Fix slippage cache keys, cache-hit recomputation, and wallet-aligned UICompare with previous version
changed the description
resolved all threads
Cursor Bugbot has reviewed your changes 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
977adae9c8. Configure here.Cached route slippage amount mismatch
Medium Severity
On a hybrid GET cache hit,
enrich_route_slippageruns with the caller’samount_inbut still uses the cachedestimated_amount_outfrom an earlier solve. Amounts in the same coarse bucket (e.g. 1.5M vs 1.9M raw) share a cache key, soslippage_percentcan disagree withspot_amount_outand misstate route slippage for API consumers.Additional Locations (1)
indexer/src/api/route_slippage.rs#L188-L253Reviewed by Cursor Bugbot for commit
977adae9c8. Configure here.Security review
Commit reviewed:
977adae9c8dc97179a4de04849f25a6f0be04c68Scope: MR !828 (re-review after fix commit) — route-based expected slippage (
indexer/src/api/route_slippage.rs,route_solver.rs,best_execution.rs) and Swap Expert Mode retail guard (SwapPage.tsx,expertMode.ts,swapRouteSlippage.ts).Outcome:
FINDINGS: 0medium+Summary: Security review: no medium, high, or critical vulnerabilities identified on this diff.
Changes since prior review (
081e80e):discount_bpsandmax_maker_fills(route_slippage.rs:137).enrich_route_slippagewith the requestamount_in(route_solver.rs:729-735).simulateMultiHopSwapreceive vs indexerspot_amount_out(swapRouteSlippage.ts:26-36,SwapPage.tsx:486-490).These address correctness/UX alignment; they do not introduce new attacker-controlled sinks or bypass on-chain enforcement.
Reviewed areas (unchanged from prior pass):
enrich_route_slippageadds up to two cached (30s)solve_global_best_execution_innercalls per/api/v1/route/solverequest (enrich_slippage: falseprevents recursion). Work stays within existing LCD-heavy rate limit (RATE_LIMIT_LCD_HEAVY_RPS, default 10).max_spread/min_returnunchanged. Direct contract interaction remains possible by design — not a security boundary.slippage_percentparsed withparseFloat+Number.isFinite; React text rendering only (nodangerouslySetInnerHTML). No XSS or injection sink.Cargo.toml/package.jsonchanges in this MR.Inline threads: None (no findings to anchor).
Prior security-review comment on
081e80e: superseded by this re-review; no prior medium+ findings to re-report.added 1 commit
443e8af8- Fix cached hybrid route slippage when amount differs within bucketCompare with previous version
changed the description
resolved all threads
Security review
Commit reviewed:
443e8af85f2ceb4985494bed3bcbff4d4344d4caScope: MR !828 — route-based expected slippage (
indexer/src/api/route_slippage.rs,route_solver.rs,best_execution.rs) and Swap Expert Mode retail guard (SwapPage.tsx,expertMode.ts,swapRouteSlippage.ts).Outcome:
FINDINGS: 0medium+Summary: Security review: no medium, high, or critical vulnerabilities identified on this diff.
Changes since prior review (
977adae9):amount_inand scalesestimated_amount_outlinearly when enriching slippage on bucket cache hits (route_solver.rs,route_slippage.rs). Correctness fix only; no new attacker-controlled sinks.Reviewed areas:
enrich_route_slippageadds up to two cached (30s)solve_global_best_execution_innercalls per/api/v1/route/solverequest (enrich_slippage: falseprevents recursion). Work stays within existing LCD-heavy rate limit (RATE_LIMIT_LCD_HEAVY_RPS, default 10). Price cache keys includediscount_bpsandmax_maker_fills.max_spread/min_returnenforcement unchanged. Direct contract interaction remains possible by design — not a security boundary.slippage_percentparsed withparseFloat+Number.isFinite; displayed via React text nodes (nodangerouslySetInnerHTML). No XSS or injection sink.terra1bech32; amounts parsed asu128. Enrich failures fail silently (no new error bodies or internal path leakage).Cargo.toml/package.jsonchanges in this MR.Inline threads: None (no findings to anchor).
Prior security-review comments on
081e80e/977adae9: superseded; no medium+ findings to re-report.mentioned in commit
494f5bb626mentioned in commit
3221d74949mentioned in commit
666dcf105e