DeFi 契約セキュリティの新しいモデル: プロトコルの不変性に焦点を当てる

## まとめ

特定の関数に対して require ステートメントを記述するだけでなく、プロトコルに対して require ステートメントを記述します。機能コンプライアンス チェック (要件) - 有効性 (効果) - インタラクション (INteractions) + プロトコル不変性 (イニアンツ) または FREI-PI モードは、開発者が機能レベルのセキュリティに重点を置くことになるため、契約の安全性を高めるのに役立ちます。プロトコルレベルの不変条件の場合。

## モチベーション

2023 年 3 月、オイラー ファイナンスはハッキングを受け、2 億ドルを失いました。 Euler Finance は、ユーザーが担保を預けて、それに対して借りることができる融資市場です。これにはいくつかのユニークな機能があり、実際、Compound Finance や Aave に匹敵する融資市場です。

このハッキングに関する事後調査はここで読むことができます。その主な内容は、特定の機能におけるヘルスチェックの欠如であり、これによりユーザーは融資市場の基本的な不変性を破ることができます。

基本的なイニシエイト

ほとんどの DeFi プロトコルの中核には、常に true であることが期待されるプログラム状態の特性である不変性があります。複数の不変条件を持つことも可能ですが、一般に、それらは中心となるアイデアに基づいて構築されます。ここではいくつかの例を示します。

  • 融資市場と同様: ユーザーは、アカウントを安全でない、または安全性の低い担保ポジションに置くいかなるアクションも実行できません (「安全性が低い」とは、すでに最低安全基準を下回っているため、それ以上引き出すことができないことを意味します)。
  • AMM DEX の場合: x * y == k、x + y == k など。
  • 流動性マイニングのステーキングでは、ユーザーは自分が預けたステーキング トークンの量のみを引き出すことができる必要があります。

Euler Finance で問題が発生したのは、必ずしも機能を追加したり、テストを作成しなかったり、従来のベスト プラクティスに従わなかったことではありません。彼らはアップグレードを監査し、テストを実施しましたが、依然として亀裂をすり抜けていました。中心的な問題は、融資市場の中核となる不変条件を彼らが忘れていることです(監査人も同様です!)。

※注:オイラーを非難するつもりはありません、彼らは才能のあるチームですが、これは最近のケースです。 *

問題の核心

あなたはおそらく、「まあ、その通りです。だから彼らはハッキングされたのです。彼らは require ステートメントを忘れていたのです。」と考えているでしょう。はいといいえ。

しかし、なぜ彼らは require ステートメントを忘れてしまうのでしょうか?

チェック - 検証 - インタラクションが十分ではありません

Solidity 開発者に推奨される一般的なパターンは、Checks-Effects-Interactions パターンです。これは、再入可能性に関連するバグを排除するのに非常に役立ちますが、多くの場合、開発者が実行する必要がある入力検証の量が増加します。 _しかし_、木を見て森を見ないという問題が起こりがちです。

これが開発者に教えることは、「最初に require ステートメントを書き、次に検証を行い、その後何らかの対話を行うと、安全である」ということです。問題は、多くの場合、チェックとエフェクトが混在することです。悪くないですよね?インタラクションはまだ最終的なものであるため、再入可能性は問題ではありません。しかし、それによりユーザーは、グローバルでより広範なコンテキストではなく、より具体的な機能と個々の状態遷移に集中することになります。この意味は:

単なるチェック、検証、相互作用のパターンでは、開発者はプロトコルの中核となる不変条件を忘れてしまいます。

これは依然として開発者にとって優れたパターンですが、プロトコルの不変性を常に確保する必要があります (真剣に、CEI を使用する必要があります!)。

正しく実行: FREI-PI モード

たとえば、貸付市場およびレバレッジ取引契約である dYdX の SoloMargin 契約 (ソース コード) からのこのスニペットを見てみましょう。これは、私が Function Requirements-Effects-Interactions + Protocol Iniants パターン、または FREI-PI パターンと呼んでいるものの良い例です。

したがって、アーリーステージ融資市場の中で市場に起因する脆弱性が存在しない唯一の融資市場であると考えております。 Compound と Aave には直接的な問題はありませんが、フォークには問題があります。そして、bZx は何度もハッキングされています。

以下のコードを調べて、次の抽象化に注目してください。

  1. 入力パラメータ (_verifyInputs) を確認します。
  2. アクション(データ変換、状態操作)
  3. 最終状態を確認します (_verifyFinalState)。

