Back to Blog

アレイファイナンスのセキュリティインシデント分析

Code Auditing
July 19, 2021
5 min read

7月18日、当社のDeFiRangerシステムは、いくつかの不審なトランザクションを報告しました。手動分析の結果、これらのトランザクションがArray Financeへの攻撃であることを確認しました。以下では、攻撃トランザクションを使用して、攻撃プロセスと脆弱性の根本原因を説明します。

攻撃トランザクション

このブログで使用する攻撃トランザクションは以下の通りです。 0xa17bbc7c9ab17aa88fdb5de83b41de982845e9c9c072efff6709dd29febf0daa

攻撃フロー

Figure 1
Figure 1

図1に示すように、攻撃者はAAVEからフラッシュローンを借りることで186.62 WETH(このブログではWETHとETHを明確に区別していません)の利益を得たことがわかりました。

Figure 2
Figure 2

図2に詳細な攻撃プロセスを示します。

  • まず、攻撃者はArray Financeのbuy関数を呼び出しました。攻撃者は45.91 WETHを使用してArray Financeが発行した430 ARRAYトークンを取得しました。
  • 次に、攻撃者は非公開ソースのコントラクト(Array Collater - 0xa800cda5)のjoinPool関数を5回呼び出しました。676,410.58 DAI + 679,080.46 USDC + 901.82 WETH + 20 WBTC + 20 renBTCを預け入れ、Array Collaterが発行した726.38 aBPTトークンを取得しました。
  • 攻撃者はsell関数を呼び出して430 ARRAYトークンをバーンし、77.17 aBPTトークンを取得しました。
  • 最後に、攻撃者はArray CollaterのexitPool関数を呼び出しました。前の2つのステップで取得した804.55 aBPTトークンをバーンし、748,271.55 DAI + 751,225.08 USDC + 997.62 WETH + 22.63 WBTC + 22.74 renBTCを取得しました。

図2から、攻撃者はステップ5(図2: sell関数を呼び出す)で利益を得ていることがわかります。これは、取得した77.17 aBPTトークンがステップ3(図2: buy関数を呼び出す)で預け入れた49.9142 WETHよりも価値があったためです。以下で、この攻撃が発生した理由を理解するためにコードを分析します。

コードの脆弱性

以下のコードは、Array Financeのsell関数を示しています。この関数では、Array Financeは攻撃者が所有するARRAYトークンの残高を使用し、内部の_sell関数を呼び出して、ARRAYトークンを売却して取得できるaBPTトークンの数を計算します。

以下は_sell関数の実装です。これはcalculateLPtokensGivenArrayTokensを呼び出して、特定の数のARRAYトークンが与えられた場合に取得できるaBPTトークンの数を得ます。その後、この関数はARRAYトークンをバーンし、aBPTトークンを返します。

以下はcalculateLPtokensGivenArrayTokens関数の実装です。

amountLPTokenの計算に影響を与える4つの引数があることに注意してください。saleTargetAmountを読んだ後、以下の式を推測しました。

arraySmartPool.totalSupply() * (1 - (1 - amount / ARRAY.totalSupply()) ^ (1000000 / reseveRatio))

arraySmartPoolはArray Collater(0xa800cda5f3416a6fb64ef93d84d6298a685d190d)のスマートコントラクトアドレスです。攻撃者がフラッシュローンから借りた資金をArray Collaterに預け入れると、arraySmartPool.totalSupply()の値が増加します(以下の表を参照)。

TxnIndex: 64 arraySmartPool.totalSupply():  110162296218708026400
TxnIndex: 107 arraySmartPool.totalSupply():  165243444328062039600
TxnIndex: 150 arraySmartPool.totalSupply():  247865166492093059400
TxnIndex: 193 arraySmartPool.totalSupply():  371797749738139589100
TxnIndex: 236 arraySmartPool.totalSupply():  557696624607209383650
TxnIndex: 280 arraySmartPool.totalSupply():  836544936910814075475

arraySmartPoolのコードを読むことで、このロジックを確認できます。以下はarraySmartPoolのjoinPool関数です。

この関数は、まずSmartPoolManager.joinPool関数を呼び出して、msg.senderから取得する必要があるトークン数(actualAmountsIn)を計算します。その後、各トークンについて_pullUnderlying関数を呼び出してトークンをarraySmartPoolに預け入れます。最後に、_mintPoolShare_pushPoolShareを呼び出してaBPTトークンを発行し、発行されたaBPTトークンをmsg.senderに転送します。

arraySmartPoolはPCTokenから継承していることに注意してください。_mintPoolShare関数は_mint関数を呼び出しますが、これは以下のように示されています。

_mint関数はvarTotalSupply変数を増加させますが、これはtotalSupply()から直接返されます。したがって、この値はjoinPoolが呼び出されるたびに増加します。

利益見積もり

まとめ

要約すると、攻撃者はArray Financeの価格メカニズムが操作可能なaBPTトークンのtotalSupplyに依存しているという脆弱性を悪用しました。この脆弱性は、当社の研究論文DeFiRanger: Detecting Price Manipulation Attacks on DeFi Applicationsで議論されています。

謝辞

Junjie Fei、Yufeng Hu、Ziling Lin、Siwei Wu、Lei Wu、Yajin Zhou @BlockSec (姓のアルファベット順)

BlockSecについて

BlockSecは、世界的に著名なセキュリティ専門家グループによって2021年に設立された、先駆的なブロックチェーンセキュリティ企業です。同社は、新興のWeb3世界のためにセキュリティとユーザビリティを向上させ、その大量採用を促進することに尽力しています。この目的のために、BlockSecは、スマートコントラクトおよびEVMチェーンのセキュリティ監査サービス、セキュリティ開発とプロアクティブな脅威ブロックのためのPhalconプラットフォーム、資金追跡と調査のためのMetaSleuthプラットフォーム、そしてWeb3ビルダーが仮想通貨の世界を効率的にサーフィンするためのMetaDock拡張機能を提供しています。

現在までに、同社はMetaMask、Uniswap Foundation、Compound、Forta、PancakeSwapなど、300社以上の著名なクライアントにサービスを提供し、Matrix Partners、Vitalbridge Capital、Fenbushi Capitalなどの著名な投資家から2回の資金調達で数千万米ドルを受け取っています。

公式ウェブサイト:https://blocksec.com/ 公式Twitterアカウント:https://twitter.com/BlockSecTeam

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit