Validate destination address at swap confirm and CLI entry#50
Merged
LandynDev merged 1 commit intoentrius:testfrom Apr 18, 2026
Merged
Conversation
LandynDev
approved these changes
Apr 18, 2026
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.
Summary
An empty or malformed
to_addresscurrently flows through the swap-confirm path intovote_initiateuntouched. The CLI side prints a soft warning and then proceeds anyway. Both entry points should reject a bad destination before it leaves the validator or the user's terminal.Changes
Validator (
handle_swap_confirminallways/validator/axon_handlers.py):to_addressis rejected before the axon lock is acquired, matching the existing pattern forfrom_addressandfrom_tx_proof.resolve_swap_directionreturns, the destination-chain provider is looked up andis_valid_address(synapse.to_address)is checked. Missing provider or failed format check rejects the synapse before the source-chain tx fetch runs.CLI (
alw swap nowinallways/cli/swap_commands/swap.py):hasattr(provider, 'is_valid_address')guard is removed because the method is abstract onChainProviderand every provider already implements it.Why this layer
A queued
PendingConfirmcarrying a garbageto_addressotherwise sits in the validator state store until either the reservation expires or the auto-initiate replay hits it, blocking the miner from being reserved for a legitimate swap in the meantime. Catching athandle_swap_confirmavoids that trap and also keeps the contract from seeing values it would have to reject anyway.Tests
tests/test_axon_handlers.pyis new. It covers every rejection branch ofhandle_swap_confirm, including the two added checks, plus the queue-on-unconfirmed path, reservation expired, reservation data missing, no commitment, same-chain commitment, unsupported direction, unsupported source chain, unsupported destination chain, source tx not found, contract rejection, non-rejection contract error, and unexpected exception. This handler had no unit coverage before.Local run: