use std::sync::Arc;
use std::time::Instant;
use alloy_primitives::{Address, address};
use alloy_provider::ProviderBuilder;
use alloy_provider::network::AnyNetwork;
use anyhow::Result;
use evm_fork_cache::cache::EvmCache;
const WETH: Address = address!("C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2");
const HOLDER: Address = address!("88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640");
#[tokio::main(flavor = "multi_thread")]
async fn main() -> Result<()> {
let Ok(rpc_url) = std::env::var("RPC_URL") else {
eprintln!("This example needs an Ethereum mainnet RPC endpoint. Run with:");
eprintln!(" RPC_URL=https://eth.llamarpc.com cargo run --example fork_token_balance");
return Ok(());
};
let provider = ProviderBuilder::new()
.network::<AnyNetwork>()
.connect_http(rpc_url.parse()?);
let mut cache = EvmCache::new(Arc::new(provider)).await;
let decimals = cache.erc20_decimals(WETH)?;
println!("WETH decimals: {decimals}");
let t0 = Instant::now();
let cold_balance = cache.erc20_balance_of(WETH, HOLDER)?;
let cold = t0.elapsed();
let t1 = Instant::now();
let warm_balance = cache.erc20_balance_of(WETH, HOLDER)?;
let warm = t1.elapsed();
let whole = cold_balance
/ alloy_primitives::U256::from(10u64).pow(alloy_primitives::U256::from(decimals));
println!("holder WETH balance: {cold_balance} wei (~{whole} WETH)");
println!("cold read: {cold:?}");
println!("warm read: {warm:?} (served from cache)");
assert_eq!(cold_balance, warm_balance, "cached read must match");
Ok(())
}