Skip to content

Commit

Permalink
Merge pull request #412 from Phoenix-Protocol-Group/kalo/add-construc…
Browse files Browse the repository at this point in the history
…tors

All: add constructors
  • Loading branch information
ueco-jb authored Jan 15, 2025
2 parents 6b9c44e + 8316d92 commit d8a46ff
Show file tree
Hide file tree
Showing 46 changed files with 1,282 additions and 1,570 deletions.
144 changes: 61 additions & 83 deletions contracts/factory/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ use crate::{
error::ContractError,
stake_contract::StakedResponse,
storage::{
get_config, get_lp_vec, get_stable_wasm_hash, is_initialized, save_config, save_lp_vec,
save_lp_vec_with_tuple_as_key, save_stable_wasm_hash, set_initialized, Asset, Config,
LiquidityPoolInfo, LpPortfolio, PairTupleKey, StakePortfolio, UserPortfolio, ADMIN,
get_config, get_lp_vec, get_stable_wasm_hash, save_config, save_lp_vec,
save_lp_vec_with_tuple_as_key, save_stable_wasm_hash, Asset, Config, LiquidityPoolInfo,
LpPortfolio, PairTupleKey, StakePortfolio, UserPortfolio, ADMIN,
},
utils::{deploy_and_initialize_multihop_contract, deploy_lp_contract},
utils::deploy_and_initialize_multihop_contract,
ConvertVec,
};
use phoenix::{
Expand All @@ -18,8 +18,8 @@ use phoenix::{
utils::{LiquidityPoolInitInfo, PoolType, StakeInitInfo, TokenInitInfo},
};
use soroban_sdk::{
contract, contractimpl, contractmeta, log, panic_with_error, vec, Address, BytesN, Env,
IntoVal, String, Symbol, Val, Vec,
contract, contractimpl, contractmeta, log, panic_with_error, vec, xdr::ToXdr, Address, Bytes,
BytesN, Env, IntoVal, String, Symbol, Val, Vec,
};

// Metadata that is added on to the WASM custom section
Expand All @@ -30,19 +30,6 @@ pub struct Factory;

#[allow(dead_code)]
pub trait FactoryTrait {
#[allow(clippy::too_many_arguments)]
fn initialize(
env: Env,
admin: Address,
multihop_wasm_hash: BytesN<32>,
lp_wasm_hash: BytesN<32>,
stable_wasm_hash: BytesN<32>,
stake_wasm_hash: BytesN<32>,
token_wasm_hash: BytesN<32>,
whitelisted_accounts: Vec<Address>,
lp_token_decimals: u32,
);

#[allow(clippy::too_many_arguments)]
fn create_liquidity_pool(
env: Env,
Expand Down Expand Up @@ -89,56 +76,6 @@ pub trait FactoryTrait {

#[contractimpl]
impl FactoryTrait for Factory {
#[allow(clippy::too_many_arguments)]
fn initialize(
env: Env,
admin: Address,
multihop_wasm_hash: BytesN<32>,
lp_wasm_hash: BytesN<32>,
stable_wasm_hash: BytesN<32>,
stake_wasm_hash: BytesN<32>,
token_wasm_hash: BytesN<32>,
whitelisted_accounts: Vec<Address>,
lp_token_decimals: u32,
) {
if is_initialized(&env) {
log!(
&env,
"Factory: Initialize: initializing contract twice is not allowed"
);
panic_with_error!(&env, ContractError::AlreadyInitialized);
}

if whitelisted_accounts.is_empty() {
log!(&env, "Factory: Initialize: there must be at least one whitelisted account able to create liquidity pools.");
panic_with_error!(&env, ContractError::WhiteListeEmpty);
}

set_initialized(&env);

let multihop_address =
deploy_and_initialize_multihop_contract(env.clone(), admin.clone(), multihop_wasm_hash);

save_config(
&env,
Config {
admin: admin.clone(),
multihop_address,
lp_wasm_hash,
stake_wasm_hash,
token_wasm_hash,
whitelisted_accounts,
lp_token_decimals,
},
);
save_stable_wasm_hash(&env, stable_wasm_hash);

save_lp_vec(&env, Vec::new(&env));

env.events()
.publish(("initialize", "LP factory contract"), admin);
}

#[allow(clippy::too_many_arguments)]
fn create_liquidity_pool(
env: Env,
Expand Down Expand Up @@ -175,18 +112,6 @@ impl FactoryTrait for Factory {
let stake_wasm_hash = config.stake_wasm_hash;
let token_wasm_hash = config.token_wasm_hash;

let pool_hash = match pool_type {
PoolType::Xyk => config.lp_wasm_hash,
PoolType::Stable => get_stable_wasm_hash(&env),
};

let lp_contract_address = deploy_lp_contract(
&env,
pool_hash,
&lp_init_info.token_init_info.token_a,
&lp_init_info.token_init_info.token_b,
);

validate_bps!(
lp_init_info.swap_fee_bps,
lp_init_info.max_allowed_slippage_bps,
Expand All @@ -197,7 +122,6 @@ impl FactoryTrait for Factory {
);

let factory_addr = env.current_contract_address();
let init_fn: Symbol = Symbol::new(&env, "initialize");
let mut init_fn_args: Vec<Val> = (
stake_wasm_hash,
token_wasm_hash,
Expand All @@ -218,7 +142,21 @@ impl FactoryTrait for Factory {

init_fn_args.push_back(max_allowed_fee_bps.into_val(&env));

env.invoke_contract::<Val>(&lp_contract_address, &init_fn, init_fn_args);
let mut salt = Bytes::new(&env);
salt.append(&lp_init_info.token_init_info.token_a.clone().to_xdr(&env));
salt.append(&lp_init_info.token_init_info.token_b.clone().to_xdr(&env));
let salt = env.crypto().sha256(&salt);

let lp_contract_address = match pool_type {
PoolType::Xyk => env
.deployer()
.with_current_contract(salt)
.deploy_v2(config.lp_wasm_hash, init_fn_args.clone()),
PoolType::Stable => env
.deployer()
.with_current_contract(salt)
.deploy_v2(get_stable_wasm_hash(&env), init_fn_args),
};

let mut lp_vec = get_lp_vec(&env);

Expand Down Expand Up @@ -501,6 +439,46 @@ impl FactoryTrait for Factory {

#[contractimpl]
impl Factory {
#[allow(clippy::too_many_arguments)]
pub fn __constructor(
env: Env,
admin: Address,
multihop_wasm_hash: BytesN<32>,
lp_wasm_hash: BytesN<32>,
stable_wasm_hash: BytesN<32>,
stake_wasm_hash: BytesN<32>,
token_wasm_hash: BytesN<32>,
whitelisted_accounts: Vec<Address>,
lp_token_decimals: u32,
) {
if whitelisted_accounts.is_empty() {
log!(&env, "Factory: Initialize: there must be at least one whitelisted account able to create liquidity pools.");
panic_with_error!(&env, ContractError::WhiteListeEmpty);
}

let multihop_address =
deploy_and_initialize_multihop_contract(env.clone(), admin.clone(), multihop_wasm_hash);

save_config(
&env,
Config {
admin: admin.clone(),
multihop_address,
lp_wasm_hash,
stake_wasm_hash,
token_wasm_hash,
whitelisted_accounts,
lp_token_decimals,
},
);
save_stable_wasm_hash(&env, stable_wasm_hash);

save_lp_vec(&env, Vec::new(&env));

env.events()
.publish(("initialize", "LP factory contract"), admin);
}

#[allow(dead_code)]
pub fn update(env: Env, new_wasm_hash: BytesN<32>, new_stable_pool_hash: BytesN<32>) {
let admin = get_config(&env).admin;
Expand Down
15 changes: 7 additions & 8 deletions contracts/factory/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ use soroban_sdk::contracterror;
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[repr(u32)]
pub enum ContractError {
AlreadyInitialized = 1,
WhiteListeEmpty = 2,
NotAuthorized = 3,
LiquidityPoolNotFound = 4,
TokenABiggerThanTokenB = 5,
MinStakeInvalid = 6,
MinRewardInvalid = 7,
AdminNotSet = 8,
WhiteListeEmpty = 1,
NotAuthorized = 2,
LiquidityPoolNotFound = 3,
TokenABiggerThanTokenB = 4,
MinStakeInvalid = 5,
MinRewardInvalid = 6,
AdminNotSet = 7,
}
19 changes: 1 addition & 18 deletions contracts/factory/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub const ADMIN: Symbol = symbol_short!("ADMIN");
pub enum DataKey {
Config = 1,
LpVec = 2,
Initialized = 3,
Initialized = 3, // deprecated, do not remove for now
}

#[derive(Clone)]
Expand Down Expand Up @@ -233,20 +233,3 @@ pub fn save_lp_vec_with_tuple_as_key(
PERSISTENT_BUMP_AMOUNT,
);
}

pub fn is_initialized(e: &Env) -> bool {
e.storage()
.persistent()
.get(&DataKey::Initialized)
.unwrap_or(false)
}

pub fn set_initialized(e: &Env) {
e.storage().persistent().set(&DataKey::Initialized, &true);

e.storage().persistent().extend_ttl(
&DataKey::Initialized,
PERSISTENT_LIFETIME_THRESHOLD,
PERSISTENT_BUMP_AMOUNT,
);
}
49 changes: 1 addition & 48 deletions contracts/factory/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,50 +1,3 @@
use soroban_sdk::{testutils::Address as _, vec, Address, Env};

use self::setup::{
deploy_factory_contract, install_lp_contract, install_multihop_wasm, install_stable_lp,
install_stake_wasm, install_token_wasm,
};

mod config;
mod setup;

mod queries;
#[test]
#[should_panic(expected = "Factory: Initialize: initializing contract twice is not allowed")]
fn test_deploy_factory_twice_should_fail() {
let env = Env::default();
env.mock_all_auths();
env.cost_estimate().budget().reset_unlimited();

let admin = Address::generate(&env);

let auth_user = Address::generate(&env);
let multihop_wasm_hash = install_multihop_wasm(&env);
let lp_wasm_hash = install_lp_contract(&env);
let stable_wasm_hash = install_stable_lp(&env);
let stake_wasm_hash = install_stake_wasm(&env);
let token_wasm_hash = install_token_wasm(&env);

let factory = deploy_factory_contract(&env, admin.clone());

factory.initialize(
&admin,
&multihop_wasm_hash,
&lp_wasm_hash,
&stable_wasm_hash,
&stake_wasm_hash,
&token_wasm_hash,
&vec![&env, auth_user.clone()],
&10u32,
);
factory.initialize(
&admin,
&multihop_wasm_hash,
&lp_wasm_hash,
&stable_wasm_hash,
&stake_wasm_hash,
&token_wasm_hash,
&vec![&env, auth_user.clone()],
&10u32,
);
}
mod setup;
31 changes: 18 additions & 13 deletions contracts/factory/src/tests/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,24 +245,29 @@ fn factory_fails_to_init_lp_when_no_whitelisted_accounts() {
env.mock_all_auths();
env.cost_estimate().budget().reset_unlimited();

let factory = FactoryClient::new(&env, &env.register(Factory, ()));
let multihop_wasm_hash = install_multihop_wasm(&env);
let whitelisted_accounts = vec![&env];
let whitelisted_accounts: soroban_sdk::Vec<Address> = vec![&env];

let lp_wasm_hash = install_lp_contract(&env);
let stable_wasm_hash = install_stable_lp(&env);
let stake_wasm_hash = install_stake_wasm(&env);
let token_wasm_hash = install_token_wasm(&env);

factory.initialize(
&admin,
&multihop_wasm_hash,
&lp_wasm_hash,
&stable_wasm_hash,
&stake_wasm_hash,
&token_wasm_hash,
&whitelisted_accounts,
&10u32,
let _ = FactoryClient::new(
&env,
&env.register(
Factory,
(
&admin,
&multihop_wasm_hash,
&lp_wasm_hash,
&stable_wasm_hash,
&stake_wasm_hash,
&token_wasm_hash,
whitelisted_accounts,
&10u32,
),
),
);
}

Expand Down Expand Up @@ -478,9 +483,9 @@ fn factory_create_xyk_pool_with_amp_parameter_should_still_succeed() {
&String::from_str(&env, "Pool Stable"),
&String::from_str(&env, "EUROC/USDC"),
&PoolType::Xyk,
&Some(10),
&Some(10u64),
&100i64,
&1_000,
&1_000i64,
);

let lp_contract_addr = factory.query_pools().get(0).unwrap();
Expand Down
Loading

0 comments on commit d8a46ff

Please sign in to comment.