Arbitrage triangulaire sur Uniswap v3

Intermédiaire5/7/2024, 10:38:35 AM
L'arbitrage triangulaire sert de stratégie dans le trading d'échange de crypto-monnaie, en exploitant les variations des taux de change au sein d'un seul marché ou à travers plusieurs marchés.

Implémenté avec des échanges multihop

L'arbitrage triangulaire sert de stratégie dans le trading d'échange de crypto, exploitant les variations des taux de change au sein d'un seul marché ou à travers plusieurs marchés. Cette méthode comprend trois transactions séquentielles : échanger une crypto-monnaie initiale contre une deuxième, la deuxième contre une troisième, et enfin, la troisième crypto contre la première, le tout dans le but de générer des bénéfices. Ainsi, le terme "triangulaire" encapsule son processus en trois étapes.

Image générée par l'IA

Comment ça marche?

Sur DEX, les opportunités d'arbitrage triangulaire sont généralement causées par des différences de liquidité à travers plusieurs pools. Elles sont généralement de courte durée, ne durant que quelques secondes ou même moins, car l'échange ajuste rapidement toute disparité de prix. Par conséquent, des algorithmes de trading automatisés capables d'exécuter rapidement des transactions sont utilisés pour tirer parti de ces différences fugaces. Pour aider à comprendre le concept, voici un exemple :

La transaction triangulaire ci-dessus commence à 01 - l'achat de 1 wBTC avec 60 000 $ USDC, suivi de 02 - l'achat de 16 WETH avec 1 wBTC et s'est terminé par 03 - la vente de 16 WETH pour 66 000 $ USDC. À la fin du voyage, nous aurions obtenu 6 000 $ USDC de profit.

Implémentation avec Mutihop Swaps sur Uniswap v3

Il existe deux styles de permutation multi-sauts disponibles sur Uniswap v3 : Entrée Exacte et Sortie Exacte. Comme leurs noms l'indiquent, le premier s'attend à ce que le jeton soit exactement le montant en entrée de la permutation, et à la fin de celle-ci, un jeton avec un montant sera produit aux taux de change ; Le second s'attend à un montant exact spécifié en sortie, seule une quantité suffisante de jeton en entrée peut satisfaire l'échange aux taux de change.

Avec la nature commerciale de l'arbitrage triangulaire, nous aimerions prendre un jeton avec le montant exact comme entrée, l'échanger contre un autre crypto, puis l'échanger à nouveau contre le jeton d'origine pour réaliser un profit, comme nous le souhaitons.

adresse constante SWAP_ROUTER_02 = 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45;

adresse constante WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

adresse constante USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;

adresse constante DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;

contrat MultiHopSwap { using SafeERC20 pour IERC20;ISwapRouter02 privé constant ROUTER = ISwapRouter02(SWAP_ROUTER_02);uint256 privé constant MAX_INT =   115792089237316195423570985008687907853269984665640564039457584007913129639935;fonction swapExactInputMultiHop(uint256 amountIn) externe {   IERC20(USDC).safeApprove(address(ROUTER), MAX_INT);   IERC20(WETH).safeApprove(address(ROUTER), MAX_INT);   IERC20(DAI).safeApprove(address(ROUTER), MAX_INT);   bytes memory path =       abi.encodePacked(USDC, uint24(3000), WETH, uint24(3000), DAI, uint24(3000), USDC) ;   ISwapRouter02.ExactInputParams memory params = ISwapRouter02       .ExactInputParams({       path: path,       recipient: address(this),       amountIn: amountIn,       amountOutMinimum: 1   });   ROUTER.exactInput(params); }}

Les routeurs jouent un rôle crucial dans la facilitation de la fourniture de liquidité. Comme ils sont sans état et ne détiennent pas de soldes de jetons, les routeurs peuvent être remplacés en toute sécurité. Pour cette raison, les routeurs ont des numéros de version, commençant par 01. Dans notre implémentation, nous utilisons Router02 à 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45sur le réseau principal.

