Diablo_ClaudeMD_Ricing_example/skills/entry-point-analyzer/references/cosmwasm.md
diablo 50fa79407d
Some checks are pending
CI — CoM Config Validation / Validate JSON Configs (push) Waiting to run
CI — CoM Config Validation / Validate YAML Configs (push) Waiting to run
CI — CoM Config Validation / Lint Shell Scripts (push) Waiting to run
CI — CoM Config Validation / Secret Detection (push) Waiting to run
CI — CoM Config Validation / Lint Markdown (push) Waiting to run
CI — CoM Config Validation / Validate CODEOWNERS (push) Waiting to run
CoM Claude Command Center — sanitized public configuration
Public, sanitized mirror of an AI orchestration command center: agents, skills,
MCP servers, slash-command workflows. All infrastructure identifiers, hostnames,
mesh IPs/subnets, repo paths, maintainer identity, and hardware fleet specifics
scrubbed to <placeholders>; session debug logs and host-specific memory removed.
No live credentials. Verified clean by automated leak sweep. See SANITIZATION.md.

churchofmalware.org . authorized research only
2026-06-10 02:02:03 -04:00

5.3 KiB

CosmWasm Entry Point Detection

Entry Point Identification (State-Changing Only)

Include: State-Changing Entry Points

// Instantiate - called once on deployment
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
    msg: InstantiateMsg,
) -> Result<Response, ContractError> { }

// Execute - main entry point for state changes
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn execute(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
    msg: ExecuteMsg,
) -> Result<Response, ContractError> { }

// Query - read-only entry point
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn query(
    deps: Deps,
    env: Env,
    msg: QueryMsg,
) -> StdResult<Binary> { }

// Migrate - called on contract migration
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(
    deps: DepsMut,
    env: Env,
    msg: MigrateMsg,
) -> Result<Response, ContractError> { }

// Reply - handles submessage responses
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn reply(
    deps: DepsMut,
    env: Env,
    msg: Reply,
) -> Result<Response, ContractError> { }

// Sudo - privileged operations (governance)
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn sudo(
    deps: DepsMut,
    env: Env,
    msg: SudoMsg,
) -> Result<Response, ContractError> { }

Entry Point Types

Entry Point Include? Classification Notes
instantiate Yes One-time setup Sets initial state
execute Yes Main dispatcher Contains multiple operations
query No Read-only EXCLUDE - no state changes
migrate Yes Admin/Governance Requires migration permission
reply Yes Contract-Only Submessage callback
sudo Yes Governance Chain-level privileged

ExecuteMsg Variants (Primary Focus)

#[cw_serde]
pub enum ExecuteMsg {
    Transfer { recipient: String, amount: Uint128 },     // Usually public
    UpdateConfig { admin: Option<String> },              // Admin only
    Pause {},                                            // Guardian
    Withdraw { amount: Uint128 },                        // Public or restricted
}

Access Control Patterns

Cw-Ownable Pattern

use cw_ownable::{assert_owner, initialize_owner};

pub fn execute_admin_action(deps: DepsMut, info: MessageInfo) -> Result<...> {
    assert_owner(deps.storage, &info.sender)?;
    // ...
}

Manual Owner Check

pub fn execute_update_config(deps: DepsMut, info: MessageInfo) -> Result<...> {
    let config = CONFIG.load(deps.storage)?;
    if info.sender != config.owner {
        return Err(ContractError::Unauthorized {});
    }
    // ...
}

Role-Based Access

// Common patterns
if info.sender != state.admin { return Err(Unauthorized); }
if info.sender != state.governance { return Err(Unauthorized); }
if !state.operators.contains(&info.sender) { return Err(Unauthorized); }

// Using cw-controllers
use cw_controllers::Admin;
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;

Access Control Classification

Pattern Classification
assert_owner(storage, &sender) Owner
ADMIN.assert_admin(deps, &sender) Admin
info.sender != config.owner Owner
info.sender != config.admin Admin
info.sender != config.governance Governance
!operators.contains(&sender) Operator
!guardians.contains(&sender) Guardian
No sender check Public (Unrestricted)

Contract-Only Detection

Reply Handler

#[entry_point]
pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result<Response, ContractError> {
    match msg.id {
        INSTANTIATE_REPLY_ID => handle_instantiate_reply(deps, msg),
        _ => Err(ContractError::UnknownReplyId { id: msg.id }),
    }
}

Callback Messages

// Messages expected from other contracts
ExecuteMsg::Callback { ... } => {
    // Should verify sender is expected contract
    if info.sender != expected_contract {
        return Err(ContractError::Unauthorized {});
    }
}

Extraction Strategy

  1. Find Message Enums:

    • ExecuteMsg - main operations (INCLUDE)
    • QueryMsg - read operations (EXCLUDE)
    • SudoMsg - governance operations (INCLUDE)
  2. For Each ExecuteMsg Variant:

    • Find handler function (usually execute_<variant_name>)
    • Check for access control at start of function
    • Classify by access pattern
  3. Map Entry Points:

    • execute dispatcher → enumerate variants (state-changing)
    • querySKIP (read-only, no state changes)
    • sudo → all variants are governance-level
    • reply → contract-only callbacks

CosmWasm-Specific Considerations

  1. Message Info: info.sender is the caller address
  2. Query Has No Sender: Queries are stateless, no access control
  3. Sudo Is Privileged: Only callable by chain governance
  4. Submessages: reply handles responses from submessages
  5. IBC: IBC entry points for cross-chain messages

Common Gotchas

  1. Instantiate Race: First caller sets owner if not careful
  2. Migration Admin: Separate from contract admin
  3. Cw20 Callbacks: Cw20ReceiveMsg is a callback pattern
  4. IBC Callbacks: ibc_packet_receive etc. are entry points
  5. Admin vs Owner: May be different addresses