最近の Curve プールの脆弱性は、これまでに発生した暗号通貨ハッキング事件とは異なります。今回の問題は、スマート コントラクト自体の脆弱性に直接関係しているのではなく、使用されているプログラミング言語 Vyper の基礎となるコンパイラーに関係しているからです。
Vyper は、Python のようなスタイルを採用し、特にイーサリアム仮想マシン (EVM) と対話するように設計されたスマート コントラクト指向のプログラミング言語です。
この脆弱性の影響は非常に深刻で、巨額の損失が毎日ニュースで報道されています。状況は制御されているように見えますが、ハッカーが 7,000 万ドル以上を盗むまでには至っていませんでした。 LlamaRiskの事後評価によると、1,100万米ドルを失ったPEGDのpETH/ETHプール、340万米ドルを失ったMetronomeのmsETH/ETHプール、11米ドルを失ったAlchemixのalETH/ETHプールなど、一部のDeFiプロジェクトプールもハッカーによる攻撃を受けた。 Curve DAOのプールは約2,470万米ドルを失いました。
この脆弱性は再入エラーと呼ばれ、主に Vyper プログラミング言語の一部のバージョン、具体的には v0.2.15、v0.2.16、v0.3.0 で発生します。したがって、これらの特定のバージョンの Vyper を使用するプロジェクトは攻撃のターゲットになる可能性があります。
リエントラントとは何ですか?
この脆弱性が発生した理由を理解するために、まずリエントラントとは何か、そしてそれがどのように機能するかを理解しましょう。
いわゆるリエントランシーとは、関数が実行中に中断され、前の呼び出しが完了する前に安全に再度呼び出すことができることを意味します。このメカニズムは、ハードウェア割り込み処理や再帰などのアプリケーションでよく使用されます。
関数がリエントラントであるためには、いくつかの条件を満たす必要があります。
まず、グローバル データや静的データは使用できません。これは規則であり、関数の実行時にグローバル データや静的変数に依存しないことを意味します。実行中に関数が中断され、再度呼び出された場合、グローバル データや静的データが破損したり、情報が失われる可能性があるためです。
第二に、それ自体のコードを変更することはできません。関数がいつ中断されても、同じ方法で実行を継続できる必要があります。関数が実行中にそれ自体のコードを変更すると、再度呼び出したときにエラーが発生する可能性があります。
最後に、再入可能ではない他の関数を呼び出すことはできません。つまり、再入可能関数内では、再入可能ではない他の関数を呼び出すべきではありません。これを行うと、予期しない結果が発生し、プログラムがクラッシュしたりエラーが発生したりする可能性があるためです。
理解するのが非常に難しいので、詳細は説明しません。
どのように悪用されたのでしょうか?
再入攻撃がどのようにして資金の盗難につながり、Curve 攻撃で 7,000 万ドルの損失がもたらされたのかを説明しましょう。
まず、リエントランシー攻撃とは、悪意のあるコントラクトがスマート コントラクト内の関数を繰り返し呼び出す手法を指すことがわかっています。 Curve 攻撃では、この機能はプール内のユーザーの流動性を引き出すために使用されます。この関数には、金額を更新する前に十分なチェックが行われないという欠陥があります。
攻撃の具体的なプロセスを見てみましょう。
脆弱なスマートコントラクトに 10 イーサがあるとします。
攻撃者はデポジット関数を呼び出し、1 イーサリアムをデポジットします。
次に、攻撃者は引き出し関数を呼び出し、1 イーサリアムを引き出す準備をします。この関数では、攻撃者が自分のアカウントに 1 つのイーサリアムを持っているかどうかを確認します。
ただし、この機能は、攻撃者のアカウントに 1 イーサを送金する前に、契約の残高を更新しません。これは、コントラクトではまだ内部に 10 個のイーサがあると考えられていることを意味します。
攻撃者は再度出金関数(リエントリー)を呼び出し、再び1イーサリアムの出金準備をします。
コントラクトではまだ内部に 10 エーテルがあると考えられているため、攻撃者に 1 エーテルが再度転送されます。
このプロセスは、契約の流動性がなくなるまで繰り返されます。
このようにして、攻撃者は引き出し関数を繰り返し呼び出し、契約内のほぼすべての流動性を自分の口座に移し、契約内の資金を盗むことができます。
契約の金額はリアルタイムで更新されないため、この脆弱性は攻撃者にとって非常に有益であり、攻撃者は契約で引き出し可能な資金がなくなるまで攻撃を繰り返すことができます。 #Crv