WEB3DEV

Cover image for Encontrando o maior swap da 1inch v3 na Ethereum e na Binance Smart Chain usando Web3.js
Banana Labs
Banana Labs

Posted on • Atualizado em

Encontrando o maior swap da 1inch v3 na Ethereum e na Binance Smart Chain usando Web3.js

Você já se perguntou como encontrar o evento no contrato inteligente e como lê-los?

Neste artigo, apresentarei um passo a passo para encontrar o maior swap em USD na 1inch.

Se você ainda não ouviu falar de 1inch, 1inch é uma rede distribuída para protocolos descentralizados que permitem as operações mais lucrativas, rápidas e protegidas em DeFi.
Leia mais aqui e https://app.1inch.io/

Antes que possamos descobrir como isso é feito, alguns dados devem ser preparados de antemão, conforme listado abaixo:

  • Endereço do contrato router da 1inch e sua ABI
  • Nome de evento do swap
  • Bloco inicial do swap
  • Endereço do token de stablecoins

Sumário

1 . Preparar dados
..... . Endereço do contrato router da 1inch e ABI
..... . Nome de evento do swap
..... . Bloco inicial do evento Swapped
..... . Endereço de contrato de Stablecoins

2 . Encontre o maior swap na 1Inch v3
..... . Configure um projeto NodeJS
..... . Prepare os dados necessários
..... . Leia os eventos anteriores do contrato
..... . Filtre os eventos Swapped para as stablecoins

3 . Conclusão


Preparar dados

Endereço do contrato router da 1inch e ABI

Eu tenho o endereço do contrato router da 1inch ao tentar fazer um trade na 1inch e, em seguida, copiei o endereço de destino para a Metamask. Portanto, eu encontro o endereço do contrato router da 1inch que é: 0x11111112542D85B3EF69AE05771c2dCCff4fAa26 .

O contrato ABI pode ser encontrado no Etherscan

Nome de evento do swap

Precisamos do nome de evento do swap para filtrar os eventos acionados pelo contrato router da 1inch. Então, vou ler o contrato deles usando o Etherscan e, em seguida, procuro o evento do swap que pode ser encontrado na captura de tela abaixo.

evento Swapped
evento Swapped no contrato AggregationRouterV3

Como você pode ver, o nome do evento é Swapped.

Bloco inicial do evento Swapped

O primeiro bloco em que o evento Swapped acontece deve ser conhecido porque não queremos perder nenhum evento. Eu encontrei ele pesquisando no google o artigo 1Inch publicado no Medium. A data de publicação é 16 de março de 2021. Assim, podemos supor que não houve nenhum evento Swapped significativo ocorrido antes disso.

O próximo problema é como encontrar o número do bloco em 16 de março de 2021?
Temos boas notícias, podemos encontrá-lo facilmente utilizando a API Covalent! A API para este caso é a API Get block heights. Vamos tentar usá-la com curl.

curl -X GET "https://api.covalenthq.com/v1/1/block_v2/2021-03-16/2021-05-20/?page-size=1&key=ckey_75720a8fd64c4f6f9c6acbabaf9" \
 -H "Accept: application/json"
Enter fullscreen mode Exit fullscreen mode

A resposta é essa

1 {
2   "data": {
3     "updated_at": "2021-05-19T18:21:35.275391530Z",
4     "items": [
5       {
6         "signed_at": "2021-03-16T00:00:09Z",
7         "height": 12046295
8       }
9     ],
10     "pagination": {
11       "has_more": true,
12       "page_number": 0,
13       "page_size": 1,
14       "total_count": 420106
15     }
16   },
17   "error": false,
18   "error_message": null,
19   "error_code": null
20 }
Enter fullscreen mode Exit fullscreen mode

A altura do bloco em 16 de março de 2021 é 12046295 . Excelente! Graças à incrível API Covalent.

Endereço de contrato de Stablecoins

Neste artigo, vou me concentrar apenas no swap de Stablecoins porque posso omitir os serviços de alimentação de preços, que são mais complicados de medir o valor do swap. Para manter as coisas simples, vamos nos concentrar no swap de Stablecoins.

O endereço do contrato de tokens é fácil de encontrar. Ele pode ser encontrado no explorador de blocos ou em qualquer serviço agregador de dados cripto, por exemplo. Coingecko, Coinmarketcap, etc. Então as Stablecoins que vamos usar são:

Ethereum Chain

USDT = 0xdac17f958d2ee523a2206206994597c13d831ec7
USDC = 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
DAI = 0x6b175474e89094c44da98b954eedeac495271d0f
Enter fullscreen mode Exit fullscreen mode

Binance Smart Chain

USDT = 0x55d398326f99059ff775485246999027b3197955
USDC = 0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d
DAI = 0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3
BUSD = 0xe9e7cea3dedca5984780bafc599bd69add087d56
Enter fullscreen mode Exit fullscreen mode

