Cosmos / CosmWasm Security Scanner

SkillCommunication

Use when the user wants to audit Cosmos SDK modules or CosmWasm smart contracts, scan IBC protocol interactions for relay, channel, or packet vulnerabilities, review Cosmos Go modules for state machine exploits, or analyze cross-chain message handling in the Cosmos ecosystem.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Cosmos / CosmWasm Security Scanner skill

What this skill tells your AI

The instructions your AI receives, as published by 0x-shashi/web3-audit-skills in skills/cosmos-scanner/SKILL.md and read by ahel’s review.

Security scanner for Cosmos SDK modules (Go), CosmWasm smart contracts (Rust/WASM), and Inter-Blockchain Communication (IBC) protocol interactions.


Language & Runtime

AttributeValue
ChainCosmos Hub, Osmosis, Juno, Neutron, Injective, Sei, + 60 app-chains
Smart Contract LanguageRust (compiled to WASM)
SDK LanguageGo (custom Cosmos SDK modules)
VMCosmWasm (WASM-based)
Token StandardCW20 (fungible), CW721 (NFT), CW1155 (multi-token)
Key Frameworkcosmwasm-std, Cosmos SDK
Storage ModelKey-value store (binary prefixed maps)
Gas ModelGas consumed per operation, configurable per chain

Detection Capabilities

CategoryDetectionSeverity
AuthorizationMissing info.sender check on Execute handlersCritical
AuthorizationKeeper function callable without proper auth (SDK modules)Critical
AuthorizationAuthZ overly broad grants enabling privilege escalationHigh
IBCPacket source/destination validation missingCritical
IBCChannel ordering assumption violationHigh
IBCTimeout and acknowledgement handling errorsHigh
StateUnbounded range() iteration (gas DoS)High
StateIterator invalidation during mutationHigh
StateStorage key collision in multi-contract systemsMedium
Cross-ContractSubMessage reply handler not checking msg_idHigh
Cross-ContractBank send reentrancy via SubMessage replyMedium
MathUint128/Uint256 overflow (panics in debug, wraps in release)High
MathDecimal256 precision loss in rate calculationsMedium
GovernanceParameter manipulation via governance proposalMedium
GovernanceAdmin key not removable (centralization)Medium
BlockHooksBeginBlocker/EndBlocker gas consumption DoS (SDK modules)High
Migrationmigrate() entry point without access controlCritical

Architecture Model: CosmWasm Contracts

┌────────────────────────────────────────────────┐
│  CosmWasm Contract Entry Points               │
├────────────┬───────────┬───────────┬───────────┤
│ instantiate │ execute    │ query      │ migrate    │
│ (once)      │ (state)    │ (read)     │ (upgrade)  │
└────────────┴───────────┴───────────┴───────────┘
        │                                      │
   State (Items, Maps, SnapshotMaps)    SubMessages
        │                                      │
   Storage (KV Store)               Reply Handler

Entry Point Security Model

Entry Pointinfo.senderState AccessSecurity Focus
instantiateContract deployerWriteSet admin, validate config
executeTransaction signerWritePrimary attack surface
queryNot availableRead-onlyGas DoS, expensive computation
migrateContract adminWriteMust check authorization
replyContract itselfWriteSubMessage result handling
sudoChain governanceWritePrivileged chain operations

Notable Cosmos/CosmWasm Vulnerabilities

IncidentChainIssueImpact
Osmosis LP bug (2022)OsmosisRounding error in LP share calculation$5M at risk (white-hat)
Juno whale governance (2022)JunoGovernance used to confiscate tokensGovernance centralization debate
Terra UST depeg (2022)TerraAlgorithmic stablecoin design flaw~$40B market value lost
Wormhole bridge (2022)MultiGuardian signature verification bypass$320M stolen
CW20 unlimited mintVariousMissing admin check on mint executeToken inflation
IBC race conditionVariousPacket ordering assumption violatedToken duplication

Key Vulnerability Patterns

1. Missing info.sender Check

// VULNERABLE: Anyone can call
pub fn execute_withdraw(
    deps: DepsMut,
    _info: MessageInfo,  // sender not checked!
    amount: Uint128,
) -> Result<Response, ContractError> {
    // Withdraws funds without checking who's requesting
    let msg = BankMsg::Send {
        to_address: "attacker".to_string(),
        amount: vec![Coin { denom: "uatom".to_string(), amount }],
    };
    Ok(Response::new().add_message(msg))
}

