Back to Blog

~US$ 11,3M perdidos: Multicall Router, Nostra | BlockSec Weekly

Code Auditing
24 de setembro de 2026
12 min read
Key Insights
  • Este relatório cobre 2 incidentes de segurança totalizando aproximadamente US$ 11,3 milhões em perdas, entre Ethereum e Starknet. Ambos os valores são estimativas feitas no momento do incidente, e a Nostra Finance declarou que sua perda final e as recuperações ainda eram desconhecidas.

  • Em ambos os casos, a verificação de autorização ou avaliação de valor foi executada e retornou sucesso, mas avaliou a entrada errada. Um roteador aceitou uma identidade introduzida por sua própria chamada aninhada em vez do chamador externo original, e um mercado monetário aceitou um preço agregado sustentado por poucas fontes independentes.

  • Nenhum dos incidentes exigiu um defeito em um protocolo conhecido. As falhas estavam no código de integração personalizado anexado a componentes já estabelecidos, uma pilha de módulos Safe em um caso e uma configuração de adaptador de oráculo no outro.

Durante a semana passada (14/09/2026 - 20/09/2026), observamos 2 incidentes de segurança com uma perda total estimada de aproximadamente $11.3M.

Data Incidente Tipo Perda Estimada
2026/09/15 Unknown Multicall Router Controle de Acesso Inadequado ~$7.8M
2026/09/17 Nostra Finance Configuração Falha de Oráculo ~$3.5M

Verificação de Segurança Gratuita

Uma verificação de segurança rápida com nosso mecanismo de análise automatizada interno.

Verificar gratuitamente

Destaque da Semana: Unknown Multicall Router

Este incidente foi selecionado porque uma sutil mudança de identidade do chamador em chamadas aninhadas do roteador derrotou a autorização em uma carteira Safe que executava módulos personalizados e permitiu uma retirada substancial de ativos.

Em 15 de setembro de 2026, um bot MEV operando sob o nome Yoink antecipou (front-ran) uma tentativa de exploração contra uma carteira Safe que gerenciava seus ativos por meio de módulos de estratégia personalizados, resultando em uma perda estimada de aproximadamente $7.8M [1]. As solicitações chegavam a esses módulos por meio de um roteador multicall, onde um erro de autorização em chamada aninhada permitiu que instruções não confiáveis passassem para a cadeia de módulos, enquanto uma permissão reutilizável forneceu suporte adicional para a operação não autorizada.

Contexto

Uma carteira Safe pode habilitar um módulo Safe. Uma vez habilitado, o módulo pode chamar execTransactionFromModule() para instruir a carteira a executar operações sem aprovação multisig, portanto, um módulo habilitado é um privilégio permanente sobre os ativos da carteira. A carteira Safe vítima havia habilitado dois componentes de estratégia, o módulo Gateway e o módulo LP.

O módulo Gateway definia modelos de comando reutilizáveis, cada um descrevendo uma operação que a carteira Safe vítima tinha permissão para realizar, com os valores concretos preenchidos no momento da execução. Ele aceitava comandos apenas de chamadores em sua própria lista de chamadores autorizados. Cada execução também tinha que carregar uma prova Merkle, verificada em relação a uma raiz armazenada, que autenticava o modelo de comando sendo invocado. Alguns modelos instruíam a carteira a chamar o módulo LP, que executava operações de liquidez do Uniswap v4 usando os ativos da carteira. O controle, portanto, retornava por meio da própria carteira em vez de passar diretamente de um módulo para o outro:

Authorized Caller
       |
       v
Gateway module -- verify(command, Merkle proof, root)
       |
       | execTransactionFromModule(...)
       v
Safe wallet context
       |
       v
   LP module --> mintPosition(...)

Os operadores neste incidente não chamaram o módulo Gateway diretamente. As solicitações chegavam por meio de um roteador multicall, que despachava chamadas em lote em nome deles. Como o roteador era o chamador direto sempre que encaminhava uma solicitação legítima, a lista de chamadores autorizados do módulo Gateway incluía o próprio roteador.

Por meio desse caminho, a carteira Safe vítima podia depositar aEthrsETH, o token de recibo da Aave para rsETH fornecido, em um pool do Uniswap v4, criando (mint) uma posição NFT de volta para a carteira. Qualquer detentor de aEthrsETH poderia queimá-lo (burn) por meio da Aave para retirar o rsETH subjacente.

