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

Écran générique de vérification de contrat affichant Ethereum Mainnet, une adresse de contrat, la version du compilateur, le statut de vérification du code source et une correspondance exacte avec le 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

Fenêtre générique de revue de code source listant les fonctions Solidity publiques et externes à côté d'une implémentation de contrat de type 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

Terminal générique affichant la commande slither dot et les résultats concernant la réentrance, les appels de bas niveau non vérifiés et un problème d'interface 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 .

Enregistrez les résultats et triez-les par impact et niveau de confiance. Examinez attentivement les résultats concernant les envois de jetons arbitraires, les mises à niveau non protégées, la réentrance, les valeurs de retour non vérifiées, les appels délégués dangereux, l'origine des transactions (tx.origin), l'aléatoire faible et les interfaces incorrectes. Un détecteur peut générer un faux positif, manquer une faille économique spécifique au projet ou signaler du code intentionnellement contraint ailleurs. L'analyse statique affine la recherche ; elle ne remplace pas le raisonnement manuel. Le dépôt et la documentation de Slither répertorient également des outils d'impression pour les points d'entrée, l'autorisation, les graphes d'appels et les résumés de contrats, facilitant ainsi l'organisation de l'analyse.

Étape 4 : Tracer manuellement les appels externes et les réentrances

Fenêtre de revue de code générique mettant en évidence un appel de valeur de bas niveau avant une mise à jour de solde et une note de revue de réentrance de haute gravité
Un appel externe est mis en évidence avant une mise à jour du solde, illustrant la question de l'ordre que le réviseur doit vérifier dans chaque chemin de retrait.

Pour chaque appel externe, interrompez et suivez l'état du système avant, pendant et après l'appel. Le destinataire peut être un contrat malveillant, un jeton avec des hooks, un récepteur de rappel ou un autre protocole modifiant une dépendance partagée. La documentation de Solidity explique qu'une interaction avec un autre contrat peut lui en céder le contrôle et recommande le modèle « Vérifications-Effets-Interactions » : validez d'abord, mettez à jour l'état du contrat en second lieu, puis interagissez avec l'extérieur en dernier lieu.

Ne limitez pas la recherche aux transferts Ether évidents. Examinez les hooks de type ERC-777, les rappels ERC-1155, les rappels de prêts flash, les routeurs arbitraires, les appels d'oracle et les appels effectués via des bibliothèques héritées. Vérifiez la réentrance inter-fonctions et inter-contrats : un rappel peut entrer dans une autre fonction qui lit un état intermédiaire. Assurez-vous que chaque appel de bas niveau vérifie son résultat de succès et traite correctement la valeur de retour. Demandez-vous si un destinataire défaillant peut bloquer définitivement les retraits ou une boucle.

Consignez une séquence d'attaque concrète pour chaque problème plausible. Par exemple : l'attaquant effectue un dépôt, lance un retrait, reçoit une confirmation, effectue un second retrait, puis autorise la fin du premier. Si la séquence est impossible à reproduire en raison d'un invariant ou d'une mesure de sécurité spécifique, notez-en la raison. Ainsi, la conclusion sera vérifiable et non spéculative.

Étape 5 : Tester les invariants arithmétiques et commerciaux

Liste de contrôle d'audit générique présentant les vérifications des limites entières, de l'arrondi, des calculs du prix des actions et des cas limites de valeur nulle
Une liste de contrôle arithmétique et de logique métier met en évidence les cas limites que les tests ordinaires de scénario nominal omettent souvent.

Vérifiez la signification de chaque unité et conversion : wei et ether, décimales des jetons, points de base, actions et actifs, valeurs signées et unités de temps. Respectez le sens d’arrondi. Une division arrondie en faveur d’un déposant, d’un emprunteur, d’un liquidateur ou d’un bénéficiaire de frais peut entraîner une perte de valeur lors de sa répétition. Examinez la multiplication avant la division, les montants minimum et maximum, les plafonds de frais, les prix obsolètes, l’offre nulle, le solde nul et l’identité du premier déposant ou du dernier retrait.

