教育目的のみであり、投資またはセキュリティ上の助言ではありません。監査報告書、ツールの結果、解決済みの指摘、または一致するソースファイルは、認証、保険、補償、あるいは稼働中のデプロイが安全であることの証明ではありません。
要点
スマートコントラクト監査は、明示された期間において、指定された要件、ソースコード、ビルド入力、デプロイロジック、セキュリティ上の前提を調べる限定的なレビューです。監査担当者は相互補完的な手法で欠陥を特定し、悪用経路を実証し、影響を評価して、提案された修正を確認します。結論が適用されるのは、報告書に記載された監査時点のスナップショットと証拠だけです。
スナップショットでは、リポジトリとコミットまたはツリーハッシュ、サブモジュールと依存関係のロック、コンパイラと設定、生成コード、デプロイスクリプト、対象チェーンとアドレス、プロキシ、実装またはビーコン、コンストラクタまたは初期化データ、ライブラリ、管理者、タイムロック、特定のブロックまたは時点を固定します。除外事項は対象事項と同じくらい重要です。フロントエンド、keeper、オラクル、ブリッジ、ガバナンス手続、オフチェーン署名者が監査対象外でも、リスクを左右することがあります。
監査には脅威モデルと仕様が必要です。資産、主体、特権ロール、信頼境界、攻撃者の能力、順序と再編成の前提、外部依存関係、状態遷移、正確な安全性とライブネスの性質を特定します。単位、事前条件、量化、例外がない不変条件は、誤った挙動を完全に証明またはテストしかねません。
4つの台帳を用います。スコープ・ビルド・デプロイ同一性、要件・脅威・不変条件、指摘・証拠・再テスト、残存リスク・受容・開示です。critical の指摘がない報告書はセキュリティ認証ではなく、resolved とされた指摘がデプロイ済みとは限りません。証明も、符号化した性質、モデル、前提だけを対象とします。
仕組み
手動レビューでは、アーキテクチャ、資金フロー、関数をまたぐ状態、経済的意図を追跡します。静的解析はパターンとデータフローを検出しますが、偽陽性と偽陰性があり得ます。単体、統合、フォーク、差分テストは具体的な挙動を比較します。ステートフル・ファジングと不変条件テストは生成した呼び出し列を探索しますが、結果はハンドラ、セレクタ、シード、コーパス、実行回数、深さ、モデル化した環境に依存します。
シンボリック実行と形式検証は、対応する意味論と前提の下で特定の表明を確立できます。ソルバーの unknown、タイムアウト、未対応の挙動は証明ではありません。証明済みの性質でも、オラクルの経済性、ガバナンス、デプロイ設定、チェーンの挙動、またはチームが本当に意図した要件を含まないことがあります。仕様と解釈は人によるレビューの責任であり、AIが生成した所見は独立した保証手法ではありません。
各指摘には、影響を受ける成果物とデプロイ、前提条件、最小限の実証、悪用経路、到達可能性、必要権限、攻撃資本、反復可能性、経済的影響、重大度基準、推奨事項を記載します。悪用可能性または発生可能性と影響は別の軸です。理論上の最大値、脆弱性名、ツールのラベルだけでは、実行可能な損失を立証できません。
open、acknowledged、risk accepted、partially fixed、resolved、retested などの状態は統一規格ではありません。根拠ある完了には、元の指摘を正確な修正コミットに結び付け、変更箇所と隣接経路のテストを記録し、誰がいつ何を再テストしたかを示す必要があります。受容したリスクもリスクであり、限定的な再テストによって元の範囲がすべての新規コードへ広がるわけではありません。
アップグレード可能なデプロイには特別な照合が必要です。プロキシ、実装またはビーコンと管理者スロットを解決し、初期化・再初期化の挙動、実装のロック、ストレージ互換性、アップグレード権限、タイムロックまたは緊急時の迂回、移行とロールバックを検証します。監査済みビルドから作成バイトコードとランタイムバイトコードを再現し、各チェーンでリンク済みライブラリ、パラメータ、ロール、初期化済み状態を比較します。
最終報告書には、改訂版、監査担当者と日付、正確な範囲、手法と設定、制限、指摘、証拠、修正状況、未解決または受容済みのリスク、開示条件を記載します。リリース後は、実装ハッシュ、ロール、パラメータ、依存関係、インシデントを監視します。重要な変更は新たな差分レビューを必要とし、旧報告書のバッジが将来のコードへ自動的に引き継がれることはありません。
次の手順を用います。
- 監査マニフェストを固定します。リポジトリ、コミット、依存関係、コンパイラと設定、生成コードとデプロイコード、チェーン、アドレス、プロキシ構成、パラメータ、ブロック、報告書の改訂、対象と除外事項を記録します。
- 資産、主体、特権ロール、信頼境界、攻撃者の能力、ライフサイクル、順序とライブネスの前提、外部依存関係、測定可能な不変条件を定義します。
- ビルドを再現し、アーキテクチャ、ストレージ、データ、資金、制御を対応付けます。ソース、成果物、ライブラリ、作成・ランタイムバイトコード、初期化、ロール、稼働中のデプロイを照合します。
- 手動、静的、単体、統合、フォーク、差分、ファジング、不変条件、シンボリック、形式的手法を組み合わせ、ツールの版、設定、シード、コーパス、カバレッジ、タイムアウト、未確定結果を記録します。
- 各問題について、対象成果物、前提、実証、悪用可能性、影響、重大度手法、デプロイの露出、推奨事項、機密証拠を記録し、ツールのラベルを判断そのものとして扱いません。
- 修正コミットを固定し、問題、隣接経路、不変条件を再テストします。プロキシストレージ、初期化、移行、ロールバック、再現可能ビルド、デプロイレシートを検証し、証拠に基づく状態を付与します。
- 範囲、手法、制限、残存リスクを公開し、監査済み成果物を稼働中の各チェーンと照合します。システムの変化に合わせて監視、開示、インシデント対応、バグバウンティを更新します。
例
- ボールトのインフレーション経路には完全な台帳が必要です。 攻撃者が初回入金分岐から
1 assetを預けて1 shareを受け取り、続いて1,000,000 assetsを寄付すると、合計は1,000,001 assetsと1 shareになります。被害者が500,000 assetsを入金し、安全でない切り捨て計算によりfloor(500,000 * 1 / 1,000,001) = 0 sharesとなります。ゼロシェアの入金を受け入れる場合、ボールトは1,500,001 assetsを保有し、攻撃者は全額を償還して500,000 assetsを得ます。攻撃者の拠出は1,000,001-assetです。ゼロシェアでリバートする実装なら、この損失経路は実行されません。 - ファイルのカバレッジはデプロイのカバレッジではありません。 マニフェストには
24 source units、4 deployment scripts、3 keeper services、合計31 itemsがあります。監査対象は20 source unitsと2 scriptsなので、件数カバレッジは22 / 31 = 70.96774194%、残る9 itemsは除外です。稼働中のプロキシが除外された単位からビルドした実装を参照するなら、その実装のカバレッジは0%です。これは見出しに示した70.96774194%とは別の尺度です。 - ファジングの観測は不存在証明ではありません。 ステートフル実行で
2,000 sequences * 64 calls = 128,000 callsを行い、不変条件が3 sequencesで失敗すると、生成列における観測比率は3 / 2,000 = 0.15%です。修正後、10,000 sequences * 64 calls = 640,000 callsで失敗がゼロでも、このコーパスでゼロというだけで証明ではありません。独立かつ生成器が安定しているという教材上の前提では、三の法則による近似95%上限は生成列当たり3 / 10,000 = 0.03%です。 - 指摘の完了とデプロイ同一性は独立しています。 報告書には
12 findings、内訳は2 critical、3 high、4 medium、3 lowがあります。再テストで2 + 2 + 3 + 2 = 9件が完了し、件数完了率は9 / 12 = 75%ですが、高・中・低が1件ずつ残ります。監査済みランタイムハッシュはH1、稼働中の実装はH2なので、完了率にかかわらずデプロイ検証は失敗です。正確なH1に置き換え、プロキシスロット、初期化、ロールが一致しても、証明できるのは確認したブロック時点の同一性だけです。
リスク
- リポジトリ、コミット、サブモジュール、生成ソースが古い、または曖昧です。
- コンパイラ版、最適化設定、ライブラリ、依存関係が固定されていません。
- デプロイスクリプト、コンストラクタデータ、初期化、CREATE2 saltが除外されています。
- 誤ったチェーン、アドレス、プロキシ、ビーコン、実装を調べています。
- ソース、成果物、作成バイトコード、ランタイムバイトコードを照合できません。
- 脅威モデルが主体、権限、資産、信頼境界を見落としています。
- 仕様または不変条件の単位、事前条件、例外が誤っています。
- 管理者、ガーディアン、タイムロック、一時停止、アップグレード、移行経路を見落としています。
- オラクル、トークン、ブリッジ、keeper、ガバナンス、チェーンの前提が崩れます。
- 静的解析の偽陽性が未精査のままです。
- 手動レビュー、テスト、ファジングが生成されなかった経路を見落とします。
- ファジングのハーネス、セレクタ、シード、コーパス、深さ、状態モデルに偏りがあります。
- ソルバーのタイムアウト、未対応の意味論、
unknownを証明と誤認します。 - 正しい証明が誤った要件または不完全なシステムを形式化しています。
- 重大度を悪用可能性と影響ではなく脆弱性名で決めています。
- 理論上のリスク額を到達可能な損失または攻撃者利益と誤認します。
- 修正が隣接箇所の回帰や経済的不変条件の破壊を招きます。
- プロキシストレージ、初期化、アップグレード、移行が稼働状態を破壊します。
- 受容済み、未解決、一部修正の問題が監査済みバッジで隠れます。
- 報告書が保険、認証、補償、恒久的な保証範囲として扱われます。
よくある誤解
- 「重大な指摘がなければコントラクトは安全だ。」 限定された範囲、期間、手法で報告された指摘を示すだけで、あらゆる欠陥を否定するものではありません。
- 「高いテストカバレッジやファジング失敗ゼロは、バグがない証明だ。」 選んだコードと生成経路の測定値であり、不存在証明ではありません。
- 「形式検証はプロトコル全体の安全を証明する。」 前提の下でモデルに符号化した性質を証明するだけで、仕様や周辺システムが誤っている可能性は残ります。
- 「解決済みならすべての稼働中デプロイが修正済みだ。」 完了には独立した再テストと、各デプロイのビルド、バイトコード、プロキシ、パラメータ、ロールの照合が必要です。
- 「著名な監査会社なら補償や将来のアップグレードも保証する。」 責任は監査契約によって決まり、利用者が受益者とは限らず、後続コードや設定は旧スナップショットの対象外です。
関連トピック
出典
- OWASP Smart Contract Security Verification Standard (SCSVS) - OWASP (参照日: 2026-08-13)
- Security Considerations - Solidity (参照日: 2026-08-13)
- Slither, the smart contract static analyzer - Crytic (参照日: 2026-08-13)
- Invariant Testing - Foundry (参照日: 2026-08-13)
- Certora User’s Guide - Certora (参照日: 2026-08-13)
- ERC-1967: Proxy Storage Slots - Ethereum Improvement Proposals (参照日: 2026-08-13)
- Writing Upgradeable Contracts - OpenZeppelin (参照日: 2026-08-13)
- Contract Metadata - Solidity (参照日: 2026-08-13)