通常のチェック、効果、相互作用は引き続き実行されます。追加チェックとのチェック検証相互作用は FREI-PI と同等ではないことに注意してください。FREI-PI は似ていますが、根本的に異なる目的を果たします。したがって、開発者はこれらを異なるものとして考える必要があります。FREI-PI はより高い抽象化として、プロトコルの安全性を目的としているのに対し、CEI は機能の安全性を目的としています。

この契約の構造は非常に興味深いもので、ユーザーは一連のアクションで必要なアクション (入金、借入、取引、送金、清算など) を実行できます。 3 つの異なるトークンを入金し、4 つ目のトークンを引き出し、アカウントを清算したいですか?一本の電話です。

これが FREI-PI のパワーです。ユーザーは、通話終了時にコア融資市場の不変条件が保持されている限り、プロトコル内でやりたいことを何でも行うことができます。単一のユーザーは、アカウントを安全に保つようなアクションを実行できません。またはそれ以上の担保ポジションが安全ではありません。この契約の場合、これは _verifyFinalState で実行され、影響を受ける各アカウントの担保をチェックして、契約が取引開始時よりも良好であることを確認します。

この関数には、コアの不変条件を補完し、市場を閉じるなどのサイド機能を支援する追加の不変条件がいくつか含まれていますが、実際にプロトコルの安全性を維持するのはコアのチェックです。

エンティティ中心の FREI-PI

FREI-PI のもう 1 つの問題は、エンティティ中心の概念です。例として、融資市場と想定されるコア不変条件を取り上げます。

技術的には、これは唯一の不変式ではありませんが、ユーザー エンティティに対するものです (これはまだコア プロトコルの不変式であり、通常、ユーザーの不変式はコア プロトコルの不変式です)。融資市場には通常、さらに 2 つのエンティティもあります。

  • オラクル
  • 経営/ガバナンス

不変性が増えるたびにプロトコルの保証が難しくなるため、不変性は低いほど良いのです。これは実際、ダン・エリッツァー氏が「DeFi が壊れている理由とその修正方法 #1 オラクルレス プロトコル」というタイトルの記事で述べたことです (ヒント: この記事では実際にはオラクルが問題であるとは言っていません)。

オラクル

オラクルの場合は、1 億 3,000 万ドルの Cream Finance のエクスプロイトを例に挙げます。 Oracle エンティティの中核となる不変性:

結局のところ、FREI-PI を使用して実行時にオラクルを検証するのは難しいですが、事前に考えておけば実行可能です。一般的に言えば、Chainlink は不変性のほとんどを満たしており、主に依存するのに適した選択肢です。まれに操作や予期せぬ事態が発生した場合には、精度を優先して柔軟性を低下させる安全装置を設けると有益な場合があります (最後に知られた値が現在の値より数パーセント大きいかどうかを確認するなど)。また、dYdX の SoloMargin システムは、DAI オラクルで素晴らしい仕事をしています。コードは次のとおりです (分からない場合は、これはこれまでに書かれた中で最高の複雑なスマート コントラクト システムだと思います)。

オラクルの評価の詳細と、オイラーのチームの能力を強調するために、彼らは Uniswap V3 TWAP オラクル価格の計算操作に関する優れた記事を書きました。

管理/ガバナンス

管理対象エンティティの不変条件の作成は最も注意が必要です。これは主に、それらの役割のほとんどが既存の他の不変条件を変更することであるという事実によるものです。とはいえ、管理ロールの使用を避けられるのであれば、そうすべきです。

基本的に、管理対象エンティティの中核となる不変条件は次のとおりです。

解釈: 管理者は、ユーザーの資金を保護するために大幅に変更しない限り、不変条件を破ることにならないことを行うことができます (例: 資産をレスキュー コントラクトに移動することは、不変条件を削除することです)。管理者もユーザーとみなされる必要があるため、コア融資市場のユーザー不変性も管理者に適用される必要があります (つまり、管理者は他のユーザーやプロトコルを攻撃できないということです)。現在、一部の管理者のアクションは FREI-PI を介して実行時に検証することができませんが、十分に強力な不変条件が他の場所にあれば、ほとんどの問題が軽減されることが期待されます。現在、と言うのは、コントラクトの状態全体 (ユーザーごと、オラクルごとなど) をチェックする可能性のある zk 証明システムを使用することが想像できるためです。

