Back to Blog

Array Finance 安全事件分析

Code Auditing
July 19, 2021
6 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 函式。他存入了 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 函式。他銷毀了在前兩步中獲得的 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 的計算。在閱讀 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 代幣並將其轉移給 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) 在內的卓越投資者兩輪數千萬美元的融資。

官方網站: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