diff --git a/contracts/factory/src/contract.rs b/contracts/factory/src/contract.rs
index 33e3ac23..394fd8f6 100644
--- a/contracts/factory/src/contract.rs
+++ b/contracts/factory/src/contract.rs
@@ -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::{
@@ -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
@@ -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
,
- lp_token_decimals: u32,
- );
-
#[allow(clippy::too_many_arguments)]
fn create_liquidity_pool(
env: Env,
@@ -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,
- 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,
@@ -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,
@@ -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 = (
stake_wasm_hash,
token_wasm_hash,
@@ -218,7 +142,21 @@ impl FactoryTrait for Factory {
init_fn_args.push_back(max_allowed_fee_bps.into_val(&env));
- env.invoke_contract::(&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);
@@ -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,
+ 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;
diff --git a/contracts/factory/src/error.rs b/contracts/factory/src/error.rs
index ced4476a..622f044b 100644
--- a/contracts/factory/src/error.rs
+++ b/contracts/factory/src/error.rs
@@ -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,
}
diff --git a/contracts/factory/src/storage.rs b/contracts/factory/src/storage.rs
index a82882a7..3d1eea69 100644
--- a/contracts/factory/src/storage.rs
+++ b/contracts/factory/src/storage.rs
@@ -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)]
@@ -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,
- );
-}
diff --git a/contracts/factory/src/tests.rs b/contracts/factory/src/tests.rs
index 48f5751a..035cf4ae 100644
--- a/contracts/factory/src/tests.rs
+++ b/contracts/factory/src/tests.rs
@@ -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;
diff --git a/contracts/factory/src/tests/config.rs b/contracts/factory/src/tests/config.rs
index 06089bf7..57326979 100644
--- a/contracts/factory/src/tests/config.rs
+++ b/contracts/factory/src/tests/config.rs
@@ -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 = 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,
+ ),
+ ),
);
}
@@ -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();
diff --git a/contracts/factory/src/tests/setup.rs b/contracts/factory/src/tests/setup.rs
index 9b8f6f9c..ba0d9641 100644
--- a/contracts/factory/src/tests/setup.rs
+++ b/contracts/factory/src/tests/setup.rs
@@ -3,7 +3,7 @@ use crate::{
token_contract,
};
use phoenix::utils::{LiquidityPoolInitInfo, StakeInitInfo, TokenInitInfo};
-use soroban_sdk::{testutils::Address as _, vec, Address, BytesN, Env, String};
+use soroban_sdk::{testutils::Address as _, vec, Address, BytesN, Env, String, Vec};
pub const ONE_DAY: u64 = 86400;
const TOKEN_WASM: &[u8] =
include_bytes!("../../../../target/wasm32-unknown-unknown/release/soroban_token_contract.wasm");
@@ -62,24 +62,29 @@ pub fn deploy_factory_contract<'a>(
admin: impl Into