﻿---
title: "Come leggere un audit di smart contract"
description: "Un audit di smart contract è una revisione delimitata di codice, build, deployment, ipotesi e proprietà specifici; risultati e correzioni vanno riconciliati con il sistema live."
image: "https://wiki.fcontext.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://wiki.fcontext.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Come leggere un audit di smart contract

> Solo a scopo educativo; non costituisce consulenza né raccomandazione d’investimento. Gli investimenti possono comportare perdite.

<a id="answer"></a>

## Risposta diretta

Un audit esamina in un periodo dichiarato requisiti, codice sorgente, input di build, logica di deployment e ipotesi di sicurezza specifici. Metodi complementari identificano difetti, dimostrano percorsi di exploit, valutano l'impatto e verificano le correzioni. La conclusione vale solo per lo snapshot e le prove descritti.

Lo snapshot fissa repository, commit o tree hash, submodule, dipendenze, compilatore, impostazioni, codice generato, script, chain, indirizzi, proxy, implementazione o beacon, dati di constructor o initializer, librerie, amministratori, timelock e blocco o ora. Le esclusioni contano: frontend, keeper, oracle, bridge, governance o firmatario off-chain possono dominare il rischio restando fuori audit.

Servono threat model e specifica: asset, attori, ruoli privilegiati, confini di fiducia, capacità, ordinamento e reorg, dipendenze, transizioni e proprietà precise di safety e liveness. Un invariante senza unità, precondizioni, quantificatori ed eccezioni può verificare perfettamente il comportamento sbagliato.

Usare quattro registri: identità di ambito, build e deployment; requisiti, minacce e invarianti; risultati, prove e retest; rischio residuo, accettazione e disclosure. Nessun `critical` non certifica la sicurezza, `resolved` non significa distribuito e una prova copre solo proprietà, modello e ipotesi codificati.

<a id="mechanism"></a>

## Come funziona

La revisione manuale segue architettura, fondi, stato tra funzioni e intento economico. L'analisi statica trova pattern ma produce falsi positivi e negativi. Test unitari, di integrazione, fork e differenziali confrontano casi concreti. Fuzzing stateful e test d'invariante dipendono da handler, selettori, seed, corpus, run, profondità e ambiente modellato.

Esecuzione simbolica e verifica formale dimostrano asserzioni selezionate sotto semantiche e ipotesi supportate. `unknown`, timeout o comportamento non supportato non sono prove. Anche una proprietà dimostrata può omettere economia dell'oracle, governance, configurazione o requisito voluto. La revisione umana governa specifica e interpretazione; un'osservazione IA non è un metodo autonomo.

Ogni risultato indica artefatto e deployment, prerequisito, prova minima, percorso, raggiungibilità, privilegi, capitale, ripetibilità, impatto, metodo di gravità e raccomandazione. Sfruttabilità o probabilità e impatto sono distinti. Massimo teorico, nome o etichetta di tool non stabiliscono una perdita eseguibile.

`open`, `acknowledged`, `risk accepted`, `partially fixed`, `resolved` e `retested` non sono standard universali. Una chiusura difendibile collega il problema al commit esatto e documenta percorsi adiacenti, chi ha ritestato cosa e quando. Il rischio accettato resta rischio; un retest limitato non amplia l'ambito.

I deployment aggiornabili richiedono riconciliazione di slot proxy, implementazione o beacon e admin; initializer/reinitializer, blocco dell'implementazione, compatibilità storage, autorizzazione, timelock o bypass, migrazione e rollback. Si riproducono bytecode creation e runtime e si confrontano librerie, parametri, ruoli e stato su ogni chain.

Il rapporto finale indica revisione, auditor, date, ambito, metodi, configurazioni, limiti, risultati, prove, stato, rischi e disclosure. Poi si monitorano hash, ruoli, parametri, dipendenze e incidenti. Ogni modifica materiale crea un nuovo delta; un badge vecchio non segue il codice futuro.

Procedura:

1. Congelare manifesto con repository, commit, dipendenze, compilatore, impostazioni, codice generato e di deployment, chain, indirizzi, stack proxy, parametri, blocco, revisione, inclusioni ed esclusioni.
2. Definire asset, attori, ruoli, confini, capacità, ciclo di vita, ordinamento, liveness, dipendenze e invarianti misurabili.
3. Riprodurre la build; mappare architettura, storage, dati, fondi e controllo; riconciliare sorgente, artefatti, librerie, bytecode, initializer, ruoli e deployment.
4. Eseguire metodi manuali, statici, unitari, integrazione, fork, differenziali, fuzz, invarianti, simbolici o formali registrando versioni, configurazioni, seed, corpus, coverage, timeout e incognite.
5. Registrare artefatto, prerequisito, prova, sfruttabilità, impatto, gravità, esposizione, raccomandazione ed evidenza riservata senza scambiare l'etichetta per giudizio.
6. Congelare il fix e ritestare problema, percorsi e invarianti; validare storage, inizializzazione, migrazione, rollback, build e ricevute prima dello status.
7. Pubblicare ambito, metodi, limiti e rischi; riconciliare artefatti con ogni chain e mantenere aggiornati monitoraggio, disclosure, risposta e bug bounty.

<a id="example"></a>

## Esempi

