smart-contract-vulnerabilities
Solidity/EVMコントラクトのセキュリティ監査に特化したプレイブック。リエントランシー、整数オーバーフロー、アクセス制御の不備、delegatecall、フラッシュローン、署名リプレイ、MEV関連の攻撃パターンを検出・分析する際に使用します。
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.md 本文
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. 関連ルーティング
defi-attack-patterns脆弱性が DeFi プロトコル悪用の一部である場合(フラッシュローン、オラクル操作、ガバナンス攻撃)deserialization-insecureターゲットがブロックチェーンデータをデシリアライズするオフチェーンインフラストラクチャの場合
高度なリファレンス
以下が必要な場合は SOLIDITY_VULN_PATTERNS.md もロードしてください:
- 各脆弱性クラスについて、脆弱なコードと修正済みコードのパターンを並べて表示
- 脆弱性を導入するガス最適化トラップ
- スロット計算を含むプロキシパターンのストレージ衝突の例
1. リエントランシ
最も象徴的なスマートコントラクト脆弱性。外部呼び出しが実行制御を転送し、状態が呼び出し前に更新されない場合、呼び出し先は再入することができます。
1.1 クラシックなリエントランシ(単一関数)
Victim.withdraw()
├── checks balance[msg.sender] > 0 ✓
├── msg.sender.call{value: balance}("") ← 外部呼び出し
│ └── Attacker.receive()
│ └── Victim.withdraw() ← 状態更新前に再入
│ ├── checks balance[msg.sender] ← 依然 > 0!
│ └── 再度 ETH を送信
└── balance[msg.sender] = 0 ← 遅すぎる
1.2 クロスファンクション リエントランシ
2つの関数がステートを共有;攻撃者がコールバック中に異なる関数に再入ります:
| ステップ | 実行 | ステート |
|---|---|---|
| 1 | withdraw() 呼び出し → 外部呼び出し | 残高はまだ正 |
| 2 | 攻撃者のフォールバックが transfer(attacker2) を呼び出し | リセット前の残高を使用 |
| 3 | transfer が古い残高を読み取る → 資金を移動 | attacker2 がトークンを受け取る |
| 4 | 元の withdraw が完了、残高をゼロにする | 損害完了 |
1.3 クロスコントラクト リエントランシ
Contract A が Contract B を呼び出し、Contract B が Contract A にコールバック(または Contract A の古い状態を読む Contract C)。特に DeFi プロトコルでは複数のコントラクトがステートを共有する場合に危険です。
1.4 リードオンリー リエントランシ
再入される関数は、サードパーティーコントラクトが価格計算に使用する view 関数です。被害者には状態修正はありませんが、古い中間状態が読み取り側に誤った情報を与えます。
実例:Curve プール get_virtual_price() が remove_liquidity() コールバック中に読み取られる → 価格が膨らむ → 従属する融資プロトコルで利益を得る。
緩和策
| パターン | 保護レベル |
|---|---|
| Checks-Effects-Interactions (CEI) | コア防御;外部呼び出し前に状態を更新 |
ReentrancyGuard (OpenZeppelin) | ミューテックスロック;同一Tx再入を防止 |
| プルペイメントパターン | ステート変更関数の外部呼び出しを削除 |
| CEI +すべてのパブリック関数のガード | クロスファンクション防御 |
2. 整数オーバーフロー/アンダーフロー
Solidity 0.8 前
算術がサイレントにラップ:uint8(255) + 1 == 0、uint8(0) - 1 == 255。
| 攻撃 | 例 |
|---|---|
| 残高アンダーフロー | balances[attacker] -= amount(amount > balance の場合) → 巨大な残高 |
| サプライオーバーフロー | totalSupply + mintAmount がラップ → キャップチェックをバイパス |
| タイムロック回避 | lockTime[msg.sender] + extend が過去にラップ → 早期ロック解除 |
Solidity 0.8 以降
デフォルトのチェック済み算術はオーバーフローで revert します。しかし unchecked{} ブロックはリスクを再導入します:
unchecked {
// 「ガス最適化」だが、i がユーザー入力の影響を受ける場合、オーバーフロー返却
for (uint i = start; i < end; i++) { ... }
}
SafeMath バイパスシナリオ
- キャスト:
uint256→uint128SafeMath チェック前の切り詰め - Assembly ブロック:
mstore/addが Solidity レベルのチェックをバイパス - 除算前の中間乗算オーバーフロー:
(a * b) / c(ここでa * bがオーバーフロー)
3. アクセスコントロール
tx.origin vs msg.sender
| プロパティ | msg.sender | tx.origin |
|---|---|---|
| 値 | 即座の呼び出し元 | Tx を開始した EOA |
| 認証に安全 | はい | いいえ — フィッシング コントラクトが tx.origin を継承可能 |
攻撃:オーナーを攻撃者コントラクト呼び出しにトリックする → 攻撃者コントラクトがオーナーの tx.origin で被害者を呼び出す。
一般的なパターン
| 問題 | 影響 |
|---|---|
クリティカル関数の onlyOwner 欠落 | 誰でも管理者関数を呼び出し可能 |
保護されていない selfdestruct | 誰でもコントラクトを破壊、ETH を強制送信 |
保護されていない delegatecall | 攻撃者が被害者コンテキストで任意コードを実行 |
| デフォルト可視性(0.6.0 前) | 関数はデフォルトで public |
| ゼロアドレスチェック欠落 | 所有権が address(0) に転送される |
4. ランダムネス操作
オンチェーンランダムネスソースはマイナー/バリデーターに予測可能:
| ソース | 予測可能性 |
|---|---|
block.timestamp | マイナーは約 15 秒のウィンドウを操作可能 |
blockhash(block.number - 1) | 実行時に全員が知っている |
blockhash(block.number) | 常に 0 を返す(現在のブロック ハッシュは不明) |
block.difficulty / block.prevrandao | マージ後:既知のビーコンチェーン値 |
コミット-リビール バイパス:リビールフェーズがタイムアウトまたはボンドを強制しない場合、攻撃者は不利な結果をリビールしないことを選択可能(選択的中止攻撃)。
5. DELEGATECALL 脆弱性
delegatecall は呼び出し元のストレージコンテキストで呼び出し先のコードを実行します。ストレージスロットレイアウトは完全に一致する必要があります。
ストレージレイアウト衝突
Proxy (storage): Implementation (code):
slot 0: owner slot 0: someVariable
slot 1: implementation slot 1: anotherVariable
Implementation が someVariable(slot 0)に書き込み → プロキシの owner を上書き。攻撃者が slot 0 に書き込む implementation 関数を呼び出し → プロキシオーナーになる。
関数セレクター衝突
4 バイト関数セレクターは衝突可能です。プロキシの admin() セレクターが implementation の transfer() と衝突する場合、プロキシで admin() を呼び出すと transfer() ロジックが実行されます。
ツール:cast selectors <bytecode>(Foundry)でセレクターを列挙。
6. フロントランニング / MEV
トランザクション順序付け操作
被害者が DEX スワップ tx を送信(メモプール内で見える)
├── フロントランナー:被害者前にトークンを購入(価格を上げる)
├── 被害者 tx がより悪い価格で実行
└── バックランナー:被害者後にトークンを売却(スプレッドから利益)
= サンドイッチ攻撃
保護パターン
| 防御 | メカニズム |
|---|---|
| コミット-リビール | リビールまでトランザクション意図を非表示 |
| Flashbots / プライベート メモプール | Tx をブロックビルダーに直接送信 |
| スリップページ保護 | minAmountOut を設定して MEV 抽出を制限 |
| タイムロック | 実行を遅延させて予測可能性を削減 |
7. 署名リプレイ
Nonce 欠落
有効な署名を再利用して、アクション(例:転送)を複数回繰り返す。
クロスチェーン リプレイ
同じコントラクトが同じアドレスで複数のチェーンにデプロイ → 署名はすべてのチェーンで有効。署名されたメッセージに block.chainid を含める必要があります。
EIP-712 実装エラー
| エラー | 結果 |
|---|---|
chainId を含む DOMAIN_SEPARATOR 欠落 | クロスチェーンリプレイ |
| ドメインセパレーターがデプロイ時にキャッシュ | ハードフォーク後 chainId 変更で破損 |
| 構造体ハッシュに nonce 欠落 | 署名リプレイ |
ecrecover が無効な sig で address(0) を返す | == address(0) オーナーチェックをパス |
8. SELFDESTRUCT & ETH 強制送信
selfdestruct(recipient) はすべてのコントラクト ETH を受信者に強制送信 — receive() と fallback() をバイパス、拒否不可。
address(this).balance をロジックに依存するコントラクトを破壊(例:require(balance == expected))。
EIP-6780 後(Dencun):selfdestruct は ETH のみ送信;コード/ストレージ削除はクリエーションと同じ tx で呼び出された場合のみ。
9. CREATE2 & 決定論的アドレス悪用
CREATE2 アドレス = keccak256(0xff ++ deployer ++ salt ++ keccak256(initCode))。
| 攻撃 | 方法 |
|---|---|
| プリファンド悪用 | アドレスを予測 → デプロイ前にトークン/ETH を送信 → selfdestruct → 同じアドレスで異なるコードを再デプロイ |
| プリアプルーブ悪用 | 予測アドレスがトークンアプルーブを取得 → マリシャスコントラクトをデプロイ → アプルーブされたトークンをドレイン |
| メタモルフィック コントラクト | CREATE2 → selfdestruct → 同じ salt で異なる initCode で CREATE2(EIP-6780 前) |
10. フラッシュローン 攻撃パターン
単一トランザクション:
├── 担保なしで大量を借用
├── ステートを操作(価格オラクル、ガバナンスなど)
├── 操作されたステートから利益を抽出
├── ローン + 手数料を返金
└── 利益を保持
キー:シーケンス全体はアトミックに成功する必要があります。さもなければ、全 tx は revert します。
11. SHORT ADDRESS 攻撃
EVM は ABI エンコードされたコールデータ内の欠落バイトをゼロで埋めます。transfer(address, uint256) が 19 バイトアドレスで呼び出された場合、uint256 額は左に 8 ビットシフト → 256 倍になります。
緩和策:コールデータ長を検証;最新の Solidity コンパイラーはチェックを追加します。
12. ツール
| ツール | 目的 | 使用方法 |
|---|---|---|
| Slither | 静的解析、脆弱性検出 | プロジェクトルートで slither . |
| Mythril | シンボリック実行、パス探索 | myth analyze contract.sol |
| Echidna | プロパティベースファジング | 不変条件を定義、違反でファズ |
| Foundry (Forge) | テスト フレームワーク、ファジング、ガス分析 | forge test --fuzz-runs 10000 |
| Hardhat | 開発、テスト、デプロイ | npx hardhat test |
| Certora | 形式検証 | 仕様を記述、プロパティを証明/反証 |
| 4naly3er | 自動ガス最適化 + 脆弱性報告 | CI 統合 |
13. デシジョンツリー
スマートコントラクト監査?
├── プロキシパターンですか?
│ ├── はい → ストレージレイアウト衝突を確認(セクション 5)
│ │ ├── プロキシと implementation のスロット割り当てを比較
│ │ ├── 関数セレクター衝突を確認
│ │ └── イニシャライザーが 2 回呼び出されないことを検証
│ └── いいえ → 続行
├── 外部呼び出しを行いますか?
│ ├── はい → リエントランシを確認(セクション 1)
│ │ ├── 呼び出し前に状態は更新されましたか? → CEI パターン OK
│ │ ├── ReentrancyGuard が存在しますか? → すべてのエントリーポイントを確認
│ │ ├── クロスファンクション ステート共有がありますか? → クロスファンクション リエントランシリスク
│ │ └── ビュー関数はコールバック中に読み取られますか? → リードオンリー リエントランシ
│ └── いいえ → 続行
├── トークン/ETH を処理しますか?
│ ├── はい → 整数オーバーフローを確認(セクション 2)
│ │ ├── Solidity < 0.8? → すべての算術が疑わしい
│ │ ├── unchecked{} ブロック? → ユーザー影響値がないことを確認
│ │ └── uint サイズ間のキャスト? → 切り詰めリスク
│ └── また selfdestruct 強制送信を確認(セクション 8)
├── 署名を使用しますか?
│ ├── はい → リプレイを確認(セクション 7)
│ │ ├── Nonce が含まれていますか? → インクリメントされていることを確認
│ │ ├── ChainId が含まれていますか? → クロスチェーン安全
│ │ └── ecrecover 結果が address(0) でチェックされていますか? → OK
│ └── いいえ → 続行
├── オンチェーン ランダムネスを使用しますか?
│ ├── はい → 予測可能(セクション 4)
│ │ └── Chainlink VRF またはボンド付きのコミット-リビール を推奨
│ └── いいえ → 続行
├── DeFi プロトコルと相互作用しますか?
│ ├── はい → [defi-attack-patterns](../defi-attack-patterns/SKILL.md) をロード
│ │ ├── フラッシュローン ベクトル
│ │ ├── オラクル操作
│ │ └── MEV 露出
│ └── いいえ → 続行
├── CREATE2 を使用しますか?
│ ├── はい → 決定論的アドレス悪用を確認(セクション 9)
│ └── いいえ → 続行
└── 自動ツールを実行(セクション 12)
├── 静的解析用の Slither
├── シンボリック実行用の Mythril
└── ファジング不変条件用の Echidna
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- yaklang
- リポジトリ
- yaklang/hack-skills
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/yaklang/hack-skills / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。