Agent skill

migration-analysis

Trigger Pattern Program upgrades, account data layout changes, deprecated instructions, token migrations - Inject Into Breadth agents, depth-state-trace

Stars 215
Forks 33

Install this agent skill to your Project

npx add-skill https://github.com/PlamenTSV/plamen/tree/main/agents/skills/solana/migration-analysis

SKILL.md

Skill: Migration Analysis (Solana)

Trigger Pattern: Program upgrades, account data layout changes, deprecated instructions, token migrations Inject Into: Breadth agents, depth-state-trace Finding prefix: [MG-N] Rules referenced: S1, S3, S4, S9, R4, R9, R10

upgrade|authority|reinitialize|deprecated|migrat|legacy|v2|V2|old_mint|new_mint|
BPFLoaderUpgradeable|set_authority|close_account

Reasoning Template

Step 1: Identify Token and Account Transitions

Find all migration patterns:

  • Old mint -> New mint (SPL Token migrations, token rebranding, Token-2022 migration)
  • Deprecated instructions still callable
  • Account data layout changes across program versions
  • PDA seed schema changes

For each transition:

Old Entity New Entity Migration Instruction Bidirectional? Account Type

Step 2: Check Account Data Layout Compatibility

For each program upgrade that changes account data structures:

  1. What fields exist in the OLD account data layout?
  2. What fields exist in the NEW account data layout?
  3. Are new fields APPENDED (safe) or INSERTED/REORDERED (breaking)?
  4. Does the discriminator change between versions? (Anchor uses first 8 bytes)
rust
// Example mismatch:
// V1 layout: [discriminator(8)][authority(32)][amount(8)]  = 48 bytes
// V2 layout: [discriminator(8)][authority(32)][new_field(8)][amount(8)] = 56 bytes
// BREAKING: V1 accounts read `amount` at offset 40, but V2 expects it at offset 48
Account Type V1 Layout (fields + offsets) V2 Layout (fields + offsets) Compatible? Migration Path

Step 3: Trace Account Flow Paths

For each instruction that interacts with migrated accounts:

  1. Entry point: What account data version does the user provide?
  2. Internal flow: What version does the program expect?
  3. CPI calls: What version do CPI target programs expect?
  4. Return data: What version does the program write back?
Instruction Account Expected Actual Account Version CPI Target Expects Mismatch?

Step 3b: CPI Side Effect Compatibility

When migration changes program behavior, check whether CPI callers handle the changes:

CPI Call Pre-Migration Behavior Post-Migration Behavior Caller Handles Both? Mismatch?

Pattern: Program upgrade changes return data or account mutations from a CPI, but callers were written for the old behavior. After upgrade, CPI results are misinterpreted.

Step 3c: Pre-Upgrade Account Inventory

Before analyzing stranded asset paths, inventory all accounts the program owns:

Account Type How Created Current Lamports/Tokens Post-Upgrade Logic Handles? Close Path Post-Upgrade?
{pda_vault} PDA init SOL + SPL tokens YES/NO {instruction or NONE}
{user_state} User init Rent-exempt SOL YES/NO {instruction or NONE}
{legacy_acct} V1 init Held from V1 ops YES/NO {instruction or NONE}

Pattern: Upgrade changes which accounts the program reads/writes, but old accounts still hold SOL (rent) and tokens. If new logic cannot close or drain old accounts, assets are stranded.

Step 4: Stranded Asset Analysis (ENHANCED)

4a. Asset Inventory by Era

Asset/Account V1 Creation Path V2 Creation Path V1 Close Path V2 Close Path
{pda_vault} initialize() initialize_v2() close_vault() close_vault_v2()
{user_account} create_user() create_user() close_user() close_user()

Rule: If V1 Creation exists but V2 Close doesn't handle V1 state -> potential stranding.

4b. Cross-Era Path Matrix

Account Era State Condition Available Close/Drain Paths Works? Reason
V1 PDA vault V2 program deployed close_vault_v2() Y/N {why}
V1 PDA vault V1 instruction removed close_vault() Y/N {why}
V1 user state In-flight during upgrade ??? Y/N {why}

STRANDING RULE: If ALL close/drain paths fail for any account state -> STRANDED ASSETS FINDING

4c. Recovery Function Inventory

Function Who Can Call What Accounts Can Recover Limitations
close_account() Authority only Program-owned accounts Requires active authority
migrate_v1() Any user V1 user accounts One-time per account
sweep_lamports() Authority Unclaimed rent Cannot recover user deposits

4d. Worst-Case Scenarios (MANDATORY)

Scenario 1: V1 Account + V2 Program

State: User created account via V1 initialize() with deposited tokens
Event: Program upgraded to V2 with new data layout
Question: Can user close/withdraw via V2 instructions?
Trace: [document instruction path and deserialization]
Result: [SUCCESS/STRANDED + amount]

