Voltar aos artigos
Advanced

Criando um Forta Bot para Detectar Ataques de Governança Financiados por Flash Loans em Tempo Real

Este conteúdo é fornecido **EXCLUSIVAMENTE** para fins de **EDUCAÇÃO** e **TESTES DE SEGURANÇA AUTORIZADOS**.

@0xrafasecFebruary 18, 2026detection_and_defense

Available in English

Share:

Criando um Forta Bot para Detectar Ataques de Governança Financiados por Flash Loans em Tempo Real

Legal & Ethical Disclaimer

This content is provided for EDUCATIONAL and AUTHORIZED SECURITY TESTING purposes only.

DO
  • Use these techniques on systems you own or have explicit written permission to test
  • Practice in authorized lab environments (VulnHub, HackTheBox, DVWA, etc.)
  • Follow responsible disclosure practices when finding vulnerabilities
  • Use knowledge for defensive security and authorized penetration testing
DO NOT
  • Access systems without explicit authorization
  • Use these techniques for malicious purposes
  • Deploy exploits against production systems you don't own
  • Share working exploits for unpatched vulnerabilities

Legal warning

Unauthorized access to computer systems is illegal in most jurisdictions (e.g. CFAA in the US, Computer Misuse Act in the UK). Violators may face criminal prosecution and civil liability. The author and publisher assume no liability for misuse of this information. By continuing, you agree to use this knowledge ethically and legally.

Hook & Contexto

Em abril de 2022, um atacante tomou emprestado $1 bilhão em um flash loan, usou o capital para adquirir uma participação controladora no token de governança do Beanstalk, aprovou duas propostas maliciosas no mesmo bloco e drenou $182 milhões do protocolo — tudo antes de uma única pessoa conseguir reagir. O ataque não era um bug em uma função Solidity. Era uma exploração lógica do próprio sistema de governança, e foi executado inteiramente dentro da atomicidade de um único bundle de transação Ethereum. Nenhum alarme disparou. Nenhum circuit breaker foi acionado. O protocolo simplesmente não estava ouvindo esse padrão.

Essa é a classe de ataque que auditoria estática baseada em regras não consegue prevenir sozinha. Você não consegue corrigi-la com uma instrução require depois do fato. A superfície de defesa é temporal e comportamental: você precisa detectar a correlação entre uma aquisição massiva de tokens e uma ação de governança e expor isso rápido o suficiente para importar — idealmente antes da execução da proposta, ou no mínimo antes que um segundo ataque na mesma campanha passe despercebido. Monitoramento em tempo real on-chain é a camada da pilha de segurança que fecha essa lacuna.

Forta foi construído especificamente para isso. É uma rede de monitoramento descentralizada onde bots de detecção — programas Node.js/TypeScript que consomem dados blockchain bloco a bloco — são executados continuamente e emitem alertas quando padrões anômalos são encontrados. Este artigo aborda o design racional, estratégia de correlação de dados e calibração de limites para um bot Forta que especificamente procura pelo padrão flash-loan-para-ação-de-governança. Usamos dados históricos de transações do Compound e Beanstalk como âncoras de calibração.


🎯 TL;DR

DimensãoResumo
O que você está criandoUm bot de detecção Forta que correlaciona fluxos de tokens de flash loan com votos/propostas de governança dentro de uma janela de blocos configurável
Técnica centralMapeamento de estado por bloco efêmero, endereços mapeados para eventos de aquisição de tokens, limpo e comparado contra logs de eventos de governança
Âncoras de calibraçãoBloco 14602790 do Beanstalk (ataque), histórico de delegações grandes do Compound
Sinal de alertaO receptor de flash loan aparece em ação de governança dentro de N blocos de receber tokens, onde o delta de token excede o limiar de quórum
Desafio-chaveDistinguir delegações legítimas grandes de votação em flash loan maliciosa — resolvido via impressão digital de fonte de empréstimo e proximidade de bloco
Ferramentas usadasForta SDK, ethers.js, The Graph (calibração histórica), Tenderly (simulação de transação para testes)

Fundações & Teoria

Por Que Governança É a Nova Superfície de Ataque

Sistemas de governança on-chain transferem o controle do protocolo para detentores de tokens. Essa foi uma decisão de design democratizadora — mas introduziu uma suposição latente: que detentores de tokens estão alinhados economicamente com a saúde de longo prazo do protocolo. Flash loans destroem essa suposição. Um flash loan permite que qualquer endereço mantenha temporariamente um saldo de token arbitrariamente grande pela duração de uma única transação, com zero compromisso econômico além de gas e taxas. Se um sistema de governança aceita um snapshot do saldo de token no momento do voto em vez de em um bloco anterior, esse saldo de flash loan se torna um peso de voto válido.

