Em 30 de abril de 2022, um invasor explorou a mesma vulnerabilidade do Incidente Nerve Bridge para atacar o Saddle Finance. No total, 4.900 Ether foram atacados. Felizmente, 1.360 Ether foram salvos por nós com sucesso. A descrição detalhada deste incidente pode ser encontrada no post mortem oficial.


Embora a mesma vulnerabilidade tenha sido explorada, o método de ataque é diferente do anterior. Como o novo método de ataque não é tão simples quanto se poderia esperar, acreditamos que ele merece mais esforços para uma investigação aprofundada. Neste relatório, primeiro ilustramos brevemente a vulnerabilidade e, em seguida, revisamos o método de ataque original do Incidente Nerve Bridge. Depois disso, nos concentramos no Incidente Saddle Finance, dissecando o processo de ataque para desmistificar o novo método de ataque.
0x1. Sobre os Contratos Implantados
Os endereços de contrato relevantes estão listados a seguir:
- O contrato MetaSwap vítima: 0x824dcd7b044d60df2e89b1bb888e66d8bcf41491
- O contrato MetaSwapUtils vulnerável: 0x88Cc4aA0dd6Cf126b00C012dDa9f6F4fd9388b17
Vale ressaltar que o código exibido do contrato MetaSwapUtils associado ao contrato MetaSwap verificado NÃO é equivalente ao contrato MetaSwapUtils implantado, cujo endereço está especificado nas Configurações, conforme mostrado abaixo:

Portanto, não se confunda com esses dois contratos MetaSwapUtils :)
0x2. Análise da Vulnerabilidade
O contrato vulnerável pertence ao MetaPool, que foi discutido em detalhes no blog anterior. Em resumo, o MetaPool foi originalmente projetado pela Curve para permitir que uma única moeda seja agrupada com todas as moedas em outro pool (base) sem diluir sua liquidez. É essencialmente um pool composto por uma stable-coin e um token LP do pool base, que consiste em várias outras stable-coins. Existe uma preocupação com o design do MetaPool, ou seja, o MetaPool é basicamente um pool de stable-coins que mantém preços para stable-coins, enquanto o token LP de um pool base de stable-coins NÃO é uma stable-coin.
Na prática, o preço de um token LP de um pool base de stable-coins pode ser obtido invocando a função getVirtualPrice
do pool base, e seu preço aumenta de forma constante com o acúmulo de taxas
cobradas pelo pool base.
Para lidar com isso, o MetaPool escala a reserva do token LP antes de calcular o preço, conforme mostrado abaixo.

Consequentemente, se um usuário troca um token LP por uma stable-coin, a quantidade do token LP será escalada para cima antes do cálculo do preço. Alternativamente, se um usuário troca uma stable-coin por um token LP, a quantidade calculada do token LP será escalada para baixo antes da transferência e da contabilização.

O trecho de código acima da função swapUnderlying é usado para realizar trocas entre a stable-coin no MetaPool e as stable-coins no pool base. Conforme mostrado nos dois retângulos vermelhos,
a função escala para cima a quantidade de token LP recebido e escala para baixo a quantidade de token LP sendo trocada.
No entanto, a implementação da função swap é inconsistente com a da função swapUnderlying. Especificamente, a causa raiz da vulnerabilidade se deve ao cálculo falho implementado na função swap (ou seja, a função _calculateSwap) que não escala corretamente para baixo e para cima a quantidade do token LP. Conforme mostrado abaixo, o lado esquerdo apresenta o código vulnerável do MetaPool, enquanto o lado direito apresenta a versão corrigida.

O invasor do Incidente Nerve Bridge explorou a inconsistência entre a função swap e a função swapUnderlying.
(Observe que o Nerve Bridge é um projeto fork do Saddle Finance.)
Depois disso, o Saddle Finance corrigiu a vulnerabilidade e reimplantou imediatamente a nova versão (ou seja, V2) da biblioteca MetaSwapUtils.
Infelizmente, por algum motivo desconhecido, o sUSD V2 MetaPool na Ethereum ainda foi implantado com a biblioteca MetaSwapUtils antiga e vulnerável. Como resultado, essa vulnerabilidade foi explorada com sucesso por um invasor mais uma vez em 30 de abril. Curiosamente, ao contrário do método de ataque utilizado no Incidente Nerve Bridge, uma forma diferente foi adotada para atacar o MetaPool vulnerável.
0x3. O Método de Ataque Original do Incidente Nerve Bridge
Reutilizamos a figura abaixo (veja o blog anterior) para revisar o método de ataque original.

Como a função swap vulnerável não escala para baixo a quantidade do token LP (Nerve 3-LP) sendo trocada, a quantidade trocada (36.959) na Etapa 3 é maior do que o normal.
Em seguida, o invasor invoca a função swapUnderlying (sem vulnerabilidade) para vender os 36.959 Nerve 3-LP (nas Etapas 4 e 5)
por 51.494 fUSDT, obtendo um lucro de 1.143 fUSDT.
Razoavelmente, o lucro pode ser explicado da seguinte forma: o invasor obtém mais Nerve 3-LP na Etapa 3 e, em seguida, os vende a um preço "normal" aproveitando a inconsistência entre a função swap e a função swapUnderlying.
0x4. O Novo Método de Ataque do Incidente Saddle Finance
O invasor do recente Incidente Saddle Finance utilizou uma forma diferente para atacar
a mesma função swap vulnerável sem envolver a função swapUnderlying.
Aqui tomamos uma transação de ataque como exemplo concreto para ilustrar o processo.

