Back to Blog

A Análise do Incidente de Segurança do Array Finance

Code Auditing
19 de julho de 2021
5 min read

Em 18 de julho, nosso sistema DeFiRanger reportou algumas transações suspeitas. Após análise manual, confirmamos que essas transações são ataques à Array Finance. A seguir, usaremos uma transação de ataque para ilustrar o processo de ataque e a causa raiz da vulnerabilidade.

Transação de Ataque

A transação de ataque utilizada neste blog é: 0xa17bbc7c9ab17aa88fdb5de83b41de982845e9c9c072efff6709dd29febf0daa

Fluxo do Ataque

Figura 1
Figura 1

Conforme mostrado na Figura 1, descobrimos que o atacante obteve um lucro de 186,62 WETH (não distinguimos explicitamente entre WETH e ETH neste blog) após tomar emprestado o flash loan da AAVE.

Figura 2
Figura 2

O processo detalhado do ataque é mostrado na Figura 2.

  • Primeiro, o atacante invocou a função buy da Array Finance. O atacante obteve 430 tokens ARRAY cunhados pela Array Finance usando 45,91 WETH.
  • Em seguida, o atacante invocou a função joinPool de um contrato de código fechado (Array Collater - 0xa800cda5) cinco vezes. Ele/ela depositou 676.410,58 DAI + 679.080,46 USDC + 901,82 WETH + 20 WBTC + 20 renBTC e obteve 726,38 tokens aBPT cunhados pelo Array Collater.
  • O atacante invocou a função sell para queimar 430 tokens ARRAY e obteve 77,17 tokens aBPT.
  • Por fim, o atacante invocou a função exitPool do Array Collater. Ele/ela queimou 804,55 tokens aBPT obtidos nas duas etapas anteriores e obteve 748.271,55 DAI + 751.225,08 USDC + 997,62 WETH + 22,63 WBTC + 22,74 renBTC.

Pela Figura 2, podemos ver que o atacante obtém lucros na etapa 5 (Figura 2: Invocar a função sell). Isso ocorre porque os 77,17 tokens aBPT obtidos são mais valiosos do que os 49,9142 WETH depositados na etapa 3 (Figura 2: Invocar a função buy). A seguir, analisaremos o código para entender por que esse ataque pode acontecer.

Vulnerabilidade no Código

O código a seguir mostra a função sell da Array Finance. Nesta função, a Array Finance usa o saldo do token ARRAY de propriedade do atacante e invoca a função interna _sell para calcular o número de tokens aBPT que podem ser obtidos ao vender o token ARRAY.

A seguir está a implementação da função _sell. Ela invoca a calculateLPtokensGivenArrayTokens para obter o número de tokens aBPT que podem ser ganhos dado um certo número de tokens ARRAY. Em seguida, essa função queima o token ARRAY e retorna o token aBPT.

A seguir está a implementação da função calculateLPtokensGivenArrayTokens.

Observe que há quatro argumentos que podem afetar o cálculo de amountLPToken. Após ler o saleTargetAmount, inferimos que a fórmula é a seguinte:

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

O arraySmartPool é o endereço do contrato inteligente do Array Collater (0xa800cda5f3416a6fb64ef93d84d6298a685d190d). O valor de arraySmartPool.totalSupply() aumentará quando o atacante depositar fundos emprestados do flash loan no Array Collater (mostrado na tabela a seguir).

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

Podemos confirmar essa lógica após ler o código do arraySmartPool. A seguir está a função joinPool do arraySmartPool.

Essa função primeiro invoca a função SmartPoolManager.joinPool para calcular o número de tokens (actualAmountsIn) que precisam ser obtidos do msg.sender. Em seguida, para cada token, ela invoca a função _pullUnderlying para depositar o token no arraySmartPool. Por fim, ela invoca o _mintPoolShare e o _pushPoolShare para cunhar o token aBPT e transferir o token aBPT cunhado para o msg.sender.

Observe que o arraySmartPool herda do PCToken. A função _mintPoolShare invoca a função _mint, que é mostrada a seguir.

A função _mint aumentará a variável varTotalSupply, que é retornada diretamente pelo totalSupply(). Portanto, esse valor é incrementado a cada invocação do joinPool.

