Back to Blog

The Analysis of the Array Finance Security Incident

Code Auditing
July 19, 2021
5 min read

On July 18th, our DeFiRanger system reported a couple of suspicious transactions. After manual analysis, we confirm that these transactions are attacks to Array Finance. In the following, we will use an attack transaction to illustrate the attack process and the root cause of the vulnerability.

Attack Transaction

The attack transaction used in this blog is: 0xa17bbc7c9ab17aa88fdb5de83b41de982845e9c9c072efff6709dd29febf0daa

Attack Flow

Figure 1
Figure 1

As shown in Figure 1, we found that the attacker gained a profit of 186.62 WETH (we do not explicitly distinguish between WETH and ETH in this blog.) after borrowing the flash loan from AAVE.

Figure 2
Figure 2

The detailed attack process is shown in Figure 2.

  • First, the attacker invoked the buy function of the Array Finance. The attacker gained 430 ARRAY tokens minted by the Array Finance using 45.91 WETH.
  • Then the attacker invoked the joinPool function of a closed source contract (Array Collater - 0xa800cda5) five times. He/she deposited 676,410.58 DAI + 679,080.46 USDC + 901.82 WETH + 20 WBTC + 20 renBTC and gained 726.38 aBPT tokens minted by Array Collater.
  • The attacker invoked the sell function to burn 430 ARRAY tokens and got 77.17 aBPT tokens.
  • At last, the attacker invoked the exitPool function of the Array Collater. He/she burned 804.55 aBPT tokens obtained in previous two steps and obtained 748,271.55 DAI + 751,225.08 USDC + 997.62 WETH + 22.63 WBTC + 22.74 renBTC.

From Figure 2, we can find the attacker gains profits in step 5 (Figure 2: Invoke the sell function). That's because the obtained 77.17 aBPT tokens are more valuable than the 49.9142 WETH deposited in step 3 (Figure 2: Invoke the buy function). In the following, we will analyze the code to understand why this attack can happen.

Code Vulnerability

The following code shows the sell function of Array Finance. In this function, Array Finance uses the balance of the ARRAY token owned by the attacker and invokes the internal _sell function to calculate the number of aBPT tokens that can be obtained by selling the ARRAY token.

The following is the implementation of the _sell function. It invokes the calculateLPtokensGivenArrayTokens to get the number of aBPT tokens that can be gained given a certain number of ARRAY tokens. Then this function burns ARRAY token and returns the aBPT token.

The following shows the implementation of the calculateLPtokensGivenArrayTokens function.

Note that, there are four arguments that can affect the calculation of amountLPToken. After reading the saleTargetAmount, we infer the formula is as following:

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

The arraySmartPool is the smart contract address of the Array Collater (0xa800cda5f3416a6fb64ef93d84d6298a685d190d). The value of arraySmartPool.totalSupply() will increase when the attacker deposits fundings borrowed from the flash loan into the Array Collater (shown in the following table).

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

We can confirm this logic after reading the code of the arraySmartPool. The following shows the joinPool function of the arraySmartPool.

This function first invokes the SmartPoolManager.joinPool function to calculate the number of tokens (actualAmountsIn) that need to be obtained from the msg.sender. Then for each token, it invokes the _pullUnderlying function to deposit the token to arraySmartPool. At last, it invokes the _mintPoolShare and _pushPoolShare to mint aBPT token and transfer the minted aBPT token to msg.sender.

Note that the arraySmartPool inherits from the PCToken. The _mintPoolShare function invokes the _mint function, which is shown in the following.

The _mint function will increase the varTotalSupply variable, which is directly returned by the totalSupply(). Thus, this value is increased for each invocation of the joinPool.

Profit Estimation

Summary

In summary, the attacker exploits the vulnerability that the price mechanism of the Array Finance depends on the totalSupply of the aBPT token, which is manipulatable. The vulnerability has been discussed in our research paper DeFiRanger: Detecting Price Manipulation Attacks on DeFi Applications.

Credits

Junjie Fei, Yufeng Hu, Ziling Lin, Siwei Wu, Lei Wu, Yajin Zhou @BlockSec

(In alphabetical order by the last name)

About BlockSec

BlockSec is a pioneering blockchain security company established in 2021 by a group of globally distinguished security experts. The company is committed to enhancing security and usability for the emerging Web3 world in order to facilitate its mass adoption. To this end, BlockSec provides smart contract and EVM chain security auditing services, the Phalcon platform for security development and blocking threats proactively, the MetaSleuth platform for fund tracking and investigation, and MetaDock extension for web3 builders surfing efficiently in the crypto world.

To date, the company has served over 300 esteemed clients such as MetaMask, Uniswap Foundation, Compound, Forta, and PancakeSwap, and received tens of millions of US dollars in two rounds of financing from preeminent investors, including Matrix Partners, Vitalbridge Capital, and Fenbushi Capital.

Official website: https://blocksec.com/

Official Twitter account: https://twitter.com/BlockSecTeam

Sign up for the latest updates
~$542K Lost: MakerDaoBot Exploit | BlockSec Weekly
Security Insights

~$542K Lost: MakerDaoBot Exploit | BlockSec Weekly

This report covers 1 security incident on Ethereum from 2026/10/05 - 2026/10/11, with an estimated loss of approximately $542K. An attack contract deployed a malicious adapter and passed it to a MakerDaoBot function that lacked access control, causing the bot to grant the adapter permission over its internal MakerDAO balances. The adapter settled four legacy ETH-A auctions and converted 200 units of ETH-A collateral to WETH; the attack contract unwrapped it and sent 200 ETH to the attacker.

~$418M Lost: Bitget, NEAR Intents Exploits | BlockSec Weekly
Security Insights

~$418M Lost: Bitget, NEAR Intents Exploits | BlockSec Weekly

This biweekly security report records eight incidents from September 21 to October 4, 2026, with approximately $418.4M in losses across Ethereum, BNB Chain, Solana, Bitcoin, TRON, XRP Ledger, Zcash, Avalanche, NEAR, and related networks. Detailed analysis covers Bitget's $387.5M third-party security product vulnerability and NEAR Intents' $3.87M refund validation flaw and missing state rollback.

Bitget's $387.5M Off-Chain Breach: Beyond Keys and Contracts
Security Insights

Bitget's $387.5M Off-Chain Breach: Beyond Keys and Contracts

On September 24, 2026, attackers exploited a vulnerability in a third-party security product, obtained internal credentials, and forged withdrawal commands. The resulting transfers moved approximately $387.5M from some of Bitget's operational wallets across Ethereum, other EVM networks, XRP Ledger, Zcash, and TRON; private keys and cold wallets remained intact. This deep dive summarizes the disclosed incident path and fund flow, examines rapid conversion into native assets and the ecosystem recovery response, proposes a systematic defense-in-depth framework for institutions, and explains how authorized blockchain penetration testing can validate cross-layer assumptions.

Best Security Auditor for Web3

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

BlockSec Audit