Reentrancy
Uma chamada externa feita antes de atualizar o estado permite a um atacante reentrar na função antes de os saldos serem decrementados. Siga checks-effects-interactions e use um guard anti-reentrancy.
// vulnerable
function withdraw(uint a) public {
require(bal[msg.sender] >= a);
(bool ok,) = msg.sender.call{value:a}("");
bal[msg.sender] -= a; // too late
}
// fixed
function withdraw(uint a) public nonReentrant {
require(bal[msg.sender] >= a);
bal[msg.sender] -= a; // effects first
(bool ok,) = msg.sender.call{value:a}("");
require(ok);
}
Autenticação via tx.origin
Usar tx.origin para autorização permite que um contrato intermediário aja em nome do usuário. Use msg.sender.
Manipulação de oráculo / preço
Ler um preço spot de uma única pool o torna manipulável por um swap grande, muitas vezes financiado por um flash loan. Prefira um preço médio ponderado no tempo (TWAP) ou um oráculo agregado.
Falta de controle de acesso
Uma função sensível sem modifier restritivo pode ser chamada por qualquer um. Proteja as funções privilegiadas com onlyOwner ou verificações de papel.
Chamada externa não verificada
Ignorar o valor de retorno de uma chamada de baixo nível deixa o contrato continuar após uma transferência falhada. Sempre verifique o booleano retornado.
Falhas de lógica de negócio
Uma comparação invertida ou cálculo de cota errado quebra um invariante. Essas falhas são específicas do contrato, escapam aos detectores genéricos e costumam ser as mais caras. Descreva o comportamento esperado e compare-o com o código.
Quer praticar explorando-as com segurança? Veja Aprender. Pronto para escanear seu contrato? Abra o scanner.