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
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
5.3 KiB
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
-
Find Message Enums:
ExecuteMsg- main operations (INCLUDE)QueryMsg- read operations (EXCLUDE)SudoMsg- governance operations (INCLUDE)
-
For Each ExecuteMsg Variant:
- Find handler function (usually
execute_<variant_name>) - Check for access control at start of function
- Classify by access pattern
- Find handler function (usually
-
Map Entry Points:
executedispatcher → enumerate variants (state-changing)query→ SKIP (read-only, no state changes)sudo→ all variants are governance-levelreply→ contract-only callbacks
CosmWasm-Specific Considerations
- Message Info:
info.senderis the caller address - Query Has No Sender: Queries are stateless, no access control
- Sudo Is Privileged: Only callable by chain governance
- Submessages:
replyhandles responses from submessages - IBC: IBC entry points for cross-chain messages
Common Gotchas
- Instantiate Race: First caller sets owner if not careful
- Migration Admin: Separate from contract admin
- Cw20 Callbacks:
Cw20ReceiveMsgis a callback pattern - IBC Callbacks:
ibc_packet_receiveetc. are entry points - Admin vs Owner: May be different addresses