James Bachini

DeFi Analysis With Rust

DeFi Rust

In this tutorial I’m going to provide some code and show you how to monitor the number of depositors to Eigenlayer over the last 24 hours.

We will be using Rust with the Tokio and Ethers libraries along with the Infura API which you can get a free key from here.

The first thing we will do is take a look at the smart contract which holds deposits on etherscan: https://etherscan.io/address/0x858646372CC42E1A627fcE94aa7A7033e7CF075A#events

You can see the Deposit events coming in here and this is what we will be trying to track.

Let’s start by creating a new rust repository

cargo init

Now let’s add some dependencies to Cargo.toml

ethers = "1.0.0-beta.2"
tokio = { version = "1", features = ["full"] }

Next take a look at the code in src/main.rs and copy this in alongside your Infura API key on line 7. Make sure you don’t upload the code to Github with your API key still in it, for extra points use env variables.

Full code repository can be found here: https://github.com/jamesbachini/EigenLayerMonitor

use ethers::prelude::*;
use ethers::utils::hex;
use std::convert::TryFrom;
use std::sync::Arc;
use tokio::runtime::Runtime;

const INFURA_API_KEY: &str = "";
const POOL_ADDRESS: &str = "0x858646372CC42E1A627fcE94aa7A7033e7CF075A";
const TOPIC: &str = "0x7cfff908a4b583f36430b25d75964c458d8ede8a99bd61be750e97ee1b2f3a96";

async fn get_block_24_hours_ago(provider: Arc<Provider<Http>>) -> Result<U64, Box<dyn std::error::Error>> {
    let current_block_number = provider.get_block_number().await?;
    let average_block_time = 13; // average block time in seconds
    let blocks_24_hours_ago = (24 * 60 * 60) / average_block_time;
    let estimated_block_number = current_block_number - blocks_24_hours_ago;
    println!("Target Start Block: {}", estimated_block_number);
    Ok(estimated_block_number)
}

async fn calculate_deposits(provider: Arc<Provider<Http>>, pool_address: &str, topic: &str, from_block: U64) -> Result<usize, Box<dyn std::error::Error>> {
    let filter = Filter::new()
        .address(pool_address.parse::<Address>()?)
        .from_block(from_block)
        .to_block(BlockNumber::Latest)
        .topic0(ValueOrArray::Value(H256::from_slice(&hex::decode(topic.trim_start_matches("0x"))?)));
    
    let logs = provider.get_logs(&filter).await?;
    Ok(logs.len())
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let runtime = Runtime::new()?;
    runtime.block_on(async {
        let provider = Arc::new(Provider::<Http>::try_from(format!("https://mainnet.infura.io/v3/{}", INFURA_API_KEY))?);
        let from_block = get_block_24_hours_ago(provider.clone()).await?;
        let total_depositors = calculate_deposits(provider.clone(), POOL_ADDRESS, TOPIC, from_block).await?;
        println!("Total Depositors: {}", total_depositors);
        Ok(())
    })
}

We start by estimating the block 24 hours ago based on a 13 second block time. This isn’t particularly accurate but it’s good enough for this example.

We then download the logs for the last 24 hours by topic. The Keccak topic hash is taken directly from etherscan, see [topic0].

We then count the number of results and print that out.

To run the application use:

cargo run

There you have a quick way to monitor transactions on Ethereum using Rust and Ethers. You could take this further by calculating the value of those deposits or doing more in-depth analysis of historical data.


Get The Blockchain Sector Newsletter, binge the YouTube channel and connect with me on Twitter

The Blockchain Sector newsletter goes out a few times a month when there is breaking news or interesting developments to discuss. All the content I produce is free, if you’d like to help please share this content on social media.

Thank you.

James Bachini

Disclaimer: Not a financial advisor, not financial advice. The content I create is to document my journey and for educational and entertainment purposes only. It is not under any circumstances investment advice. I am not an investment or trading professional and am learning myself while still making plenty of mistakes along the way. Any code published is experimental and not production ready to be used for financial transactions. Do your own research and do not play with funds you do not want to lose.