Reentrancy
Una chiamata esterna effettuata prima di aggiornare lo stato consente a un attaccante di rientrare nella funzione prima che i saldi vengano decrementati. Segui checks-effects-interactions e usa un reentrancy guard.
// 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);
}
Autenticazione via tx.origin
Usare tx.origin per l'autorizzazione permette a un contratto intermedio di agire per conto dell'utente. Usa msg.sender.
Manipolazione di oracolo / prezzo
Leggere un prezzo spot da un'unica pool lo rende manipolabile con un grande swap, spesso finanziato con un flash loan. Preferisci un prezzo medio ponderato nel tempo (TWAP) o un oracolo aggregato.
Controllo degli accessi mancante
Una funzione sensibile senza modifier restrittivo può essere chiamata da chiunque. Proteggi le funzioni privilegiate con onlyOwner o controlli di ruolo.
Chiamata esterna non verificata
Ignorare il valore di ritorno di una chiamata di basso livello lascia proseguire il contratto dopo un trasferimento fallito. Controlla sempre il booleano restituito.
Falle di logica di business
Un confronto invertito o un calcolo di quota errato rompe un invariante. Queste falle sono specifiche del contratto, sfuggono ai rilevatori generici e sono spesso le più costose. Descrivi il comportamento atteso e confrontalo con il codice.
Vuoi esercitarti a sfruttarle in sicurezza? Vedi Imparare. Pronto a scansionare il tuo contratto? Apri lo scanner.