Filed from the second-wave repository audit (issue 16/100). See the audit summary for full category context.
- Location:
backend/src/services/sorobanService.ts:253-259
- Problem:
submitContractCall only checks response.status !== 'ERROR' (accepted, not confirmed) and returns immediately; topUpStreamHandler/cancelStreamHandler then commit DB changes right after, before knowing whether the transaction actually succeeded on-chain.
- Evidence: No
getTransaction poll-for-final-status call after sendTransaction.
- Suggested implementation: Poll
getTransaction for a terminal status (success/failed) with a bounded timeout before committing DB mutations, or mark the DB row pending and reconcile via the indexer.
- Acceptance criteria: A simulated on-chain failure after acceptance leaves the DB unchanged (or reconciled), covered by a test that mocks a post-submission failure.
- Difficulty: L
- Expected impact: Prevents permanent DB/chain divergence when a transaction is accepted into the mempool but later fails.
backend/src/services/sorobanService.ts:253-259submitContractCallonly checksresponse.status !== 'ERROR'(accepted, not confirmed) and returns immediately;topUpStreamHandler/cancelStreamHandlerthen commit DB changes right after, before knowing whether the transaction actually succeeded on-chain.getTransactionpoll-for-final-status call aftersendTransaction.getTransactionfor a terminal status (success/failed) with a bounded timeout before committing DB mutations, or mark the DB rowpendingand reconcile via the indexer.