Finding the biggest swap of 1inch v3 on Ethereum and Binance Smart Chain using Web3.js
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
- 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.
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
- Setup Node.js project
First, I created a new Node.js project with npm init
in 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