Agora, tenho todos os dados necessários. A seguir, vamos ver como posso encontrar o maior swap na 1inch v3.

Encontre o maior swap na 1Inch v3

Configure um projeto NodeJS

Primeiro, criei um novo projeto Node.js com npm init em uma pasta vazia com web3.js como dependência.

Prepare os dados necessários

Depois de ter meu projeto pronto, crio um novo arquivo chamado index.js. Em seguida, mantenha todos os dados que coletamos na seção anterior em variáveis. Por fim, crie o web3 e contract do agregador 1inch v3.

const Web3 = require('web3')
const routerAbi = require('./abi/router.json')

// O mais comum geth rpc é infura.
const GETH_RPC_ENDPOINT = "YOUR_GETH_RPC_ENDPOINT"

// Primeiro bloco em 2021-03-16 na Ethereum
const fromBlock = "12046295"

// Contrato 1Inch's AggregatorRouterV3 
const routerV3 = "0x11111112542D85B3EF69AE05771c2dCCff4fAa26"

async function printBiggestSwap() {
  const web3 = new Web3(GETH_RPC_ENDPOINT)
  const contract = new web3.eth.Contract(routerAbi, routerV3)
}

printBiggestSwap()
Enter fullscreen mode Exit fullscreen mode

Leia os eventos anteriores do contrato

Esta etapa é a razão pela qual eu quero usar o web3. O Web3 pode ler todos os eventos para determinado endereço de contrato e o nome do evento. Portanto, meu código agora se parece com este abaixo.

const Web3 = require('web3')

// O mais comum geth rpc é infura.
const GETH_RPC_ENDPOINT = "YOUR_GETH_RPC_ENDPOINT"

// Primeiro bloco em 2021-03-16 na Ethereum
const fromBlock = "12046295"

//  Contrato 1Inch's AggregatorRouterV3 
const routerV3 = "0x11111112542D85B3EF69AE05771c2dCCff4fAa26"

async function printBiggestSwap() {
  const web3 = new Web3(GETH_RPC_ENDPOINT)
  const contract = new web3.eth.Contract(routerAbi, routerV3)

  // Isso não funcionará se o contrato tiver mais de 10 milk eventos. 
 // Portanto, não escreva assim.
  const _result = await contract.getPastEvents("Swapped", {
    fromBlock
  })

  // Em vez disso, leremos eventos limitados por rodada até atingir o último bloco.
  const eventsPerRound = 10000;
  const latestBlock = await web3.eth.getBlockNumber();
  const _toBlock = Math.min(fromBlock + eventsPerRound, latestBlock)
  let events = []
  while (_toBlock < latestBlock) {
    const _events = await contract.getPastEvents("Swapped", {
      fromBlock,
      toblock: _toBlock
    })

    events = events.concat(_events)
  }
}

printBiggestSwap()
Enter fullscreen mode Exit fullscreen mode

Os eventos passados podem ser lidos como a linha 17 — 19 . Infelizmente, o serviço Geth RPC não permitirá que o cliente consulte eventos com mais de 10 mil eventos por chamada. Portanto, precisamos reduzir os eventos retornados por chamada e continuar inserindo-os gradualmente em um array. Ver linha 22 - 33

Se você quer saber como o objeto event é retornado a partir de getPastEvents, veja abaixo:

