#[macro_export]
macro_rules! impl_v3_pool_state {
($struct_name:ident) => {
#[async_trait::async_trait]
impl $crate::traits::pool_state::PoolState for $struct_name {
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn sqrt_price_x96(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::U160> {
let slot0 = self.slot0(block_id).await?;
tracing::debug!(sqrt_price_x96 = ?slot0.sqrtPriceX96, "Sqrt price retrieved from slot0");
Ok(slot0.sqrtPriceX96)
}
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn tick(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::I24> {
let slot0 = self.slot0(block_id).await?;
tracing::debug!(tick = ?slot0.tick, "Tick retrieved from slot0");
Ok(slot0.tick)
}
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn liquidity(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::U128> {
let pool_contract = uniswap_lens::bindings::iuniswapv3pool::IUniswapV3Pool::IUniswapV3PoolInstance::new(self.pool_address(), self.provider.clone());
tracing::trace!("Calling liquidity() on pool contract");
let mut call_builder = pool_contract.liquidity();
if let Some(block_id) = block_id {
call_builder = call_builder.block(block_id);
}
let liquidity: u128 = call_builder.call().await.map_err(|e| anyhow::anyhow!("Failed to call liquidity: {:?}", e))?;
tracing::debug!(liquidity = ?liquidity, "Liquidity retrieved");
Ok(alloy::primitives::aliases::U128::from(liquidity))
}
}
impl $struct_name {
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
pub async fn slot0(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<uniswap_lens::bindings::iuniswapv3pool::IUniswapV3Pool::slot0Return> {
let pool_contract = uniswap_lens::bindings::iuniswapv3pool::IUniswapV3Pool::IUniswapV3PoolInstance::new(self.pool_address(), self.provider.clone());
tracing::trace!("Calling slot0() on pool contract");
let mut call_builder = pool_contract.slot0();
if let Some(block_id) = block_id {
call_builder = call_builder.block(block_id);
}
call_builder.call().await.map_err(Into::into)
}
}
};
}
#[macro_export]
macro_rules! impl_shadow_pool_state {
($struct_name:ident) => {
#[async_trait::async_trait]
impl $crate::traits::pool_state::PoolState for $struct_name {
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn sqrt_price_x96(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::U160> {
let slot0 = self.slot0(block_id).await?;
tracing::debug!(sqrt_price_x96 = ?slot0.sqrtPriceX96, "Sqrt price retrieved from slot0");
Ok(slot0.sqrtPriceX96)
}
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn tick(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::I24> {
let slot0 = self.slot0(block_id).await?;
tracing::debug!(tick = ?slot0.tick, "Tick retrieved from slot0");
Ok(slot0.tick)
}
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn liquidity(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::U128> {
let pool_contract = waterpump_evm_shadow_client::interfaces::IRamsesV3PoolState::IRamsesV3PoolStateInstance::new(self.pool_address(), self.provider.clone());
tracing::trace!("Calling liquidity() on pool contract");
let mut call_builder = pool_contract.liquidity();
if let Some(block_id) = block_id {
call_builder = call_builder.block(block_id);
}
let liquidity: u128 = call_builder.call().await.map_err(|e| anyhow::anyhow!("Failed to call liquidity: {:?}", e))?;
tracing::debug!(liquidity = ?liquidity, "Liquidity retrieved");
Ok(alloy::primitives::aliases::U128::from(liquidity))
}
}
impl $struct_name {
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
pub async fn slot0(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<waterpump_evm_shadow_client::interfaces::IRamsesV3PoolState::slot0Return> {
let pool_contract = waterpump_evm_shadow_client::interfaces::IRamsesV3PoolState::IRamsesV3PoolStateInstance::new(self.pool_address(), self.provider.clone());
tracing::trace!("Calling slot0() on pool contract");
let mut call_builder = pool_contract.slot0();
if let Some(block_id) = block_id {
call_builder = call_builder.block(block_id);
}
call_builder.call().await.map_err(Into::into)
}
}
};
}
#[macro_export]
macro_rules! impl_pancake_v3_pool_state {
($struct_name:ident) => {
#[async_trait::async_trait]
impl $crate::traits::pool_state::PoolState for $struct_name {
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn sqrt_price_x96(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::U160> {
let slot0 = self.slot0(block_id).await?;
tracing::debug!(sqrt_price_x96 = ?slot0.sqrtPriceX96, "Sqrt price retrieved from slot0");
Ok(slot0.sqrtPriceX96)
}
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn tick(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::I24> {
let slot0 = self.slot0(block_id).await?;
tracing::debug!(tick = ?slot0.tick, "Tick retrieved from slot0");
Ok(slot0.tick)
}
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn liquidity(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::U128> {
let pool_contract = waterpump_evm_pancakeswap_client::interfaces::IPancakeV3PoolState::IPancakeV3PoolStateInstance::new(self.pool_address(), self.provider.clone());
tracing::trace!("Calling liquidity() on pool contract");
let mut call_builder = pool_contract.liquidity();
if let Some(block_id) = block_id {
call_builder = call_builder.block(block_id);
}
let liquidity: u128 = call_builder.call().await.map_err(|e| anyhow::anyhow!("Failed to call liquidity: {:?}", e))?;
tracing::debug!(liquidity = ?liquidity, "Liquidity retrieved");
Ok(alloy::primitives::aliases::U128::from(liquidity))
}
}
impl $struct_name {
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
pub async fn slot0(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<waterpump_evm_pancakeswap_client::interfaces::IPancakeV3PoolState::slot0Return> {
let pool_contract = waterpump_evm_pancakeswap_client::interfaces::IPancakeV3PoolState::IPancakeV3PoolStateInstance::new(self.pool_address(), self.provider.clone());
tracing::trace!("Calling slot0() on pool contract");
let mut call_builder = pool_contract.slot0();
if let Some(block_id) = block_id {
call_builder = call_builder.block(block_id);
}
call_builder.call().await.map_err(Into::into)
}
}
};
}
#[macro_export]
macro_rules! impl_slipstream_pool_state {
($struct_name:ident) => {
#[async_trait::async_trait]
impl $crate::traits::pool_state::PoolState for $struct_name {
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn sqrt_price_x96(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::U160> {
let slot0 = self.slot0(block_id).await?;
tracing::debug!(sqrt_price_x96 = ?slot0.sqrtPriceX96, "Sqrt price retrieved from slot0");
Ok(slot0.sqrtPriceX96)
}
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn tick(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::I24> {
let slot0 = self.slot0(block_id).await?;
tracing::debug!(tick = ?slot0.tick, "Tick retrieved from slot0");
Ok(slot0.tick)
}
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn liquidity(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::U128> {
let block_id = block_id.unwrap_or(alloy::eips::BlockId::latest());
let pool_contract = uniswap_lens::bindings::iuniswapv3pool::IUniswapV3Pool::IUniswapV3PoolInstance::new(self.pool_address(), self.provider.clone());
tracing::trace!("Calling liquidity() on pool contract");
let call_builder = pool_contract.liquidity().block(block_id);
let liquidity: u128 = call_builder.call().await.map_err(|e| anyhow::anyhow!("Failed to call liquidity: {:?}", e))?;
tracing::debug!(liquidity = ?liquidity, "Liquidity retrieved");
Ok(alloy::primitives::aliases::U128::from(liquidity))
}
}
impl $struct_name {
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
pub async fn slot0(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<waterpump_evm_slipstream_client::interfaces::ICLPool::slot0Return> {
let pool_contract = waterpump_evm_slipstream_client::interfaces::ICLPool::ICLPoolInstance::new(self.pool_address(), self.provider.clone());
tracing::trace!("Calling slot0() on pool contract");
let mut call_builder = pool_contract.slot0();
if let Some(block_id) = block_id {
call_builder = call_builder.block(block_id);
}
call_builder.call().await.map_err(Into::into)
}
}
};
}
#[macro_export]
macro_rules! impl_quickswap_pool_state {
($struct_name:ident) => {
#[async_trait::async_trait]
impl $crate::traits::pool_state::PoolState for $struct_name {
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn sqrt_price_x96(
&self,
block_id: Option<alloy::eips::BlockId>,
) -> anyhow::Result<alloy::primitives::aliases::U160> {
let state = self.get_global_state(block_id).await?;
Ok(state.price)
}
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn tick(
&self,
block_id: Option<alloy::eips::BlockId>,
) -> anyhow::Result<alloy::primitives::aliases::I24> {
let state = self.get_global_state(block_id).await?;
Ok(state.tick)
}
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
async fn liquidity(
&self,
block_id: Option<alloy::eips::BlockId>,
) -> anyhow::Result<alloy::primitives::aliases::U128> {
let pool =
waterpump_evm_algebra_client::interfaces::IAlgebraPoolState::IAlgebraPoolStateInstance::new(
self.pool_address(),
self.provider.clone(),
);
let mut call_builder = pool.liquidity();
if let Some(block_id) = block_id {
call_builder = call_builder.block(block_id);
}
let liquidity = call_builder.call().await?;
Ok(alloy::primitives::aliases::U128::from(liquidity))
}
}
impl $struct_name {
#[tracing::instrument(skip(self), fields(pool_address = ?self.pool_address()))]
pub async fn get_global_state(
&self,
block_id: Option<alloy::eips::BlockId>,
) -> anyhow::Result<waterpump_evm_algebra_client::interfaces::IAlgebraPoolState::globalStateReturn>
{
let pool =
waterpump_evm_algebra_client::interfaces::IAlgebraPoolState::IAlgebraPoolStateInstance::new(
self.pool_address(),
self.provider.clone(),
);
let mut call_builder = pool.globalState();
if let Some(block_id) = block_id {
call_builder = call_builder.block(block_id);
}
call_builder.call().await.map_err(Into::into)
}
}
};
}
#[macro_export]
macro_rules! impl_v4_pool_state {
($struct_name:ident) => {
#[async_trait::async_trait]
impl $crate::traits::pool_state::PoolState for $struct_name {
#[tracing::instrument(skip(self), fields(pool_id = ?self.pool_id()))]
async fn sqrt_price_x96(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::U160> {
let slot0 = self.slot0(block_id).await?;
tracing::debug!(sqrt_price_x96 = ?slot0.0, "Sqrt price retrieved from slot0");
Ok(slot0.0)
}
#[tracing::instrument(skip(self), fields(pool_id = ?self.pool_id()))]
async fn tick(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::I24> {
let slot0 = self.slot0(block_id).await?;
tracing::debug!(tick = ?slot0.1, "Tick retrieved from slot0");
Ok(slot0.1)
}
#[tracing::instrument(skip(self), fields(pool_id = ?self.pool_id()))]
async fn liquidity(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<alloy::primitives::aliases::U128> {
use $crate::contract_libs::state_view::IStateView;
let state_view = IStateView::new(self.state_view_address(), self.provider.clone());
let mut call_builder = state_view.getLiquidity(self.pool_id());
if let Some(block_id) = block_id {
call_builder = call_builder.block(block_id);
}
let liquidity: u128 = call_builder.call().await?;
Ok(alloy::primitives::aliases::U128::from(liquidity))
}
}
impl $struct_name {
#[tracing::instrument(skip(self), fields(pool_id = ?self.pool_id()))]
pub async fn slot0(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<(alloy::primitives::aliases::U160, alloy::primitives::aliases::I24, alloy::primitives::aliases::U24, alloy::primitives::aliases::U24)> {
use $crate::contract_libs::state_view::IStateView;
let state_view = IStateView::new(self.state_view_address(), self.provider.clone());
let mut call_builder = state_view.getSlot0(self.pool_id());
if let Some(block_id) = block_id {
call_builder = call_builder.block(block_id);
}
let slot0 = call_builder.call().await?;
Ok((slot0.sqrtPriceX96, slot0.tick, slot0.protocolFee, slot0.lpFee))
}
}
};
}
#[macro_export]
macro_rules! impl_v3_multi_pool_state {
($struct_name:ident) => {
#[async_trait::async_trait]
impl $crate::traits::pool_state::MultiPoolState for $struct_name {
#[tracing::instrument(skip(self), fields(pool_count = self.pools().len()))]
async fn sqrt_price_x96s(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<Vec<alloy::primitives::aliases::U160>> {
let slot0s = self.slot0s(block_id).await?;
tracing::debug!("Extracting sqrt prices from {} pools", slot0s.len());
let sqrt_prices: Vec<alloy::primitives::aliases::U160> = slot0s
.into_iter()
.map(|r| r.sqrtPriceX96)
.collect();
tracing::debug!(sqrt_price_count = sqrt_prices.len(), "All sqrt prices extracted");
Ok(sqrt_prices)
}
#[tracing::instrument(skip(self), fields(pool_count = self.pools().len()))]
async fn ticks(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<Vec<alloy::primitives::aliases::I24>> {
let slot0s = self.slot0s(block_id).await?;
tracing::debug!("Extracting ticks from {} pools", slot0s.len());
let ticks: Vec<alloy::primitives::aliases::I24> = slot0s
.into_iter()
.map(|r| r.tick)
.collect();
tracing::debug!(tick_count = ticks.len(), "All ticks extracted");
Ok(ticks)
}
#[tracing::instrument(skip(self), fields(pool_count = self.pools().len()))]
async fn liquidities(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<Vec<alloy::primitives::aliases::U128>> {
let mut multicall = alloy::providers::Provider::multicall(&self.provider).dynamic();
if let Some(block_id) = block_id {
multicall = multicall.block(block_id);
}
tracing::debug!("Building multicall for liquidity queries on {} pools", self.pools().len());
for (_, pool_address) in self.pools() {
let pool_contract = uniswap_lens::bindings::iuniswapv3pool::IUniswapV3Pool::IUniswapV3PoolInstance::new(pool_address.clone(), self.provider.clone());
multicall = multicall.add_dynamic(pool_contract.liquidity());
}
tracing::trace!("Executing multicall for liquidity queries");
let result: Vec<u128> = multicall.aggregate().await?;
tracing::debug!(result_count = result.len(), "Multicall completed");
let liquidities: Vec<alloy::primitives::aliases::U128> = result
.into_iter()
.map(|l| alloy::primitives::aliases::U128::from(l))
.collect();
Ok(liquidities)
}
}
impl $struct_name {
#[tracing::instrument(skip(self), fields(pool_count = self.pools().len()))]
pub async fn slot0s(&self, block_id: Option<alloy::eips::BlockId>) -> anyhow::Result<Vec<uniswap_lens::bindings::iuniswapv3pool::IUniswapV3Pool::slot0Return>> {
let mut multicall = alloy::providers::Provider::multicall(&self.provider).dynamic();
if let Some(block_id) = block_id {
multicall = multicall.block(block_id);
}
tracing::debug!("Building multicall for {} pools", self.pools().len());
for (_, pool_address) in self.pools() {
let pool_contract = uniswap_lens::bindings::iuniswapv3pool::IUniswapV3Pool::IUniswapV3PoolInstance::new(pool_address.clone(), self.provider.clone());
multicall = multicall.add_dynamic(pool_contract.slot0());
}
tracing::trace!("Executing multicall for slot0 queries");
let result = multicall.aggregate().await?;
tracing::debug!(result_count = result.len(), "Multicall completed");
Ok(result)
}
}
};
}
#[macro_export]
macro_rules! impl_slipstream_multi_pool_state {
($struct_name:ident) => {
#[async_trait::async_trait]
impl $crate::traits::pool_state::MultiPoolState for $struct_name {
#[tracing::instrument(skip(self), fields(pool_count = self.pools().len()))]
async fn sqrt_price_x96s(
&self,
block_id: Option<alloy::eips::BlockId>,
) -> anyhow::Result<Vec<alloy::primitives::aliases::U160>> {
let slot0s = self.slot0s(block_id).await?;
tracing::debug!("Extracting sqrt prices from {} pools", slot0s.len());
let sqrt_prices: Vec<alloy::primitives::aliases::U160> =
slot0s.into_iter().map(|r| r.sqrtPriceX96).collect();
tracing::debug!(sqrt_price_count = sqrt_prices.len(), "All sqrt prices extracted");
Ok(sqrt_prices)
}
#[tracing::instrument(skip(self), fields(pool_count = self.pools().len()))]
async fn ticks(
&self,
block_id: Option<alloy::eips::BlockId>,
) -> anyhow::Result<Vec<alloy::primitives::aliases::I24>> {
let slot0s = self.slot0s(block_id).await?;
tracing::debug!("Extracting ticks from {} pools", slot0s.len());
let ticks: Vec<alloy::primitives::aliases::I24> =
slot0s.into_iter().map(|r| r.tick).collect();
tracing::debug!(tick_count = ticks.len(), "All ticks extracted");
Ok(ticks)
}
#[tracing::instrument(skip(self), fields(pool_count = self.pools().len()))]
async fn liquidities(
&self,
block_id: Option<alloy::eips::BlockId>,
) -> anyhow::Result<Vec<alloy::primitives::aliases::U128>> {
let mut multicall = alloy::providers::Provider::multicall(&self.provider).dynamic();
if let Some(block_id) = block_id {
multicall = multicall.block(block_id);
}
tracing::debug!(
"Building multicall for liquidity queries on {} pools",
self.pools().len()
);
for (_, pool_address) in self.pools() {
let pool_contract =
waterpump_evm_slipstream_client::interfaces::ICLPool::ICLPoolInstance::new(
pool_address.clone(),
&self.provider,
);
multicall = multicall.add_dynamic(pool_contract.liquidity());
}
tracing::trace!("Executing multicall for liquidity queries");
let result: Vec<u128> = multicall.aggregate().await?;
tracing::debug!(result_count = result.len(), "Multicall completed");
let liquidities: Vec<alloy::primitives::aliases::U128> =
result.into_iter().map(|l| alloy::primitives::aliases::U128::from(l)).collect();
Ok(liquidities)
}
}
impl $struct_name {
#[tracing::instrument(skip(self), fields(pool_count = self.pools().len()))]
pub async fn slot0s(
&self,
block_id: Option<alloy::eips::BlockId>,
) -> anyhow::Result<
Vec<waterpump_evm_slipstream_client::interfaces::ICLPool::slot0Return>,
> {
let mut multicall = alloy::providers::Provider::multicall(&self.provider).dynamic();
if let Some(block_id) = block_id {
multicall = multicall.block(block_id);
}
tracing::debug!("Building multicall for {} pools", self.pools().len());
for (_, pool_address) in self.pools() {
let pool_contract =
waterpump_evm_slipstream_client::interfaces::ICLPool::ICLPoolInstance::new(
pool_address.clone(),
&self.provider,
);
multicall = multicall.add_dynamic(pool_contract.slot0());
}
tracing::trace!("Executing multicall for slot0 queries");
let result = multicall.aggregate().await?;
tracing::debug!(result_count = result.len(), "Multicall completed");
Ok(result)
}
}
};
}
#[macro_export]
macro_rules! impl_v4_multi_pool_state {
($struct_name:ident) => {
#[async_trait::async_trait]
impl $crate::traits::pool_state::MultiPoolState for $struct_name {
#[tracing::instrument(skip(self), fields(pool_count = self.pools().len()))]
async fn sqrt_price_x96s(
&self,
block_id: Option<alloy::eips::BlockId>,
) -> anyhow::Result<Vec<alloy::primitives::aliases::U160>> {
let slot0s = self.slot0s(block_id).await?;
tracing::debug!("Extracting sqrt prices from {} pools", slot0s.len());
let sqrt_prices: Vec<alloy::primitives::aliases::U160> =
slot0s.into_iter().map(|slot0| slot0.0).collect();
tracing::debug!(sqrt_price_count = sqrt_prices.len(), "All sqrt prices extracted");
Ok(sqrt_prices)
}
#[tracing::instrument(skip(self), fields(pool_count = self.pools().len()))]
async fn ticks(
&self,
block_id: Option<alloy::eips::BlockId>,
) -> anyhow::Result<Vec<alloy::primitives::aliases::I24>> {
let slot0s = self.slot0s(block_id).await?;
tracing::debug!("Extracting ticks from {} pools", slot0s.len());
let ticks: Vec<alloy::primitives::aliases::I24> =
slot0s.into_iter().map(|slot0| slot0.1).collect();
tracing::debug!(tick_count = ticks.len(), "All ticks extracted");
Ok(ticks)
}
#[tracing::instrument(skip(self), fields(pool_count = self.pools().len()))]
async fn liquidities(
&self,
block_id: Option<alloy::eips::BlockId>,
) -> anyhow::Result<Vec<alloy::primitives::aliases::U128>> {
use $crate::contract_libs::state_view::IStateView;
let state_view = IStateView::new(self.state_view_address(), &self.provider);
let mut multicall = alloy::providers::Provider::multicall(&self.provider).dynamic();
if let Some(block_id) = block_id {
multicall = multicall.block(block_id);
}
tracing::debug!(
"Building multicall for liquidity queries on {} pools",
self.pools().len()
);
for (_, pool_id) in self.pools() {
multicall = multicall.add_dynamic(state_view.getLiquidity(*pool_id));
}
let result: Vec<u128> = multicall.aggregate().await?;
tracing::debug!("Multicall completed with {} results", result.len());
let liquidities: Vec<alloy::primitives::aliases::U128> = result
.into_iter()
.map(|liquidity| alloy::primitives::aliases::U128::from(liquidity))
.collect();
Ok(liquidities)
}
}
impl $struct_name {
#[tracing::instrument(skip(self), fields(pool_count = self.pools().len()))]
pub async fn slot0s(
&self,
block_id: Option<alloy::eips::BlockId>,
) -> anyhow::Result<
Vec<(
alloy::primitives::aliases::U160,
alloy::primitives::aliases::I24,
alloy::primitives::aliases::U24,
alloy::primitives::aliases::U24,
)>,
> {
use $crate::contract_libs::state_view::IStateView;
let state_view = IStateView::new(self.state_view_address(), &self.provider);
let mut multicall = alloy::providers::Provider::multicall(&self.provider).dynamic();
if let Some(block_id) = block_id {
multicall = multicall.block(block_id);
}
tracing::debug!("Building multicall for {} pools", self.pools().len());
for (_, pool_id) in self.pools() {
multicall = multicall.add_dynamic(state_view.getSlot0(*pool_id));
}
let result = multicall.aggregate().await?;
tracing::debug!("Multicall completed with {} results", result.len());
let slot0s: Vec<(
alloy::primitives::aliases::U160,
alloy::primitives::aliases::I24,
alloy::primitives::aliases::U24,
alloy::primitives::aliases::U24,
)> = result
.into_iter()
.map(|slot0| (slot0.sqrtPriceX96, slot0.tick, slot0.protocolFee, slot0.lpFee))
.collect();
Ok(slot0s)
}
}
};
}