Skip to content

Commit

Permalink
refactor(exchange): wip refactoring internal methods of the mod
Browse files Browse the repository at this point in the history
  • Loading branch information
willyrgf committed Oct 4, 2023
1 parent 94969d1 commit 74546c9
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 35 deletions.
14 changes: 14 additions & 0 deletions src/asset/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@ impl Asset {
})
}

#[cfg(test)]
pub fn dummy_asset(address: &str, path_asset_address: &str) -> Self {
let network = Network::default();
Asset {
name: "dummy".to_string(),
kind: "dummy".to_string(),
network_id: network.name().to_string(),
address: address.to_string(),
slippage: 0.0,
path_asset: path_asset_address.to_string(),
network: Network::default(),
}
}

pub fn slippage(&self) -> f64 {
self.slippage
}
Expand Down
53 changes: 32 additions & 21 deletions src/cmd/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ use std::str::FromStr;

use crate::{
asset::Asset,
config::{
exchange::Exchange, network::Network, wallet::Wallet, withdraw_wallet::WithdrawWallet,
Config,
},
config::{network::Network, wallet::Wallet, withdraw_wallet::WithdrawWallet, Config},
exchange::Exchange,
rebalancer::config::RebalancerConfig,
utils::math,
};
Expand All @@ -15,21 +13,18 @@ use web3::types::{Address, H160, U256};

//TODO: add constants to all keys in value_of

#[tracing::instrument(name = "get exchange from command args", level = "debug", skip(args))]
#[tracing::instrument(name = "get exchange from command args", level = "debug", skip(args))]
pub fn get_exchange(args: &ArgMatches) -> Result<&Exchange, anyhow::Error> {
match args.get_one::<String>("exchange") {
Some(n) => {
let network = Config::global()
.exchanges
.get(n)
.context("exchange not found")?;
Ok(network)
Some(exchange_name) => {
let exchange = Exchange::try_from((Config::global(), exchange_name))?;
Ok(&exchange)
}
None => Err(anyhow::anyhow!("--exchange is required")),
}
}

#[tracing::instrument(name = "get network from command args", level = "debug", skip(args))]
#[tracing::instrument(name = "get network from command args", level = "debug", skip(args))]
pub fn get_network(args: &ArgMatches) -> Result<&Network, anyhow::Error> {
match args.get_one::<String>("network") {
Some(n) => {
Expand All @@ -43,15 +38,15 @@ pub fn get_network(args: &ArgMatches) -> Result<&Network, anyhow::Error> {
}
}

#[tracing::instrument(name = "get address from command args", level = "debug", skip(args))]
#[tracing::instrument(name = "get address from command args", level = "debug", skip(args))]
pub fn get_address(args: &ArgMatches) -> Result<H160, anyhow::Error> {
match args.get_one::<String>("address") {
Some(a) => Address::from_str(a).map_err(|e| anyhow::anyhow!(e)),
None => Err(anyhow::anyhow!("--address is required")),
}
}

#[tracing::instrument(name = "get wallet from command args", level = "debug", skip(args))]
#[tracing::instrument(name = "get wallet from command args", level = "debug", skip(args))]
pub fn get_wallet(args: &ArgMatches) -> Result<&Wallet, anyhow::Error> {
let config = Config::global();
match args.get_one::<String>("wallet") {
Expand Down Expand Up @@ -106,15 +101,23 @@ pub fn get_amount(args: &ArgMatches, asset_decimals: u8) -> Result<U256, anyhow:
}
}

#[tracing::instrument(name = "get amount in f64 from command args", level = "debug", skip(args))]
#[tracing::instrument(
name = "get amount in f64 from command args",
level = "debug",
skip(args)
)]
pub fn get_amount_f64(args: &ArgMatches) -> Result<f64, anyhow::Error> {
match args.get_one::<f64>("amount") {
Some(amount) => Ok(*amount),
None => Err(anyhow::anyhow!("--amount is not a number")),
}
}

#[tracing::instrument(name = "get slippage in f64 from command args", level = "debug", skip(args))]
#[tracing::instrument(
name = "get slippage in f64 from command args",
level = "debug",
skip(args)
)]
pub fn get_slippage(args: &ArgMatches) -> Result<f64, anyhow::Error> {
match args.get_one::<f64>("slippage") {
Some(f) if *f > 0.0 && *f <= 100.0 => Ok(*f),
Expand All @@ -126,7 +129,11 @@ pub fn get_slippage(args: &ArgMatches) -> Result<f64, anyhow::Error> {
}
}

#[tracing::instrument(name = "get input token in network from command args", level = "debug", skip(args))]
#[tracing::instrument(
name = "get input token in network from command args",
level = "debug",
skip(args)
)]
pub fn get_token_input_in_network_from_args(
args: &ArgMatches,
network_id: &str,
Expand All @@ -141,7 +148,11 @@ pub fn get_token_input_in_network_from_args(
}
}

