# Immunefi Vulnerability Patterns

> Audit Web3 smart contracts against top Immunefi bug bounty disclosure patterns, post-mortems, and critical severity vulnerability categories across DeFi, lending, bridges, and yield protocols.

- Skill: `netvar1337/immunefi-vulnerability-patterns` (Agent Skill)
- Install (CLI): `npx skillmds@latest add netvar1337/immunefi-vulnerability-patterns`
- Raw SKILL.md: https://api.skillmd.com/api/skills/netvar1337/immunefi-vulnerability-patterns/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: netvar1337 (https://skillmd.com/u/netvar1337)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/netvar1337/immunefi-vulnerability-patterns

---


# Immunefi Vulnerability Patterns & Post-Mortem Audit Playbook

## Overview
This skill synthesizes core vulnerability classes, recurring architectural pitfalls, and remediation strategies from the highest-impact vulnerability reports published on Immunefi (`reports.immunefi.com`). It targets critical flaw categories across decentralized finance (DeFi), bridge protocols, automated market makers (AMMs), and governance layers.

---

## 1. Core Threat Categories (Immunefi Taxonomy)

### A. Liquidity & Vault Drains
- **Empty-Pool Manipulation / Rounding Attacks**:
  - Protocols converting assets to shares where low initial liquidity allows integer division truncation to return zero shares or maximize share exchange rates.
  - *Invariant*: `sharePrice` must never be manipulable by direct unbacked token transfers (donations).
- **First-Deposit Offset & Virtual Shares**:
  - Enforce virtual offset (`Math.mulDiv` with virtual assets + virtual shares) or initial supply burning to mitigate exchange rate skewing.

### B. Read-Only Reentrancy Across Cross-Contract Integrations
- **Transient State Exposure**:
  - Core pools (e.g., Balancer, Curve) execute native asset transfers before internal state updates or while intermediate variables reflect unfinalized pool balances.
  - Third-party lending markets query `get_virtual_price()` or oracle views during this callback window, pricing collateral at inflated or deflated rates.
- *Checklist*:
  - [ ] Are view/query functions guarded against execution during active pool operations?
  - [ ] Does the integrating protocol verify the pool's reentrancy lock before consuming price views?

### C. Cross-Chain & Bridge Message Relay Failures
- **Unverified Source Address / Bridge Adapters**:
  - Message receiving functions (`lzReceive`, `execute`, `receivePayload`) failing to validate that the remote sender contract matches the expected origin address on the source chain.
- **Payload Decoding & Type Confusion**:
  - Ambiguous `abi.decode` schemas where variable-length arrays or nested structs lead to parameter injection or payload truncation.
- **Gas Limit Exhaustion**:
  - Destination chain execution failing silently or leaving assets locked due to insufficient execution gas allocated at source.

### D. Flash Loan-Driven Oracle & Reserves Exploitation
- **Spot Price Reliance**:
  - Using `balanceOf(address(this))` or instant AMM reserves (`reserve0`, `reserve1`) to compute valuation instead of decentralized, time-weighted or cryptographically verified feeds.
- **Chainlink Staleness & L2 Sequencer Downtime**:
  - Failure to validate `answeredInRound >= roundId`, `updatedAt != 0`, or Sequencer Uptime feeds on Arbitrum, Optimism, and Base.

### E. EIP-712 & Permitted Signature Pitfalls
- **Domain Separator Invalidation**:
  - Omitting `block.chainid` dynamically, allowing pre-fork signatures to be replayed post-hardfork across competing chains.
- **Missing Nonce Invalidation**:
  - Allowing multiple executions of meta-transactions or approvals using the same signature.
- **High-Order S-Value Malleability**:
  - Failing to constrain $s \le \text{secp256k1n}/2$, allowing alternate valid signatures for identical transactions.

---

## 2. Comprehensive Security Review Workflow

```mermaid
graph TD
    A[Contract Intake] --> B[Architecture & Asset Flow Map]
    B --> C[Invariant Definition & Invariant Testing]
    C --> D[Oracle & External Integration Audit]
    C --> E[Reentrancy & Execution Ordering Audit]
    C --> F[Token Compatibility & Boundary Checks]
    D --> G[Report Generation & Hardening Verification]
    E --> G
    F --> G
```

### Phase 1: Architecture & Asset Flow Mapping
1. Identify all state-changing entry points that accept external tokens or ETH.
2. Determine trusted vs untrusted actors and privileged administrative roles.
3. Map every external contract interaction, identifying potential hooks (`safeTransfer`, fallback functions, ERC-777).

### Phase 2: Invariant Specification
Every Web3 protocol requires documented invariants prior to audit:
- **Solvency Conservation**: Vault assets under custody must equal or exceed total depositor claims.
- **Monotonicity**: Nonces, epoch counts, and reward accrual indices must never decrease.
- **Access Boundary**: State-modifying admin parameters must strictly obey multi-sig and timelock requirements.

### Phase 3: Edge Case & Boundary Verification
- Check zero-amount deposits/withdrawals, maximal `uint256` inputs, array lengths, and off-by-one errors in loop terminations.
- Verify safe token handling (`SafeERC20`) for tokens with non-standard behavior (USDT missing return, fee-on-transfer tokens, rebasing balances).

---

## 3. Remediation & Hardening Patterns

### Safe Oracle Price Feed Consumption
```solidity
function getValidatedOraclePrice(
    AggregatorV3Interface priceFeed,
    uint256 maxStalenessPeriod
) internal view returns (uint256) {
    (
        uint80 roundId,
        int256 price,
        ,
        uint256 updatedAt,
        uint80 answeredInRound
    ) = priceFeed.latestRoundData();

    require(price > 0, "Oracle: Negative or zero price");
    require(updatedAt != 0, "Oracle: Incomplete round");
    require(answeredInRound >= roundId, "Oracle: Stale round");
    require(block.timestamp - updatedAt <= maxStalenessPeriod, "Oracle: Price expired");

    return uint256(price);
}
```

### Two-Step Ownership & Role Transfers
Avoid single-step privileged address mutations. Enforce two-step acceptance workflows:
```solidity
address public pendingAdmin;
address public admin;

event AdminTransferInitiated(address indexed currentAdmin, address indexed pendingAdmin);
event AdminTransferred(address indexed previousAdmin, address indexed newAdmin);

function initiateAdminTransfer(address _newAdmin) external {
    require(msg.sender == admin, "Unauthorized");
    require(_newAdmin != address(0), "Zero address");
    pendingAdmin = _newAdmin;
    emit AdminTransferInitiated(admin, _newAdmin);
}

function acceptAdmin() external {
    require(msg.sender == pendingAdmin, "Unauthorized");
    emit AdminTransferred(admin, pendingAdmin);
    admin = pendingAdmin;
    pendingAdmin = address(0);
}
```

