
編集者注: この記事は以下から引用しましたPeckShield(ID:PeckShield)、許可を得てOdailyによって転載されました。
編集者注: この記事は以下から引用しました
PeckShieldのセキュリティ担当者はbZx攻撃を積極的に追跡調査し、このインシデントはDeFiプロジェクト間の共有および構成可能な流動性の設計に対する攻撃であることを発見しました特に、レバレッジ取引や融資機能を備えたDeFiプロジェクトでは、この問題が悪用されやすくなります。
Figure 1: Five Arbitrage Steps in bZx Hack
脆弱性に対する攻撃の詳細は以下のとおりです。
脆弱性に対する攻撃の詳細は以下のとおりです。
この攻撃イベントは北京時間 2020-02-15 09:38:57 に発生しました (ブロック高さ #9484688)。攻撃者の取引情報はetherscanで見つけることができます。この攻撃プロセスは次の 5 つのステップに分けることができます。
ステップ 1: フラッシュ ローンで利用可能な資金を入手する
Figure 2: Flashloan Borrowing From dYdX
画像の説明
最初のステップの後、現時点では、次の表にある攻撃者の資産には何のメリットもありません。
ステップ 2: WBTC スポットを貯め込む
Figure 3: WBTC Hoarding From Compound
画像の説明
このステップの後、攻撃者によって制御されている資産が変更されたことがわかりますが、この時点ではまだメリットはありません。
副題
bZxのレバレッジ取引機能を利用してETHをショートして大量のWBTCを購入します。具体的な手順は次のとおりです。攻撃者は 1,300 ETH をデポジットし、bZx レバレッジ取引関数、つまりインターフェイス mintWithEther() を呼び出します。この関数はインターフェイス marginTradeFromDeposit() を内部的に呼び出し続けます。次に、攻撃者は、bZx の 5 倍のレバレッジから得た 5,637.62 ETH を、KyberSwap を通じて 51.345576 WBTC に交換しました。ここでETHをショートすると5回借りたことになるので注意してください。この取引により、WETH/WBTC 為替レートは 109.8 に上昇し、通常の為替レート (約 38.5 WETH/WBTC) の約 3 倍となりました。
Figure 4: Margin Pumping With bZx (and Kyber + Uniswap)
この取引を完了するために、KyberSwap は基本的にその準備金を照会し、最良の為替レートを見つけます。最終的にそのような流動性を提供できるのは Uniswap だけであるため、この取引は実質的に Uniswap の WBTC 価格を 3 倍に押し上げます。
このステップではコントラクト内にセキュリティ チェック ロジックを実装しますが、実際にはトランザクション後のロック値は検証されないことに注意してください。つまり、攻撃が発生したとき、このチェックは有効になっていませんでした。この契約の問題については、後のセクションで詳しく説明します。
このステップの後、ハッカーが管理する資産に関して次のような変化が見られました。ただし、このステップを行っても利益は得られません。
画像の説明
Figure 5: WBTC Dumping With Uniswap
ステップ5: フラッシュローン返済
副題
ステップ5: フラッシュローン返済
このステップの後、次の資産の詳細を再計算しました。結果は、攻撃者がこの攻撃を通じて 71 ETH を取得し、さらにこれら 2 つのロックされたポジション、Compound (+5,500weth/-112WBTC) と bZx (-4,337WETH/+51WBTC) を取得したことを示しています。 bZx ロックアップはデフォルトで、Compound のロックアップは有益です。どうやら、攻撃後、攻撃者は抵当に入った5,500WETHを償還するために複合債務(112BTC)の返済を開始したようです。 bZx ロックアップはすでにデフォルトになっているため、攻撃者はもう興味を持ちません。
平均市場価格 1WBTC=38.5WETH (1WETH=0.025BTC) を参照すると、攻撃者が市場価格で 112 WBTC を購入すると、約 4,300 ETH のコストがかかります。 112 WBTC は Compond の負債を返済し、担保の 5,500 ETH を取り戻すために使用されるため、最終的な攻撃者の合計利益は 71 WETH +5,500 WETH -4,300 ETH=1,271 ETH、合計約 355,880 ドルになります (現在の ETH 価格は 280 ドル)。
副題
ハードコア分析: bZx は危険なコード ロジックの欠陥を回避できます
コントラクト内で攻撃者によって実装された前のステップから、問題の中心的な原因は、3 番目のステップで marginTradeFromDeposit() が呼び出され、1,300 ETH を借りて 5 倍のレバレッジを追加することで ETH/WBTC トランザクションをショートすることであることがわかります。 、そのため、契約コードをさらに確認すると、これは「回避可能な裁定取引の機会」であることがわかりましたが、コード内のロジック エラーにより、リスクを回避するために使用できるコード ロジックが有効になりませんでした。具体的なコード追跡は次のとおりです。
まず、marginTradeFromDeposit( ) が _borrowTokenAndUse( ) を呼び出しますが、ここでは預け入れた資産をレバレッジ取引に使用するため、4 番目のパラメーターは true になります (840 行目)。
_borrowTokenAndUse( ) で、amountIsADeposit が true の場合、_getBorrowAmountAndRate( ) を呼び出し、borrowAmount を sendAmounts[1] に格納します (1,348 行目)。
1,355 行目で、sentAmounts[6] が sendAmounts[1] に設定され、1,370 行目で _borrowTokenAndUseFinal() が呼び出されます。
IBZx インターフェース経由で bZxContract の takeOrderFromiToken( ) 関数に入ります。
bZxContract は別のコントラクト iTokens_loanopeningFunctions に属しています。 したがって、コントラクト コードの分析を続けて、関数内で重要な論理的判断を見つけます。
148 行目で、bZx は実際にオラクル コントラクトの shouldLiquidate() を使用して、このレバレッジ トランザクションのポジションが健全かどうかをチェックしようとします。ただし、最初の条件 (146 ~ 147 行目) がすでに true であるため、 shouldLiquidate() の論理判断を無視して実行が続行されます。