diff --git a/dex/router/src/config.rs b/dex/router/src/config.rs index ebe45031e..105765bca 100644 --- a/dex/router/src/config.rs +++ b/dex/router/src/config.rs @@ -12,6 +12,12 @@ pub trait ConfigModule: read_pair_storage::ReadPairStorageModule { self.pair_template_address().set(&address); } + #[only_owner] + #[endpoint(setPairCreationEnabled)] + fn set_pair_creation_enabled(&self, enabled: bool) { + self.pair_creation_enabled().set(enabled); + } + fn check_is_pair_sc(&self, pair_address: &ManagedAddress) { let first_token_id = self.get_first_token_id_mapper(pair_address.clone()).get(); let second_token_id = self.get_second_token_id_mapper(pair_address.clone()).get(); diff --git a/dex/router/src/lib.rs b/dex/router/src/lib.rs index 6d3bf60c3..aeba7cc14 100644 --- a/dex/router/src/lib.rs +++ b/dex/router/src/lib.rs @@ -10,21 +10,9 @@ pub mod state; pub mod temp_owner; pub mod views; -use common_structs::Percent; -use pair::config::ProxyTrait as _; -use pair::fee::ProxyTrait as _; -use pair::{read_pair_storage, ProxyTrait as _}; -use pair_actions::create::{CreatePairArgs, PairTokens}; +use pair::read_pair_storage; use state::{ACTIVE, INACTIVE}; -const LP_TOKEN_DECIMALS: usize = 18; -const LP_TOKEN_INITIAL_SUPPLY: u64 = 1000; - -const DEFAULT_TOTAL_FEE_PERCENT: Percent = 300; -const DEFAULT_SPECIAL_FEE_PERCENT: Percent = 50; -const MAX_TOTAL_FEE_PERCENT: Percent = 100_000; -const USER_DEFINED_TOTAL_FEE_PERCENT: Percent = 1_000; - const DEFAULT_TEMPORARY_OWNER_PERIOD_BLOCKS: Blocks = 50; pub type Blocks = u64; @@ -39,6 +27,9 @@ pub trait Router: + pair_actions::multi_pair_swap::MultiPairSwap + pair_actions::create::CreateModule + pair_actions::upgrade::UpgradeModule + + pair_actions::tokens::TokensModule + + pair_actions::fees::FeesModule + + pair_actions::remove::RemoveModule + state::StateModule + temp_owner::TempOwnerModule + views::ViewsModule @@ -62,292 +53,4 @@ pub trait Router: fn upgrade(&self) { self.state().set(INACTIVE); } - - #[allow_multiple_var_args] - #[endpoint(createPair)] - fn create_pair_endpoint( - &self, - first_token_id: TokenIdentifier, - second_token_id: TokenIdentifier, - initial_liquidity_adder: ManagedAddress, - opt_fee_percents: OptionalValue>, - mut admins: MultiValueEncoded, - ) -> ManagedAddress { - self.require_active(); - - let owner = self.owner().get(); - let caller = self.blockchain().get_caller(); - - if caller != owner { - require!( - self.pair_creation_enabled().get(), - "Pair creation is disabled" - ); - } - - require!(first_token_id != second_token_id, "Identical tokens"); - require!( - first_token_id.is_valid_esdt_identifier(), - "First Token ID is not a valid esdt token ID" - ); - require!( - second_token_id.is_valid_esdt_identifier(), - "Second Token ID is not a valid esdt token ID" - ); - let pair_address = self.get_pair(first_token_id.clone(), second_token_id.clone()); - require!(pair_address.is_zero(), "Pair already exists"); - - let mut total_fee_percent_requested = DEFAULT_TOTAL_FEE_PERCENT; - let mut special_fee_percent_requested = DEFAULT_SPECIAL_FEE_PERCENT; - - if caller == owner { - if let Some(fee_percents_multi_arg) = opt_fee_percents.into_option() { - let fee_percents_tuple = fee_percents_multi_arg.into_tuple(); - total_fee_percent_requested = fee_percents_tuple.0; - special_fee_percent_requested = fee_percents_tuple.1; - - require!( - total_fee_percent_requested >= special_fee_percent_requested - && total_fee_percent_requested < MAX_TOTAL_FEE_PERCENT, - "Bad percents" - ); - } else { - sc_panic!("Bad percents length"); - } - } - - admins.push(caller.clone()); - - let address = self.create_pair(CreatePairArgs { - first_token_id: &first_token_id, - second_token_id: &second_token_id, - owner: &owner, - total_fee_percent: total_fee_percent_requested, - special_fee_percent: special_fee_percent_requested, - initial_liquidity_adder: &initial_liquidity_adder, - admins, - }); - - self.emit_create_pair_event( - caller, - first_token_id, - second_token_id, - total_fee_percent_requested, - special_fee_percent_requested, - address.clone(), - ); - - address - } - - #[only_owner] - #[endpoint(upgradePair)] - fn upgrade_pair_endpoint( - &self, - first_token_id: TokenIdentifier, - second_token_id: TokenIdentifier, - ) { - self.require_active(); - require!(first_token_id != second_token_id, "Identical tokens"); - require!( - first_token_id.is_valid_esdt_identifier(), - "First Token ID is not a valid esdt token ID" - ); - require!( - second_token_id.is_valid_esdt_identifier(), - "Second Token ID is not a valid esdt token ID" - ); - let pair_address = self.get_pair(first_token_id.clone(), second_token_id.clone()); - require!(!pair_address.is_zero(), "Pair does not exists"); - - self.upgrade_pair(pair_address); - } - - #[payable("EGLD")] - #[endpoint(issueLpToken)] - fn issue_lp_token( - &self, - pair_address: ManagedAddress, - lp_token_display_name: ManagedBuffer, - lp_token_ticker: ManagedBuffer, - ) { - self.require_active(); - - let issue_cost = self.call_value().egld_value().clone_value(); - let caller = self.blockchain().get_caller(); - if caller != self.owner().get() { - require!( - self.pair_creation_enabled().get(), - "Pair creation is disabled" - ); - } - - self.check_is_pair_sc(&pair_address); - - let result = self.get_pair_temporary_owner(&pair_address); - match result { - None => {} - Some(temporary_owner) => { - require!(caller == temporary_owner, "Temporary owner differs"); - } - }; - - let get_lp_result: TokenIdentifier = self - .pair_contract_proxy(pair_address.clone()) - .get_lp_token_identifier() - .execute_on_dest_context(); - require!( - !get_lp_result.is_valid_esdt_identifier(), - "LP Token already issued" - ); - - self.send() - .esdt_system_sc_proxy() - .issue_fungible( - issue_cost, - &lp_token_display_name, - &lp_token_ticker, - &BigUint::from(LP_TOKEN_INITIAL_SUPPLY), - FungibleTokenProperties { - num_decimals: LP_TOKEN_DECIMALS, - can_freeze: true, - can_wipe: true, - can_pause: true, - can_mint: true, - can_burn: true, - can_change_owner: true, - can_upgrade: true, - can_add_special_roles: true, - }, - ) - .with_callback( - self.callbacks() - .lp_token_issue_callback(&caller, &pair_address), - ) - .async_call_and_exit() - } - - #[endpoint(setLocalRoles)] - fn set_local_roles(&self, pair_address: ManagedAddress) { - self.require_active(); - self.check_is_pair_sc(&pair_address); - - let pair_token: TokenIdentifier = self - .pair_contract_proxy(pair_address.clone()) - .get_lp_token_identifier() - .execute_on_dest_context(); - require!(pair_token.is_valid_esdt_identifier(), "LP token not issued"); - - let roles = [EsdtLocalRole::Mint, EsdtLocalRole::Burn]; - - self.send() - .esdt_system_sc_proxy() - .set_special_roles(&pair_address, &pair_token, roles.iter().cloned()) - .async_call_and_exit() - } - - #[only_owner] - #[endpoint(removePair)] - fn remove_pair( - &self, - first_token_id: TokenIdentifier, - second_token_id: TokenIdentifier, - ) -> ManagedAddress { - self.require_active(); - require!(first_token_id != second_token_id, "Identical tokens"); - require!( - first_token_id.is_valid_esdt_identifier(), - "First Token ID is not a valid esdt token ID" - ); - require!( - second_token_id.is_valid_esdt_identifier(), - "Second Token ID is not a valid esdt token ID" - ); - let mut pair_address = self.get_pair(first_token_id.clone(), second_token_id.clone()); - require!(!pair_address.is_zero(), "Pair does not exists"); - - pair_address = self - .pair_map() - .remove(&PairTokens { - first_token_id: first_token_id.clone(), - second_token_id: second_token_id.clone(), - }) - .unwrap_or_else(ManagedAddress::zero); - - if pair_address.is_zero() { - pair_address = self - .pair_map() - .remove(&PairTokens { - first_token_id: second_token_id, - second_token_id: first_token_id, - }) - .unwrap_or_else(ManagedAddress::zero); - } - - pair_address - } - - #[only_owner] - #[endpoint(setFeeOn)] - fn set_fee_on( - &self, - pair_address: ManagedAddress, - fee_to_address: ManagedAddress, - fee_token: TokenIdentifier, - ) { - self.require_active(); - self.check_is_pair_sc(&pair_address); - - let _: IgnoreValue = self - .pair_contract_proxy(pair_address) - .set_fee_on(true, fee_to_address, fee_token) - .execute_on_dest_context(); - } - - #[only_owner] - #[endpoint(setFeeOff)] - fn set_fee_off( - &self, - pair_address: ManagedAddress, - fee_to_address: ManagedAddress, - fee_token: TokenIdentifier, - ) { - self.require_active(); - self.check_is_pair_sc(&pair_address); - - let _: IgnoreValue = self - .pair_contract_proxy(pair_address) - .set_fee_on(false, fee_to_address, fee_token) - .execute_on_dest_context(); - } - - #[callback] - fn lp_token_issue_callback( - &self, - caller: &ManagedAddress, - address: &ManagedAddress, - #[call_result] result: ManagedAsyncCallResult<()>, - ) { - let (token_id, returned_tokens) = self.call_value().egld_or_single_fungible_esdt(); - match result { - ManagedAsyncCallResult::Ok(()) => { - self.pair_temporary_owner().remove(address); - let _: IgnoreValue = self - .pair_contract_proxy(address.clone()) - .set_lp_token_identifier(token_id.unwrap_esdt()) - .execute_on_dest_context(); - } - ManagedAsyncCallResult::Err(_) => { - if token_id.is_egld() && returned_tokens > 0u64 { - self.send().direct_egld(caller, &returned_tokens); - } - } - } - } - - #[only_owner] - #[endpoint(setPairCreationEnabled)] - fn set_pair_creation_enabled(&self, enabled: bool) { - self.pair_creation_enabled().set(enabled); - } } diff --git a/dex/router/src/pair_actions/create.rs b/dex/router/src/pair_actions/create.rs index 91f80333a..61893f003 100644 --- a/dex/router/src/pair_actions/create.rs +++ b/dex/router/src/pair_actions/create.rs @@ -19,18 +19,105 @@ pub struct CreatePairArgs<'a, M: ManagedTypeApi> { pub admins: MultiValueEncoded>, } +pub const DEFAULT_TOTAL_FEE_PERCENT: Percent = 300; +pub const DEFAULT_SPECIAL_FEE_PERCENT: Percent = 50; +pub const MAX_TOTAL_FEE_PERCENT: Percent = 100_000; +pub const USER_DEFINED_TOTAL_FEE_PERCENT: Percent = 1_000; + #[multiversx_sc::module] pub trait CreateModule: crate::config::ConfigModule + pair::read_pair_storage::ReadPairStorageModule + crate::temp_owner::TempOwnerModule + + crate::events::EventsModule + + crate::state::StateModule + + crate::views::ViewsModule { + #[allow_multiple_var_args] + #[endpoint(createPair)] + fn create_pair_endpoint( + &self, + first_token_id: TokenIdentifier, + second_token_id: TokenIdentifier, + initial_liquidity_adder: ManagedAddress, + opt_fee_percents: OptionalValue>, + mut admins: MultiValueEncoded, + ) -> ManagedAddress { + self.require_active(); + + let owner = self.owner().get(); + let caller = self.blockchain().get_caller(); + if caller != owner { + require!( + self.pair_creation_enabled().get(), + "Pair creation is disabled" + ); + } + + require!(first_token_id != second_token_id, "Identical tokens"); + require!( + first_token_id.is_valid_esdt_identifier(), + "First Token ID is not a valid esdt token ID" + ); + require!( + second_token_id.is_valid_esdt_identifier(), + "Second Token ID is not a valid esdt token ID" + ); + + let pair_address = self.get_pair(first_token_id.clone(), second_token_id.clone()); + require!(pair_address.is_zero(), "Pair already exists"); + + let mut total_fee_percent_requested = DEFAULT_TOTAL_FEE_PERCENT; + let mut special_fee_percent_requested = DEFAULT_SPECIAL_FEE_PERCENT; + if caller == owner { + match opt_fee_percents { + OptionalValue::Some(fee_percents_multi_arg) => { + let fee_percents_tuple = fee_percents_multi_arg.into_tuple(); + total_fee_percent_requested = fee_percents_tuple.0; + special_fee_percent_requested = fee_percents_tuple.1; + + require!( + total_fee_percent_requested >= special_fee_percent_requested + && total_fee_percent_requested < MAX_TOTAL_FEE_PERCENT, + "Bad percents" + ); + } + OptionalValue::None => sc_panic!("Bad percents length"), + } + } + + admins.push(caller.clone()); + + let address = self.create_pair(CreatePairArgs { + first_token_id: &first_token_id, + second_token_id: &second_token_id, + owner: &owner, + total_fee_percent: total_fee_percent_requested, + special_fee_percent: special_fee_percent_requested, + initial_liquidity_adder: &initial_liquidity_adder, + admins, + }); + + self.emit_create_pair_event( + caller, + first_token_id, + second_token_id, + total_fee_percent_requested, + special_fee_percent_requested, + address.clone(), + ); + + address + } + fn create_pair(&self, args: CreatePairArgs) -> ManagedAddress { require!( !self.pair_template_address().is_empty(), "pair contract template is empty" ); + let template_addr = self.pair_template_address().get(); + let code_metadata = self.get_default_code_metadata(); let (new_address, ()) = self .pair_contract_deploy_proxy() .init( @@ -43,10 +130,7 @@ pub trait CreateModule: args.initial_liquidity_adder, args.admins, ) - .deploy_from_source( - &self.pair_template_address().get(), - CodeMetadata::UPGRADEABLE | CodeMetadata::READABLE | CodeMetadata::PAYABLE_BY_SC, - ); + .deploy_from_source(&template_addr, code_metadata); self.pair_map().insert( PairTokens { @@ -62,9 +146,14 @@ pub trait CreateModule: self.blockchain().get_block_nonce(), ), ); + new_address } + fn get_default_code_metadata(&self) -> CodeMetadata { + CodeMetadata::UPGRADEABLE | CodeMetadata::READABLE | CodeMetadata::PAYABLE_BY_SC + } + #[proxy] fn pair_contract_deploy_proxy(&self) -> pair::Proxy; } diff --git a/dex/router/src/pair_actions/enable_swap_by_user.rs b/dex/router/src/pair_actions/enable_swap_by_user.rs index 1b1704187..b9c1ed713 100644 --- a/dex/router/src/pair_actions/enable_swap_by_user.rs +++ b/dex/router/src/pair_actions/enable_swap_by_user.rs @@ -6,7 +6,7 @@ use pair::{config::ProxyTrait as _, pair_actions::views::ProxyTrait as _, read_p use pausable::{ProxyTrait as _, State}; use simple_lock::locked_token::LockedTokenAttributes; -use crate::{DEFAULT_SPECIAL_FEE_PERCENT, USER_DEFINED_TOTAL_FEE_PERCENT}; +use super::create::{DEFAULT_SPECIAL_FEE_PERCENT, USER_DEFINED_TOTAL_FEE_PERCENT}; static PAIR_LP_TOKEN_ID_STORAGE_KEY: &[u8] = b"lpTokenIdentifier"; static PAIR_INITIAL_LIQ_ADDER_STORAGE_KEY: &[u8] = b"initial_liquidity_adder"; diff --git a/dex/router/src/pair_actions/fees.rs b/dex/router/src/pair_actions/fees.rs new file mode 100644 index 000000000..d301b80c9 --- /dev/null +++ b/dex/router/src/pair_actions/fees.rs @@ -0,0 +1,48 @@ +use pair::fee::ProxyTrait as _; + +multiversx_sc::imports!(); + +#[multiversx_sc::module] +pub trait FeesModule: + crate::config::ConfigModule + + pair::read_pair_storage::ReadPairStorageModule + + crate::temp_owner::TempOwnerModule + + crate::state::StateModule +{ + #[only_owner] + #[endpoint(setFeeOn)] + fn set_fee_on( + &self, + pair_address: ManagedAddress, + fee_to_address: ManagedAddress, + fee_token: TokenIdentifier, + ) { + self.require_active(); + self.check_is_pair_sc(&pair_address); + + let _: IgnoreValue = self + .pair_contract_proxy_fees(pair_address) + .set_fee_on(true, fee_to_address, fee_token) + .execute_on_dest_context(); + } + + #[only_owner] + #[endpoint(setFeeOff)] + fn set_fee_off( + &self, + pair_address: ManagedAddress, + fee_to_address: ManagedAddress, + fee_token: TokenIdentifier, + ) { + self.require_active(); + self.check_is_pair_sc(&pair_address); + + let _: IgnoreValue = self + .pair_contract_proxy_fees(pair_address) + .set_fee_on(false, fee_to_address, fee_token) + .execute_on_dest_context(); + } + + #[proxy] + fn pair_contract_proxy_fees(&self, to: ManagedAddress) -> pair::Proxy; +} diff --git a/dex/router/src/pair_actions/mod.rs b/dex/router/src/pair_actions/mod.rs index 6d509656e..2ef1ff893 100644 --- a/dex/router/src/pair_actions/mod.rs +++ b/dex/router/src/pair_actions/mod.rs @@ -1,4 +1,7 @@ pub mod create; pub mod enable_swap_by_user; +pub mod fees; pub mod multi_pair_swap; +pub mod remove; +pub mod tokens; pub mod upgrade; diff --git a/dex/router/src/pair_actions/remove.rs b/dex/router/src/pair_actions/remove.rs new file mode 100644 index 000000000..ecd58bd76 --- /dev/null +++ b/dex/router/src/pair_actions/remove.rs @@ -0,0 +1,53 @@ +use crate::pair_actions::create::PairTokens; + +multiversx_sc::imports!(); + +#[multiversx_sc::module] +pub trait RemoveModule: + crate::config::ConfigModule + + pair::read_pair_storage::ReadPairStorageModule + + crate::temp_owner::TempOwnerModule + + crate::state::StateModule + + crate::views::ViewsModule +{ + #[only_owner] + #[endpoint(removePair)] + fn remove_pair( + &self, + first_token_id: TokenIdentifier, + second_token_id: TokenIdentifier, + ) -> ManagedAddress { + self.require_active(); + require!(first_token_id != second_token_id, "Identical tokens"); + require!( + first_token_id.is_valid_esdt_identifier(), + "First Token ID is not a valid esdt token ID" + ); + require!( + second_token_id.is_valid_esdt_identifier(), + "Second Token ID is not a valid esdt token ID" + ); + let mut pair_address = self.get_pair(first_token_id.clone(), second_token_id.clone()); + require!(!pair_address.is_zero(), "Pair does not exists"); + + pair_address = self + .pair_map() + .remove(&PairTokens { + first_token_id: first_token_id.clone(), + second_token_id: second_token_id.clone(), + }) + .unwrap_or_else(ManagedAddress::zero); + + if pair_address.is_zero() { + pair_address = self + .pair_map() + .remove(&PairTokens { + first_token_id: second_token_id, + second_token_id: first_token_id, + }) + .unwrap_or_else(ManagedAddress::zero); + } + + pair_address + } +} diff --git a/dex/router/src/pair_actions/tokens.rs b/dex/router/src/pair_actions/tokens.rs new file mode 100644 index 000000000..8e0f79c00 --- /dev/null +++ b/dex/router/src/pair_actions/tokens.rs @@ -0,0 +1,123 @@ +use pair::config::ProxyTrait as _; + +multiversx_sc::imports!(); + +pub const LP_TOKEN_DECIMALS: usize = 18; +pub const LP_TOKEN_INITIAL_SUPPLY: u64 = 1000; + +#[multiversx_sc::module] +pub trait TokensModule: + crate::config::ConfigModule + + pair::read_pair_storage::ReadPairStorageModule + + crate::temp_owner::TempOwnerModule + + crate::state::StateModule +{ + #[payable("EGLD")] + #[endpoint(issueLpToken)] + fn issue_lp_token( + &self, + pair_address: ManagedAddress, + lp_token_display_name: ManagedBuffer, + lp_token_ticker: ManagedBuffer, + ) { + self.require_active(); + + let issue_cost = self.call_value().egld_value().clone_value(); + let caller = self.blockchain().get_caller(); + if caller != self.owner().get() { + require!( + self.pair_creation_enabled().get(), + "Pair creation is disabled" + ); + } + + self.check_is_pair_sc(&pair_address); + + let result = self.get_pair_temporary_owner(&pair_address); + match result { + None => {} + Some(temporary_owner) => { + require!(caller == temporary_owner, "Temporary owner differs"); + } + }; + + let get_lp_result: TokenIdentifier = self + .pair_contract_proxy_tokens(pair_address.clone()) + .get_lp_token_identifier() + .execute_on_dest_context(); + require!( + !get_lp_result.is_valid_esdt_identifier(), + "LP Token already issued" + ); + + self.send() + .esdt_system_sc_proxy() + .issue_fungible( + issue_cost, + &lp_token_display_name, + &lp_token_ticker, + &BigUint::from(LP_TOKEN_INITIAL_SUPPLY), + FungibleTokenProperties { + num_decimals: LP_TOKEN_DECIMALS, + can_freeze: true, + can_wipe: true, + can_pause: true, + can_mint: true, + can_burn: true, + can_change_owner: true, + can_upgrade: true, + can_add_special_roles: true, + }, + ) + .with_callback( + self.callbacks() + .lp_token_issue_callback(&caller, &pair_address), + ) + .async_call_and_exit() + } + + #[endpoint(setLocalRoles)] + fn set_local_roles(&self, pair_address: ManagedAddress) { + self.require_active(); + self.check_is_pair_sc(&pair_address); + + let pair_token: TokenIdentifier = self + .pair_contract_proxy_tokens(pair_address.clone()) + .get_lp_token_identifier() + .execute_on_dest_context(); + require!(pair_token.is_valid_esdt_identifier(), "LP token not issued"); + + let roles = [EsdtLocalRole::Mint, EsdtLocalRole::Burn]; + self.send() + .esdt_system_sc_proxy() + .set_special_roles(&pair_address, &pair_token, roles.iter().cloned()) + .async_call_and_exit() + } + + #[callback] + fn lp_token_issue_callback( + &self, + caller: &ManagedAddress, + address: &ManagedAddress, + #[call_result] result: ManagedAsyncCallResult<()>, + ) { + let (token_id, returned_tokens) = self.call_value().egld_or_single_fungible_esdt(); + match result { + ManagedAsyncCallResult::Ok(()) => { + self.pair_temporary_owner().remove(address); + let _: IgnoreValue = self + .pair_contract_proxy_tokens(address.clone()) + .set_lp_token_identifier(token_id.unwrap_esdt()) + .execute_on_dest_context(); + } + ManagedAsyncCallResult::Err(_) => { + if token_id.is_egld() && returned_tokens > 0u64 { + self.send().direct_egld(caller, &returned_tokens); + } + } + } + } + + #[proxy] + fn pair_contract_proxy_tokens(&self, to: ManagedAddress) -> pair::Proxy; +} diff --git a/dex/router/src/pair_actions/upgrade.rs b/dex/router/src/pair_actions/upgrade.rs index de28f05d0..96ac67fa4 100644 --- a/dex/router/src/pair_actions/upgrade.rs +++ b/dex/router/src/pair_actions/upgrade.rs @@ -2,12 +2,40 @@ multiversx_sc::imports!(); #[multiversx_sc::module] pub trait UpgradeModule: - crate::config::ConfigModule + pair::read_pair_storage::ReadPairStorageModule + crate::config::ConfigModule + + pair::read_pair_storage::ReadPairStorageModule + + super::create::CreateModule + + crate::temp_owner::TempOwnerModule + + crate::events::EventsModule + + crate::state::StateModule + + crate::views::ViewsModule { + #[only_owner] + #[endpoint(upgradePair)] + fn upgrade_pair_endpoint( + &self, + first_token_id: TokenIdentifier, + second_token_id: TokenIdentifier, + ) { + self.require_active(); + require!(first_token_id != second_token_id, "Identical tokens"); + require!( + first_token_id.is_valid_esdt_identifier(), + "First Token ID is not a valid esdt token ID" + ); + require!( + second_token_id.is_valid_esdt_identifier(), + "Second Token ID is not a valid esdt token ID" + ); + let pair_address = self.get_pair(first_token_id.clone(), second_token_id.clone()); + require!(!pair_address.is_zero(), "Pair does not exists"); + + self.upgrade_pair(pair_address); + } + fn upgrade_pair(&self, pair_address: ManagedAddress) { let pair_template_address = self.pair_template_address().get(); - let code_metadata = - CodeMetadata::UPGRADEABLE | CodeMetadata::READABLE | CodeMetadata::PAYABLE_BY_SC; + let code_metadata = self.get_default_code_metadata(); self.tx() .to(pair_address) .raw_upgrade() diff --git a/dex/router/tests/router_test.rs b/dex/router/tests/router_test.rs index c7ec4ec14..1008b007b 100644 --- a/dex/router/tests/router_test.rs +++ b/dex/router/tests/router_test.rs @@ -17,8 +17,10 @@ use pausable::{PausableModule, State}; use router::{ config::ConfigModule, pair_actions::{ - create::PairTokens, enable_swap_by_user::EnableSwapByUserModule, + create::{CreateModule, PairTokens}, + enable_swap_by_user::EnableSwapByUserModule, multi_pair_swap::SWAP_TOKENS_FIXED_INPUT_FUNC_NAME, + upgrade::UpgradeModule, }, Router, }; diff --git a/dex/router/wasm/src/lib.rs b/dex/router/wasm/src/lib.rs index 2e0cd891b..9f5f7ed7f 100644 --- a/dex/router/wasm/src/lib.rs +++ b/dex/router/wasm/src/lib.rs @@ -20,15 +20,8 @@ multiversx_sc_wasm_adapter::endpoints! { ( init => init upgrade => upgrade - createPair => create_pair_endpoint - upgradePair => upgrade_pair_endpoint - issueLpToken => issue_lp_token - setLocalRoles => set_local_roles - removePair => remove_pair - setFeeOn => set_fee_on - setFeeOff => set_fee_off - setPairCreationEnabled => set_pair_creation_enabled setPairTemplateAddress => set_pair_template_address + setPairCreationEnabled => set_pair_creation_enabled getPairCreationEnabled => pair_creation_enabled getOwner => owner getPairTemplateAddress => pair_template_address @@ -39,6 +32,13 @@ multiversx_sc_wasm_adapter::endpoints! { setSwapEnabledByUser => set_swap_enabled_by_user getEnableSwapByUserConfig => try_get_config multiPairSwap => multi_pair_swap + createPair => create_pair_endpoint + upgradePair => upgrade_pair_endpoint + issueLpToken => issue_lp_token + setLocalRoles => set_local_roles + setFeeOn => set_fee_on + setFeeOff => set_fee_off + removePair => remove_pair pause => pause resume => resume getState => state