Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factory: enhance query_pool #128

Merged
25 changes: 7 additions & 18 deletions contracts/factory/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use soroban_sdk::{
contract, contractimpl, contractmeta, log, Address, Env, IntoVal, Symbol, Val, Vec,
};

use crate::storage::{LiquidityPoolInfo, PoolResponse};
use crate::storage::LiquidityPoolInfo;
use crate::{
error::ContractError,
storage::{get_admin, get_lp_vec, save_admin, save_lp_vec},
Expand Down Expand Up @@ -100,37 +100,26 @@ impl FactoryTrait for Factory {
env: Env,
pool_address: Address,
) -> Result<LiquidityPoolInfo, ContractError> {
let pool_response: PoolResponse = env.invoke_contract(
let pool_response: LiquidityPoolInfo = env.invoke_contract(
&pool_address,
&Symbol::new(&env, "query_pool_info"),
&Symbol::new(&env, "query_pool_info_for_factory"),
Vec::new(&env),
);
let total_fee_bps: i64 = 30; // env.invoke_contract(&pool_address, &Symbol::new(&env, "query_total_fee_bps"), Vec::new(&env));
let lp_info = LiquidityPoolInfo {
pool_response,
total_fee_bps,
};

Ok(lp_info)
Ok(pool_response)
}

fn query_all_pool_details(env: Env) -> Result<Vec<LiquidityPoolInfo>, ContractError> {
let all_lp_vec_addresses = get_lp_vec(&env)?;
let mut result = Vec::new(&env);
for address in all_lp_vec_addresses {
let pool_response: PoolResponse = env.invoke_contract(
let pool_response: LiquidityPoolInfo = env.invoke_contract(
&address,
&Symbol::new(&env, "query_pool_info"),
&Symbol::new(&env, "query_pool_info_for_factory"),
Vec::new(&env),
);
let total_fee_bps = 30; // query_pool_total_fee_bps(&env, &address);

let lp_info = LiquidityPoolInfo {
pool_response,
total_fee_bps,
};

result.push_back(lp_info);
result.push_back(pool_response);
}

Ok(result)
Expand Down
24 changes: 24 additions & 0 deletions contracts/factory/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,30 @@ impl TryFromVal<Env, DataKey> for Val {
}
}

#[contracttype]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum PairType {
Xyk = 0,
}
#[contracttype]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Config {
pub token_a: Address,
pub token_b: Address,
pub share_token: Address,
pub stake_contract: Address,
pub pair_type: PairType,
/// The total fees (in bps) charged by a pair of this type.
/// In relation to the returned amount of tokens
pub total_fee_bps: i64,
pub fee_recipient: Address,
/// The maximum amount of slippage (in bps) that is tolerated during providing liquidity
pub max_allowed_slippage_bps: i64,
/// The maximum amount of spread (in bps) that is tolerated during swap
pub max_allowed_spread_bps: i64,
}

gangov marked this conversation as resolved.
Show resolved Hide resolved
#[contracttype]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Asset {
Expand Down
105 changes: 91 additions & 14 deletions contracts/factory/src/tests/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ use super::setup::{
};
use phoenix::utils::{LiquidityPoolInitInfo, StakeInitInfo, TokenInitInfo};

use crate::storage::Config;
use soroban_sdk::arbitrary::std;
use soroban_sdk::{testutils::Address as _, Address, Env, Symbol, Vec};

#[test]
fn test_single_query() {
fn test_deploy_multiple_liquidity_pools() {
let env = Env::default();
let admin = Address::random(&env);
let user = Address::random(&env);
Expand Down Expand Up @@ -60,6 +61,18 @@ fn test_single_query() {
min_reward: 2i128,
};

let third_token_init_info = TokenInitInfo {
token_wasm_hash: install_token_wasm(&env),
token_a: token5.clone(),
token_b: token6.clone(),
};
let third_stake_init_info = StakeInitInfo {
stake_wasm_hash: install_stake_wasm(&env),
min_bond: 6i128,
max_distributions: 6u32,
min_reward: 3i128,
};

let lp_wasm_hash = install_lp_contract(&env);

let first_lp_init_info = LiquidityPoolInitInfo {
Expand All @@ -77,7 +90,7 @@ fn test_single_query() {
let second_lp_init_info = LiquidityPoolInitInfo {
admin: admin.clone(),
fee_recipient: user.clone(),
lp_wasm_hash,
lp_wasm_hash: lp_wasm_hash.clone(),
max_allowed_slippage_bps: 4_000,
max_allowed_spread_bps: 400,
share_token_decimals: 6,
Expand All @@ -86,36 +99,100 @@ fn test_single_query() {
stake_init_info: second_stake_init_info,
};

let third_lp_init_info = LiquidityPoolInitInfo {
admin: admin.clone(),
fee_recipient: user.clone(),
lp_wasm_hash,
max_allowed_slippage_bps: 4_000,
max_allowed_spread_bps: 400,
share_token_decimals: 6,
swap_fee_bps: 0,
token_init_info: third_token_init_info,
stake_init_info: third_stake_init_info,
};

factory.create_liquidity_pool(&first_lp_init_info);
factory.create_liquidity_pool(&second_lp_init_info);
factory.create_liquidity_pool(&third_lp_init_info);

let lp_contract_addr = factory.query_pools().get(0).unwrap();
let result = factory.query_pool_details(&lp_contract_addr);
let first_result = factory.query_pool_details(&lp_contract_addr);
let share_token_addr: Address = env.invoke_contract(
&lp_contract_addr,
&Symbol::new(&env, "query_share_token_address"),
Vec::new(&env),
);
let first_lp_config: Config = env.invoke_contract(
&lp_contract_addr,
&Symbol::new(&env, "query_config"),
Vec::new(&env),
);

assert_eq!(
first_lp_init_info.max_allowed_spread_bps,
first_lp_config.max_allowed_spread_bps
);

assert_eq!(token1, result.pool_response.asset_a.address);
assert_eq!(token2, result.pool_response.asset_b.address);
assert_eq!(token1, first_result.pool_response.asset_a.address);
assert_eq!(token2, first_result.pool_response.asset_b.address);
assert_eq!(
share_token_addr,
result.pool_response.asset_lp_share.address
first_result.pool_response.asset_lp_share.address
);

let lp_contract_addr = factory.query_pools().get(1).unwrap();
let result = factory.query_pool_details(&lp_contract_addr);
let share_token_addr: Address = env.invoke_contract(
&lp_contract_addr,
let second_lp_contract_addr = factory.query_pools().get(1).unwrap();
let second_result = factory.query_pool_details(&second_lp_contract_addr);
let second_share_token_addr: Address = env.invoke_contract(
&second_lp_contract_addr,
&Symbol::new(&env, "query_share_token_address"),
Vec::new(&env),
);
let second_lp_config: Config = env.invoke_contract(
&second_lp_contract_addr,
&Symbol::new(&env, "query_config"),
Vec::new(&env),
);

assert_eq!(token3, result.pool_response.asset_a.address);
assert_eq!(token4, result.pool_response.asset_b.address);
assert_eq!(
share_token_addr,
result.pool_response.asset_lp_share.address
second_lp_init_info.max_allowed_spread_bps,
second_lp_config.max_allowed_spread_bps
);

assert_eq!(token3, second_result.pool_response.asset_a.address);
assert_eq!(token4, second_result.pool_response.asset_b.address);
assert_eq!(
second_share_token_addr,
second_result.pool_response.asset_lp_share.address
);

let third_lp_contract_addr = factory.query_pools().get(2).unwrap();
let third_result = factory.query_pool_details(&third_lp_contract_addr);
let third_share_token_addr: Address = env.invoke_contract(
&third_lp_contract_addr,
&Symbol::new(&env, "query_share_token_address"),
Vec::new(&env),
);
let third_lp_config: Config = env.invoke_contract(
&third_lp_contract_addr,
&Symbol::new(&env, "query_config"),
Vec::new(&env),
);

assert_eq!(
third_lp_init_info.max_allowed_spread_bps,
third_lp_config.max_allowed_spread_bps
);

assert_eq!(token5, third_result.pool_response.asset_a.address);
assert_eq!(token6, third_result.pool_response.asset_b.address);
assert_eq!(
third_share_token_addr,
third_result.pool_response.asset_lp_share.address
);

let all_pools = factory.query_all_pool_details();
assert_eq!(all_pools.len(), 3);
all_pools.iter().for_each(|pool| {
assert!(all_pools.contains(pool));
});
}
34 changes: 27 additions & 7 deletions contracts/pair/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use soroban_sdk::{contract, contractimpl, contractmeta, log, Address, BytesN, En

use num_integer::Roots;

use crate::storage::LiquidityPoolInfo;
use crate::{
error::ContractError,
stake_contract,
Expand Down Expand Up @@ -107,6 +108,8 @@ pub trait LiquidityPoolTrait {
// Returns the total amount of LP tokens and assets in a specific pool
fn query_pool_info(env: Env) -> Result<PoolResponse, ContractError>;

fn query_pool_info_for_factory(env: Env) -> Result<LiquidityPoolInfo, ContractError>;

// Simulate swap transaction
fn simulate_swap(
env: Env,
Expand All @@ -120,8 +123,6 @@ pub trait LiquidityPoolTrait {
sell_a: bool,
ask_amount: i128,
) -> Result<SimulateReverseSwapResponse, ContractError>;

fn get_total_fee_bps(env: Env) -> Result<i64, ContractError>;
}

#[contractimpl]
Expand Down Expand Up @@ -502,6 +503,30 @@ impl LiquidityPoolTrait for LiquidityPool {
})
}

fn query_pool_info_for_factory(env: Env) -> Result<LiquidityPoolInfo, ContractError> {
let config = get_config(&env)?;
let pool_response = PoolResponse {
asset_a: Asset {
address: config.token_a,
amount: utils::get_pool_balance_a(&env)?,
},
asset_b: Asset {
address: config.token_b,
amount: utils::get_pool_balance_b(&env)?,
},
asset_lp_share: Asset {
address: config.share_token,
amount: utils::get_total_shares(&env)?,
},
};
let total_fee_bps = config.max_allowed_spread_bps;

Ok(LiquidityPoolInfo {
pool_response,
total_fee_bps,
})
gangov marked this conversation as resolved.
Show resolved Hide resolved
}

fn simulate_swap(
env: Env,
sell_a: bool,
Expand Down Expand Up @@ -562,11 +587,6 @@ impl LiquidityPoolTrait for LiquidityPool {
commission_amount,
})
}

fn get_total_fee_bps(env: Env) -> Result<i64, ContractError> {
let config = get_config(&env)?;
Ok(config.total_fee_bps)
}
}

fn do_swap(
Expand Down
7 changes: 7 additions & 0 deletions contracts/pair/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ pub struct PoolResponse {
pub asset_lp_share: Asset,
}

#[contracttype]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct LiquidityPoolInfo {
pub pool_response: PoolResponse,
pub total_fee_bps: i64,
gangov marked this conversation as resolved.
Show resolved Hide resolved
}

#[contracttype]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SimulateSwapResponse {
Expand Down
Loading