Scenario 2: In-Flight During Upgrade

State: User initiated multi-instruction operation (e.g., unstake request) at slot N
Event: Program upgrade deployed at slot N+1
Question: Can user complete operation at slot N+2?
Trace: [document instruction path]
Result: [SUCCESS/STRANDED + amount]

Scenario 3: PDA Seed Change

State: PDA derived with seeds [b"vault", user.key()] in V1
Event: V2 changes seeds to [b"vault_v2", user.key()]
Question: Can V2 program access the V1 PDA? Are V1 tokens recoverable?
Trace: [document PDA derivation and account lookup]
Result: [SUCCESS/STRANDED + amount]

4e. Step 4 Completion Checklist

  • 4a: ALL accounts inventoried with creation/close paths per era
  • 4b: Cross-era path matrix completed for all state combinations
  • 4c: Recovery instructions enumerated with limitations
  • 4d: All three worst-case scenarios modeled with traces
  • For EVERY stranding possibility: recovery path exists OR finding created

Step 4f: User-Blocks-Admin Scenarios

Admin/Migration Instruction Precondition Required User Action That Blocks It Timing Window Severity
{admin_ix} {precondition} {user_action} {window} {assess}

Solana-specific patterns:

  • User creates token accounts owned by program PDA -> non-zero balance prevents PDA closure
  • User initiates pending operations (unstake, withdrawal request) -> in-flight state blocks migration
  • User creates many small accounts -> iteration over accounts exceeds CU limit for admin migration instruction

Step 5: Upgrade Authority Lifecycle

Check Status Evidence
Upgrade authority identified? {pubkey or multisig} {source location}
Is authority a multisig (Squads)? YES/NO
Can authority be revoked (program made immutable)? YES/NO
If revoked: are all config parameters frozen? YES/NO
If revoked: can stranded assets be recovered? YES/NO Apply Rule 9
Buffer validation during upgrade? YES/NO Can malicious buffer be substituted?
IDL discriminator stability? YES/NO Changed discriminators break all callers

Step 6: Downstream Integration Compatibility

Program Change Downstream Consumer Expected Interface Post-Migration Actual Breaking?
{change} CPI callers {expected IDL} {actual IDL} YES/NO
{change} Indexers (Geyser, Helius) {expected account layout} {actual layout} YES/NO
{change} Frontend/SDK {expected instruction format} {actual} YES/NO

Pattern: Program upgrade changes instruction discriminators, account layouts, or CPI behavior, but downstream consumers (other programs calling via CPI, indexers, SDKs) were built for the old interface.

Key Questions (Must Answer All)

  1. Data Layout: Are ALL existing accounts readable by the new program version?
  2. PDA Stability: Do ALL PDAs remain derivable with the same seeds after upgrade?
  3. Migration Completeness: Can ALL V1 accounts be migrated/closed via V2 paths?
  4. Stranded Assets: Is there any combination of (old_account_state + new_program) that traps funds?
  5. Authority Lifecycle: Is the upgrade authority appropriately secured and revocable?

Common False Positives

  1. Append-only layout changes: New fields added at end with defaults -- backward compatible
  2. Versioned deserialization: Program explicitly handles both V1 and V2 layouts
  3. Admin-controlled migration: Stranded accounts recoverable via authority instructions

Finding Template

markdown
**ID**: [MG-N]
**Verdict**: CONFIRMED / PARTIAL / REFUTED / CONTESTED
**Step Execution**: (see checklist below)
**Rules Applied**: [S1:___, S3:___, S4:___, S9:___, R4:___, R9:___, R10:___]
**Severity**: Critical/High/Medium/Low/Info
**Location**: programs/{program}/src/{file}.rs:LineN

**Account Transition**:
- Old: {old_layout/mint/PDA}
- New: {new_layout/mint/PDA}
- Mismatch Point: {where layouts/seeds diverge}

**Description**: {what is wrong}
**Impact**: {stranded funds, corrupted state, broken CPI callers}
**Evidence**: {code showing mismatch}

Step Execution Checklist (MANDATORY)

Step Required Completed? Notes
1. Identify Token and Account Transitions YES
2. Check Account Data Layout Compatibility YES
3. Trace Account Flow Paths YES
3b. CPI Side Effect Compatibility YES
3c. Pre-Upgrade Account Inventory YES
4. Stranded Asset Analysis (4a-4e) YES
4f. User-Blocks-Admin Scenarios YES
5. Upgrade Authority Lifecycle YES
6. Downstream Integration Compatibility YES

If any step skipped, document valid reason (N/A, immutable program, single version, no CPI callers).

Expand your agent's capabilities with these related and highly-rated skills.

Didn't find tool you were looking for?

Be as detailed as possible for better results