#[tracing::instrument(name = "get output token in network from command args", level = "debug", skip(args))]
#[tracing::instrument(
name = "get output token in network from command args",
level = "debug",
skip(args)
)]
pub fn get_token_output_in_network_from_args(
args: &ArgMatches,
network_id: &str,
Expand Down Expand Up @@ -184,20 +195,20 @@ pub fn get_withdraw_wallet(args: &ArgMatches) -> WithdrawWallet {
}
}

#[tracing::instrument(name = "get hide zero from command args", level = "debug", skip(args))]
#[tracing::instrument(name = "get hide zero from command args", level = "debug", skip(args))]
pub fn get_hide_zero(args: &ArgMatches) -> bool {
match args.get_one::<String>("hide-zero") {
Some(b) => b.parse().unwrap_or(false),
_ => false,
}
}

#[tracing::instrument(name = "get run every from command args", level = "debug", skip(args))]
#[tracing::instrument(name = "get run every from command args", level = "debug", skip(args))]
pub fn get_run_every(args: &ArgMatches) -> Option<&u32> {
args.get_one::<u32>("run-every")
}

#[tracing::instrument(name = "get track from command args", level = "debug", skip(args))]
#[tracing::instrument(name = "get track from command args", level = "debug", skip(args))]
pub fn get_track(args: &ArgMatches) -> bool {
match args.get_one::<String>("track") {
Some(b) => b.parse().unwrap_or(false),
Expand Down
2 changes: 1 addition & 1 deletion src/config/exchange.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl Exchange {
}

pub fn kind(&self) -> &str {
self.kind.as_str()
self..as_str()
}

pub fn network_id(&self) -> &str {
Expand Down
9 changes: 4 additions & 5 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
mod decrypt_wallet;
pub mod exchange;
pub mod network;
pub mod wallet;
pub mod withdraw_wallet;
Expand All @@ -8,10 +7,10 @@ use once_cell::sync::OnceCell;
use serde::{Deserialize, Serialize};

use crate::{
asset::config::AssetsConfig, notification::config::Notifications,
rebalancer::config::RebalancersConfig,
asset::config::AssetsConfig, exchange::config::ExchangesConfig,
notification::config::Notifications, rebalancer::config::RebalancersConfig,
};
use exchange::Exchanges;

use network::Networks;
use wallet::Wallets;
use withdraw_wallet::WithdrawWallets;
Expand All @@ -30,7 +29,7 @@ pub struct Config {
pub wallets: Wallets,
pub withdraw_wallets: Option<WithdrawWallets>,
pub networks: Networks,
pub exchanges: Exchanges,
pub exchanges: ExchangesConfig,
pub assets: AssetsConfig,
pub rebalancers: Option<RebalancersConfig>,
pub notifications: Option<Notifications>,
Expand Down
15 changes: 12 additions & 3 deletions src/config/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use web3::{
Web3,
};

use super::{exchange::Exchange, wallet::Wallet, Config};
use crate::{asset::Asset, utils::scalar::BigDecimal};
use super::{wallet::Wallet, Config};
use crate::{asset::Asset, exchange::Exchange, utils::scalar::BigDecimal};

#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub struct Network {
Expand All @@ -22,6 +22,14 @@ pub struct Network {
wrapped_asset: Option<String>,
}

impl Default for Network {
fn default() -> Self {
Self {
..Default::default()
}
}
}

impl Network {
pub fn rpc_url(&self) -> &str {
self.rpc_url.as_str()
Expand Down Expand Up @@ -86,7 +94,8 @@ impl Network {
.exchanges
.hashmap()
.values()
.filter(|e| e.network_id() == self.name)
.filter(|exchange_config| exchange_config.network_id() == self.name)
.map(|config| &Exchange::new(config))
.collect()
}

Expand Down
76 changes: 73 additions & 3 deletions src/exchange/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::asset::Asset;
use crate::config::Config;
use crate::utils::resources::{exists_resource_file_fs_or_res, get_resource_file_fs_or_res};
use crate::utils::scalar::BigDecimal;
use crate::utils::{self, math};
Expand All @@ -20,7 +21,6 @@ use web3::{

use crate::config::network::Network;
use crate::config::wallet::Wallet;
use crate::config::Config;

use super::swap_tokens_for_tokens;

Expand Down Expand Up @@ -179,18 +179,23 @@ impl ExchangeConfig {
// input -> path_asset -> path_asset from output -> output
//TODO: check liquidity of directly path
let mut v = vec![];

//let network = self.get_network();
// let wrapped_asset = network.get_wrapped_asset();
let input_path_asset = input_asset.get_path_asset();
let output_path_asset = output_asset.get_path_asset();

let same_input_output_path_asset =
input_path_asset.address() == output_path_asset.address();

let input_asset_is_same_of_some_asset_path = input_asset.address()
== input_path_asset.address()
|| input_asset.address() == output_path_asset.address();

let output_asset_is_same_of_some_asset_path = output_asset.address()
== input_path_asset.address()
|| output_asset.address() == output_path_asset.address();

// let has_direct_route = match self.get_factory_pair(input_asset, output_asset).await {
// Some(a) => (a.to_string().as_str() != ZERO_ADDRESS),
// _ => false,
Expand Down Expand Up @@ -498,12 +503,77 @@ impl ExchangeConfig {
}

#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct Exchanges(HashMap<String, ExchangeConfig>);
impl Exchanges {
pub struct ExchangesConfig(HashMap<String, ExchangeConfig>);
impl ExchangesConfig {
pub fn hashmap(&self) -> &HashMap<String, ExchangeConfig> {
&self.0
}
pub fn get(&self, key: &str) -> Option<&ExchangeConfig> {
self.0.get(key)
}
}


#[cfg(test)]
mod test {
use crate::asset::Asset;
use crate::config::Config;

use super::ExchangeConfig;

fn get_exchange() -> &'static ExchangeConfig{
Config::global().exchanges.0.values().last().unwrap()
}

#[tokio::test]
async fn test_same_path_assets() {
let route_builder = get_exchange();

// TODO: remove this generation of data, use the test_config.yaml
// FIXME: continue from here
let input_asset = Asset::dummy_asset("0x1", "0x2");
let output_asset = Asset::dummy_asset("0x3", "0x2");

let result = route_builder.build_route_for(&input_asset, &output_asset).await;
let expected = vec!["0x1", "0x2", "0x3"];
assert_eq!(result, expected);
}

#[tokio::test]
async fn test_input_asset_is_path_asset() {
let route_builder = ...; // instantiate your struct

let input_asset = dummy_asset("0x2", "0x2"); // input_asset is its own path_asset
let output_asset = dummy_asset("0x3", "0x4");

let result = route_builder.build_route_for(&input_asset, &output_asset).await;
let expected = vec!["0x2", "0x3"];
assert_eq!(result, expected);
}

#[tokio::test]
async fn test_output_asset_is_path_asset() {
let route_builder = ...; // instantiate your struct

let input_asset = dummy_asset("0x1", "0x2");
let output_asset = dummy_asset("0x4", "0x4"); // output_asset is its own path_asset

let result = route_builder.build_route_for(&input_asset, &output_asset).await;
let expected = vec!["0x1", "0x4"];
assert_eq!(result, expected);
}

#[tokio::test]
async fn test_generic_case() {
let route_builder = ...; // instantiate your struct

let input_asset = dummy_asset("0x1", "0x2");
let output_asset = dummy_asset("0x3", "0x4");

let result = route_builder.build_route_for(&input_asset, &output_asset).await;
let expected = vec!["0x1", "0x2", "0x4", "0x3"];
assert_eq!(result, expected);
}

// ... Other test cases
}
27 changes: 25 additions & 2 deletions src/exchange/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
use crate::config::network::Network;

use self::config::ExchangeConfig;
use crate::config::Config;

pub mod config;

pub mod swap_eth_for_tokens;
pub mod swap_tokens_for_tokens;
use anyhow::Context;

use self::config::ExchangeConfig;

pub struct Exchange {
config: ExchangeConfig,
network: Network,
}

impl Exchange {
pub fn new(config: &ExchangeConfig) -> Self {
let network = config.get_network();
Self {
config: config.clone(),
network: network.clone(),
}
}
}

impl TryFrom<(&Config, &String)> for Exchange {
type Error = anyhow::Error;
fn try_from(t: (&Config, &String)) -> Result<Self, Self::Error> {
let config =
t.0.exchanges
.get(t.1)
.context(format!("exchange '{}' not found", t.1))?;
Ok(Exchange::new(config))
}
}

0 comments on commit 74546c9

Please sign in to comment.