A Step-by-Step Guide to Auditing a Crypto Project's Smart Contract

A smart-contract audit is a structured attempt to discover how a contract can fail, be misused, or be controlled in a way users did not expect. It is not the same as running one scanner, reading an audit badge, or confirming that source code is verified. Use the workflow below to review a deployed EVM contract or a codebase before you trust it with meaningful funds.

Important: This is a practical review framework, not a guarantee that a project is safe and not investment advice. A production protocol holding substantial value should receive an independent review by experienced security professionals. The interface-style images in this guide are illustrative and should not be treated as evidence about any particular project or deployment.

Audit checklist at a glance

StepPrimary questionUseful evidence
1. ScopeAm I reviewing the exact contract that users call?Address, chain, bytecode, proxy and implementation
2. Entry pointsWhat can each caller do?Public/external functions, state changes, call graph
3. AutomationWhat obvious patterns deserve attention?Compiler output, Slither findings, detector triage
4. Manual securityCan a call sequence break assumptions?External calls, reentrancy, callbacks, failure handling
5. LogicDoes the accounting remain correct at edge cases?Arithmetic, rounding, fees, limits, state transitions
6. PrivilegesWho can change or stop the system?Roles, owner, admin keys, proxy, initializer
7. TestingDoes behavior hold across unexpected inputs and sequences?Unit, fuzz, invariant and fork tests
8. ReportingCan another person reproduce and retest the result?Finding, impact, evidence, fix and retest status

Step 1: Confirm the scope and the deployed artifact

Schermata generica di verifica del contratto che mostra la rete principale di Ethereum, l'indirizzo del contratto, la versione del compilatore, lo stato di verifica della sorgente e una corrispondenza esatta del bytecode.
A contract verification view showing the network, address, compiler version, and bytecode-match checks to record before analysis.

Start with the exact chain and address. Record the deployment address, transaction hash, block number, compiler version, optimizer settings, constructor arguments, and the commit or release that the team says is deployed. A project may have several addresses for a token, router, vault, proxy, implementation, oracle, or test deployment. A review of the wrong address has no practical value.

Check whether the explorer’s verified source reproduces the deployed bytecode. Verification is useful because it lets you inspect source and ABI, but it is only an identity check: it does not prove that the business logic is safe. If the contract is upgradeable, identify both the proxy and its current implementation. Read the implementation address from the proxy’s documented mechanism or explorer information, then confirm that the implementation is the one you intend to review. Etherscan’s official Foundry verification guide documents verification for new and existing contracts.

Also define the boundary. Include imported libraries, inherited contracts, linked libraries, deployed helper contracts, oracle adapters, tokens received from users, and privileged off-chain components. Write down what is out of scope and why. This prevents a narrow review from being mistaken for a review of the complete system.

Step 2: Build an entry-point and asset map

Finestra di revisione generica del codice sorgente che elenca le funzioni Solidity pubbliche ed esterne, accanto a un'implementazione di contratto in stile ERC-20.
A function inventory that separates public and external entry points before the reviewer traces their state changes.

List every public and external function, including inherited functions and fallback or receive handlers. For each one, record whether it can:

  • move native currency or tokens;
  • mint, burn, borrow, liquidate, or alter accounting;
  • change an oracle, fee, limit, role, pause state, or implementation;
  • make an external call, delegatecall, or low-level call; or
  • read data that another state-changing function relies on.

Then map the assets and trust boundaries. Follow a deposit from the user into storage, through pricing and share calculation, to withdrawal. Identify every address supplied by a caller and every address loaded from storage. Ask which values are assumed to be honest: an oracle, a token, a bridge message, a keeper, a callback receiver, or an administrator. The highest-value review targets are functions that combine user-controlled input, privileged state, arithmetic, and an external call.

Step 3: Compile cleanly and run static analysis

Terminale generico che mostra il comando slither dot e i risultati relativi a reentrancy, chiamate di basso livello non controllate e un problema di interfaccia ERC-20
A static-analysis run can quickly surface candidate issues, which must still be confirmed against the actual code and threat model.

Reproduce the project’s build with the stated Solidity version, dependency versions, optimizer configuration, and target chain assumptions. Treat compiler warnings as review items rather than harmless noise. Solidity’s security considerations specifically recommend taking warnings seriously, keeping contracts understandable, and checking known compiler issues. Consult the official list of known Solidity compiler bugs when the compiler version or affected code patterns make it relevant.

