Guida tecnica. Aggiornata al 15 febbraio 2026.
Gli smart contract hanno perso agli utenti oltre $5 miliardi tra il 2020 e il 2025. Non perché la tecnologia sia intrinsecamente insicura, ma perché scrivere codice corretto che gestisce valore è difficile e le conseguenze degli errori sono irreversibili. Capire come funzionano i bug principali, cosa copre un audit e come verificare un contratto prima di interagire permette di ridurre il rischio in modo pratico.
I bug più comuni negli smart contract
Reentrancy: la vulnerabilità che ha colpito The DAO
Il reentrancy è la classe di bug più nota nella storia degli smart contract. Il meccanismo: un contratto A chiama un contratto B per trasferire ETH; il contratto B, nella sua funzione di ricezione, richiama A prima che A abbia aggiornato il proprio stato interno. Il risultato è che A viene ingannato a credere che il bilancio dell’attaccante sia ancora alto, e può essere drenato più volte nella stessa transazione.
The DAO hack del 2016 ha sfruttato esattamente questo: $60 milioni di ETH rubati. La soluzione standard è il pattern “checks-effects-interactions”: aggiorna sempre lo stato interno (effects) prima di interagire con contratti esterni (interactions). Il ReentrancyGuard di OpenZeppelin è oggi lo strumento standard di difesa.
Oracle price manipulation
Molti protocolli DeFi leggono il prezzo di un asset da uno spot price on-chain (es. una pool AMM). Un attaccante con abbastanza capitale — spesso tramite flash loan — può manipolare temporaneamente quel prezzo e sfruttarlo per liquidare posizioni artificialmente o estrarre valore da protocolli di lending. La difesa è usare prezzi TWAP (Time-Weighted Average Price) invece di spot price: la media nel tempo è molto più costosa da manipolare. Chainlink e altri oracle off-chain risolvono il problema in modo diverso, ma introducono una dipendenza esterna.
Flash loan attack
I flash loan permettono di prendere in prestito qualsiasi importo senza collateral, purché venga restituito nella stessa transazione. Non sono intrinsecamente pericolosi — sono uno strumento utile per arbitraggio e liquidazioni. Diventano un vettore d’attacco quando un protocollo non è progettato per gestire operazioni di grandi dimensioni in un singolo blocco. Beanstalk (2022, $182M), Cream Finance (2021, $130M) e dozzine di altri protocolli sono stati svuotati con flash loan che hanno amplificato vulnerabilità nel design del contratto.
Integer overflow e underflow
Prima di Solidity 0.8.x, operazioni aritmetiche potevano superare i limiti del tipo intero senza revert. Un contatore che doveva arrivare a 100 poteva “avvolgere” a 0 se manipolato correttamente. Da Solidity 0.8.x il comportamento di default è il revert su overflow, ma contratti legacy (o compilati con versioni vecchie) rimangono vulnerabili. SafeMath di OpenZeppelin era la soluzione pre-0.8.x.
Come funziona un audit di sicurezza
Un audit di smart contract è una revisione sistematica del codice da parte di esperti di sicurezza. Non è una garanzia di assenza di bug — è una riduzione significativa della probabilità di bug comuni e noti.
Cosa copre un audit
Un buon audit copre: logica di business (il codice fa quello che dice il whitepaper?), vulnerabilità note (reentrancy, overflow, oracle manipulation, accesso non autorizzato), dipendenze esterne (oracle, token usati come collateral, contratti chiamati), e centralizzazione (chi può pausare il contratto, chi può aggiornarlo, con quale meccanismo).
Cosa non copre un audit: il rischio di mercato, la qualità del team, la sostenibilità del business model, vulnerabilità zero-day sconosciute alla data dell’audit. Un audit su un codice vecchio non copre le modifiche successive, a meno che non ci sia un re-audit.
Come trovare e leggere gli audit
Gli audit pubblici sono disponibili su GitHub del progetto, nei loro Docs, o su piattaforme come Solodit.xyz che li aggrega. Quando leggi un audit, cerca: quante “critical” e “high” issue sono state trovate? Sono state risolte? Il report post-fix conferma la risoluzione? Un report che trova solo “low” e “informational” può essere un segno che l’audit non era approfondito, o che il codice è davvero pulito — devi avere il contesto per capire quale.
Auditor riconosciuti nel 2026: Trail of Bits, Spearbit, OpenZeppelin, Halborn, Code4rena (contest model), Cantina. Un audit da un auditor sconosciuto, non verificabile, non vale quasi nulla come segnale di sicurezza.
Upgradeability: proxy pattern e rischi
La maggior parte dei contratti DeFi importanti è upgradeable: il codice può essere modificato dopo il deployment. Questo sembra contraddire la premessa dell'”immutabilità” blockchain, ma è una necessità pratica per correggere bug o aggiungere funzionalità.
Come funziona il proxy pattern
Il meccanismo standard è il proxy pattern: gli utenti interagiscono con un proxy contract che delega l’esecuzione a un implementation contract. Per fare un upgrade, l’implementation contract viene sostituito. Lo storage rimane nel proxy, il codice cambia nell’implementation.
Il rischio principale è che un upgrade mal progettato può causare “storage collision”: se la nuova implementation usa variabili in posizioni di storage diverse dalla precedente, può corrompere dati esistenti. Il pattern UUPS (Universal Upgradeable Proxy Standard) e il Transparent Proxy di OpenZeppelin sono i più usati e auditati.
Chi può fare un upgrade?
La domanda critica non è tecnica ma di governance: chi detiene le chiavi per autorizzare un upgrade? Se è un multisig con 3 persone anonime, il contratto può essere cambiato in modo malevolo con la compromissione di 2 chiavi. Se è una governance DAO con timelock di 48 ore, hai almeno il tempo di uscire prima che un cambiamento malevolo diventi effettivo.
Timelock: il meccanismo di sicurezza per la governance
Un timelock è un contratto che impone un ritardo tra la proposta di un cambiamento e la sua esecuzione. Serve a dare agli utenti il tempo di verificare cosa sta per succedere e di uscire se non approvano.
Standard di mercato: 24-48 ore per protocolli minori, 72 ore o più per protocolli con TVL elevato. Aave v3 usa un timelock di 24 ore per parametri minori e 7 giorni per cambiamenti critici. Compound usa 48 ore. Un protocollo senza timelock — dove l’upgrade può essere eseguito istantaneamente — è strutturalmente pericoloso per gli utenti.
Verifica il timelock su chain: cerca il Timelock contract nell’explorer, controlla il valore di minDelay e quale indirizzo ha il ruolo PROPOSER. Se il minDelay è 0 o l’executor è un singolo EOA (Externally Owned Account), il timelock è di fatto inutile.
Come verificare un contratto prima di interagire
Etherscan: verificato vs non verificato
Su Etherscan, un contratto è “verified” se il codice sorgente è stato pubblicato e corrisponde al bytecode deployato. Questo non significa che il codice sia sicuro — significa che puoi leggerlo. Un contratto non verificato non permette di sapere cosa fa: evitalo per qualsiasi interazione rilevante.
Controlla anche la data di deployment e il numero di transazioni. Un contratto deployato ieri con zero transazioni è un segnale diverso da uno deployato 2 anni fa con milioni di interazioni.
Allowance: il rischio che si accumula silenziosamente
Ogni volta che approvi un contratto a spendere i tuoi token (via ERC-20 approve), stai dando una firma permanente finché non la revochi. Nel tempo, accumuli decine di allowance su contratti che magari non usi più. Se uno di quei contratti viene compromesso, può drenarti i token approvati anche se non interagisci più con esso.
Verifica e revoca le allowance periodicamente con strumenti come Revoke.cash o Etherscan Token Approvals. Imposta allowance al minimo necessario invece di “approve max” — molti wallet e dApp offrono questa opzione. Il costo in gas di una revoca è minimo rispetto al rischio che elimina.
Checklist sicurezza prima di interagire con un nuovo contratto
- Il contratto è verificato su Etherscan/Basescan/ecc.?
- Esiste un audit recente (non più vecchio di 12 mesi per una codebase attiva) da auditor riconosciuto?
- Chi può upgradare il contratto e con quale timelock?
- Quale oracle usa per i prezzi — spot price o TWAP?
- Qual è l’allowance che sto dando — è limitata o illimitata?
- C’è un bug bounty attivo su Immunefi o simili?
- Qual è lo storico di sicurezza del protocollo negli ultimi 12 mesi?
Access control: owner, ruoli e permessi
La maggior parte degli exploit di governance — non i bug di codice puro, ma le manipolazioni intenzionali — sfrutta configurazioni errate di access control. Chi può chiamare quale funzione su un contratto è tanto importante quanto la correttezza della logica interna.
Il pattern Ownable
Il contratto più semplice ha un “owner” che può eseguire funzioni amministrative. OpenZeppelin Ownable è il pattern standard: una variabile owner, un modifier onlyOwner, e funzioni di trasferimento della proprietà. Il rischio principale è che se la chiave privata dell’owner viene compromessa, l’attaccante ha controllo completo. Per contratti con TVL elevato, un EOA come owner è insufficiente — serve almeno un multisig.
Role-based access control (RBAC)
AccessControl di OpenZeppelin introduce ruoli granulari: ADMIN_ROLE, PAUSER_ROLE, UPGRADER_ROLE, ecc. Ogni ruolo può essere assegnato a indirizzi diversi — un multisig per gli upgrade, un indirizzo separato per la pausa di emergenza, un terzo per i parametri operativi. La granularità riduce il rischio: compromettere il ruolo PAUSER non dà accesso agli upgrade del contratto.
Come verificare: su Etherscan, nella sezione “Read Contract”, cerca le funzioni hasRole, getRoleAdmin, e leggi quali indirizzi hanno quali ruoli. Verifica poi quei indirizzi: sono EOA o multisig? Se sono multisig, quanti signatari e con quale threshold?
Come leggere e interpretare un report di audit
Un report di audit è un documento tecnico che descrive le vulnerabilità trovate, la loro severità e lo stato della risoluzione. Capire come leggerlo permette di usarlo come strumento di valutazione, non come semplice certificato da esporre nel marketing.
Struttura di un report tipico
La maggior parte dei report di audit è strutturata in: sommario esecutivo, scope (quale codice è stato revisionato, a quale commit), findings (le vulnerabilità), e appendice tecnica. La sezione più importante per un non-tecnico è i findings con il loro stato di risoluzione.
Livelli di severità
| Severità | Significato | Risposta attesa |
|---|---|---|
| Critical | Perdita di fondi diretta e immediata possibile | Fix obbligatorio prima del deploy |
| High | Perdita di fondi possibile in condizioni specifiche | Fix fortemente raccomandato |
| Medium | Comportamento scorretto, perdita di fondi improbabile | Fix raccomandato |
| Low | Problema di design, best practice non seguita | Fix a discrezione |
| Informational | Osservazione, nessun rischio diretto | Considerare per miglioramenti futuri |
Un report con issue Critical o High non risolte prima del deploy è un red flag grave. Un report con solo Low e Informational può indicare un codebase ben scritto — o un audit non abbastanza approfondito. Il contesto e la reputazione dell’auditor sono fondamentali per interpretare correttamente.
Cosa fare se l’audit è vecchio
Un audit valido al momento del deploy può diventare obsoleto se il contratto viene modificato. Cerca sempre: il report è datato? Ci sono stati upgrade o modifiche dopo l’audit? Se sì, esiste un re-audit che copre le modifiche? Un protocollo che si vanta di audit del 2021 su codice che è stato modificato 10 volte da allora non offre le garanzie che sembra.
Bug bounty: il mercato della sicurezza continua
Un bug bounty è un programma che remunera chi trova e segnala responsabilmente le vulnerabilità invece di sfruttarle. Su Immunefi, il principale aggregatore di bug bounty crypto, i premi vanno da poche migliaia a milioni di dollari per vulnerabilità critiche. MakerDAO, Compound, Aave, Uniswap hanno tutti bug bounty con premi massimi sopra $1 milione.
L’esistenza di un bug bounty attivo e ben finanziato è un segnale positivo: indica che il team ha interesse economico a trovare i bug prima degli attaccanti, e che la community di security researcher ha incentivo a guardare il codice. Un protocollo con $500 milioni di TVL e nessun bug bounty sta scommettendo che i propri audit siano stati perfetti — una scommessa che storicamente ha un cattivo track record.
Monitoraggio continuo: non basta l’audit iniziale
La sicurezza di un protocollo non è statica. Nuovi blocchi vengono minati ogni pochi secondi; nuove transazioni interagiscono con i contratti in modi che nessun audit poteva prevedere completamente; aggiornamenti di governance cambiano i parametri. Il monitoraggio continuo è parte integrante della sicurezza.
Strumenti come Tenderly e Forta permettono di impostare alert su eventi specifici: una transazione insolita di grandi dimensioni verso un contratto che usi, un cambiamento del owner, l’attivazione di una funzione di emergenza. OpenZeppelin Defender offre una suite più completa per i team che gestiscono contratti in produzione.
Per gli utenti (non i team di sviluppo), il monitoraggio pratico è più semplice: segui i canali di allerta dei protocolli che usi (molti hanno bot Telegram o Discord per alert di sicurezza), imposta alert Etherscan via email per i contratti principali, e usa aggregatori di sicurezza come DeFi Safety o DefiWatch che segnalano exploit non appena vengono rilevati.
La velocità di reazione è critica in caso di exploit: i protocolli seri hanno procedure di incident response che includono pause di emergenza (circuit breaker). Ma come utente, avere un’allerta entro 30 minuti da un exploit ti dà il tempo di uscire prima che la situazione si deteriori ulteriormente — spesso la differenza tra recuperare il 90% e il 20% del valore.
Bug bounty: il mercato della sicurezza preventiva
I programmi di bug bounty rappresentano uno dei meccanismi più efficaci per la sicurezza preventiva degli smart contract. Piattaforme come Immunefi hanno distribuito oltre 100 milioni di dollari in ricompense a ricercatori indipendenti che hanno identificato vulnerabilità critiche prima che venissero sfruttate. Il costo di un bug bounty è quasi sempre inferiore al costo di un exploit non mitigato.
Conclusione
La sicurezza degli smart contract non è un problema risolto, ma è un problema gestibile. I bug più costosi della storia — reentrancy, oracle manipulation, upgrade malevoli — sono tutti prevenibili con pattern di design noti, audit di qualità e meccanismi di governance trasparenti. Come utente, il tuo ruolo è verificare che questi elementi esistano prima di fidarti di un contratto con il tuo capitale.



