# MsgSwapOrder will never work for Canto nodes

MsgSwapOrder lacks a cosmos.msg.v1.signer annotation, so Canto nodes cannot resolve the signer and the message never executes, blocking arbitrage that keeps onboarding swap prices in range.

- Payout: Audit contest
- Severity: medium
- Program: Canto
- Found by: 0x1771
- Disclosed: 2024-08-19
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2024-05-canto#m-02
- Library page: https://bugbountylibrary.com/r/c4%3A2024-05-canto%3AM-02
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:misconfiguration

**Target:** Cosmos SDK message type (coinswap Input / MsgSwapOrder) in app.go signer registration
**Root cause:** The coinswap Input message has no cosmos.msg.v1.signer option and no DefineCustomGetSigners registration in app.go, so the protov2 signing context cannot derive the signer for MsgSwapOrder.
**Steps:**
1. Inspect coinswap Input proto: only address and coin fields, no (cosmos.msg.v1.signer) option.
2. Compare with erc20v1.MsgConvertERC20 which registers `signingOptions.DefineCustomGetSigners(protov2.MessageName(&erc20v1.MsgConvertERC20{}), erc20types.GetSignersFromMsgConvertERC20V2)` in app.go.
3. Observe MsgSwapOrder has no equivalent DefineCustomGetSigners call, so signer resolution fails and the tx cannot be processed.
4. Consequence: arbitrageurs cannot swap IBC voucher back to Canto to rebalance pool prices after auto-swap onboarding.
**How found:** Code reading of app.go signer registration, noticing MsgConvertERC20 had a custom signer resolver while the coinswap Input message did not, and that the proto lacked the cosmos.msg.v1.signer annotation.
**Exploitation:** Not directly exploitable for theft; the missing arbitrage path lets pool prices drift from auto-swap onboarding, potentially causing slippage/maxSwapAmount checks to fail and denying the onboarding functionality.
**Insight:** When auditing Cosmos SDK chains, diff every custom message against the app.go DefineCustomGetSigners registrations; a message missing both the proto signer annotation and a custom resolver silently becomes unusable, which can break arbitrage/keeper invariants rather than just a single tx.