For a Hardhat, Foundry, or similar project, run Slither from the project root. Its official documentation describes the tool as a Solidity and Vyper static analyzer and gives the common command:

slither .

Salva l'output e classifica ogni risultato in base all'impatto e all'affidabilità. Esamina attentamente i risultati relativi a invii arbitrari di token, aggiornamenti non protetti, rientranza, valori di ritorno non controllati, delegatecall pericolosi, tx.origin, casualità debole e interfacce errate. Un rilevatore può segnalare un falso positivo, non individuare un difetto economico specifico del progetto o segnalare codice che è intenzionalmente vincolato altrove. L'analisi statica restringe la ricerca, ma non sostituisce il ragionamento manuale. Il repository e la documentazione di Slither elencano anche i printer per i punti di ingresso, l'autorizzazione, i grafici delle chiamate e i riepiloghi dei contratti che aiutano a organizzare una revisione.

Passaggio 4: Tracciamento manuale delle chiamate esterne e del rientro

Finestra di revisione del codice generica che evidenzia una chiamata di valore di basso livello prima di un aggiornamento del saldo e una nota di revisione della rientranza ad alta gravità
Una chiamata esterna viene evidenziata prima di un aggiornamento del saldo, illustrando la questione dell'ordine che un revisore dovrebbe verificare in ogni percorso di prelievo.

Per ogni chiamata esterna, interrompi e traccia lo stato prima, durante e dopo la chiamata. Il destinatario della chiamata potrebbe essere un contratto dannoso, un token con hook, un ricevitore di callback o un altro protocollo che modifica una dipendenza condivisa. La documentazione di Solidity spiega che un'interazione con un altro contratto può trasferire il controllo a tale contratto e raccomanda il modello Controlli-Effetti-Interazioni: convalida prima, aggiorna lo stato di questo contratto in secondo luogo e interagisci esternamente per ultimo.

Non limitare la ricerca ai soli trasferimenti Ether. Verifica gli hook in stile ERC-777, i callback ERC-1155, i callback flash-loan, i router arbitrari, le chiamate oracle e le chiamate effettuate tramite librerie ereditate. Esamina la rientranza tra funzioni e tra contratti: un callback può entrare in una funzione diversa che legge uno stato intermedio. Conferma che ogni chiamata di basso livello controlli il risultato positivo e gestisca correttamente il valore restituito. Chiedi se un destinatario non riuscito può bloccare in modo permanente i prelievi o un ciclo.

Per ogni possibile problema, è necessario documentare una sequenza di attacco concreta. Ad esempio: l'attaccante effettua un deposito, avvia un prelievo, riceve una chiamata di conferma, avvia un secondo prelievo e solo a quel punto consente il completamento della prima chiamata. Se la sequenza non può essere eseguita a causa di un invariante o di una condizione di sicurezza specifica, è necessario annotare tale motivo. In questo modo, la conclusione risulterà verificabile anziché speculativa.

Passaggio 5: Verifica degli invarianti aritmetici e aziendali

Lista di controllo generica per la verifica dei dati, che include controlli sui limiti degli interi, arrotondamenti, calcoli relativi al prezzo delle azioni e casi limite con valore zero.
Una checklist aritmetica e di logica aziendale evidenzia i casi limite che i normali test di tipo "happy-path" spesso omettono.

Verifica il significato di ogni unità e conversione: wei rispetto a ether, decimali dei token, punti base, azioni rispetto ad attività, valori con segno e unità di tempo. Segui la direzione di arrotondamento. Una divisione che arrotonda a favore di un depositante, un mutuatario, un liquidatore o un beneficiario di commissioni può comportare una perdita di valore se ripetuta. Rivedi la moltiplicazione prima della divisione, gli importi minimi e massimi, i limiti delle commissioni, i prezzi non aggiornati, l'offerta zero, il saldo zero e il primo depositante o l'ultimo prelevatore.

Solidity 0.8 e versioni successive normalmente rilevano overflow e underflow aritmetici, ma il codice all'interno di un uncheckedblocco modifica deliberatamente questo comportamento. L'aritmetica controllata può anche causare il ripristino di un protocollo o renderlo inutilizzabile se i limiti non sono progettati correttamente. Testare entrambi gli esiti: furto o contabilizzazione errata e negazione del servizio causata da un valore che non può essere elaborato.

