kabu_defi_pools/loaders/
uniswap2.rs1use crate::protocols::{UniswapV2Protocol, fetch_uni2_factory};
2use crate::{UniswapV2Pool, pool_loader};
3use alloy::primitives::{Bytes, Log};
4use alloy::sol_types::SolEventInterface;
5use alloy_evm::EvmEnv;
6use eyre::eyre;
7use futures::Stream;
8use kabu_defi_abi::uniswap2::IUniswapV2Pair::IUniswapV2PairEvents;
9use kabu_evm_db::KabuDBError;
10use kabu_types_market::PoolClass;
11use kabu_types_market::{PoolId, PoolLoader, PoolProtocol, PoolWrapper, get_protocol_by_factory};
12use reth_ethereum_primitives::EthPrimitives;
13use revm::DatabaseRef;
14use std::future::Future;
15use std::pin::Pin;
16use std::sync::Arc;
17
18pool_loader!(UniswapV2PoolLoader);
19
20impl<P, N, LDT> PoolLoader<P, N, LDT> for UniswapV2PoolLoader<P, N, LDT>
21where
22 N: Network,
23 P: Provider<N> + Clone + 'static,
24 LDT: Send + Sync + 'static,
25{
26 fn get_pool_class_by_log(&self, log_entry: &Log) -> Option<(PoolId, PoolClass)> {
27 let log_entry: Option<Log> = Log::new(log_entry.address, log_entry.data.topics().to_vec(), log_entry.data.data.clone());
28 match log_entry {
29 Some(log_entry) => match IUniswapV2PairEvents::decode_log(&log_entry) {
30 Ok(event) => match event.data {
31 IUniswapV2PairEvents::Swap(_)
32 | IUniswapV2PairEvents::Mint(_)
33 | IUniswapV2PairEvents::Burn(_)
34 | IUniswapV2PairEvents::Sync(_) => Some((PoolId::Address(log_entry.address), PoolClass::UniswapV2)),
35 _ => None,
36 },
37 Err(_) => None,
38 },
39 None => None,
40 }
41 }
42
43 fn fetch_pool_by_id<'a>(&'a self, pool_id: PoolId) -> Pin<Box<dyn Future<Output = eyre::Result<PoolWrapper>> + Send + 'a>> {
44 Box::pin(async move {
45 if let Some(provider) = self.provider.clone() {
46 self.fetch_pool_by_id_from_provider(pool_id, provider).await
47 } else {
48 Err(eyre!("NO_PROVIDER"))
49 }
50 })
51 }
52
53 fn fetch_pool_by_id_from_provider<'a>(
54 &'a self,
55 pool_id: PoolId,
56 provider: P,
57 ) -> Pin<Box<dyn Future<Output = eyre::Result<PoolWrapper>> + Send + 'a>> {
58 Box::pin(async move {
59 let pool_address = match pool_id {
60 PoolId::Address(addr) => addr,
61 PoolId::B256(_) => return Err(eyre!("UniswapV2 pools only support Address-based pool IDs")),
62 };
63 let factory_address = fetch_uni2_factory(provider.clone(), pool_address).await?;
64 match get_protocol_by_factory(factory_address) {
65 PoolProtocol::NomiswapStable
66 | PoolProtocol::Miniswap
67 | PoolProtocol::Integral
68 | PoolProtocol::Safeswap
69 | PoolProtocol::AntFarm => Err(eyre!("POOL_PROTOCOL_NOT_SUPPORTED")),
70 _ => Ok(PoolWrapper::new(Arc::new(UniswapV2Pool::fetch_pool_data(provider, pool_address).await?))),
71 }
72 })
73 }
74
75 fn fetch_pool_by_id_from_evm(&self, pool_id: PoolId, db: &dyn DatabaseRef<Error = KabuDBError>) -> eyre::Result<PoolWrapper> {
76 let pool_address = match pool_id {
77 PoolId::Address(addr) => addr,
78 PoolId::B256(_) => return Err(eyre!("UniswapV2 pools only support Address-based pool IDs")),
79 };
80 Ok(PoolWrapper::new(Arc::new(UniswapV2Pool::fetch_pool_data_evm(db, &EvmEnv::default(), pool_address)?)))
81 }
82
83 fn is_code(&self, code: &Bytes) -> bool {
84 UniswapV2Protocol::is_code(code)
85 }
86
87 fn protocol_loader(&self) -> eyre::Result<Pin<Box<dyn Stream<Item = (PoolId, PoolClass)> + Send>>> {
88 Err(eyre!("NOT_IMPLEMENTED"))
89 }
90}