Repository navigation
Recover Axelar transfers whose failed confirm poll shows as confirmed - #1406
Merged
Merged
Conversation
Axelarscan can report a failed validator poll as status "confirmed" because it records the poll's confirm event alongside confirm_failed. The classifier mapped that to relayer_pending, so no recovery ran and the stuck alert suggested a manual execute on a call that was never approved.
…atus A failed poll reported as "confirmed" (2026-10-06, Base to BSC) never re-polls on its own, but the status loop only recovered status "called".
✅ Deploy Preview for vortex-sandbox ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for vrtx-dashboard canceled.
|
✅ Deploy Preview for vortexfi canceled.
|
Verification only filters candidates, so a finder's misses are final. The Workflow tool also has no model option, so the sonnet directive never applied there.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
On 2026-10-06 a Base -> BSC Squid GMP (0x9813…8ff7) got stuck at "failed to confirm". The validator poll (3258866) ended with
NoEventsConfirmed, and Axelar never re-polls a failed poll by itself.Axelarscan reported the transfer as
status: "confirmed"withconfirm_failed: true, not as"called". It records the failed poll's confirm event alongside the failure. Vortex's recovery only fired for"called", so this transfer was missed:ConfirmGatewayTx.classifyGmpStatusmapped the transfer torelayer_pending, so the stuck monitor didn't recover it either. Its Slack alert also suggested a manual execute on a call that was never approved.What changes
classifyGmpStatusreturnssource_confirmation_stuckforconfirm_failed && !approved && !executed, whatever the status. Theexecutedandinsufficient_gaschecks still run first.SquidRouterPayExecutoruses the same condition. Cooldown, abort handling and the single-keyaxelarConfirmRecoveryAtwrite are unchanged.docs/security-spec/05-integrations/squid-router.mdnow describes the trigger.Once Axelarscan reports
approved, nothing changes: the transfer still goes torelayer_pending/approved_not_executed(#1403).Side effect
If Axelarscan keeps
confirm_failedset after a successful re-poll, we send at most one redundant recovery every 10 minutes until approval. On chain, a confirm for an already-confirmed event succeeds without changing state, so this only wastes the relayer's fee.Tests
"confirmed"+confirm_failedis stuck. Once approved it becomesrelayer_pending, orapproved_not_executedafter the grace period. Executed and insufficient gas still take precedence."confirmed"+confirm_failedshape, with the hash and source chain, and records the cooldown. It does not trigger once approved.bun test squid(api) and the shared Axelar tests pass.