O padrão de ataque é determinístico:

[Bloco N]
  1. Flash loan: emprestar X tokens de governança
  2. Votar / criar proposta usando peso emprestado
  3. Reembolsar flash loan
  ↓
[Bloco N ou N+k]
  4. Proposta executa (se timelock é zero ou é ignorado)

O insight crítico para detecção é que passos 1–3 são rastreáveis via logs de eventos. Toda transferência ERC-20 emite um evento Transfer(address indexed from, address indexed to, uint256 value). Todo contrato de governança emite VoteCast ou ProposalCreated. A correlação entre essas duas correntes, ancorada na proximidade de tempo de bloco, é o sinal de detecção.

Por Que Detecção em Tempo Real Importa Mesmo Pós-Ataque

Você poderia perguntar: se o ataque é atômico, o que a detecção em tempo real até oferece? Três coisas. Primeiro, ataques em múltiplas etapas — como Beanstalk, que exigiu duas propostas — têm janelas entre propostas onde alertas podem disparar pausas de emergência. Segundo, detecção de campanha: um atacante sondando limites em múltiplos protocolos deixará um rastro entre cadeias que um bot em execução acumula. Terceiro, velocidade forense: geração de alerta mais rápida comprime o tempo até análise pós-mortem, o que importa para reivindicações de seguro, decisões de fork e resposta da comunidade.


Onde Isso Se Encaixa no Fluxo de Trabalho

Em uma pilha de segurança DeFi, bots de detecção ocupam a camada de monitoramento contínuo — distinta de auditoria pré-implantação (análise estática, fuzzing) e resposta a incidentes (multisig do tesouro, pausa de protocolo). Pense na pilha geral como um modelo de defesa em profundidade:

Loading diagram…

O bot Forta fica nessa terceira camada. Seu trabalho não é prevenir — é detectar e escalar rápido o suficiente para que a camada de resposta a incidente tenha tempo de agir. Para protocolos com governança com timelock (por exemplo, atraso de 48 horas na execução de proposta), um bot alertando dentro de segundos de um voto suspeito dá aos proprietários da multisig uma janela de intervenção significativa.


Conceitos-Chave em Profundidade

1. Subscrição de Fluxo Duplo e o Modelo de Estado Por-Bloco

A fundação deste bot é subscrição simultânea a dois fluxos de eventos e correlação com estado através de uma janela de bloco deslizante. No Forta, sua função handleTransaction é chamada para toda transação em todo bloco. Você também tem acesso a handleBlock para limpeza por bloco.

A arquitetura de estado se parece com isso:

typescript
// Estado efêmero: mapeia endereço do destinatário → {amount, blockNumber, txHash}
const flashLoanRecipients: Map<string, FlashLoanEvent[]> = new Map();

// Ações de governança observadas: mapeia endereço → {action, blockNumber, txHash}  
const governanceActions: Map<string, GovernanceEvent[]> = new Map();

const BLOCK_WINDOW = 3; // configurável — discutido na seção de calibração
const QUORUM_THRESHOLD = ethers.utils.parseUnits("100000", 18); // específico do protocolo

Em cada transação, você decodifica logs contra duas ABIs: o token de governança (ERC-20 Transfer) e o contrato de governança (VoteCast, ProposalCreated). Quando um evento grande de Transfer é detectado de um endereço de pool de empréstimo conhecido (Aave, dYdX, endereços de pool Uniswap V2/V3), você registra o destinatário. Quando um evento de governança é detectado, você verifica se o remetente aparece em flashLoanRecipients dentro de BLOCK_WINDOW blocos.

A decisão de design-chave é de onde você obtém a "impressão digital de flash loan". Você tem duas estratégias:

  • Impressão digital de endereço de origem: mantenha uma lista de endereços de pool de empréstimo conhecido e provedores de flash loan. Uma Transfer de um desses para um novo endereço é provavelmente um desembolso de flash loan.
  • Padrão de transferência de retorno: flash loans exigem reembolso, então você verá uma Transfer simétrica de saída do destinatário de volta para o pool dentro do mesmo bloco. Este é o sinal mais forte, mas requer consciência de ordenação intra-bloco.

Para um bot de produção, use ambas. A impressão digital de origem dispara cedo (no recebimento); o padrão de retorno dispara como confirmação.

2. Decodificação de ABI e Filtragem de Log no Forta SDK