Solidity 0.8 et versions ultérieures détectent normalement les dépassements de capacité arithmétiques (overflow et underflow), mais le code à l'intérieur d'un uncheckedbloc peut modifier délibérément ce comportement. Des opérations arithmétiques vérifiées peuvent également entraîner un dysfonctionnement du protocole ou le rendre inutilisable si les limites ne sont pas correctement définies. Il est important de tester les deux cas de figure : vol de données ou erreur de comptabilisation, et déni de service dû à une valeur impossible à traiter.

Rédigez les invariants en langage clair avant de les transformer en tests. Par exemple : « le nombre total d’actions correspond aux actifs selon la règle d’arrondi spécifiée », « un utilisateur ne peut pas retirer plus que le montant enregistré », « l’offre totale de jetons est égale à la somme des soldes lorsque ce modèle s’applique » et « les frais ne peuvent pas dépasser le plafond configuré ». Comparez les soldes de stockage avec les soldes réels de jetons, car ces derniers peuvent être envoyés directement à un contrat ou se comporter différemment de l’implémentation ERC-20 supposée.

Étape 6 : Examiner les autorisations et la possibilité de mise à niveau

Écran générique des autorisations et de la possibilité de mise à niveau affichant les rôles de propriétaire, d'administrateur, de mise en pause et de mise à niveau, ainsi qu'une relation entre le proxy et l'implémentation.
L’examen des privilèges doit associer chaque rôle à son adresse, aux actions autorisées, au processus de transfert et au chemin de mise à niveau.

Élaborez une matrice des privilèges. Pour chaque fonction administrative, identifiez le rôle requis, le détenteur actuel, le mécanisme de transfert, le délai, le contrôle de signature multiple ou de gouvernance, et le comportement en cas d'urgence. Portez une attention particulière à la création, la suspension, la modification des frais, le changement de source d'oracle, la récupération de fonds, la mise à jour du code et la modification des adresses des jetons de confiance ou des routeurs. La documentation d'OpenZeppelin sur le contrôle d'accès distingue la simple propriété des permissions basées sur les rôles et décrit le principe du moindre privilège comme une pratique de sécurité utile.

Distinguez les actions autorisées à un administrateur de celles qu'un utilisateur lambda peut effectuer. La première peut présenter un risque explicite de gouvernance ou de sécurité ; la seconde, une vulnérabilité d'autorisation. Vérifiez que les contrôles de rôle couvrent tous les chemins sensibles, y compris les fonctions internes accessibles depuis les fonctions publiques. Assurez-vous qu'un administrateur par défaut peut s'octroyer ou octroyer à d'autres des pouvoirs supplémentaires et que le transfert de propriété n'est pas susceptible d'être envoyé par erreur à une adresse inutilisable.

Pour les proxys, examinez l'initialiseur, l'autorisation d'implémentation, le délai de mise à jour, l'organisation du stockage et le plan de restauration ou d'urgence. Les recommandations d'OpenZeppelin concernant les contrats évolutifs expliquent pourquoi les constructeurs n'initialisent pas le stockage du proxy, pourquoi les initialiseurs doivent être protégés, pourquoi une implémentation ne doit pas rester non initialisée et pourquoi toute modification de l'ordre ou des types de stockage peut corrompre une mise à jour. Considérez la clé d'administration du proxy comme faisant partie intégrante du périmètre de sécurité du protocole, et non comme un détail d'implémentation.

Étape 7 : Tester le système avec du fuzzing, des invariants et des forks

Tableau de bord de test générique affichant les tests de fuzzing réussis, les tests d'invariants réussis et une séquence d'appels de contre-exemple
Les campagnes passées constituent une preuve utile, tandis qu'un contre-exemple permet de déterminer précisément quelle séquence nécessite une enquête.

Exécutez des tests unitaires pour vérifier le comportement attendu, puis ajoutez des tests de comportement négatif pour les appels non autorisés, les valeurs nulles, les valeurs maximales, les signatures expirées, les données d'oracle obsolètes, les transferts ayant échoué et les opérations répétées. Testez la robustesse des entrées plutôt que de vous limiter à quelques valeurs triées sur le volet. Intégrez plusieurs acteurs et des contrats de réception malveillants lorsque la conception permet les rappels.

Utilisez des tests d'invariance pour les propriétés qui doivent rester vraies après de nombreux appels aléatoires. La documentation de Foundry sur les tests d'invariance décrit les séquences aléatoires, les entrées fuzzées, les exécutions, la profondeur, les contrats cibles et les expéditeurs cibles. Configurez les gestionnaires pour que les appels soient pertinents ; si chaque dépôt fuzzé est annulé parce que l'acteur de test ne possède aucun jeton, un test d'invariance réussi peut simplement signifier qu'aucun état utile n'a changé.