SafeERC20 est une couche de protection construite autour des transactions ERC20, garantissant une interaction sécurisée avec les jetons ERC20 au sein de notre contrat. Contrairement aux fonctions ERC20 régulières, SafeERC20 renforce la sécurité en vérifiant les valeurs de retour booléennes des opérations ERC20. Si une opération échoue, la transaction est annulée, minimisant les risques. De plus, SafeERC20 prend en charge les jetons ERC20 non standard ne disposant pas de valeurs de retour booléennes, offrant ainsi une flexibilité et une robustesse dans la gestion des jetons. En approuvant le montant maximal, nous permettons à Router02 de transférer des jetons en notre nom. Sans cela, vous vous attendriez à voir un message d'erreur STF dans lequel STF signifie que l'exécution est annulée par l'assertion require dans la fonction TransferHelper.safeTransferFrom.

Ensuite, nous verrons comment un chemin triangulaire est défini :

bytes memory path = abi.encodePacked(USDC, uint24(3000),

WETH, uint24(3000), DAI,  uint24(3000), USDC) ;

À travers abi.encodePacked, Solidity emballe étroitement plusieurs valeurs sans ajouter de rembourrage. Il concatène les données binaires brutes de chaque paramètre. Pas difficile de comprendre que les paramètres séquentialisés les swaps avec frais entre les paires de cryptomonnaies. Le chemin commence par USDC et s'arrête à USDC en espérant un profit. Ensuite, il est enveloppé par ExactInputParams avec d'autres paramètres obligatoires et alimenté dans le routeur pour un échange multi-sauts.

Test

Nous utilisons la même technique parforking mainnet avec impersonation. Une fois que 10 USDC ont été vérifiés comme crédités sur le contrat, les échanges multi-sauts peuvent être déclenchés comme ci-dessous :

it("effectue un échange multi-saut", async () => {balance = await swap.tokenBalance(USDC);console.log(`Solde actuel de USDC = ${balance}`);console.log(`Échange de ${initialFundingHuman} USDC`);const tx = await swap.swapExactInputMultiHop(ethers.parseUnits(initialFundingHuman, DECIMALS));receipt = await tx.wait();balance = await swap.tokenBalance(USDC);console.log(`Solde actuel de USDC = ${balance}`);expect(balance).not.equal(0);});

Le résultat du test devrait ressembler à ce qui suit :

Solde USDC du whale: 170961218210457n

Impersonation Started.

Impersonation terminée.

Solde actuel de USDC = 100000000

Échange de 100 USDC

Solde actuel de USDC = 91677417

Après avoir sauté à travers les obstacles, nous avons perdu de l'argent - De toute évidence, le chemin avec les taux au comptant n'était pas en notre faveur, mais vous avez une idée de la manière dont l'arbitrage triangulaire devrait être réalisé en utilisant des swaps multi-sauts sur Uniswap v3.

Prêt flash financé arbitrage triangulaire

N'ai-je pas dit la source de financement la plus puissante dans l'écosystème DeFi est le prêt FlashIl ne vous faudra pas beaucoup de créativité pour construire une stratégie de trading d'arbitrage triangulaire financée par un prêt Flash en utilisant à la fois un prêt Flash et des swaps multihop que j'ai enseignés. Une logique combinée peut être expliquée par le diagramme de séquence mis à jour ci-dessous :

Diagramme de séquence pour l'arbitrage triangulaire financé par prêt éclair sur Uniswap v3 (Opérations ignorées pour des raisons de simplicité)

Découvrez mon code source pour les prêts Flash et les échanges Multihop mis en œuvre sur Uniswap v3 — https://medium.com/cryptocurrency-scripts/flash-loan-on-uniswap-v3-84bca2bfe255, digérer le diagramme de séquence et faites vos devoirs pour obtenir la combinaison des contrats intelligents terminée.

Considérations de rentabilité

La première chose que nous voulons regarder est le chemin qui se compose de la séquence des 3 transactions : Pour être rentables, elles doivent être les bonnes 3 paires de crypto aux bons taux. Afin de trouver toute cette justesse, vous devez développer un programme qui permutte les paires échangeables dans le schéma de l'arbitrage triangulaire et simuler les échanges pour vérifier la rentabilité. Récupérer des taux à partir de la blockchain peut être lent et cela ralentira encore le processus s'il y a trop de chemins en attente d'être vérifiés pour la rentabilité. Vous voudrez peut-être réduire la liste des chemins triangulaires en calculant le Profit & Loss basé sur les prix de surface fournis par les points de tarification GraphQL d'une DEX, le cas échéant (ici vient Uniswap v3’s) Les API GraphQL sont beaucoup plus rapides que la blockchain pour fournir des données de cotation. Une fois les chemins présélectionnés, exécutez-les avec des devis récupérés de la chaîne pour un calcul plus précis des bénéfices et des pertes.

