O ataque de empréstimo relâmpago de 13 de março contra a Euler Finance resultou em mais de US$ 195 milhões em perdas. Ele causou um contágio que se espalhou por vários protocolos de finanças descentralizadas (DeFi), e pelo menos 11 protocolos além da Euler sofreram perdas devido ao ataque.
Nos 23 dias seguintes, e para grande alívio de muitos usuários do Euler, o invasor devolveu todos os fundos explorados.
Mas, embora a comunidade cripto possa comemorar o retorno dos fundos, permanece a questão se ataques semelhantes podem causar perdas enormes no futuro.
Pode ser útil analisar como o ataque aconteceu e se os desenvolvedores e usuários podem fazer algo para ajudar a prevenir esses tipos de ataques no futuro.
Felizmente, os documentos do desenvolvedor de Euler explicam claramente como o protocolo funciona, e o próprio blockchain preservou um registro completo do ataque.
Como funciona a Euler Finance
De acordo com os documentos oficiais do protocolo, Euler é uma plataforma de empréstimo similar ao Compound ou Aave. Usuários podem depositar cripto e permitir que o protocolo empreste para outros, ou podem usar um depósito como garantia para pegar cripto emprestado.
O valor da garantia de um usuário deve ser sempre maior do que o que ele toma emprestado. Suponha que a garantia de um usuário caia abaixo de uma proporção específica de valor da garantia para o valor da dívida. Nesse caso, a plataforma permitirá que eles sejam "liquidados", o que significa que sua garantia será vendida para pagar suas dívidas. A quantidade exata de garantia que um usuário precisa depende do ativo que está sendo depositado vs. o ativo que está sendo emprestado.
eTokens são ativos, enquanto dTokens são dívidas
Sempre que os usuários depositam na Euler, eles recebem eTokens representando as moedas depositadas. Por exemplo, se um usuário deposita 1.000 USD Coin (USDC), ele receberá a mesma quantia de eUSDC em troca.
Como eles se tornam mais valiosos do que as moedas subjacentes à medida que o depósito rende juros, os eTokens não têm uma correspondência 1:1 com o ativo subjacente em termos de valor.
Euler também permite que os usuários ganhem alavancagem ao cunhar eTokens. Mas se eles fizerem isso, o protocolo enviará a eles tokens de dívida (dTokens) para equilibrar os ativos criados.
Por exemplo, os documentos dizem que se um usuário depositar 1.000 USDC, ele pode cunhar 5.000 eUSDC. No entanto, se ele fizer isso, o protocolo também enviará a ele 5.000 de um token de dívida chamado “dUSDC”.
A função de transferência para um dToken é escrita de forma diferente de um token ERC-20 padrão. Se você possui um token de dívida, não pode transferi-lo para outra pessoa, mas qualquer um pode pegar um dToken de você se quiser.
De acordo com os documentos de Euler, um usuário só pode cunhar tantos eTokens quantos eles seriam capazes de depositar e pegar emprestado repetidamente, como afirma: "A função Mint imita o que aconteceria se um usuário depositasse $ 1.000 USDC, então pegasse emprestado $ 900 USDC, então redepositasse esses $ 900 USDC, para pegar emprestado mais $ 810 USDC, e assim por diante."
Usuários liquidados se as pontuações de saúde caírem para 1 ou menos
De acordo com uma postagem de blog de Euler, cada usuário tem uma “pontuação de saúde” com base no valor dos eTokens mantidos em suas carteiras versus o valor dos dTokens mantidos. Um usuário precisa ter um valor em dólar maior de eTokens do que de dTokens, mas quanto mais depende das moedas específicas que ele está pegando emprestado ou depositando. Independentemente disso, um usuário com eTokens suficientes terá uma pontuação de saúde maior que 1.
Se o usuário mal ficar abaixo do número necessário de eTokens, ele terá uma pontuação de saúde de precisamente 1. Isso o sujeitará à “liquidação suave”. Os bots liquidadores podem chamar uma função para transferir alguns dos eTokens e dTokens do usuário para si mesmos até que a pontuação de saúde do mutuário retorne a 1,25. Como um usuário que está mal abaixo dos requisitos de garantia ainda terá mais garantia do que dívida, o liquidador deve lucrar com essa transação.
Se a pontuação de saúde de um usuário cair abaixo de 1, então um desconto crescente é dado ao liquidador com base em quão ruim a pontuação de saúde é. Quanto pior a pontuação de saúde, maior o desconto para o liquidador. Isso tem a intenção de garantir que alguém sempre liquide uma conta antes que ela acumule muitas dívidas inadimplentes.
A postagem de Euler afirma que outros protocolos oferecem um “desconto fixo” para liquidação e argumenta por que ele acha que descontos variáveis são superiores.
Como aconteceu o ataque de Euler
Dados do blockchain revelam que o invasor se envolveu em uma série de ataques que drenaram vários tokens do protocolo. O primeiro ataque drenou cerca de US$ 8,9 milhões em Dai (DAI) do pool de depósito Dai. Em seguida, foi repetido várias vezes para outros pools de depósito até que o valor total fosse drenado.
O invasor usou três endereços Ethereum diferentes para executar o ataque. O primeiro foi um contrato inteligente, que o Etherscan rotulou como “Euler Exploit Contract 1”, usado para tomar emprestado do Aave. O segundo endereço foi usado para depositar e tomar emprestado do Euler, e o terceiro foi usado para executar uma liquidação.
Para evitar ter que declarar repetidamente os endereços que o Etherscan não rotulou, a segunda conta será chamada de “Mutuário” e a terceira conta de “Liquidatário”, conforme mostrado abaixo:
Endereços Ethereum usados pelo hacker. Fonte: Etherscan
O primeiro ataque consistiu em 20 transações no mesmo bloco.
Primeiro, o Euler Exploit Contract 1 tomou emprestado 30 milhões de DAI da Aave em um empréstimo rápido. Então, ele enviou esse empréstimo para a conta do mutuário.
Após receber os 30 milhões de DAI, o mutuário depositou 20 milhões deles para a Euler. A Euler então respondeu cunhando aproximadamente 19,6 milhões de eDAI e enviando-os para o mutuário.
Essas moedas eDAI eram um recibo do depósito, então uma quantia correspondente de dDai não foi cunhada no processo. E como cada eDAI pode ser resgatado por um pouco mais de um DAI, o tomador recebeu apenas 19,6 milhões em vez dos 20 milhões completos.
Após realizar esse depósito inicial, o mutuário cunhou aproximadamente 195,7 milhões de eDAI. Em resposta, Euler cunhou 200 milhões de dDAI e os enviou ao mutuário.
Neste ponto, o mutuário estava próximo do limite de cunhagem de eDAI, pois agora havia tomado emprestado cerca de 10 vezes a quantia de DAI que havia depositado. Então, o próximo passo foi pagar algumas das dívidas. Eles depositaram os outros 10 milhões de DAI que haviam mantido, efetivamente pagando US$ 10 milhões do empréstimo. Em resposta, Euler tirou 10 milhões de dDAI da carteira do mutuário e os queimou, reduzindo a dívida do mutuário em US$ 10 milhões.
O invasor então ficou livre para cunhar mais eDAI. O mutuário cunhou outros 195,7 milhões de eDAI, elevando seu total de eDAI cunhado para cerca de 391,4 milhões. Os 19,6 milhões de eDAI em recibos de depósito elevaram o total de eDAI do mutuário para cerca de 411 milhões.
Em resposta, Euler cunhou outros 200 milhões de dDai e os enviou ao mutuário, elevando a dívida total do mutuário para US$ 400 milhões.
Depois que o mutuário maximizou sua capacidade de cunhagem de eDAI, ele enviou 100 milhões de eDai para o endereço nulo, destruindo-o efetivamente.
Isso fez com que sua pontuação de saúde caísse bem abaixo de 1, já que agora eles tinham US$ 400 milhões em dívidas, contra aproximadamente US$ 320 milhões em ativos.
É aqui que entra a conta do liquidador. Ela é chamada de função de liquidação, inserindo o endereço do mutuário como a conta a ser liquidada.
Evento de liquidação emitido durante o ataque de Euler. Fonte: Dados do blockchain Ethereum
Em resposta, a Euler iniciou o processo de liquidação. Primeiro, ela pegou cerca de 254 milhões de dDAI do mutuário e os destruiu, depois cunhou 254 milhões de novos dDai e os transferiu para o liquidante. Essas duas etapas transferiram US$ 254 milhões em dívidas do mutuário para o liquidante.
Em seguida, Euler cunhou 5,08 milhões de dDAI adicionais e os enviou ao liquidador. Isso elevou a dívida do liquidador para US$ 260 milhões. Finalmente, Euler transferiu aproximadamente 310,9 milhões de eDAI do mutuário para o liquidador, completando o processo de liquidação.
No final, o mutuário ficou sem eDAI, sem DAI e 146 milhões de dDAI. Isso significava que a conta não tinha ativos e US$ 146 milhões em dívidas.
Por outro lado, o liquidatário tinha aproximadamente 310,9 milhões de eDAI e apenas 260 milhões de dDAI.
Uma vez que a liquidação foi concluída, o liquidatário resgatou 38 milhões de eDAI ($ 38,9 milhões), recebendo 38,9 milhões de DAI em troca. Eles então devolveram 30 milhões de DAI mais juros para o Euler Exploiter Contract 1, que o contrato usou para pagar o empréstimo da Aave.
No final, o liquidador ficou com aproximadamente US$ 8,9 milhões em lucro que havia sido explorado de outros usuários do protocolo.
Este ataque foi repetido para vários outros tokens, incluindo Wrapped Bitcoin (WBTC), Staked Ether (stETH) e USDC, totalizando US$ 197 milhões em criptomoedas exploradas.
Perdas do ataque de Euler. Fonte: Blocksec O que deu errado no ataque de Euler
As empresas de segurança de blockchain Omniscia e SlowMist analisaram o ataque para tentar determinar o que poderia tê-lo evitado.
De acordo com um relatório de 13 de março da Omniscia, o principal problema com o Euler era sua função “donateToReserves”. Essa função permitia que o invasor doasse seu eDAI para as reservas do Euler, removendo ativos de sua carteira sem remover uma quantia correspondente de dívida. A Omnisica diz que essa função não estava na versão original do Euler, mas foi introduzida na Proposta de Melhoria do Euler 14 (eIP-14).
O código para eIP-14 revela que ele criou uma função chamada donateToReserves, que permite ao usuário transferir tokens de seu próprio saldo para uma variável de protocolo chamada “assetStorage.reserveBalance”. Sempre que essa função é chamada, o contrato emite um evento “RequestDonate” que fornece informações sobre a transação.
Dados do blockchain mostram que esse evento RequestDonate foi emitido para um valor de 100 milhões de tokens. Essa é a quantia exata que o Etherscan mostra que foi queimada, levando a conta à insolvência.
Evento RequestDonate de Euler sendo emitido durante o ataque. Fonte: dados do blockchain Ethereum
Em sua análise de 15 de março, a SlowMist concordou com a Omniscia sobre a importância da função donateToReserve, afirmando:
“A falha em verificar se o usuário estava em estado de liquidação após doar fundos para o endereço de reserva resultou no acionamento direto do mecanismo de liquidação suave.”
O invasor também poderia ter sido capaz de realizar o ataque mesmo se a função de doação não existisse. O código do contrato Euler “EToken.sol” no GitHub contém uma função de “transferência” ERC-20 padrão. Isso parece implicar que o invasor poderia ter transferido seus eTokens para outro usuário aleatório ou para o endereço nulo em vez de doar, levando-se à insolvência de qualquer maneira.
Função de transferência de contrato Euler eToken. Fonte: GitHub
No entanto, o invasor optou por doar os fundos em vez de transferi-los, o que sugere que a transferência não teria funcionado.
A Cointelegraph entrou em contato com a Omniscia, a SlowMist e a equipe da Euler para esclarecimentos sobre se a função donateToReserves foi essencial para o ataque. No entanto, não recebeu uma resposta até o momento da publicação.
As duas empresas concordaram que outra grande vulnerabilidade na Euler eram os grandes descontos oferecidos aos liquidatários. De acordo com a SlowMist, quando um protocolo de empréstimo tem um “mecanismo de liquidação que atualiza descontos dinamicamente”, ele “cria oportunidades lucrativas de arbitragem para os invasores desviarem uma grande quantidade de garantia sem a necessidade de garantia ou pagamento de dívida”. A Omniscia fez observações semelhantes, afirmando:
“Quando o infrator se liquida, um desconto percentual é aplicado [...] garantindo que ele estará ‘acima da água’ e incorrerá apenas na dívida que corresponde à garantia que ele adquirirá.”
Como prevenir um futuro ataque de Euler
Em sua análise, a SlowMist aconselhou os desenvolvedores sobre como evitar outro ataque do tipo Euler no futuro. Ela argumentou que os protocolos de empréstimo não devem permitir que os usuários queimem ativos se isso os fizer criar dívidas ruins, e alegou que os desenvolvedores devem ter cuidado ao usar vários módulos que podem interagir uns com os outros de maneiras inesperadas:
“A SlowMist Security Team recomenda que os protocolos de empréstimo incorporem verificações de saúde necessárias em funções que envolvam fundos de usuários, ao mesmo tempo em que consideram os riscos de segurança que podem surgir da combinação de diferentes módulos. Isso permitirá o design de modelos econômicos e viáveis seguros que efetivamente mitiguem tais ataques no futuro.”
Um representante do desenvolvedor DeFi Spool disse ao Cointelegraph que o risco tecnológico é uma característica intrínseca do ecossistema DeFi. Embora não possa ser eliminado, pode ser mitigado por meio de modelos que classifiquem adequadamente os riscos dos protocolos.
De acordo com o white paper de gerenciamento de risco do Spool, ele usa uma “matriz de risco” para determinar o risco dos protocolos. Esta matriz considera fatores como o rendimento percentual anual (APY) do protocolo, auditorias realizadas em seus contratos, tempo desde sua implantação, valor total bloqueado (TVL) e outros para criar uma classificação de risco. Os usuários do Spool podem empregar esta matriz para diversificar os investimentos em DeFi e limitar os riscos.
O representante disse ao Cointelegraph que a matriz de Spool reduziu significativamente as perdas dos investidores no incidente de Euler.
“Neste incidente, os Smart Vaults mais afetados, aqueles projetados por usuários para buscar rendimentos mais altos (e mais arriscados), foram afetados apenas em até 35%. O vault menos afetado com exposição a estratégias de Euler (via Harvest ou Idle), em comparação, foi afetado apenas em 6%. Alguns vaults tiveram exposição zero e, portanto, não foram impactados”, eles declararam.
Spool continuou: “Embora isso não seja o ideal, demonstra claramente a capacidade dos Smart Vaults de fornecer modelos de risco personalizados e distribuir os fundos dos usuários entre várias fontes de rendimento.”
O Cointelegraph obteve uma resposta semelhante do SwissBorg, outro protocolo DeFi que visa ajudar os usuários a limitar o risco por meio da diversificação. O CEO do SwissBorg, Cyrus Fazel, declarou que o aplicativo SwissBorg tem “estratégias de rendimento diferentes com base em risco/timeAPY”.
Algumas estratégias são listadas como “1: core = low”, enquanto outras são listadas como “2: adventurer = risky”. Como Euler recebeu uma classificação “2”, as perdas do protocolo foram limitadas a apenas uma pequena parte do valor total bloqueado do SwissBorg, afirmou Fazel.
O chefe de engenharia da SwissBorg, Nicolas Rémond, esclareceu ainda que a equipe emprega critérios sofisticados para determinar quais protocolos podem ser listados no aplicativo SwissBorg.
“Temos um processo de due diligence para todas as plataformas DeFi antes de entrar em qualquer posição. E então, uma vez que estamos lá, temos procedimentos de operação”, ele disse, acrescentando, “A due diligence é toda sobre TVL, equipe, auditorias, código de fonte aberta, TVL, ataque de manipulação de oráculo, etc. […] O procedimento de operação é sobre monitoramento de plataforma, monitoramento de mídia social e algumas medidas de emergência. Algumas ainda são manuais, mas estamos investindo para automatizar tudo com base para que possamos ser extremamente reativos.”
Em um tópico do Twitter em 13 de março, a equipe da SwissBorg declarou que, embora o protocolo tenha perdido 2,2% dos fundos de um pool e 29,52% de outro, todos os usuários seriam compensados pela SwissBorg caso os fundos não pudessem ser recuperados da Euler.
O ataque de Euler foi o pior exploit DeFi do Q1 de 2023. Felizmente, o invasor devolveu a maior parte dos fundos, e a maioria dos usuários deve acabar sem perdas quando tudo estiver dito e feito. Mas o ataque levanta questões sobre como desenvolvedores e usuários podem limitar o risco à medida que o ecossistema DeFi continua a se expandir.
Alguma combinação de diligência do desenvolvedor e diversificação do investidor pode ser a solução para o problema. Mas, independentemente disso, o hack de Euler pode continuar a ser discutido no futuro, se não por outra razão que não seu tamanho e ilustração dos riscos de exploits DeFi.
