agents/skills/sui/package-version-safety/SKILL.md
Trigger Pattern PACKAGE_UPGRADE flag (UpgradeCap detected, multiple package versions, upgrade policy references) - Inject Into Breadth agents, depth-external
npx skillsauth add plamentsv/plamen package-version-safetyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Trigger Pattern: PACKAGE_UPGRADE flag (UpgradeCap detected, multiple package versions, upgrade policy references) Inject Into: Breadth agents, depth-external Finding prefix:
[PV-N]Rules referenced: R4, R8, R9, R10
Sui packages are immutable once published. "Upgrading" a package means publishing a NEW version at a NEW on-chain address, linked to the original via the UpgradeCap lineage. The old version's code remains callable forever. This creates a fundamentally different upgrade risk model compared to EVM proxies: instead of replacing logic in-place, Sui packages accumulate versions -- and shared objects may be accessible by ALL versions simultaneously.
UpgradeCap|upgrade_policy|package::make_immutable|compatible|additive|dep_only|version|
migrate|old_version|new_version
For each package in scope:
| # | Package | UpgradeCap Location | UpgradeCap Holder | Has store? | Upgrade Policy | Destroyed? |
|---|---------|--------------------|--------------------|-------------|---------------|-----------|
| 1 | {pkg_name} | {init function:line} | {address / shared / wrapped in governance} | YES/NO | {compatible/additive/dep_only} | YES (immutable) / NO |
Checks:
Where is UpgradeCap stored?
make_immutable(): Package is permanently immutable. No upgrade risk.@0x0 or burn address: Effectively immutable.Can UpgradeCap be transferred?
key + store by default -> freely transferable via public_transfer.GovernanceCap wrapping UpgradeCap)Can UpgradeCap be destroyed?
sui::package::make_immutable(cap) consumes UpgradeCap -> permanent immutability.drop via wrapper -> accidental destruction possible.| Governance Model | Risk Level | Assessment | |-----------------|------------|------------| | Single EOA | CRITICAL | One key compromise replaces all package logic | | Multisig (2/3 or lower) | HIGH | Low collusion threshold | | Multisig (3/5+) | MEDIUM | Requires majority collusion | | Multisig + timelock | LOW | Users can exit before malicious upgrade takes effect | | DAO/governance contract | LOW | Distributed control, but check voter distribution | | Destroyed (immutable) | NONE | Cannot upgrade, but also cannot patch bugs |
For shared objects created by this package:
| Shared Object | Created By (Version) | Current Version Field? | V1 Functions Access? | V2 Functions Access? | Consistency Risk |
|--------------|---------------------|----------------------|---------------------|---------------------|-----------------|
| {obj_type} | V1 init() | YES: version: u64 / NO | {list funcs} | {list funcs} | {describe} |
What happens when package is upgraded?
Can old-version and new-version calls on same shared object create inconsistency?
For each dependency in Move.toml:
| Dependency | Source | Pinned To | Immutable? | Upgrade Risk |
|-----------|--------|-----------|-----------|-------------|
| Sui Framework | sui = "..." | {git rev or latest} | Upgraded by validators | Framework upgrade could change behavior |
| MoveStdlib | MoveStdlib = "..." | {git rev} | Upgraded with framework | Same as above |
| {third_party} | {git url or on-chain} | {specific rev / branch / on-chain version} | YES/NO | {describe} |
Checks:
main -> upstream changes included on recompile.Can dependency upgrade break our package?
sui::* packages upgraded by validators. Can change Move VM behavior, gas costs, object model rules.When package V2 adds new types or fields:
| Type | V1 Definition | V2 Changes | Compatible Upgrade Rule | Migration Needed? | |------|-------------|-----------|------------------------|------------------| | {struct_name} | {fields} | {cannot change for compatible} | Struct layouts FROZEN | NO -- same layout | | {new_struct} | N/A | {new in V2} | New types allowed | N/A |
Sui type rules for compatible upgrades:
Can V1 objects be used with V2 functions?
Can V2 objects be used with V1 functions?
Dynamic field implications:
Does the package have migration functions to update shared objects from V1->V2 state?
| Migration Function | Trigger | What It Updates | Reversible? | Access Control | |-------------------|---------|----------------|-----------|---------------| | {migrate_func} | {admin call / automatic} | {version field, new state} | NO | {AdminCap / anyone} |
Version guard pattern: Shared objects contain version: u64. V1 functions check assert!(version == 1). V2 migration function sets version = 2. After migration, V1 functions abort because version != 1.
Check:
If UpgradeCap is owned by a single address:
| Risk | Description | Severity | |------|-------------|----------| | Full logic replacement | Attacker upgrades package with malicious code. All shared objects now interact with attacker's logic. | CRITICAL | | Subtle parameter change | Attacker upgrades to change a fee calculation or threshold in function body. Hard to detect. | HIGH | | Dependency manipulation | Attacker upgrades to change dependency versions, pulling in vulnerable code. | HIGH | | Policy escalation blocked | Upgrade policies can only be tightened (compatible -> additive -> dep_only -> immutable). Attacker cannot escalate from additive to compatible. | Mitigation |
Mitigations to check:
compatible?make_immutable() called in init() for packages that should never upgrade?make_immutable called -> no upgrade riskadditive or dep_only policy: Existing logic frozen (but new functions can still access shared objects -- check Step 3c)## Finding [PV-N]: Title
**Verdict**: CONFIRMED / PARTIAL / REFUTED / CONTESTED
**Step Execution**: check1,2,3,4,5,6 | skip(reason) | uncertain
**Rules Applied**: [R4:___, R8:___, R9:___, R10:___]
**Severity**: Critical/High/Medium/Low/Info
**Location**: sources/{module}.move:LineN
**Upgrade Risk Type**: UPGRADECAP_MANAGEMENT / POLICY_INAPPROPRIATE / CROSS_VERSION_BYPASS / TYPE_INCOMPATIBILITY / DEPENDENCY_RISK / MISSING_VERSION_GUARD
**Package Version**: V{N} -> V{N+1}
**Shared Objects Affected**: {list}
**Description**: What is wrong
**Impact**: What can happen (logic replacement, security bypass, stranded assets, type mismatch)
**Evidence**: Code showing vulnerability
**Recommendation**: How to fix (tighten policy, add version guard, migrate capabilities, destroy UpgradeCap)
| Step | Required | Completed? | Notes | |------|----------|------------|-------| | 1. Upgrade Policy Inventory | YES | | UpgradeCap location, holder, policy | | 1b. UpgradeCap Governance Assessment | YES | | Risk level for each package | | 2. Version Consistency Check | YES | | All shared objects checked for dual-version access | | 3. Dependency Version Pinning | YES | | Move.toml analyzed | | 4. Type Compatibility Across Versions | YES | | Dynamic fields included | | 5. Upgrade Migration Safety | YES | | Version guard pattern checked | | 6. UpgradeCap Governance | IF single-address holder | | Multisig/timelock/approval checks |
After Step 1: If UpgradeCap held by single address -> immediate finding (minimum HIGH).
After Step 2: If cross-version bypass possible -> cross-reference with MIGRATION_ANALYSIS Step 5 for shared object function enumeration.
After Step 3: Feed dependency risks to DEPENDENCY_AUDIT for transitive dependency analysis.
After Step 5: If no version guard AND shared objects hold user funds -> minimum HIGH finding.
If any step skipped, document valid reason (N/A, package is immutable, no shared objects, no third-party dependencies).
development
Prepare Solidity projects for a security audit — test coverage, test quality, NatSpec docs, code hygiene, dependency health, best-practice enforcement, deployment readiness, and project documentation checks. Generates a scored Audit Readiness Report and optionally runs static analysis. Trigger on: "prepare for audit", "audit readiness", "pre-audit check", "audit prep", "NatSpec check", or any request to review a Solidity codebase before a security review.
development
Launch the Plamen deterministic Web3 security audit pipeline
development
Run the Plamen smart-contract audit wizard in Codex
testing
Launch the Plamen deterministic L1 infrastructure audit pipeline