スマートコントラクト監査の実務:投資家のためのデューデリジェンス完全ガイド

金融

「監査済みなら安心」——この思い込みは危険です。スマートコントラクトの脆弱性は、単一の欠陥でTVLが瞬時に蒸発する非連続リスクを生みます。本稿では投資家の立場から、監査(スマコン監査)をどう読み、どう補完し、最終判断に落とし込むかを実務の順序で解説します。専門用語は使いますが、手を動かして確認できる初歩の手順に落として説明します。

スポンサーリンク
【DMM FX】入金

監査とは何を保証し、何を保証しないのか

監査は「一定の観点でのレビュー記録」にすぎません。保証しない代表例は次のとおりです。

経済設計の妥当性:トークンインセンティブやエミッションが価格クラッシュを招くかは、コード外の設計問題です。
オラクル・マーケット依存:価格取得の遅延や歪みは仕様次第で起きます。
運用オペレーション:権限ローテ、マルチシグ閾値、緊急停止の実装と運用体制は別問題です。

つまり監査レポートは必要条件であって十分条件ではありません。投資家は「監査のカバレッジ外」を自分で埋める必要があります。

監査レポートの読み方:5つの赤信号

1) 未解決のHigh/Mediumが残存:修正済みか、パッチのタグ・コミットIDまで追跡します。更新がリリースに反映されていなければ未解決同然です。
2) 再現手順の曖昧さ:PoC(概念実証)がテキストだけでコード不在なら、本当に直ったかが検証不能です。
3) 権限集中:アップグレード、ミント、パラメータ変更が単一アドレス権限になっていないか。実態がEOAなら運用リスクは跳ね上がります。
4) 外部依存:ブリッジやオラクルに対する依存が列挙されていない、あるいはフェイルセーフがない。
5) テストカバレッジ不明:単体・プロパティ・ファジングの別が記載なし。

コードを見る最低限の順序(初心者でもできる)

以下は読みやすい→重大影響の順です。リポジトリが公開されている前提で、タグは実デプロイのコミットに合わせます。

権限周りOwnable等のonlyOwnerメソッド、AccessControlDEFAULT_ADMIN_ROLEの配布、マルチシグの閾値。
資産の出入りtransfertransferFromsafeTransferFromの呼び出し箇所を横断検索。入出金の単一経路化が理想。
外部呼び出しcalldelegatecallexternalの有無。順序(Checks-Effects-Interactions)が崩れていないか。
パラメータ更新:手数料、担保率、上限額などガバナンス変数の上限・下限チェック。
初期化:アップグレード可能プロキシでの二重初期化防止(initializer修飾子)。

典型的な脆弱性と投資家の実務影響

1. リエントランシー

外部コール後の状態更新が遅れると再入可能になります。投資家への影響は、プール資産の抜き取り会計不整合です。Checks-Effects-Interactionsの順序、ReentrancyGuard、プル型払い出しの採用を確認します。

2. 整数オーバーフロー/アンダーフロー

近年はSolidity 0.8+で標準的に検出されますが、uncheckedブロックや低レイヤ最適化で露出します。報酬計算の桁あふれはAPR/APYの虚偽表示に直結します。

3. オラクル依存と価格操作

低流動性ペアを参照するspot一本足打法は危険です。TWAPや複数オラクルの合議、デペッグ検知のガードを確認します。

4. アクセス制御不備

緊急停止の呼び出し権限や、アップグレード管理者がEOAであることは赤信号です。マルチシグMPCでの管理、タイムロック付与が望ましいです。

5. 初期化ミス/鍵漏えい

未初期化のプロキシ、テスト用鍵の残骸、公開レポジトリに秘密情報が残っていないか。これはゼロデイ級の破壊力です。

セルフレビューの最小手順(実務フロー)

1) デプロイ情報の固定:アドレス、チェーン、バージョン、コミットID、ブロック高。エクスプローラのソース検証が一致するか。
2) 依存関係ロックpackage-lock.jsonfoundry.tomlのバージョン固定を確認。
3) 権限台帳を作る:各コントラクトの管理者・ミンター・パウザーを表にし、誰が何をいつ変えられるかを把握します。
4) 資金フロー図:入金→保管→出金の矢印を一本化。分岐や短絡(ショートカット)があると攻撃面が増えます。
5) 最小ファジング:境界値(0、最大値、同一トランザクション連打)で簡易ファズ。リワード計算や手数料が破綻しないか。

監査の「外側」を詰める:運用とガバナンス

権限の分散:3/5以上のマルチシグ+タイムロック24–48h。
緊急停止:停止ロジックが資産を凍結するのか、操作のみ無効化するのか。復帰手順と所要時間。
パラメータ変更の透明性:オンチェーン投票or多署名の公開通知。
運用監視:残高、価格乖離、オラクル遅延、ガス急騰のしきい値監視。

投資判断への落とし込み:スコアリング

定性・定量を混ぜてスコアリングします。

【例:20点満点】
・コード健全性(0–6):未解決のHigh=−3、外部呼出の順序正しい+2、テスト記述+1など。
・権限/ガバナンス(0–6):マルチシグ+2、タイムロック+2、権限範囲明記+2。
・外部依存(0–4):オラクル多重化+2、ブリッジ冗長化+2。
・運用体制(0–4):監視/アラート+2、インシデント手順+2。

閾値例:16点以上→許容、12–15→少額から、11以下→見送り。数式ではなく意思決定の拘束具として使います。

ケーススタディ:単純化した金庫コントラクト

以下の擬似コードは、典型的な落とし穴と是正案を同時に示します。

// 擬似Solidity
withdraw(amount) {
  // NG: 外部呼出しを先にしている(リエントランシー)
  token.transfer(msg.sender, amount);
  balances[msg.sender] -= amount;
}

// 改善
withdraw(amount) {
  uint256 b = balances[msg.sender];
  require(b >= amount, "exceed");
  balances[msg.sender] = b - amount; // Effects
  bool ok = token.transfer(msg.sender, amount); // Interactions
  require(ok, "transfer failed");
}

投資家としては、こうした書き換えの痕跡が実デプロイに反映されているか(コミット→タグ→アドレス)をトレースすることが要点です。

テストを一つだけ書くなら(最小実験)

連続出金:同一トランザクションで2回withdrawを試み、2回目が失敗すること。
境界値:残高=0、最大値−1、最大値+1での挙動。
権限:一般ユーザが管理関数を呼べないこと。

よくある誤解と対処

「監査会社が有名ならOK」:バグはゼロになりません。自分のスコアリングで上書きします。
「TVLが大きいから安全」:攻撃者の動機が強まり、逆に危険です。
「アップグレード可能=柔軟で良い」:後出しで仕様変更できるため、投資家保護の観点ではリスクです。

まとめ

監査はスタート地点です。投資家は、権限・資金フロー・外部依存・運用体制を最小限の手順で確認し、独自スコアで意思決定を固定化します。複雑さを避け、確認可能性を重視することが、長期的な損失回避に直結します。

コメント

タイトルとURLをコピーしました