Detecting ERC-20 Token Transfers

For this project I’ve chosen 12 biggest ERC-20 tokens by market cap and saved them in a Javascript array:

Since the list was short, I just copypasted their contract address from Etherscan.

So how are we going to follow the transfers of these tokens? Each ERC-20 token transfer emits a Transfer() event. The natural way would be to use the web3.js library to subscribe to these events and get notified directly by the blockchain (via Infura’s infrastructure) each time an event is emitted by a tracked ERC-20 contract, like so:

There is only one problem with this approach. First we have to connect to Infura via a web socket:

const web3 = new Web3(

new Web3.providers.WebsocketProvider(‘wss://mainnet.infura.io/ws’)

);

And in my experience, this connection is not the most reliable for getting frequent notifications. Since our bot is going to be hosted on Heroku (which restarts its instances every day), we need a more reliable solution.

This solution is the free API provided by Ethplorer.io. Specifically the getTokenHistory endpoint returns an array of any token’s operations. It can filter by a type of operation (transfer, in our case) and by time.

For example, this call http://api.ethplorer.io/getTokenHistory/0xB8c77482e45F1F44dE1745F52C74426C631bDD52?apiKey=freekey&type=transfer&limit=5 will return the most recent five BNB token transfers. This is exactly what we need.

Calculating the value of ERC-20 token transfer

We have seen how to poll the Ethplorer API and get the latest ERC-20 token transfer per token contract address. But we are only interested in significant transfers, say transfers of tokens valued above $25,000.

To calculate the value of a transfer, we need multiply the amount of tokens transferred by the token’s current going rate.

Conveniently, Ethplorer’s API returns a tokenInfo object in the response to getTokenHistory API call. This object contains updated price information for the token. But there is a catch. For some interesting tokens, like REP (Augur) and HOT (Holo), the price information is not returned.

To work around this issue, we can use the CryptoCompare API. The free tier gives you 100,000 calls per month, which is more than enough for retrieving our tokens’ current price daily.

On initializing our bot, we will simply call CryptoCompare API’s /data/price endpoint for each token in our token array and save the price that we get. We only need to do it once, because Heroku reboots the instance daily anyway, so the price will be updated every 24 hours.

Now that we have all token rates, we can easily calculate the values of each token transfer that we detect and tweet only about the significant ones.

Continous transfer tracking with setInterval()

Knowing how to ask about token transfers and calculate their value, we can now tie it all together:

This code does all the work of continuously tracking specific ERC-20 token transfers. We call the Ethplorer API and ask about all the transfers that happened in the last minute, then we send each received operation to the provided callback.

The call to Ethplorer API is wrapped in setInterval to execute the call repeated with a fixed time delay. The interval is randomized, so that we don’t bombard the API with call bursts.

Filtering the important transfers

We have seen that for each detected token transfer, a callback is invoked. This callback function needs to calculate the value of a transfer and tweet about it only if the value exceeds our threshold.

Here we convert the amount of transferred tokens into a normalized form, taking into account the decimals that each token defines. Most ERC-20 tokens have 18 decimals (as Ethereum itself), but some are not: USDC stable coin defines only 6 and Zilliqa has 12, so we have to take this into account.

Next, we multuply the transferred tokens amount by the price and get the value. If it exceeds the threshold (currently $50000$), we construct a message string and tweet it.

We also save the transaction hash so that we won’t tweet about the same transfer more than once.

The simple act of tweeting

Please see this informative article on how to connect to the Twitter API with node.js.

It succintly describes how to generate Twitter API keys and use them in our bot. Once we have those, we can simply tweet any message (and log it to the console too for a good measure):

Bringing it all together

To connect all these pieces, all we need to do is to read our API secrets from the .env file, initialize the tokens with their prices and start tracking them.

Deploying the Twitter bot on Heroku

I’ve deployed the bot by signing up on Heroku, creating a new app and connecting it to the bot’s Github repo.

There are two modifications needed for Heroku:

Add a `Procfile` to the repo’s root. This file lets Heroku know that this is a worker process and not a web application, and it only has a single line of code:

worker: node app.js

2. We cannot use the dotenv module anymore to read our API secrets from the .env file. Naturally, the .env file is not uploaded to Github and doesn’t get deployed to Heroku. The simple solution is to manually define the secrets as config vars on Heroku’s app settings page:

Results

The ERC-20 transfer tracker bot has been running for a few days now, making 301 tweets and already has 10 followers.

There are a few things that can be done to improve it, such as make the tweets more visually attractive and filter out stablecoin tokens transfers.

Please let me know in the comments if you have any quesitons or suggestions.