概要
概要
攻撃分析
2023 年 4 月 13 日、 Yearn Finance がハッキングされ、約 1,000 万ドルの損失が発生しました。この記事では、攻撃プロセスと脆弱性の原因を分析します。
https://etherscan.io/tx/0xd55e43c1602b28d4fd4667ee445d570c8f298f5401cf04e62ec329759ecda95d
攻撃分析
攻撃トランザクションは次のとおりです。
攻撃者は、Balancer からフラッシュ ローンを開始し、500 万 DAI、500 万 USDC、200 万 USDT を借り入れました。
次に、Curve 上で、攻撃者は 500 万 DAI を 695,000 USDT に、350 万 USDC を 151 USDT に交換しました。
攻撃者は、IEarnAPRWithPool の推奨関数を呼び出して、現在の APR を確認します。この時点で、Aave の APR だけが 0 に等しくありません。
次に、攻撃者は 800,000 USDT を攻撃コントラクト 0x9fcc1409b56cf235d9cdbbb86b6ad5089fa0eb0f に送金しました。このコントラクトでは、攻撃者は、Aave の APR が 0 になるように、他人の借金返済を支援するために、Aave: Lending Pool V1 の返済関数を数回呼び出しました。
攻撃者は yUSDT の預金関数を呼び出し、900,000 USDT を抵当にし、820,000 yUSDT を取得しました。
次に、攻撃者は bZx iUSDC の mint 関数を呼び出し、156,000 USDC を使用して 152,000 bZx iUSDC をミントし、それを Yearn yUSDT に転送しました。
攻撃者は Yearn:yUSDT のdraw関数を呼び出して、820,000 yUSDTを1,030,000 USDTに変換します。この時点で、攻撃者によって転送された bZx iUSDC のみがコントラクトに残ります。
次に、攻撃者は Yearn:yUSDT のリバランス関数を呼び出して、bZx iUSDC を破壊します。
次に、Curve 上で、攻撃者は 70,000 yUSDT を 5,990,000 yDAI に、4 億 yUSDT を 4,490,000 yUSDC に、1,240,133,244,352,200 yUSDT を 1,360,000 yTUSD に交換しました。
脆弱性分析
次に、yearn: yDAI と yearn: yUSDC でそれぞれdrawalnを呼び出し、678万DAIと562万USDCを引き出し、フラッシュローンを返します。
脆弱性分析
この攻撃の最も重要な点は、攻撃者が 1,252,660,242,850,000 yUSDT を鋳造するために 100,000 USDT を使用したことです。デポジット関数の実装を確認してください。
シェアの数は変数プールに関連しており、プールが小さいほどシェアは大きくなり、プールの値は _calcPoolValueInToken によって取得されることがわかります。
攻撃者が rebalance 関数を呼び出した後、コントラクトには USDC のみが存在しますが、_balance() は USDT の残高を取得し、USDC の残高は含まれていないため、この時点のプールは 1 (攻撃者によって転送) :
これは明らかにプロジェクト側の設定エラーです。yUSDT コントラクトはすべて USDT トークンである必要がありますが、その支点変数は USDC に関連する bZx IUSDC トークンであるため、yUSDT の USDC は残高に含まれていません。"newProvider != provider"なぜ攻撃者はリバランス関数を呼び出して bZx iUSDC トークンを書き込むことができるのでしょうか?リバランス関数の実装を確認してください。
_withdrawFulcrum() で引き換えと書き込みの操作があることがわかります。そのため、次のようにする必要があります。
が確立され、recommend() が実装されます。
攻撃者は、IIEarnManager(apr).recommend(token) の戻り値を 0 に制御することで newProvider を操作します。
全て0にするにはどうすればよいでしょうか? この関数の戻り値は各DeFiで計算されたAPRに関係します Compound、bZx、dydxにはプールがないのでAave(Aave: Lending Pool Core V1)を制御するだけで済みます:
値 0 を返すようにするには、apr.calculateInterestRates 関数の最初の戻り値が 0 である必要があります。
_totalBorrowsVariable は 0、つまり、Aave: レンディング プール コア V1 には現時点では負債がありません。この条件を達成するために、攻撃者はプール内の全員の負債を返済します。
要約する
Yearn 攻撃インシデントの根本原因は、プロジェクト関係者による構成エラーでした。攻撃者は一連の巧妙な方法でこの脆弱性を悪用し、最終的に約 1,000 万ドルの利益を得ました。
私たちについて
At Eocene Research, we provide the insights of intentions and security behind everything you know or don't know of blockchain, and empower every individual and organization to answer complex questions we hadn't even dreamed of back then.
