From d2919367360fa647c065bb7f320a3168fbe6bcfe Mon Sep 17 00:00:00 2001 From: Sorin Petreasca Date: Tue, 16 Jul 2024 23:51:54 +0300 Subject: [PATCH] Proxy dex legacy contract --- Cargo.lock | 19 + Cargo.toml | 2 + legacy-contracts/proxy-dex-legacy/.gitignore | 7 + legacy-contracts/proxy-dex-legacy/Cargo.toml | 24 ++ legacy-contracts/proxy-dex-legacy/README.md | 24 ++ .../proxy-dex-legacy/meta/Cargo.toml | 14 + .../proxy-dex-legacy/meta/src/main.rs | 3 + .../proxy-dex-legacy/multiversx.json | 4 + .../proxy-dex-legacy/src/energy.rs | 109 +++++ .../proxy-dex-legacy/src/energy_update.rs | 135 ++++++ .../proxy-dex-legacy/src/events.rs | 149 +++++++ legacy-contracts/proxy-dex-legacy/src/lib.rs | 31 ++ .../src/migration_from_v1_2.rs | 116 +++++ .../proxy-dex-legacy/src/proxy_common.rs | 129 ++++++ .../proxy-dex-legacy/src/proxy_farm.rs | 159 +++++++ .../proxy-dex-legacy/src/proxy_pair.rs | 220 ++++++++++ .../proxy-dex-legacy/src/transfer_role.rs | 90 ++++ .../proxy-dex-legacy/testnet.toml | 0 .../proxy-dex-legacy/wasm/Cargo.lock | 398 ++++++++++++++++++ .../proxy-dex-legacy/wasm/Cargo.toml | 34 ++ .../proxy-dex-legacy/wasm/src/lib.rs | 44 ++ locked-asset/factory/src/lib.rs | 2 +- 22 files changed, 1712 insertions(+), 1 deletion(-) create mode 100644 legacy-contracts/proxy-dex-legacy/.gitignore create mode 100644 legacy-contracts/proxy-dex-legacy/Cargo.toml create mode 100644 legacy-contracts/proxy-dex-legacy/README.md create mode 100644 legacy-contracts/proxy-dex-legacy/meta/Cargo.toml create mode 100644 legacy-contracts/proxy-dex-legacy/meta/src/main.rs create mode 100644 legacy-contracts/proxy-dex-legacy/multiversx.json create mode 100644 legacy-contracts/proxy-dex-legacy/src/energy.rs create mode 100644 legacy-contracts/proxy-dex-legacy/src/energy_update.rs create mode 100644 legacy-contracts/proxy-dex-legacy/src/events.rs create mode 100644 legacy-contracts/proxy-dex-legacy/src/lib.rs create mode 100644 legacy-contracts/proxy-dex-legacy/src/migration_from_v1_2.rs create mode 100644 legacy-contracts/proxy-dex-legacy/src/proxy_common.rs create mode 100644 legacy-contracts/proxy-dex-legacy/src/proxy_farm.rs create mode 100644 legacy-contracts/proxy-dex-legacy/src/proxy_pair.rs create mode 100644 legacy-contracts/proxy-dex-legacy/src/transfer_role.rs create mode 100644 legacy-contracts/proxy-dex-legacy/testnet.toml create mode 100644 legacy-contracts/proxy-dex-legacy/wasm/Cargo.lock create mode 100644 legacy-contracts/proxy-dex-legacy/wasm/Cargo.toml create mode 100644 legacy-contracts/proxy-dex-legacy/wasm/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index d7e21d7f3..97f3c2e89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2242,6 +2242,25 @@ dependencies = [ "proxy-deployer", ] +[[package]] +name = "proxy-dex-legacy" +version = "0.0.0" +dependencies = [ + "common_structs", + "factory", + "multiversx-sc", + "multiversx-sc-scenario", + "token_merge_helper", +] + +[[package]] +name = "proxy-dex-legacy-meta" +version = "0.0.0" +dependencies = [ + "multiversx-sc-meta", + "proxy-dex-legacy", +] + [[package]] name = "proxy_dex" version = "0.0.0" diff --git a/Cargo.toml b/Cargo.toml index 88a66788f..db13e51b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,8 @@ members = [ "legacy-contracts/farm-staking-proxy-v-13/meta", "legacy-contracts/farm-v-13", "legacy-contracts/farm-v-13/meta", + "legacy-contracts/proxy-dex-legacy", + "legacy-contracts/proxy-dex-legacy/meta", "locked-asset/", "locked-asset/distribution", diff --git a/legacy-contracts/proxy-dex-legacy/.gitignore b/legacy-contracts/proxy-dex-legacy/.gitignore new file mode 100644 index 000000000..eaf5915bd --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/.gitignore @@ -0,0 +1,7 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +*/target/ + +# The erdpy output +output diff --git a/legacy-contracts/proxy-dex-legacy/Cargo.toml b/legacy-contracts/proxy-dex-legacy/Cargo.toml new file mode 100644 index 000000000..cb6801e13 --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "proxy-dex-legacy" +version = "0.0.0" +edition = "2018" +publish = false + +[lib] +path = "src/lib.rs" + +[dependencies.multiversx-sc] +version = "=0.50.5" +features = ["esdt-token-payment-legacy-decode"] + +[dev-dependencies.multiversx-sc-scenario] +version = "=0.50.5" + +[dependencies.common_structs] +path = "../../common/common_structs" + +[dependencies.token_merge_helper] +path = "../../common/modules/token_merge_helper" + +[dependencies.factory] +path = "../../locked-asset/factory" diff --git a/legacy-contracts/proxy-dex-legacy/README.md b/legacy-contracts/proxy-dex-legacy/README.md new file mode 100644 index 000000000..cfa338037 --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/README.md @@ -0,0 +1,24 @@ +# DEX Proxy Smart Contract + +This document presents how one can deploy and configure a DEX Proxy Contract. +The bigger picture about what a DEX Proxy Contract can do can be found in the Repository's Root Readme. + +## Deployment + +The DEX Proxy contract can be deployed using `erdpy` and using the interraction snippets. + +The init parameters are: + +- asset_token_id. The TokenId of the asset that a locked asset represents. In case of Maiar Exchange it will be MEX. + +- locked_asset_token_id. The TokenId of the locked asset represents. In case of Maiar Exchange it will be Locked MEX. + +## Configuration workflow + +1. In order to complete the setup of the dex proxy contracts, Wrapped LP Token and Wrapped Farm token must be issued via `issueSftProxyPair` and `issueSftProxyFarm`. After this, setLocalRoles has to be called once for each of the two tokens, using for address the Proxy Address itself. + +2. In order to add a pair to intermediate, meaning a pair that is eligible to function with MEX, the admin should use `addPairToIntermediate` and `removeIntermediatedPair`. + +3. In order to add a farm to intermediate, meaning a farm that is eligible to function with MEX or with Wrapped LP Tokens, the admin should use `addFarmToIntermediate` and `removeIntermediatedFarm`. + +4. In order for the Setup to be complete, LocalMint + LocalBurn roles for MEX and NftBurn role for Locked MEX should be granted to the Proxy Contract. diff --git a/legacy-contracts/proxy-dex-legacy/meta/Cargo.toml b/legacy-contracts/proxy-dex-legacy/meta/Cargo.toml new file mode 100644 index 000000000..38efa5f0d --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/meta/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "proxy-dex-legacy-meta" + +version = "0.0.0" +authors = [ "you",] +edition = "2018" +publish = false + +[dependencies.proxy-dex-legacy] +path = ".." + +[dependencies.multiversx-sc-meta] +version = "0.50.5" +default-features = false diff --git a/legacy-contracts/proxy-dex-legacy/meta/src/main.rs b/legacy-contracts/proxy-dex-legacy/meta/src/main.rs new file mode 100644 index 000000000..c282d1ab7 --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/meta/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + multiversx_sc_meta::cli_main::(); +} \ No newline at end of file diff --git a/legacy-contracts/proxy-dex-legacy/multiversx.json b/legacy-contracts/proxy-dex-legacy/multiversx.json new file mode 100644 index 000000000..c2cab7433 --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/multiversx.json @@ -0,0 +1,4 @@ +{ + "language": "rust" +} + diff --git a/legacy-contracts/proxy-dex-legacy/src/energy.rs b/legacy-contracts/proxy-dex-legacy/src/energy.rs new file mode 100644 index 000000000..651bbf544 --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/src/energy.rs @@ -0,0 +1,109 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +use common_structs::Epoch; + +#[derive(TypeAbi, TopEncode, TopDecode, NestedEncode, NestedDecode, Clone, PartialEq, Debug)] +pub struct Energy { + amount: BigInt, + last_update_epoch: Epoch, + total_locked_tokens: BigUint, +} + +impl Default for Energy { + fn default() -> Self { + Self { + amount: BigInt::zero(), + last_update_epoch: 0, + total_locked_tokens: BigUint::zero(), + } + } +} + +impl Energy { + #[inline] + pub fn new( + amount: BigInt, + last_update_epoch: Epoch, + total_locked_tokens: BigUint, + ) -> Self { + Energy { + amount, + last_update_epoch, + total_locked_tokens, + } + } + + pub fn new_zero_energy(current_epoch: Epoch) -> Self { + Self::new(BigInt::zero(), current_epoch, BigUint::zero()) + } + + fn add(&mut self, future_epoch: Epoch, current_epoch: Epoch, amount_per_epoch: &BigUint) { + if current_epoch >= future_epoch { + return; + } + + let epochs_diff = future_epoch - current_epoch; + let energy_added = amount_per_epoch * epochs_diff; + self.amount += BigInt::from(energy_added); + } + + fn subtract(&mut self, past_epoch: Epoch, current_epoch: Epoch, amount_per_epoch: &BigUint) { + if past_epoch >= current_epoch { + return; + } + + let epoch_diff = current_epoch - past_epoch; + let energy_decrease = amount_per_epoch * epoch_diff; + self.amount -= BigInt::from(energy_decrease); + } + + pub fn deplete(&mut self, current_epoch: Epoch) { + if self.last_update_epoch == current_epoch { + return; + } + + if self.total_locked_tokens > 0 { + self.subtract( + self.last_update_epoch, + current_epoch, + &self.total_locked_tokens.clone(), + ); + } + + self.last_update_epoch = current_epoch; + } + + pub fn refund_after_token_unlock( + &mut self, + unlock_amount: &BigUint, + unlock_epoch: Epoch, + current_epoch: Epoch, + ) { + self.add(current_epoch, unlock_epoch, unlock_amount); + self.total_locked_tokens -= unlock_amount; + } + + pub fn deplete_after_early_unlock( + &mut self, + unlock_amount: &BigUint, + unlock_epoch: Epoch, + current_epoch: Epoch, + ) { + self.subtract(current_epoch, unlock_epoch, unlock_amount); + self.total_locked_tokens -= unlock_amount; + } + + pub fn update_after_unlock_any( + &mut self, + unlock_amount: &BigUint, + unlock_epoch: Epoch, + current_epoch: Epoch, + ) { + if unlock_epoch < current_epoch { + self.refund_after_token_unlock(unlock_amount, unlock_epoch, current_epoch); + } else { + self.deplete_after_early_unlock(unlock_amount, unlock_epoch, current_epoch); + } + } +} diff --git a/legacy-contracts/proxy-dex-legacy/src/energy_update.rs b/legacy-contracts/proxy-dex-legacy/src/energy_update.rs new file mode 100644 index 000000000..06921dd35 --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/src/energy_update.rs @@ -0,0 +1,135 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +use common_structs::LockedAssetTokenAttributesEx; +use factory::attr_ex_helper; + +use crate::{energy::Energy, proxy_common}; + +static LEGACY_LOCKED_TOKEN_ID_STORAGE_KEY: &[u8] = b"legacyLockedTokenId"; +static USER_ENERGY_STORAGE_KEY: &[u8] = b"userEnergy"; +static EXTENDED_ATTRIBUTES_ACTIVATION_NONCE_KEY: &[u8] = b"extended_attributes_activation_nonce"; + +mod energy_factory_proxy { + multiversx_sc::imports!(); + use crate::energy_update::Energy; + + #[multiversx_sc::proxy] + pub trait LockedTokenTransferModule { + #[endpoint(setUserEnergyAfterLockedTokenTransfer)] + fn set_user_energy_after_locked_token_transfer( + &self, + user: ManagedAddress, + energy: Energy, + ); + } +} + +#[multiversx_sc::module] +pub trait EnergyUpdateModule: + proxy_common::ProxyCommonModule + attr_ex_helper::AttrExHelper +{ + #[only_owner] + #[endpoint(setEnergyFactoryAddress)] + fn set_energy_factory_address(&self, sc_address: ManagedAddress) { + require!( + self.blockchain().is_smart_contract(&sc_address), + "Invalid address" + ); + + self.energy_factory_address().set(&sc_address); + } + + fn deduct_energy_from_user( + &self, + user: &ManagedAddress, + token_id: &TokenIdentifier, + token_nonce: u64, + token_amount: &BigUint, + ) { + let energy_factory_addr = self.energy_factory_address().get(); + let legacy_locked_token_id = self.get_legacy_locked_token_id(&energy_factory_addr); + if token_id != &legacy_locked_token_id { + return; + } + + let mut energy = self.get_energy_entry(user); + let current_epoch = self.blockchain().get_block_epoch(); + let attributes: LockedAssetTokenAttributesEx = + self.get_attributes_ex(token_id, token_nonce); + let amounts_per_epoch = attributes.get_unlock_amounts_per_epoch(token_amount); + for epoch_amount_pair in &amounts_per_epoch.pairs { + energy.update_after_unlock_any( + &epoch_amount_pair.amount, + epoch_amount_pair.epoch, + current_epoch, + ); + } + + self.set_energy_in_factory(user.clone(), energy, energy_factory_addr); + } + + fn set_energy_in_factory( + &self, + user: ManagedAddress, + energy: Energy, + energy_factory_addr: ManagedAddress, + ) { + let _: () = self + .energy_factory_proxy(energy_factory_addr) + .set_user_energy_after_locked_token_transfer(user, energy) + .execute_on_dest_context(); + } + + fn get_energy_entry(&self, user: &ManagedAddress) -> Energy { + let current_epoch = self.blockchain().get_block_epoch(); + if self.energy_factory_address().is_empty() { + return Energy::new_zero_energy(current_epoch); + } + + let energy_buffer: ManagedBuffer = self.read_storage_from_energy_factory(user); + if !energy_buffer.is_empty() { + let mut user_energy: Energy = Energy::top_decode(energy_buffer) + .unwrap_or_else(|_| sc_panic!("Failed decoding result from energy factory")); + user_energy.deplete(current_epoch); + + user_energy + } else { + Energy::new_zero_energy(current_epoch) + } + } + + fn read_storage_from_energy_factory(&self, user: &ManagedAddress) -> T { + let energy_factory_address = self.energy_factory_address().get(); + let mut key_buffer = ManagedBuffer::new_from_bytes(USER_ENERGY_STORAGE_KEY); + key_buffer.append(user.as_managed_buffer()); + + self.storage_raw() + .read_from_address(&energy_factory_address, key_buffer) + } + + fn get_legacy_locked_token_id(&self, energy_factory_addr: &ManagedAddress) -> TokenIdentifier { + self.storage_raw().read_from_address( + energy_factory_addr, + ManagedBuffer::new_from_bytes(LEGACY_LOCKED_TOKEN_ID_STORAGE_KEY), + ) + } + + fn get_extended_attributes_activation_nonce(&self) -> u64 { + let sc_address = self.locked_asset_factory_address().get(); + self.storage_raw().read_from_address( + &sc_address, + ManagedBuffer::new_from_bytes(EXTENDED_ATTRIBUTES_ACTIVATION_NONCE_KEY), + ) + } + + #[proxy] + fn energy_factory_proxy( + &self, + sc_address: ManagedAddress, + ) -> energy_factory_proxy::Proxy; + + #[view(getEnergyFactoryAddress)] + #[storage_mapper("energyFactoryAddress")] + fn energy_factory_address(&self) -> SingleValueMapper; +} diff --git a/legacy-contracts/proxy-dex-legacy/src/events.rs b/legacy-contracts/proxy-dex-legacy/src/events.rs new file mode 100644 index 000000000..3fefd8fb1 --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/src/events.rs @@ -0,0 +1,149 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +use crate::proxy_common::{WrappedFarmTokenAttributes, WrappedLpTokenAttributes}; + +#[derive(TypeAbi, TopEncode)] +pub struct RemoveLiquidityProxyEvent { + caller: ManagedAddress, + pair_address: ManagedAddress, + wrapped_lp_token_id: TokenIdentifier, + wrapped_lp_token_nonce: u64, + wrapped_lp_token_amount: BigUint, + wrapped_lp_attributes: WrappedLpTokenAttributes, + first_token_id: TokenIdentifier, + first_token_nonce: u64, + first_token_amount: BigUint, + second_token_id: TokenIdentifier, + second_token_nonce: u64, + second_token_amount: BigUint, + block: u64, + epoch: u64, + timestamp: u64, +} + +#[derive(TypeAbi, TopEncode)] +pub struct ExitFarmProxyEvent { + caller: ManagedAddress, + farm_address: ManagedAddress, + wrapped_farm_token_id: TokenIdentifier, + wrapped_farm_token_nonce: u64, + wrapped_farm_token_amount: BigUint, + wrapped_farm_attributes: WrappedFarmTokenAttributes, + farming_token_id: TokenIdentifier, + farming_token_nonce: u64, + farming_token_amount: BigUint, + reward_token_id: TokenIdentifier, + reward_token_nonce: u64, + reward_token_amount: BigUint, + block: u64, + epoch: u64, + timestamp: u64, +} + +#[multiversx_sc::module] +pub trait EventsModule { + fn emit_remove_liquidity_proxy_event( + self, + caller: &ManagedAddress, + pair_address: &ManagedAddress, + wrapped_lp_token_id: &TokenIdentifier, + wrapped_lp_token_nonce: u64, + wrapped_lp_token_amount: &BigUint, + wrapped_lp_attributes: &WrappedLpTokenAttributes, + first_token_id: &TokenIdentifier, + first_token_nonce: u64, + first_token_amount: &BigUint, + second_token_id: &TokenIdentifier, + second_token_nonce: u64, + second_token_amount: &BigUint, + ) { + let epoch = self.blockchain().get_block_epoch(); + self.remove_liquidity_proxy_event( + first_token_id, + second_token_id, + caller, + pair_address, + epoch, + &RemoveLiquidityProxyEvent { + caller: caller.clone(), + pair_address: pair_address.clone(), + first_token_id: first_token_id.clone(), + first_token_nonce, + first_token_amount: first_token_amount.clone(), + second_token_id: second_token_id.clone(), + second_token_nonce, + second_token_amount: second_token_amount.clone(), + wrapped_lp_token_id: wrapped_lp_token_id.clone(), + wrapped_lp_token_nonce, + wrapped_lp_token_amount: wrapped_lp_token_amount.clone(), + wrapped_lp_attributes: wrapped_lp_attributes.clone(), + block: self.blockchain().get_block_nonce(), + epoch, + timestamp: self.blockchain().get_block_timestamp(), + }, + ) + } + + fn emit_exit_farm_proxy_event( + self, + caller: &ManagedAddress, + farm_address: &ManagedAddress, + wrapped_farm_token_id: &TokenIdentifier, + wrapped_farm_token_nonce: u64, + wrapped_farm_token_amount: &BigUint, + wrapped_farm_attributes: &WrappedFarmTokenAttributes, + farming_token_id: &TokenIdentifier, + farming_token_nonce: u64, + farming_token_amount: &BigUint, + reward_token_id: &TokenIdentifier, + reward_token_nonce: u64, + reward_token_amount: &BigUint, + ) { + let epoch = self.blockchain().get_block_epoch(); + self.exit_farm_proxy_event( + farming_token_id, + caller, + farm_address, + epoch, + &ExitFarmProxyEvent { + caller: caller.clone(), + farm_address: farm_address.clone(), + farming_token_id: farming_token_id.clone(), + farming_token_nonce, + farming_token_amount: farming_token_amount.clone(), + wrapped_farm_token_id: wrapped_farm_token_id.clone(), + wrapped_farm_token_nonce, + wrapped_farm_token_amount: wrapped_farm_token_amount.clone(), + wrapped_farm_attributes: wrapped_farm_attributes.clone(), + reward_token_id: reward_token_id.clone(), + reward_token_nonce, + reward_token_amount: reward_token_amount.clone(), + block: self.blockchain().get_block_nonce(), + epoch, + timestamp: self.blockchain().get_block_timestamp(), + }, + ) + } + + #[event("remove_liquidity_proxy")] + fn remove_liquidity_proxy_event( + self, + #[indexed] first_token: &TokenIdentifier, + #[indexed] second_token: &TokenIdentifier, + #[indexed] caller: &ManagedAddress, + #[indexed] pair_address: &ManagedAddress, + #[indexed] epoch: u64, + remove_liquidity_proxy_event: &RemoveLiquidityProxyEvent, + ); + + #[event("exit_farm_proxy")] + fn exit_farm_proxy_event( + self, + #[indexed] farm_token: &TokenIdentifier, + #[indexed] caller: &ManagedAddress, + #[indexed] farm_address: &ManagedAddress, + #[indexed] epoch: u64, + exit_farm_proxy_event: &ExitFarmProxyEvent, + ); +} diff --git a/legacy-contracts/proxy-dex-legacy/src/lib.rs b/legacy-contracts/proxy-dex-legacy/src/lib.rs new file mode 100644 index 000000000..32305f10f --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/src/lib.rs @@ -0,0 +1,31 @@ +#![no_std] + +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +mod energy; +mod energy_update; +mod events; +pub mod migration_from_v1_2; +pub mod proxy_common; +pub mod proxy_farm; +mod proxy_pair; +pub mod transfer_role; + +use factory::attr_ex_helper; + +#[multiversx_sc::contract] +pub trait ProxyDexImpl: + proxy_common::ProxyCommonModule + + proxy_pair::ProxyPairModule + + proxy_farm::ProxyFarmModule + + token_merge_helper::TokenMergeHelperModule + + events::EventsModule + + energy_update::EnergyUpdateModule + + migration_from_v1_2::MigrationModule + + transfer_role::TransferRoleModule + + attr_ex_helper::AttrExHelper +{ + #[init] + fn init(&self) {} +} diff --git a/legacy-contracts/proxy-dex-legacy/src/migration_from_v1_2.rs b/legacy-contracts/proxy-dex-legacy/src/migration_from_v1_2.rs new file mode 100644 index 000000000..838954dd8 --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/src/migration_from_v1_2.rs @@ -0,0 +1,116 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +use common_structs::RawResultWrapper; +use common_structs::RawResultsType; +use factory::attr_ex_helper; + +use super::events; +use super::proxy_common; +use super::proxy_pair; +use crate::energy_update; +use crate::proxy_common::WrappedFarmTokenAttributes; +use crate::proxy_farm; + +mod farm_v1_2_contract_proxy { + multiversx_sc::imports!(); + + #[multiversx_sc::proxy] + pub trait Farm { + #[payable("*")] + #[endpoint(migrateToNewFarm)] + fn migrate_to_new_farm( + &self, + orig_caller: ManagedAddress, + ) -> MultiValue2, EsdtTokenPayment>; + } +} + +#[multiversx_sc::module] +pub trait MigrationModule: + proxy_farm::ProxyFarmModule + + proxy_common::ProxyCommonModule + + proxy_pair::ProxyPairModule + + token_merge_helper::TokenMergeHelperModule + + events::EventsModule + + energy_update::EnergyUpdateModule + + attr_ex_helper::AttrExHelper +{ + #[payable("*")] + #[endpoint(migrateV1_2Position)] + fn migrate_v1_2_position(&self, farm_address: ManagedAddress) { + self.require_is_intermediated_farm(&farm_address); + self.require_wrapped_farm_token_id_not_empty(); + self.require_wrapped_lp_token_id_not_empty(); + + let (payment_token_id, payment_token_nonce, payment_amount) = + self.call_value().single_esdt().into_tuple(); + let wrapped_farm_token = self.wrapped_farm_token_id().get(); + require!( + payment_token_id == wrapped_farm_token, + "Should only be used with wrapped farm tokens" + ); + require!(payment_amount != 0u64, "Payment amount cannot be zero"); + + // The actual work starts here + let wrapped_farm_token_attrs = + self.get_wrapped_farm_token_attributes(&payment_token_id, payment_token_nonce); + let farm_token_id = wrapped_farm_token_attrs.farm_token_id.clone(); + let farm_token_nonce = wrapped_farm_token_attrs.farm_token_nonce; + let farm_amount = payment_amount.clone(); + + // Get the new farm position from the new contract. + let raw_results: RawResultsType = self + .farm_v1_2_contract_proxy(farm_address) + .migrate_to_new_farm(self.blockchain().get_sc_address()) + .with_esdt_transfer((farm_token_id, farm_token_nonce, farm_amount)) + .execute_on_dest_context(); + + let mut results_wrapper = RawResultWrapper::new(raw_results); + results_wrapper.trim_results_front(2); + + let new_pos: EsdtTokenPayment = results_wrapper.decode_next_result(); + let reward: EsdtTokenPayment = results_wrapper.decode_next_result(); + + // Burn the old proxy farm position + self.send() + .esdt_local_burn(&payment_token_id, payment_token_nonce, &payment_amount); + + // Create a new proxy farm position based on the new farm position. + let new_attrs = WrappedFarmTokenAttributes { + farm_token_id: new_pos.token_identifier.clone(), + farm_token_nonce: new_pos.token_nonce, + farm_token_amount: new_pos.amount.clone(), + farming_token_id: wrapped_farm_token_attrs.farming_token_id, + farming_token_nonce: wrapped_farm_token_attrs.farming_token_nonce, + farming_token_amount: self.rule_of_three_non_zero_result( + &payment_amount, + &wrapped_farm_token_attrs.farm_token_amount, + &wrapped_farm_token_attrs.farming_token_amount, + ), + }; + let new_nonce = + self.send() + .esdt_nft_create_compact(&wrapped_farm_token, &new_pos.amount, &new_attrs); + + let mut payments = ManagedVec::new(); + payments.push(EsdtTokenPayment::new( + wrapped_farm_token, + new_nonce, + new_pos.amount, + )); + + if reward.amount != 0u64 { + payments.push(reward); + } + + let caller = self.blockchain().get_caller(); + self.send().direct_multi(&caller, &payments); + } + + #[proxy] + fn farm_v1_2_contract_proxy( + &self, + to: ManagedAddress, + ) -> farm_v1_2_contract_proxy::Proxy; +} diff --git a/legacy-contracts/proxy-dex-legacy/src/proxy_common.rs b/legacy-contracts/proxy-dex-legacy/src/proxy_common.rs new file mode 100644 index 000000000..105f3cbc1 --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/src/proxy_common.rs @@ -0,0 +1,129 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +use common_structs::Nonce; + +#[derive(ManagedVecItem, TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, Clone)] +pub struct WrappedLpTokenAttributes { + pub lp_token_id: TokenIdentifier, + pub lp_token_total_amount: BigUint, + pub locked_assets_invested: BigUint, + pub locked_assets_nonce: Nonce, +} + +#[derive(ManagedVecItem, TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, Clone)] +pub struct WrappedFarmTokenAttributes { + pub farm_token_id: TokenIdentifier, + pub farm_token_nonce: Nonce, + pub farm_token_amount: BigUint, + pub farming_token_id: TokenIdentifier, + pub farming_token_nonce: Nonce, + pub farming_token_amount: BigUint, +} + +#[multiversx_sc::module] +pub trait ProxyCommonModule { + fn get_wrapped_lp_token_attributes( + &self, + token_id: &TokenIdentifier, + token_nonce: Nonce, + ) -> WrappedLpTokenAttributes { + let token_info = self.blockchain().get_esdt_token_data( + &self.blockchain().get_sc_address(), + token_id, + token_nonce, + ); + + token_info.decode_attributes() + } + + fn get_wrapped_farm_token_attributes( + &self, + token_id: &TokenIdentifier, + token_nonce: Nonce, + ) -> WrappedFarmTokenAttributes { + let token_info = self.blockchain().get_esdt_token_data( + &self.blockchain().get_sc_address(), + token_id, + token_nonce, + ); + + token_info.decode_attributes() + } + + fn burn_payment_tokens( + &self, + payments: ManagedVecRefIterator>, + ) { + for payment in payments { + self.send().esdt_local_burn( + &payment.token_identifier, + payment.token_nonce, + &payment.amount, + ); + } + } + + fn send_multiple_tokens_if_not_zero( + &self, + destination: &ManagedAddress, + payments: &ManagedVec>, + ) { + let mut non_zero_payments = ManagedVec::new(); + for payment in payments { + if payment.amount > 0u32 { + non_zero_payments.push(payment); + } + } + + if !non_zero_payments.is_empty() { + self.send().direct_multi(destination, &non_zero_payments) + } + } + + #[storage_mapper("current_tx_accepted_funds")] + fn current_tx_accepted_funds(&self) -> MapMapper<(TokenIdentifier, Nonce), BigUint>; + + #[view(getAssetTokenId)] + #[storage_mapper("asset_token_id")] + fn asset_token_id(&self) -> SingleValueMapper; + + #[view(getLockedAssetTokenId)] + #[storage_mapper("locked_asset_token_id")] + fn locked_asset_token_id(&self) -> SingleValueMapper; + + #[view(getWrappedLpTokenId)] + #[storage_mapper("wrapped_lp_token_id")] + fn wrapped_lp_token_id(&self) -> SingleValueMapper; + + #[view(getWrappedFarmTokenId)] + #[storage_mapper("wrapped_farm_token_id")] + fn wrapped_farm_token_id(&self) -> SingleValueMapper; + + #[storage_mapper("locked_asset_factory_address")] + fn locked_asset_factory_address(&self) -> SingleValueMapper; + + #[storage_mapper("intermediated_farms")] + fn intermediated_farms(&self) -> SetMapper; + + #[view(getIntermediatedFarms)] + fn get_intermediated_farms(&self) -> MultiValueEncoded { + let mut result = MultiValueEncoded::new(); + for pair in self.intermediated_farms().iter() { + result.push(pair); + } + result + } + + #[storage_mapper("intermediated_pairs")] + fn intermediated_pairs(&self) -> SetMapper; + + #[view(getIntermediatedPairs)] + fn get_intermediated_pairs(&self) -> MultiValueEncoded { + let mut result = MultiValueEncoded::new(); + for pair in self.intermediated_pairs().iter() { + result.push(pair); + } + result + } +} diff --git a/legacy-contracts/proxy-dex-legacy/src/proxy_farm.rs b/legacy-contracts/proxy-dex-legacy/src/proxy_farm.rs new file mode 100644 index 000000000..bd39605e6 --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/src/proxy_farm.rs @@ -0,0 +1,159 @@ +#![allow(clippy::too_many_arguments)] + +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +use common_structs::Nonce; +use common_structs::{RawResultWrapper, RawResultsType}; +use factory::attr_ex_helper; + +use crate::energy_update; +use crate::proxy_common::WrappedFarmTokenAttributes; + +use super::events; +use super::proxy_common; +use super::proxy_pair; + +type ExitFarmResultType = + MultiValue2, EsdtTokenPayment>; + +mod farm_proxy { + multiversx_sc::imports!(); + + #[multiversx_sc::proxy] + pub trait FarmProxy { + #[payable("*")] + #[endpoint(exitFarm)] + fn exit_farm(&self) -> super::ExitFarmResultType; + } +} + +#[derive(ManagedVecItem, Clone)] +pub struct WrappedFarmToken { + pub token_amount: EsdtTokenPayment, + pub attributes: WrappedFarmTokenAttributes, +} + +#[multiversx_sc::module] +pub trait ProxyFarmModule: + proxy_common::ProxyCommonModule + + proxy_pair::ProxyPairModule + + token_merge_helper::TokenMergeHelperModule + + events::EventsModule + + energy_update::EnergyUpdateModule + + attr_ex_helper::AttrExHelper +{ + #[only_owner] + #[endpoint(addFarmToIntermediate)] + fn add_farm_to_intermediate(&self, farm_address: ManagedAddress) { + self.intermediated_farms().insert(farm_address); + } + + #[only_owner] + #[endpoint(removeIntermediatedFarm)] + fn remove_intermediated_farm(&self, farm_address: ManagedAddress) { + self.require_is_intermediated_farm(&farm_address); + self.intermediated_farms().remove(&farm_address); + } + + #[payable("*")] + #[endpoint(exitFarmProxy)] + fn exit_farm_proxy(&self, farm_address: &ManagedAddress) { + self.require_is_intermediated_farm(farm_address); + self.require_wrapped_farm_token_id_not_empty(); + self.require_wrapped_lp_token_id_not_empty(); + + let (token_id, token_nonce, amount) = self.call_value().single_esdt().into_tuple(); + + require!(amount != 0, "Payment amount cannot be zero"); + require!( + token_id == self.wrapped_farm_token_id().get(), + "Should only be used with wrapped farm tokens" + ); + + let wrapped_farm_token_attrs = + self.get_wrapped_farm_token_attributes(&token_id, token_nonce); + let farm_token_id = wrapped_farm_token_attrs.farm_token_id.clone(); + let farm_token_nonce = wrapped_farm_token_attrs.farm_token_nonce; + + let farm_result = self + .actual_exit_farm(farm_address, &farm_token_id, farm_token_nonce, &amount) + .into_tuple(); + let farming_token_returned = farm_result.0; + let reward_token_returned = farm_result.1; + + let caller = self.blockchain().get_caller(); + let mut payments_vec = ManagedVec::new(); + payments_vec.push(EsdtTokenPayment::new( + wrapped_farm_token_attrs.farming_token_id.clone(), + wrapped_farm_token_attrs.farming_token_nonce, + farming_token_returned.amount.clone(), + )); + payments_vec.push(EsdtTokenPayment::new( + reward_token_returned.token_identifier.clone(), + reward_token_returned.token_nonce, + reward_token_returned.amount.clone(), + )); + self.send_multiple_tokens_if_not_zero(&caller, &payments_vec); + self.send().esdt_local_burn(&token_id, token_nonce, &amount); + + if farming_token_returned.token_identifier == self.asset_token_id().get() { + self.send().esdt_local_burn( + &farming_token_returned.token_identifier, + 0, + &farming_token_returned.amount, + ); + } + + self.emit_exit_farm_proxy_event( + &caller, + farm_address, + &token_id, + token_nonce, + &amount, + &wrapped_farm_token_attrs, + &wrapped_farm_token_attrs.farming_token_id, + wrapped_farm_token_attrs.farming_token_nonce, + &farming_token_returned.amount, + &reward_token_returned.token_identifier, + reward_token_returned.token_nonce, + &reward_token_returned.amount, + ); + } + + fn actual_exit_farm( + &self, + farm_address: &ManagedAddress, + farm_token_id: &TokenIdentifier, + farm_token_nonce: Nonce, + amount: &BigUint, + ) -> ExitFarmResultType { + let raw_results: RawResultsType = self + .farm_contract_proxy(farm_address.clone()) + .exit_farm() + .with_esdt_transfer((farm_token_id.clone(), farm_token_nonce, amount.clone())) + .execute_on_dest_context(); + + let mut results_wrapper = RawResultWrapper::new(raw_results); + results_wrapper.trim_results_front(2); + + let farming_tokens = results_wrapper.decode_next_result(); + let reward_tokens = results_wrapper.decode_next_result(); + + (farming_tokens, reward_tokens).into() + } + + fn require_is_intermediated_farm(&self, address: &ManagedAddress) { + require!( + self.intermediated_farms().contains(address), + "Not an intermediated farm" + ); + } + + fn require_wrapped_farm_token_id_not_empty(&self) { + require!(!self.wrapped_farm_token_id().is_empty(), "Empty token id"); + } + + #[proxy] + fn farm_contract_proxy(&self, to: ManagedAddress) -> farm_proxy::Proxy; +} diff --git a/legacy-contracts/proxy-dex-legacy/src/proxy_pair.rs b/legacy-contracts/proxy-dex-legacy/src/proxy_pair.rs new file mode 100644 index 000000000..d0bc68b4a --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/src/proxy_pair.rs @@ -0,0 +1,220 @@ +#![allow(clippy::too_many_arguments)] +#![allow(clippy::comparison_chain)] +#![allow(clippy::vec_init_then_push)] + +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +use common_structs::{RawResultWrapper, RawResultsType}; +use factory::attr_ex_helper; + +use crate::energy_update; +use crate::proxy_common::WrappedLpTokenAttributes; + +use super::events; +use super::proxy_common; + +type RemoveLiquidityResultType = + MultiValue2, EsdtTokenPayment>; + +mod pair_proxy { + multiversx_sc::imports!(); + + #[multiversx_sc::proxy] + pub trait PairProxy { + #[payable("*")] + #[endpoint(removeLiquidity)] + fn remove_liquidity( + &self, + first_token_amount_min: BigUint, + second_token_amount_min: BigUint, + ) -> super::RemoveLiquidityResultType; + + #[view(getLpTokenIdentifier)] + fn get_lp_token_identifier(&self) -> TokenIdentifier; + } +} + +#[derive(ManagedVecItem, Clone)] +pub struct WrappedLpToken { + pub token_amount: EsdtTokenPayment, + pub attributes: WrappedLpTokenAttributes, +} + +#[multiversx_sc::module] +pub trait ProxyPairModule: + proxy_common::ProxyCommonModule + + token_merge_helper::TokenMergeHelperModule + + events::EventsModule + + energy_update::EnergyUpdateModule + + attr_ex_helper::AttrExHelper +{ + #[only_owner] + #[endpoint(addPairToIntermediate)] + fn add_pair_to_intermediate(&self, pair_address: ManagedAddress) { + self.intermediated_pairs().insert(pair_address); + } + + #[only_owner] + #[endpoint(removeIntermediatedPair)] + fn remove_intermediated_pair(&self, pair_address: ManagedAddress) { + self.require_is_intermediated_pair(&pair_address); + self.intermediated_pairs().remove(&pair_address); + } + + #[payable("*")] + #[endpoint(removeLiquidityProxy)] + fn remove_liquidity_proxy( + &self, + pair_address: ManagedAddress, + first_token_amount_min: BigUint, + second_token_amount_min: BigUint, + ) { + self.require_is_intermediated_pair(&pair_address); + self.require_wrapped_lp_token_id_not_empty(); + + let (token_id, token_nonce, amount) = self.call_value().single_esdt().into_tuple(); + require!(token_nonce != 0, "Can only be called with an SFT"); + require!(amount != 0, "Payment amount cannot be zero"); + + let wrapped_lp_token_id = self.wrapped_lp_token_id().get(); + require!(token_id == wrapped_lp_token_id, "Wrong input token"); + + let caller = self.blockchain().get_caller(); + let lp_token_id = self.ask_for_lp_token_id(&pair_address); + let attributes = self.get_wrapped_lp_token_attributes(&token_id, token_nonce); + require!(lp_token_id == attributes.lp_token_id, "Bad input address"); + + let locked_asset_token_id = self.locked_asset_token_id().get(); + let asset_token_id = self.asset_token_id().get(); + + let tokens_for_position = self + .actual_remove_liquidity( + &pair_address, + &lp_token_id, + &amount, + &first_token_amount_min, + &second_token_amount_min, + ) + .into_tuple(); + + let fungible_token_id: TokenIdentifier; + let fungible_token_amount: BigUint; + let assets_received: BigUint; + let locked_assets_invested = self.rule_of_three_non_zero_result( + &amount, + &attributes.lp_token_total_amount, + &attributes.locked_assets_invested, + ); + + if tokens_for_position.1.token_identifier == asset_token_id { + assets_received = tokens_for_position.1.amount.clone(); + fungible_token_id = tokens_for_position.0.token_identifier.clone(); + fungible_token_amount = tokens_for_position.0.amount.clone(); + } else { + sc_panic!("Bad tokens received from pair SC"); + } + + // Send back the tokens removed from pair sc. + let locked_assets_to_send = + core::cmp::min(assets_received.clone(), locked_assets_invested.clone()); + let mut payments_vec = ManagedVec::new(); + payments_vec.push(EsdtTokenPayment::new( + fungible_token_id.clone(), + 0, + fungible_token_amount.clone(), + )); + payments_vec.push(EsdtTokenPayment::new( + locked_asset_token_id.clone(), + attributes.locked_assets_nonce, + locked_assets_to_send.clone(), + )); + self.send_multiple_tokens_if_not_zero(&caller, &payments_vec); + + // Do cleanup + if assets_received > locked_assets_invested { + let difference = assets_received - locked_assets_invested; + self.send() + .direct_esdt(&caller, &asset_token_id, 0, &difference); + } else if assets_received < locked_assets_invested { + let difference = locked_assets_invested - assets_received; + self.deduct_energy_from_user( + &caller, + &locked_asset_token_id, + attributes.locked_assets_nonce, + &difference, + ); + self.send().esdt_local_burn( + &locked_asset_token_id, + attributes.locked_assets_nonce, + &difference, + ); + } + + self.send() + .esdt_local_burn(&asset_token_id, 0, &locked_assets_to_send); + self.send() + .esdt_local_burn(&wrapped_lp_token_id, token_nonce, &amount); + + self.emit_remove_liquidity_proxy_event( + &caller, + &pair_address, + &token_id, + token_nonce, + &amount, + &attributes, + &tokens_for_position.0.token_identifier, + 0, + &tokens_for_position.0.amount, + &tokens_for_position.1.token_identifier, + 0, + &tokens_for_position.1.amount, + ); + } + + fn actual_remove_liquidity( + &self, + pair_address: &ManagedAddress, + lp_token_id: &TokenIdentifier, + liquidity: &BigUint, + first_token_amount_min: &BigUint, + second_token_amount_min: &BigUint, + ) -> RemoveLiquidityResultType { + let raw_results: RawResultsType = self + .pair_contract_proxy(pair_address.clone()) + .remove_liquidity( + first_token_amount_min.clone(), + second_token_amount_min.clone(), + ) + .with_esdt_transfer((lp_token_id.clone(), 0, liquidity.clone())) + .execute_on_dest_context(); + + let mut results_wrapper = RawResultWrapper::new(raw_results); + results_wrapper.trim_results_front(2); + + let first_token = results_wrapper.decode_next_result(); + let second_token = results_wrapper.decode_next_result(); + + (first_token, second_token).into() + } + + fn ask_for_lp_token_id(&self, pair_address: &ManagedAddress) -> TokenIdentifier { + self.pair_contract_proxy(pair_address.clone()) + .get_lp_token_identifier() + .execute_on_dest_context() + } + + fn require_is_intermediated_pair(&self, address: &ManagedAddress) { + require!( + self.intermediated_pairs().contains(address), + "Not an intermediated pair" + ); + } + + fn require_wrapped_lp_token_id_not_empty(&self) { + require!(!self.wrapped_lp_token_id().is_empty(), "Empty token id"); + } + + #[proxy] + fn pair_contract_proxy(&self, to: ManagedAddress) -> pair_proxy::Proxy; +} diff --git a/legacy-contracts/proxy-dex-legacy/src/transfer_role.rs b/legacy-contracts/proxy-dex-legacy/src/transfer_role.rs new file mode 100644 index 000000000..ad0787e4e --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/src/transfer_role.rs @@ -0,0 +1,90 @@ +multiversx_sc::imports!(); + +use super::proxy_common; + +#[multiversx_sc::module] +pub trait TransferRoleModule: proxy_common::ProxyCommonModule { + /// Sets the transfer role for the given address. Defaults to own SC address. + #[only_owner] + #[endpoint(setTransferRoleLockedLpToken)] + fn set_transfer_role_locked_lp_token(&self, opt_address: OptionalValue) { + let locked_lp_token_id = self.wrapped_lp_token_id().get(); + let role_dest_address = match opt_address { + OptionalValue::Some(addr) => addr, + OptionalValue::None => self.blockchain().get_sc_address(), + }; + let roles = [EsdtLocalRole::Transfer]; + + self.send() + .esdt_system_sc_proxy() + .set_special_roles( + &role_dest_address, + &locked_lp_token_id, + roles.iter().cloned(), + ) + .async_call_and_exit() + } + + /// Removes the transfer role for the given address. Defaults to own SC address. + #[only_owner] + #[endpoint(unsetTransferRoleLockedLpToken)] + fn unset_transfer_role_locked_lp_token(&self, opt_address: OptionalValue) { + let locked_lp_token_id = self.wrapped_lp_token_id().get(); + let role_dest_address = match opt_address { + OptionalValue::Some(addr) => addr, + OptionalValue::None => self.blockchain().get_sc_address(), + }; + let roles = [EsdtLocalRole::Transfer]; + + self.send() + .esdt_system_sc_proxy() + .unset_special_roles( + &role_dest_address, + &locked_lp_token_id, + roles.iter().cloned(), + ) + .async_call_and_exit() + } + + /// Sets the transfer role for the given address. Defaults to own SC address. + #[only_owner] + #[endpoint(setTransferRoleLockedFarmToken)] + fn set_transfer_role_locked_farm_token(&self, opt_address: OptionalValue) { + let locked_farm_token_id = self.wrapped_farm_token_id().get(); + let role_dest_address = match opt_address { + OptionalValue::Some(addr) => addr, + OptionalValue::None => self.blockchain().get_sc_address(), + }; + let roles = [EsdtLocalRole::Transfer]; + + self.send() + .esdt_system_sc_proxy() + .set_special_roles( + &role_dest_address, + &locked_farm_token_id, + roles.iter().cloned(), + ) + .async_call_and_exit() + } + + /// Removes the transfer role for the given address. Defaults to own SC address. + #[only_owner] + #[endpoint(unsetTransferRoleLockedFarmToken)] + fn unset_transfer_role_locked_farm_token(&self, opt_address: OptionalValue) { + let locked_farm_token_id = self.wrapped_farm_token_id().get(); + let role_dest_address = match opt_address { + OptionalValue::Some(addr) => addr, + OptionalValue::None => self.blockchain().get_sc_address(), + }; + let roles = [EsdtLocalRole::Transfer]; + + self.send() + .esdt_system_sc_proxy() + .unset_special_roles( + &role_dest_address, + &locked_farm_token_id, + roles.iter().cloned(), + ) + .async_call_and_exit() + } +} diff --git a/legacy-contracts/proxy-dex-legacy/testnet.toml b/legacy-contracts/proxy-dex-legacy/testnet.toml new file mode 100644 index 000000000..e69de29bb diff --git a/legacy-contracts/proxy-dex-legacy/wasm/Cargo.lock b/legacy-contracts/proxy-dex-legacy/wasm/Cargo.lock new file mode 100644 index 000000000..a3143553e --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/wasm/Cargo.lock @@ -0,0 +1,398 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "common_errors" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "common_structs" +version = "0.0.0" +dependencies = [ + "fixed-supply-token", + "math", + "mergeable", + "multiversx-sc", + "unwrappable", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "energy-factory" +version = "0.0.0" +dependencies = [ + "common_structs", + "legacy_token_decode_module", + "math", + "mergeable", + "multiversx-sc", + "multiversx-sc-modules", + "sc_whitelist_module", + "simple-lock", + "unwrappable", + "utils", +] + +[[package]] +name = "factory" +version = "0.0.0" +dependencies = [ + "arrayvec", + "common_errors", + "common_structs", + "energy-factory", + "itertools", + "multiversx-sc", + "multiversx-sc-modules", + "token_merge_helper", + "token_send", + "wee_alloc", +] + +[[package]] +name = "fixed-supply-token" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "legacy_token_decode_module" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", + "utils", +] + +[[package]] +name = "libc" +version = "0.2.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e509672465a0504304aa87f9f176f2b2b716ed8fb105ebe5c02dc6dce96a94" + +[[package]] +name = "math" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "memory_units" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" + +[[package]] +name = "mergeable" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "multiversx-sc" +version = "0.50.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a38a802d6cfa67748145a9e729336f4e6390eba702b5f14360ed01fcff14faa4" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c94397b2fba14e40edfa55905b3f453ed57aa06c9b1960ad6a0ca6bfb7a236" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf72a8042da0bc19da0b8f0d4f61b4c66ae853560fefc69cd8fea87bf1aa8c14" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.50.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dc53ddcbd71948d2e8d3d6b814da866e2920b24e6c0cbfa643922f781897476" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-modules" +version = "0.50.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea1ae09db9cac18669b85d50932410df6082e1a575975ba5224e3b7ae33cbe7d" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.50.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99a090365b4483b4ea955ba1322f986f6821be88144291f0013c03f59b4de753" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proxy-dex-legacy" +version = "0.0.0" +dependencies = [ + "common_structs", + "factory", + "multiversx-sc", + "token_merge_helper", +] + +[[package]] +name = "proxy-dex-legacy-wasm" +version = "0.0.0" +dependencies = [ + "multiversx-sc-wasm-adapter", + "proxy-dex-legacy", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "sc_whitelist_module" +version = "0.0.0" +dependencies = [ + "common_errors", + "multiversx-sc", +] + +[[package]] +name = "simple-lock" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", + "multiversx-sc-modules", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "syn" +version = "2.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "token_merge_helper" +version = "0.0.0" +dependencies = [ + "common_errors", + "multiversx-sc", +] + +[[package]] +name = "token_send" +version = "0.0.0" +dependencies = [ + "common_errors", + "common_structs", + "multiversx-sc", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + +[[package]] +name = "unwrappable" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "utils" +version = "0.0.0" +dependencies = [ + "common_structs", + "fixed-supply-token", + "mergeable", + "multiversx-sc", +] + +[[package]] +name = "wee_alloc" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" +dependencies = [ + "cfg-if", + "libc", + "memory_units", + "winapi", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/legacy-contracts/proxy-dex-legacy/wasm/Cargo.toml b/legacy-contracts/proxy-dex-legacy/wasm/Cargo.toml new file mode 100644 index 000000000..fa6f756fe --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/wasm/Cargo.toml @@ -0,0 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "proxy-dex-legacy-wasm" +version = "0.0.0" +edition = "2018" +publish = false + +[lib] +crate-type = ["cdylib"] + +[profile.release] +codegen-units = 1 +opt-level = "z" +lto = true +debug = false +panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" + +[dependencies.proxy-dex-legacy] +path = ".." + +[dependencies.multiversx-sc-wasm-adapter] +version = "=0.50.5" + +[workspace] +members = ["."] diff --git a/legacy-contracts/proxy-dex-legacy/wasm/src/lib.rs b/legacy-contracts/proxy-dex-legacy/wasm/src/lib.rs new file mode 100644 index 000000000..5d418f971 --- /dev/null +++ b/legacy-contracts/proxy-dex-legacy/wasm/src/lib.rs @@ -0,0 +1,44 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Endpoints: 20 +// Async Callback (empty): 1 +// Total number of exported functions: 22 + +#![no_std] + +multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + proxy_dex_legacy + ( + init => init + getAssetTokenId => asset_token_id + getLockedAssetTokenId => locked_asset_token_id + getWrappedLpTokenId => wrapped_lp_token_id + getWrappedFarmTokenId => wrapped_farm_token_id + getIntermediatedFarms => get_intermediated_farms + getIntermediatedPairs => get_intermediated_pairs + addPairToIntermediate => add_pair_to_intermediate + removeIntermediatedPair => remove_intermediated_pair + removeLiquidityProxy => remove_liquidity_proxy + addFarmToIntermediate => add_farm_to_intermediate + removeIntermediatedFarm => remove_intermediated_farm + exitFarmProxy => exit_farm_proxy + setEnergyFactoryAddress => set_energy_factory_address + getEnergyFactoryAddress => energy_factory_address + migrateV1_2Position => migrate_v1_2_position + setTransferRoleLockedLpToken => set_transfer_role_locked_lp_token + unsetTransferRoleLockedLpToken => unset_transfer_role_locked_lp_token + setTransferRoleLockedFarmToken => set_transfer_role_locked_farm_token + unsetTransferRoleLockedFarmToken => unset_transfer_role_locked_farm_token + getExtendedAttributesActivationNonce => extended_attributes_activation_nonce + ) +} + +multiversx_sc_wasm_adapter::async_callback_empty! {} diff --git a/locked-asset/factory/src/lib.rs b/locked-asset/factory/src/lib.rs index bd27c4752..268ff0c05 100644 --- a/locked-asset/factory/src/lib.rs +++ b/locked-asset/factory/src/lib.rs @@ -1,6 +1,6 @@ #![no_std] -mod attr_ex_helper; +pub mod attr_ex_helper; mod cache; mod events; pub mod locked_asset;