use crate::market::error::MarketError;
use cosmrs::Coin;
use serde::{Deserialize, Serialize};
use super::client::MarketClient;
impl MarketClient {
pub async fn quotes_for_lp(
&self,
market_address: String,
lp_address: String,
) -> Result<Vec<Coin>, MarketError> {
let query = Query {
quotes_for_lp: QuotesForLpRequest { lp_address },
};
let response: QuotesForLpResponse = self
.cosmos_client
.query_contract(market_address, &query, None)
.await?
.data;
response
.quotes
.into_iter()
.map(|coin| Coin::new(coin.amount.u128(), &coin.denom))
.collect::<Result<Vec<_>, _>>()
.map_err(MarketError::EyreError)
}
}
#[derive(Serialize)]
struct Query {
pub quotes_for_lp: QuotesForLpRequest,
}
#[derive(Serialize)]
pub struct QuotesForLpRequest {
lp_address: String,
}
#[derive(Deserialize, Debug)]
pub struct QuotesForLpResponse {
pub quotes: Vec<cosmwasm_std::Coin>,
}
#[cfg(test)]
mod tests {
use crate::market::client::{MarketAdminClient, MarketClient};
use crate::market::error::MarketError;
use crate::oracle::client::OracleAdminClient;
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 cosmrs::{AccountId, Coin};
use cosmwasm_std::{Addr, 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_quotes_for_lp() {
let mut test_scenario = TestScenario::new_from_config("config.json".to_string()).await;
let price_threshold_ratio = Decimal256::from_str("0.1").unwrap();
let price_expire_millis = Some(1000);
let oracle_contract_address = test_scenario
.instantiate_oracle_contract(price_threshold_ratio, price_expire_millis)
.await;
let client = OracleAdminClient::from_scenario(&test_scenario, &oracle_contract_address)
.expect("Failed to create oracle admin client");
test_scenario.set_default_assets(&client).await;
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_prices(&client, price_expiry_timestamp, "50000")
.await;
let new_account = test_scenario.create_new_account().await;
let protocol_fee = Decimal256::percent(10);
let lp_fee = Decimal256::percent(10);
let min_base_out = Uint128::new(10);
let market_contract_addr = test_scenario
.instantiate_settlement_contract(
oracle_contract_address.clone(),
new_account.account_id.to_string(),
protocol_fee,
lp_fee,
TEST_ASSET_ARCH_SYMBOL.to_owned(),
vec![
TEST_ASSET_USDT_SYMBOL.to_owned(),
TEST_ASSET_ETH_SYMBOL.to_owned(),
],
min_base_out,
)
.await;
let market_client = MarketAdminClient::from_scenario(&test_scenario).unwrap();
let quotes_err = market_client
.public_market_client
.quotes_for_lp(
oracle_contract_address.clone(),
new_account.account_id.to_string(),
)
.await
.expect_err("Should fail to get quotes for LP as we have given oracle address instead of market address");
assert!(matches!(quotes_err, MarketError::CosmosClientError(_)));
let quotes = market_client
.public_market_client
.quotes_for_lp(
market_contract_addr.clone(),
new_account.account_id.to_string(),
)
.await
.expect("Failed to get quotes for LP as LP hasnt deposited any assets yet");
assert_eq!(quotes.len(), 0);
test_scenario
.deposit_base(
&market_client,
AccountId::from_str(&market_contract_addr).unwrap(),
&new_account,
Coin::new(10_000_000, TEST_ASSET_ARCH_SYMBOL).unwrap(),
)
.await;
let quotes = market_client
.public_market_client
.quotes_for_lp(
market_contract_addr.clone(),
new_account.account_id.to_string(),
)
.await
.expect("Failed to get quotes for LP");
assert_eq!(quotes.len(), 0);
let transfer_amount = 5000000;
let minimum_base_out = Some(Uint128::new(10));
let receiver = Some(Addr::unchecked(new_account.account_id.clone()));
let market_contract_account_id: AccountId =
market_contract_addr.to_string().parse().unwrap();
for asset in [TEST_ASSET_USDT_SYMBOL, TEST_ASSET_ETH_SYMBOL] {
let coin = Coin::new(transfer_amount, asset).unwrap();
test_scenario
.swap(
&market_client,
market_contract_account_id.clone(),
&new_account,
coin,
minimum_base_out,
receiver.clone(),
)
.await;
}
let market_client =
MarketClient::new(test_scenario.cosmos_client).expect("Failed to create market client");
let quotes = market_client
.quotes_for_lp(
market_contract_addr.clone(),
new_account.account_id.to_string(),
)
.await
.unwrap();
let expected = vec![
Coin::new(4_500_000, TEST_ASSET_USDT_SYMBOL).unwrap(),
Coin::new(4_500_000, TEST_ASSET_ETH_SYMBOL).unwrap(),
];
assert_eq!(quotes, expected);
}
}