Diablo_ClaudeMD_Ricing_example/skills/entry-point-analyzer/references/vyper.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

3.8 KiB

Vyper Entry Point Detection

Entry Point Identification (State-Changing Only)

Include: State-Changing Functions

@external                    # State-changing entry point
def function_name():
    pass

@external
@payable                     # State-changing, receives ETH
def payable_function():
    pass

@external
@nonreentrant("lock")        # State-changing with reentrancy protection
def protected():
    pass

Exclude: Read-Only Functions

@external
@view                        # EXCLUDE - cannot modify state
def read_only():
    pass

@external
@pure                        # EXCLUDE - no state access
def pure_function():
    pass

Decorator Matrix

Decorators Include? Notes
@external Yes State-changing entry point
@external @payable Yes State-changing, receives ETH
@external @nonreentrant Yes State-changing with protection
@external @view No Read-only, exclude
@external @pure No No state access, exclude
@internal No Not externally callable
@deploy No Constructor (Vyper 0.4+)

Special Entry Points

@external
@payable
def __default__():           # Fallback function (receives ETH + unmatched calls)
    pass

Access Control Patterns

Owner Pattern

owner: public(address)

@external
def restricted_function():
    assert msg.sender == self.owner, "Not owner"
    # ...

Role-Based Patterns

# Common patterns
admin: public(address)
governance: public(address)
guardian: public(address)
operator: public(address)

# Mapping-based roles
authorized: public(HashMap[address, bool])
minters: public(HashMap[address, bool])

@external
def mint(to: address, amount: uint256):
    assert self.minters[msg.sender], "Not minter"
    # ...

Access Control Classification

Pattern Classification
assert msg.sender == self.owner Admin/Owner
assert msg.sender == self.admin Admin
assert msg.sender == self.governance Governance
assert msg.sender == self.guardian Guardian
assert self.authorized[msg.sender] Review Required
assert self.whitelist[msg.sender] Review Required

Contract-Only Detection

Callback Functions

@external
def onERC721Received(...) -> bytes4:
    return method_id("onERC721Received(address,address,uint256,bytes)")

@external
def uniswapV3SwapCallback(amount0: int256, amount1: int256, data: Bytes[...]):
    # Must verify caller is the pool
    pass

Contract-Caller Checks

assert msg.sender == self.pool, "Only pool"
assert msg.sender != tx.origin, "No EOA"  # Vyper 0.3.7+

Extraction Strategy

  1. Parse all .vy files
  2. For each function:
    • Check for @external decorator
    • Skip functions with @view or @pure decorators
    • Record function name and parameters
    • Record line number
    • Check for access control assertions in function body
  3. Classify:
    • No access assertions → Public (Unrestricted)
    • msg.sender == self.X → Check what X is
    • self.mapping[msg.sender] → Review Required
    • Known callback name → Contract-Only

Vyper-Specific Considerations

  1. No Modifiers: Vyper doesn't have modifiers—access control is inline assert statements
  2. No Inheritance: Each contract is standalone (interfaces only)
  3. Explicit is Better: All visibility must be declared explicitly
  4. Default Internal: Functions without decorators are internal

Common Gotchas

  1. Initializer Pattern: Look for initialized: bool flag with one-time setup
  2. Raw Calls: raw_call() can delegate to other contracts
  3. Create Functions: create_minimal_proxy_to(), create_copy_of() are factory patterns
  4. Reentrancy: @nonreentrant protects against reentrancy but function is still entry point