【ITニュース解説】Who can upgrade this contract? Five RPC calls, five traps, and 146 Morpho vaults
2026年10月13日に「Dev.to」が公開したITニュース「Who can upgrade this contract? Five RPC calls, five traps, and 146 Morpho vaults」について初心者にもわかりやすく解説しています。
ITニュース概要
DeFiの損失原因は管理者キー盗難に移行中。スマートコントラクトのアップグレード権限が誰にあるか、RPCコールで自分で確認する方法を解説する。管理者キーが単一か複数か、時間差承認があるかなど、キーの種類を把握することが重要だ。単一キーで即座に変更可能なリスクも存在することが判明している。
ITニュース解説
分散型金融(DeFi)の領域では、私たちの資産はスマートコントラクトによって管理されている。これらのコントラクトは、一度ブロックチェーン上にデプロイされると変更できないのが原則と思われがちだが、実際には多くのコントラクトがアップグレード可能に設計されている。近年、DeFiにおける資金損失の最大の原因は、従来のスマートコントラクトのバグから、コントラクト管理者のキーが流出したり盗まれたりすることにシフトしている。これは、誰がコントラクトをアップグレードできる権限を持っているのか、その権限がどれほど安全に管理されているのか、という点が極めて重要になっていることを示している。
通常のセキュリティ監査は、コード自体の脆弱性を評価するものだ。しかし、それは明日誰がそのコードを書き換えられるかまでは教えてくれない。そこで、システムエンジニアを目指す初心者でも、スマートコントラクトのアップグレード権限が誰にあるのかを自分で確認する方法を理解することが求められる。この確認には、主に5つのリモートプロシージャコール(RPC)を使用する。
まず、確認すべきは、そのコントラクトが「プロキシ」であるかどうかだ。プロキシパターンは、スマートコントラクトのアップグレードを可能にする一般的な仕組みである。ユーザーが直接操作するのはプロキシコントラクトだが、実際のビジネスロジックは別の「実装コントラクト」にあり、プロキシはこの実装コントラクトのアドレスを参照する。この実装コントラクトのアドレスをプロキシ内で書き換えることで、ロジック全体をアップグレードできる。 ほとんどのアップグレード可能なコントラクトは、実装コントラクトのアドレスを特定のストレージスロット(EIP-1967という標準規格)に格納している。しかし、古いプロキシコントラクトの中には、異なるストレージスロットを使用しているものがあるため注意が必要だ。例えば、USDCコントラクトでは、EIP-1967のスロットを確認しても何も情報が得られず、アップグレード不可能に見えるかもしれないが、実際にはZeppelinOS時代からの古いスロットを使用している。したがって、両方のスロットをチェックすることが重要となる。 さらに、管理者アドレスがストレージに全く保存されていないような複雑なケースも存在する。Aaveのプールプロキシのように、管理者がコントラクトのバイトコード内に不変の値としてハードコードされている場合や、Aragonアプリケーションのように分散型自律組織(DAO)のアクセス制御リスト(ACL)を通じてアップグレードが行われる場合がある。これらは単にストレージを読み取るだけでは特定できないため、コントラクトのドキュメントや構造を深く調査する必要がある。
次に、管理者アドレスが特定できたら、そのアドレスが誰によって制御されているのかを確認する。もしコントラクトがUUPSプロキシ(実装アドレスは設定されているが、管理者アドレスがストレージにないタイプのプロキシ)であれば、アップグレード権限は通常、コントラクトのowner()関数によって返されるアドレスか、OpenZeppelinのAccessControlモジュールで定義された特定のロール(例えばDEFAULT_ADMIN_ROLE)に紐付いていることが多い。owner()関数を呼び出したり、ロールのメンバー数を問い合わせたりすることで確認できる。もし管理者アドレス自体がOpenZeppelinのProxyAdminコントラクトであれば、そのProxyAdminコントラクトのowner()を呼び出すことで、真の管理者を見つけ出す必要がある。
最も重要なステップは、特定された管理者アドレスがどのような種類の「キー」であるかを判別することだ。この情報は、ブロックエクスプローラーでは通常直接表示されない。
管理者アドレスがEOA(Externally Owned Account、秘密鍵によって直接制御されるアカウント)であれば、そのアドレスのコードは空である(cast codeコマンドで「0x」が返される)。これは、単一の秘密鍵がアップグレード権限を握っていることを意味する。
一方、もしコードが空でなければ、そのアドレスはスマートコントラクトである。これがマルチシグ(複数の署名が必要な契約)であるGnosis Safeのようなコントラクトであれば、getThreshold()(必要な署名の数)やgetOwners()(署名者リスト)といった関数でその詳細を確認できる。また、アップグレードをすぐに実行せず、一定期間の遅延を設けるタイムロックコントローラ(OpenZeppelin TimelockControllerやCompound-style Timelock)であれば、getMinDelay()やdelay()といった関数でその遅延期間を確認できる。
ここでも重要な注意点がある。Gnosis Safeが常に高い安全性を持つマルチシグであるとは限らない。例えば、3つのオーナーがいるSafeでも、「1-of-3」の設定であれば、たった1つの署名で全ての操作が可能になる。これは、実質的には単一の秘密鍵で制御されているのと同じ状態だ。また、EOAが判明したとしても、それが必ずしも「ホットウォレット」(常にインターネットに接続され、盗まれやすい状態のウォレット)を意味するわけではない。Circle社のUSDC管理キーのように、高いセキュリティを持つハードウェアセキュリティモジュール(HSM)やMPC(Multi-Party Computation)技術で保護されている可能性もある。しかし、オンチェーンでマルチシグや遅延機構がない場合、資産保持者にはアップグレード前に警告の機会がないという事実は正確に理解し、報告すべきだ。
最後に、公開されているRPCノードは不安定な場合がある点にも注意が必要だ。レート制限にかかったり、一時的なエラーで「スロットが空」や「関数が存在しない」といった誤った結果を返す可能性がある。結論を出す前に、必ず別のエンドポイントで再試行することが賢明である。
これらの調査手法は、実際に146のMorpho vaultsに適用された事例がある。Morpho vaultsでは、キュレーターと呼ばれる役割が新しいマーケットを有効にしたり、アダプターを追加して上限を引き上げたりする権限を持つ。この権限は、預金資金を新たな宛先にルーティングできるため、非常に重要視される。 調査の結果、Morphoアプリにリストされている122のvaultsは全て、これらの危険なアクションに3〜7日間のタイムロックが設定されていた。これは、預金者にとってアップグレードに気付き、資金を引き出すための十分な時間があることを意味する。ただし、これらのうち22のvaultsでは、オーナーまたはキュレーターが単一のEOA、あるいは実質的に単一のEOA署名で制御されるSafeだった。タイムロックがあるため緊急事態ではないが、ガバナンスの透明性の観点からは注目すべき点である。 一方で、リストされていない5つのvaults(合計で約3億500万ドルの資産)は、タイムロックがゼロで、単一のEOAがオーナーまたはキュレーターを務めていた。これは、単一のキーがあれば即座に新しいマーケットやアダプターを開設できることを意味する。これらのvaultsは通常、プライベートなものか、まだセットアップ中であると推測されるが、直接これらのvaultアドレスを統合するシステムは、このリスクを確認する必要がある。
これらのステップは、手動でコマンドを叩いて確認することもできるが、この解説の筆者は「OneKeyAway」というツールを開発しており、ワンクリックで同様の情報を取得できるようにしている。このツールは、ブラウザで実行できる無料のチェッカーや、APIを通じて詳細なアップグレードパス(管理者、Safeの閾値と署名者、タイムロックの遅延など)を提供する有料サービスを提供している。
このように、スマートコントラクトのアップグレード権限と、それを制御するキーの種類を正確に理解することは、DeFiプロジェクトのセキュリティリスクを評価する上で不可欠な要素である。特にシステムエンジニアを目指す初心者にとっては、コードのセキュリティだけでなく、運用上のセキュリティ、つまり「誰が何をいつ変更できるか」という視点を持つことが、将来的に安全で堅牢なシステムを設計・構築するために重要な知識となるだろう。