// SAFE: Validates caller
pub fn execute_withdraw(
    deps: DepsMut,
    info: MessageInfo,
    amount: Uint128,
) -> Result<Response, ContractError> {
    let config = CONFIG.load(deps.storage)?;
    if info.sender != config.admin {
        return Err(ContractError::Unauthorized {});
    }
    // Proceed with withdrawal...
}

2. Unbounded State Iteration

// VULNERABLE: Iterates ALL entries — gas DoS as state grows
pub fn query_all_balances(deps: Deps) -> StdResult<Vec<(Addr, Uint128)>> {
    let result: Vec<_> = BALANCES
        .range(deps.storage, None, None, Order::Ascending)
        .collect::<StdResult<Vec<_>>>()?;  // Unbounded!
    Ok(result)
}

// SAFE: Paginated with limit
pub fn query_balances(
    deps: Deps,
    start_after: Option<Addr>,
    limit: Option<u32>,
) -> StdResult<Vec<(Addr, Uint128)>> {
    let limit = limit.unwrap_or(30).min(100); // Cap at 100
    let start = start_after.map(Bound::exclusive);
    let result: Vec<_> = BALANCES
        .range(deps.storage, start, None, Order::Ascending)
        .take(limit as usize)
        .collect::<StdResult<Vec<_>>>()?;
    Ok(result)
}

3. SubMessage Reply Handler Bug

// VULNERABLE: Reply handler doesn't check which SubMessage triggered it
#[entry_point]
pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractError> {
    // Assumes all replies are from the token transfer SubMessage
    // But could be from any SubMessage!
    handle_transfer_reply(deps, msg)
}

// SAFE: Checks reply ID
const TRANSFER_REPLY_ID: u64 = 1;
const MINT_REPLY_ID: u64 = 2;

#[entry_point]
pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result<Response, ContractError> {
    match msg.id {
        TRANSFER_REPLY_ID => handle_transfer_reply(deps, msg),
        MINT_REPLY_ID => handle_mint_reply(deps, msg),
        _ => Err(ContractError::UnknownReplyId { id: msg.id }),
    }
}

Resources

Workflows

Error Code Reference

Common Cosmos SDK, CosmWasm, and IBC error codes encountered during audits.

CosmWasm Standard Errors

Error TypeError NameMeaning
StdError::NotFoundNotFound { kind }Queried item not found in storage
StdError::InvalidBase64InvalidBase64 { msg }Invalid base64 encoding in message
StdError::InvalidUtf8InvalidUtf8 { msg }Invalid UTF-8 in string conversion
StdError::OverflowOverflow { source }Arithmetic overflow in Uint128/Uint256 operations
StdError::DivideByZeroDivideByZero { source }Division by zero in math operation
StdError::ConversionOverflowConversionOverflow { source }Type conversion exceeds target range
StdError::GenericErrGenericErr { msg }Catch-all error — check msg for specifics

Cosmos SDK Module Errors

ModuleCodespaceError CodeMeaning
bankbank5Insufficient funds for send
bankbank8Send disabled for denom
stakingstaking5Validator not found
stakingstaking7Delegation not found
stakingstaking12Insufficient shares for undelegation
authauth4Insufficient fee
authauth9Signature verification failed
govgov3Unknown proposal
govgov5Inactive proposal — voting period ended

IBC Protocol Errors

ModuleError CodeMeaning
channel5Channel not found
channel11Packet already received — replay protection
channel17Packet timeout — message expired
connection5Connection not found
transfer3Invalid denomination trace
transfer6Receive disabled on this channel
client6Client state not found
client9Consensus state not found

Troubleshooting

IssueLikely CauseSolution
IBC message handling vulnerabilities missedScanner only checks contract logic, not IBC layerLoad resources/ibc-security.md and audit ibc_packet_receive / ibc_packet_ack handlers
CosmWasm reply handler issues not detectedScanner doesn't follow submessage flowTrace all SubMsg with ReplyOn::Success/ReplyOn::Error and match reply IDs
State machine exploit not flaggedScanner checks individual messages, not sequencesAnalyze multi-message transaction flows for state inconsistencies
Missing sudo handler auditScanner focuses on execute/query onlyCheck sudo() entry point — often used for privileged chain-level operations
Gas griefing not detectedScanner doesn't model gas costsFlag unbounded loops/iterations in execute and query handlers
Cross-contract call risks missedScanner doesn't trace inter-contract callsMap all WasmMsg::Execute and WasmQuery::Smart calls to external contracts

Signals

GitHub stars
60
Forks
10
Last commit
Feb 2026
Advanced
Catalog kind
skill
Gateway key
cosmos-scanner
Source
github.com/0x-shashi/web3-audit-skills