Smart Contract Audits: What Auditors Check—and What an Audit Does Not Guarantee
スマートコントラクト監査は、定められた範囲内でコードとアーキテクチャを独立して検証するものです。脆弱性、実装上の誤り、意図した動作と実際の動作の不一致を特定することを目的とします。
監査は不確実性を減らせますが、コントラクトを無リスクにするものではありません。Ethereum の公式セキュリティガイダンスでも、監査はすべてのバグを見つける万能策ではなく、追加のレビューと説明されています。
この記事は教育目的でのみ提供されています。監査は安全性、資金回収、リターンを保証しません。
まず対象範囲を確認する
有用なレポートでは、確認した対象を正確に示します:
- リポジトリとコミットハッシュ。
- ファイルとコントラクト。
- コンパイラーバージョンとビルド設定;
- 依存関係。
- アーキテクチャと特権ロール;
- ブランチまたはリリース;
- 除外事項、制限事項、前提条件。
- レビュー日。
本物の監査でも、旧バージョン、別のデプロイ、または大規模システムの一部だけを対象としている場合があるため、この確認が重要です。
監査担当者が一般に確認する項目
1. 想定される動作と不変条件
監査担当者はコードと仕様を比較します:
- 各関数を呼び出せるのは誰か。
- 金額と手数料の計算方法。
- ステータスがいつ変更されるか。
- 常に成立すべきプロパティは何か。
- エッジケースや障害への対処方法。
仕様に重要な要件が欠けていると、技術的には正しいコードでも、安全でない、または望ましくない設計を実装してしまう可能性があります。
2. アクセス制御
レビュー担当者は、owner、admin、operator などの特権ロールと、次の権限を確認します:
- 権限を付与または取り消す。
- システムを一時停止する。
- 手数料と上限を変更する;
- トークンをミントする。
- 資産を引き出す。
- 実装をアップグレードする。
さらに、一つの鍵だけで重要な変更が可能か、マルチシグやタイムロックなどの制御が設計に含まれるかも確認します。
3. 外部呼び出しとリエントランシー
コントラクトは実行中に別のコントラクトへ制御を渡すことがあります。このとき、元の状態変更が完了する前に外部コントラクトから再び呼び出されるリエントランシーが発生する可能性があります。Solidity の公式ガイダンスでは、必要に応じてチェック、状態変更、外部とのやり取りを慎重な順序で行うことを推奨しています。
4. 計算と単位
監査担当者が確認する項目:
- 丸め処理と精度の損失。
- トークンの小数桁の不一致。
- 誤った処理順序。
- 境界値;
- ゼロ除算。
- unsafe
uncheckedarithmetic; - 内部単位と表示単位の不一致。
5. サービス拒否とガス
上限のないループ、増大する配列、失敗する外部呼び出し、高コストな操作により、関数の実行が現実的でなくなる場合があります。レビュー担当者は、データ量が増えた場合や異常な入力でも設計を利用できるかテストします。
6. プロキシとアップグレード
アップグレード可能なシステムでは、次をレビュー対象に含めます:
- プロキシコントラクトと実装コントラクト。
- upgrader または admin の権限。
- 初期化。
- ストレージレイアウトの互換性。
- 不正なアップグレード経路。
- 監査後にロジックを変更することによる影響。
プロキシは、ユーザー向けアドレスを変えずに新しいロジックへ処理を委譲できます。そのため「コントラクトは変更できない」という主張は、実際のアーキテクチャに照らして確認する必要があります。
7. 連携機能
コントラクトは、トークン、価格オラクル、ブリッジ、DEX、署名、その他のコントラクトに依存する場合があります。監査担当者は、こうした依存関係に関する前提、古いデータ、通常とは異なるトークン動作、外部障害のシナリオを確認します。
8. イベントと監視
レビュー担当者は、ロール変更、アップグレード、一時停止、送金などの重要な操作がイベントに正確に記録されているか確認します。イベントは監視に役立ちますが、状態確認の代わりにはなりません。
監査で使用される手法
一般的なレビューで組み合わせて確認するもの:
- コードとアーキテクチャの手動分析。
- 単体テストと統合テスト。
- 静的解析と動的解析。
- 生成した入力値によるファジング。
- プロパティベーステスト。
- 既知の脆弱性分類に関するチェック;
- ビルドとデプロイのレビュー;
- 場合によっては、選択したプロパティの形式検証。
一つの手法だけですべてを確認することはできません。形式検証では、コードが形式仕様を満たすことを証明できますが、仕様に記載されていない性質は証明できません。
ユーザーが監査結果を読む方法
1. 監査対象バージョンとの一致を確認する
コミットハッシュを確認し、次を判断します:
- 現在の実装がそのコードからビルドされたか。
- レポート日以降にアップグレードが行われたか。
- チェーンとデプロイ済みアドレスが一致しているか。
- 重要な依存関係が監査範囲に含まれていたか。
これを確認できない場合、そのレポートが稼働中のデプロイについて示す証拠は限定的です。
2. 要約だけでなく指摘事項も読む
各指摘事項について確認する項目:
- 重大度と想定シナリオ。
- 影響を受けるコード;
- 推奨事項。
- 開発者からの回答。
- 現在のステータス。
- 監査人が修正後に再テストしたか。
Fixed or Resolved is meaningful only when tied to a specific corrected version.
3. 制限事項を読む
レポートの対象外となる可能性があるもの:
- フロントエンドおよびバックエンドシステム。
- 鍵の管理。
- 経済設計。
- 第三者のコントラクト。
- デプロイ基盤。
- 本番環境の設定。
- 法務および運用上の問題。
ユーザーが利用するのは Solidity ファイルだけでなく、システム全体です。
4. 管理権限のリスクを確認する
確認事項:
- 誰がアップグレードを管理しているか。
- 操作を一時停止できるか。
- 手数料または関連アドレスを変更できるか。
- タイムロックが存在するか。
- マルチシグが使用されているか。
- 変更がユーザーに周知される方法。
コードに既知の脆弱性がなくても、これらはガバナンスと信頼に関する問題です。
5. 監査後のセキュリティも確認する
継続的に確認すると役立つ指標:
- すべてのリリースのテスト。
- 重要なアップグレードの審査。
- バグ報奨金プログラム;
- ロールと実装の監視。
- インシデント対応手順。
- リスクにさらす資産額を制限する。
What an audit does not guarantee
監査で保証されないこと:
- あらゆるバグが存在しないこと;
- レビュー後に変更されたコードの安全性。
- ウェブサイト、ウォレット、DNS、またはサーバーの安全性。
- 特権鍵のセキュリティ。
- 外部トークン、オラクル、ブリッジの正確性;
- あらゆる経済的攻撃への耐性。
- チームの誠実性。
- 法令遵守。
- トークンの流動性。
- 資金の返還。
- 固定収益またはその他の収益。
慎重なユーザーが確認すべき質問
Is an auditor’s logo enough?
No. Find the report from the auditor’s own source and check its scope, commit, date, and findings.
If every finding was fixed, is the contract safe?
It means the listed findings were addressed in a stated version. Unknown issues and out-of-scope risks remain.
Are several audits automatically better?
The count alone says little. Coverage, quality, independence, recency, and version matching matter more.
Does an audit still apply after a proxy upgrade?
Only if the new implementation and configuration are covered by the reviewed version.
レポート確認リスト
- レポートを監査会社の情報源から入手できる。
- リポジトリとコミットハッシュが記載されている。
- 重要なコントラクトと依存関係が監査範囲に含まれている。
- レビュー対象バージョンが稼働中のデプロイと一致している。
- プロキシ、実装、admin が監査範囲に含まれている。
- ステータスの確認方法と再テストが記録されている。
- 前提条件と除外事項を確認済み。
- コード外のリスクを別途評価した。
情報源と参考資料
- Ethereum.org — スマートコントラクトのセキュリティ
- Ethereum.org — スマートコントラクトのテスト
- Ethereum.org — スマートコントラクトの形式検証
- Solidity Documentation — セキュリティ上の注意事項
- OpenZeppelin Docs — プロキシアップグレードパターン