Aller au contenu

Contrat intelligent évolutif

Un contrat intelligent évolutif conserve l'adresse et l'état d'un proxy tandis que des acteurs autorisés remplacent ou redirigent son implémentation. Cette souplesse ajoute des risques de stockage, d'initialisation, de gouvernance et de suivi.

Mis à jour

À des fins éducatives uniquement ; ne constitue ni un conseil en investissement ni un conseil de sécurité. L’évolutivité peut permettre à des acteurs privilégiés de modifier le comportement du contrat et entraîner des pertes.

Réponse directe

Un contrat intelligent évolutif est un système déployé dont la logique effective peut changer sans déplacer les utilisateurs vers une nouvelle adresse principale ni abandonner l’état qui y est conservé. Sur les réseaux compatibles avec Ethereum, un proxy détient généralement l’état et transmet les appels par delegatecall à un contrat d’implémentation. Une mise à niveau autorisée change l’implémentation, tandis que l’adresse, le stockage et le solde du proxy restent en place.

Le bytecode immuable n’est pas réécrit : une couche d’indirection précède l’application. Elle permet de corriger des défauts ou d’ajouter des fonctions, mais crée aussi une voie privilégiée pouvant modifier retraits, frais, droits ou comptabilité. Il faut donc examiner le code actuel et les règles qui détermineront le code futur.

Tous les proxies ne sont pas évolutifs et tous les systèmes modifiables n’utilisent pas de proxy. Certains projets déploient de nouveaux contrats et migrent l’état ; d’autres désactivent définitivement les mises à niveau. L’architecture et l’autorité réelles en chaîne comptent davantage qu’une étiquette d’interface.

Fonctionnement

L’appelant envoie sa transaction au proxy, qui lit l’adresse d’une implémentation et exécute son code dans le contexte de stockage du proxy via delegatecall. Le code vient de l’implémentation, mais les lectures et écritures touchent le proxy ; l’appelant et la valeur d’origine sont conservés. ERC-1967 normalise les slots d’implémentation, de beacon et d’administrateur.

Les proxies transparents gèrent la mise à niveau dans le proxy et séparent appels administratifs et appels utilisateur. Les proxies UUPS placent cette logique dans l’implémentation et emploient la compatibilité ERC-1822 ; leur autorisation est donc cruciale. Les proxies beacon lisent une implémentation dans un beacon, dont une mise à jour peut modifier plusieurs proxies.

La compatibilité de l’état est la contrainte centrale. Réordonner, supprimer ou changer le type des variables, ou modifier l’héritage, peut corrompre les données. Un agencement uniquement extensible, des espaces réservés ou le stockage à espaces de noms ERC-7201 aident, mais n’évitent pas la validation entre versions.

Un constructeur initialise l’implémentation, pas le stockage du proxy. Le déploiement appelle donc normalement une seule fois un initialiseur tel que initialize. L’implémentation doit bloquer son initialisation directe et les migrations ultérieures utiliser des réinitialiseurs limités. Un initialiseur public ou répétable peut transférer les rôles à un attaquant.

Un processus défendable consiste à :

  1. Figer sources, compilateur, dépendances, agencements, adresses et bytecode attendu des deux implémentations.
  2. Examiner le delta, la compatibilité, l’initialisation ou migration, l’autorisation, les dépendances et le retour arrière ; tester la transaction complète sur un fork.
  3. Publier la proposition et l’adresse, puis appliquer multisig, gouvernance et timelock annoncés sans contournement caché.
  4. Exécuter et vérifier slot d’implémentation ou beacon, événements, bytecode, état initialisé, rôles et invariants à un bloc consigné.
  5. Surveiller slots, rôles et paramètres, et préparer les incidents sans supposer qu’un retour arrière sera toujours sûr.

Exemple

Un protocole de prêt doit ajouter une fonction de remboursement. Son proxy délègue à l’implémentation A. L’équipe déploie B, vérifie que B ne fait qu’ajouter du stockage et prépare la migration. La gouvernance publie le bytecode et place la mise à niveau derrière un timelock de 48 heures. Ensuite, la même adresse délègue à B et les soldes restent dans le proxy.

Les utilisateurs doivent confirmer que le slot est passé de A à B, que la migration n’a été exécutée qu’une fois et que rôles et soldes sont conformes. Si un gardien peut contourner le timelock ou un signataire remplacer B par un code arbitraire, ce pouvoir appartient au modèle de confiance malgré le respect de la procédure ordinaire.

Risques

  • Remplacement privilégié : un administrateur, multisig, gouverneur ou une clé compromise peut installer une logique malveillante ou défectueuse.
  • Corruption du stockage : un agencement incompatible peut réinterpréter soldes, propriétaires, mappings ou données comptables.
  • Échec d’initialisation : un initialiseur oublié, répété ou exposé peut bloquer le système ou transférer le contrôle.
  • Défaillance propre au modèle : transparent, UUPS, beacon et proxies personnalisés échouent différemment ; leur nom ne prouve rien.
  • Gouvernance de façade : timelock ou vote peuvent cacher un contournement d’urgence, un délai bref, un pouvoir concentré ou des signataires faibles.
  • Migration ou retour dangereux : le nouvel état peut être irréversible ; restaurer l’ancien code ne restaure pas forcément son sens.
  • Écart de vérification : un code d’implémentation vérifié ne prouve pas que le proxy le vise ni que l’administrateur et l’état sont attendus.
  • Risque de suivi et d’intégration : explorateurs, interfaces, auditeurs et intégrations peuvent suivre une version périmée ou manquer un changement du beacon.

Idées reçues

  • « Le contrat à cette adresse est immuable. » Le bytecode du proxy peut l’être alors que son comportement change par un slot d’implémentation ou beacon.
  • « Un multisig décentralise les mises à niveau. » Il ne réduit la dépendance à une clé que si signataires, seuil, opérations et remplacement sont robustes.
  • « Un timelock empêche une mise à niveau malveillante. » Il donne du temps pour observer et sortir, mais ne sécurise pas le code.
  • « Une vérification du stockage réussie prouve la sûreté. » Elle couvre l’agencement, pas logique, autorisation, oracle, migration ou économie.
  • « Renoncer aux mises à niveau supprime toujours le contrôle. » Administrateur, beacon, gouverneur, autorisation UUPS et voies alternatives doivent être vérifiés en chaîne.

Sujets connexes

Sources

Navigation

Rechercher dans le wiki...