Bots Forta recebem um objeto TransactionEvent que expõe filterLog(abi, address) — um método de conveniência envolvendo a decodificação da interface ethers.js. O aspecto elegante desse design é que você pode filtrar múltiplas assinaturas de evento em uma única passagem:

typescript
import { Finding, FindingSeverity, FindingType, HandleTransaction, TransactionEvent } from "forta-agent";
import { GOVERNANCE_ABI, TOKEN_ABI, KNOWN_LENDING_POOLS } from "./constants";

const handleTransaction: HandleTransaction = async (txEvent: TransactionEvent) => {
  const findings: Finding[] = [];

  // Decodifique transferências de token grandes DE fontes de flash loan conhecidas
  const transferLogs = txEvent.filterLog(TOKEN_ABI, GOVERNANCE_TOKEN_ADDRESS);
  
  for (const log of transferLogs) {
    const { from, to, value } = log.args;
    if (KNOWN_LENDING_POOLS.has(from.toLowerCase()) && value.gte(QUORUM_THRESHOLD)) {
      recordFlashLoanRecipient(to, value, txEvent.blockNumber, txEvent.hash);
    }
  }

  // Decodifique ações de governança
  const voteLogs = txEvent.filterLog(GOVERNANCE_ABI, GOVERNOR_ADDRESS);
  
  for (const log of voteLogs) {
    const voter = log.args.voter ?? log.args.proposer;
    const finding = checkCorrelation(voter, txEvent.blockNumber, txEvent.hash);
    if (finding) findings.push(finding);
  }

  return findings;
};

Uma nota de implementação crítica: filterLog retorna eventos decodificados para a transação inteira, não apenas logs do contrato principal. Isso importa porque orquestração de flash loan tipicamente acontece através de um contrato de atacante personalizado que chama governança na mesma transação — os eventos aparecem no mesmo array de log de transação independentemente da profundidade de chamada.

3. Gerenciamento de Estado de Janela Deslizante e Limpeza de Bloco

Estado efêmero que nunca expira cria vazamentos de memória e falsos positivos de dados obsoletos. O hook handleBlock é seu mecanismo de limpeza:

typescript
const handleBlock = async (blockEvent: BlockEvent) => {
  const currentBlock = blockEvent.blockNumber;
  
  // Remova entradas mais antigas que BLOCK_WINDOW
  for (const [address, events] of flashLoanRecipients.entries()) {
    const filtered = events.filter(e => currentBlock - e.blockNumber <= BLOCK_WINDOW);
    if (filtered.length === 0) {
      flashLoanRecipients.delete(address);
    } else {
      flashLoanRecipients.set(address, filtered);
    }
  }
  
  return [];
};

Por que BLOCK_WINDOW importa arquiteturalmente: ataques no mesmo bloco (como Beanstalk) exigem BLOCK_WINDOW = 0 para detectar com certeza, mas definir a janela para 1–3 blocos também pega ataques de múltiplas transações onde o atacante empresta no bloco N e vota no bloco N+1 antes de reembolsar no bloco N+2 (um padrão que pode evitar detecção no mesmo bloco se o contrato de governança apenas verifica o saldo atual).

4. Calibração de Limiar Usando Dados Históricos

É aqui que o bot se move de brinquedo para qualidade de produção. Limiares descalibrados são a razão principal pela qual bots de monitoramento falham na prática — ou afogando operadores em ruído ou perdendo ataques reais.

Calibrando contra Beanstalk (bloco 14602790): O atacante adquiriu aproximadamente 79 milhões de Stalk (peso de governança). No momento do ataque, a oferta total de Stalk era aproximadamente 170 milhões, tornando o peso do ataque ~46% da oferta total. Seu QUORUM_THRESHOLD para Beanstalk deveria ter sido definido bem abaixo de 46% da oferta — algo como 10–15% da oferta em circulação como disparo, já que nenhum votante legítimo único manteria essa proporção através de um flash loan.

Calibrando contra delegações legítimas grandes do Compound: O histórico de governança do Compound inclui endereços como 0xa2869... (delegação a16z) segurando 8–10% do COMP através de meios legítimos. As características distintivas são:

  • A delegação não foi adquirida no mesmo ou bloco adjacente como um voto
  • A fonte do token era uma multisig ou carteira VC conhecida, não um pool de empréstimo
  • A participação persistiu através de milhares de blocos

A partir disso, derive dois eixos de calibração:

EixoSinal MaliciosoSinal Legítimo
Fonte do tokenPool de empréstimo conhecidoMultisig / exchange / carteira com posse de longo prazo
Proximidade de blocoMesmo ou ≤3 blocos entre aquisição e votoSemanas/meses de posse anterior
Delta de token>10% da oferta em circulação<5% em um evento de aquisição único
Histórico de endereçoVotante de primeira vez, sem participação anterior em governançaEndereço com histórico de governança

Usando The Graph, consulte eventos VoteCast históricos e faça referência cruzada de idades de endereço de votante contra timestamps de aquisição de token. Qualquer endereço que recebeu tokens de governança pela primeira vez no mesmo bloco em que votou é um ponto de calibração perfeito para BLOCK_WINDOW = 0.

5. Estrutura de Alerta e Design de Escalação

Um Finding em Forta não é apenas uma entrada de log — é um alerta estruturado com severidade, tipo, metadados e rótulos de protocolo que consumidores downstream (webhooks Tenderly, PagerDuty, bots Discord) podem agir. Projete seu alerta para carregar contexto forense máximo:

typescript
Finding.fromObject({
  name: "Flash Loan Governance Attack Detected",
  description: `Address ${voter} cast governance vote within ${blockDelta} blocks of receiving ${formattedAmount} tokens from flash loan source ${loanSource}`,
  alertId: "FLASH-LOAN-GOV-1",
  severity: blockDelta === 0 ? FindingSeverity.Critical : FindingSeverity.High,
  type: FindingType.Exploit,
  metadata: {
    voter,
    loanSource,
    tokenAmount: amount.toString(),
    acquisitionBlock: acquisitionBlock.toString(),
    voteBlock: voteBlock.toString(),
    proposalId: proposalId ?? "unknown",
    blockDelta: blockDelta.toString(),
  },
  protocol: "compound-v2", // ou dinâmico
  addresses: [voter, loanSource],
});

Gradação de severidade importa para resposta de operador. Um alerta Critical (mesmo bloco) deve disparar uma ação de emergência automatizada se seu protocolo tiver uma. Um alerta High (janela de 1–3 blocos) deve paginar um responsável on-call. Medium (>3 blocos, aquisição grande, votante de primeira vez) deve registrar em um dashboard para revisão humana.


Alternativas & Comparação

AbordagemForçasFraquezas
Bot Forta (esta abordagem)Tempo real, descentralizado, componível, alertas estruturadosRequer manutenção, bots podem perder eventos se mal subscritos
Webhooks TenderlyFácil setup, UI excelenteCentralizado, lógica de correlação limitada, fadiga de alerta
The Graph + polling por cronConsultas históricas ricas, ótimo para janelas de múltiplos blocosLatência (minutos, não segundos), não verdadeiramente tempo real
Custom RPC mempool watcherLatência mais baixa (pré-confirmação)Pesado em infraestrutura, requer nó archive, sem descentralização
Chainalysis / TRM LabsQualidade compliance, entre cadeiasCaro, não aberto, não customizável para lógica específica do protocolo

Para protocolos DeFi com governança ao vivo, Forta + roteamento de alerta Tenderly é a pilha prática: Forta manipula a lógica de detecção; Tenderly manipula a entrega e simulação legível por humano da transação detectada para que respondentes verifiquem em menos de 60 segundos.


Aprendizados & Leitura Complementar

O ataque Beanstalk não é uma anomalia histórica — é um blueprint que outros atacantes seguirão conforme o poder de governança continua se concentrando em tokens líquidos e emprestáveis. O bot de detecção descrito aqui não é uma bala de prata: não pode impedir um ataque atômico de ser completado, mas pode detectar o padrão, alertar a tempo para campanhas de múltiplas etapas, e construir um registro forense que colapsa investigação pós-incidente de semanas para horas.

Os três princípios de design que tornam este bot qualidade de produção em vez de prova de conceito:

  1. Correlação de fluxo duplo sobre alerting de evento único — um evento em isolamento nunca é sinal suficiente
  2. Limiares calibrados historicamente — construa seu ajuste a partir de dados reais on-chain, não intuição
  3. Alertas estruturados e acionáveis — um alerta que não diz ao respondente exatamente o que procurar é ruído

📚 Leitura Complementar:

A superfície de ataque de governança crescerá apenas conforme protocolos DeFi amadurecem e o poder de governança acumula valor econômico real. Construa a camada de monitoramento agora, calibre-a contra histórico, e trate-a como um artefato de engenharia de primeira classe — não um afterthought parafusado depois que o exploit já executou.

Achou este artigo interessante? Siga-me no X e no LinkedIn.