Fix post-sign broadcast timeout double-execution risk (#359) #867
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!867
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/359-post-sign-broadcast-recovery"
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
Fixes #359: after the wallet signs, a hung RPC broadcast no longer shows a false "Could not broadcast… try again" message that invited double-execution inside the swap deadline window.
terraWalletSignTxRaw.ts): compute tx hash from signed bytes before RPC submit.recovering, show honest "Broadcast status unknown — the transaction may still confirm" copy, poll LCD through the msgdeadline(or 300s default), and only then offer retry.postpath, user reject before sign) keep existingTERRA_TX_BROADCAST_TIMEOUT_MESSAGE.docs/frontend.md,AGENTS_FRONTEND_TX_BROADCAST_TIMEOUT.md,AGENTS_FRONTEND_USER_ERRORS.md.Acceptance checklist
npm run test:unit -- src/services/terraclassic/__tests__/terraBroadcastRecovery.test.ts(broadcast timeout →recovering→ success)npm run test:unit -- src/utils/__tests__/terraTxHash.test.ts+ split-path sign interraWalletSignTxRaw.tspollTxUntilRecoveryDeadline; submit stays disabled viaisPendinguntil resolveterraBroadcastRecovery.test.tsexpectsTERRA_TX_POST_SIGN_NOT_FOUND_MESSAGEtransactions.test.tsbroadcast timeout on atomic mock wallet (no split)TerraBroadcastPendingLink.test.tsx+terraBroadcastUi.test.tsnpm run test:unit(934 tests)make setup-cloud-localterra+ DevTools offline after wallet approve on RPC onlyThird-party verification
Manual (optional): LocalTerra + Simulated Wallet →
/swap→ approve swap → block LCD/RPC (not wallet) → expect Broadcast status unknown…, button disabled with Checking broadcast…, then success if chain unfreezes before deadline.Closes #359 when merged (issue left open per implement workflow).
changed the description
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
cd178131ad. Configure here.Recovery skips LCD at deadline
High Severity
When recovery polling reaches the swap
deadlinefrom the signed msg,pollTxUntilRecoveryDeadlinethrowsTERRA_TX_POST_SIGN_NOT_FOUND_MESSAGEwithout callinggetTx, so a transaction that already confirmed can still surface as not found and invite retry.Reviewed by Cursor Bugbot for commit
cd178131ad. Configure here.Security review
Commit reviewed:
cd178131adbb7309523287177500a068646e8730Scope: MR !867 — post-sign broadcast timeout recovery (#359): split sign/broadcast (
terraWalletSignTxRaw.ts), LCD deadline polling (terraTxRecoveryPoll.ts,terraMsgDeadline.ts), recovery UI phases, timeout copy.Outcome:
FINDINGS: 0medium+Reviewed added/modified frontend broadcast paths for injection, authz bypass, secret leakage, unsafe deserialization, SSRF/XSS, and double-execution regressions. Prior MR security threads: none.
Summary
This change reduces double-execution risk by keeping submit disabled through an honest recovery phase after post-sign RPC/poll timeouts, deriving the tx hash from signed bytes before broadcast, and polling LCD until the on-chain msg
deadline(or 300s default) before offering retry.No medium+ issues identified on this diff:
TxRaw(fixed hex); React text/hrefsinks are not attacker-controlled.wallet.rpcis the connected wallet’s configured endpoint (same trust model as existingpollTx/getTxusage);txHashis not user-supplied.entriesused to build the signed execute msgs; finite-number checks; malformed CW20 innermsgfalls back to default recovery window — no injection path to sinks.bumpWalletCachedSequenceis deferred on broadcast timeout until recovery confirms inclusion, avoiding premature retry with a stale sequence.postexclusion: Station/LuncDash WC retain the pre-MR path (documented); not a new attack surface introduced by this diff.Inline threads: none (no findings to anchor).
changed this line in version 2 of the diff
added 1 commit
839ab90a- fix: query LCD before deadline expiry in recovery poll (#359)Compare with previous version
changed the description
resolved all threads
mentioned in commit
748e36af7bmentioned in issue #337
mentioned in merge request !870
mentioned in issue #368