Skip to content
Security
Skill

/ref-lifecycle

Type Thought-template (instantiate before use) - Trigger Pattern Always (Aptos Move) -- ConstructorRef/TransferRef/MintRef/BurnRef lifecycle

From plugin
plamen
276160 skills12 agents4 commands
Install
$ npx -y skills add PlamenTSV/plamen --skill ref-lifecycle --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/ref-lifecycle

Context preview

The summary Claude sees to decide when to auto-load this skill.

Type Thought-template (instantiate before use) - Trigger Pattern Always (Aptos Move) -- ConstructorRef/TransferRef/MintRef/BurnRef lifecycle

SKILL.md

ref-lifecycle.SKILL.md
name: "ref-lifecycle"
description: "Type Thought-template (instantiate before use) - Trigger Pattern Always (Aptos Move) -- ConstructorRef/TransferRef/MintRef/BurnRef lifecycle"

Skill: Reference Lifecycle Analysis

> **Type**: Thought-template (instantiate before use) > **Trigger Pattern**: Always (Aptos Move) -- ConstructorRef/TransferRef/MintRef/BurnRef lifecycle > **Inject Into**: Breadth agents, depth-state-trace, depth-token-flow > **Research basis**: Aptos Object model capability-based access control, permanent reference semantics

Background

In Aptos Move, object capabilities (Refs) are unforgeable tokens that grant specific permissions over objects. Unlike role-based access control in EVM, Refs are permanent once created -- they CANNOT be revoked. A leaked or improperly stored Ref grants permanent capability to its holder.

Key Ref types:

  • **ConstructorRef**: Created once during `object::create_*`. Parent of all other Refs. Grants ability to generate TransferRef, MintRef, BurnRef, DeleteRef, and ExtendRef.
  • **TransferRef**: Grants ability to transfer an object even when its `TransferRef` is frozen. Bypasses `ungated_transfer` restrictions.
  • **MintRef**: Grants ability to mint FungibleAsset. Unlimited minting if held.
  • **BurnRef**: Grants ability to burn FungibleAsset from any FungibleStore.
  • **DeleteRef**: Grants ability to delete an object.
  • **ExtendRef**: Grants ability to generate a signer for the object, enabling further resource manipulation.

Trigger Patterns

ConstructorRef|TransferRef|MintRef|BurnRef|DeleteRef|ExtendRef|
object::create_named_object|object::create_sticky_object|object::create_object|
fungible_asset::generate_mint_ref|fungible_asset::generate_burn_ref|
fungible_asset::generate_transfer_ref|object::generate_delete_ref|
object::generate_extend_ref|object::generate_transfer_ref

Reasoning Template

Step 1: Reference Inventory

Enumerate ALL Ref types found in the codebase. For each:

| Ref Type | Created In (module::function) | Stored Location | Access Control | Capability Granted | |----------|-------------------------------|-----------------|----------------|--------------------| | ConstructorRef | {module}::{init_fn} | {consumed / stored in resource} | {who can access} | Generate all other Refs | | MintRef | {module}::{init_fn} | {global resource at @addr} | {who can access} | Unlimited minting of {asset} | | BurnRef | {module}::{init_fn} | {global resource at @addr} | {who can access} | Burn {asset} from any store | | TransferRef | {module}::{init_fn} | {global resource at @addr} | {who can access} | Transfer {asset} bypassing freeze | | DeleteRef | {module}::{init_fn} | {global resource at @addr} | {who can access} | Delete {object} | | ExtendRef | {module}::{init_fn} | {global resource at @addr} | {who can access} | Generate signer for {object} |

**Completeness check**: Search for ALL `generate_*_ref` calls and `object::create_*` calls. Every Ref created MUST appear in the table.

Step 2: ConstructorRef Analysis

The ConstructorRef is the root capability. It exists only during the `init_module` or object creation call.

**Check 2a: Is ConstructorRef stored?**

  • Search for any struct field of type `ConstructorRef` -- this type has `drop` but NOT `store`, so it CANNOT be stored in global storage directly.
  • If code attempts to extract a signer from ConstructorRef via `object::generate_signer(&constructor_ref)` and stores the signer reference indirectly, trace what that signer can do.
  • **Expected pattern**: ConstructorRef is consumed during init to generate other Refs, then dropped. It should NOT persist beyond the creation transaction.

**Check 2b: What Refs are generated from it?**

  • List every `generate_*_ref` call that uses this ConstructorRef
  • For each generated Ref: is it stored with appropriate access control?
  • **FINDING trigger**: If ConstructorRef generates MintRef AND that MintRef is stored with `public` visibility or weak access control -> unlimited minting capability leak.

**Check 2c: ExtendRef derived signer**

  • If `object::generate_extend_ref` is called, the resulting ExtendRef can later produce a signer via `object::generate_signer_for_extending`
  • Trace ALL uses of this derived signer -- it can move resources, modify object state, and call `move_to`/`move_from`
  • **FINDING trigger**: If ExtendRef is stored with weaker access control than the operations its signer can perform.

Step 3: MintRef / BurnRef Analysis

**Check 3a: Storage access control**

  • Where is MintRef stored? (must be in a resource at a controlled address)
  • Who can call functions that borrow the MintRef? (check `acquires` and signer requirements)
  • Is there any `public fun` that exposes MintRef via return value or mutable reference?
  • **FINDING trigger**: `public fun` returning `&MintRef` or `&mut MintRef` = capability leak to any module.

**Check 3b: Mint amount validation**

  • Does the minting function validate the amount? (cap, rate limit, per-epoch limit)
  • Is there a supply cap enforced? (`fungible_asset::supply` check before mint)
  • **FINDING trigger**: Unlimited minting with no cap = inflation vulnerability.

**Check 3c: BurnRef scope**

  • `fungible_asset::burn_from` with a BurnRef can burn tokens from ANY FungibleStore
  • Check: does the burn function require the store owner's authorization, or only the BurnRef?
  • **FINDING trigger**: If BurnRef holder can burn from arbitrary user stores without authorization.

**Check 3d: Mint/Burn symmetry**

  • If protocol has both MintRef and BurnRef: are they held by the same entity?
  • Can one be used without the other? (mint without ability to burn = permanent inflation; burn without mint = permanent deflation)
  • Are there economic invariants that depend on mint/burn balance?

Step 4: TransferRef Analysis

**Check 4a: Freeze bypass**

  • `fungible_asset::transfer_with_ref` bypasses frozen store checks
  • If the protocol uses `fungible_asset::set_frozen_flag` for compliance/security
Read more
Ships withplamen

Autonomous Web3 security auditor for Claude Code and OpenAI Codex CLI. Orchestrates 18-100 AI agents across 40+ phases to produce audit reports with verified PoC exploits — for smart contracts and L1 node-client infrastructure.

Get the whole plugin