Skip to main content

smart-contract-vulnerabilities

Smart contract vulnerability playbook. Use when auditing Solidity/EVM contracts for reentrancy, integer overflow, access control, delegatecall, flash loan, signature replay, and MEV-related attack patterns.

Source facts

Repository
yaklang/hack-skills
Last source activity
April 9, 2026 at 12:46
Detected SKILL.md language
English
Stars
2,458
Forks
331

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions ยท Read-only preview
name
smart-contract-vulnerabilities
description
Smart contract vulnerability playbook. Use when auditing Solidity/EVM contracts for reentrancy, integer overflow, access control, delegatecall, flash loan, signature replay, and MEV-related attack patterns.
# SKILL: Smart Contract Vulnerabilities โ€” Expert Attack Playbook > **AI LOAD INSTRUCTION**: Expert smart contract audit techniques. Covers reentrancy (single, cross-function, cross-contract, read-only), integer overflow, access control, delegatecall, randomness manipulation, flash loans, signature replay, front-running/MEV, and CREATE2 exploitation. Base models miss subtle cross-contract reentrancy and storage layout collisions in proxy patterns. ## 0. RELATED ROUTING - [defi-attack-patterns](../defi-attack-patterns/SKILL.md) when the vulnerability is part of a DeFi protocol exploit (flash loans, oracle manipulation, governance attacks) - [deserialization-insecure](../deserialization-insecure/SKILL.md) when the target is off-chain infrastructure deserializing blockchain data ### Advanced Reference Also load [SOLIDITY_VULN_PATTERNS.md](./SOLIDITY_VULN_PATTERNS.md) when you need: - Side-by-side vulnerable vs fixed code patterns for each vulnerability class - Gas optimization traps that introduce vulnerabilities - Proxy pattern storage collision examples with slot calculations --- ## 1. REENTRANCY The most iconic smart contract vulnerability. External calls transfer execution control; if state is not updated before the call, the callee can re-enter. ### 1.1 Classic Reentrancy (Single-Function) ``` Victim.withdraw() โ”œโ”€โ”€ checks balance[msg.sender] > 0 โœ“ โ”œโ”€โ”€ msg.sender.call{value: balance}("") โ† external call โ”‚ โ””โ”€โ”€ Attacker.receive() โ”‚ โ””โ”€โ”€ Victim.withdraw() โ† re-enters before state update โ”‚ โ”œโ”€โ”€ checks balance[msg.sender] โ† still > 0! โ”‚ โ””โ”€โ”€ sends ETH again โ””โ”€โ”€ balance[msg.sender] = 0 โ† too late ``` ### 1.2 Cross-Function Reentrancy Two functions share state; attacker re-enters a different function during callback: | Step | Execution | State | |---|---|---| | 1 | Call `withdraw()` โ†’ external call | balance still positive | | 2 | Attacker fallback calls `transfer(attacker2)` | balance used before reset | | 3 | `transfer` reads stale balance โ†’ moves funds | attacker2 receives tokens | | 4 | Original `withdraw` completes, zeroes balance | damage done | ### 1.3 Cross-Contract Reentrancy Contract A calls Contract B, which calls back into Contract A (or Contract C that reads A's stale state). Especially dangerous in DeFi protocols where multiple contracts share state. ### 1.4 Read-Only Reentrancy The re-entered function is a `view` function used by a third-party contract for price calculation. No state modification in the victim, but the stale intermediate state misleads the reader. **Real-world**: Curve pool `get_virtual_price()` read during `remove_liquidity()` callback โ†’ inflated price โ†’ profit on dependent lending protocol. ### Mitigations | Pattern | Protection Level | |---|---| | Checks-Effects-Interactions (CEI) | Core defense; update state before external call | | `ReentrancyGuard` (OpenZeppelin) | Mutex lock; prevents same-tx re-entry | | Pull payment pattern | Eliminate external calls in state-changing functions | | CEI + guard on all public functions | Defense-in-depth against cross-function | --- ## 2. INTEGER OVERFLOW / UNDERFLOW ### Pre-Solidity 0.8 Arithmetic silently wraps: `uint8(255) + 1 == 0`, `uint8(0) - 1 == 255`. | Attack | Example | |---|---| | Balance underflow | `balances[attacker] -= amount` when amount > balance โ†’ huge balance | | Supply overflow | `totalSupply + mintAmount` wraps โ†’ bypass cap checks | | Timelock bypass | `lockTime[msg.sender] + extend` wraps to past โ†’ early unlock | ### Post-Solidity 0.8 Default checked arithmetic reverts on overflow. But `unchecked{}` blocks reintroduce risk: ```solidity unchecked { // "gas optimization" โ€” but if i can be influenced by user input, overflow returns for (uint i = start; i < end; i++) { ... } } ``` ### SafeMath Bypass Scenarios - Casting: `uint256` โ†’ `uint128` truncation before SafeMath check - Assembly blocks: `mstore` / `add` bypass Solidity-level checks - Intermediate multiplication overflow before division: `(a * b) / c` where `a * b` overflows --- ## 3. ACCESS CONTROL ### tx.origin vs msg.sender | Property | `msg.sender` | `tx.origin` | |---|---|---| | Value | Immediate caller | EOA that initiated the tx | | Safe for auth | Yes | **No** โ€” phishing contract can inherit tx.origin | Attack: trick owner into calling attacker contract โ†’ attacker contract calls victim with owner's `tx.origin`. ### Common Patterns | Issue | Impact | |---|---| | Missing `onlyOwner` on critical functions | Anyone can call admin functions | | Unprotected `selfdestruct` | Anyone can destroy the contract, force-send ETH | | Unprotected `delegatecall` | Attacker executes arbitrary code in victim's context | | Default visibility (pre-0.6.0) | Functions default to `public` | | Missing zero-address checks | Ownership transferred to `address(0)` | --- ## 4. RANDOMNESS MANIPULATION On-chain randomness sources are predictable to miners/validators: | Source | Predictability | |---|---| | `block.timestamp` | Miner has ~15s window to manipulate | | `blockhash(block.number - 1)` | Known to all at execution time | | `blockhash(block.number)` | Always returns 0 (current block hash unknown) | | `block.difficulty` / `block.prevrandao` | Post-merge: known beacon chain value | **Commit-reveal bypass**: If reveal phase doesn't enforce timeout or bond, attacker can choose not to reveal unfavorable outcomes (selective abort attack). --- ## 5. DELEGATECALL VULNERABILITIES `delegatecall` executes callee's code in caller's storage context. Storage slot layout must match exactly. ### Storage Layout Collision ``` Proxy (storage): Implementation (code): slot 0: owner slot 0: someVariable slot 1: implementation slot 1: anotherVariable ``` Implementation writes to `someVariable` (slot 0) โ†’ overwrites proxy's `owner`. Attacker calls implementation function that writes slot 0 โ†’ becomes proxy owner. ### Function Selector Collision 4-byte function selectors can collide. If proxy's `admin()` selector collides with implementation's `transfer()`, calling `admin()` on the proxy executes `transfer()` logic. Tool: `cast selectors <bytecode>` (Foundry) to enumerate selectors. --- ## 6. FRONT-RUNNING / MEV ### Transaction Ordering Manipulation ``` Victim submits DEX swap tx (visible in mempool) โ”œโ”€โ”€ Front-runner: buy token before victim (raise price) โ”œโ”€โ”€ Victim tx executes at worse price โ””โ”€โ”€ Back-runner: sell token after victim (profit from spread) = Sandwich attack ``` ### Protection Patterns | Defense | Mechanism | |---|---| | Commit-reveal | Hide transaction intent until reveal | | Flashbots / private mempool | Submit tx directly to block builder | | Slippage protection | Set `minAmountOut` to limit MEV extraction | | Time-lock | Delay execution to reduce predictability | --- ## 7. SIGNATURE REPLAY ### Missing Nonce Reuse a valid signature to repeat the action (e.g., transfer) multiple times. ### Cross-Chain Replay Same contract deployed on multiple chains with same address โ†’ signature valid on all chains. Must include `block.chainid` in signed message. ### EIP-712 Implementation Errors | Error | Consequence | |---|---| | Missing `DOMAIN_SEPARATOR` with chainId | Cross-chain replay | | Domain separator cached at deploy | Breaks after hard fork changing chainId | | Missing nonce in struct hash | Signature replay | | `ecrecover` returns `address(0)` on invalid sig | Passes `== address(0)` owner check | --- ## 8. SELF-DESTRUCT & FORCE-SEND ETH `selfdestruct(recipient)` force-sends all contract ETH to recipient โ€” bypasses `receive()` and `fallback()`, cannot be rejected. Breaks contracts that rely on `address(this).balance` for logic (e.g., `require(balance == expected)`). Post-EIP-6780 (Dencun): `selfdestruct` only sends ETH; code/storage deletion only if called in same tx as creation. --- ## 9. CREATE2 & DETERMINISTIC ADDRESS EXPLOITATION `CREATE2` address = `keccak256(0xff ++ deployer ++ salt ++ keccak256(initCode))`. | Attack | Method | |---|---| | Pre-fund exploitation | Predict address โ†’ send tokens/ETH before deployment โ†’ `selfdestruct` โ†’ redeploy different code at same address | | Pre-approve exploitation | Predicted address gets token approvals โ†’ deploy malicious contract โ†’ drain approved tokens | | Metamorphic contracts | `CREATE2` โ†’ `selfdestruct` โ†’ `CREATE2` with same salt but different `initCode` (pre-EIP-6780) | --- ## 10. FLASH LOAN ATTACK PATTERNS ``` Single transaction: โ”œโ”€โ”€ Borrow large amount (no collateral) โ”œโ”€โ”€ Manipulate state (price oracle, governance, etc.) โ”œโ”€โ”€ Extract profit from manipulated state โ”œโ”€โ”€ Repay loan + fee โ””โ”€โ”€ Keep profit ``` Key: entire sequence must succeed atomically or the whole tx reverts. --- ## 11. SHORT ADDRESS ATTACK EVM pads missing bytes in ABI-encoded calldata with zeros. If `transfer(address, uint256)` is called with a 19-byte address, the uint256 amount shifts left by 8 bits โ†’ multiplied by 256. Mitigation: validate calldata length; modern Solidity compilers add checks. --- ## 12. TOOLS | Tool | Purpose | Usage | |---|---|---| | Slither | Static analysis, vulnerability detection | `slither .` in project root | | Mythril | Symbolic execution, path exploration | `myth analyze contract.sol` | | Echidna | Property-based fuzzing | Define invariants, fuzz for violations | | Foundry (Forge) | Test framework, fuzzing, gas analysis | `forge test --fuzz-runs 10000` | | Hardhat | Development, testing, deployment | `npx hardhat test` | | Certora | Formal verification | Write specs, prove/disprove properties | | 4naly3er | Automated gas optimization + vuln report | CI integration | --- ## 13. DECISION TREE ``` Auditing a smart contract? โ”œโ”€โ”€ Is it a proxy pattern? โ”‚ โ”œโ”€โ”€ Yes โ†’ Check storage layout collision (Section 5) โ”‚ โ”‚ โ”œโ”€โ”€ Compare slot assignments between proxy and implementation โ”‚ โ”‚ โ”œโ”€โ”€ Check for function selector collision โ”‚ โ”‚ โ””โ”€โ”€ Verify initializer cannot be called twice โ”‚ โ””โ”€โ”€ No โ†’ Continue โ”œโ”€โ”€ Does it make external calls? โ”‚ โ”œโ”€โ”€ Yes โ†’ Check reentrancy (Section 1) โ”‚ โ”‚ โ”œโ”€โ”€ State updated before call? โ†’ CEI pattern OK โ”‚ โ”‚ โ”œโ”€โ”€ ReentrancyGuard present? โ†’ Check all entry points โ”‚ โ”‚ โ”œโ”€โ”€ Cross-function state sharing? โ†’ Cross-function reentrancy risk โ”‚ โ”‚ โ””โ”€โ”€ View functions read during callback? โ†’ Read-only reentrancy โ”‚ โ””โ”€โ”€ No โ†’ Continue โ”œโ”€โ”€ Does it handle tokens/ETH? โ”‚ โ”œโ”€โ”€ Yes โ†’ Check integer overflow (Section 2) โ”‚ โ”‚ โ”œโ”€โ”€ Solidity < 0.8? โ†’ All arithmetic suspect โ”‚ โ”‚ โ”œโ”€โ”€ unchecked{} blocks? โ†’ Verify no user-influenced values โ”‚ โ”‚ โ””โ”€โ”€ Casting between uint sizes? โ†’ Truncation risk โ”‚ โ””โ”€โ”€ Also check self-destruct force-send (Section 8) โ”œโ”€โ”€ Does it use signatures? โ”‚ โ”œโ”€โ”€ Yes โ†’ Check replay (Section 7) โ”‚ โ”‚ โ”œโ”€โ”€ Nonce included? โ†’ Verify incremented โ”‚ โ”‚ โ”œโ”€โ”€ ChainId included? โ†’ Cross-chain safe โ”‚ โ”‚ โ””โ”€โ”€ ecrecover result checked for address(0)? โ†’ OK โ”‚ โ””โ”€โ”€ No โ†’ Continue โ”œโ”€โ”€ Does it use on-chain randomness? โ”‚ โ”œโ”€โ”€ Yes โ†’ Predictable (Section 4) โ”‚ โ”‚ โ””โ”€โ”€ Recommend Chainlink VRF or commit-reveal with bond โ”‚ โ””โ”€โ”€ No โ†’ Continue โ”œโ”€โ”€ Does it interact with DeFi protocols? โ”‚ โ”œโ”€โ”€ Yes โ†’ Load [defi-attack-patterns](../defi-attack-patterns/SKILL.md) โ”‚ โ”‚ โ”œโ”€โ”€ Flash loan vectors โ”‚ โ”‚ โ”œโ”€โ”€ Oracle manipulation โ”‚ โ”‚ โ””โ”€โ”€ MEV exposure โ”‚ โ””โ”€โ”€ No โ†’ Continue โ”œโ”€โ”€ Does it use CREATE2? โ”‚ โ”œโ”€โ”€ Yes โ†’ Check deterministic address exploitation (Section 9) โ”‚ โ””โ”€โ”€ No โ†’ Continue โ””โ”€โ”€ Run automated tools (Section 12) โ”œโ”€โ”€ Slither for static analysis โ”œโ”€โ”€ Mythril for symbolic execution โ””โ”€โ”€ Echidna for fuzzing invariants ```
View on GitHub