Array金融安全事件分析

深入剖析 Array Finance 漏洞:分步攻击分析 - 详细分解导致 Array Finance 被攻破的恶意交易,深入了解 DeFi 漏洞

Array金融安全事件分析

7月18日,我们的DeFiRanger系统报告了几笔可疑交易。经过人工分析,我们确认这些交易是针对Array Finance的攻击。接下来,我们将使用一笔攻击交易来说明攻击过程和漏洞的根本原因。

攻击交易

本文博客中使用的攻击交易是: 0xa17bbc7c9ab17aa88fdb5de83b41de982845e9c9c072efff6709dd29febf0daa

攻击流程

Figure 1

如图1所示,我们发现攻击者从AAVE借入闪电贷后,获利186.62 WETH(本文博客中我们不明确区分WETH和ETH)。

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的智能合约地址(0xa800cda5)。当攻击者将从闪电贷借入的资金存入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等顶尖投资者。

官方网站:https://blocksec.com/

官方Twitter账号:https://twitter.com/BlockSecTeam

Sign up for the latest updates