waterpump-evm-pool-sdk 0.1.0

EVM pool SDK — viewers, infusers, harvesters, swappers for Uniswap V3/V4, PancakeSwap, Slipstream, Shadow, Algebra
Documentation
use anyhow::Result;
use uniswap_sdk_core::{entities::BaseCurrency, prelude::Currency};

use crate::common::price_utils::PoolKey;

/// Determine the tokens for a two-hop swap path
/// Returns (token0, token1, token2) where:
/// - token0 is the input token
/// - token1 is the intermediate token (shared between pools)
/// - token2 is the output token
pub fn determine_two_hop_path_tokens(
    pool_a_key: &impl PoolKey,
    pool_b_key: &impl PoolKey,
    is_to_pool_b: bool,
) -> Result<(Currency, Currency, Currency)> {
    let (token0, token1, token2) =
        if pool_a_key.token_b().address() == pool_b_key.token_a().address() {
            // Pool A: tokenA -> tokenB, Pool B: tokenB -> tokenC
            if is_to_pool_b {
                (
                    pool_a_key.token_a().clone(),
                    pool_a_key.token_b().clone(),
                    pool_b_key.token_b().clone(),
                )
            } else {
                // Reverse direction
                (
                    pool_b_key.token_b().clone(),
                    pool_b_key.token_a().clone(),
                    pool_a_key.token_a().clone(),
                )
            }
        } else if pool_a_key.token_b().address() == pool_b_key.token_b().address() {
            // Pool A: tokenA -> tokenB, Pool B: tokenA -> tokenB (reversed)
            if is_to_pool_b {
                (
                    pool_a_key.token_a().clone(),
                    pool_a_key.token_b().clone(),
                    pool_b_key.token_a().clone(),
                )
            } else {
                (
                    pool_b_key.token_a().clone(),
                    pool_b_key.token_b().clone(),
                    pool_a_key.token_a().clone(),
                )
            }
        } else if pool_a_key.token_a().address() == pool_b_key.token_a().address() {
            // Pool A: tokenA -> tokenB, Pool B: tokenA -> tokenC
            if is_to_pool_b {
                (
                    pool_a_key.token_b().clone(),
                    pool_a_key.token_a().clone(),
                    pool_b_key.token_b().clone(),
                )
            } else {
                (
                    pool_b_key.token_b().clone(),
                    pool_b_key.token_a().clone(),
                    pool_a_key.token_b().clone(),
                )
            }
        } else if pool_a_key.token_a().address() == pool_b_key.token_b().address() {
            // Pool A: tokenA -> tokenB, Pool B: tokenC -> tokenA
            if is_to_pool_b {
                (
                    pool_a_key.token_b().clone(),
                    pool_a_key.token_a().clone(),
                    pool_b_key.token_a().clone(),
                )
            } else {
                (
                    pool_b_key.token_a().clone(),
                    pool_b_key.token_b().clone(),
                    pool_a_key.token_b().clone(),
                )
            }
        } else {
            return Err(anyhow::anyhow!("Pools must share a common token for two-hop swap"));
        };

    Ok((token0, token1, token2))
}