Audit 1 pouce : Protocole LimitOrder


CoinFabrik a été invité à auditer les contrats du protocole de commande à cours limité pour 1 pouce. Les ordres limités sont des contrats entre un fabricant, qui génère l’ordre, et un preneur, qui accepte l’ordre. Un maker définit une commande (offchain) comprenant une paire de jetons, un taux de change et un montant total qu’il souhaite échanger, entre autres paramètres. Un preneur qui accepte cet ordre peut remplir l’ordre et le faire exécuter, si certaines conditions sont remplies.

un résumé de nos découvertes, quel est leur état actuel.

1inch/

Cet audit est basé sur le commit suivant  :

Contrats

Les contrats audités sont :

  • contracts/LimitOrderProtocol.sol : fonctions principales

    Audit 1 pouce : Protocole LimitOrder

  • contracts/helpers/AmountCalculator.sol  : fonctions d’assistance calculant les montants du fabricant et du preneur

  • contracts/helpers/PredicateHelper.sol  : fonctions d’assistance pour la construction de prédicats

  • contrats/helpers/ImmutableOwner.sol  : modificateur

  • contracts/helpers/ERC20Proxy.sol  : assistant proxy

  • contracts/helpers/ERC1155Proxy.sol  : assistant proxy

  • contracts/helpers/ERC721Proxy.sol  : assistant proxy

  • contrats/helpers/NonceManager.sol  : nonces

  • contracts/libraries/ArgumentsDecoder.sol  : aide au décodage des arguments

  • contracts/libraries/UncheckedAddress.sol  : inclut les appels aux fonctions de jeton (externes)

  • contrats/interfaces/IEIP1271.sol  : interface

  • contrats/interfaces/InteractiveMaker.sol  : interface

Analyses

Les analyses suivantes ont été effectuées :

  • Abus des différentes méthodes d’appel
  • Erreurs de dépassement d’entier
  • Division par zéro erreur
  • Version obsolète du compilateur Solidity
  • Attaques frontales
  • Attaques de réentrance
  • Utilisation abusive des horodatages de bloc
  • Attaques par déni de service Softlock
  • Fonctionne avec un coût de gaz excessif
  • Qualificateurs de fonction manquants ou mal utilisés
  • Interactions de code et de contrat inutilement complexes
  • Gestion des erreurs médiocre ou inexistante
  • Défaut d’utiliser un modèle de retrait
  • Validation insuffisante des paramètres d’entrée
  • Manipulation incorrecte des signatures cryptographiques

Analyses spécifiques pour ce projet

