use crate::router::client::RouterClient;
use crate::router::error::RouterError;
use cosmwasm_std::Addr;
use serde::{Deserialize, Serialize};
impl RouterClient {
pub async fn market_for_base(
&self,
base_asset_symbol: &str,
) -> Result<MarketForBaseResponse, RouterError> {
let query = Query {
market_for_base: MarketForBaseRequest {
base_asset: base_asset_symbol.to_string(),
},
};
let response: MarketForBaseResponse = self
.query_contract(self.router_contract_address.to_string(), &query, None)
.await
.map_err(|err| {
if let RouterError::CosmosClientError(cosmos_err) = &err {
if cosmos_err.no_data_returned_from_contract() {
return RouterError::NoMarketFound(base_asset_symbol.to_string());
}
}
err
})?
.data;
Ok(response)
}
}
#[derive(Serialize)]
struct Query {
pub market_for_base: MarketForBaseRequest,
}
#[derive(Serialize)]
pub struct MarketForBaseRequest {
pub base_asset: String,
}
#[derive(Debug, Deserialize)]
pub struct MarketForBaseResponse {
pub market_address: Addr,
pub base_asset_symbol: String,
pub quote_assets_symbols: Vec<String>,
}
#[cfg(test)]
mod tests {
use crate::oracle::client::OracleAdminClient;
use crate::router::client::RouterAdminClient;
use crate::router::error::RouterError;
use crate::test_utils::helpers::{
TEST_ASSET_ARCH_SYMBOL, TEST_ASSET_ETH_SYMBOL, TEST_ASSET_USDT_SYMBOL,
};
use crate::test_utils::test_scenario::TestScenario;
use cosmwasm_std::{Decimal256, Uint128};
use serial_test::serial;
use std::ops::Add;
use std::str::FromStr;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
#[tokio::test]
#[serial]
async fn test_market_for_base() {
let mut test_scenario = TestScenario::new_from_config("config.json".to_string()).await;
let price_threshold_ratio = Decimal256::from_str("0.5").unwrap();
let price_expire_millis = Some(1000);
let oracle_contract_address = test_scenario
.instantiate_oracle_contract(price_threshold_ratio, price_expire_millis)
.await;
let default_protocol_fee = Decimal256::from_str("0.1").unwrap();
let default_lp_fee = Decimal256::from_str("0.1").unwrap();
let router_contract_address = test_scenario
.instantiate_router_contract(
oracle_contract_address.clone(),
oracle_contract_address.clone(),
default_protocol_fee,
default_lp_fee,
)
.await;
let oracle_client =
OracleAdminClient::from_scenario(&test_scenario, &oracle_contract_address)
.expect("Failed to create oracle admin client");
let price_expiry_time = SystemTime::now().add(Duration::from_secs(7200)); let price_expiry_timestamp = price_expiry_time
.duration_since(UNIX_EPOCH)
.expect("Converting to timestamp failed");
test_scenario.set_default_assets(&oracle_client).await;
test_scenario
.set_default_prices(&oracle_client, price_expiry_timestamp, "50000")
.await;
let router_admin_client = RouterAdminClient::from_scenario(
&test_scenario,
router_contract_address.parse().unwrap(),
)
.expect("Failed to create router admin client");
test_scenario
.create_market(
&router_admin_client,
TEST_ASSET_ARCH_SYMBOL,
&[TEST_ASSET_USDT_SYMBOL],
Uint128::new(10),
)
.await;
test_scenario
.create_market(
&router_admin_client,
TEST_ASSET_USDT_SYMBOL,
&[TEST_ASSET_ARCH_SYMBOL],
Uint128::new(10),
)
.await;
let router_client = router_admin_client.public_router_client;
let arch_market = router_client
.market_for_base(TEST_ASSET_ARCH_SYMBOL)
.await
.expect("Failed to get market for base asset");
assert_eq!(arch_market.base_asset_symbol, TEST_ASSET_ARCH_SYMBOL);
assert_eq!(arch_market.quote_assets_symbols.len(), 1);
assert_eq!(arch_market.quote_assets_symbols[0], TEST_ASSET_USDT_SYMBOL);
let usdt_market = router_client
.market_for_base(TEST_ASSET_USDT_SYMBOL)
.await
.expect("Failed to get market for base asset");
assert_eq!(usdt_market.base_asset_symbol, TEST_ASSET_USDT_SYMBOL);
assert_eq!(usdt_market.quote_assets_symbols.len(), 1);
assert_eq!(usdt_market.quote_assets_symbols[0], TEST_ASSET_ARCH_SYMBOL);
let eth_market_err = router_client
.market_for_base(TEST_ASSET_ETH_SYMBOL)
.await
.expect_err("Failed to get market for base asset");
assert!(matches!(
eth_market_err,
RouterError::NoMarketFound(ref s) if s == TEST_ASSET_ETH_SYMBOL
));
}
#[tokio::test]
#[serial]
async fn no_market_found() {
let mut test_scenario = TestScenario::new_from_config("config.json".to_string()).await;
let price_threshold_ratio = Decimal256::from_str("0.5").unwrap();
let price_expire_millis = Some(1000);
let oracle_contract_address = test_scenario
.instantiate_oracle_contract(price_threshold_ratio, price_expire_millis)
.await;
let default_protocol_fee = Decimal256::from_str("0.1").unwrap();
let default_lp_fee = Decimal256::from_str("0.1").unwrap();
let router_contract_address = test_scenario
.instantiate_router_contract(
oracle_contract_address.clone(),
oracle_contract_address.clone(),
default_protocol_fee,
default_lp_fee,
)
.await;
let oracle_client =
OracleAdminClient::from_scenario(&test_scenario, &oracle_contract_address)
.expect("Failed to create oracle admin client");
let price_expiry_time = SystemTime::now().add(Duration::from_secs(7200)); let price_expiry_timestamp = price_expiry_time
.duration_since(UNIX_EPOCH)
.expect("Converting to timestamp failed");
test_scenario.set_default_assets(&oracle_client).await;
test_scenario
.set_default_prices(&oracle_client, price_expiry_timestamp, "50000")
.await;
let router_admin_client = RouterAdminClient::from_scenario(
&test_scenario,
router_contract_address.parse().unwrap(),
)
.expect("Failed to create router admin client");
test_scenario
.create_market(
&router_admin_client,
TEST_ASSET_ARCH_SYMBOL,
&[TEST_ASSET_USDT_SYMBOL],
Uint128::new(10),
)
.await;
test_scenario
.create_market(
&router_admin_client,
TEST_ASSET_USDT_SYMBOL,
&[TEST_ASSET_ARCH_SYMBOL],
Uint128::new(10),
)
.await;
let incorrect_token = "incorrect_token";
let router_client = router_admin_client.public_router_client;
let err = router_client
.market_for_base(incorrect_token)
.await
.expect_err("should not be found");
assert!(matches!(err, RouterError::NoMarketFound(token) if token == incorrect_token));
}
}