Skip to main content
ClaudeWave
Skill109 repo starsupdated 2mo ago

proxy-upgrade-safety

Detects vulnerabilities in upgradeable proxy smart contracts including storage layout collisions, uninitialized implementations, function selector clashing, delegatecall context issues, and upgrade path safety. Covers Transparent Proxy, UUPS (EIP-1822), Beacon, Diamond (EIP-2535), and Minimal Proxy (EIP-1167) patterns. Use when auditing upgradeable contracts, reviewing implementation upgrades, analyzing delegatecall architectures, or verifying proxy pattern compliance.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/quillai-network/quillshield_skills /tmp/proxy-upgrade-safety && cp -r /tmp/proxy-upgrade-safety/plugins/proxy-upgrade-safety/skills/proxy-upgrade-safety ~/.claude/skills/proxy-upgrade-safety
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Proxy & Upgrade Safety

Detect vulnerabilities specific to **upgradeable proxy architectures** — the most widely deployed contract pattern on Ethereum (54.2% of contracts). Proxy bugs cause storage corruption, unauthorized upgrades, and complete contract takeover.

## When to Use

- Auditing any contract using proxy/implementation pattern (Transparent, UUPS, Beacon, Diamond)
- Reviewing implementation contract upgrades for storage layout compatibility
- Analyzing `delegatecall`-based architectures and library usage
- Verifying initialization safety (can `initialize()` be front-run?)
- Checking Diamond (EIP-2535) facet management for selector collisions

## When NOT to Use

- Non-upgradeable contracts without proxy patterns
- Pure logic audits without proxy architecture (use behavioral-state-analysis)
- Token standard compliance (use external-call-safety)

## Core Concept: The Delegatecall Storage Model

When Proxy calls Implementation via `delegatecall`:

```
┌─────────────────────┐     delegatecall     ┌─────────────────────┐
│       PROXY         │ ──────────────────→   │   IMPLEMENTATION    │
│                     │                       │                     │
│ Storage:            │  Implementation code  │ Code only:          │
│   slot 0: admin     │  executes in proxy's  │   No persistent     │
│   slot 1: impl addr │  storage context      │   storage           │
│   slot 2: user data │                       │                     │
│   slot 3: user data │                       │                     │
└─────────────────────┘                       └─────────────────────┘
```

**Key Rule:** The implementation's code reads/writes the PROXY's storage slots. If storage layouts don't match, data corruption occurs.

## Five Vulnerability Classes

### Class 1: Storage Layout Collision

**Between Proxy and Implementation:**

```solidity
// Proxy contract
contract Proxy {
    address public admin;           // slot 0
    address public implementation;  // slot 1

    fallback() external payable {
        delegatecall(implementation);
    }
}

// Implementation contract
contract ImplementationV1 {
    uint256 public totalSupply;     // slot 0 — COLLIDES with admin!
    mapping(address => uint256) public balances; // slot 1 — COLLIDES with implementation!
}
```

**Detection:** Compare storage slot assignments between proxy and implementation. Any overlap = CRITICAL vulnerability.

**Between Implementation Versions:**

```solidity
// V1
contract ImplementationV1 {
    uint256 public totalSupply;     // slot 0
    address public owner;           // slot 1
    mapping(address => uint256) balances; // slot 2
}

// V2 — DANGEROUS: inserted variable before existing ones
contract ImplementationV2 {
    bool public paused;             // slot 0 — COLLIDES with totalSupply!
    uint256 public totalSupply;     // slot 1 — COLLIDES with owner!
    address public owner;           // slot 2 — COLLIDES with balances!
    mapping(address => uint256) balances; // slot 3
}
```

**Safe V2:**

```solidity
contract ImplementationV2 {
    uint256 public totalSupply;     // slot 0 — same
    address public owner;           // slot 1 — same
    mapping(address => uint256) balances; // slot 2 — same
    bool public paused;             // slot 3 — NEW, appended at end
}
```

### Class 2: Uninitialized Implementation

Proxy pattern uses `initialize()` instead of `constructor()`. If the implementation contract itself is not initialized, an attacker can call `initialize()` directly on it.

```solidity
contract ImplementationV1 is Initializable {
    address public owner;

    function initialize(address _owner) external initializer {
        owner = _owner;
    }

    function selfDestruct() external {
        require(msg.sender == owner);
        selfdestruct(payable(msg.sender));
    }
}
```

**Attack:**

```
1. Implementation deployed but initialize() not called on impl itself
2. Attacker calls implementation.initialize(attacker_address)
3. Attacker is now owner of the IMPLEMENTATION contract
4. Attacker calls selfDestruct() on implementation
5. Proxy now delegatecalls to destroyed contract
6. ALL proxy calls return empty data — contract bricked
```

**Detection:**