A carteira Safe vítima também havia tomado empréstimo com base nessa garantia da Aave. A Aave, portanto, rastreava um fator de saúde (health factor) para ela, a razão entre o valor de sua garantia e sua dívida, e rejeita uma transferência de garantia que deixaria o fator abaixo de 1.

Análise de Vulnerabilidade

O roteador em 0x4f00...8ebC não tem código-fonte verificado. A análise a seguir, portanto, baseia-se em seu bytecode implantado, lógica decompilada, rastreamentos de transações e uma reconstrução pública de teste de fork, em vez de nomes autoritativos em nível de código-fonte.

A lógica de despacho do roteador aceitava um alvo que estava em sua lista de permissões (allowlist) ou o próprio endereço do roteador, e então verificava a lista de chamadores autorizados desse alvo em relação ao msg.sender da invocação atual. Nada preservava a identidade do chamador externo original ao longo de uma chamada que o roteador fazia para si mesmo.

Quando o roteador chamava a si mesmo, a invocação interna observava o roteador como msg.sender. O auxiliar de autorização aceitava o roteador no caso de auto-alvo e, caso contrário, verificava se o msg.sender atual aparecia na lista de chamadores autorizados do próximo alvo. Consequentemente, uma chamada interna direcionada ao módulo Gateway era avaliada como originada do roteador já autorizado, em vez de do chamador externo. Isso permitiu que instruções de uma origem não confiável satisfizessem a autorização de chamador do Gateway por meio da rota aninhada.

Um segundo defeito estava na própria verificação de prova. A prova autenticava o modelo de comando, mas nenhuma verificação vinculava os parâmetros de tempo de execução fornecidos com ela. Uma prova válida emitida para um comando legítimo anterior, portanto, permanecia utilizável após seus valores concretos de execução serem alterados. A prova reutilizada forneceu uma permissão utilizável, mas foi o desvio de autorização aninhada que permitiu que um chamador não confiável alcançasse o módulo Gateway.

Análise do Ataque

Uma prova Merkle previamente emitida para o mesmo modelo de comando permaneceu utilizável com valores de tempo de execução diferentes. Essa propriedade não contornou de forma independente a autorização de chamador do Gateway, mas forneceu uma permissão utilizável depois que o caminho aninhado do roteador satisfez essa verificação de autorização.

A análise a seguir é baseada na transação 0x0e7680...a8705.

Antes da transação bem-sucedida, o atacante original implantou um contrato de ataque, um token PAT controlado pelo atacante e um segundo contrato que mais tarde executaria a troca (swap) de PAT.

No bloco seguinte, o atacante chamou prepare() para criar e inicializar um pool PAT/aEthrsETH do Uniswap v4.

O bot MEV Yoink detectou a exploração pendente e antecipou (front-ran) o atacante original invocando o contrato de ataque preparado. A chamada resultante entrou no roteador, fez com que o roteador chamasse a si mesmo e, em seguida, alcançou o módulo Gateway com o roteador como msg.sender. Sendo um módulo habilitado, o Gateway poderia então fazer com que a carteira Safe vítima executasse a operação fornecida sem aprovação multisig.

A instrução fez com que a carteira Safe vítima fornecesse aproximadamente 2.900 aEthrsETH como liquidez para o pool PAT/aEthrsETH controlado pelo atacante, dentro do intervalo de ticks [10, 20]. A transação também criou (mint) o NFT de posição associado do Uniswap v4 para a carteira, fazendo com que a operação parecesse estar dentro do fluxo de liquidez esperado. Isso não consumiu todo o saldo de aEthrsETH da carteira: o valor foi limitado para que a verificação do fator de saúde da Aave ainda passasse, deixando a carteira com um fator de saúde de 1.001182484056805114.

O contrato de ataque então trocou PAT controlado pelo atacante por quase todo o aEthrsETH depositado por meio daquele segundo contrato. Ele queimou (burn) os tokens de recibo adquiridos por meio da Aave e retirou a quantidade correspondente de rsETH. Dos aproximadamente 2.900 rsETH que chegaram ao bot Yoink, aproximadamente 2.882,37 rsETH foram para seu destinatário de lucro, enquanto aproximadamente 17,63 rsETH foram trocados por ETH, e quase todo o ETH resultante foi pago ao construtor de blocos (block builder).

Conclusão

A causa raiz foi um defeito de autorização em infraestrutura personalizada anexada a uma única carteira Safe, agravado por uma permissão que não vinculava todos os parâmetros de execução. Isso não deve ser atribuído aos contratos principais do Safe, Aave, Uniswap v4 ou Kelp.

