kabu_defi_pools/state_readers/
uniswapv3.rs

1use alloy::primitives::aliases::U24;
2use alloy::primitives::Address;
3use alloy::sol_types::{SolCall, SolInterface};
4use alloy_evm::EvmEnv;
5use kabu_defi_abi::uniswap3::IUniswapV3Pool;
6use kabu_defi_abi::uniswap3::IUniswapV3Pool::slot0Return;
7use kabu_evm_db::KabuDBError;
8use kabu_evm_utils::evm_call;
9use kabu_types_entities::PoolError;
10use revm::DatabaseRef;
11
12pub struct UniswapV3EvmStateReader {}
13
14impl UniswapV3EvmStateReader {
15    pub fn factory<DB: DatabaseRef<Error = KabuDBError> + ?Sized>(db: &DB, pool: Address) -> Result<Address, PoolError> {
16        let input = IUniswapV3Pool::IUniswapV3PoolCalls::factory(IUniswapV3Pool::factoryCall {}).abi_encode();
17        let (call_data_result, _, _) = evm_call(db, EvmEnv::default(), pool, input)?;
18
19        let call_return = IUniswapV3Pool::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 = IUniswapV3Pool::IUniswapV3PoolCalls::token0(IUniswapV3Pool::token0Call {}).abi_encode();
26        let (call_data_result, _, _) = evm_call(db, EvmEnv::default(), pool, input)?;
27
28        let call_return = IUniswapV3Pool::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 = IUniswapV3Pool::IUniswapV3PoolCalls::token1(IUniswapV3Pool::token1Call {}).abi_encode();
35        let (call_data_result, _, _) = evm_call(db, EvmEnv::default(), pool, input)?;
36
37        let call_return = IUniswapV3Pool::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 fee<DB: DatabaseRef<Error = KabuDBError> + ?Sized>(db: &DB, pool: Address) -> Result<U24, PoolError> {
43        let input = IUniswapV3Pool::IUniswapV3PoolCalls::fee(IUniswapV3Pool::feeCall {}).abi_encode();
44        let (call_data_result, _, _) = evm_call(db, EvmEnv::default(), pool, input)?;
45
46        let call_return = IUniswapV3Pool::feeCall::abi_decode_returns(&call_data_result)
47            .map_err(|e| PoolError::AbiDecodingError { method: "fee", source: e })?;
48        Ok(call_return)
49    }
50
51    pub fn tick_spacing<DB: DatabaseRef<Error = KabuDBError> + ?Sized>(db: &DB, pool: Address) -> Result<u32, PoolError> {
52        let input = IUniswapV3Pool::IUniswapV3PoolCalls::tickSpacing(IUniswapV3Pool::tickSpacingCall {}).abi_encode();
53        let (call_data_result, _, _) = evm_call(db, EvmEnv::default(), pool, input)?;
54
55        let call_return = IUniswapV3Pool::tickSpacingCall::abi_decode_returns(&call_data_result)
56            .map_err(|e| PoolError::AbiDecodingError { method: "tickSpacing", source: e })?;
57        call_return.try_into().map_err(|_| PoolError::InvalidInput { reason: "Invalid tick spacing" })
58    }
59
60    pub fn slot0<DB: DatabaseRef<Error = KabuDBError> + ?Sized>(db: &DB, pool: Address) -> Result<slot0Return, PoolError> {
61        let input = IUniswapV3Pool::IUniswapV3PoolCalls::slot0(IUniswapV3Pool::slot0Call {}).abi_encode();
62        let (call_data_result, _, _) = evm_call(db, EvmEnv::default(), pool, input)?;
63
64        let call_return = IUniswapV3Pool::slot0Call::abi_decode_returns(&call_data_result)
65            .map_err(|e| PoolError::AbiDecodingError { method: "slot0", source: e })?;
66        Ok(call_return)
67    }
68    pub fn liquidity<DB: DatabaseRef<Error = KabuDBError> + ?Sized>(db: &DB, pool: Address) -> Result<u128, PoolError> {
69        let input = IUniswapV3Pool::IUniswapV3PoolCalls::liquidity(IUniswapV3Pool::liquidityCall {}).abi_encode();
70        let (call_data_result, _, _) = evm_call(db, EvmEnv::default(), pool, input)?;
71
72        let call_return = IUniswapV3Pool::liquidityCall::abi_decode_returns(&call_data_result)
73            .map_err(|e| PoolError::AbiDecodingError { method: "liquidity", source: e })?;
74        Ok(call_return)
75    }
76}