Estimativa de Lucro

Resumo

Em resumo, o atacante explora a vulnerabilidade de que o mecanismo de preço da Array Finance depende do totalSupply do token aBPT, que é manipulável. A vulnerabilidade foi discutida em nosso artigo de pesquisa DeFiRanger: Detecting Price Manipulation Attacks on DeFi Applications.

Créditos

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

(Em ordem alfabética pelo sobrenome)

Sobre a BlockSec

A BlockSec é uma empresa pioneira em segurança blockchain estabelecida em 2021 por um grupo de especialistas em segurança de renome mundial. A empresa está comprometida em aprimorar a segurança e a usabilidade para o emergente mundo Web3, a fim de facilitar sua adoção em massa. Para isso, a BlockSec oferece serviços de auditoria de contratos inteligentes e segurança de redes EVM, a plataforma Phalcon para desenvolvimento seguro e bloqueio proativo de ameaças, a plataforma MetaSleuth para rastreamento e investigação de fundos, e a extensão MetaDock para construtores web3 navegando com eficiência no mundo cripto.

Até o momento, a empresa atendeu mais de 300 clientes renomados, como MetaMask, Uniswap Foundation, Compound, Forta e PancakeSwap, e recebeu dezenas de milhões de dólares americanos em duas rodadas de financiamento de investidores proeminentes, incluindo Matrix Partners, Vitalbridge Capital e Fenbushi Capital.

Site oficial: https://blocksec.com/

Conta oficial no Twitter: https://twitter.com/BlockSecTeam

Sign up for the latest updates
Perdas de ~5,57 milhões USD: exploração de falhas no X100 Freezer e no NEM | Boletim semanal da BlockSec
Security Insights

Perdas de ~5,57 milhões USD: exploração de falhas no X100 Freezer e no NEM | Boletim semanal da BlockSec

Este relatório semanal aborda dois incidentes de segurança na Ethereum e na BNB Chain no período de 19/10/2026–25/10/2026. Ele examina uma tomada de controle da governança do X100 Freezer financiada por um empréstimo-relâmpago e uma falha na liquidação de impostos que afetou um pool de liquidez de um token NEM na BNB Chain. As perdas estimadas no escopo do relatório totalizam aproximadamente 5,57 milhões USD: cerca de 4,75 milhões USD da transação representativa do X100 e cerca de 820 mil USD do incidente no pool do NEM. O total exclui as extrações subsequentes do X100 relatadas separadamente.

Perdas de ~3,87 milhões USD: ataques à Autheo Network e à UNCX | Resumo semanal da BlockSec
Security Insights

Perdas de ~3,87 milhões USD: ataques à Autheo Network e à UNCX | Resumo semanal da BlockSec

Este relatório semanal aborda 3 incidentes de segurança no período de 12/10/2026–18/10/2026, com perdas totais estimadas em aproximadamente 3,87 milhões USD. A Autheo Network sofreu um comprometimento de chave privada com perdas de cerca de 1,76 milhões USD, a Qubic Wallet perdeu cerca de 1,30 milhões USD devido à geração de seeds fracas, e os contratos Smart Token Vesting V2 da UNCX Network sofreram um erro contábil de cerca de 807 mil USD nas redes Ethereum, BNB Chain, Base e Robinhood Chain. A análise em destaque da UNCX explica como um cálculo incorreto do total de cotas misturou parcelas de vesting criadas com diferentes proporções entre tokens e cotas, permitindo saques acima do devido de pools compartilhados.

~US$ 542 mil perdidos: ataque ao MakerDaoBot | Boletim semanal da BlockSec
Security Insights

~US$ 542 mil perdidos: ataque ao MakerDaoBot | Boletim semanal da BlockSec

O relatório cobre 1 incidente no Ethereum (05–11/10/2026), com perda estimada de US$ 542 mil. Um adaptador malicioso obteve acesso aos saldos MakerDAO via função desprotegida do MakerDaoBot, liquidou 4 leilões ETH-A e converteu 200 ETH-A em WETH, depois enviados como ETH ao atacante.

Best Security Auditor for Web3

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

BlockSec Audit