{
  address: '0x11111112542D85B3EF69AE05771c2dCCff4fAa26',
  blockNumber: 5746136,
  transactionHash: '0x3d838039c450b1af55ba1c57d667bf800177d69936d412e0c698e80b83099007',
  transactionIndex: 48,
  blockHash: '0x0928fdc5f83087bcdc97b4ae7bc769b4f91550e42e220722168f9e59c640508e',
  logIndex: 233,
  removed: false,
  id: 'log_40e4073c',
  returnValues: Result {
    '0': '0x0D080A3c3290C98E755d8123908498BcE2C5620d',
    '1': '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56',
    '2': '0x55d398326f99059fF775485246999027B3197955',
    '3': '0x0D080A3c3290C98E755d8123908498BcE2C5620d',
    '4': '2000200000000000000000000',
    '5': '2000031648518588335779396',
    sender: '0x0D080A3c3290C98E755d8123908498BcE2C5620d',
    srcToken: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56',
    dstToken: '0x55d398326f99059fF775485246999027B3197955',
    dstReceiver: '0x0D080A3c3290C98E755d8123908498BcE2C5620d',
    spentAmount: '2000200000000000000000000',
    returnAmount: '2000031648518588335779396'
  },
  event: 'Swapped',
  signature: '0xd6d4f5681c246c9f42c203e287975af1601f8df8035a9251f79aab5c8f09e2f8',
  raw: {
    data: '0x0000000000000000000000000d080a3c3290c98e755d8123908498bce2c5620d000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d5600000000000000000000000055d398326f99059ff775485246999027b31979550000000000000000000000000d080a3c3290c98e755d8123908498bce2c5620d00000000000000000000000000000000000000000001a78f0f2c56360820000000000000000000000000000000000000000000000001a785eed3b9d4df19ee44',
    topics: [
      '0xd6d4f5681c246c9f42c203e287975af1601f8df8035a9251f79aab5c8f09e2f8'
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Filtre os eventos Swapped para as stablecoins

Como nos concentramos apenas no evento swap que tem stablecoin pelo menos de um lado, nós precisamos filtrar e descartar aqueles eventos swap que não têm stablecoins.

Como podemos obter o endereço do contrato de token a partir da resposta? Felizmente, ele já está incluído no objeto event como acima. Então você pode ver dstToken (Token de destino) e srcToken (Token de origem) que significam:

  • dstToken endereço de contrato do token que o remetente obterá após o swap
  • srcToken endereço de contrato do token que o remetente usa para o swap

Já temos o endereço de contrato de Stablecoins, então meu código evolui para este:

const Web3 = require('web3')

// O mais comum geth rpc é infura.
const GETH_RPC_ENDPOINT = "YOUR_GETH_RPC_ENDPOINT"

// Primeiro bloco em 2021-03-16 na Ethereum
const fromBlock = "12046295"

// Contrato 1Inch's AggregatorRouterV3
const routerV3 = "0x11111112542D85B3EF69AE05771c2dCCff4fAa26"

async function printBiggestSwap() {
  const web3 = new Web3(GETH_RPC_ENDPOINT)
  const contract = new web3.eth.Contract(routerAbi, routerV3)

 // Isso não funcionará se o contrato tiver mais de 10 milk eventos. 
 // Portanto, não escreva assim.
  const _result = await contract.getPastEvents("Swapped", {
    fromBlock
  })

  // Em vez disso, leremos eventos limitados por rodada até atingir o último bloco.
  const eventsPerRound = 10000;
  const latestBlock = await web3.eth.getBlockNumber();
  const _fromBlock = fromBlock
  const _toBlock = Math.min(fromBlock + eventsPerRound, latestBlock)
  let biggestSwap;
  while (_toBlock < latestBlock) {
    const _events = await contract.getPastEvents("Swapped", {
      fromBlock: _fromBlock,
      toblock: _toBlock
    })

    const filteredEvents = _events.forEach({ returnValues } => {
      if(isStableCoins(returnValues.dstToken)) {
          biggestSwap = Math.max(biggestSwap, parseInt(returnValues.returnAmount))
      }

      if(isStableCoins(returnValues.srcToken)) {
          biggestSwap = Math.max(biggestSwap, parseInt(returnValues.spentAmount))
      }
    })

    _fromBlock = _toBlock + 1
    _toBlock = Math.min(_toBlock + eventsPerRound, latestBlock)
  }

  console.log(biggestSwap)
}

function isStableCoins(token) {
  const USDT = "0xdac17f958d2ee523a2206206994597c13d831ec7"
  const USDC = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
  const DAI = "0x6b175474e89094c44da98b954eedeac495271d0f"
  const stablecoins = [USDT, USDC, DAI]
  return stablecoins.indexOf(token.toLowerCase()) > -1
}

printBiggestSwap()
Enter fullscreen mode Exit fullscreen mode

Vamos dar uma olhada no código adicional da etapa anterior.

Linha 34 a 42

  • Verifique se o evento é swap de Stablecoins
  • Se for um swap de Stablecoins, atribua um evento de swap maior à variável biggestSwap

Linha 45 a 46

  • Incrementar blocos para consultar eventos passados.

Linha 49

  • Imprima o maior swap

Linha 52–58

  • Retorna true se o endereço do contrato de token fornecido for USDT, USDC ou DAI

E a linha final imprime a maior transação de swap.

O resultado está abaixo:

{
  address: '0x11111112542D85B3EF69AE05771c2dCCff4fAa26',
  blockHash: '0x7936392cd01131f7e21bdd353a4b5a7b96f8fd3bba0d02fa9e2afada1365c74e',
  blockNumber: 12446903,
  logIndex: 69,
  removed: false,
  transactionHash: '0x6b1594e1a7aa3f2dfa3b00f8913745d961579d7e7e97950364cce11c02459d56',
  transactionIndex: 5,
  id: 'log_bc980976',
  returnValues: Result {
    '0': '0xB66f8015E916e0d6590761Ed299BF4B3BDF40006',
    '1': '0x6B175474E89094C44Da98b954EedeAC495271d0F',
    '2': '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
    '3': '0xB66f8015E916e0d6590761Ed299BF4B3BDF40006',
    '4': '31407288037329481247334373',
    '5': '8607683887337745631338',
    sender: '0xB66f8015E916e0d6590761Ed299BF4B3BDF40006',
    srcToken: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
    dstToken: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
    dstReceiver: '0xB66f8015E916e0d6590761Ed299BF4B3BDF40006',
    spentAmount: '31407288037329481247334373',
    returnAmount: '8607683887337745631338'
  },
  event: 'Swapped',
  signature: '0xd6d4f5681c246c9f42c203e287975af1601f8df8035a9251f79aab5c8f09e2f8',
  raw: {
    data: '0x000000000000000000000000b66f8015e916e0d6590761ed299bf4b3bdf400060000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000b66f8015e916e0d6590761ed299bf4b3bdf4000600000000000000000000000000000000000000000019fac07f003f6ee5459fe50000000000000000000000000000000000000000000001d29f9c4a11e3d3486a',
    topics: [
      '0xd6d4f5681c246c9f42c203e287975af1601f8df8035a9251f79aab5c8f09e2f8'
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Você pode ver os detalhes desta transação aqui. Vale cerca de $ 31 milhões e pagou 0,91 ETH pela taxa de gás.

Para a Binance Smart Chain, será um pouco diferente. Por exemplo, o nó BSC não permitirá consultas que retornem mais de 5.000 resultados e o nó Geth rpc fica inativo com bastante frequência. Portanto, você pode considerar reduzir eventsPerRound e agrupar a chamada getPastEvent com lógica de repetição. Se você está curioso para ver o resultado no BSC. O resultado está abaixo (o último bloco é 7601227 quando o script é executado)

{
  address: '0x11111112542D85B3EF69AE05771c2dCCff4fAa26',
  blockNumber: 7360052,
  transactionHash: '0xd58b583ccc04c2502828bd1d20a7d31f61806a839108cdad6ff2b19ca9a36fd9',
  transactionIndex: 116,
  blockHash: '0xee0c3a305ed738ea0d7629af6d93e0fccd291fb80f1732f22c4dd329dbe07aec',
  logIndex: 142,
  removed: false,
  id: 'log_bf221914',
  returnValues: Result {
    '0': '0x0426266CF573388100183343b6e26b8bf5e4FDBb',
    '1': '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82',
    '2': '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56',
    '3': '0x0426266CF573388100183343b6e26b8bf5e4FDBb',
    '4': '420189781342653493372938',
    '5': '11524614549462974075302973',
    sender: '0x0426266CF573388100183343b6e26b8bf5e4FDBb',
    srcToken: '0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82',
    dstToken: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56',
    dstReceiver: '0x0426266CF573388100183343b6e26b8bf5e4FDBb',
    spentAmount: '420189781342653493372938',
    returnAmount: '11524614549462974075302973'
  },
  event: 'Swapped',
  signature: '0xd6d4f5681c246c9f42c203e287975af1601f8df8035a9251f79aab5c8f09e2f8',
  raw: {
    data: '0x0000000000000000000000000426266cf573388100183343b6e26b8bf5e4fdbb0000000000000000000000000e09fabb73bd3ade0a17ecc321fd13a19e81ce82000000000000000000000000e9e7cea3dedca5984780bafc599bd69add087d560000000000000000000000000426266cf573388100183343b6e26b8bf5e4fdbb0000000000000000000000000000000000000000000058fa889fde44c0a9680a00000000000000000000000000000000000000000009886e9b48c7c6ff54f43d',
    topics: [
      '0xd6d4f5681c246c9f42c203e287975af1601f8df8035a9251f79aab5c8f09e2f8'
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Os detalhes da transação podem ser lidos aqui. São cerca de 420k $ CAKE trocados por $ 11,5 milhões $ BUSD. É um swap menor do que a transação na Ethereum. Portanto, a maior troca com Stablecoins desde que a 1inch v3 começou oficialmente é
https://etherscan.io/tx/0x6b1594e1a7aa3f2dfa3b00f8913745d961579d7e7e97950364cce11c02459d56 (Testado em 20 de maio de 2021)

Conclusão

As etapas para obter esses dados são bastante complicadas. Felizmente, casos de uso como esse se tornarão muito mais fáceis com a API Covalent. Ela suporta 1 milhão de blocos por chamada. Observe que ainda está na versão beta, se você encontrou algum bug, pode relatar a eles em seu canal no Discord #feedback-and-support. Assim, podemos obter uma API ainda melhor para usar. Espero que este artigo ajude você a entender como ler o evento do contrato na blockchain mais facilmente. Saúde.

O código completo está hospedado aqui: https://github.com/npty/data-dungeon



Esse artigo é uma tradução feita por @bananlabs. Você pode encontrar o artigo original aqui

Latest comments (0)