use alloy::{
eips::BlockId,
primitives::{address, Address, TxKind, U256},
providers::ProviderBuilder,
sol,
sol_types::SolCall,
};
use revm::{context::TxEnv, database::WrapDatabaseAsync};
use trevm::{db::alloy::AlloyDb, revm::database::CacheDB, NoopBlock, NoopCfg, TrevmBuilder, Tx};
sol! {
#[allow(missing_docs)]
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
}
struct GetReservesFiller;
impl Tx for GetReservesFiller {
fn fill_tx_env(&self, tx_env: &mut TxEnv) {
tx_env.caller = Address::with_last_byte(0);
tx_env.kind = TxKind::Call(POOL_ADDRESS);
tx_env.data = getReservesCall::new(()).abi_encode().into();
tx_env.value = U256::from(0);
}
}
const POOL_ADDRESS: Address = address!("0d4a11d5EEaaC28EC3F61d100daF4d40471f1852");
#[tokio::main]
async fn main() -> eyre::Result<()> {
let rpc_url = "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27";
let client = ProviderBuilder::new().connect_http(rpc_url.parse()?);
let alloydb = WrapDatabaseAsync::new(AlloyDb::new(client, BlockId::default())).unwrap();
let cache_db = CacheDB::new(alloydb);
let evm = TrevmBuilder::new()
.with_db(cache_db)
.build_trevm()
.fill_cfg(&NoopCfg)
.fill_block(&NoopBlock)
.fill_tx(&GetReservesFiller)
.run()
.inspect_err(|e| panic!("Execution error {e:?}"))
.unwrap();
println!("Execution result: {:#?}", evm.result());
let output = evm.output().expect("Execution halted");
let return_vals = getReservesCall::abi_decode_returns_validate(output)?;
println!("Reserve0: {:#?}", return_vals.reserve0);
println!("Reserve1: {:#?}", return_vals.reserve1);
println!("Timestamp: {:#?}", return_vals.blockTimestampLast);
Ok(())
}