Intuitivamente, parece que não deveria haver nenhum lucro, pois qualquer implicação das Etapas 3 e 4 seria neutralizada.
Especificamente, na Etapa 3, o invasor poderia obter mais saddleUSD devido à falta de escalonamento para baixo do token LP (ou seja, saddleUSD) sendo trocado.
No entanto, na Etapa 4, o invasor inevitavelmente obteria MENOS sUSD, porque a função swap vulnerável não escala para cima a quantidade de saddleUSD recebido antes de calcular o preço.
Porém, conforme mostrado na figura acima, o invasor lucrou 2.059.771 sUSD por meio do par de trocas nas Etapas 3 e 4. Para descobrir o motivo do lucro, precisamos mergulhar no mecanismo de precificação e realizar uma investigação aprofundada para entender o processo de ataque.
0x4.1 O Mecanismo de Precificação
O MetaPool do Saddle Finance herda a fórmula de precificação da Curve:

O gráfico da função (quando n é igual a 2) é mostrado como a curva azul na figura abaixo. (O design da fórmula pode ser encontrado no Whitepaper do Curve StableSwap.)

Surge então a questão: como o MetaPool calcula o preço para cada troca usando esta fórmula?
Digamos que n seja 2, e um usuário use dx0 de token0 para trocar dx1 de token1.
Podemos simular o processo de cálculo para dx1.
Em cada troca, A pode ser tratado como uma constante,
e D é a única variável que pode afetar a curva de preços. Na prática,
D aumenta com o acúmulo das taxas cobradas pelo pool.
Especificamente, o processo de cálculo pode ser resumido nas três etapas a seguir:
- Etapa I: Inserir as reservas atuais do pool (x0 e x1) na fórmula para calcular o
Datual, que determina a curva de preços atual. - Etapa II: Deixar x0 aumentar em dx0, e inserir o
Datual e x0 na fórmula para calcular o novo x1. - Etapa III: Então, dx1 é a diferença entre o novo x1 e o antigo x1.
Se token0 for o token LP de um pool base, então a Etapa II se torna:

Aqui baseVirtualPrice/1e18 é aproximadamente 1,0033 durante o ataque. Alternativamente, se o token for o token LP de um pool base, então a Etapa III se torna:

Para entender como D afeta a curva de preços, também usamos um exemplo para descrevê-lo.
Digamos que um usuário primeiro troca dx0 de token0 por dx1 de token1, e depois troca dx1 de token1 por dx0' de token0.

Conforme mostrado na figura acima, como a Etapa ② cobra taxas pela primeira troca, D aumenta para deslocar a curva de preços para cima (da curva preta para a azul).
Além disso, a figura descreve claramente o motivo pelo qual dx0' é menor que dx0'.
0x4.2 A Análise do Ataque
Para analisar o motivo do lucro, implantamos as bibliotecas MetaSwapUtils vulnerável e corrigida localmente e usamos o estado do pool vítima naquele momento para simular o ataque.
Além disso, durante esta simulação, também registramos alguns valores que podem ajudar a entender o processo de ataque, ou seja, A é 10.000, x_sUSD é 8.130.463, x_saddleUSD é 9.688.608,
e D é 17.818.392 naquele momento.

A figura acima descreve o processo do par de trocas lucrativo:
- Troca-I: troca de 14.800.272 sUSD por 9.657.586 saddleUSD
- Troca-II: troca de 9.657.586 saddleUSD por 16.860.043 sUSD
Especificamente, a Troca-I pode ser dividida nas duas etapas a seguir:
- ①: Troca de 14.800.272 sUSD por 9.625.654 saddleUSD. Agora,
Daumenta para 17.931.435 (devido às taxas cobradas). - ②: Como o MetaPool vulnerável não escala para baixo a quantidade de saddleUSD trocado, o pool perde 31.932 saddleUSD. As perdas diminuem
Dpara 15.736.195, o que desloca ainda mais a curva de preços para baixo (da curva preta para a cinza).
Da mesma forma, a Troca-II também pode ser dividida em duas etapas:
- ③: Como a curva de preços foi deslocada para baixo, os mesmos 9.625.654 saddleUSD podem obter 16.891.906 sUSD, muito mais do que o custo: 14.800.272 sUSD.
- ④: Como o MetaPool vulnerável não escala para cima a quantidade de saddleUSD recebido antes de calcular o preço, há 31.863 sUSD restantes no MetaPool, o que desloca a curva de preços para cima (da curva cinza para a azul). No entanto, o par de trocas ainda lucra 2.059.771 sUSD.
Obviamente, a análise acima elabora claramente por que o invasor conseguiu obter lucro usando o novo método de ataque. Além disso, parece que o método de ataque original é mais eficiente do que o novo, devido ao sUSD restante no MetaPool na Troca-II. É claro que o invasor poderia lançar múltiplos ataques para esvaziar o pool, o que foi observado na prática.
0x5. Conclusões
A investigação sugere que a causa raiz dos lucros nos dois incidentes é a mesma. Especificamente, a primeira troca (que troca pelo token LP) diminui o D do MetaPool vulnerável, o que desloca ainda mais sua curva de preços para baixo. Esse deslocamento afeta enormemente a precificação subsequente e é o principal motivo para o lucro subsequente.
Sobre a BlockSec
A BlockSec é uma empresa pioneira em segurança de blockchain, fundada em 2021 por um grupo de especialistas em segurança de renome mundial. A empresa está comprometida em melhorar 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 segurança de contratos inteligentes e chains EVM, a plataforma Phalcon para desenvolvimento de segurança e bloqueio proativo de ameaças, a plataforma MetaSleuth para rastreamento e investigação de fundos, e a extensão MetaDock para construtores Web3 que navegam 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 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



