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:
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
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
- Identify all state-changing entry points that accept external tokens or ETH.
- Determine trusted vs untrusted actors and privileged administrative roles.
- 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
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:
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);
}
1---2name: immunefi-vulnerability-patterns3description: 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.4---56# Immunefi Vulnerability Patterns & Post-Mortem Audit Playbook78## Overview9This 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.1011---1213## 1. Core Threat Categories (Immunefi Taxonomy)1415### A. Liquidity & Vault Drains16- **Empty-Pool Manipulation / Rounding Attacks**:17 - Protocols converting assets to shares where low initial liquidity allows integer division truncation to return zero shares or maximize share exchange rates.18 - *Invariant*: `sharePrice` must never be manipulable by direct unbacked token transfers (donations).19- **First-Deposit Offset & Virtual Shares**:20 - Enforce virtual offset (`Math.mulDiv` with virtual assets + virtual shares) or initial supply burning to mitigate exchange rate skewing.2122### B. Read-Only Reentrancy Across Cross-Contract Integrations23- **Transient State Exposure**:24 - Core pools (e.g., Balancer, Curve) execute native asset transfers before internal state updates or while intermediate variables reflect unfinalized pool balances.25 - Third-party lending markets query `get_virtual_price()` or oracle views during this callback window, pricing collateral at inflated or deflated rates.26- *Checklist*:27 - [ ] Are view/query functions guarded against execution during active pool operations?28 - [ ] Does the integrating protocol verify the pool's reentrancy lock before consuming price views?2930### C. Cross-Chain & Bridge Message Relay Failures31- **Unverified Source Address / Bridge Adapters**:32 - Message receiving functions (`lzReceive`, `execute`, `receivePayload`) failing to validate that the remote sender contract matches the expected origin address on the source chain.33- **Payload Decoding & Type Confusion**:34 - Ambiguous `abi.decode` schemas where variable-length arrays or nested structs lead to parameter injection or payload truncation.35- **Gas Limit Exhaustion**:36 - Destination chain execution failing silently or leaving assets locked due to insufficient execution gas allocated at source.3738### D. Flash Loan-Driven Oracle & Reserves Exploitation39- **Spot Price Reliance**:40 - Using `balanceOf(address(this))` or instant AMM reserves (`reserve0`, `reserve1`) to compute valuation instead of decentralized, time-weighted or cryptographically verified feeds.41- **Chainlink Staleness & L2 Sequencer Downtime**:42 - Failure to validate `answeredInRound >= roundId`, `updatedAt != 0`, or Sequencer Uptime feeds on Arbitrum, Optimism, and Base.4344### E. EIP-712 & Permitted Signature Pitfalls45- **Domain Separator Invalidation**:46 - Omitting `block.chainid` dynamically, allowing pre-fork signatures to be replayed post-hardfork across competing chains.47- **Missing Nonce Invalidation**:48 - Allowing multiple executions of meta-transactions or approvals using the same signature.49- **High-Order S-Value Malleability**:50 - Failing to constrain $s \le \text{secp256k1n}/2$, allowing alternate valid signatures for identical transactions.5152---5354## 2. Comprehensive Security Review Workflow5556```mermaid57graph TD58 A[Contract Intake] --> B[Architecture & Asset Flow Map]59 B --> C[Invariant Definition & Invariant Testing]60 C --> D[Oracle & External Integration Audit]61 C --> E[Reentrancy & Execution Ordering Audit]62 C --> F[Token Compatibility & Boundary Checks]63 D --> G[Report Generation & Hardening Verification]64 E --> G65 F --> G66```6768### Phase 1: Architecture & Asset Flow Mapping691. Identify all state-changing entry points that accept external tokens or ETH.702. Determine trusted vs untrusted actors and privileged administrative roles.713. Map every external contract interaction, identifying potential hooks (`safeTransfer`, fallback functions, ERC-777).7273### Phase 2: Invariant Specification74Every Web3 protocol requires documented invariants prior to audit:75- **Solvency Conservation**: Vault assets under custody must equal or exceed total depositor claims.76- **Monotonicity**: Nonces, epoch counts, and reward accrual indices must never decrease.77- **Access Boundary**: State-modifying admin parameters must strictly obey multi-sig and timelock requirements.7879### Phase 3: Edge Case & Boundary Verification80- Check zero-amount deposits/withdrawals, maximal `uint256` inputs, array lengths, and off-by-one errors in loop terminations.81- Verify safe token handling (`SafeERC20`) for tokens with non-standard behavior (USDT missing return, fee-on-transfer tokens, rebasing balances).8283---8485## 3. Remediation & Hardening Patterns8687### Safe Oracle Price Feed Consumption88```solidity89function getValidatedOraclePrice(90 AggregatorV3Interface priceFeed,91 uint256 maxStalenessPeriod92) internal view returns (uint256) {93 (94 uint80 roundId,95 int256 price,96 ,97 uint256 updatedAt,98 uint80 answeredInRound99 ) = priceFeed.latestRoundData();100101 require(price > 0, "Oracle: Negative or zero price");102 require(updatedAt != 0, "Oracle: Incomplete round");103 require(answeredInRound >= roundId, "Oracle: Stale round");104 require(block.timestamp - updatedAt <= maxStalenessPeriod, "Oracle: Price expired");105106 return uint256(price);107}108```109110### Two-Step Ownership & Role Transfers111Avoid single-step privileged address mutations. Enforce two-step acceptance workflows:112```solidity113address public pendingAdmin;114address public admin;115116event AdminTransferInitiated(address indexed currentAdmin, address indexed pendingAdmin);117event AdminTransferred(address indexed previousAdmin, address indexed newAdmin);118119function initiateAdminTransfer(address _newAdmin) external {120 require(msg.sender == admin, "Unauthorized");121 require(_newAdmin != address(0), "Zero address");122 pendingAdmin = _newAdmin;123 emit AdminTransferInitiated(admin, _newAdmin);124}125126function acceptAdmin() external {127 require(msg.sender == pendingAdmin, "Unauthorized");128 emit AdminTransferred(admin, pendingAdmin);129 admin = pendingAdmin;130 pendingAdmin = address(0);131}132```