16 décembre 2021
Introduction
Les 1m l'équipe nous a demandé d'examiner et d'auditer leur Protocole d'ordre limité contrats intelligents v2. Nous avons examiné le code et publions maintenant nos résultats.
Domaine
Nous avons audité l'engagement 4d94eea25e4dac6271bfd703096a5c4a4d899b4a
des 1inch/limit-order-protocol
dépôt. Sont concernés les contrats suivants :
- OrderMixin.sol
- OrderRFQMixin.sol
- PredicateHelper.sol
- RevertReasonParser.sol
- Permitable.sol
- ChainlinkCalculator.sol
- ArgumentsDecoder.sol
- AmountCalculator.sol
- NonceManager.sol
- LimitOrderProtocol.sol
- ImmutableOwner.sol
- InteractiveNotificationReceiver.sol
- AggregatorInterface.sol
- IDaiLikePermit.sol
Tous les autres fichiers et répertoires de projet (y compris les tests), ainsi que les dépendances et projets externes, la théorie des jeux et la conception incitative, ont également été exclus de la portée de cet audit. Le code externe et les dépendances contractuelles étaient supposés fonctionner comme documenté et les services back-end fournis par 1inch étaient supposés agir dans le meilleur intérêt du protocole.
Santé globale
En général, nous avons trouvé la base de code du projet lisible et bien organisée, même si elle pourrait bénéficier d'une documentation plus complète, notamment autour des blocs de code assembleur, des cas limites du protocole, des actifs/prédicats/ressources externes qui seront utilisés, responsabilités/limites du service back-end fourni et interactions entre les acteurs. Le projet se donne beaucoup de mal pour rendre les actions économes en gaz, parfois même au risque de rendre le code plus difficile à raisonner ; nous soulevons des questions liées à cela ci-dessous. Tout au long de l'audit, l'équipe de 1 pouce s'est montrée très disponible, réactive et très facile à travailler.
Présentation du système
Le protocole d'ordre limité permet l'ordre makers
pour signer des commandes hors chaîne pour des échanges de jetons. Le protocole facilite alors le remplissage des commandes préalablement signées par commande takers
. Les commandes sont hautement extensibles et peuvent appeler des contrats externes de manière statique à plusieurs moments du processus d'exécution des commandes. Cette extensibilité imprègne le protocole d'utilité, mais elle ajoute à la fois de la complexité et une plus grande surface d'attaque pour les commandes elles-mêmes.
Il est important de noter qu'il n'y a pas de stockage en chaîne des détails de la commande. L'état de remplissage ou d'annulation des commandes n'est suivi que via les hachages de commande. Cela nécessite que les commandes soient partagées entre pairs ou via une partie centralisée. Dans ce cas, l'équipe 1inch a l'intention d'agir en tant que partie centralisée, regroupant les commandes signées et utilisant ces commandes comme source de liquidité pour leurs autres protocoles. Les commandes seront publiées via leur propre API afin que les utilisateurs puissent interagir avec elles.
Cette centralisation donne à l'équipe 1 pouce un contrôle extrême sur les commandes qui sont publiées et finalement exécutées. Cela leur donne également la possibilité de censurer les commandes, ce qui pourrait être utile dans le cas de commandes malveillantes ou trompeuses, mais pourrait également être abusé et leur permettre de devancer tout autre utilisateur en cas de commande favorable en ne la montrant pas via l'API.
Rôles privilégiés
Bien que les contrats dans lesquels le rôle est utilisé étaient hors de portée, un rôle privilégié a été identifié. Un immutableOwner
est défini sur le créateur d'un contrat de proxy au moment de la construction, et est utilisé pour limiter l'accès au proxy external
fonctions.
Dépendances externes et hypothèses de confiance
La conception de ce protocole nécessite des composants hors chaîne et en chaîne, et ce modèle hybride peut être utilisé pour atténuer certains vecteurs d'attaque que nous identifions dans notre rapport, mais le coût de cette capacité est une dépendance accrue à l'équipe et à l'infrastructure de 1 pouce.
De plus, le protocole de commande à cours limité fournit des fonctions destinées à récupérer les prix des oracles Chainlink. Nous avons supposé que ces oracles étaient honnêtes, accessibles et fonctionnaient correctement.
De plus, du fait de la souplesse d'une commande, il existe plusieurs points de contact avec des contrats externes qui ne sont pas validés. Cela signifie qu'un utilisateur malveillant pourrait abuser de ces appels et usurper l'identité de prédicats, d'actifs ou d'oracles avec des contrats malveillants afin d'exécuter des actions lors de l'exécution des commandes. Bien que le projet soit protégé dans certaines zones contre la réentrance, de tels vecteurs pourraient provoquer des attaques par déni de service ou des ordres de spam non détectés. L'équipe de 1 pouce est consciente que certains problèmes peuvent apparaître lors de l'utilisation de contrats inconnus pour le protocole et a indiqué son intention que seuls les principaux actifs « de premier ordre » soient entièrement pris en charge par le projet. Cependant, il convient de noter que même avec les actifs les plus populaires, il existe des comportements intrinsèques de chaque actif qui peuvent causer des problèmes sur les protocoles qui ne les traitent pas correctement, comme avoir des frais lors des transferts avec USDT ou renvoyer un code d'erreur au lieu d'un succès booléen avec cTokens.
Résultats
Nous présentons ici nos conclusions.
Gravité critique
Aucun.
Haute gravité
[H01] Données incohérentes transmises à _makeCall
Dans le OrderMixin
contrat, le _makeCall
la fonction est utilisée pour transférer des actifs du preneur au fabricant et alors du fabricant au preneur. Dans ce dernier transfert, le _makeCall
la fonction est transmise de manière incorrecte à la commande makerAsset
comme dernier paramètre, alors qu'il devrait être celui de la commande makerAssetData
.
Par conséquent, toute fonctionnalité de proxy qui s'appuie sur le makerAssetData
l'argument va se briser.
Pour être cohérent avec l'appel précédent à _makeCall
et pour prendre pleinement en charge la fonctionnalité de proxy, envisagez de mettre à jour le order.makerAsset
paramètre order.makerAssetData
.
Mettre à jour: Fixé dans pull request # 57.
[H02] Les commandes privées partiellement exécutées peuvent être exécutées par n'importe qui
Le protocole permet la création de commandes privées et publiques. Sur les commandes privées, seuls les allowedSender
adresse, précisée par le fabricant lors de la création de la commande, est en mesure d'honorer la commande.
Cependant, dans le OrderMixin
Contrat, validation pour le allowedSender
propos est incorrectement défini, ce qui signifie qu'il n'est évalué qu'à l'intérieur de la logique qui gère le premier remplissage d'une commande. Si une commande privée est partiellement exécutée, le chèque du allowedSender
l'adresse n'est plus joignable et la commande devient remplissable par n'importe qui.
Pour clarifier l'intention de savoir si un utilisateur doit être en mesure de remplir ou non des commandes privées partiellement remplies, envisagez soit de documenter la raison du comportement actuel, soit de valider le allowedSender
adresse en dehors de la portée du premier remplissage pour s'assurer qu'elle sera validée à chaque tentative de remplissage.
Mettre à jour: Fixé dans pull request # 58.
[H03] Un fabricant malveillant pourrait profiter des remplissages partiels pour voler les actifs du preneur
Les commandes du OrderMixin
contrat ont la possibilité d'être partiellement pourvus. Pour prendre en charge les remplissages partiels, le protocole nécessite un moyen de calculer les deux côtés des swaps. Tous les deux getMakerAmount
ainsi que getTakerAmount
les champs sont définis par le donneur d'ordre dans ce but précis.
Lors de l'exécution d'une commande, les preneurs doivent fournir soit le makingAmount
au sein de l’ takingAmount
valeurs ainsi qu'une thresholdAmount
valeur. Il existe deux chemins de code différents qui peuvent être empruntés, selon que le makingAmount
au sein de l’ takingAmount
a été fourni.
La première est lorsque le makingAmount
paramètre est défini. Ça pourrait tronquer le makingAmount
valeur et aussi Calculez le takingAmount
valeur pour cela. Dans cette situation, le thresholdAmount
assure que le takingAmount
la valeur prise est pas étonnamment grand.
La seconde est lorsque le takingAmount
paramètre est défini. Dans un tel cas, il sera Calculez le makingAmount
valeur, avec la possibilité de le tronquer ainsi que recalculer le takingAmount
valeur si cela se produit. Dans cette situation, le thresholdAmount
valeur assure que la makingAmount
la valeur renvoyée est pas étonnamment petit.
Il existe deux méthodes d'exploitation, chacune propre à l'un des chemins de code mentionnés précédemment. Ces méthodes d'exploitation nécessitent des getMakerAmount
ainsi que getTakerAmount
les fonctions. Une implémentation simple de ces fonctions aurait un comportement identique à AmountCalculator
's getMakerAmount
ainsi que getTakerAmount
fonctions, mais avec un commutateur codé en dur qui les forcera à renvoyer une valeur contrôlée par l'attaquant en cas de besoin.
Le premier modèle d'exploitation, moins grave, implique le premier chemin de code où le makingAmount
la valeur est spécifiée dans une commande de remplissage. Un fabricant malveillant attendrait une commande d'exécution qui spécifie makingAmount
pour apparaître dans le mempool afin de le diriger. Ils videraient toute la valeur sauf 1 du côté du fabricant, puis forceraient _callGetTakerAmount
pour retourner le montant spécifié dans le thresholdAmount
valeur (ou leur allocation si elle est inférieure). Lorsque la transaction de l'utilisateur aura finalement abouti, il échangera son plein thresholdAmount
la valeur de takerAsset
pour une seule unité de makerAsset
. Cet exploit est limité par le montant donné par le thresholdAmount
valeur ou le montant de la takerAsset
l'utilisateur autorisé sur le LimitOrderProtocol
contrat.
Le deuxième modèle d'exploitation, plus grave, implique le deuxième chemin de code où le takingAmount
la valeur est spécifiée. Le fabricant malveillant attendrait de la même manière une commande d'exécution qui spécifiait un takingAmount
valeur à afficher dans le mempool. Ils feraient avancer la transaction et forceraient le makingAmount
valeur renvoyée par _callGetMakerAmount
fonction supérieure à la fois à la remainingMakerAmount
et par thresholdAmount
. Ils établiraient également le takingAmount
valeur renvoyée par _callGetTakerAmount
être le montant de takerAsset
actif autorisé sur le LimitOrderProtocol
par le preneur. Lorsque la transaction du preneur aboutira, il tronquer le makingAmount
valeur et ensuite recalculer le takingAmount
valeur. Ce recalcul n'est cependant pas garanti inférieur, et dans ce cas videra le preneur de tous les takerAsset
qu'ils ont autorisé sur le contrat. Dans ce chemin de code, le thresholdAmount
valeur est s'assurer que le makingAmount
n'est pas trop bas, donc en prenant tous les preneurs takerAsset
l'actif n'est pas coché. Les fonds perdus sont limités par le montant de la takerAsset
actif que l'utilisateur a autorisé sur le LimitOrderProtocol
contrat.
Ces exploits ne sont pas possibles sans commandes partielles et, plus précisément, des commandes partielles avec des getMakerAmount
ainsi que getTakerAmount
mises en œuvre.
L'enjeu principal de la thresholdAmount
Le contrôle de valeur est qu'il ne couvre qu'un côté du swap, mais l'autre côté peut être manipulé via le frontrunning. Rien ne garantit que la valeur initialement proposée par le preneur reste inchangée. Envisagez de supprimer makingAmount
troncature des deux chemins de code et retour si la commande ne peut pas prendre en charge un remplissage aussi grand que celui demandé. En faisant cela, le thresholdAmount
peut être utilisé pour restreindre suffisamment l'autre côté du swap et éviter les comportements inattendus, même dans les commandes malveillantes.
Mettre à jour: Fixé dans pull request # 83.
Gravité moyenne
[M01] Arguments statiques passés après les arguments dynamiques
Dans le OrderMixin
contrat, le getTakerAmount
ainsi que getMakerAmount
les champs d'octets sont utilisés comme arguments pour le _callGetTakerAmount
ainsi que _callGetMakerAmount
les fonctions. Ces appels fournissent un moyen de calculer un côté du swap en fonction de l'autre côté, et ils permettent aux utilisateurs de remplir partiellement les commandes.
Les getTakerAmount
/getMakerAmount
les champs sont des variables dynamiques et sont emballés devant le takerAmount
ainsi que makerAmount
valeurs dans le _callGetTakerAmount
ainsi que _callGetMakerAmount
les fonctions. Il est possible qu'un fabricant malveillant fournisse plus de données que prévu dans le getTakerAmount
ainsi que getMakerAmount
champs pour pousser le takerAmount
ainsi que makerAmount
octets passés où ils sont supposés être lors du décodage dans la fonction suivante. Cela permet au fabricant de décaler le montant du preneur ou du fabricant transmis d'un octet complet vers la droite et même de les remplacer complètement si 32 octets de données supplémentaires sont fournis.
Les utilisateurs doivent déjà revoir manuellement le getTakerAmount
ainsi que getMakerAmount
champs dans l'ordre, mais cette technique est assez difficile à repérer. Il convient également de noter que cette attaque s'applique même à la confiance interne getMakerAmount
ainsi que getTakerAmount
les fonctions. Pour la plupart des attaques, fournir un montant seuil raisonnable empêchera la perte de fonds.
Pour éviter cela, envisagez de coder les arguments statiques avant les arguments dynamiques pour éviter de donner aux arguments dynamiques une méthode pour contrôler les arguments statiques.
Mettre à jour: Non fixé. L'équipe de 1 pouce a déclaré:
Nous prendrons des précautions supplémentaires avec la validation des getters. Nous essaierons d'implémenter la validation de santé mentale des getters dans notre SDK qui aidera à filtrer les commandes potentiellement malveillantes.
[M02] Les commandes ERC721 peuvent être manipulées
Il est possible d'échanger plus que des ERC20 via le OrderMixin
en déployant un contrat qui partage le même sélecteur de fonctions que l'IERC20 transferFrom
, et en fournissant ce contrat comme makerAsset
au sein de l’ takerAsset
dans une commande.
Les proxys hors champ d'application, à savoir, ERC721Proxy
, ERC721ProxySafe
et ERC1155Proxy
les contrats suivent ce modèle pour fournir un soutien aux ERC721
ainsi que ERC1155
jetons. Étant donné que les proxys doivent être appelés avec le même modèle qu'un IERC20 transferFrom
appel, la signature doit commencer par address from
, address to
ainsi que uint256 amount
. Tout ce dont les proxys ont besoin peut être transmis après et est défini dans la commande comme makerAssetData
ainsi que takerAssetData
.
Les ERC1155 peuvent naturellement transférer plusieurs des mêmes jetons d'identification à la fois, ce qui signifie que le ERC1155Proxy
contrat utilise le amount
domaine. D'autre part, ERC721
s n'ont pas d'utilité évidente pour les amount
domaine. Puisqu'ils représentent des jetons non fongibles, un tokenId spécifique n'en aura qu'un, ce qui rendra le amount
champ inutile. Pour cette raison, la mise en œuvre pour les deux ERC721Proxy
ainsi que ERC721ProxySafe
les contrats utilisent les amount
champ comme le tokenId
à la place.
Cette surcharge du amount
paramètre crée la possibilité de remplir partiellement ERC721
commandes afin d'acheter des jetons répertoriés séparément à des prix réduits. Par exemple, il peut arriver qu'un même utilisateur ait plusieurs ERC721
s du même contrat pouvant être cédés par le ERC721Proxy
contrat et les énumère dans des ordres limités distincts.
Si les ordres à cours limité prévoient également la getMakerAmount
ainsi que getTakerAmount
champs, il sera possible de remplir partiellement ces ERC721
ordres. Depuis la commande amount
champ correspond en fait au tokenId
, un utilisateur malveillant peut placer un remplissage partiel sur le ERC721
avec le tokenId le plus élevé, ce qui entraîne un makingAmount
/takingAmount
d'un ERC721
qui pourrait correspondre à une baisse tokenId
. Le résultat est le ERC721
avec le plus bas tokenId
seraient transférés au prix de (higher tokenId price) * (lower tokenId's id) / (higher tokenId's id)
.
Cet exploit a quelques exigences :
- Multiple
ERC721
s du même contrat pour être autorisés sur l'un ou l'autreERC721
procuration par un seul propriétaire. - Commande ouverte pour l'un des
ERC721
s ce n'est pas le plus bastokenId
de ceux autorisés. - Remplissages partiels autorisés sur la commande.
Pour supprimer complètement la possibilité de ERC721
remplit, envisagez de séparer les amount
ainsi que tokenId
arguments. Que les arguments soient séparés ou non, pensez également à documenter cela pour alerter les utilisateurs de ce comportement et éviter ce modèle à l'avenir.
Mettre à jour: Fixé dans pull request # 59.
[M03] Hypothèses décimales non documentées
Les LimitOrderProtocol
contrat hérite du ChainlinkCalculator
contrat par l'intermédiaire du OrderMixin
Contrat. Ce contrat expose deux fonctions pour permettre l'utilisation des oracles Chainlink pendant la vérification des prédicats et la recherche de montant du fabricant/montant preneur.
Cependant, le contrat fait des hypothèses non documentées sur le nombre de décimales que les oracles Chainlink doivent rapporter, ainsi que sur le nombre de décimales que les paramètres de la fonction doivent contenir. Dans certains scénarios, cela pourrait entraîner des comportements inattendus, notamment une mauvaise évaluation des actifs et la perte involontaire de fonds.
Plus précisément, tout au long du contrat, l'hypothèse implicite est que les oracles Chainlink rapporteront avec 18 décimales de précision. Cependant, non tous les oracles Chainlink rapport avec ce nombre de décimales. En fait, si l'oracle signale une paire de jetons en termes de devise (USD, par exemple), il n'aura que 8 décimales de précision. Puisqu'il n'y a pas de restrictions sur qui oracles peuvent être utilisés, il ne faut pas faire d'hypothèses implicites sur le nombre de décimales avec lesquelles ils rapporteront.
Dans le même ordre d'idées, il existe une hypothèse implicite selon laquelle le amount
paramètre pour la ChainlinkCalculator
les fonctions utiliseront 18 décimales, ainsi que la déclaration explicite trompeuse que le singlePrice
fonction Calculates price of token relative to ETH scaled by 1e18
. En réalité, même avec un oracle qui rapport avec 18 décimales, la valeur de retour du singlePrice
fonction serait mis à l'échelle par le nombre de décimales de la amount
paramètre, qui n'est pas nécessairement 18 décimales.
De même, le doublePrice
La fonction suppose que deux oracles Chainlink rapporteront avec le même nombre de décimales, ce qui entraînera un écart entre le résultat de la fonction et les attentes.
Envisagez de documenter explicitement les hypothèses concernant le nombre de décimales que les paramètres et les valeurs de retour doivent contenir. De plus, envisagez soit de limiter les calculs qui dépendent d'oracles qui brisent ces hypothèses, soit de faire en sorte que les calculs pertinents prennent en compte le nombre réel de décimales.
Mettre à jour: Fixé dans pull request # 75.
Faible gravité
[L01] Constantes non déclarées explicitement
Il y a quelques occurrences de valeurs littérales utilisées avec une signification inexpliquée dans la base de code. Par example:
- Dans le
OrderMixin
contrat, le_remaining
le mappage est sémantiquement surchargé (comme expliqué dans le numéro Surcharge sémantique de la cartographie) pour suivre le montant de l'actif restant pour une commande partiellement remplie ainsi que si une commande a été entièrement remplie. Spécifiquement,0
signifie qu'aucun remplissage associé à une commande n'a été effectué,1
signifie qu'une commande ne peut plus être remplie, et tout ce qui dépasse1
signifie qu'il reste un montant associé à la commande qui peut potentiellement être exécuté. - Dans le
ChainlinkCalculator
contrat, la valeur littérale1e18
est utilisé dans lesinglePrice
la fonction.
Pour améliorer la lisibilité du code et faciliter le refactoring, pensez à définir une constante pour chaque nombre magique, en lui donnant un nom clair et explicite. Pour les valeurs complexes, pensez à ajouter un commentaire en ligne expliquant comment elles ont été calculées ou pourquoi elles ont été choisies.
Mettre à jour: Fixé dans pull request # 75 ainsi que pull request # 76.
[L02] Des parties malveillantes pourraient empêcher l'exécution d'ordres autorisés
Les OrderMixin
le contrat permet aux utilisateurs maker de soumettre commandes autorisées afin que ceux-ci puissent être exécutés en une seule transaction, plutôt que d'avoir à avoir une transaction distincte pour les approbations. De plus, les preneurs de commandes peuvent soumettre son propre permis lors de l'exécution de la commande dans le même but.
Cependant, étant donné que le permis de fabricant se trouve à l'intérieur du de commander, les permis du fabricant et du preneur seraient accessibles pendant que la transaction de traitement des commandes se trouve dans le mempool. Cela permettrait à tout utilisateur malveillant de prendre ces autorisations et de les exécuter sur les contrats d'actifs respectifs tout en exécutant la transaction de remplissage. Étant donné que ces permis ont une nonce
pour éviter une double attaque de dépenses, la transaction d'exécution de la commande échouerait à la suite d'une tentative d'utilisation du même permis que celui qui vient d'être utilisé lors de la première exécution.
Bien qu'il n'y ait aucun risque de sécurité et que le fabricant puisse créer une nouvelle commande et pré-approuver la transaction, cette attaque pourrait certainement avoir un impact sur l'utilisabilité des commandes autorisées. En effet, un attaquant motivé pourrait bloquer TOUTE ordres autorisés avec cette attaque. Envisagez de valider si le permis a déjà été soumis, ou si l'allocation est suffisante, lors de l'exécution de la commande. Pensez également à informer les utilisateurs de cette éventuelle attaque lors de la composition de la commande.
Mettre à jour: Non fixé. L'équipe 1inch déclare:
Nous avions déjà effectué des vérifications d'approbation, mais nous avons décidé de simplifier le flux de permis pour simplement revenir sur les approbations infructueuses. Nous réfléchirons aux moyens d'informer les fabricants du problème.
[L03] Code dupliqué
Il existe des instances de code dupliqué dans la base de code. La duplication de code peut entraîner des problèmes plus tard dans le cycle de développement et rend le projet plus vulnérable à l'introduction d'erreurs. De telles erreurs peuvent être introduites par inadvertance lorsque les modifications de fonctionnalité ne sont pas répliquées sur toutes les instances de code qui devraient être identiques. Voici des exemples de code dupliqué :
Plutôt que de dupliquer le code, envisagez d'avoir un seul contrat ou une seule bibliothèque contenant le code dupliqué et de l'utiliser chaque fois que la fonctionnalité dupliquée est requise.
Mettre à jour: Partiellement fixé dans pull request # 60.
[L04] Suite de tests erronée ou trompeuse
Il existe des cas dans la suite de tests où les tests s'écartent de leur comportement attendu. Par exemple:
- Les
ChainlinkCalculator
contrat est hérité par leOrderMixin
Contrat. Cependant, lors des tests, lesAmountCalculator.arbitraryStaticCall
fonction est utilisée pour appeler leChainlinkCalculator
contrat comme un contrat externe et indépendant. Même si le résultat est celui attendu, le test doit refléter le comportement avec la conception actuelle du système et le cas d'utilisation anticipé en appelantChainlinkCalculator
fonctionne directement sans utiliser l'appel statique arbitraire. - Bien que les contrats de procuration soient hors de portée, nous avons remarqué que lors du test du protocole avec les actifs ERC721, le
ERC721Proxy
contrat n'est pas utilisé pour échanger les actifs dans son suite de tests.
Étant donné que la suite de tests elle-même n'entre pas dans le cadre de cet audit, veuillez envisager d'examiner attentivement la suite de tests pour vous assurer que tous les tests s'exécutent avec succès conformément aux spécifications du protocole.
Mettre à jour: Fixé dans pull request # 57, pull request # 59et pull request # 61.
[L05] Erreurs et omissions dans les événements
Dans toute la base de code, des événements sont généralement émis lorsque des modifications sensibles sont apportées aux contrats. Cependant, de nombreux événements manquent de paramètres indexés et/ou manquent de paramètres importants. Par example:
Il existe également des actions sensibles qui manquent d'événements, telles que :
Envisagez d'indexer plus complètement les événements existants et d'ajouter de nouveaux paramètres là où ils manquent. Envisagez également d'émettre tous les événements de manière si complète qu'ils pourraient être utilisés pour reconstruire l'état du contrat par des services hors chaîne.
Mettre à jour: Non fixé. Cependant, l'équipe de 1 pouce a ajouté un orderRemaining
paramètre à la OrderCanceled
événement dans pull request # 62.
L'équipe 1inch déclare:
Nous avons constaté que seul un sous-ensemble limité de données est nécessaire pour satisfaire les besoins frontaux. Dans le cas d'une analyse poussée, tous les champs suggérés sont disponibles via le traçage. Pour
OrderRFQMixin
nous nous attendons à ce que les teneurs de marché élaborent leur propre méthode sophistiquée de suivi des ordres annulés.
[L06] Changements de stockage lors de l'émission d'un événement
Dans le NonceManager
contrat, lorsque le NonceIncreased
événement est émis, le nonce de l'expéditeur du message est également augmenté.
L'exécution simultanée de plusieurs opérations peut rendre la base de code plus difficile à raisonner, plus sujette aux erreurs et peut conduire à des opérations négligées ou mal comprises.
Pour améliorer l'intentionnalité globale, la lisibilité et la clarté du code, envisagez d'augmenter la valeur nonce avant d'émettre l'événement.
Mettre à jour: Fixé dans pull request # 63.
[L07] Des méthodologies de décodage incohérentes pourraient entraîner des écarts de résultats
Pour prendre en charge toute son extensibilité et sa flexibilité, le protocole d'ordre limité doit régulièrement traiter des données d'octets dynamiques et des valeurs de retour arbitraires provenant de contrats externes. Par conséquent, le protocole comprend une ArgumentsDecoder
bibliothèque pour convertir plus efficacement les valeurs d'octets dynamiques en types de données de base. Cependant, cette bibliothèque n'est pas utilisée exclusivement, et dans certains cas abi.decode
est utilisé à la place. De plus, certains contrats utilisent abi coder v1
tandis que d'autres utilisent abi coder v2
. Le premier fonctionne de manière plus similaire au ArgumentsDecoder
bibliothèque, tandis que ce dernier effectue des vérifications supplémentaires lors du décodage.
L'utilisation incohérente de ces différentes méthodologies de décodage peut entraîner des écarts subtils entre l'intention et le comportement réel de la base de code.
Par exemple, le simulateCalls
la fonction utilise uniquement le ArgumentsDecoder.decodeBool
une fonction. Si la simulateCalls
est utilisée pour vérifier les appels qui seraient effectués dans la partie prédicat d'une commande, ses résultats pourraient s'écarter de ce qui se produit réellement lorsque les conditions de prédicat sont évaluées, car différentes méthodologies de décodage sont utilisées.
Ainsi, par exemple, si un prédicat fait un externe staticcall
à une fonction qui renvoie un uint256
valeur supérieure à un plutôt que la valeur attendue bool
, cet appel sera annulé, car la valeur de retour est décodé avec abi coder v2
's abi.decode
qui n'acceptera pas des valeurs telles que bool
. Cependant, si le même appel est passé avec simulateCalls
, puis il sera simplement marqué comme true
, Parce decodeBool
traite toute valeur supérieure à zéro comme true
.
Pour rendre le simulateCalls
fonction reflète entièrement le comportement des appels de prédicats réels, envisagez de le modifier pour l'utiliser abi.decode
.
Mettre à jour: Fixé dans pull request # 82.
[L08] Absence de validation des entrées
Les fillOrderToWithPermit
ainsi que fillOrderTo
fonctions du OrderMixin
contrat, ainsi que le fillOrderRFQToWithPermit
ainsi que fillOrderRFQTo
fonctions du OrderRFQMixin
contrat, ne validez pas le target
paramètre d'adresse.
Cela permet à un utilisateur de transmettre par inadvertance l'adresse zéro et, par conséquent, de verrouiller les actifs qu'il est censé recevoir après avoir rempli une commande.
Pour vous assurer que les utilisateurs ne verrouillent pas accidentellement leurs fonds, envisagez de valider que le target
l'adresse n'est pas égale à l'adresse zéro dans les fonctions citées.
Mettre à jour: Fixé dans pull request # 78.
[L09] Faible couverture des tests unitaires
La couverture des tests unitaires pour l'ensemble du projet est d'environ 75 %, certains contrats ayant une couverture particulièrement faible.
Compte tenu de l'importance des tests unitaires pour valider le code et éviter les régressions lors de la refactorisation et du développement de nouvelles fonctionnalités, nous encourageons l'augmentation significative de la couverture des tests unitaires à au moins 95 %, et l'inclusion de cas extrêmes qui couvrent même des situations improbables.
Mettre à jour: Non fixé.
[L10] Documentation en ligne trompeuse ou incomplète
Tout au long de la base de code, quelques cas de documentation en ligne trompeuse et/ou incomplète ont été identifiés et doivent être corrigés.
Voici des exemples de documentation en ligne trompeuse :
- Dans le
ChainlinkCalculator
contrat, lesinglePrice
les fonctions Spéc.Nat@notice
Étiquette dit qu'ilCalculates price of token relative to ETH scaled by 1e18
, mais en fait, son résultat est le Plus-value ofamount
jetons mis à l'échelle par1e18
, où l'oracle peut ne pas rapporter en termes d'ETH (pour une paire n'incluant pas l'ETH, par exemple). - Dans le
OrderRFQMixin
contrat, leinvalidatorForOrderRFQ
les fonctions Spéc.Nat@return
Étiquette est trompeur, car le guillemet n'a peut-être pas été rempli pour que le bit d'invalidation respectif ait été défini. La commande peut également avoir été annulée. - Sur les lignes 147, 165et 188 of
OrderMixin.sol
, la NatSpec@param
les balises sont agrammaticales. - En ligne 20 of
ERC1155Proxy.sol
,@notice
balise indique que le hachage calculé est le résultat du hachage dufunc_733NCGU
fonction, où il devrait être lefunc_301JL5R
fonction à la place.
Voici des exemples de documentation en ligne incomplète :
- Fonctions dans le
AmountCalculator
contrat ne décrivent aucun des paramètres. - Dans le
ChainlinkCalculator
contrat, lesinglePrice
ainsi quedoublePrice
les fonctions ne décrivent pas tous les paramètres. - Dans le
ImmutableOwner
contract, la variable publique et le modificateur n'ont pas de NatSpec. - Dans le
InteractiveNotificationReceiver
contrat, lenotifyFillOrder
fonction ne décrit aucun des paramètres. - Dans le
LimitOrderProtocol
contrat, leDOMAIN_SEPARATOR
la fonction n'a pas de NatSpec. - Événements et mappages dans le
NonceManager
n'ont pas de NatSpec. - Dans le
OrderRFQMixin
Contrat,cancelOrderRFQ*
les fonctions ne décrivent pas les valeurs de retour. - Dans le
OrderMixin
contrat, plusieurs fonctions manquent de NatSpec complète. - En ligne 168 of
OrderMixin.sol
et en ligne 71 ofOrderRFQMixin.sol
, il manque le@dev
Étiquette. - Fonctions dans le
PredicateHelper
contrat ne décrivent pas tous les paramètres.
Une documentation en ligne claire est fondamentale pour décrire les intentions du code. Les incompatibilités entre la documentation en ligne et l'implémentation peuvent conduire à de graves idées fausses sur la façon dont le système est censé se comporter. Envisagez de corriger ces erreurs pour éviter toute confusion pour les développeurs, les utilisateurs et les auditeurs.
Mettre à jour: Partiellement corrigé. Documents trompeurs traités dans pull request # 75 ainsi que pull request # 77.
L'équipe 1inch déclare:
Nous avons corrigé les documents trompeurs. La finalisation des docs se fera plus tard.
[L11] Commandes DoS possibles lors de l'utilisation de crochets
Les OrderMixin
Le contrat implémente une fonctionnalité pour remplir les ordres d'échange génériques hors chaîne qui pourraient avoir des conditions pour leur succès. Pendant l'exécution des commandes, la commande peut vérifier les conditions de "prédicat" prédéfinies avant de poursuivre l'exécution.
Cependant, étant donné que ces conditions de prédicat pourraient cibler la logique de tout contrat arbitraire, un fabricant malveillant pourrait faire croire aux preneurs qu'une commande se comporte correctement et qu'elle est valide lors de sa vérification hors chaîne, mais qu'elle échoue lorsqu'elle tente de remplir la même commande. en chaîne. Ce changement dans le comportement du prédicat pourrait être effectué soit en exécutant en avant un état variable dont dépendent les prédicats, en examinant le gaz envoyé ou même quelles adresses sont impliquées dans l'appel, soit par une autre logique.
De plus, si le fabricant a défini un interaction pendant l'échange, interactionTarget
le contrat pourrait revenir sur lui-même ou révoquer l'autorisation pour empêcher une exécution réussie de la commande, conduisant essentiellement au même résultat que les prédicats malveillants.
Bien que les actifs ne soient pas menacés, les utilisateurs ou les bots trouvant une commande favorable auront la charge accrue d'essayer d'identifier ces types de commandes de spam qui peuvent sembler légitimes à première vue. Dans le cas où ils ne parviennent pas à identifier ces types de commandes, ils encourront des coûts de gaz gaspillés. Pour réduire le nombre de commandes de spam, envisagez de restreindre les cibles disponibles pour ces crochets. Pensez également à avertir les utilisateurs de cette possibilité avant qu'ils ne tentent d'exécuter des commandes.
Mettre à jour: Non fixé. L'équipe 1inch déclare:
Nous gérons cela sur notre backend et nous réfléchirons aux moyens d'informer les preneurs potentiels du problème.
[L12] L'arrondi peut être défavorable pour taker
Dans le OrderMixin
ainsi que OrderRFQMixin
contrats, lorsqu'une commande est en cours d'exécution et que le preneur ne fournit qu'un makingAmount
or takingAmount
montant, le protocole tente de calculer le montant de la contrepartie du swap.
Il y a deux problèmes avec ces calculs, le premier étant qu'il n'y a pas de documentation ou de logique limitant le nombre de décimales que les paramètres de montant doivent utiliser, ce que nous avons abordé dans le Hypothèses décimales non documentées problème.
Le deuxième problème est qu'au cours de ces calculs, le protocole tourne en faveur du fabricant. Le problème d'arrondi peut être considérablement exacerbé lorsque les hypothèses décimales implicites sont brisées, mais même lorsque tout est dans les termes attendus, l'arrondi se produira avec de petites quantités impaires.
Envisagez de permettre au preneur de spécifier un montant minimum de makerAsset
actif qu'ils sont prêts à recevoir avec un montant maximum de takerAsset
l'actif qu'ils sont prêts à échanger, de sorte que l'acceptation de tout arrondi est plus explicite.
Mettre à jour: Non fixé. L'équipe 1inch déclare:
Le montant du seuil devrait être suffisant pour la protection du preneur.
[L13] Gestion des commandes contradictoires en l'absence de paramètres
Dans le OrderMixin
contrat, le fillOrderTo
la fonction effectue des appels internes au _callGetMakerAmount
ainsi que _callGetTakerAmount
fonctionne chaque fois qu'un remplissage est tenté et que makingAmount
au sein de l’ takingAmount
paramètres sont zéro, respectivement, ou si les makingAmount
la valeur est plus grande que la remainingMakerAmount
valeur.
Les _callGetMakerAmount
ainsi que _callGetTakerAmount
les appels conduiront à des annulations si la commande n'a pas été créée avec le getMakerAmount
or getTakerAmount
paramètres, respectivement, et un remplissage partiel est en cours d'exécution.
An commentaire en ligne à côté _callGetMakerAmount
et le commentaire en ligne à côté _callGetTakerAmount
prétendre que "seuls les remplissages entiers sont autorisés" si la commande n'a pas été créée avec getMakerAmount
or getTakerAmount
paramètres.
Cependant, il existe des chemins de code pour lesquels cela ne s'applique pas, car ces chemins ne vérifient pas le length
s des deux getMakerAmount
ainsi que getTakerAmount
paramètres.
Plus précisément, lorsqu'un taker
spécifie un takerAmount
valeur pour une commande qui n'a qu'un getMakerAmount
, à moins que cet appel à getMakerAmount
renvoie un montant supérieur à remainingMakerAmount
, un remplissage partiel peut être exécuté en contradiction avec la documentation en ligne.
Cela laisse l'intentionnalité de ces chemins de code incertaine. S'il s'agit du comportement attendu, envisagez de modifier la documentation en ligne afin qu'elle soit plus explicite. S'il s'agit d'un comportement involontaire, pensez à toujours vérifier les longueurs des getMakerAmount
et par getTakerAmount
paramètres simultanément afin que l'implémentation renforce le comportement décrit par la documentation en ligne.
Mettre à jour: Fixé dans pull request # 79.
[L14] Utilisation d'appels Chainlink obsolètes
Les ChainlinkCalculator
contract est destiné à être utilisé pour interroger les oracles Chainlink. Il le fait en passant des appels à leur latestTimestamp
ainsi que latestAnswer
Méthodes, qui ont tous deux été dépréciés. En effet, les méthodes ne sont plus présentes dans l'API des agrégateurs Chainlink à partir de la version trois.
Pour éviter d'éventuelles incompatibilités futures avec les oracles Chainlink, pensez à utiliser le latestRoundData
à la place.
Mettre à jour: Fixé dans pull request # 67.
Remarques et informations supplémentaires
[N01] Ne pas importer les interfaces
Les AggregatorInterface
l'interface semble être un sous-ensemble de code copié à partir de ChainLink
référentiel de code public de. L'interface complète est incluse dans ChainLink
le contrat de npm package.
Lorsque cela est possible, pour réduire le risque d'incompatibilités d'interface et de problèmes qui en résultent, plutôt que de redéfinir et/ou de réécrire les interfaces d'un autre projet, envisagez plutôt d'utiliser les interfaces installées via leurs packages npm officiels.
Mettre à jour: Fixé dans pull request # 66.
[N02] Dépendances de projet obsolètes
Lors de l'installation du dépendances du projet, NPM avertit que l'un des packages installés, Highlight
, "ne sera plus pris en charge ou ne recevra plus de mises à jour de sécurité à l'avenir".
Même s'il est peu probable que ce package puisse entraîner un risque de sécurité, envisagez de mettre à niveau la dépendance qui utilise ce package vers une version maintenue.
Mettre à jour: Fixé dans pull request # 64.
[N03] Les appels externes pour afficher les méthodes ne sont pas des appels statiques
Dans la majeure partie de la base de code, le protocole effectue explicitement des appels externes via OpenZeppelin functionStaticCall
méthode pour limiter la possibilité de changements d'état lorsqu'ils ne sont pas attendus ou souhaitables. Cependant, dans le ChainlinkCalculator
contrat, malgré l'intention de faire des appels externes uniquement pour view
méthodes sur les oracles Chainlink, les appels externes dans le singlePrice
ainsi que doublePrice
les fonctions ne sont pas faites via explicite staticcall
s.
Bien que nous n'ayons identifié aucun problème de sécurité immédiat découlant de cela, pour réduire la surface d'attaque, améliorer la cohérence et clarifier l'intention, envisagez d'utiliser des staticcall
s, pour tous les appels externes vers view
fonctions dans le ChainlinkCalculator
contrat.
Mettre à jour: Non fixé. L'équipe 1inch déclare:
Nous pensons que la complication de la syntaxe annule les améliorations de cohérence.
[N04] Ne pas échouer tôt avec des commandes invalides
Dans le OrderMixin
contrat, le fillOrderTo
La fonction gère la condition spéciale lorsqu'une commande n'a pas été soumise auparavant (remainingMakerAmount == 0
), mais il ne gère pas explicitement la condition lorsque la commande n'est plus valide (remainingMakerAmount == 1
).
Dans ce dernier scénario, la fonction finira par revenir, mais seulement après avoir brûlé des quantités non négligeables de gaz. Pour clarifier l'intention, augmenter la lisibilité et réduire la consommation de gaz, envisagez de gérer explicitement le scénario de commande invalide vers le début de la fonction.
Mettre à jour: Fixé dans pull request # 68.
[N05] Contrats d'assistance non marqués comme abstraits
Dans Solidity, le mot clé abstract
est utilisé pour les contrats qui ne sont pas des contrats fonctionnels à part entière ou qui ne sont pas destinés à être utilisés comme tels. Plutôt, abstract
les contrats sont hérités par d'autres contrats dans le système pour créer des contrats fonctionnels autonomes.
Tout au long de la base de code, il existe des exemples de contrats d'assistance qui ne sont pas marqués comme abstraits, malgré le fait qu'ils ne sont pas destinés à être déployés seuls. Par exemple, le AmountCalculator
, ChainlinkCalculator
, ImmutableOwner
, NonceManager
et PredicateHelper
les contrats sont tous composés d'un ensemble de fonctions de base destinées à être utilisées par les contrats hérités.
Envisagez de marquer les contrats d'aide comme abstract
pour signifier clairement qu'ils sont conçus uniquement pour ajouter des fonctionnalités aux contrats qui en héritent.
Mettre à jour: Non fixé. L'équipe 1inch déclare:
Ces assistants peuvent être déployés séparément. Ils sont hérités uniquement pour les économies de gaz.
[N06] Ordre des fonctions incohérent
Tout au long de la base de code, l'ordre des fonctions suit généralement le ordre recommandé dans le Solidity Style Guide, lequel est: constructor
, fallback
, external
, public
, internal
, private
.
Cependant, dans le OrderMixin
contrat, le public
checkPredicate
fonction s'écarte du guide de style, coupant en deux la external
fonctions.
Pour améliorer la lisibilité globale du projet, envisagez de normaliser l'ordre des fonctions dans la base de code, comme recommandé par le Solidity Style Guide.
Mettre à jour: Fixé dans pull request # 69.
[N07] Flux d'exécution des commandes incohérent
Les OrderMixin
ainsi que RFQOrderMixin
les deux contrats gèrent l'exécution des commandes signées, mais le flux général des commandes entre les deux contrats est incohérent.
OrderMixin
's fillOrderTo
fonction suit ce flux général (pseudo-code):
if ((takingAmount == 0) == (makingAmount == 0))
else if (takingAmount == 0)
else (handle makingAmount == 0) THEN swapTokens
Tandis que RFQOrderMixin
est analogue fillOrderRFQTo
la fonction suit ce flux (pseudo-code) :
if (takingAmount == 0 && makingAmount == 0)
else if (takingAmount == 0)
else if (makingAmount == 0)
else revert THEN swapTokens
La documentation ne donne aucune idée de la raison pour laquelle le premier conditionnel de chacune de ces deux fonctions diffère, ou pourquoi takingAmount
ainsi que makingAmount
ne peuvent pas tous deux être nuls dans cette dernière fonction. Aussi, le cas où à la fois un makingAmount
et takingAmount
sont fournis est beaucoup plus facile de raisonner dans le fillOrderRFQTo
fonction, puisqu'elle est traitée clairement dans la version finale else
bloque.
Pour clarifier l'intention et augmenter la lisibilité globale du code, envisagez soit de normaliser le flux général des commandes entre ces deux contrats, soit de documenter explicitement pourquoi les différences existent.
Mettre à jour: Non fixé. L'équipe 1inch déclare:
Cela est dû aux fonctions de tarification personnalisées dans les ordres à cours limité. Depuis
getMakerAmount
peut potentiellement différer considérablement degetTakerAmount
, nous avons pensé qu'il valait mieux ne pas faire d'option par défaut pour le preneur car cela les confondrait probablement dans les cas où ces getters seraient différents.
[N08] Les messages d'erreur sont formatés de manière incohérente ou trompeurs
Dans toute la base de code, le require
ainsi que revert
les messages d'erreur, destinés à informer les utilisateurs des conditions particulières provoquant l'échec d'une transaction, se sont avérés être formatés de manière incohérente.
Par exemple, chacun des messages d'erreur sur les lignes 85 de OrderMixin.sol
, 16 de ERC721ProxySafe.sol
et 26 de Permitable.sol
employer un style différent.
De plus, certains messages d'erreur sont trompeurs :
Les messages d'erreur sont destinés à informer les utilisateurs des conditions défaillantes, ils doivent donc fournir suffisamment d'informations pour que les corrections appropriées puissent être apportées pour interagir avec le système. Les messages d'erreur non informatifs endommagent considérablement l'expérience globale de l'utilisateur, réduisant ainsi la qualité du système. De plus, des messages d'erreur au format incohérent peuvent introduire une confusion inutile. Par conséquent, envisagez de revoir l'intégralité de la base de code pour vous assurer que chaque require
ainsi que revert
L'instruction contient un message d'erreur formaté de manière cohérente, précis, informatif et convivial.
Mettre à jour: Partiellement fixé dans pull request # 81.
[N09] Utilisation incohérente des variables de retour nommées
Il y a une utilisation incohérente des variables de retour nommées dans le OrderMixin
Contrat. Certaines fonctions retourner les variables nommées, autres retourner des valeurs explicites, et d'autres déclarer une variable de retour nommée mais la remplacer avec une instruction de retour explicite.
Envisagez d'adopter une approche cohérente pour renvoyer des valeurs dans toute la base de code en supprimant toutes les variables de retour nommées, en les déclarant explicitement en tant que variables locales et en ajoutant les instructions de retour nécessaires, le cas échéant. Cela améliorerait à la fois l'explicitation et la lisibilité du code, et cela pourrait également aider à réduire les régressions lors des futures refactorisations de code.
Mettre à jour: Fixé dans pull request # 73.
[N10] Le calcul de hachage de la commande n'est pas ouvert à l'API
Les external
fonctions remaining
, remainingRaw
ainsi que remainingsRaw
tous attendent un hachage de commande pour une opération réussie.
Cependant, la fonction d'assistance _hash
, qui renvoie le hachage d'une commande, a private
visibilité. Cela signifie que les utilisateurs devront emballer manuellement des parties des commandes et des chaînes de domaine afin d'obtenir le hachage d'une commande.
Pour éviter le risque d'erreurs lors du calcul des hachages de commande et pour fournir aux utilisateurs une méthode de génération du hachage respectif d'une commande, envisagez d'étendre la visibilité des _hash
fonction à public
et refactoriser le nom pour hash
pour être cohérent avec le reste du code.
Mettre à jour: Fixé dans pull request # 74.
[N11] Surcharge sémantique du mapping
Les _remaining
cartographie dans le OrderMixin
contract est sémantiquement surchargé pour suivre l'état des commandes et le montant restant des actifs disponibles pour ces commandes.
Les trois états qu'il peut prendre sont :
0
: Le hachage de la commande n'a pas encore été vu.1
: La commande a été annulée ou entièrement remplie.- Toutes
uint
plus grand que1
: Le restemakerAmount
disponible à remplir sur la commande plus1
.
Cette surcharge sémantique nécessite l'habillage et le déshabillage de cette valeur lors de lookup
, cancellation
, initialization
et storage
.
La surcharge sémantique et la logique nécessaire pour l'activer peuvent être sujettes à des erreurs et peuvent rendre la base de code plus difficile à comprendre et à raisonner, cela peut également ouvrir la porte à des régressions dans les futures mises à jour du code.
Pour améliorer la lisibilité du code, envisagez de suivre l'état d'achèvement des commandes dans un mappage distinct.
Mettre à jour: Non fixé. L'équipe de 1 pouce a indiqué qu'un correctif augmenterait les coûts de gaz pour le fillOrder
la fonction.
[N12] Les commandes avec permis autorisent les appels à des contrats arbitraires
Les OrderMixin
contrat hérite du Permitable
contrat pour permettre le remplissage de commandes en une seule transaction avec des actifs qui acceptent de tels permit
appels à modifier les indemnités.
Toutefois, malgré la appels au Permitable
contrat ne validez pas si la cible est un actif autorisé ni même s'il s'agit d'un actif, ce qui pourrait permettre à un utilisateur malveillant de transmettre l'adresse d'un contrat arbitraire qui pourrait exécuter un autre appel avant la fin du traitement de la commande.
Bien que le contrat soit protégé contre la réentrance, réduire la surface d'attaque et empêcher l'appel de contrats externes pendant l'exécution est toujours recommandé. Envisagez de restreindre l'actif impliqué dans le permis aux actifs impliqués dans la commande ou à une liste blanche d'actifs pour le protocole.
Mettre à jour: Non fixé. L'équipe 1inch déclare:
OrderMixin
n'a pas réellement d'informations sur les jetons réels carmakerAsset
ainsi quetakerAsset
il s'agit parfois de procurations ou d'autres contrats intermédiaires et les informations sur les jetons réels sont stockées dans des octets arbitraires. Il n'existe donc aucun moyen viable de restreindre l'actifpermit
est appelé.
[N13] solhint
n'est jamais réactivé
Tout au long de la base de code, il y a quelques solhint-disable
déclarations, en particulier celles en ligne 23 et en ligne 41 of RevertReasonParser.sol
, qui ne se terminent pas par solhint-enable
.
Privilégier l'explicitation et être le plus restrictif possible lors de la désactivation solhint
, pensez à utiliser solhint-disable-line
or solhint-disable-next-line
à la place, similaire à la ligne 16 du même fichier.
Mettre à jour: Fixé dans pull request # 72.
[N14] Fautes de frappe
La base de code contient les fautes de frappe suivantes :
De plus, le projet README
(hors de portée pour cet audit) contient les fautes de frappe suivantes :
Pensez à corriger ces fautes de frappe pour améliorer la lisibilité du code.
Mettre à jour: Fixé dans pull request # 71 ainsi que pull request # 77.
[N15] Utilisation de uint
au lieu de uint256
Pour favoriser l'explicitation, toutes les instances de uint
doit être déclaré comme uint256
. En particulier, ceux du for
boucles sur les lignes 98 ainsi que 119 of OrderMixin.sol
et lignes 16 ainsi que 30 of PredicateHelper.sol
.
Mettre à jour: Fixé dans pull request # 70.
Conclusions
3 problèmes de gravité élevée ont été détectés. Certaines modifications ont été proposées pour suivre les meilleures pratiques et réduire la surface d'attaque potentielle.
- &
- 7
- Qui sommes-nous
- accès
- Selon
- Compte
- à travers
- Agis
- actes
- Supplémentaire
- propos
- Avantage
- Tous
- Permettre
- déjà
- Bien que
- quantités
- selon une analyse de l’Université de Princeton
- api
- une approche
- arguments
- autour
- atout
- Outils
- audit
- Back-end
- Début
- va
- LES MEILLEURS
- les meilleures pratiques
- Bit
- les robots
- construire
- Appelez-nous
- les soins
- cas
- Causes
- Maillon de chaîne
- Change
- vérification
- Contrôles
- code
- complexe
- condition
- confusion
- construction
- contient
- contrat
- contrats
- Corrections
- Costs
- pourriez
- Couples
- créateur
- Devise
- Courant
- données
- affaire
- Déni de service
- déployer
- Conception
- mobiles
- Développement
- DID
- différer
- différent
- domaine
- double
- Dynamic
- "Early Bird"
- Edge
- encourager
- notamment
- ETH
- événement
- événements
- peut
- exemple
- échange
- attendu
- Découvrez
- Exploiter
- Fonctionnalités:
- Des champs
- finalement
- Prénom
- Fixer
- Flexibilité
- flux
- suivre
- trouvé
- plein
- fonction
- fonds
- avenir
- jeu
- GAS
- Général
- Don
- l'
- guide
- Maniabilité
- hachage
- Hachage
- ayant
- aider
- Haute
- très
- Comment
- HTTPS
- Hybride
- identifier
- Impact
- Mettre en oeuvre
- important
- l'importation
- inclus
- Y compris
- Améliore
- increased
- info
- d'information
- Infrastructure
- idées.
- intention
- intérêt
- Interfaces
- impliqué
- vous aider à faire face aux problèmes qui vous perturbent
- IT
- gros
- plus importantes
- conduire
- conduisant
- Bibliothèque
- limité
- Gamme
- Liquidité
- Listé
- Liste
- locales
- regardé
- rechercher
- majeur
- fabricant
- Fabrication
- Marché
- Mempool
- miroir
- modèle
- (en fait, presque toutes)
- Le Plus Populaire
- à savoir
- Nouvelles fonctionnalités
- non fongible
- jetons non fongibles
- officiel
- ouvert
- Opérations
- Option
- oracle
- de commander
- passer commande
- Autre
- propriétaire
- Patron de Couture
- Populaire
- représentent
- prévention
- prix
- établissement des prix
- Privé
- processus
- Projet
- projets
- protection
- protocole
- fournir
- fournit
- procuration
- public
- publier
- achat
- qualité
- augmenter
- Réalité
- réduire
- dépendance
- rapport
- Rapports
- dépôt
- Exigences
- REST
- Résultats
- Retours
- Avis
- Analyse
- tours
- Courir
- Sdk
- sécurité
- Services
- set
- commun
- Partages
- décalage
- similaires
- étapes
- petit
- smart
- Contrats intelligents
- So
- solidité
- le spam
- spécifiquement
- Dépenses
- Spot
- Commencer
- Région
- Déclaration
- États
- Statut
- storage
- Catégorie
- soumis
- succès
- réussi
- Avec succès
- Support
- Appareils
- Surface
- Interrupteur
- combustion propre
- Target
- tester
- Essais
- tests
- Avec
- tout au long de
- fiable
- ensemble
- jeton
- Tokens
- suivre
- Tracking
- transaction
- La confiance
- unique
- Actualités
- us
- convivialité
- USD
- USDT
- utilisateurs
- utilitaire
- Plus-value
- Voir
- définition
- attendez
- Quoi
- whitelist
- dans les
- sans
- Activités principales
- vaut
- zéro