kabu_defi_pools/state_readers/
uniswapv2.rs

1use 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}