Um componente que encaminha chamadas em nome de terceiros deve decidir a autorização a partir do chamador externo original, não a partir de uma identidade que a cadeia de chamadas adquire ao longo do caminho, e não deve ser acessível como seu próprio alvo. Uma permissão deve igualmente vincular os valores concretos com os quais uma operação será executada, não apenas o modelo ao qual essa operação pertence.

Comece com o Phalcon Explorer

Mergulhe nas Transações para Agir com Sabedoria

Experimente grátis agora

Mais Incidentes Esta Semana

Nostra Finance

Em 17 de setembro de 2026, o mercado monetário da Nostra na Starknet foi explorado por meio de um preço de oráculo NSTR inflado, permitindo que aproximadamente $3.5M em ativos fossem emprestados contra garantias supervalorizadas. A causa raiz foi uma configuração de integração de oráculo que aceitava fontes de precificação insuficientes, permitindo que uma cotação manipulada de um pool raso afetasse materialmente o preço agregado. A Nostra pausou seus mercados [2], enquanto a Pragma relatou que o endereço do atacante havia sido congelado e o trabalho de recuperação estava em andamento [3]. A perda final e possíveis recuperações permaneceram desconhecidas.

Contexto

A Nostra operava um mercado monetário na Starknet onde os usuários podiam fornecer garantias suportadas e emprestar outros ativos de acordo com o valor derivado do oráculo da garantia.

A Nostra obtinha o preço do NSTR por meio de seu próprio contrato de feed de preço, que delegava a um contrato de oráculo principal que lia dados da Pragma, um oráculo que publica preços agregados na Starknet. Os publicadores enviavam observações para a Pragma sob fontes nomeadas, incluindo AVNU e GECKOTERMINAL, e sua configuração documentada de NSTR descrevia uma mediana entre três delas [4][5]. Cada resposta do oráculo incluía um preço, precisão decimal, timestamp e contagem de fontes contribuintes [6]. O contrato de oráculo principal armazenava MinAggregatedSources, um número mínimo configurável de fontes contribuintes.

A implementação de agregação implantada não foi lida diretamente. Duas indicações independentes, no entanto, apontam na mesma direção: o código de código aberto da Pragma retorna a média das duas entradas do meio sempre que a contagem de entradas é par [6], e a resposta MEDIAN observada neste incidente equivaleu à média aritmética de suas duas observações contribuintes.

Os números por trás dessas fontes vinham do mercado. Uma observação da GECKOTERMINAL poderia ser derivada de pools on-chain, e um desses locais na Starknet é a Ekubo, uma exchange descentralizada que usa liquidez concentrada, semelhante ao Uniswap v3. Provedores de liquidez colocam ativos dentro de intervalos de ticks selecionados, e as trocas (swaps) movem o preço do pool por meio dos intervalos ativos, enquanto lacunas sem liquidez ativa podem separar posições colocadas em preços materialmente diferentes.

A Nostra usava o preço do NSTR obtido por meio desse caminho de oráculo para avaliar a garantia depositada e calcular a capacidade de empréstimo da conta.

Análise de Vulnerabilidade

O mercado monetário da Nostra lia os preços do NSTR de 0x6838...5bf0, o contrato que sua documentação lista como o feed de preço do NSTR [7]. Esse contrato delegava ao oráculo principal que designava, 0x7b05...f0ab, que tinha o MinAggregatedSources configurado como 1. A Pragma recomenda pelo menos três fontes de precificação, e relatou após o incidente que um mínimo de três fontes aplicado teria rejeitado a resposta aceita neste caso [3].

Uma resposta contendo duas observações válidas, portanto, excedia o limite configurado. Como o cálculo MEDIAN para duas observações resultava em sua média aritmética, uma única cotação extrema poderia distorcer substancialmente o resultado, mesmo quando a outra observação permanecesse próxima do preço de mercado predominante.

Essa foi uma fraqueza de configuração de integração, não um erro de escalonamento decimal ou de implementação de mediana. A Pragma não encontrou nenhum defeito em nenhum dos cálculos [3]. O limite insuficiente de fontes permitiu que a saída corretamente calculada, a partir de um conjunto de entrada inadequadamente diversificado, determinasse o valor da garantia e a capacidade de empréstimo.

Análise do Ataque

