Severity: S0 (money-at-risk, user-error amplification)
Location: allways/chain_providers/subtensor.py:276-283, gated by allways/cli/swap_commands/swap.py:751
Bug
SubtensorProvider.is_valid_address only checks 48-char length and Base58 charset via regex — no SS58 checksum. The string 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' passes. The swap flow gates on to_provider.is_valid_address(receive_address), so a user who mistypes their TAO destination gets past the only validation gate. The miner later sends TAO to that literal address and the funds are unrecoverable.
Comparison
- Bitcoin has proper validation via bitcoin.py:319-330 (bech32 / base58check decode).
- The correct SS58 pattern already exists at helpers.py:117-130 wrapping
scalecodec.ss58_decode — but it's only used in admin commands.
Fix
Replace the regex body of SubtensorProvider.is_valid_address with scalecodec.ss58_decode(address) wrapped in try/except. Zero behavior change for legitimate addresses; catches all typos.
The same gap exists for user_from_address at swap.py:757-766 but the validator's sender-mismatch check catches that one on-chain.
Severity: S0 (money-at-risk, user-error amplification)
Location: allways/chain_providers/subtensor.py:276-283, gated by allways/cli/swap_commands/swap.py:751
Bug
SubtensorProvider.is_valid_addressonly checks 48-char length and Base58 charset via regex — no SS58 checksum. The string'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'passes. The swap flow gates onto_provider.is_valid_address(receive_address), so a user who mistypes their TAO destination gets past the only validation gate. The miner later sends TAO to that literal address and the funds are unrecoverable.Comparison
scalecodec.ss58_decode— but it's only used in admin commands.Fix
Replace the regex body of
SubtensorProvider.is_valid_addresswithscalecodec.ss58_decode(address)wrapped in try/except. Zero behavior change for legitimate addresses; catches all typos.The same gap exists for
user_from_addressat swap.py:757-766 but the validator's sender-mismatch check catches that one on-chain.