管理者が不変性を破る例として、2022 年 8 月に cETH 市場を引き起こした複合ガバナンス アクションを取り上げます。基本的に、このアップグレードは Oracle の不変性を破壊します。Oracle は正確で (比較的) リアルタイムの情報を提供します。機能が欠落しているため、Oracle は誤った情報を提供する可能性があります。実行時の FREI-PI 検証により、影響を受ける Oracle がリアルタイム情報を提供できるかどうかを確認することで、アップグレードでのこの問題の発生を防ぐことができます。これを _setPriceOracle に組み込んで、すべての資産がリアルタイム情報を受信したかどうかを確認できます。管理者ロールにとって FREI-PI の優れた点は、管理者ロールが価格に比較的鈍感である (少なくともそうあるべきである) ため、ガス使用量が増えても大きな問題にならないことです。

複雑さは危険です

したがって、最も重要な不変式はプロトコルのコア不変式ですが、コア不変式によって保持されなければならないエンティティ中心の不変式もいくつか存在する可能性があります。ただし、最も単純な (そして最小の) 不変条件のセットがおそらく最も安全です。シンプルであることは良いことです。その好例は Uniswap です…

Uniswap がハッキングされなかった理由 (おそらく)

AMM は、DeFi プリミティブの最も単純な基本不変性を持つことができます: tokenBalanceX * tokenBalanceY == k (例: 定数製品モデル)。 Uniswap V2 のすべての関数は、次の単純な不変条件を中心に展開します。

1.ミント:kに追加 2. 燃焼: k から減算します。 3. スワップ: x と y を転送しますが、k は保持します。 4. スキム: tokenBalanceX * tokenBalanceY を k と等しくなるように再調整し、冗長な部分を削除します。

Uniswap V2 のセキュリティの秘密: コアは単純な不変性であり、すべての機能はそれにサービスを提供します。議論できる他の唯一のエンティティはガバナンスです。ガバナンスは料金スイッチをオンにすることができますが、これは中核となる不変性には触れず、トークン残高の所有権の分配にのみ影響します。 Uniswap がこれまでハッキングされなかった理由は、セキュリティに関する声明のこのシンプルさです。シンプルさは、Uniswap のスマート コントラクトの優れた開発者を軽蔑するものではなく、逆に、シンプルさを見つけるには優秀なエンジニアが必要です。

ガスの問題

私のツイッターはすでに、こうしたチェックは不必要で非効率的だという、最適化主義者の恐怖と痛みの叫びでいっぱいだ。この質問については次の 2 つのことがわかります。

  1. 他に何が非効率なのか知っていますか? ~~ローレンス~~ 北朝鮮のハッカーにetherscan経由でメッセージを送信し、ETHを使用して送金し、FBIが介入すると脅迫しなければなりませんでした。
  2. おそらく、必要なデータはすべてストレージからすでにロードされているので、通話の最後に、ホット データに少しの require チェックを追加するだけです。契約にかかる費用は無視できる程度に抑えたいですか、それとも契約を破棄しますか?

コストが法外に高い場合は、中核となる変数を再考し、簡素化を試みてください。

これは私にとって何を意味しますか?

開発者としては、開発プロセスの早い段階で核となる不変条件を定義して表現することが重要です。具体的な提案として、自分で作成する最初の関数は _verifyAfter で、コントラクトを呼び出すたびに不変条件を検証します。それを契約に入れて、そこにデプロイします。この不変条件 (および他のエンティティ中心の不変条件) を、展開前にチェックされる広範な不変条件テストで補足します (Foundry ガイド)。

一時ストアは、Nascent が実験する予定の興味深い最適化と改善の可能性をもたらします。呼び出しコンテキスト全体での安全性を向上させるツールとして一時ストアをどのように使用できるかを検討することをお勧めします。

この記事では、入力検証のための FREI-PI モデルの導入にはあまり時間がかかりませんが、これも非常に重要です。入力の境界を定義することは、オーバーフローや同様の状況を回避するための困難な作業です。私たちのツールであるパイロメーター (現在ベータ版です。星を付けてください) をチェックして進捗状況を追跡することを検討してください。ドリルダウンして、入力検証を行っていない可能性のある場所を見つけるのに役立ちます。

## 結論は

キャッチーな頭字語 (FREI-PI) やスキーマ名に加えて、本当に重要なのは次のとおりです。

プロトコルの中核となる不変性にシンプルさを見出してください。そして、それが決して破壊されないように(または破壊される前に捕らえられるように)、必死に働きます。

原文表示
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
  • 報酬
  • コメント
  • 共有
コメント
0/400
コメントなし
  • ピン
いつでもどこでも暗号資産取引
qrCode
スキャンしてGateアプリをダウンロード
コミュニティ
日本語
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)