O ataque dependeu da manipulabilidade de um pool de liquidez concentrada recém-criado e com pouco capital. As evidências disponíveis indicam que a semeadura do pool pelo atacante e sua atividade repetida podem ter influenciado o pool usado para a observação da GECKOTERMINAL, embora a causalidade exata da seleção do pool não tenha sido estabelecida.

A análise a seguir é baseada na transação 0x2460fd...cdf00e.

O atacante primeiro criou um pool NSTR/SolvBTC na Ekubo e forneceu 1,5 SolvBTC como liquidez unilateral em um intervalo de preço inferior e inativo. O atacante então adicionou aproximadamente 1.900 NSTR e 0,0001514751 SolvBTC em torno do preço normal de mercado e realizou trocas (swaps) repetidas no pool.

Em seguida, o atacante colocou 190 NSTR como liquidez unilateral em um intervalo estreito muito acima do preço normal. Após remover a liquidez em torno do preço normal de mercado, o atacante deixou uma lacuna de liquidez vazia antes dessa posição de preço elevado.

Uma troca (swap) contendo apenas 0,00000001 SolvBTC atravessou a lacuna vazia e moveu o pool para o tick -6645400, no limite da posição de preço elevado. O valor manipulado do pool foi posteriormente enviado como uma observação NSTR/USD da GECKOTERMINAL de $99,02439975.

A outra observação contribuinte, enviada sob AVNU, avaliou o NSTR em $0,00596118. Nenhuma observação da terceira fonte configurada aparece nessa resposta, deixando esses dois como os únicos valores que chegaram à agregação [4].

Com dois valores, a resposta MEDIAN foi sua média aritmética, aproximadamente $49,51518046 por NSTR. A Nostra aceitou a avaliação resultante e tratou o depósito de NSTR do atacante como garantia suficiente para empréstimos substanciais.

Na primeira extração identificada, o atacante usou uma conta separada mantendo garantia em NSTR para emprestar aproximadamente 939,386010 ETH na avaliação inflada [4]. A Nostra relatou que a sequência completa de empréstimos também envolveu STRK, USDC, USDT, WBTC e DAIv1, com um valor agregado emprestado de aproximadamente $3.5M [2].

Conclusão

O incidente resultou de um limite insuficiente de fontes de oráculo na integração da Nostra, não de um erro no tratamento decimal ou no cálculo de agregação da Pragma. Uma resposta de duas fontes permaneceu válida mesmo que uma observação viesse de um pool altamente manipulável.

A Nostra deve aplicar um mínimo de pelo menos três fontes de precificação contribuintes e rejeitar qualquer resposta de oráculo cuja contagem de fontes esteja abaixo desse limite antes de usar o preço para avaliação de garantia ou empréstimo. A elegibilidade de garantia e os limites de exposição também devem refletir a liquidez de mercado disponível e a profundidade necessária para manipular as fontes de preço subjacentes de cada ativo.

Comece com o Phalcon Security

Detecte cada ameaça, alerte o que importa e bloqueie ataques.

Experimente grátis agora

Referências

[1] https://x.com/Phalcon_xyz/status/2099741447776096270

[2] https://x.com/nostrafinance/status/2100577538053493076

[3] https://www.pragma.build/updates/nostra-nstr-incident

[4] https://x.com/Phalcon_xyz/status/2100818035082952751

[5] https://www.pragma.build/asset/NSTR-USD?network=mainnet

[6] https://github.com/Astraly-Labs/pragma-oracle

[7] https://docs.nostra.finance/lend-and-borrow/deployed-contracts/money-market-mainnet

Sobre a BlockSec

A BlockSec é uma provedora full-stack de segurança blockchain e conformidade cripto. Construímos produtos e serviços que ajudam os clientes a realizar auditoria de código (incluindo contratos inteligentes, blockchain e carteiras), interceptar ataques em tempo real, analisar incidentes, rastrear fundos ilícitos e cumprir obrigações de AML/CFT, ao longo de todo o ciclo de vida de protocolos e plataformas.

A BlockSec publicou múltiplos artigos de segurança blockchain em conferências de prestígio, relatou vários ataques de dia zero (zero-day) em aplicações DeFi, bloqueou múltiplos hacks para resgatar mais de 20 milhões de dólares, e protegeu bilhões em criptomoedas.

Melhor Auditor de Segurança para Web3

Valide design, código e lógica de negócios antes do lançamento

Best Security Auditor for Web3

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

BlockSec Audit