Booster votre investissement avec un prêt flashpeut encore étendre le profit - emprunter des jetons à faible intérêt et les investir avec une stratégie rentable sera toujours une bonne idée. Théoriquement, tant que le bénéfice brut est suffisant pour couvrir le prêt Flash et les frais d'échange, la stratégie d'arbitrage triangulaire sera considérée comme rentable. Un truc essentiel pour protéger votre profit et atténuer le risque global de trading est d'avoir une logique dans votre contrat de trading pour annuler la transaction de prêt flash si le contrôle de la rentabilité brute échoue, car lorsque la transaction échoue, toutes les opérations seront annulées et vous n'aurez pas à supporter la perte et même les frais de la transaction. Cette logique agira comme un gardien universel pour prévenir le glissement ou le mouvement du taux de change qui n'est pas en notre faveur.

Cela étant dit, que la transaction réussisse ou échoue, les frais de gaz sont quelque chose dont vous ne pourrez jamais vous échapper et pourraient être la principale cause de votre perte d'argent dans l'arbitrage triangulaire. Évaluez toujours les frais de gaz pour la transaction de votre stratégie et intégrez-les dans le calcul de rentabilité net. Veuillez vous référer aux cas de test d'estimation des frais de gaz dans mon code source.

Avertissement:

  1. Cet article est repris de [GateScripts de cryptomonnaie], Tous les droits d'auteur appartiennent à l'auteur original [Aaron Li]. Si vous avez des objections à cette réimpression, veuillez contacter le Gate Learnéquipe, et ils s'en occuperont rapidement.
  2. Responsabilité déniée: Les points de vue et opinions exprimés dans cet article sont uniquement ceux de l'auteur et ne constituent aucun conseil en investissement.
  3. Les traductions de l'article dans d'autres langues sont effectuées par l'équipe Gate Learn. Sauf mention contraire, la copie, la distribution ou le plagiat des articles traduits est interdit.

Arbitrage triangulaire sur Uniswap v3

Intermédiaire5/7/2024, 10:38:35 AM
L'arbitrage triangulaire sert de stratégie dans le trading d'échange de crypto-monnaie, en exploitant les variations des taux de change au sein d'un seul marché ou à travers plusieurs marchés.

Implémenté avec des échanges multihop

L'arbitrage triangulaire sert de stratégie dans le trading d'échange de crypto, exploitant les variations des taux de change au sein d'un seul marché ou à travers plusieurs marchés. Cette méthode comprend trois transactions séquentielles : échanger une crypto-monnaie initiale contre une deuxième, la deuxième contre une troisième, et enfin, la troisième crypto contre la première, le tout dans le but de générer des bénéfices. Ainsi, le terme "triangulaire" encapsule son processus en trois étapes.

Image générée par l'IA

Comment ça marche?

Sur DEX, les opportunités d'arbitrage triangulaire sont généralement causées par des différences de liquidité à travers plusieurs pools. Elles sont généralement de courte durée, ne durant que quelques secondes ou même moins, car l'échange ajuste rapidement toute disparité de prix. Par conséquent, des algorithmes de trading automatisés capables d'exécuter rapidement des transactions sont utilisés pour tirer parti de ces différences fugaces. Pour aider à comprendre le concept, voici un exemple :

La transaction triangulaire ci-dessus commence à 01 - l'achat de 1 wBTC avec 60 000 $ USDC, suivi de 02 - l'achat de 16 WETH avec 1 wBTC et s'est terminé par 03 - la vente de 16 WETH pour 66 000 $ USDC. À la fin du voyage, nous aurions obtenu 6 000 $ USDC de profit.

Implémentation avec Mutihop Swaps sur Uniswap v3

Il existe deux styles de permutation multi-sauts disponibles sur Uniswap v3 : Entrée Exacte et Sortie Exacte. Comme leurs noms l'indiquent, le premier s'attend à ce que le jeton soit exactement le montant en entrée de la permutation, et à la fin de celle-ci, un jeton avec un montant sera produit aux taux de change ; Le second s'attend à un montant exact spécifié en sortie, seule une quantité suffisante de jeton en entrée peut satisfaire l'échange aux taux de change.

