Fix: Terra broadcast → confirming UI phase (GitLab #305) #778

Merged
PlasticDigits merged 3 commits from cursor/gitlab-issue-workflow-49bf into main 2026-06-05 09:30:59 +00:00
PlasticDigits commented 2026-06-05 08:16:39 +00:00 (Migrated from gitlab.com)

Summary

Implements GitLab #305 (part 1 of #304): retail submit buttons now distinguish wallet signing/broadcast from on-chain confirmation.

What changed

  • broadcastTerraExecuteContracts fires optional onPhaseChange at signing → broadcasting → confirming (with txHash) boundaries; canonical #127 path preserved.
  • terraBroadcastScope + useTerraBroadcastMutation thread phase callbacks into existing service layers without per-function option parameters.
  • Primary action surfaces updated: Swap, Limit Orders, Trade ticket (limit + market), Pool add/withdraw, limit ladder.
  • In-flight Confirming… copy + explorer tx link via TerraBroadcastPendingLink.
  • localnet-trading-swarm broadcast.ts aligned with the same phase callback shape.
  • Documented invariants in docs/frontend.md § Broadcast phase UI.

Acceptance checklist

Criterion Verification Result
After tx hash, UI shows Confirming… until pollTx resolves terraBroadcast.test.ts phase ordering; useTerraBroadcastMutation hook; Swap/Limits/Trade button labels PASS
Phase callback fires for every transition; no silent gaps Unit test asserts signing → broadcasting → confirming sequence PASS
Failed broadcast never enters confirming; failed poll does not re-trigger signing terraBroadcast.test.ts failure cases PASS
Timeout tests (#173) still pass; new phase ordering tests make test-frontend (832 tests) PASS
Trade ticket, Limit Orders, Swap updated (others migrated) Pool, ladder, market panel also migrated in same MR PASS

Verification for third parties

make test-frontend    # includes terraBroadcast + useTerraBroadcastMutation tests
make lint-frontend    # 0 errors

Manual (LocalTerra): Simulated Wallet swap on /swap — button should read Signing… / Broadcasting… then Confirming… with a tx hash link until confirmation; success alert shows final hash.

Blockers

None.

Related: #305 (issue stays open until merge).


Note

Low Risk
Mostly submit-button UX and observability on the existing broadcast path; phase ordering and failure cases are unit-tested, with no changes to signing, fee, or timeout semantics.

Overview
Adds signing → broadcasting → confirming phase tracking for on-chain submits (GitLab #305).

broadcastTerraExecuteContracts accepts optional onPhaseChange at sign lock, inside broadcastTx, and after a tx hash before pollTx. Failed broadcast skips confirming; failed poll does not re-fire signing (covered in terraBroadcast.test.ts).

terraBroadcastScope + useTerraBroadcastMutation thread callbacks into existing executeTerraContract* / executeCw20AllowanceThen paths without adding options on every service entry point. Mutations expose phase, pendingTxHash, and still use isPending to disable buttons.

Primary surfaces migrated from plain useMutation: Swap, Trade limit/market/ladder, Limits page, Pool add/withdraw. Shared UI: terraBroadcastPendingButtonLabel, TerraBroadcastPendingLink (explorer link while Confirming…). packages/localnet-trading-swarm broadcast.ts uses the same phase shape. Documented in docs/frontend.md § Broadcast phase UI.

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

## Summary Implements GitLab [#305](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/305) (part 1 of [#304](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/304)): retail submit buttons now distinguish wallet signing/broadcast from on-chain confirmation. ### What changed - **`broadcastTerraExecuteContracts`** fires optional `onPhaseChange` at `signing` → `broadcasting` → `confirming` (with `txHash`) boundaries; canonical #127 path preserved. - **`terraBroadcastScope`** + **`useTerraBroadcastMutation`** thread phase callbacks into existing service layers without per-function option parameters. - Primary action surfaces updated: Swap, Limit Orders, Trade ticket (limit + market), Pool add/withdraw, limit ladder. - In-flight **Confirming…** copy + explorer tx link via **`TerraBroadcastPendingLink`**. - **`localnet-trading-swarm`** `broadcast.ts` aligned with the same phase callback shape. - Documented invariants in [`docs/frontend.md` § Broadcast phase UI](docs/frontend.md#broadcast-phase-ui). ## Acceptance checklist | Criterion | Verification | Result | |-----------|--------------|--------| | After tx hash, UI shows **Confirming…** until `pollTx` resolves | `terraBroadcast.test.ts` phase ordering; `useTerraBroadcastMutation` hook; Swap/Limits/Trade button labels | **PASS** | | Phase callback fires for every transition; no silent gaps | Unit test asserts `signing` → `broadcasting` → `confirming` sequence | **PASS** | | Failed broadcast never enters confirming; failed poll does not re-trigger signing | `terraBroadcast.test.ts` failure cases | **PASS** | | Timeout tests (#173) still pass; new phase ordering tests | `make test-frontend` (832 tests) | **PASS** | | Trade ticket, Limit Orders, Swap updated (others migrated) | Pool, ladder, market panel also migrated in same MR | **PASS** | ## Verification for third parties ```bash make test-frontend # includes terraBroadcast + useTerraBroadcastMutation tests make lint-frontend # 0 errors ``` **Manual (LocalTerra):** Simulated Wallet swap on `/swap` — button should read Signing… / Broadcasting… then **Confirming…** with a tx hash link until confirmation; success alert shows final hash. ## Blockers None. Related: #305 (issue stays open until merge). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Mostly submit-button UX and observability on the existing broadcast path; phase ordering and failure cases are unit-tested, with no changes to signing, fee, or timeout semantics. > > **Overview** > Adds **signing → broadcasting → confirming** phase tracking for on-chain submits ([GitLab **#305**](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/305)). > > **`broadcastTerraExecuteContracts`** accepts optional **`onPhaseChange`** at sign lock, inside **`broadcastTx`**, and after a tx hash before **`pollTx`**. Failed broadcast skips **confirming**; failed poll does not re-fire **signing** (covered in **`terraBroadcast.test.ts`**). > > **`terraBroadcastScope`** + **`useTerraBroadcastMutation`** thread callbacks into existing **`executeTerraContract*`** / **`executeCw20AllowanceThen`** paths without adding options on every service entry point. Mutations expose **`phase`**, **`pendingTxHash`**, and still use **`isPending`** to disable buttons. > > Primary surfaces migrated from plain **`useMutation`**: Swap, Trade limit/market/ladder, Limits page, Pool add/withdraw. Shared UI: **`terraBroadcastPendingButtonLabel`**, **`TerraBroadcastPendingLink`** (explorer link while **Confirming…**). **`packages/localnet-trading-swarm`** **`broadcast.ts`** uses the same phase shape. Documented in **`docs/frontend.md`** § Broadcast phase UI. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 186b82cc189042d516ef5973609564380a20e260. 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-05 08:16:49 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-05 08:17:02 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-05 08:17:05 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
PlasticDigits commented 2026-06-05 08:17:05 +00:00 (Migrated from gitlab.com)

mentioned in issue #305

mentioned in issue #305
ghost1 commented 2026-06-05 08:18:53 +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 18479446d2. 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 18479446d2f8d2bd6d7d8ddd0bc5ee065736b3d5. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> </details>
ghost1 commented 2026-06-05 08:18:54 +00:00 (Migrated from gitlab.com)

Global scope misroutes phases

Medium Severity

Module-level scopeStack plus getTerraBroadcastScopeOptions() on every executeTerraContract* call ties phase updates to whichever scope was pushed last. Overlapping txs (e.g. cancel via plain useMutation while a useTerraBroadcastMutation is confirming, or add and withdraw on Pool) can drive the wrong mutation’s phase and pendingTxHash.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 18479446d2. Configure here.

### Global scope misroutes phases **Medium Severity** <!-- DESCRIPTION START --> Module-level `scopeStack` plus `getTerraBroadcastScopeOptions()` on every `executeTerraContract*` call ties phase updates to whichever scope was pushed last. Overlapping txs (e.g. cancel via plain `useMutation` while a `useTerraBroadcastMutation` is confirming, or add and withdraw on Pool) can drive the wrong mutation’s `phase` and `pendingTxHash`. <!-- DESCRIPTION END --> <!-- BUGBOT_BUG_ID: 7af29177-8182-48d6-b829-7af3e1e666fb --> <!-- LOCATIONS START frontend-dapp/src/services/terraclassic/terraBroadcastScope.ts#L2-L22 frontend-dapp/src/services/terraclassic/transactions.ts#L175-L189 LOCATIONS END --> <details> <summary>Additional Locations (1)</summary> - [`frontend-dapp/src/services/terraclassic/transactions.ts#L175-L189`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-//blob/18479446d2f8d2bd6d7d8ddd0bc5ee065736b3d5/frontend-dapp/src/services/terraclassic/transactions.ts#L175-L189) </details> <div><a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OjQ4YjdiYzJjLWQyOGUtNGQ3My1iYTlkLTFmMmE5NTE4ZmNkNSIsImVuY3J5cHRpb25LZXkiOiJFMGJkcmdvSzhMejFTVlB0M0tLN3Vpb25rbzM2ME5HREZZRk9zeEJzWXVFIiwiYnJhbmNoIjoiY3Vyc29yL2dpdGxhYi1pc3N1ZS13b3JrZmxvdy00OWJmIiwicmVwb093bmVyIjoiUGxhc3RpY0RpZ2l0cyIsInJlcG9OYW1lIjoiY2w4eS1kZXgtdGVycmFjbGFzc2ljIn19" 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=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OjQ4YjdiYzJjLWQyOGUtNGQ3My1iYTlkLTFmMmE5NTE4ZmNkNSIsImVuY3J5cHRpb25LZXkiOiJFMGJkcmdvSzhMejFTVlB0M0tLN3Vpb25rbzM2ME5HREZZRk9zeEJzWXVFIiwiYnJhbmNoIjoiY3Vyc29yL2dpdGxhYi1pc3N1ZS13b3JrZmxvdy00OWJmIiwicmVwb093bmVyIjoiUGxhc3RpY0RpZ2l0cyIsInJlcG9OYW1lIjoiY2w4eS1kZXgtdGVycmFjbGFzc2ljIiwicHJOdW1iZXIiOjYwLCJjb21taXRTaGEiOiIxODQ3OTQ0NmQyZjhkMmJkNmQ3ZDhkZGQwYmM1ZWUwNjU3MzZiM2Q1IiwicHJvdmlkZXIiOiJnaXRsYWIiLCJob3N0bmFtZSI6ImdpdGxhYi5jb20ifX0" 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 18479446d2f8d2bd6d7d8ddd0bc5ee065736b3d5. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
ghost1 commented 2026-06-05 08:25:58 +00:00 (Migrated from gitlab.com)

changed this line in version 2 of the diff

changed this line in [version 2 of the diff](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/60/diffs?diff_id=1836201631&start_sha=18479446d2f8d2bd6d7d8ddd0bc5ee065736b3d5#c1839e8b8a0c09f010bcb01c13e4bd9fa7099b70_22_40)
ghost1 commented 2026-06-05 08:25:58 +00:00 (Migrated from gitlab.com)

added 1 commit

  • 5944a0c3 - Fix Terra broadcast scope misrouting overlapping mutations

Compare with previous version

added 1 commit <ul><li>5944a0c3 - Fix Terra broadcast scope misrouting overlapping mutations</li></ul> [Compare with previous version](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/60/diffs?diff_id=1836201631&start_sha=18479446d2f8d2bd6d7d8ddd0bc5ee065736b3d5)
ghost1 commented 2026-06-05 08:26:04 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-05 08:26:12 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-05 08:26:24 +00:00 (Migrated from gitlab.com)

resolved all threads

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

Security review

Commit reviewed: 5944a0c

Scope: 17 files — Terra broadcast phase UI (onPhaseChange callbacks, terraBroadcastScope, useTerraBroadcastMutation, TerraBroadcastPendingLink), retail surface wiring (Swap, Trade, Limits, Pool), docs, and localnet-trading-swarm broadcast helper alignment.

Method: Diff review with attacker-controlled-input tracing for injection, XSS/open-redirect, authz bypass, secret leakage, and unsafe deserialization. Prior Bugbot thread on global scope misrouting re-checked against the 5944a0c fix (activeScopes + scopedExecutionDepth; ambiguous overlap returns undefined).

Outcome: FINDINGS: 0 medium+

No inline security threads — nothing met the medium+ bar with a plausible exploit path.

Areas examined (no issues)

Area Result
XSS / open redirect (TerraBroadcastPendingLink, getExplorerTxUrl) txHash is wallet-returned chain hash, not user/API input. React escapes JSX text/attributes; explorer URLs are prefixed with a trusted base from build-time NETWORKS / chainlist — same pattern as existing TxResultAlert.
Authn / authz No server endpoints, roles, or signing logic changed; wallet still gates all broadcasts.
Scope overlap (prior Bugbot note) Fixed in 5944a0c. Remaining ambiguity only suppresses phase callbacks (fallback button copy) — UX, not a permission or fund-safety boundary. isPending disable guards unchanged.
CW20 two-step scope (executeCw20AllowanceThen) Re-enters scope for follow-up execute; does not skip wallet sign or alter msg construction.
Secrets / logging No new sensitive data logged; public tx hashes only.
Dependencies No new packages.

Security review: no medium+ findings on this diff.

## Security review **Commit reviewed:** [`5944a0c`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/commit/5944a0c3e3999b4683247aed7fcfe2efe8c180fe) **Scope:** 17 files — Terra broadcast phase UI (`onPhaseChange` callbacks, `terraBroadcastScope`, `useTerraBroadcastMutation`, `TerraBroadcastPendingLink`), retail surface wiring (Swap, Trade, Limits, Pool), docs, and `localnet-trading-swarm` broadcast helper alignment. **Method:** Diff review with attacker-controlled-input tracing for injection, XSS/open-redirect, authz bypass, secret leakage, and unsafe deserialization. Prior Bugbot thread on global scope misrouting re-checked against the `5944a0c` fix (`activeScopes` + `scopedExecutionDepth`; ambiguous overlap returns `undefined`). **Outcome:** **FINDINGS: 0** medium+ No inline security threads — nothing met the medium+ bar with a plausible exploit path. ### Areas examined (no issues) | Area | Result | |------|--------| | **XSS / open redirect** (`TerraBroadcastPendingLink`, `getExplorerTxUrl`) | `txHash` is wallet-returned chain hash, not user/API input. React escapes JSX text/attributes; explorer URLs are prefixed with a trusted base from build-time `NETWORKS` / chainlist — same pattern as existing `TxResultAlert`. | | **Authn / authz** | No server endpoints, roles, or signing logic changed; wallet still gates all broadcasts. | | **Scope overlap** (prior Bugbot note) | Fixed in `5944a0c`. Remaining ambiguity only suppresses phase callbacks (fallback button copy) — UX, not a permission or fund-safety boundary. `isPending` disable guards unchanged. | | **CW20 two-step scope** (`executeCw20AllowanceThen`) | Re-enters scope for follow-up execute; does not skip wallet sign or alter msg construction. | | **Secrets / logging** | No new sensitive data logged; public tx hashes only. | | **Dependencies** | No new packages. | **Security review: no medium+ findings on this diff.**
ghost1 commented 2026-06-05 08:28:37 +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 5944a0c3e3. 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=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9BTExfSU5fQ1VSU09SIiwiZGF0YSI6eyJyZWRpc0tleSI6ImJ1Z2JvdC1tdWx0aTo2YzMwOGNjNy0zMDIyLTQ2NzYtYjg3ZC1lYzZlYzVjOTY5OTQiLCJlbmNyeXB0aW9uS2V5IjoiQU9SSVdDanI0WF9ndndFNFRGbTR5eW5KN1JaZW5IN0lWSzc2bW91QWVQQSIsImJyYW5jaCI6ImN1cnNvci9naXRsYWItaXNzdWUtd29ya2Zsb3ctNDliZiIsInJlcG9Pd25lciI6IlBsYXN0aWNEaWdpdHMiLCJyZXBvTmFtZSI6ImNsOHktZGV4LXRlcnJhY2xhc3NpYyJ9fQ" 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 5944a0c3e3999b4683247aed7fcfe2efe8c180fe. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
ghost1 commented 2026-06-05 08:28:38 +00:00 (Migrated from gitlab.com)

Broadcast scope lost after await

Medium Severity

invokeScoped decrements scopedExecutionDepth in a synchronous finally as soon as the wrapped function returns its promise, while getTerraBroadcastScopeOptions refuses to resolve when depth is zero. Later broadcasts in the same mutation (after an await) no longer receive onPhaseChange, so the button can stay on Confirming… with a stale tx link during the next wallet step.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5944a0c3e3. Configure here.

### Broadcast scope lost after await **Medium Severity** <!-- DESCRIPTION START --> `invokeScoped` decrements `scopedExecutionDepth` in a synchronous `finally` as soon as the wrapped function returns its promise, while `getTerraBroadcastScopeOptions` refuses to resolve when depth is zero. Later broadcasts in the same mutation (after an `await`) no longer receive `onPhaseChange`, so the button can stay on **Confirming…** with a stale tx link during the next wallet step. <!-- DESCRIPTION END --> <!-- BUGBOT_BUG_ID: 78778335-d92b-4be7-bb0d-57a3e12c6216 --> <!-- LOCATIONS START frontend-dapp/src/services/terraclassic/terraBroadcastScope.ts#L10-L41 frontend-dapp/src/pages/PoolPage.tsx#L382-L401 LOCATIONS END --> <details> <summary>Additional Locations (1)</summary> - [`frontend-dapp/src/pages/PoolPage.tsx#L382-L401`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-//blob/5944a0c3e3999b4683247aed7fcfe2efe8c180fe/frontend-dapp/src/pages/PoolPage.tsx#L382-L401) </details> <div><a href="https://cursor.com/open?link=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9DVVJTT1IiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OjdjY2Q2NDZiLTQ4Y2QtNDYyNS1hNmI1LTIzMTYyMmQyYWIxNCIsImVuY3J5cHRpb25LZXkiOiIzUzBPaWpmZERJNUxNY3MySEVWdDJURlh2NXZSOWpqTm9RMHd1R3ZWQWNBIiwiYnJhbmNoIjoiY3Vyc29yL2dpdGxhYi1pc3N1ZS13b3JrZmxvdy00OWJmIiwicmVwb093bmVyIjoiUGxhc3RpY0RpZ2l0cyIsInJlcG9OYW1lIjoiY2w4eS1kZXgtdGVycmFjbGFzc2ljIn19" 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=eyJ2ZXJzaW9uIjoxLCJ0eXBlIjoiQlVHQk9UX0ZJWF9JTl9XRUIiLCJkYXRhIjp7InJlZGlzS2V5IjoiYnVnYm90OjdjY2Q2NDZiLTQ4Y2QtNDYyNS1hNmI1LTIzMTYyMmQyYWIxNCIsImVuY3J5cHRpb25LZXkiOiIzUzBPaWpmZERJNUxNY3MySEVWdDJURlh2NXZSOWpqTm9RMHd1R3ZWQWNBIiwiYnJhbmNoIjoiY3Vyc29yL2dpdGxhYi1pc3N1ZS13b3JrZmxvdy00OWJmIiwicmVwb093bmVyIjoiUGxhc3RpY0RpZ2l0cyIsInJlcG9OYW1lIjoiY2w4eS1kZXgtdGVycmFjbGFzc2ljIiwicHJOdW1iZXIiOjYwLCJjb21taXRTaGEiOiI1OTQ0YTBjM2UzOTk5YjQ2ODMyNDdhZWQ3ZmNmZTJlZmU4YzE4MGZlIiwicHJvdmlkZXIiOiJnaXRsYWIiLCJob3N0bmFtZSI6ImdpdGxhYi5jb20ifX0" 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 5944a0c3e3999b4683247aed7fcfe2efe8c180fe. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
ghost1 commented 2026-06-05 08:29:47 +00:00 (Migrated from gitlab.com)

added 1 commit

  • 186b82cc - fix: keep broadcast scope depth until async mutation settles

Compare with previous version

added 1 commit <ul><li>186b82cc - fix: keep broadcast scope depth until async mutation settles</li></ul> [Compare with previous version](/PlasticDigits/cl8y-dex-terraclassic/-/merge_requests/60/diffs?diff_id=1836209408&start_sha=5944a0c3e3999b4683247aed7fcfe2efe8c180fe)
ghost1 commented 2026-06-05 08:30:01 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
ghost1 commented 2026-06-05 08:30:02 +00:00 (Migrated from gitlab.com)

resolved all threads

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

Security review

Commit reviewed: 186b82c

Scope: 17 files — Terra broadcast phase UI (onPhaseChange, terraBroadcastScope, useTerraBroadcastMutation, TerraBroadcastPendingLink), retail surface wiring (Swap, Trade, Limits, Pool), docs, and localnet-trading-swarm broadcast helper alignment. Re-reviewed after the 186b82c fix that keeps scopedExecutionDepth until the scoped promise settles.

Method: Full diff review with attacker-controlled-input tracing for injection, XSS/open-redirect, authn/authz bypass, secret leakage, SSRF, and unsafe deserialization. Prior security review on 5944a0c and resolved Bugbot threads (global scope misrouting, async scope depth) re-checked on this head.

Outcome: FINDINGS: 0 medium+

No inline security threads — nothing met the medium+ bar with a plausible exploit path.

Areas examined (no issues)

Area Result
XSS / open redirect (TerraBroadcastPendingLink, getExplorerTxUrl) pendingTxHash is set only from onPhaseChange after wallet.broadcastTx returns — not user/API/query input. React escapes JSX text/attributes; explorer URLs prefix a build-time-trusted base (NETWORKS / chainlist) and append the hash as a path segment — same pattern as existing TxResultAlert. A crafted hash cannot yield a javascript: href.
Authn / authz No server endpoints or signing logic changed. Wallet still gates every broadcast; requireConnectedWalletForAddress unchanged. Phase callbacks are observability only.
Module scope overlap (terraBroadcastScope) activeScopes + scopedExecutionDepth; ambiguous overlap (size !== 1) returns undefined and suppresses callbacks. Misrouting affects button copy only — not tx construction, gas, or approval. isPending disable guards unchanged. 186b82c fixes sequential in-mutation scope loss (UX).
CW20 two-step (executeCw20AllowanceThen) Re-enters scope for follow-up execute; does not skip wallet sign or alter msg construction.
Secrets / logging No new sensitive data logged; public tx hashes only. Pre-existing console.error on broadcast failure unchanged.
Dependencies / supply chain No new packages. localnet-trading-swarm changes are dev-tooling only.

Security review: no medium+ findings on this diff.

## Security review **Commit reviewed:** [`186b82c`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/commit/186b82cc189042d516ef5973609564380a20e260) **Scope:** 17 files — Terra broadcast phase UI (`onPhaseChange`, `terraBroadcastScope`, `useTerraBroadcastMutation`, `TerraBroadcastPendingLink`), retail surface wiring (Swap, Trade, Limits, Pool), docs, and `localnet-trading-swarm` broadcast helper alignment. Re-reviewed after the `186b82c` fix that keeps `scopedExecutionDepth` until the scoped promise settles. **Method:** Full diff review with attacker-controlled-input tracing for injection, XSS/open-redirect, authn/authz bypass, secret leakage, SSRF, and unsafe deserialization. Prior security review on `5944a0c` and resolved Bugbot threads (global scope misrouting, async scope depth) re-checked on this head. **Outcome:** **FINDINGS: 0** medium+ No inline security threads — nothing met the medium+ bar with a plausible exploit path. ### Areas examined (no issues) | Area | Result | |------|--------| | **XSS / open redirect** (`TerraBroadcastPendingLink`, `getExplorerTxUrl`) | `pendingTxHash` is set only from `onPhaseChange` after `wallet.broadcastTx` returns — not user/API/query input. React escapes JSX text/attributes; explorer URLs prefix a build-time-trusted base (`NETWORKS` / chainlist) and append the hash as a path segment — same pattern as existing `TxResultAlert`. A crafted hash cannot yield a `javascript:` href. | | **Authn / authz** | No server endpoints or signing logic changed. Wallet still gates every broadcast; `requireConnectedWalletForAddress` unchanged. Phase callbacks are observability only. | | **Module scope overlap** (`terraBroadcastScope`) | `activeScopes` + `scopedExecutionDepth`; ambiguous overlap (`size !== 1`) returns `undefined` and suppresses callbacks. Misrouting affects button copy only — not tx construction, gas, or approval. `isPending` disable guards unchanged. `186b82c` fixes sequential in-mutation scope loss (UX). | | **CW20 two-step** (`executeCw20AllowanceThen`) | Re-enters scope for follow-up execute; does not skip wallet sign or alter msg construction. | | **Secrets / logging** | No new sensitive data logged; public tx hashes only. Pre-existing `console.error` on broadcast failure unchanged. | | **Dependencies / supply chain** | No new packages. `localnet-trading-swarm` changes are dev-tooling only. | **Security review: no medium+ findings on this diff.**
PlasticDigits commented 2026-06-05 09:19:41 +00:00 (Migrated from gitlab.com)

Security review

Commit reviewed: 186b82c

Scope: 17 files — Terra broadcast phase UI (onPhaseChange, terraBroadcastScope, useTerraBroadcastMutation, TerraBroadcastPendingLink), retail surface wiring (Swap, Trade, Limits, Pool), docs, and localnet-trading-swarm broadcast helper alignment.

Method: Full diff review with attacker-controlled-input tracing for injection, XSS/open-redirect, authn/authz bypass, secret leakage, SSRF, and unsafe deserialization. Prior Bugbot threads (global scope misrouting, async scopedExecutionDepth) and earlier security reviews on 5944a0c / 186b82c re-checked on this head.

Outcome: FINDINGS: 0 medium+

No inline security threads — nothing met the medium+ bar with a plausible exploit path.

Areas examined (no issues)

Area Result
XSS / open redirect (TerraBroadcastPendingLink, getExplorerTxUrl) pendingTxHash is set only from onPhaseChange after wallet.broadcastTx returns — not user/API/query input. React escapes JSX text/attributes; explorer URLs prefix a build-time-trusted base (NETWORKS / chainlist) and append the hash as a path segment — same pattern as existing TxResultAlert. A crafted hash cannot yield a javascript: href.
Authn / authz No server endpoints or signing logic changed. Wallet still gates every broadcast; requireConnectedWalletForAddress unchanged. Phase callbacks are observability only.
Module scope overlap (terraBroadcastScope) activeScopes + scopedExecutionDepth; ambiguous overlap (size !== 1) returns undefined and suppresses callbacks. Misrouting affects button copy only — not tx construction, gas, or approval. isPending disable guards unchanged. 186b82c keeps scope depth until the scoped promise settles (sequential in-mutation UX).
CW20 two-step (executeCw20AllowanceThen) Re-enters scope for follow-up execute; does not skip wallet sign or alter msg construction.
Secrets / logging No new sensitive data logged; public tx hashes only. Pre-existing console.error on broadcast failure unchanged.
Dependencies / supply chain No new packages. localnet-trading-swarm changes are dev-tooling only.

Security review: no medium+ findings on this diff.

## Security review **Commit reviewed:** [`186b82c`](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/commit/186b82cc189042d516ef5973609564380a20e260) **Scope:** 17 files — Terra broadcast phase UI (`onPhaseChange`, `terraBroadcastScope`, `useTerraBroadcastMutation`, `TerraBroadcastPendingLink`), retail surface wiring (Swap, Trade, Limits, Pool), docs, and `localnet-trading-swarm` broadcast helper alignment. **Method:** Full diff review with attacker-controlled-input tracing for injection, XSS/open-redirect, authn/authz bypass, secret leakage, SSRF, and unsafe deserialization. Prior Bugbot threads (global scope misrouting, async `scopedExecutionDepth`) and earlier security reviews on `5944a0c` / `186b82c` re-checked on this head. **Outcome:** **FINDINGS: 0** medium+ No inline security threads — nothing met the medium+ bar with a plausible exploit path. ### Areas examined (no issues) | Area | Result | |------|--------| | **XSS / open redirect** (`TerraBroadcastPendingLink`, `getExplorerTxUrl`) | `pendingTxHash` is set only from `onPhaseChange` after `wallet.broadcastTx` returns — not user/API/query input. React escapes JSX text/attributes; explorer URLs prefix a build-time-trusted base (`NETWORKS` / chainlist) and append the hash as a path segment — same pattern as existing `TxResultAlert`. A crafted hash cannot yield a `javascript:` href. | | **Authn / authz** | No server endpoints or signing logic changed. Wallet still gates every broadcast; `requireConnectedWalletForAddress` unchanged. Phase callbacks are observability only. | | **Module scope overlap** (`terraBroadcastScope`) | `activeScopes` + `scopedExecutionDepth`; ambiguous overlap (`size !== 1`) returns `undefined` and suppresses callbacks. Misrouting affects button copy only — not tx construction, gas, or approval. `isPending` disable guards unchanged. `186b82c` keeps scope depth until the scoped promise settles (sequential in-mutation UX). | | **CW20 two-step** (`executeCw20AllowanceThen`) | Re-enters scope for follow-up execute; does not skip wallet sign or alter msg construction. | | **Secrets / logging** | No new sensitive data logged; public tx hashes only. Pre-existing `console.error` on broadcast failure unchanged. | | **Dependencies / supply chain** | No new packages. `localnet-trading-swarm` changes are dev-tooling only. | **Security review: no medium+ findings on this diff.**
PlasticDigits commented 2026-06-05 09:30:59 +00:00 (Migrated from gitlab.com)

mentioned in commit 531d00ef55

mentioned in commit 531d00ef55525ac30a60d3caf10115dbb972d8dd
PlasticDigits (Migrated from gitlab.com) merged commit 531d00ef55 into main 2026-06-05 09:31:00 +00:00
PlasticDigits commented 2026-06-05 13:44:13 +00:00 (Migrated from gitlab.com)

mentioned in issue #330

mentioned in issue #330
PlasticDigits commented 2026-06-06 07:35:24 +00:00 (Migrated from gitlab.com)

mentioned in merge request !827

mentioned in merge request !827
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!778
No description provided.