fix(#328): degraded pair search typed fallback + seed token names for QA #812

Merged
PlasticDigits merged 5 commits from cursor/gitlab-issue-workflow-4e2c into main 2026-06-05 14:33:26 +00:00
PlasticDigits commented 2026-06-05 13:56:13 +00:00 (Migrated from gitlab.com)

Summary

Fixes #328 — follow-up to #314 pair search combobox.

What changed

  1. Degraded typed search (frontend) — Rich per-pair haystack (menu label + addresses + localStorage-cached CW20 symbol/name + registry). When the indexer is down, typing EMBER matches factory pairs if token metadata was cached from a prior on-chain read. PairSearchSelect shows a dim Offline search hint in degraded mode.
  2. Indexer token names (QA tier 2) — resolve_asset re-fetches CW20 token_info and upserts when an existing DB row has empty name or symbol.
  3. Merge with main — Combined main’s sticky indexer-unavailable fallback and two-token XXX YYY / XXX/YYY pair queries with #328 haystack search.

Acceptance checklist

Criterion Verification Result
Merge conflicts with main resolved git merge origin/main on branch PASS
Indexer stopped + typed EMBER returns factory matches PairSearchSelect.degraded.test.tsx PASS
Sticky degraded mode + two-token pair queries PairSearchSelect.test.tsx, pairSearchQuery.test.ts (17 tests) PASS
Indexer healthy path unchanged No local filter when API succeeds PASS
Indexer compiles cargo check (indexer) PASS
Post-deploy q=Ember tier 2/3 hits ./scripts/qa/verify-issue-328.sh layer 2 SKIP (no indexer on agent VM)
#314 matrix re-run Manual after merge + LocalTerra QA SKIP (post-merge)

Third-party verification

cd frontend-dapp && npm run test:run -- src/utils/__tests__/pairSearchQuery.test.ts src/components/trade/__tests__/PairSearchSelect.degraded.test.tsx src/components/trade/__tests__/PairSearchSelect.test.tsx
cd indexer && cargo check
./scripts/qa/verify-issue-328.sh

Closes #328

Related: #314

## Summary Fixes [#328](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/328) — follow-up to #314 pair search combobox. ### What changed 1. **Degraded typed search (frontend)** — Rich per-pair haystack (menu label + addresses + localStorage-cached CW20 symbol/name + registry). When the indexer is down, typing `EMBER` matches factory pairs if token metadata was cached from a prior on-chain read. `PairSearchSelect` shows a dim **Offline search** hint in degraded mode. 2. **Indexer token names (QA tier 2)** — `resolve_asset` re-fetches CW20 `token_info` and upserts when an existing DB row has empty `name` or `symbol`. 3. **Merge with `main`** — Combined main’s sticky indexer-unavailable fallback and two-token `XXX YYY` / `XXX/YYY` pair queries with #328 haystack search. ## Acceptance checklist | Criterion | Verification | Result | |-----------|--------------|--------| | Merge conflicts with `main` resolved | `git merge origin/main` on branch | **PASS** | | Indexer stopped + typed `EMBER` returns factory matches | `PairSearchSelect.degraded.test.tsx` | **PASS** | | Sticky degraded mode + two-token pair queries | `PairSearchSelect.test.tsx`, `pairSearchQuery.test.ts` (17 tests) | **PASS** | | Indexer healthy path unchanged | No local filter when API succeeds | **PASS** | | Indexer compiles | `cargo check` (indexer) | **PASS** | | Post-deploy `q=Ember` tier 2/3 hits | `./scripts/qa/verify-issue-328.sh` layer 2 | **SKIP** (no indexer on agent VM) | | #314 matrix re-run | Manual after merge + LocalTerra QA | **SKIP** (post-merge) | ## Third-party verification ```bash cd frontend-dapp && npm run test:run -- src/utils/__tests__/pairSearchQuery.test.ts src/components/trade/__tests__/PairSearchSelect.degraded.test.tsx src/components/trade/__tests__/PairSearchSelect.test.tsx cd indexer && cargo check ./scripts/qa/verify-issue-328.sh ``` Closes #328 Related: #314
ghost1 commented 2026-06-05 13:56:21 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-05 13:56:22 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-05 13:56:23 +00:00 (Migrated from gitlab.com)

mentioned in issue #328

mentioned in issue #328
ghost1 commented 2026-06-05 13:56:29 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-05 13:57:15 +00:00 (Migrated from gitlab.com)
Stale Security Review comment
Stale Security Review comment

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 fd54fb6ce2. Configure here.

<details> <summary>Stale Security Review comment</summary> <details> <summary>Stale Security Review comment</summary> <!-- BUGBOT_REVIEW --> Cursor Bugbot has reviewed your changes and found 1 potential issue.<!-- 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 fd54fb6ce27308d55471c0ac66e85f6f3b82eb01. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> </details> </details>
ghost1 commented 2026-06-05 13:57:16 +00:00 (Migrated from gitlab.com)

LCD failure blocks partial assets

Medium Severity

When a CW20 row exists but name or symbol is blank, resolve_asset always re-queries LCD. Any LCD/token_info error now fails resolution entirely instead of returning the existing asset id, so pair discovery and swap indexing can stop for pairs that previously indexed with partial metadata.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fd54fb6ce2. Configure here.

### LCD failure blocks partial assets **Medium Severity** <!-- DESCRIPTION START --> When a CW20 row exists but `name` or `symbol` is blank, `resolve_asset` always re-queries LCD. Any LCD/`token_info` error now fails resolution entirely instead of returning the existing asset id, so pair discovery and swap indexing can stop for pairs that previously indexed with partial metadata. <!-- DESCRIPTION END --> <!-- BUGBOT_BUG_ID: 335adad4-e245-45e7-96cd-811e17b7aafb --> <!-- LOCATIONS START indexer/src/indexer/asset_resolver.rs#L15-L28 LOCATIONS END --> <div><a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OmI2Yjg4OTY1LWYyNzAtNGI5NC04OGMzLWE1YmE4ZDY5Njc5ZSIsImVuY3J5cHRpb25LZXkiOiJ5OS1YRmNndlFvdmozZm1zQzNCNEtrdFpNV1YzM0tMMVJ4cDcwRkN1Z1k4IiwiYnJhbmNoIjoiY3Vyc29yL2dpdGxhYi1pc3N1ZS13b3JrZmxvdy00ZTJjIiwicmVwb093bmVyIjoiUGxhc3RpY0RpZ2l0cyIsInJlcG9OYW1lIjoiY2w4eS1kZXgtdGVycmFjbGFzc2ljIn19" 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=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OmI2Yjg4OTY1LWYyNzAtNGI5NC04OGMzLWE1YmE4ZDY5Njc5ZSIsImVuY3J5cHRpb25LZXkiOiJ5OS1YRmNndlFvdmozZm1zQzNCNEtrdFpNV1YzM0tMMVJ4cDcwRkN1Z1k4IiwiYnJhbmNoIjoiY3Vyc29yL2dpdGxhYi1pc3N1ZS13b3JrZmxvdy00ZTJjIiwicmVwb093bmVyIjoiUGxhc3RpY0RpZ2l0cyIsInJlcG9OYW1lIjoiY2w4eS1kZXgtdGVycmFjbGFzc2ljIiwicHJOdW1iZXIiOjk0LCJjb21taXRTaGEiOiJmZDU0ZmI2Y2UyNzMwOGQ1NTQ3MWMwYWM2NmU4NWY2ZjNiODJlYjAxIiwicHJvdmlkZXIiOiJnaXRsYWIiLCJob3N0bmFtZSI6ImdpdGxhYi5jb20ifX0" 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 fd54fb6ce27308d55471c0ac66e85f6f3b82eb01. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
ghost1 commented 2026-06-05 13:58:59 +00:00 (Migrated from gitlab.com)

added 1 commit

  • 5e81f6f3 - fix(indexer): fall back to existing asset id when LCD refresh fails

Compare with previous version

added 1 commit <ul><li>5e81f6f3 - fix(indexer): fall back to existing asset id when LCD refresh fails</li></ul> [Compare with previous version](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/94/diffs?diff_id=1836861640&start_sha=fd54fb6ce27308d55471c0ac66e85f6f3b82eb01)
PlasticDigits commented 2026-06-05 13:59:04 +00:00 (Migrated from gitlab.com)

Security review

Commit reviewed: fd54fb6ce27308d55471c0ac66e85f6f3b82eb01
Scope: MR !812 — degraded pair search haystack fallback (pairSearchQuery.ts, PairSearchSelect.tsx, tokenDisplay.ts), indexer resolve_asset metadata refresh (asset_resolver.rs), QA script/docs.

Outcome: FINDINGS: 0 medium+

Areas reviewed

Area Assessment
XSS / HTML injection Haystack text is used only for client-side includes() filtering; rendered option labels still come from pairInfoMenuLabel / React text nodes ({opt.label}), not haystack content. No new dangerouslySetInnerHTML or HTML sinks.
localStorage cache poisoning getCachedTokenEntry reads same-origin cl8y-dex-token-info cache (pre-existing write path via on-chain token_info). Poisoning requires prior same-origin compromise (XSS). Degraded search results are still gated to factoryPairs / factorySet; selected value is a factory-registered pair address, not attacker-supplied haystack text.
Injection (SQL / shell) Indexer upsert_asset and pair list filters remain parameterized (push_bind). QA script verify-issue-328.sh is operator-run tooling only.
SSRF / LCD amplification resolve_asset LCD query_contract calls use operator-configured endpoints with on-chain contract_addr from pair discovery — not user HTTP input. Extra refresh when DB name/symbol are empty is bounded to assets already referenced by indexed pairs.
Authn / authz No new API routes or permission boundaries changed.

Prior threads

No prior security-review inline comments on this MR. Bugbot’s LCD partial-metadata availability note (reliability regression, not an attacker-controlled exploit path) was considered out of scope for medium+ security findings.

Inline threads: none (no medium+ findings).

## Security review **Commit reviewed:** `fd54fb6ce27308d55471c0ac66e85f6f3b82eb01` **Scope:** MR !812 — degraded pair search haystack fallback (`pairSearchQuery.ts`, `PairSearchSelect.tsx`, `tokenDisplay.ts`), indexer `resolve_asset` metadata refresh (`asset_resolver.rs`), QA script/docs. **Outcome:** `FINDINGS: 0` medium+ ### Areas reviewed | Area | Assessment | |------|------------| | **XSS / HTML injection** | Haystack text is used only for client-side `includes()` filtering; rendered option labels still come from `pairInfoMenuLabel` / React text nodes (`{opt.label}`), not haystack content. No new `dangerouslySetInnerHTML` or HTML sinks. | | **localStorage cache poisoning** | `getCachedTokenEntry` reads same-origin `cl8y-dex-token-info` cache (pre-existing write path via on-chain `token_info`). Poisoning requires prior same-origin compromise (XSS). Degraded search results are still gated to `factoryPairs` / `factorySet`; selected `value` is a factory-registered pair address, not attacker-supplied haystack text. | | **Injection (SQL / shell)** | Indexer `upsert_asset` and pair list filters remain parameterized (`push_bind`). QA script `verify-issue-328.sh` is operator-run tooling only. | | **SSRF / LCD amplification** | `resolve_asset` LCD `query_contract` calls use operator-configured endpoints with on-chain `contract_addr` from pair discovery — not user HTTP input. Extra refresh when DB name/symbol are empty is bounded to assets already referenced by indexed pairs. | | **Authn / authz** | No new API routes or permission boundaries changed. | ### Prior threads No prior security-review inline comments on this MR. Bugbot’s LCD partial-metadata availability note (reliability regression, not an attacker-controlled exploit path) was considered out of scope for medium+ security findings. **Inline threads:** none (no medium+ findings).
ghost1 commented 2026-06-05 13:59:12 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-05 13:59:16 +00:00 (Migrated from gitlab.com)

resolved all threads

resolved all threads
ghost1 commented 2026-06-05 14:00:47 +00:00 (Migrated from gitlab.com)
Stale Security Review comment

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 5e81f6f3bd. Configure here.

<details> <summary>Stale Security Review comment</summary> <!-- BUGBOT_REVIEW --> Cursor Bugbot has reviewed your changes and found 1 potential issue.<!-- 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 5e81f6f3bd7b3fb95cf244d4880ff843fa722dbc. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> </details>
ghost1 commented 2026-06-05 14:00:49 +00:00 (Migrated from gitlab.com)

Repeated LCD refresh partial assets

Medium Severity

When a CW20 row exists but name or symbol is empty, resolve_asset now queries LCD on every call. If token_info fails, it returns the existing id without persisting a skip or backoff, so later indexing (e.g. each swap’s resolve_asset_str) repeats the same failing LCD request indefinitely instead of reusing the cached row like before.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5e81f6f3bd. Configure here.

### Repeated LCD refresh partial assets **Medium Severity** <!-- DESCRIPTION START --> When a CW20 row exists but `name` or `symbol` is empty, `resolve_asset` now queries LCD on every call. If `token_info` fails, it returns the existing id without persisting a skip or backoff, so later indexing (e.g. each swap’s `resolve_asset_str`) repeats the same failing LCD request indefinitely instead of reusing the cached row like before. <!-- DESCRIPTION END --> <!-- BUGBOT_BUG_ID: 04d1f4fd-5c59-482e-96f1-11fae7c24023 --> <!-- LOCATIONS START indexer/src/indexer/asset_resolver.rs#L15-L43 LOCATIONS END --> <div><a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OmEwMGU1MWM1LTBhNjYtNDUxZC04MGZjLTY0NGUwN2FlNTE2NCIsImVuY3J5cHRpb25LZXkiOiJlVjFzMVNKLUFOOHBxR3NZOXdhZTl3MVBKOGYyQ2llX1dNTmdGN3FWM3c0IiwiYnJhbmNoIjoiY3Vyc29yL2dpdGxhYi1pc3N1ZS13b3JrZmxvdy00ZTJjIiwicmVwb093bmVyIjoiUGxhc3RpY0RpZ2l0cyIsInJlcG9OYW1lIjoiY2w4eS1kZXgtdGVycmFjbGFzc2ljIn19" 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=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OmEwMGU1MWM1LTBhNjYtNDUxZC04MGZjLTY0NGUwN2FlNTE2NCIsImVuY3J5cHRpb25LZXkiOiJlVjFzMVNKLUFOOHBxR3NZOXdhZTl3MVBKOGYyQ2llX1dNTmdGN3FWM3c0IiwiYnJhbmNoIjoiY3Vyc29yL2dpdGxhYi1pc3N1ZS13b3JrZmxvdy00ZTJjIiwicmVwb093bmVyIjoiUGxhc3RpY0RpZ2l0cyIsInJlcG9OYW1lIjoiY2w4eS1kZXgtdGVycmFjbGFzc2ljIiwicHJOdW1iZXIiOjk0LCJjb21taXRTaGEiOiI1ZTgxZjZmM2JkN2IzZmI5NWNmMjQ0ZDQ4ODBmZjg0M2ZhNzIyZGJjIiwicHJvdmlkZXIiOiJnaXRsYWIiLCJob3N0bmFtZSI6ImdpdGxhYi5jb20ifX0" 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 5e81f6f3bd7b3fb95cf244d4880ff843fa722dbc. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
PlasticDigits commented 2026-06-05 14:00:50 +00:00 (Migrated from gitlab.com)

Security review

Commit reviewed: 5e81f6f3bd7b3fb95cf244d4880ff843fa722dbc
Scope: MR !812 — degraded pair search haystack fallback (pairSearchQuery.ts, PairSearchSelect.tsx, tokenDisplay.ts), indexer resolve_asset metadata refresh + LCD failure fallback (asset_resolver.rs), QA script/docs.

Outcome: FINDINGS: 0 medium+

Areas reviewed

Area Assessment
XSS / HTML injection Haystack text is used only for client-side includes() filtering; rendered option labels still come from pairInfoMenuLabel / React text nodes ({opt.label}), not haystack content. No new dangerouslySetInnerHTML or HTML sinks.
localStorage cache poisoning getCachedTokenEntry reads same-origin cl8y-dex-token-info cache (pre-existing write path via on-chain token_info). Poisoning requires prior same-origin compromise (XSS). Degraded search results are still gated to factoryPairs / factorySet; selected value is a factory-registered pair address, not attacker-supplied haystack text.
Injection (SQL / shell) Indexer upsert_asset and pair list filters remain parameterized (push_bind). QA script verify-issue-328.sh is operator-run tooling only.
SSRF / LCD amplification resolve_asset LCD query_contract calls use operator-configured endpoints with on-chain contract_addr from pair discovery — not user HTTP input. Extra refresh when DB name/symbol are empty is bounded to assets already referenced by indexed pairs. Commit 5e81f6f adds best-effort fallback to existing asset id on LCD failure, addressing the availability regression noted in prior Bugbot thread.
Authn / authz No new API routes or permission boundaries changed.

Prior threads

  • Prior security review on fd54fb6 reported FINDINGS: 0 medium+; re-reviewed after 5e81f6f LCD fallback fix.
  • Bugbot inline thread on LCD partial-metadata failure (availability, not an attacker-controlled exploit path) is resolved by 5e81f6f.

Inline threads: none (no medium+ findings).

## Security review **Commit reviewed:** `5e81f6f3bd7b3fb95cf244d4880ff843fa722dbc` **Scope:** MR !812 — degraded pair search haystack fallback (`pairSearchQuery.ts`, `PairSearchSelect.tsx`, `tokenDisplay.ts`), indexer `resolve_asset` metadata refresh + LCD failure fallback (`asset_resolver.rs`), QA script/docs. **Outcome:** `FINDINGS: 0` medium+ ### Areas reviewed | Area | Assessment | |------|------------| | **XSS / HTML injection** | Haystack text is used only for client-side `includes()` filtering; rendered option labels still come from `pairInfoMenuLabel` / React text nodes (`{opt.label}`), not haystack content. No new `dangerouslySetInnerHTML` or HTML sinks. | | **localStorage cache poisoning** | `getCachedTokenEntry` reads same-origin `cl8y-dex-token-info` cache (pre-existing write path via on-chain `token_info`). Poisoning requires prior same-origin compromise (XSS). Degraded search results are still gated to `factoryPairs` / `factorySet`; selected `value` is a factory-registered pair address, not attacker-supplied haystack text. | | **Injection (SQL / shell)** | Indexer `upsert_asset` and pair list filters remain parameterized (`push_bind`). QA script `verify-issue-328.sh` is operator-run tooling only. | | **SSRF / LCD amplification** | `resolve_asset` LCD `query_contract` calls use operator-configured endpoints with on-chain `contract_addr` from pair discovery — not user HTTP input. Extra refresh when DB name/symbol are empty is bounded to assets already referenced by indexed pairs. Commit `5e81f6f` adds best-effort fallback to existing asset id on LCD failure, addressing the availability regression noted in prior Bugbot thread. | | **Authn / authz** | No new API routes or permission boundaries changed. | ### Prior threads - Prior security review on `fd54fb6` reported `FINDINGS: 0` medium+; re-reviewed after `5e81f6f` LCD fallback fix. - Bugbot inline thread on LCD partial-metadata failure (availability, not an attacker-controlled exploit path) is resolved by `5e81f6f`. **Inline threads:** none (no medium+ findings).
ghost1 commented 2026-06-05 14:03:35 +00:00 (Migrated from gitlab.com)

added 1 commit

  • 74a30537 - fix(indexer): persist contract fallback when CW20 LCD refresh fails

Compare with previous version

added 1 commit <ul><li>74a30537 - fix(indexer): persist contract fallback when CW20 LCD refresh fails</li></ul> [Compare with previous version](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/94/diffs?diff_id=1836873050&start_sha=5e81f6f3bd7b3fb95cf244d4880ff843fa722dbc)
ghost1 commented 2026-06-05 14:03:49 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-05 14:03:58 +00:00 (Migrated from gitlab.com)

resolved all threads

resolved all threads
PlasticDigits commented 2026-06-05 14:04:50 +00:00 (Migrated from gitlab.com)

Security review

Commit reviewed: 74a305371e93cc18acaf76960fcd346ca1c81b3d
Scope: MR !812 — degraded pair search haystack fallback (pairSearchQuery.ts, PairSearchSelect.tsx, tokenDisplay.ts), indexer resolve_asset CW20 metadata refresh + LCD failure fallback persistence (asset_resolver.rs), QA script/docs.

Outcome: FINDINGS: 0 medium+

Security review: no medium+ findings on this diff.

Areas reviewed

Area Assessment
XSS / HTML injection Haystack strings are used only for client-side includes() filtering. Rendered option labels remain pairInfoMenuLabel / React text nodes ({opt.label}), not haystack content. No new dangerouslySetInnerHTML or HTML sinks.
localStorage cache poisoning getCachedTokenEntry reads same-origin cl8y-dex-token-info (existing write path via on-chain token_info). Poisoning requires prior same-origin compromise (XSS). Degraded matches are still limited to factoryPairs / factorySet; selected value is a factory-registered pair address, not attacker-supplied haystack text.
Injection (SQL / shell) Indexer upsert_asset and pair list filters remain parameterized (push_bind). QA script verify-issue-328.sh is operator-run tooling only.
SSRF / LCD amplification resolve_asset LCD query_contract uses operator-configured endpoints with on-chain contract_addr from pair discovery / swap indexing — not user HTTP input. Extra refresh when DB name/symbol are empty is bounded to assets already referenced by indexed pairs. Commit 74a30537 persists contract-address placeholders on LCD failure so partial rows stop re-querying; this is an availability hardening, not a new attacker-controlled sink.
Authn / authz No new API routes or permission boundaries changed.

Prior threads

  • Prior security review on 5e81f6f3 reported FINDINGS: 0 medium+; re-reviewed after 74a30537 LCD fallback persistence.
  • Bugbot inline threads on LCD partial-metadata handling (availability / DoS resistance, not attacker-controlled exploit paths) are addressed by 5e81f6f + 74a30537.

Inline threads: none (no medium+ findings).

## Security review **Commit reviewed:** `74a305371e93cc18acaf76960fcd346ca1c81b3d` **Scope:** MR !812 — degraded pair search haystack fallback (`pairSearchQuery.ts`, `PairSearchSelect.tsx`, `tokenDisplay.ts`), indexer `resolve_asset` CW20 metadata refresh + LCD failure fallback persistence (`asset_resolver.rs`), QA script/docs. **Outcome:** `FINDINGS: 0` medium+ Security review: no medium+ findings on this diff. ### Areas reviewed | Area | Assessment | |------|------------| | **XSS / HTML injection** | Haystack strings are used only for client-side `includes()` filtering. Rendered option labels remain `pairInfoMenuLabel` / React text nodes (`{opt.label}`), not haystack content. No new `dangerouslySetInnerHTML` or HTML sinks. | | **localStorage cache poisoning** | `getCachedTokenEntry` reads same-origin `cl8y-dex-token-info` (existing write path via on-chain `token_info`). Poisoning requires prior same-origin compromise (XSS). Degraded matches are still limited to `factoryPairs` / `factorySet`; selected `value` is a factory-registered pair address, not attacker-supplied haystack text. | | **Injection (SQL / shell)** | Indexer `upsert_asset` and pair list filters remain parameterized (`push_bind`). QA script `verify-issue-328.sh` is operator-run tooling only. | | **SSRF / LCD amplification** | `resolve_asset` LCD `query_contract` uses operator-configured endpoints with on-chain `contract_addr` from pair discovery / swap indexing — not user HTTP input. Extra refresh when DB name/symbol are empty is bounded to assets already referenced by indexed pairs. Commit `74a30537` persists contract-address placeholders on LCD failure so partial rows stop re-querying; this is an availability hardening, not a new attacker-controlled sink. | | **Authn / authz** | No new API routes or permission boundaries changed. | ### Prior threads - Prior security review on `5e81f6f3` reported `FINDINGS: 0` medium+; re-reviewed after `74a30537` LCD fallback persistence. - Bugbot inline threads on LCD partial-metadata handling (availability / DoS resistance, not attacker-controlled exploit paths) are addressed by `5e81f6f` + `74a30537`. **Inline threads:** none (no medium+ findings).
ghost1 commented 2026-06-05 14:04:55 +00:00 (Migrated from gitlab.com)

Cursor Bugbot has reviewed your changes 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 74a305371e. Configure here.

<!-- BUGBOT_REVIEW --> Cursor Bugbot has reviewed your changes and found 1 potential issue. <!-- BUGBOT_FIX_ALL --> <a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9BTExfSU5fQ1VSU09SIiwiZGF0YSI6eyJyZWRpc0tleSI6ImJ1Z2JvdC1tdWx0aTo4OThiNGYzZi1hMmMwLTQ1MmEtYTg5Zi1iZDJhOGZmZWQ3NmUiLCJlbmNyeXB0aW9uS2V5IjoiN2F3bkdIdFdvR05pRGFVb1dxUHNBUTkwWWx3bTV5N3RIdkNQZHcwTWxIVSIsImJyYW5jaCI6ImN1cnNvci9naXRsYWItaXNzdWUtd29ya2Zsb3ctNGUyYyIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6ImNsOHktZGV4LXRlcnJhY2xhc3NpYyJ9fQ" 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 74a305371e93cc18acaf76960fcd346ca1c81b3d. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
ghost1 commented 2026-06-05 14:04:56 +00:00 (Migrated from gitlab.com)

LCD fallback blocks metadata refresh

Medium Severity

When token_info fails during a metadata refresh, empty name or symbol fields are upserted with the contract address as placeholders. Later resolve_asset calls treat those rows as complete and skip the LCD refresh, so real CW20 names/symbols (e.g. Ember) may never populate after a transient LCD outage during pair sync.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 74a305371e. Configure here.

### LCD fallback blocks metadata refresh **Medium Severity** <!-- DESCRIPTION START --> When `token_info` fails during a metadata refresh, empty `name` or `symbol` fields are upserted with the contract address as placeholders. Later `resolve_asset` calls treat those rows as complete and skip the LCD refresh, so real CW20 names/symbols (e.g. Ember) may never populate after a transient LCD outage during pair sync. <!-- DESCRIPTION END --> <!-- BUGBOT_BUG_ID: 0230c9b6-8f3e-4612-9167-0a0059658aa6 --> <!-- LOCATIONS START indexer/src/indexer/asset_resolver.rs#L39-L61 LOCATIONS END --> <div><a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OmI1ZGI0OGNhLWUzOWQtNGZkZi1hYTY1LTA2N2FkNGFkZTU3MyIsImVuY3J5cHRpb25LZXkiOiJPcUgyNXhlSlFiVGVyU05Mei1uZEhTYldqNk9PVjh2MEFIa3prYXhfQVFzIiwiYnJhbmNoIjoiY3Vyc29yL2dpdGxhYi1pc3N1ZS13b3JrZmxvdy00ZTJjIiwicmVwb093bmVyIjoiUGxhc3RpY0RpZ2l0cyIsInJlcG9OYW1lIjoiY2w4eS1kZXgtdGVycmFjbGFzc2ljIn19" 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=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OmI1ZGI0OGNhLWUzOWQtNGZkZi1hYTY1LTA2N2FkNGFkZTU3MyIsImVuY3J5cHRpb25LZXkiOiJPcUgyNXhlSlFiVGVyU05Mei1uZEhTYldqNk9PVjh2MEFIa3prYXhfQVFzIiwiYnJhbmNoIjoiY3Vyc29yL2dpdGxhYi1pc3N1ZS13b3JrZmxvdy00ZTJjIiwicmVwb093bmVyIjoiUGxhc3RpY0RpZ2l0cyIsInJlcG9OYW1lIjoiY2w4eS1kZXgtdGVycmFjbGFzc2ljIiwicHJOdW1iZXIiOjk0LCJjb21taXRTaGEiOiI3NGEzMDUzNzFlOTNjYzE4YWNhZjc2OTYwZmNkMzQ2Y2ExYzgxYjNkIiwicHJvdmlkZXIiOiJnaXRsYWIiLCJob3N0bmFtZSI6ImdpdGxhYi5jb20ifX0" 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 74a305371e93cc18acaf76960fcd346ca1c81b3d. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
ghost1 commented 2026-06-05 14:06:49 +00:00 (Migrated from gitlab.com)

added 1 commit

  • d2414ae0 - Fix LCD fallback writing placeholder metadata that blocks refresh retries

Compare with previous version

added 1 commit <ul><li>d2414ae0 - Fix LCD fallback writing placeholder metadata that blocks refresh retries</li></ul> [Compare with previous version](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/94/diffs?diff_id=1836880556&start_sha=74a305371e93cc18acaf76960fcd346ca1c81b3d)
ghost1 commented 2026-06-05 14:07:06 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-05 14:07:18 +00:00 (Migrated from gitlab.com)

resolved all threads

resolved all threads
PlasticDigits commented 2026-06-05 14:08:31 +00:00 (Migrated from gitlab.com)

Security review

Commit reviewed: d2414ae05e449d239289029258c556ffd2b3c0c0
Scope: MR !812 — degraded pair search haystack fallback (pairSearchQuery.ts, PairSearchSelect.tsx, tokenDisplay.ts), indexer resolve_asset CW20 metadata refresh + LCD failure fallback (asset_resolver.rs), QA script/docs.

Outcome: FINDINGS: 0 medium+

Security review: no medium+ findings on this diff.

Areas reviewed

Area Assessment
XSS / HTML injection Haystack strings are used only for client-side includes() filtering. Rendered option labels remain pairInfoMenuLabel / React text nodes ({opt.label}), not haystack content. No new dangerouslySetInnerHTML or HTML sinks.
localStorage cache poisoning getCachedTokenEntry reads same-origin cl8y-dex-token-info (existing write path via on-chain token_info). Poisoning requires prior same-origin compromise (XSS). Degraded matches are still limited to factoryPairs / factorySet; selected value is a factory-registered pair address, not attacker-supplied haystack text.
Injection (SQL / shell) Indexer upsert_asset and pair list filters remain parameterized (push_bind). QA script verify-issue-328.sh is operator-run tooling only.
SSRF / LCD amplification resolve_asset LCD query_contract uses operator-configured endpoints with on-chain contract_addr from pair discovery / swap indexing — not user HTTP input. Extra refresh when DB name/symbol are empty is bounded to assets already referenced by indexed pairs. Commit d2414ae0 returns the existing asset id on LCD failure without upserting placeholder metadata, preserving retry behavior without introducing new attacker-controlled sinks.
Authn / authz No new API routes or permission boundaries changed.

Prior threads

  • Prior security reviews on fd54fb6, 5e81f6f3, and 74a30537 reported FINDINGS: 0 medium+; re-reviewed after d2414ae0 removes placeholder upsert on LCD failure (addresses Bugbot availability thread; no new exploit path).
  • No medium+ security inline threads to re-report.

Inline threads: none (no medium+ findings).

## Security review **Commit reviewed:** `d2414ae05e449d239289029258c556ffd2b3c0c0` **Scope:** MR !812 — degraded pair search haystack fallback (`pairSearchQuery.ts`, `PairSearchSelect.tsx`, `tokenDisplay.ts`), indexer `resolve_asset` CW20 metadata refresh + LCD failure fallback (`asset_resolver.rs`), QA script/docs. **Outcome:** `FINDINGS: 0` medium+ Security review: no medium+ findings on this diff. ### Areas reviewed | Area | Assessment | |------|------------| | **XSS / HTML injection** | Haystack strings are used only for client-side `includes()` filtering. Rendered option labels remain `pairInfoMenuLabel` / React text nodes (`{opt.label}`), not haystack content. No new `dangerouslySetInnerHTML` or HTML sinks. | | **localStorage cache poisoning** | `getCachedTokenEntry` reads same-origin `cl8y-dex-token-info` (existing write path via on-chain `token_info`). Poisoning requires prior same-origin compromise (XSS). Degraded matches are still limited to `factoryPairs` / `factorySet`; selected `value` is a factory-registered pair address, not attacker-supplied haystack text. | | **Injection (SQL / shell)** | Indexer `upsert_asset` and pair list filters remain parameterized (`push_bind`). QA script `verify-issue-328.sh` is operator-run tooling only. | | **SSRF / LCD amplification** | `resolve_asset` LCD `query_contract` uses operator-configured endpoints with on-chain `contract_addr` from pair discovery / swap indexing — not user HTTP input. Extra refresh when DB name/symbol are empty is bounded to assets already referenced by indexed pairs. Commit `d2414ae0` returns the existing asset id on LCD failure without upserting placeholder metadata, preserving retry behavior without introducing new attacker-controlled sinks. | | **Authn / authz** | No new API routes or permission boundaries changed. | ### Prior threads - Prior security reviews on `fd54fb6`, `5e81f6f3`, and `74a30537` reported `FINDINGS: 0` medium+; re-reviewed after `d2414ae0` removes placeholder upsert on LCD failure (addresses Bugbot availability thread; no new exploit path). - No medium+ security inline threads to re-report. **Inline threads:** none (no medium+ findings).
ghost1 commented 2026-06-05 14:31:37 +00:00 (Migrated from gitlab.com)

added 30 commits

  • d2414ae0...6e2ebbe1 - 29 commits from branch main
  • 15d38d53 - Merge origin/main into cursor/gitlab-issue-workflow-4e2c

Compare with previous version

added 30 commits <ul><li>d2414ae0...6e2ebbe1 - 29 commits from branch <code>main</code></li><li>15d38d53 - Merge origin/main into cursor/gitlab-issue-workflow-4e2c</li></ul> [Compare with previous version](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/94/diffs?diff_id=1836937345&start_sha=d2414ae05e449d239289029258c556ffd2b3c0c0)
ghost1 commented 2026-06-05 14:32:19 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-05 14:32:30 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-05 14:33:26 +00:00 (Migrated from gitlab.com)

mentioned in commit 9134e2843f

mentioned in commit 9134e2843ff06a6450988dba6f8f12115c296e7a
PlasticDigits (Migrated from gitlab.com) merged commit 9134e2843f into main 2026-06-05 14:33:26 +00:00
PlasticDigits commented 2026-06-05 14:33:48 +00:00 (Migrated from gitlab.com)

Security review

Commit reviewed: 15d38d53d6d75dbb701d0e7aa004a89e25727493
Scope: MR !812 — merge with main + degraded pair search haystack fallback (pairSearchQuery.ts, PairSearchSelect.tsx, tokenDisplay.ts), indexer resolve_asset CW20 metadata refresh + LCD failure fallback (asset_resolver.rs), QA script/docs.

Outcome: FINDINGS: 0 medium+

Security review: no medium+ findings on this diff.

Areas reviewed

Area Assessment
XSS / HTML injection Haystack strings are used only for client-side includes() filtering. Rendered option labels remain pairInfoMenuLabel / React text nodes ({opt.label}), not haystack content. No new dangerouslySetInnerHTML or HTML sinks.
localStorage cache poisoning getCachedTokenEntry reads same-origin cl8y-dex-token-info (existing write path via on-chain token_info). Poisoning requires prior same-origin compromise (XSS). Degraded matches are still limited to factoryPairs / factorySet; selected value is a factory-registered pair address, not attacker-supplied haystack text.
Injection (SQL / shell) Indexer upsert_asset and pair list filters remain parameterized (push_bind). QA script verify-issue-328.sh is operator-run tooling only.
SSRF / LCD amplification resolve_asset LCD query_contract uses operator-configured endpoints with on-chain contract_addr from pair discovery / swap indexing — not user HTTP input. Extra refresh when DB name/symbol are empty is bounded to assets already referenced by indexed pairs; LCD errors return the existing asset id without persisting placeholder metadata (lines 32–43).
Authn / authz No changes to signing, permissions, or API auth boundaries.

Prior threads

Re-checked Bugbot threads on asset_resolver.rs (LCD failure / repeated refresh). Current head handles LCD errors by returning the existing partial asset id without upserting placeholders; remaining behavior is indexer availability/retry semantics, not a plausible confidentiality/integrity attack path for external callers.

Inline findings: none on this revision.

## Security review **Commit reviewed:** `15d38d53d6d75dbb701d0e7aa004a89e25727493` **Scope:** MR !812 — merge with `main` + degraded pair search haystack fallback (`pairSearchQuery.ts`, `PairSearchSelect.tsx`, `tokenDisplay.ts`), indexer `resolve_asset` CW20 metadata refresh + LCD failure fallback (`asset_resolver.rs`), QA script/docs. **Outcome:** `FINDINGS: 0` medium+ Security review: no medium+ findings on this diff. ### Areas reviewed | Area | Assessment | |------|------------| | **XSS / HTML injection** | Haystack strings are used only for client-side `includes()` filtering. Rendered option labels remain `pairInfoMenuLabel` / React text nodes (`{opt.label}`), not haystack content. No new `dangerouslySetInnerHTML` or HTML sinks. | | **localStorage cache poisoning** | `getCachedTokenEntry` reads same-origin `cl8y-dex-token-info` (existing write path via on-chain `token_info`). Poisoning requires prior same-origin compromise (XSS). Degraded matches are still limited to `factoryPairs` / `factorySet`; selected `value` is a factory-registered pair address, not attacker-supplied haystack text. | | **Injection (SQL / shell)** | Indexer `upsert_asset` and pair list filters remain parameterized (`push_bind`). QA script `verify-issue-328.sh` is operator-run tooling only. | | **SSRF / LCD amplification** | `resolve_asset` LCD `query_contract` uses operator-configured endpoints with on-chain `contract_addr` from pair discovery / swap indexing — not user HTTP input. Extra refresh when DB name/symbol are empty is bounded to assets already referenced by indexed pairs; LCD errors return the existing asset id without persisting placeholder metadata (lines 32–43). | | **Authn / authz** | No changes to signing, permissions, or API auth boundaries. | ### Prior threads Re-checked Bugbot threads on `asset_resolver.rs` (LCD failure / repeated refresh). Current head handles LCD errors by returning the existing partial asset id without upserting placeholders; remaining behavior is indexer availability/retry semantics, not a plausible confidentiality/integrity attack path for external callers. **Inline findings:** none on this revision.
PlasticDigits commented 2026-06-08 08:43:13 +00:00 (Migrated from gitlab.com)

mentioned in commit 02c49cbb2a

mentioned in commit 02c49cbb2a0cfa30ab726391d9d41d2124fdecef
PlasticDigits commented 2026-06-08 13:42:28 +00:00 (Migrated from gitlab.com)

mentioned in commit 81784caa84

mentioned in commit 81784caa8493beb48a6adcf7fb04e901782eea37
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!812
No description provided.