Uma Audit - Phase 6 PlatoBlockchain Data Intelligence. Recherche verticale. Ai.

Audit Uma – Phase 6

Uma Audit - Phase 6 PlatoBlockchain Data Intelligence. Recherche verticale. Ai.

Introduction

UMA est une plate-forme qui permet aux utilisateurs de conclure des contrats financiers à confiance minimisée sur la blockchain Ethereum. Nous avons préalablement audité l'oracle décentralisé, un modèle de contrat financier particulier, quelques demandes d'extraction ad hoc, le modèle multipartite perpétuel, diverses demandes d'extraction incrémentielles sur un engagement plus long ainsi que le pont assuré.

Dans cet audit, nous avons examiné un nouveau contrat de proposition de gouvernance, un mécanisme pour étendre l'écosystème UMA sur plusieurs chaînes, un mécanisme pour distribuer des récompenses aux détenteurs de jetons ERC721 conformément à une spécification hors chaîne et une mise à jour du pont assuré pour soutenir WETH sur la chaîne Optimisme.

Le commit audité est 0c4cea3c3d5e48da6f8984b8ba3afdfea4ce47cc et le périmètre comprend les contrats suivants :

  • oracle/implementation/Proposer.sol
  • cross-chain-oracle/* (hors contrats test et Polygon)
  • financial-templates/optimistic-rewarder/* (hors contrats de test)

Nous avons également examiné les modifications apportées aux fichiers de solidité dans Demande de tirage 3611.

Tous les codes externes et les dépendances de contrat ont été supposés fonctionner comme documenté.

Présentation du système

Le courant Governance Le contrat permet à la Fondation Risk Labs de proposer de nouvelles actions de gouvernance pouvant être ratifiées par les détenteurs de jetons UMA. Le nouveau Proposer Le contrat est destiné à jouer le rôle de proposant, permettant à quiconque de faire de nouvelles propositions tant qu'il fournit un lien qui sera sacrifié si la proposition échoue. Il n'y a pas d'incitation spécifique à faire des propositions. L'intention est de s'assurer que seules les actions qui sont très susceptibles d'être acceptées seront proposées.

Le nouveau mécanisme inter-chaînes permet de transmettre la proposition de gouvernance du réseau principal Ethereum aux chaînes Optimism et Arbitrum. De cette manière, le mécanisme de gouvernance UMA sur la couche 1 peut être utilisé pour régir les contrats UMA sur les chaînes de couche 2 prises en charge. Le mécanisme permet également de transmettre les demandes de prix et les résolutions entre les couches, de sorte que les oracles optimistes sur les chaînes de couche 2 peuvent être sécurisés par le mécanisme de vérification des données du réseau principal de la même manière que l'Oracle optimiste de couche 1 est sécurisé par le DVM.

Il convient de noter que ces messages sont envoyés à l'aide de la mécanique de pont native, ce qui signifie qu'ils sont limités par les caractéristiques des chaînes de couche 2 concernées. En particulier, les messages de la couche 2 à la couche 1 pourraient prendre une semaine ou plus pour transiter par le pont. De plus, le mécanisme de gouvernance UMA prend en charge les propositions qui incluent plusieurs transactions ordonnées, mais cela limite simplement l'ordre dans lequel elles peuvent être ajoutées au pont. Il est possible que certaines de ces transactions soient exécutées dans un ordre différent, ou pas du tout, sur la couche 2.

Le contrat Optimistic Rewarder crée simplement des jetons ERC721 pour quiconque en fait la demande. Il permet également à quiconque d'associer des données arbitraires à n'importe quel jeton et de déposer divers jetons ERC20 à distribuer en récompense. L'interprétation des données arbitraires et la distribution attendue des récompenses entre les détenteurs de jetons sont déterminées à l'aide d'une procédure hors chaîne non spécifiée. N'importe qui peut prétendre qu'un jeton ERC721 spécifique est dû à un ensemble de récompenses s'il est prêt à déposer une caution. Le mécanisme standard d'Optimistic Oracle est utilisé pour permettre à quelqu'un d'autre de contester la réclamation, qui sera résolue par le DVM. Les réclamations qui ne sont pas contestées à temps sont supposées être valides et le contrat distribue les récompenses en conséquence. La seule restriction (pour simplifier la comptabilité) est que le jeton obligataire oracle ne peut pas être utilisé comme jeton de récompense.

Enfin, PR3611 modifie le mécanisme de pont assuré pour éviter d'envoyer WETH via le pont de jetons Optimism, qui n'est pas pris en charge. Au lieu de cela, tout L2 WETH déposé dans la boîte de dépôt Optimism est déballé en L2 ETH avant de transiter par le pont. Sur la couche 1, l'ETH est converti en WETH avant d'être transmis au pool de ponts WETH.

Gravité critique

[C01] Impossible de contester une récompense non valide

Lors de la contestation d'une demande de récompense, le OptimisticRewardBase contrat d'abord déclenche une proposition sur le SkinnyOptimisticOracle et alors conteste cette proposition. Cependant, la proposition définit le délai d'expiration en décalage par rapport à l'heure actuelle (du litige), tandis que le litige précise l'expiration comme un décalage par rapport au moment de la demande de récompense d'origine. Dans la plupart des cas, cet écart empêchera l'oracle d'identifier la proposition à contester, ce qui signifie que les litiges valides ne seront pas traités et que les demandes de récompense non valides seront acceptées.

Envisagez de mettre à jour l'appel de contestation pour spécifier correctement la proposition à contester.

Mettre à jour: Fixé à partir du commit 9e15557 in PR3690.

[C02] Résoudre les propositions à plusieurs reprises

Les resolveProposal fonction de la Proposer contrat valide simplement que l'oracle a résolu, mais ne vérifie pas si le lien a été distribué. Cela signifie que la même proposition peut être résolue plusieurs fois, ce qui entraîne des paiements de cautionnement en double. Envisagez de signaler ou de supprimer des propositions existantes lorsqu'elles sont résolues.

Mettre à jour: Fixé à partir du commit b152718 in PR3689.

Haute gravité

Aucun.

Gravité moyenne

[M01] Paramètres d'événement incorrects

Les OptimisticRewarderBase contrat définit un Requested un événement qui est émis par le requestRedemption fonctionner lorsqu'un rachat est demandé. Cet événement est défini pour émettre le date d'expiration du rachat comme dernier paramètre. Cependant, lorsque l'événement est émis, son dernier paramètre est incorrectement défini sur heure actuelle.

De même, le Redeemed un événement lit l'heure d'expiration après la suppression de l'enregistrement, il sera donc incorrectement défini sur zéro.

Étant donné que cet événement peut être utilisé pour déclencher des calculs hors chaîne, envisagez de mettre à jour la valeur émise de manière appropriée.

Mettre à jour: Fixé à partir du commit f04eef9 in PR3694.

Faible gravité

[L01] Absence d'émission d'événement après contestation d'un rachat

Les OptimisticRewarderBase contrat définit un Disputed un événement qui est destiné à être déclenché si un rachat est contesté. Cependant, cet événement n'est pas émis à l'intérieur ou à l'extérieur de la OptimisticRewarderBase contrat.

Envisagez d'émettre l'événement après que des modifications sensibles ont eu lieu dans le dispute fonction, pour faciliter le suivi et informer les clients hors chaîne suite à l'activité des contrats.

Mettre à jour: Fixé à partir du commit c275e92 in PR3695.

[L02] Garde de réentrance incohérente

Les Optimism_ParentMessenger ainsi que Arbitrum_ParentMessenger les contrats appliquent de manière incohérente nonReentrant modificateur. Envisagez de l'inclure dans toutes les fonctions publiques.

Mettre à jour: Fixé à partir du commit 6275c39 in PR3677.

[L03] Commentaires trompeurs

Voici quelques commentaires trompeurs que nous avons identifiés lors de notre examen :

  • ChildMessengerConsumerInterface.sol:
    • Ligne 5 dit « messager parent » au lieu de « messager enfant »
  • GovernorSpoke.sol:
    • Lignes 49 à 51 liens vers un Gnosis fichier même si le commentaire indique que l'extrait a été copié à partir de Governor.sol. De plus, l'extrait n'est pas identique à celui de Governor.sol

Mettre à jour: Fixé à partir du commit cc350f9 in PR3678.

[L04] Timbre de données auxiliaires manquant

Lors d'une demande de prix sur OracleSpoke contrat, les données annexes fournies est estampillé avec l'identifiant de la chaîne enfant. Cependant, le hasPrice ainsi que getPrice fonctions ne tamponnent pas les données annexes lors de l'identification de la demande de prix. Cela oblige les contrats d'appel à appliquer eux-mêmes le tampon, ce qui entraîne une incohérence entre les mécanismes de demande de prix et de récupération des prix. Envisagez d'apposer le tampon dans le hasPrice ainsi que getPrice fonctions.

Mettre à jour: Fixé à partir du commit fdb845d in PR3668.

[L05] Paramètre NatSpec manquant

De nombreuses fonctions dans le OptimisticRewarderBase contrat il manque le @return paramètre dans leurs commentaires de spécification naturelle. Pensez à l'inclure par souci d'exhaustivité.

Mettre à jour: Fixé à partir du commit 8920f38 in PR3679.

[L06] Indemnité résiduelle

Pour invoquer l'Oracle Optimiste, le OptimisticRewarderBase contrat lui accorde une indemnité symbolique, afin qu'il puisse retirer les paiements de la caution. Si la proposition échoue, l'échange de récompense est annulé mais l'allocation n'est pas réinitialisée. Par conséquent, l'Oracle Optimiste conservera une allocation résiduelle inutile jusqu'au prochain déclenchement d'un litige. Envisagez de révoquer l'allocation si la proposition échoue.

Mettre à jour: Fixé à partir du commit c2d444b in PR3698.

[L07] Adresse de remboursement invalide

L'adresse de remboursement L2 du Arbitrum_ParentMessenger est initialisé au propriétaire du contrat, qui devrait être le gouverneur L1. De même, le setRefundL2Address a un commentaire indiquant qu'il doit être défini pour le gouverneur. Cependant, lors de la transmission de messages sur le pont, cette valeur est défini comme utilisateur L2, qui est l'adresse sur Arbitrum qui reçoit les fonds excédentaires une fois le ticket résolu. Étant donné que l'adresse du gouverneur L1 ne sera pas accessible sur Arbitrum, tous les fonds envoyés à cette adresse seront perdus.

Envisagez de le définir sur une adresse L2 valide.

Mettre à jour: Fixé à partir du commit b3f2dd1 in PR3687.

[L08] Mécanisme pour changer les enfants messagers

Les GovernorSpoke ainsi que OracleSpoke contract each initialise le messager enfant dans le constructeur, sans mécanisme pour le mettre à jour. Cela signifie que lorsque le messager enfant est changé, les deux contrats à rayons deviennent obsolètes.

Étant donné que le contrat de rayons est probablement plus stable que les messagers, envisagez d'inclure un mécanisme pour mettre à jour le messager sur les rayons.

Mettre à jour: Fixé à partir du commit 7c9e061 in PR3688.

Remarques et informations supplémentaires

[N01] Changer le jeton d'obligation

Les Proposer le contrat comprend un mécanisme pour que le propriétaire modifie la taille du cautionnement de proposition. Demandez-vous s'ils devraient également pouvoir changer le jeton d'obligation. Notez que cela nécessiterait un mécanisme pour identifier la devise correcte des obligations lorsque les propositions existantes sont résolues.

Mettre à jour: Pas une solution. Déclaration de l'UMA pour ce problème :

N01 recommande d'autoriser le contrat proposant à remplacer le jeton d'obligation par autre chose que UMA. Nous n'avons aucune intention de prendre en charge un jeton autre que $UMA pour cette fonction et avons donc choisi de ne pas apporter de modifications à ce problème. De plus, un seul jeton par contrat garde cette logique aussi simple que possible. Enfin, si un changement était nécessaire (dans le cas d'une migration de jeton, par exemple), nous pourrions simplement déployer un nouveau contrat de proposant avec l'autre jeton et initier une proposition de migration du système pour utiliser celui-ci.

[N02] Interface incomplète

Les ChildMessengerInterface ne précise pas un processMessageFromCrossChainParent fonction, même si elle est supposée exister par les messagers parents. Pensez à l'inclure par souci d'exhaustivité.

Mettre à jour: Non fixé. Déclaration de l'UMA pour ce problème :

Nous avons intentionnellement choisi de laisser cette interface incohérente car son implémentation dans ChildMessengerInterface rompt la compatibilité avec Polygon_ChildMessenger car la méthode de Polygon pour traiter les messages d'autres chaînes nécessite une logique quelque peu personnalisée dans laquelle une méthode interne est appelée _processMessageFromRoot.

[N03] Interface incorrecte

Les GovernorSpoke contrat incorrect utilise l' ChildMessengerConsumerInterface type pour décrire sa messenger variable. Pensez à utiliser le ChildMessengerInterface à la place.

Mettre à jour: Fixé à partir du commit f31a527 in PR3680.

[N04] Tirez les jetons vers le magasin

Dans un audit précédent nous nous sommes interrogés sur le but de Store contrat payOracleFeesErc20 fonction (dans le numéro L19). L'équipe UMA a choisi de conserver la fonction standardiser l'interface pour d'éventuelles modifications futures. Étant donné que l'objectif de la fonction n'est pas entièrement spécifié, il n'est pas clair si elle doit être déclenchée lorsque le Proposer contrat confisque une caution. Il devrait probablement être utilisé lorsque le OracleHub paie une demande de prix. Déterminez si la fonction doit être utilisée dans l'un ou l'autre scénario.

Mettre à jour: Reconnu. Déclaration de l'UMA pour ce problème :

N04 recommande d'utiliser la méthode payOracleFeeErc20 du Store pour payer les frais dans les contrats Proposer et OracleHub afin d'être cohérent avec l'utilisation du Store. Nous avons choisi de ne pas utiliser cette fonction car cela impliquerait d'importer une interface supplémentaire (pour le magasin) et d'exiger la conversion du montant de la caution en un point fixe (ce qui nécessiterait également une importation supplémentaire. Pour garder le code simple et propre Nous avons choisi de ne pas le faire. Les commentaires d'OZ sur payOracleFeeErc20 lors de la phase d'audit 1 en avril 2020 ont confirmé que cette méthode n'est pas vraiment utile, ce qui rend ce type d'intégration plus difficile à raisonner.

[N05] TODO dans le code

Il y a des commentaires "TODO" dans la base de code qui doivent être suivis dans le backlog des problèmes du projet. Par example:

  • Gamme 37 of Arbitrum_ParentMessenger contrat
  • Gamme 25 of Optimism_ChildMessenger contrat
  • Lignés 83 ainsi que 146 of OracleHub contrat.

Pendant le développement, avoir des commentaires "TODO" bien décrits facilitera le processus de suivi et de résolution de ceux-ci. Sans ces informations, ces commentaires pourraient avoir tendance à pourrir et des informations importantes pour la sécurité du système pourraient être oubliées au moment de leur mise en production.

Ces commentaires TODO doivent contenir une brève description de la tâche en attente et un lien vers le problème correspondant dans le référentiel du projet.

Envisagez de mettre à jour les commentaires TODO pour ajouter ces informations. Pour l'exhaustivité et la traçabilité, une signature et un horodatage peuvent être ajoutés. Par example:

// TODO: point this at an interface instead.

// https://github.com/UMAprotocol/protocol/issues/XXXX

// --mrice32 - 20211209

Mettre à jour: Fixé à partir du commit 5d57b5b in PR3684.

[N06] Erreurs typographiques

La base de code contient les erreurs typographiques suivantes :

  • Dans le Admin_ChildMessenger Contrat, impleenting devrait être implementing
  • Dans le OptimisticRewarderBase Contrat, timestap devrait être timestamp.
  • Dans le OptimisticRewarderBase Contrat, liveness liveness devrait être liveness.
  • Dans le GovernorSpoke Contrat, only called devrait être only be called.
  • Dans le Optimism_ChildMessenger Contrat:

Mettre à jour: Fixé à partir du commit 9b92b0b in PR3681.

[N07] Importations non utilisées

Pour améliorer la lisibilité du code, envisagez de supprimer les importations inutilisées suivantes :

Mettre à jour: Fixé à partir du commit 40b7221 in PR3682.

[N08] Ordre des transactions L2

Les Governor Assure les transactions au sein d'une proposition sont exécutées dans l'ordre. Cependant, lorsque ces transactions impliquent des transactions inter-chaînes, cela garantit simplement qu'elles arrivent au contrat de pont L1 dans le bon ordre. Dans le cas Arbitrum, ils peuvent être réorganisés avant d'être finalisés sur L2. Par conséquent, les propositions de gouvernance devraient être élaborées pour permettre la possibilité de réorganiser les transactions L2.

Mettre à jour: Fixé à partir du commit 0fb2e7b in PR3703L’ GovernorHub peut maintenant relayer un tableau de transactions L2.

Conclusion

Deux problèmes critiques ont été trouvés dans la base de code. Un problème de gravité moyenne et plusieurs vulnérabilités mineures ont été trouvés, et des recommandations de correctifs ont été suggérées.

Source: https://blog.openzeppelin.com/uma-audit-phase-6/?utm_source=rss&utm_medium=rss&utm_campaign=uma-audit-phase-6

Horodatage:

Plus de Ouvrez Zeppelin