```
For each implementation contract:
  1. Does it have initialize() or any initializer function?
  2. Was initialize() called on the implementation address (not just the proxy)?
  3. Does the constructor call _disableInitializers()?
  4. If no → UNINITIALIZED IMPLEMENTATION vulnerability
```

### Class 3: Function Selector Clashing

Solidity function selectors are only 4 bytes. Collisions between proxy admin functions and implementation functions cause unexpected behavior.

```solidity
// Proxy has admin function
function upgrade(address newImpl) external;  // selector: 0x0900f010

// Implementation has user function with SAME selector
function collide(uint256 amount) external;   // selector: 0x0900f010

// When user calls collide(), proxy intercepts it as upgrade()!
```

**Transparent Proxy Mitigation:** Admin can only call admin functions; users can only call implementation functions. But this must be correctly implemented.

**Detection:**

```
For each function in the proxy:
  selector_proxy = keccak256(signature)[:4]
  For each function in the implementation:
    selector_impl = keccak256(signature)[:4]
    If selector_proxy == selector_impl:
      → FUNCTION SELECTOR CLASH
```

### Class 4: Missing Upgrade Authorization

**UUPS Pattern:** The upgrade logic lives in the implementation, not the proxy. If `_authorizeUpgrade()` is not properly protected, anyone can upgrade.

```solidity
// VULNERABLE: Missing access control on upgrade
contract ImplementationV1 is UUPSUpgradeable {
    function _authorizeUpgrade(address newImplementation) internal override {
        // NO ACCESS CHECK! Anyone can upgrade!
    }
}

// SAFE
contract ImplementationV1 is UUPSUpgradeable, OwnableUpgradeable {
    function _authorizeUpgrade(address newImplementation) interna
behavioral-state-analysisSkill

Token-efficient smart contract security auditing via Behavioral State Analysis (BSA). Scopes analysis to contract type, runs only relevant threat engines, and uses tiered output depth. Use for auditing smart contracts, security reviews, or DeFi threat modeling.

defenderSkill

Blue-team release-gate analysis for smart contract deployment and upgrade readiness. Classifies repositories, checks deploy/upgrade execution paths, CI/CD trust boundaries, config drift, secrets/signer operational security, and outputs evidence-backed release verdicts.

dos-griefing-analysisSkill

Detects Denial of Service and griefing vulnerabilities in smart contracts. Covers unbounded loop DoS, block gas limit exhaustion, external call failure DoS, insufficient gas griefing (63/64 rule), storage bloat attacks, timestamp griefing, self-destruct force-feeding, and push vs pull payment pattern analysis. Use when auditing contracts with batch operations, loops over user data, reward distribution, dividend systems, or any logic that depends on address(this).balance or iterates over growing collections.

external-call-safetySkill

Detects unsafe external call patterns and token integration vulnerabilities in smart contracts. Covers unchecked call/delegatecall/staticcall return values, fee-on-transfer tokens, rebasing tokens, tokens with missing return values (USDT), ERC-777 callback risks, unsafe approve race conditions, return data bombs, gas stipend limitations, and push vs pull payment patterns. Use when auditing contracts that interact with external contracts, integrate arbitrary ERC20 tokens, distribute payments, or make low-level calls.

input-arithmetic-safetySkill

Detects input validation failures and arithmetic vulnerabilities in smart contracts. Covers missing zero-address and zero-amount checks, division-before-multiplication precision loss, rounding direction exploitation, ERC4626 vault share inflation attacks, unsafe integer casting, dust amount exploitation, and Solidity 0.8+ unchecked block edge cases. Use when auditing contracts with fee calculations, share pricing, exchange rates, unchecked blocks, or any public-facing functions that accept user input.

oracle-flashloan-analysisSkill

Detects price oracle manipulation and flash loan attack vectors in DeFi smart contracts. Classifies oracle trust models (Chainlink, TWAP, spot price, custom), identifies stale price risks, circular price dependencies, and flash loan atomicity exploitation patterns. Use when auditing DeFi protocols that depend on price data, oracle integrations, lending protocols, DEXs, derivatives, or any contract where flash loans could manipulate state within a single transaction.

reentrancy-pattern-analysisSkill

Systematically detects all reentrancy vulnerability variants in smart contracts — classic, cross-function, cross-contract, and read-only reentrancy. Builds call graphs, verifies CEI (Checks-Effects-Interactions) pattern compliance, traces state changes relative to external calls, and identifies callback vectors through ERC-777/ERC-1155 hooks. Use when auditing contracts that make external calls, transfer ETH or tokens, interact with callback-enabled standards, or have complex multi-contract architectures.

semantic-guard-analysisSkill

Detects logic vulnerabilities in smart contracts by analyzing guard-state consistency patterns. Identifies functions that bypass security checks (require, modifiers) that other functions consistently apply. Uses the Consistency Principle — a contract is its own specification. Use when auditing smart contracts for missing access controls, inconsistent pause checks, logic bugs, forgotten modifiers, or when traditional tools report no issues but logic errors may exist.