Dans la mesure du possible, utilisez une copie du réseau cible pour tester les adresses déployées, la configuration actuelle, le comportement des jetons et le routage proxy. Conservez les tests de la copie en lecture seule, sauf si vous utilisez une copie locale isolée. Minimisez chaque séquence d'échec et préservez le contre-exemple, les adresses de l'appelant, le contexte des blocs, les soldes et les valeurs de stockage pertinentes. Un test réussi témoigne de la validité des chemins testés, mais ne prouve pas la validité de tous les chemins possibles.

Étape 8 : Écrire les résultats qui peuvent être corrigés et testés à nouveau

Rapport d'audit générique présentant les résultats par niveau de gravité, avec les statuts ouvert, corrigé et risque accepté, ainsi qu'une liste de contrôle pour les tests de réévaluation.
Un rapport utile établit un lien entre la gravité et l'état du problème, les preuves, une solution spécifique et les conditions d'un nouveau test.

Utilisez un enregistrement par problème. Une constatation pratique doit contenir :

  • Titre et emplacement : référence au contrat, à la fonction, au fichier et à la ligne ou au code.
  • Impact : ce qui peut être volé, gelé, gonflé, contourné ou rendu incorrect.
  • Prérequis : les autorisations, les soldes, le calendrier ou la configuration nécessaires.
  • Reproduction : une courte séquence de transactions, un test, une trace ou une preuve.
  • Recommandation : une modification spécifique du code ou du fonctionnement, avec des compromis à faire.
  • Statut : ouvert, corrigé, atténué, risque accepté ou non reproductible.
  • Retest : le test ou l’observation exacte qui confirme la résolution.

La gravité doit refléter l'impact réel et la vulnérabilité exploitable, et non l'apparence alarmante d'un schéma de code. Expliquez les hypothèses. Un appel de bas niveau peut être sûr grâce à un invariant fort ; une modification de paramètre apparemment anodine peut être critique si elle contrôle un oracle ou une mise à niveau. Après une correction, examinez les différences, relancez le test concerné, relancez la suite complète de tests et vérifiez l'absence de régressions. Si l'adresse déployée a déjà été mise à niveau ou modifiée, testez à nouveau l'implémentation et la configuration sur la blockchain.

Erreurs d'audit courantes à éviter

  • « La source est vérifiée, elle est donc sûre. » La vérification établit une correspondance entre la source et le bytecode ; elle ne valide pas la conception.
  • « Le scanner n'a rien détecté, il n'y a donc pas de bugs. » Les outils sont plus performants lorsqu'il s'agit de schémas connus, tandis que les failles économiques et les problèmes liés aux contrats croisés nécessitent souvent une analyse humaine.
  • « Le projet dispose d'un rapport d'audit, le déploiement actuel est donc couvert. » Comparez les informations du rapport concernant les commits, la portée, les adresses de déploiement, les correctifs et l'historique des mises à jour.
  • « Les tests de robustesse ont réussi, l'invariant est donc correct. » Il faut d'abord vérifier que l'invariant exprime bien la propriété économique attendue et que les gestionnaires atteignent des états significatifs.
  • « Le contrôle administratif ne pose pas de problème de sécurité. » Il s'agit peut-être d'une hypothèse de confiance intentionnelle, mais les utilisateurs devraient pouvoir voir qui peut créer, suspendre, modifier les paramètres ou effectuer une mise à niveau.

Dernière vérification avant de se fier au résultat

Vous devriez pouvoir répondre oui à ces questions :

  • Ai-je bien consigné la chaîne exacte, l'adresse, le bytecode, le proxy, l'implémentation et les paramètres de compilation ?
  • Ai-je recensé tous les points d'entrée susceptibles de modifier l'état de l'actif et les ressources qu'ils peuvent affecter ?
  • Ai-je effectué une compilation propre, examiné les avertissements et trié les résultats automatisés ?
  • Ai-je tracé chaque appel externe, chaque rappel, chaque appel de bas niveau et chaque chemin d'échec ?
  • Ai-je testé l'arrondi, les limites, les valeurs nulles, les données obsolètes et les actions répétées ?
  • Ai-je répertorié tous les rôles privilégiés, les clés, les délais, les initialiseurs et les chemins de mise à niveau ?
  • Ai-je préservé des nuances significatives et des contre-exemples invariants ?
  • Un examinateur indépendant peut-il reproduire chaque constat et vérifier chaque correction ?