Scrivi gli invarianti in linguaggio semplice prima di trasformarli in test. Esempi includono "il numero totale di azioni corrisponde agli asset secondo la regola di arrotondamento indicata", "un utente non può prelevare più di quanto richiesto", "la fornitura totale di token è pari alla somma dei saldi laddove si applichi tale modello" e "una commissione non può superare il limite configurato". Confronta i saldi di archiviazione con i saldi effettivi dei token, poiché i token possono essere inviati direttamente a un contratto o possono comportarsi in modo diverso dall'implementazione ERC-20 ipotizzata.

Passaggio 6: Esaminare le autorizzazioni e la possibilità di aggiornamento

Schermata generica di autorizzazioni e aggiornabilità che mostra i ruoli di proprietario, amministratore, utente in pausa, utente in aggiornamento e la relazione tra proxy e implementazione.
La revisione dei privilegi dovrebbe collegare ciascun ruolo al suo indirizzo, alle azioni consentite, al processo di trasferimento e al percorso di avanzamento.

Crea una matrice dei privilegi. Per ogni funzione amministrativa, identifica il ruolo richiesto, il titolare attuale, il meccanismo di trasferimento, il ritardo, il controllo multifirma o di governance e il comportamento di emergenza. Presta particolare attenzione alla creazione, alla sospensione, alla modifica delle commissioni, alla modifica delle fonti oracolo, al recupero dei fondi, all'aggiornamento del codice e alla modifica degli indirizzi di token o router attendibili. La documentazione di OpenZeppelin sul controllo degli accessi distingue la semplice proprietà dalle autorizzazioni basate sui ruoli e descrive il principio del minimo privilegio come una pratica di sicurezza utile.

Distinguere tra "il codice consente a un amministratore di fare ciò" e "un utente qualsiasi può fare ciò". Il primo caso può rappresentare un rischio esplicito di governance o di custodia; il secondo una vulnerabilità di autorizzazione. Verificare che i controlli dei ruoli coprano ogni percorso sensibile, inclusi gli helper interni raggiungibili da funzioni pubbliche. Controllare se un amministratore predefinito può concedere a sé stesso o ad altri poteri aggiuntivi e se il trasferimento di proprietà può essere inviato accidentalmente a un indirizzo inutilizzabile.

Per i proxy, esaminare l'inizializzatore, l'autorizzazione all'implementazione, il ritardo di aggiornamento, la struttura di archiviazione e il piano di rollback o di emergenza. La guida di OpenZeppelin sui contratti aggiornabili spiega perché i costruttori non inizializzano l'archiviazione del proxy, perché gli inizializzatori devono essere protetti, perché un'implementazione non dovrebbe rimanere non inizializzata e perché la modifica dell'ordine o dei tipi di archiviazione può compromettere un aggiornamento. Considerare la chiave di amministrazione del proxy come parte del perimetro di sicurezza del protocollo, non come un dettaglio di implementazione.

Passaggio 7: Testare il sistema con fuzzing, invarianti e fork

Dashboard di test generica che mostra i test di fuzzing superati, i test di invarianza superati e una sequenza di chiamate di controesempio.
Le campagne di passaggio costituiscono una prova utile, mentre una traccia di controesempio mostra esattamente quale sequenza necessita di indagine.

Esegui test unitari per il comportamento previsto, quindi aggiungi test negativi per chiamanti non autorizzati, valori zero, valori massimi, firme scadute, dati oracolo obsoleti, trasferimenti falliti e operazioni ripetute. Esegui test di fuzzing sugli input anziché testare solo pochi numeri selezionati manualmente. Includi più attori e contratti di ricezione malevoli laddove la progettazione consenta le callback.

Utilizzate test di invarianza per le proprietà che devono rimanere vere dopo numerose chiamate casuali. La documentazione di Foundry sui test di invarianza descrive sequenze casuali, input fuzzeggiati, esecuzioni, profondità, contratti target e mittenti target. Configurate i gestori in modo che le chiamate siano significative; se ogni deposito fuzzeggiato viene annullato perché l'attore di test non ha token, un invariante superato potrebbe semplicemente significare che non è cambiato alcuno stato utile.