Avec la nature commerciale de l'arbitrage triangulaire, nous aimerions prendre un jeton avec le montant exact comme entrée, l'échanger contre un autre crypto, puis l'échanger à nouveau contre le jeton d'origine pour réaliser un profit, comme nous le souhaitons.

adresse constante SWAP_ROUTER_02 = 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45;

adresse constante WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

adresse constante USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;

adresse constante DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;

contrat MultiHopSwap { using SafeERC20 pour IERC20;ISwapRouter02 privé constant ROUTER = ISwapRouter02(SWAP_ROUTER_02);uint256 privé constant MAX_INT =   115792089237316195423570985008687907853269984665640564039457584007913129639935;fonction swapExactInputMultiHop(uint256 amountIn) externe {   IERC20(USDC).safeApprove(address(ROUTER), MAX_INT);   IERC20(WETH).safeApprove(address(ROUTER), MAX_INT);   IERC20(DAI).safeApprove(address(ROUTER), MAX_INT);   bytes memory path =       abi.encodePacked(USDC, uint24(3000), WETH, uint24(3000), DAI, uint24(3000), USDC) ;   ISwapRouter02.ExactInputParams memory params = ISwapRouter02       .ExactInputParams({       path: path,       recipient: address(this),       amountIn: amountIn,       amountOutMinimum: 1   });   ROUTER.exactInput(params); }}

Les routeurs jouent un rôle crucial dans la facilitation de la fourniture de liquidité. Comme ils sont sans état et ne détiennent pas de soldes de jetons, les routeurs peuvent être remplacés en toute sécurité. Pour cette raison, les routeurs ont des numéros de version, commençant par 01. Dans notre implémentation, nous utilisons Router02 à 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45sur le réseau principal.

SafeERC20 est une couche de protection construite autour des transactions ERC20, garantissant une interaction sécurisée avec les jetons ERC20 au sein de notre contrat. Contrairement aux fonctions ERC20 régulières, SafeERC20 renforce la sécurité en vérifiant les valeurs de retour booléennes des opérations ERC20. Si une opération échoue, la transaction est annulée, minimisant les risques. De plus, SafeERC20 prend en charge les jetons ERC20 non standard ne disposant pas de valeurs de retour booléennes, offrant ainsi une flexibilité et une robustesse dans la gestion des jetons. En approuvant le montant maximal, nous permettons à Router02 de transférer des jetons en notre nom. Sans cela, vous vous attendriez à voir un message d'erreur STF dans lequel STF signifie que l'exécution est annulée par l'assertion require dans la fonction TransferHelper.safeTransferFrom.

Ensuite, nous verrons comment un chemin triangulaire est défini :

bytes memory path = abi.encodePacked(USDC, uint24(3000),

WETH, uint24(3000), DAI,  uint24(3000), USDC) ;

À travers abi.encodePacked, Solidity emballe étroitement plusieurs valeurs sans ajouter de rembourrage. Il concatène les données binaires brutes de chaque paramètre. Pas difficile de comprendre que les paramètres séquentialisés les swaps avec frais entre les paires de cryptomonnaies. Le chemin commence par USDC et s'arrête à USDC en espérant un profit. Ensuite, il est enveloppé par ExactInputParams avec d'autres paramètres obligatoires et alimenté dans le routeur pour un échange multi-sauts.

Test

Nous utilisons la même technique parforking mainnet avec impersonation. Une fois que 10 USDC ont été vérifiés comme crédités sur le contrat, les échanges multi-sauts peuvent être déclenchés comme ci-dessous :

it("effectue un échange multi-saut", async () => {balance = await swap.tokenBalance(USDC);console.log(`Solde actuel de USDC = ${balance}`);console.log(`Échange de ${initialFundingHuman} USDC`);const tx = await swap.swapExactInputMultiHop(ethers.parseUnits(initialFundingHuman, DECIMALS));receipt = await tx.wait();balance = await swap.tokenBalance(USDC);console.log(`Solde actuel de USDC = ${balance}`);expect(balance).not.equal(0);});

Le résultat du test devrait ressembler à ce qui suit :

Solde USDC du whale: 170961218210457n

Impersonation Started.

Impersonation terminée.

Solde actuel de USDC = 100000000

Échange de 100 USDC

Solde actuel de USDC = 91677417