Si la réponse est négative, indiquez que l'audit est incomplet et précisez les éléments manquants. Une limitation claire est plus utile qu'une conclusion vague de « sécurité ». La sécurité des contrats intelligents est un processus continu : chaque mise à jour, modification de dépendance, nouvelle intégration et changement de privilège peut créer un nouveau périmètre d'audit.

Laisser un commentaire

Gestion du risque de votre portefeuille crypto : comment répartir vos actifs

Gestion du risque de votre portefeuille crypto : comment répartir vos actifs

Apprenez à répartir vos cryptomonnaies en fonction de votre tolérance au risque, de votre horizon temporel, de votre diversification, de la conservation de vos actifs, de votre liquidité et de votre rééquilibrage, sans vous fier à une formule unique.

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.

Le guide ultime pour constituer un portefeuille de cryptomonnaies à long terme

Le guide ultime pour constituer un portefeuille de cryptomonnaies à long terme

Constituez un portefeuille de cryptomonnaies à long terme avec un cadre axé sur la gestion des risques pour l'allocation, la sélection des actifs, la conservation, la discipline d'achat, le rééquilibrage, la tenue des registres et la prévention des arnaques.

Analyse on-chain pour débutants : Comment suivre les portefeuilles des baleines et les investisseurs avertis

Analyse on-chain pour débutants : Comment suivre les portefeuilles des baleines et les investisseurs avertis

Apprenez à lire les données de la blockchain, à suivre les portefeuilles des baleines, à évaluer les labels de monnaie intelligente et à distinguer les faits vérifiables de la blockchain des inférences avant d'agir sur l'activité des portefeuilles.

"Insufficient Margin" Error in Crypto Futures: What It Means and How to Resolve It

"Insufficient Margin" Error in Crypto Futures: What It Means and How to Resolve It

Learn why crypto futures platforms show an “Insufficient Margin” error, how to diagnose the cause, fix it safely, and avoid margin problems before placing your next trade.

Binance Launchpad et Launchpool : Comment participer et gagner de nouveaux tokens

Binance Launchpad et Launchpool : Comment participer et gagner de nouveaux tokens

Découvrez le fonctionnement de Binance Launchpad et Launchpool, comment vérifier votre éligibilité, vous inscrire en toute sécurité, suivre vos récompenses et comprendre les limites et les risques.

Erreur « Tolérance de glissement dépassée » sur les CEX et DEX : comment la corriger

Erreur « Tolérance de glissement dépassée » sur les CEX et DEX : comment la corriger

Découvrez ce que signifie « dépassement de la tolérance de glissement » sur les CEX et les DEX, comment vérifier si une transaction a échoué et quand actualiser, réduire la taille, utiliser un ordre à cours limité ou ajuster la tolérance.

Bybit Copy Trading : Comment suivre et copier les traders crypto les plus performants

Bybit Copy Trading : Comment suivre et copier les traders crypto les plus performants

Découvrez le fonctionnement du copy trading avec Bybit, comment évaluer les Master Traders, définir les paramètres de copie, gérer les risques et surveiller les transactions perpétuelles USDT copiées.

Comprendre la tokenomics : comment l’offre et la demande influencent le prix d’une cryptomonnaie

Comprendre la tokenomics : comment l’offre et la demande influencent le prix d’une cryptomonnaie

Découvrez comment l'offre, la demande, les déblocages, les émissions, les destructions et l'utilité des jetons peuvent affecter le prix d'une cryptomonnaie, et ce que la tokenomics ne peut pas prédire.

Comment analyser le volume d'échanges pour confirmer une hausse soudaine du cours des cryptomonnaies ?

Comment analyser le volume d'échanges pour confirmer une hausse soudaine du cours des cryptomonnaies ?

Apprenez à comparer le volume des cryptomonnaies à sa valeur de référence, à confirmer les ruptures de prix, à repérer les essoufflements de la dynamique et à éviter de confondre un pic manipulé avec une force haussière.