Finding the biggest swap of 1inch v3 on Ethereum and Binance Smart Chain using Web3.js

nptytn
5 min readMay 21, 2021

--

Have you ever wonder how to find the event in the smart contract and how to read them?

In this article, I will present a step-by-step of finding biggest swap in USD on 1inch.

If you haven’t heard about 1inch, 1inch is a distributed network for decentralized protocols enabling the most lucrative, fastest and protected operations in DeFi.
Read more here and https://app.1inch.io/

Before we can figure it out, Some datas must be prepared beforehand as listed below:

  • 1Inch router contract address and its ABI
  • Swap event name
  • Start block of the swap
  • Stablecoins token address

Prepare data

  1. 1Inch router contract address and ABI

I’ve got the 1inch router contract address by trying to make a trade on 1inch, then copy the destination address on Metamask. So I find that 1inch’s router contract address is: 0x11111112542D85B3EF69AE05771c2dCCff4fAa26 .

the contract ABI can be found at Etherscan

2. Swap event name

We need the name of the swap event for filtering events fired from the 1inch’s router contract. So I go to read their contract using Etherscan, then search for the swap event which can be found as screenshot below.

Swapped event in the AggregationRouterV3 contract

As you can see, the event name is Swapped .

3. Start block of the `Swapped` event

The first block that Swapped event happens must be known because we don’t want to miss any single event. I’m finding it by google for the 1Inch article published on Medium . The published date is on Mar 16, 2021. Thus, we can assume that there’s no significant Swapped event happened before that.

The next problem is how to find block number on Mar 16, 2021?
Good news, we can easily find it by utilize the Covalent API! The API for this case is Get block heights API. Let’s try to use it with 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"

The response is

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 }

The block height on Mar 16, 2021 is 12046295 . Great! Thanks to awesome Covalent API.

4. Stablecoins contract address

In this article, I’m going to focus only on the Stablecoins swap because I can omit the price feed services which is more complicate to measure the swap value. To keep things simple, let focus on Stablecoins swap.

Tokens contract address is easy to find. It can be found from the block explorer or any crypto data aggregator services e.g. Coingecko, Coinmarketcap, etc. So the Stablecoins we’re going to use are:

Ethereum Chain

USDT = 0xdac17f958d2ee523a2206206994597c13d831ec7
USDC = 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
DAI = 0x6b175474e89094c44da98b954eedeac495271d0f

Binance Smart Chain

USDT = 0x55d398326f99059ff775485246999027b3197955
USDC = 0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d
DAI = 0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3
BUSD = 0xe9e7cea3dedca5984780bafc599bd69add087d56

Now, I have all required data. Next, let’s see how can I find the biggest swap on 1inch v3.

Find the biggest swap on 1Inch v3

  1. Setup Node.js project

First, I created a new Node.js project with npm initin the empty folder with web3.js as a dependency.

2. Prepare required datas

Once I have my project ready, I create a new file called index.js . Next, keep all datas we collected in previous section in variables. Finally, create web3 and contract of 1inch’s aggregator v3.

3. Read contract past events

This step is the reason why I want to use web3. Web3 can read all events for given contract address and event name. So my code is now looks like below.

Past events can be read like line 17 — 19 . Unfortunately, Geth RPC service won’t allow client to query events more than 10k events per call. So we need to reduce the returned events per call and keep gradually push them into an array. See line 22 — 33

If you wonder how event object that returned from getPastEvents looks like, see below:

{
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'
]
}
}

4. Filter Swapped event for Stablecoins
Since we only focus on swap event that has Stablecoins at least one side, we need to filter non-stablecoins swap out.

How can we get the token contract address from the response? Luckily, it is already included in the event object like above. So you can see dstToken and srcToken which mean:

  • dstToken contract address of the token that sender will get after swap.
  • srcToken contract address of the token that sender uses for swap.

We’re already had Stablecoins contract address, so my code evolves to this

Let’s take a look at the additional code from previous step.

Line 34 to 42
-
Check if the event is Stablecoins swap
- If it is Stablecoins swap, then assign bigger swap event to biggestSwap variable

Line 45 to 46
-
Increment blocks for querying past events.

Line 49
- Print the biggest swap

Line 52–58
-
Return true if the given token contract address is one of USDT, USDC or DAI

And the final line prints the biggest swap transaction.

The result is below:

{
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'
]
}
}

You can see the details of this transaction here. It’s worth about $31M and paid 0.91 ETH for gas fee.

For Binance Smart Chain, it will be a little different. For example, the BSC node won’t allow query that returns more than 5000 results and the Geth rpc node is down quite often. So you might consider reduce eventsPerRound and wrap the getPastEvent call with retry logic. If you are curious the result in the BSC. The result is below (the latest block is 7601227 when the script runs)

{
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'
]
}
}

The details of the transaction can be read here. It’s about 420k $CAKE swapped to $11.5M $BUSD. It’s smaller swap than the transaction on Ethereum. So the biggest swap with Stablecoins since 1inch v3 officially started is https://etherscan.io/tx/0x6b1594e1a7aa3f2dfa3b00f8913745d961579d7e7e97950364cce11c02459d56 (Tested on May 20, 2021)

Conclusion

The steps to achieve this data is quite complicated. Fortunately, the use-case like this will become much easier with the Covalent API. It supports 1 million blocks per call. Note that it is still in beta, if you found any bug, you can report to them in their Discord ,#feedback-and-support channel. So we can get even better API to use. Hope this article help you to understand about to read contract event in blockchain easier. Cheers.

Full code is hosted here: https://github.com/npty/data-dungeon

--

--

nptytn
nptytn

Written by nptytn

Passionate about Web3, Cross-chain Messaging, and other blockchain stuffs.

No responses yet