Après avoir sauté à travers les obstacles, nous avons perdu de l'argent - De toute évidence, le chemin avec les taux au comptant n'était pas en notre faveur, mais vous avez une idée de la manière dont l'arbitrage triangulaire devrait être réalisé en utilisant des swaps multi-sauts sur Uniswap v3.

Prêt flash financé arbitrage triangulaire

N'ai-je pas dit la source de financement la plus puissante dans l'écosystème DeFi est le prêt FlashIl ne vous faudra pas beaucoup de créativité pour construire une stratégie de trading d'arbitrage triangulaire financée par un prêt Flash en utilisant à la fois un prêt Flash et des swaps multihop que j'ai enseignés. Une logique combinée peut être expliquée par le diagramme de séquence mis à jour ci-dessous :

Diagramme de séquence pour l'arbitrage triangulaire financé par prêt éclair sur Uniswap v3 (Opérations ignorées pour des raisons de simplicité)

Découvrez mon code source pour les prêts Flash et les échanges Multihop mis en œuvre sur Uniswap v3 — https://medium.com/cryptocurrency-scripts/flash-loan-on-uniswap-v3-84bca2bfe255, digérer le diagramme de séquence et faites vos devoirs pour obtenir la combinaison des contrats intelligents terminée.

Considérations de rentabilité

La première chose que nous voulons regarder est le chemin qui se compose de la séquence des 3 transactions : Pour être rentables, elles doivent être les bonnes 3 paires de crypto aux bons taux. Afin de trouver toute cette justesse, vous devez développer un programme qui permutte les paires échangeables dans le schéma de l'arbitrage triangulaire et simuler les échanges pour vérifier la rentabilité. Récupérer des taux à partir de la blockchain peut être lent et cela ralentira encore le processus s'il y a trop de chemins en attente d'être vérifiés pour la rentabilité. Vous voudrez peut-être réduire la liste des chemins triangulaires en calculant le Profit & Loss basé sur les prix de surface fournis par les points de tarification GraphQL d'une DEX, le cas échéant (ici vient Uniswap v3’s) Les API GraphQL sont beaucoup plus rapides que la blockchain pour fournir des données de cotation. Une fois les chemins présélectionnés, exécutez-les avec des devis récupérés de la chaîne pour un calcul plus précis des bénéfices et des pertes.

Booster votre investissement avec un prêt flashpeut encore étendre le profit - emprunter des jetons à faible intérêt et les investir avec une stratégie rentable sera toujours une bonne idée. Théoriquement, tant que le bénéfice brut est suffisant pour couvrir le prêt Flash et les frais d'échange, la stratégie d'arbitrage triangulaire sera considérée comme rentable. Un truc essentiel pour protéger votre profit et atténuer le risque global de trading est d'avoir une logique dans votre contrat de trading pour annuler la transaction de prêt flash si le contrôle de la rentabilité brute échoue, car lorsque la transaction échoue, toutes les opérations seront annulées et vous n'aurez pas à supporter la perte et même les frais de la transaction. Cette logique agira comme un gardien universel pour prévenir le glissement ou le mouvement du taux de change qui n'est pas en notre faveur.

Cela étant dit, que la transaction réussisse ou échoue, les frais de gaz sont quelque chose dont vous ne pourrez jamais vous échapper et pourraient être la principale cause de votre perte d'argent dans l'arbitrage triangulaire. Évaluez toujours les frais de gaz pour la transaction de votre stratégie et intégrez-les dans le calcul de rentabilité net. Veuillez vous référer aux cas de test d'estimation des frais de gaz dans mon code source.

Avertissement:

  1. Cet article est repris de [GateScripts de cryptomonnaie], Tous les droits d'auteur appartiennent à l'auteur original [Aaron Li]. Si vous avez des objections à cette réimpression, veuillez contacter le Gate Learnéquipe, et ils s'en occuperont rapidement.
  2. Responsabilité déniée: Les points de vue et opinions exprimés dans cet article sont uniquement ceux de l'auteur et ne constituent aucun conseil en investissement.
  3. Les traductions de l'article dans d'autres langues sont effectuées par l'équipe Gate Learn. Sauf mention contraire, la copie, la distribution ou le plagiat des articles traduits est interdit.
Lancez-vous
Inscrivez-vous et obtenez un bon de
100$
!