Quando possibile, utilizzare una fork della rete di destinazione per testare gli indirizzi distribuiti, la configurazione corrente, il comportamento dei token e il routing proxy. Mantenere i test della fork al sicuro e in sola lettura, a meno che non si utilizzi una fork locale isolata. Ridurre al minimo ogni sequenza di errore e conservare il controesempio, gli indirizzi del chiamante, il contesto del blocco, i saldi e i valori di archiviazione pertinenti. Un test superato fornisce una prova dei percorsi testati, non la prova di tutti i percorsi possibili.

Passaggio 8: Scrivere i risultati che possono essere corretti e ritestati

Report di audit generico che mostra i risultati in base alla gravità con stato aperto, risolto e rischio accettato, oltre a una lista di controllo per la ripetizione del test.
Un rapporto utile collega la gravità e lo stato del problema alle prove, a una soluzione specifica e alle condizioni per un nuovo test.

Utilizzare un record per ogni problema. Un riscontro pratico dovrebbe contenere:

  • Titolo e posizione: contratto, funzione, file e riferimento di riga o codice.
  • Impatto: cosa può essere rubato, congelato, gonfiato, aggirato o reso errato.
  • Prerequisito: autorizzazioni, saldi, tempistiche o configurazione necessari.
  • Riproduzione: una breve sequenza di transazioni, un test, una traccia o una prova.
  • Raccomandazione: una modifica specifica al codice o alle procedure operative, con i relativi compromessi.
  • Stato: aperto, risolto, mitigato, rischio accettato o non riproducibile.
  • Ritest: il test o l'osservazione esatta che conferma la risoluzione.

La gravità dovrebbe riflettere l'impatto reale e la sfruttabilità, non quanto allarmante possa sembrare uno schema di codice. Spiegare le ipotesi. Una chiamata di basso livello potrebbe essere sicura grazie a un invariante forte; una modifica di parametro apparentemente ordinaria potrebbe essere critica se controlla un oracolo o un aggiornamento. Dopo una correzione, esaminare le differenze, rieseguire il test pertinente, rieseguire l'intera suite e verificare la presenza di regressioni. Se l'indirizzo distribuito è già stato aggiornato o modificato, ritestare l'implementazione e la configurazione on-chain effettive.

Errori comuni da evitare durante le verifiche contabili.

  • "La fonte è verificata, quindi è sicura." La verifica stabilisce la corrispondenza tra il codice sorgente e il bytecode; non convalida il progetto.
  • "Lo scanner non ha rilevato nulla, quindi non ci sono bug." Gli strumenti sono più efficaci nell'individuare schemi noti, mentre le falle economiche e quelle relative a contratti incrociati spesso richiedono un'analisi umana.
  • "Il progetto dispone di un report di audit, quindi l'implementazione corrente è coperta." Confronta il report con i commit, l'ambito, gli indirizzi di implementazione, le correzioni e la cronologia degli aggiornamenti.
  • "I test di fuzzing sono stati superati, quindi l'invariante è corretto." Innanzitutto, verificare che l'invariante esprima la proprietà economica prevista e che i gestori raggiungano stati significativi.
  • "Il controllo amministrativo non è un problema di sicurezza." Potrebbe trattarsi di un presupposto di fiducia intenzionale, ma gli utenti dovrebbero essere in grado di vedere chi può coniare criptovalute, sospenderle, modificarne i parametri o effettuare l'aggiornamento.

Verifica finale prima di fidarsi del risultato.

Dovresti essere in grado di rispondere di sì a queste domande:

  • Ho registrato con precisione la catena, l'indirizzo, il bytecode, il proxy, l'implementazione e le impostazioni di compilazione?
  • Ho inventariato ogni punto di ingresso che modifica lo stato e le risorse che può influenzare?
  • Ho compilato correttamente, esaminato gli avvisi e analizzato i risultati automatici?
  • Ho tracciato ogni chiamata esterna, ogni callback, ogni chiamata di basso livello e ogni percorso di errore?
  • Ho testato l'arrotondamento, i limiti, i valori zero, i dati obsoleti e le azioni ripetute?
  • Ho mappato tutti i ruoli privilegiati, le chiavi, i ritardi, gli inizializzatori e i percorsi di aggiornamento?
  • Ho preservato la sfocatura significativa e i controesempi invarianti?
  • Un revisore indipendente è in grado di riprodurre ciascun risultato e verificare ciascuna soluzione?

