À des fins éducatives uniquement ; ne constitue pas un conseil en investissement. Tout investissement peut entraîner des pertes.
Réponse directe
Un timelock de gouvernance est un contrôleur d’exécution, et non un nouveau vote. Une fois qu’une gouvernance a autorisé un payload, un proposant habilité programme l’opération exacte. Le contrat enregistre le moment où elle peut devenir exécutable et refuse toute exécution avant ce moment. Ce délai rend une mise à niveau, une modification de paramètre, un transfert de trésorerie ou un changement de rôle observable avant sa prise d’effet.
Le délai annoncé n’est qu’une partie du contrôle. Il faut examiner l’identifiant de l’opération, la première heure d’exécution possible, toute règle d’expiration, le prédécesseur, le proposant, l’exécuteur, l’annulateur, l’administrateur et toute autre voie pouvant contrôler la cible. Un timelock de 48-hour n’offre pas une fenêtre de sortie de 48-hour si l’opération est mise en file tardivement, si la surveillance tarde, si les retraits prennent plus de temps ou si une autre clé privilégiée peut réaliser immédiatement la même modification.
Un timelock ne détermine pas si une action est légitime ou sûre. Il donne aux personnes et aux systèmes de surveillance automatisés le temps de décoder les appels, de simuler leurs effets, d’annuler ou de suspendre l’opération lorsqu’ils y sont autorisés, de communiquer le changement et de sortir des positions lorsqu’une véritable voie de sortie existe.
Fonctionnement
- L’autorité est attribuée au timelock. Le timelock doit être propriétaire de la cible ou y détenir le rôle pertinent. Si un gouverneur n’exerce aucune autorité sur la cible, l’adoption d’une proposition ne change rien ; si un administrateur distinct conserve une autorité parallèle, cette voie peut contourner le délai.
- Un proposant programme une opération exacte. Dans le
TimelockControllerd’OpenZeppelin, l’identifiant d’une opération unique est le hash detarget,value,data,predecessoretsalt; pour une opération par lots, il correspond au hash des tableaux associés, de la même dépendance et du même salt. La modification d’un seul champ produit un identifiant d’opération différent. Le salt distingue des actions qui seraient autrement identiques. - Le délai minimal commence lors de la programmation. Un vote favorable ne déclenche pas nécessairement le timelock. La programmation enregistre un timestamp de disponibilité en utilisant un délai qui doit être au moins égal au minimum actuel du contrat. Les opérations OpenZeppelin passent de
UnsetàWaiting, puis àReadyet enfin àDoneaprès une exécution réussie. - Les dépendances et les autorisations sont vérifiées lors de l’exécution. Un prédécesseur doit déjà être
Done. L’appelant doit satisfaire à la règle de l’exécuteur et l’appel à la cible doit réussir. Un exécuteur ne peut pas modifier le payload programmé. Attribuer le rôle d’exécuteur àaddress(0)permet à quiconque d’exécuter l’opération après son arrivée à maturité, ce qui améliore la disponibilité, mais permet aussi à tout compte de choisir le moment exact d’exécution parmi ceux qui sont admissibles. - L’annulation ramène une opération en attente à son état initial. Dans les contrats OpenZeppelin actuels, un compte doté de
CANCELLER_ROLEpeut annuler une opération tant qu’elle est en attente, y compris lorsqu’elle est prête mais pas encore exécutée. Une nouvelle programmation déclenche un nouveau compte à rebours. La configuration des rôles est importante : d’anciennes versions et d’autres timelocks peuvent accorder le droit d’annulation au proposant ou à l’administrateur. - L’expiration dépend de l’implémentation. Le
TimelockControllerd’OpenZeppelin ne comporte pas d’expiration intégrée fondée sur un délai de grâce ; une opération prête le reste jusqu’à son exécution ou son annulation. À l’inverse, le Timelock de Compound v2 exige une exécution au plus tard àeta + GRACE_PERIOD, et son code source fixeGRACE_PERIODà14 days. Governor Bravo considère une proposition mise en file comme expirée une fois cette limite dépassée. - L’administration doit elle aussi être retardée. OpenZeppelin n’autorise
updateDelayque par un appel du timelock à lui-même. De même, un déploiement auto-administré impose que les changements de rôles passent par des opérations programmées. Un administrateur externe temporaire utilisé pendant la configuration doit renoncer à ce rôle une fois celle-ci terminée ; sinon, il subsiste comme une voie de confiance distincte.
Pour chaque action mise en file, reconstituez à partir de l’état du contrat et de ses événements un relevé de contrôle comprenant : l’identifiant de la chaîne, les adresses du timelock et de la cible, l’identifiant de l’opération, le payload décodé, le proposant, la transaction et le timestamp de programmation, le délai minimal, l’heure de disponibilité, l’expiration éventuelle, le prédécesseur, la politique de l’exécuteur, l’autorité d’annulation et l’état final de la transaction. Ne déduisez pas ces champs uniquement à partir d’un site de gouvernance.
Exemple détaillé
Supposons qu’une proposition abaisse le seuil de liquidation d’un marché de prêt de 75% à 60%. Le vote se termine à Monday 12:00 UTC, mais un proposant ne programme l’opération qu’à Tuesday 18:00 UTC. Le délai programmé est de 48 hours ; la première exécution possible intervient donc à Thursday 18:00 UTC, et non à Wednesday 12:00 UTC.
L’opération contient le contrat du gestionnaire de risques comme target, une value de zéro en jeton natif, les data encodées de modification du paramètre, aucun prédécesseur et un salt divulgué. Le recalcul du hash à partir de ces champs doit correspondre à l’identifiant d’opération émis. Une adresse de marché, un seuil ou un salt différent constitue une autre opération, même si la description affichée dans l’interface paraît identique.
Les utilisateurs disposent donc de 48 hours à compter de la programmation, mais leur temps de sortie réellement utilisable est plus court. Si l’alerte arrive 6 hours après la programmation et qu’une file d’unstaking ou de retrait prend 24 hours, il ne reste que 18 hours de marge :
usable response time = ready time - detection time - exit settlement time
Si un multisig d’urgence peut suspendre immédiatement les retraits, il peut réduire les pertes pendant un incident, mais aussi rendre toute sortie impossible avant le changement mis en file. Examinez cette autorité séparément. Après l’exécution, vérifiez le stockage réel de la cible et les événements émis : une transaction d’exécution du timelock peut réussir alors que son résultat économique attendu reste mal compris.
Risques et contrôles
- Autorité de contournement. Recensez les propriétaires, administrateurs de proxy, rôles de contrôle d’accès, beacons de mise à niveau, conseils d’urgence, modules et exécuteurs cross-chain. La voie privilégiée la plus courte détermine le délai effectif.
- Substitution du payload ou décodage insuffisant. Recalculez l’identifiant d’opération à partir des champs bruts, identifiez les implémentations de proxy, décodez chaque sélecteur et chaque argument, puis simulez l’intégralité du lot. Le texte lisible de la proposition n’est pas le payload exécutable.
- Préavis insuffisant. Déclenchez les alertes à partir des événements on-chain de programmation et d’annulation, et pas seulement des publications sur les forums. Mesurez le préavis entre la programmation confirmée et le premier bloc ou timestamp exécutable, puis soustrayez les temps de détection et de règlement de la sortie.
- Échec de l’annulation. Confirmez quels comptes peuvent annuler, s’ils sont opérationnels, quel seuil ils exigent et si l’annulation reste possible après que l’opération est devenue prête. Répétez la transaction avant qu’un incident ne survienne.
- Défaillance de l’exécuteur ou manipulation du moment d’exécution. Les exécuteurs soumis à des restrictions peuvent devenir indisponibles ou retarder volontairement l’exécution. Une exécution ouverte améliore la disponibilité, mais permet à des tiers d’exécuter immédiatement à maturité ; les prix dépendants, les mises à jour d’oracles et les positions des utilisateurs doivent donc être sûrs à cette limite.
- Actions obsolètes en file d’attente. En l’absence d’expiration, d’anciennes opérations prêtes peuvent rester exécutables indéfiniment. Suivez et annulez explicitement les opérations abandonnées. Lorsqu’un délai de grâce existe, surveillez sa fin exacte et exigez un nouveau cycle de gouvernance après l’expiration.
- Risques liés aux dépendances et aux lots. Vérifiez l’identifiant du prédécesseur et l’ordre atomique du lot. Un seul appel qui produit un revert peut bloquer un lot atomique ; une dépendance incorrecte peut bloquer définitivement une opération pourtant valide.
- Administration non sécurisée. Soumettez les réductions de délai, les attributions de rôles et le remplacement du timelock au timelock lui-même. Supprimez les administrateurs de déploiement, conservez au moins un proposant et un exécuteur viables et évitez toute configuration qui verrouillerait définitivement le contrôle.
- Absence de sortie crédible. Comparez le délai aux files de retrait, à la finalité des bridges, à la liquidité du marché, aux pouvoirs de suspension et à la congestion. Un délai publié ne protège pas les utilisateurs lorsque les actifs ne peuvent pas sortir avant l’exécution.
La norme opérationnelle est une chronologie étayée par des preuves, et non un compte à rebours affiché. Archivez l’événement de programmation, les appels décodés, le résultat de la simulation, les détenteurs des rôles, le plan d’annulation, les premières et dernières heures d’exécution, les canaux de communication et la différence d’état après exécution.
Idées reçues
- « Le délai commence à la fin du vote. » Il commence normalement lorsque l’action approuvée est programmée, sauf si l’implémentation déployée relie explicitement ces deux moments.
- « Tout le monde peut exécuter, donc tout le monde peut modifier la proposition. » Un exécuteur ouvert ne peut déclencher qu’un payload déjà programmé dont l’identifiant d’opération et les conditions correspondent.
- « Ready signifie que l’action doit être exécutée immédiatement. » Ready signifie que l’action est admissible. Son exécution nécessite toujours une transaction, les autorisations requises, des dépendances satisfaites et un appel réussi à la cible.
- « Tous les timelocks ont une fenêtre d’exécution. » L’expiration varie selon l’implémentation. Compound v2 utilise un délai de grâce ; par défaut, le
TimelockControllerd’OpenZeppelin ne fait pas expirer les opérations prêtes. - « Un long timelock élimine le risque de gouvernance. » Le délai n’est utile que si la surveillance, la compréhension, l’annulation ou la suspension, la communication et la sortie sont toutes possibles avant l’exécution. Des administrateurs parallèles et des retraits bloqués peuvent annuler ce bénéfice.
Sujets connexes
Sources
- Governance API: TimelockController - OpenZeppelin Documentation (consulté le : 2026-08-20)
- Access Control: Delayed operation - OpenZeppelin Documentation (consulté le : 2026-08-20)
- Timelock.sol - Compound Finance (consulté le : 2026-08-20)
- GovernorBravoDelegate.sol - Compound Finance (consulté le : 2026-08-20)