/preneurs de profiter les uns des autres. Cela comprend les analyses suivantes  :

  • leur permettant de tirer parti des fabricants, par exemple, avec un meilleur ratio takingAmount / makingAmount
  • Enfin, puisque le contrat fait des appels à des contrats externes à partir de paramètres,
  • Résultats et correctifs

    ID Titre Gravité Statut CR-1 Une attaque frontale dans un ordre malveillant conduit à un taux arbitraire défini par le fabricant Critique Fixe EN-1 Utilisation de fonctions obsolètes Amélioration Non corrigé

    Classification de gravité

    Les risques de sécurité sont classés comme suit :

    • Critique. Ils compromettent sérieusement le système. Ils doivent être corrigés immédiatement
    • Moyen : ce sont des problèmes potentiellement exploitables. ils pourraient représenter un risque pour la sécurité dans un avenir proche.
    • Mineur  : ces problèmes représentent des problèmes relativement mineurs ou difficiles à exploiter, mais qui peuvent être exploités en combinaison avec d’autres problèmes. Ces types de problèmes ne bloquent pas les déploiements dans les environnements de production. Ils doivent être pris en compte et corrigés lorsque cela est possible
    • Amélioration  : ces types de résultats ne représentent pas un risque pour la sécurité.

    Ce classement est résumé dans le tableau suivant :

    GRAVITÉ OBSTACLE EXPLOITABLE À RÉPARER Critique Oui Oui Immédiatement Moyen Dans un futur proche Oui Dès que possible Mineure Peu probable Non Éventuellement Amélioration Non Non Éventuellement

    Gravité critique

    CR-01 Une attaque frontale dans un ordre malveillant conduit à un réglage arbitraire du débit par le fabricant (corrigé)

    Le contrat LimitOrder permet à un maker de définir des commandes où un makingAmount, un takingAmount, des paramètres getMakerAmount et getTakerAmount sont définis (entre autres). Lorsque fillOrder est appelé par un preneur, les valeurs makingAmount et takingAmount de l’échange sont calculées à la volée et peuvent utiliser ces fonctions getMakerAmount et getTakerAmount définies par le fabricant de manière arbitraire.

    Un fabricant malveillant pourrait créer une commande définissant des fonctions personnalisées getMakerAmount et getTakerAmount sur un contrat arbitraire contrôlé par le fabricant avec un prix makingAmount/takingAmount différent. Le contrat du fabricant pourrait être mis en œuvre de sorte que si le preneur évalue ces valeurs getMakerAmount et getTakerAmount, il obtienne les valeurs makingAmount et takingAmount d’origine de la commande. Cependant, lorsque le preneur appelle fillOrder() avec makingAmount défini sur 0, le fabricant peut exécuter une attaque frontale appelant un setter dans le contrat malveillant du fabricant qui modifie la valeur renvoyée par getMakerAmount. Ainsi, lorsque fillOrder est exécuté, il utilisera la nouvelle valeur qui peut être inférieure à la valeur attendue par le preneur (makingAmount). (Respectivement avec takingAmount=0 et getTakerAmount.)

    Recommandation

    Le comportement attendu de fillOrder doit être documenté et en particulier, quelle est l’utilisation prévue de thresholdAmount, getMakerAmount et getTakerAmount, afin que les parties soient pleinement conscientes des résultats possibles de l’exécution de l’ordre.

    Suivre

    1inch a implémenté une solution qui élimine la menace en ajoutant un paramètre, thresholdAmount, à fillOrder avec lequel le preneur stoppe toute attaque.

    Avant de placer les virements, le code dans fillOrder exige que

    montantPrendre = thresholdAmount

    lorsque makingAmount est déterminé par getMakerAmount.

    La solution élimine ainsi la menace dans le cas où le taker saisit thresholdAmount en fonction de ses besoins : par exemple, un taker qui fixe une valeur makingAmount non nulle dans fillOrder peut spécifier que thresholdAmount est égal au takingAmount qu’il s’attend à recevoir (afin que le le fabricant ne peut pas augmenter le montant de la commande); respectivement, le preneur entrant une valeur takingAmount dans fillOrder peut spécifier que thresholdAmount soit égal au makingAmount attendu (afin que le fabricant ne puisse pas réduire le makingAmount de la commande). Lorsque les valeurs de thresholdAmount diffèrent de ce que le preneur s’attend à recevoir, cela peut empêcher la transaction de se produire ou peut permettre au fabricant de prendre un avantage.

    Une solution alternative, proposée et rejetée par 1 pouce, comprend un paramètre supplémentaire différent, minPrice, à ajouter à fillOrder et le contrat exige que

    makingAmount * 1e18 / takingAmount >= minPrice.

    Cette solution est analogue à la solution thresholdAmount. D’une manière générale, un preneur peut percevoir problématique de payer un prix inférieur à celui saisi lors de l’appel à fillOrder(); il peut même rejeter thresholdAmount (ou minPrice) car il s’attend à ce que l’ordre soit exécuté en fonction de ce qu’il a saisi sans entrer dans les étapes supplémentaires.

    Gravité moyenne

    Aucun problème n’a été trouvé.

    Gravité mineure

    Aucun problème n’a été trouvé.

    Améliorations

    FR-01 Utilisation de fonctions obsolètes

    Les fonctions restant() et fillOrder() utilisent value1.sub(value2.

    Recommandation

    Le code se réduit à un seul contrat. Les tests et les scripts de test inclus dans le référentiel ont été utiles pour comprendre le flux d’exécution des ordres limités, ainsi que pour évaluer certains scénarios.

    Un problème critique a été découvert par 1 pouce qui permet à un fabricant malveillant de tromper les preneurs en recevant un taux de change inférieur aux attentes. Le problème a été résolu en fournissant au preneur un paramètre de sécurité qui garantit que les attaques ne sont pas possibles lorsque le paramètre est choisi en respectant ses attentes.

    ce rapport d’audit n’est pas une garantie de sécurité. De plus, il ne fournit pas de garantie d’irréprochabilité du code de contrat intelligent.