Se una qualsiasi risposta è negativa, contrassegnare l'audit come incompleto e indicare le prove mancanti. Una limitazione trasparente è più utile di una vaga conclusione di "sicurezza". La sicurezza degli smart contract è un processo continuo: ogni aggiornamento, modifica delle dipendenze, nuova integrazione e modifica dei privilegi può creare un nuovo limite di revisione.

Lascia un commento

Gestione del rischio del portafoglio di criptovalute: come allocare le proprie risorse

Gestione del rischio del portafoglio di criptovalute: come allocare le proprie risorse

Impara come allocare le criptovalute in base alla tolleranza al rischio, all'orizzonte temporale, alla diversificazione, alla custodia, alla liquidità e al ribilanciamento, senza affidarti a una formula universale.

A Step-by-Step Guide to Auditing a Crypto Project's Smart Contract

A Step-by-Step Guide to Auditing a Crypto Project's Smart Contract

Learn how to audit a crypto project’s smart contract step by step, from verifying the deployment and mapping permissions to testing logic, upgrades, and fixes.

La guida definitiva per costruire un portafoglio di criptovalute a lungo termine

La guida definitiva per costruire un portafoglio di criptovalute a lungo termine

Costruisci un portafoglio di criptovalute a lungo termine con un approccio incentrato sul rischio per l'allocazione, la selezione degli asset, la custodia, la disciplina negli acquisti, il ribilanciamento, la tenuta dei registri e la prevenzione delle frodi.

Analisi on-chain per principianti: come tracciare i portafogli delle balene e il denaro intelligente

Analisi on-chain per principianti: come tracciare i portafogli delle balene e il denaro intelligente

Impara a leggere i dati on-chain, a tracciare i portafogli delle balene, a valutare le etichette delle criptovalute e a distinguere i fatti verificabili della blockchain dalle deduzioni prima di agire in base all'attività del portafoglio.

Errore di "margine insufficiente" nei future sulle criptovalute: cosa significa e come risolverlo

Errore di "margine insufficiente" nei future sulle criptovalute: cosa significa e come risolverlo

Scopri perché le piattaforme di future sulle criptovalute mostrano un errore di "Margine insufficiente", come diagnosticarne la causa, risolverlo in modo sicuro ed evitare problemi di margine prima di effettuare la tua prossima operazione.

Binance Launchpad e Launchpool: come partecipare e guadagnare nuovi token

Binance Launchpad e Launchpool: come partecipare e guadagnare nuovi token

Scopri come funzionano Binance Launchpad e Launchpool, come verificare i requisiti di idoneità, come partecipare in sicurezza, come monitorare i premi e come comprendere i limiti e i rischi.

Errore "Slippage Tolerance Exceeded" su CEX e DEX: come risolverlo

Errore "Slippage Tolerance Exceeded" su CEX e DEX: come risolverlo

Scopri cosa significa "tolleranza di slippage superata" sui CEX e DEX, come verificare se un'operazione è fallita e quando aggiornare la pagina, ridurre la dimensione della posizione, utilizzare un ordine limite o regolare la tolleranza.

Bybit Copy Trading: Come seguire e copiare i trader di criptovalute più performanti

Bybit Copy Trading: Come seguire e copiare i trader di criptovalute più performanti

Scopri come funziona Bybit Copy Trading, come valutare i Master Trader, impostare i parametri di copia, gestire il rischio e monitorare le operazioni perpetue su USDT copiate.

Comprendere la tokenomics: come domanda e offerta influenzano il prezzo di una moneta

Comprendere la tokenomics: come domanda e offerta influenzano il prezzo di una moneta

Scopri come l'offerta, la domanda, gli sblocchi, le emissioni, i burn e l'utilità dei token possono influenzare il prezzo di una criptovaluta e cosa la tokenomics non può prevedere.

Come analizzare il volume di scambi per confermare un pump di criptovalute

Come analizzare il volume di scambi per confermare un pump di criptovalute

Impara a confrontare il volume delle criptovalute con il suo livello di riferimento, a confermare le rotture di prezzo, a individuare i segnali di cedimento e ad evitare di confondere un picco manipolato con un segno di forza.