kabu_defi_pools/state_readers/
uniswapv2.rs1use alloy::primitives::{Address, U256};
2use alloy::sol_types::{SolCall, SolInterface};
3use alloy_evm::EvmEnv;
4use eyre::Result;
5use kabu_defi_abi::uniswap2::IUniswapV2Pair;
6use kabu_evm_db::KabuDBError;
7use kabu_evm_utils::evm_call;
8use kabu_types_entities::PoolError;
9use revm::DatabaseRef;
10use tracing::error;
11
12pub struct UniswapV2EVMStateReader {}
13
14impl UniswapV2EVMStateReader {
15 pub fn factory<DB: DatabaseRef<Error = KabuDBError> + ?Sized>(db: &DB, pool: Address) -> Result<Address, PoolError> {
16 let input = IUniswapV2Pair::IUniswapV2PairCalls::factory(IUniswapV2Pair::factoryCall {}).abi_encode();
17 let (call_data_result, _, _) = evm_call(db, EvmEnv::default(), pool, input)?;
18
19 let call_return = IUniswapV2Pair::factoryCall::abi_decode_returns(&call_data_result)
20 .map_err(|e| PoolError::AbiDecodingError { method: "factory", source: e })?;
21 Ok(call_return)
22 }
23
24 pub fn token0<DB: DatabaseRef<Error = KabuDBError> + ?Sized>(db: &DB, pool: Address) -> Result<Address, PoolError> {
25 let input = IUniswapV2Pair::IUniswapV2PairCalls::token0(IUniswapV2Pair::token0Call {}).abi_encode();
26 let (call_data_result, _, _) = evm_call(db, EvmEnv::default(), pool, input)?;
27
28 let call_return = IUniswapV2Pair::token0Call::abi_decode_returns(&call_data_result)
29 .map_err(|e| PoolError::AbiDecodingError { method: "token0", source: e })?;
30 Ok(call_return)
31 }
32
33 pub fn token1<DB: DatabaseRef<Error = KabuDBError> + ?Sized>(db: &DB, pool: Address) -> Result<Address, PoolError> {
34 let input = IUniswapV2Pair::IUniswapV2PairCalls::token1(IUniswapV2Pair::token1Call {}).abi_encode();
35 let (call_data_result, _, _) = evm_call(db, EvmEnv::default(), pool, input)?;
36
37 let call_return = IUniswapV2Pair::token1Call::abi_decode_returns(&call_data_result)
38 .map_err(|e| PoolError::AbiDecodingError { method: "token1", source: e })?;
39 Ok(call_return)
40 }
41
42 pub fn get_reserves<DB: DatabaseRef<Error = KabuDBError> + ?Sized>(db: &DB, pool: Address) -> Result<(U256, U256), PoolError> {
43 let input = IUniswapV2Pair::IUniswapV2PairCalls::getReserves(IUniswapV2Pair::getReservesCall {}).abi_encode();
44 let call_data_result = match evm_call(db, EvmEnv::default(), pool, input) {
45 Ok((call_data, _, _)) => call_data,
46 Err(error) => {
47 error!(%error,"get_reserves");
48 return Err(error.into());
49 }
50 };
51
52 let call_return = IUniswapV2Pair::getReservesCall::abi_decode_returns(&call_data_result)
53 .map_err(|e| PoolError::AbiDecodingError { method: "getReserves", source: e })?;
54 Ok((U256::from(call_return.reserve0), U256::from(call_return.reserve1)))
55 }
56}