use std::fmt::{self, Display};
use crate::Result;
use alloy::primitives::{BlockNumber, U256};
use crate::{
quoter::{
erc4626::ERC4626Quoter, fixed::FixedQuoter, uniswap_v2::UniswapV2Quoter,
uniswap_v3::UniswapV3Quoter,
},
token::identity::TokenIdentifier,
};
pub mod erc4626;
pub mod fixed;
pub mod uniswap_v2;
pub mod uniswap_v3;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RateDirection {
Forward,
Reverse,
}
impl Display for RateDirection {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
pub trait Quoter: Send + Sync {
fn tokens(&self) -> (TokenIdentifier, TokenIdentifier);
fn rate(
&self,
amount_in: U256,
direction: RateDirection,
block: BlockNumber,
) -> impl Future<Output = Result<U256>>;
fn id(&self) -> String;
}
#[derive(Debug, Clone)]
pub enum QuoterInstance {
Fixed(FixedQuoter),
UniswapV2(UniswapV2Quoter),
UniswapV3(UniswapV3Quoter),
ERC4626(ERC4626Quoter),
}
impl Quoter for QuoterInstance {
fn id(&self) -> String {
match self {
QuoterInstance::Fixed(tracker) => tracker.id(),
QuoterInstance::UniswapV2(quoter) => quoter.id(),
QuoterInstance::UniswapV3(quoter) => quoter.id(),
QuoterInstance::ERC4626(quoter) => quoter.id(),
}
}
fn tokens(&self) -> (TokenIdentifier, TokenIdentifier) {
match self {
QuoterInstance::Fixed(tracker) => tracker.tokens(),
QuoterInstance::UniswapV2(quoter) => quoter.tokens(),
QuoterInstance::UniswapV3(quoter) => quoter.tokens(),
QuoterInstance::ERC4626(quoter) => quoter.tokens(),
}
}
async fn rate(
&self,
amount_in: U256,
direction: RateDirection,
block: BlockNumber,
) -> Result<U256> {
match self {
QuoterInstance::Fixed(tracker) => tracker.rate(amount_in, direction, block).await,
QuoterInstance::UniswapV2(quoter) => quoter.rate(amount_in, direction, block).await,
QuoterInstance::UniswapV3(quoter) => quoter.rate(amount_in, direction, block).await,
QuoterInstance::ERC4626(quoter) => quoter.rate(amount_in, direction, block).await,
}
}
}