use std::collections::HashSet;
use alloy::{
primitives::address,
providers::{Provider, ProviderBuilder},
};
use eth_prices::{
Result,
asset::{Asset, AssetIdentifier},
config::Config,
network::NetworkTime,
quoter::RateDirection,
router::Router,
};
use tracing::info;
#[tokio::main]
pub async fn main() -> Result<()> {
tracing_subscriber::fmt::init();
let config = Config::load("config.toml").await;
for (_, chain_config) in config?.chains {
let url = chain_config.rpc_url;
let provider = ProviderBuilder::new().connect(&url).await?;
for token_config in chain_config.tokens {
let token_address = token_config.address;
info!("token: {:?}", token_address);
}
let box_provider = provider.erased();
let block = box_provider.get_block_number().await?;
let network = NetworkTime::from_provider(box_provider.clone(), 1.into(), block);
let networks = network.instant();
let precision = 10;
let quoters = chain_config.quoters.all(&box_provider).await?;
for quoter in "ers {
info!("quoter: {:?}", quoter.to_string());
let (token_a, token_b) = quoter.tokens();
let token_a = Asset::new(token_a, &box_provider).await?;
let token_b = Asset::new(token_b, &box_provider).await?;
let (amount_a, amount_b) = (token_a.nominal_amount(), token_b.nominal_amount());
let forward_rate = quoter
.rate(amount_a, RateDirection::Forward, &networks)
.await?;
let reverse_rate = quoter
.rate(amount_b, RateDirection::Reverse, &networks)
.await?;
info!(
"forward_rate: {:?} {} = {:?} {}",
token_a.format_amount(amount_a, precision),
token_a.symbol,
token_b.format_amount(forward_rate, precision),
token_b.symbol,
);
info!(
"reverse_rate: {:?} {} = {:?} {}",
token_b.format_amount(amount_b, precision),
token_b.symbol,
token_a.format_amount(reverse_rate, precision),
token_a.symbol,
);
}
let router = Router::from_iter(quoters);
info!("{}", router.to_graphviz());
let mut all_tokens = HashSet::new();
for quoter in &router.quoters {
let (token_in, token_out) = quoter.tokens();
all_tokens.insert(token_in);
all_tokens.insert(token_out);
}
let token_out = AssetIdentifier::ERC20 {
address: address!("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"),
};
let token_b = Asset::new(token_out.clone(), &box_provider).await?;
let mut routes = Vec::new();
for token in all_tokens {
if token == token_out {
continue;
}
let route = router.compute(&token, &token_out)?;
info!("route: {:?}", route);
routes.push(route);
}
for route in &routes {
let token_input = &route.input_token;
let token_a = Asset::new(token_input.clone(), &box_provider).await?;
let token_input = token_a.nominal_amount();
let token_output = route.quote(&networks, token_input).await?;
info!(
"token_output: 1 {} = {:?}",
token_a.symbol,
token_b.format_amount(token_output, precision)
);
}
}
Ok(())
}