Visão geral:
Em 11 de novembro de 2022, ocorreu um ataque de reentrância, que resultou na drenagem de um total de ~$ 7,5 milhões dos pools de liquidez da DFX Finance na rede Polygon. O invasor só conseguiu transferir US $4,3 milhões em ativos para sua carteira. A parte restante – cerca de US $3,2 milhões – foi extraída por um bot MEV (bot de Valor Extraível Máximo) em uma transação de front-running, também chamada de ataque sanduíche.
Visão geral do hack de contrato inteligente:
- Endereço do invasor: 0x14c1
- Código da DFX Finance: 0x8888
- Endereço e transação do Bot MEV: 0x6c6b
- Endereço da carteira do Bot MEV: 0xfde
- Bloco de transação de pedido não convencional: 15941904
- Bot MEV e análise do endereço de transação da carteira: 0xfde0d
Link do código do GitHub:
- https://github.com/dfx-finance/protocol-v1-deprecated/blob/main/contracts/Curve.sol#L583
- https://github.com/dfx-finance/protocol-v2/blob/main/src/Curve.sol
Decodificando a vulnerabilidade do contrato inteligente:
Série de transações conectadas à carteira e Bot MEV
- O invasor primeiro chamou a função
viewDeposit
do contrato do par “usdc-xidr
”, que aceita lptoken (tokens de pools de liquidez) como uma entrada e retorna um array de quantos tokensusdc e xidr
são necessários. Esta função também gera bastantelptokens
. - O invasor pegou emprestado
USDC
eXIDR
suficientes ao invocar a função flash da DFX, porque o mesmo projeto incluía um código flash() para empréstimos relâmpagos. Link para o código — https://github.com/dfx-finance/protocol-v2/blob/90e5ae656f64ecf13e13b03b1cb7fb1d79e09f5b/src/Curve.sol#L645
Vulnerabilidade de contrato inteligente do DFX Finance
- O USDC e o XIDR emprestados foram então redepositados no contrato do par de transações pelos assaltantes usando o método deposit (). Link para o código — https://github.com/dfx-finance/protocol-v1-deprecated/blob/5fbeac837e57ded52e25572390a90c189ef363b1/contracts/Curve.sol#L489
- A função de depósito chamou a função
ProportionalLiquidity.proportionalDeposit()
, que registrou o token LP do invasor e depositou os fundos emprestados do invasor no contrato do par de transações. https://github.com/dfx-finance/protocol-v2/blob/90e5ae656f64ecf13e13b03b1cb7fb1d79e09f5b/src/Curve.sol#L659
- Como não havia quantia pendente no endereço do invasor, as transações satisfizeram a validação quando o saldo do contrato do par de transações foi verificado, ignorando a necessidade de verificações do par de transações para pagar o empréstimo relâmpago. Link
- O método
flashCallback()
nesse caso, permitiu que o invasor retirasse todas as reservas de tokens USDC e XIDR do contrato e executasse uma lógica arbitrária sem custo inicial para concluir a transação de empréstimo relâmpago. Como o total de token emprestado do empréstimo relâmpago agora se tornou zero, o lptoken depositado pelo invasor permaneceu no saldo do contrato. - Para finalizar o ataque, o atacante executou a função withdraw (), (saque), destruiu o lptoken e pegou os tokens
usdc
exidr
. https://github.com/dfx-finance/protocol-v1-deprecated/blob/5fbeac837e57ded52e25572390a90c189ef363b1/contracts/Curve.sol#L516
A função de withdraw() tinha um modificador de proteção de reentrância que não podia ser acionado desde que o empréstimo relâmpago fosse concluído, mas os lptokens depositados pelo invasor ainda existiam no contrato de empréstimo, que na verdade pertencia ao invasor, permitindo assim que um invasor chamasse a função EmergencyWithdraw() quantas vezes quisesse até retirar todos os tokens depositados.
Devido à ativação dos bots MEV, o invasor perdeu uma quantia significativa de dinheiro para o proprietário desses bots e só conseguiu recuperar cerca de US $4 milhões em dinheiro roubado.
Melhores práticas de mitigação:
- O estado do contrato deve ter um bloqueio booleano chamado mutex (sinalizador mutuamente exclusivo). “Locked” é falso em seu estado inicial. Mas antes que a função vulnerável seja chamada, ela muda para true (verdadeira), e depois que termina, ela retorna para false (falsa).
- Use modificações de funções preventivas de reentrância, como o Re-entrance Guard da Open Zeppelin.
- Sempre certifique-se de que quaisquer alterações de estado ocorram internamente primeiro, como atualizar saldos ou chamar funções internas antes de chamar o código externo.
- Use o padrão verificação-efeito-interação.
- Examine seu contrato contra as mais comuns e recentes vulnerabilidades de segurança com mais de 130 padrões no SolidityScan, que inclui a detecção de vulnerabilidades de reentrância.
SolidityScan — Ferramenta de verificação de segurança de contrato inteligente
Conclusão:
O SolidityScan é uma ferramenta avançada de verificação de contratos inteligentes que descobre vulnerabilidades e reduz os riscos no código. Solicite uma auditoria de segurança conosco e ajudaremos você a proteger seus contratos inteligentes. Inscreva-se para uma avaliação gratuita em https://solidityscan.com/signup
Artigo escrito por Shashank e traduzido por Marcelo Panegali
Top comments (0)