- **L'inflazione di un vault richiede un registro completo.** L'attaccante deposita `1 asset`, riceve `1 share`, dona `1,000,000 assets`; restano `1,000,001 assets` e `1 share`. La vittima deposita `500,000 assets`; l'arrotondamento dà `floor(500,000 * 1 / 1,000,001) = 0 shares`. Se accettato, il vault ha `1,500,001 assets`; l'attaccante recupera `500,000 assets` oltre il proprio contributo di `1,000,001-asset`. Un revert su zero shares blocca questo percorso.
- **Copertura dei file non è copertura del deployment.** Manifesto: `24 source units`, `4 deployment scripts`, `3 keeper services`, cioè `31 items`. Inclusi `20 source units` e `2 scripts`: `22 / 31 = 70.96774194%`; esclusi `9 items`. Se il proxy usa un'unità esclusa, copertura live `0%` nonostante `70.96774194%`.
- **Il fuzzing non prova assenza.** Run: `2,000 sequences * 64 calls = 128,000 calls`; falliscono `3 sequences`, cioè `3 / 2,000 = 0.15%`. Dopo il fix: `10,000 sequences * 64 calls = 640,000 calls`, zero fallimenti. Con ipotesi didattiche, limite superiore approssimativo `95%`: `3 / 10,000 = 0.03%` per sequenza, non una prova.
- **Chiusura e identità sono indipendenti.** `12 findings`: `2 critical`, `3 high`, `4 medium`, `3 low`. Chiusi `2 + 2 + 3 + 2 = 9`: `9 / 12 = 75%`; restano high, medium e low. Audit `H1`, live `H2`: verifica fallita. Esatto `H1` più slot, initializer e ruoli prova identità solo al blocco.

<a id="risks"></a>

## Rischi

- Repository, commit, submodule o sorgente generato sono ambigui.
- Compilatore, optimizer, librerie o dipendenze non sono fissati.
- Script, constructor, initializer o salt CREATE2 sono esclusi.
- Si ispeziona chain, indirizzo, proxy, beacon o implementazione errati.
- Sorgente, artefatto e bytecode non coincidono.
- Il threat model omette attore, privilegio, asset o confine.
- Specifica o invariante ha unità, precondizioni o eccezioni errate.
- Percorsi admin, guardian, timelock, pausa, upgrade o migrazione sono omessi.
- Falliscono ipotesi su oracle, token, bridge, keeper, governance o chain.
- L'analisi statica produce falso positivo non valutato.
- Revisione, test o fuzzing omettono un percorso.
- Harness, selettore, seed, corpus, profondità o modello sono distorti.
- Timeout, semantica non supportata o `unknown` sono scambiati per prova.
- Prova corretta formalizza requisito o sistema incompleto.
- La gravità segue il nome anziché sfruttabilità e impatto.
- Valore teorico è confuso con perdita raggiungibile o profitto.
- Il fix introduce regressione o rompe un invariante economico.
- Storage, initializer, upgrade o migrazione corrompono lo stato.
- Problema accettato, aperto o parziale è nascosto dal badge.
- Rapporto è trattato come assicurazione, certificazione o copertura permanente.

<a id="misconceptions"></a>

## Errori comuni

- **«Senza critical il contratto è sicuro».** Descrive solo risultati entro ambito, tempo e metodi.
- **«Coverage alta o zero errori fuzz provano assenza».** Misurano codice e percorsi selezionati.
- **«La verifica formale prova tutto il protocollo».** Prova proprietà del modello sotto ipotesi.
- **«Resolved significa tutti i deployment corretti».** Servono retest e riconciliazione di build, bytecode, proxy, parametri e ruoli.
- **«Un auditor noto garantisce risarcimento o upgrade».** La responsabilità dipende dal contratto; modifiche future restano fuori.

<a id="related"></a>

## Argomenti correlati

- [Smart contract](/it/crypto/smart-contract/)
- [Contratto aggiornabile](/it/crypto/upgradeable-contract/)
- [Bug bounty](/it/crypto/bug-bounty/)

<a id="sources"></a>

## Fonti

- [OWASP Smart Contract Security Verification Standard (SCSVS)](https://scs.owasp.org/SCSVS/) - OWASP (consultato: 2026-08-13)
- [Security Considerations](https://docs.soliditylang.org/en/latest/security-considerations.html) - Solidity (consultato: 2026-08-13)
- [Slither, the smart contract static analyzer](https://github.com/crytic/slither) - Crytic (consultato: 2026-08-13)
- [Invariant Testing](https://www.getfoundry.sh/guides/invariant-testing) - Foundry (consultato: 2026-08-13)
- [Certora User's Guide](https://docs.certora.com/en/latest/docs/user-guide/index.html) - Certora (consultato: 2026-08-13)
- [ERC-1967: Proxy Storage Slots](https://eips.ethereum.org/EIPS/eip-1967) - Ethereum Improvement Proposals (consultato: 2026-08-13)
- [Writing Upgradeable Contracts](https://docs.openzeppelin.com/upgrades-plugins/writing-upgradeable) - OpenZeppelin (consultato: 2026-08-13)
- [Contract Metadata](https://docs.soliditylang.org/en/latest/metadata.html) - Solidity (consultato: 2026-08-13)

Source: https://wiki.fcontext.com/it/crypto/contract-audit/index.mdx
