omermaksutii/rugproof/cosmwasm
Claude Code and agent skill by omermaksutii/rugproof
- community
Checking that the SKILL.md file is still in the repository.
Detect bug classes specific to CosmWasm (Rust) contracts — missing info.sender authorization in execute handlers, unbounded map iteration → gas/DoS, reply/submessage reply_id confusion, migrate admin backdoors, addr_validate vs raw string addresses, unchecked info.funds, Uint128 overflow, query reentrancy, and migration/version state. Activate on any `.rs` file with `use cosmwasm_std`, `#[entry_point]`, `ExecuteMsg`, `InstantiateMsg`, `QueryMsg`, `cw_storage_plus`, or `DepsMut`.
Install
npx vskill@latest install omermaksutii/rugproof/cosmwasmSKILL.md
CosmWasm (Rust) detection
When this applies
- Any
.rsfile importingcosmwasm_std(use cosmwasm_std::{...}) - Macros/attrs
#[entry_point],#[cw_serde]; enumsExecuteMsg,InstantiateMsg,QueryMsg,MigrateMsg,SudoMsg cw_storage_plustypesMap,Item,IndexedMap;DepsMut/Deps,MessageInfo,EnvSubMsg,Reply,reply(),set_contract_version,cw2
CosmWasm has no msg.sender-gated visibility and no implicit auth. Every execute branch is callable by anyone unless the handler checks info.sender.
Detection patterns
Missing info.sender authorization in execute (CRITICAL)
Signal: an ExecuteMsg arm that mutates privileged state (admin, owner, mint, withdraw, pause) with no if info.sender != cfg.admin { return Err(Unauthorized) }. Anyone can dispatch any message.
Unbounded map iteration → gas exhaustion DoS (HIGH)
Signal: .range(.., None, None, ..) / .keys(..) over a user-growable Map inside execute, or a loop whose length attackers control. Each entry costs gas; an attacker inflates the map until the handler always runs out of gas (permanent freeze). Paginate with start_after + limit.
reply_id confusion / unvalidated submessage reply (HIGH)
Signal: a reply handler that doesn't match msg.id { ... } against known reply IDs, or .unwrap()s msg.result/msg.result.data, or trusts SubMsgResult data without checking it came from the expected submessage. Different submessages can land in the same reply with attacker-influenced data.
migrate admin backdoor / unguarded migrate (HIGH)
Signal: migrate that overwrites owner/config from MigrateMsg without checking set_contract_version/get_contract_version (downgrade or replay), or a centralization risk where the code-admin can swap logic+state at will. Even with chain-level migrate auth, document who holds the admin.
addr_validate vs raw string address (MEDIUM-HIGH)
Signal: Addr::unchecked(...) on user input, or storing/using a String address without deps.api.addr_validate(&s)?. Unvalidated/un-normalized addresses split balances across casing/bech32 variants and break invariants.
Unchecked info.funds (HIGH)
Signal: crediting a deposit from a message field instead of info.funds, or not asserting info.funds contains the expected denom AND amount (must_pay/one_coin from cw_utils). Also flag handlers that ignore unexpected attached funds.
Uint128 / Uint256 overflow & raw arithmetic (HIGH)
Signal: Uint128/Uint256 +/-/* where overflow should be a domain error vs a panic, OR casting to/from primitive u128/u64 with as/.u128() in accounting. Prefer checked_add/checked_sub/checked_mul returning OverflowError.
Query reentrancy / cross-contract query trust (MEDIUM)
Signal: acting on a query_wasm_smart result from a user-supplied contract address, or assuming queries are side-effect-free guarantees (a malicious queried contract returns adversarial data). Validate the oracle/contract address against an allowlist.
Severity rubric
| Pattern | Severity | Notes | |
|---|---|---|---|
Execute arm mutating privileged state, no info.sender check | Critical | Anyone seizes admin/funds | |
Unbounded .range(None,None) over user-growable map | High | Permanent gas-DoS freeze | |
reply without match msg.id / unwrap of result | High | Cross-submsg data confusion | |
migrate overwrites owner/config unguarded | High | Logic+state backdoor | |
Deposit credited from field, not info.funds | High | Free credit / fund theft | |
Uint128 overflow / lossy primitive cast | High | Value-dependent | |
Addr::unchecked on user input | Medium | Address-spoof / split state | |
| Acting on query result from unvalidated contract | Medium | Oracle-trust dependent |
Remediation patterns
- Authorize first — every privileged
executearm starts withensure_eq!(info.sender, cfg.admin, ContractError::Unauthorized {}). - Paginate iteration —
start_after+ boundedlimit(e.g. 30); never.range(None, None)over attacker-growable maps inexecute. - Match reply IDs — declare
const REPLY_X: u64,match msg.id { REPLY_X => ..., _ => Err(...) }, and validateSubMsgResultbefore trusting its data. - Guard migrate — check
cw2::get_contract_version, reject downgrades, and document the migrate-admin in centralization disclosures. - Validate addresses —
deps.api.addr_validate(&s)?, neverAddr::uncheckedon user input. - Verify funds — use
cw_utils::must_pay/one_coinagainstinfo.funds; reject unexpected denoms. - `checked_*` math on
Uint128/Uint256; avoidas/.u128()casts in accounting.
False-positive notes
Addr::uncheckedis acceptable in tests and when re-loading an address the contract itself validated and stored earlier.- An
executearm that is intentionally permissionless (e.g. publicClaim {}keyed byinfo.sender) needs no admin check — confirm it can only affect the caller's own state. Uint128+/-already returns anOverflowError(not a silent wrap) — the real risk is primitiveu128/ascasts andDecimalscaling; focus there.- A bounded
.range(.., Some(limit))is fine.
Related
- [[access-control]] — CosmWasm has no implicit sender gate; every execute arm is public
- [[dos-vectors]] — unbounded map iteration is the canonical CosmWasm gas-freeze
- [[centralization-risk]] — migrate/admin powers concentrate upgrade + state control
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/cosmwasm/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/omermaksutii/rugproof/cosmwasm)