From 541392dcc4f8e66f697f685bb1b2201e2587643a Mon Sep 17 00:00:00 2001 From: Sorin Petreasca Date: Wed, 20 Nov 2024 02:37:21 +0000 Subject: [PATCH 01/23] farm and farm staking refactor --- common/common_structs/src/farm_types.rs | 7 ++ common/modules/utils/src/lib.rs | 56 +++++++++++++++- .../src/external_interaction.rs | 64 ++++-------------- .../farm_with_locked_rewards_setup/mod.rs | 4 +- dex/farm/src/external_interaction.rs | 65 ++++--------------- .../tests/farm_setup/multi_user_farm_setup.rs | 10 ++- dex/permissions-hub/src/lib.rs | 24 +++++-- dex/permissions-hub/wasm/src/lib.rs | 10 ++- .../src/proxy_actions/claim.rs | 10 ++- .../farm-staking/src/external_interaction.rs | 56 ++++------------ .../farm-staking/src/token_attributes.rs | 4 ++ .../tests/farm_staking_setup/mod.rs | 4 +- 12 files changed, 148 insertions(+), 166 deletions(-) diff --git a/common/common_structs/src/farm_types.rs b/common/common_structs/src/farm_types.rs index d7d85e20b..676b26e36 100644 --- a/common/common_structs/src/farm_types.rs +++ b/common/common_structs/src/farm_types.rs @@ -80,6 +80,8 @@ pub trait FarmToken { fn get_compounded_rewards(&self) -> BigUint; fn get_initial_farming_tokens(&self) -> BigUint; + + fn get_original_owner(&self) -> ManagedAddress; } impl FarmToken for FarmTokenAttributes { @@ -97,4 +99,9 @@ impl FarmToken for FarmTokenAttributes { fn get_initial_farming_tokens(&self) -> BigUint { &self.current_farm_amount - &self.compounded_reward } + + #[inline] + fn get_original_owner(&self) -> ManagedAddress { + self.original_owner.clone() + } } diff --git a/common/modules/utils/src/lib.rs b/common/modules/utils/src/lib.rs index 990b88329..861061b28 100644 --- a/common/modules/utils/src/lib.rs +++ b/common/modules/utils/src/lib.rs @@ -2,7 +2,7 @@ multiversx_sc::imports!(); -use common_structs::{PaymentAttributesPair, PaymentsVec}; +use common_structs::{FarmToken, PaymentAttributesPair, PaymentsVec}; use fixed_supply_token::FixedSupplyToken; use mergeable::Mergeable; @@ -116,6 +116,60 @@ pub trait UtilsModule { } } + fn check_and_return_original_owner + TopDecode>( + &self, + payments: &PaymentsVec, + farm_token_mapper: &NonFungibleTokenMapper, + ) -> ManagedAddress { + let mut original_owner = ManagedAddress::zero(); + for payment in payments.iter() { + let attributes: T = farm_token_mapper.get_token_attributes(payment.token_nonce); + let payment_original_owner = attributes.get_original_owner(); + + if original_owner.is_zero() { + original_owner = payment_original_owner; + } else { + require!( + original_owner == payment_original_owner, + "All position must have the same original owner" + ); + } + } + + require!( + !original_owner.is_zero(), + "Original owner could not be identified" + ); + + original_owner + } + + fn check_additional_payments_original_owner + TopDecode>( + &self, + user: &ManagedAddress, + payments: &PaymentsVec, + farm_token_mapper: &NonFungibleTokenMapper, + ) { + if payments.len() == 1 { + return; + } + + let farm_token_id = farm_token_mapper.get_token_id(); + for payment in payments.into_iter() { + if payment.token_identifier != farm_token_id { + continue; + } + + let attributes: T = farm_token_mapper.get_token_attributes(payment.token_nonce); + let payment_original_owner = attributes.get_original_owner(); + + require!( + user == &payment_original_owner, + "Provided address is not the same as the original owner" + ); + } + } + fn require_valid_token_id(&self, token_id: &TokenIdentifier) { require!(token_id.is_valid_esdt_identifier(), "Invalid token ID"); } diff --git a/dex/farm-with-locked-rewards/src/external_interaction.rs b/dex/farm-with-locked-rewards/src/external_interaction.rs index 54ecf7510..3fd724465 100644 --- a/dex/farm-with-locked-rewards/src/external_interaction.rs +++ b/dex/farm-with-locked-rewards/src/external_interaction.rs @@ -45,7 +45,13 @@ pub trait ExternalInteractionsModule: let caller = self.blockchain().get_caller(); self.require_user_whitelisted(&user, &caller); - self.check_additional_payments_original_owner(&user); + let payments = self.get_non_empty_payments(); + let farm_token_mapper = self.farm_token(); + self.check_additional_payments_original_owner::>( + &user, + &payments, + &farm_token_mapper, + ); let boosted_rewards = self.claim_only_boosted_payment(&user); let new_farm_token = self.enter_farm::>(user.clone()); @@ -71,8 +77,13 @@ pub trait ExternalInteractionsModule: #[payable("*")] #[endpoint(claimRewardsOnBehalf)] fn claim_rewards_on_behalf(&self) -> ClaimRewardsResultType { - let user = self.check_and_return_original_owner(); + let payments = self.get_non_empty_payments(); + let farm_token_mapper = self.farm_token(); let caller = self.blockchain().get_caller(); + let user = self.check_and_return_original_owner::>( + &payments, + &farm_token_mapper, + ); self.require_user_whitelisted(&user, &caller); let claim_rewards_result = self.claim_rewards::>(user.clone()); @@ -95,55 +106,6 @@ pub trait ExternalInteractionsModule: (claim_rewards_result.new_farm_token, locked_rewards_payment).into() } - fn check_and_return_original_owner(&self) -> ManagedAddress { - let payments = self.call_value().all_esdt_transfers().clone_value(); - let farm_token_mapper = self.farm_token(); - let mut original_owner = ManagedAddress::zero(); - for payment in payments.into_iter() { - let attributes: FarmTokenAttributes = - farm_token_mapper.get_token_attributes(payment.token_nonce); - - if original_owner.is_zero() { - original_owner = attributes.original_owner; - } else { - require!( - original_owner == attributes.original_owner, - "All position must have the same original owner" - ); - } - } - - require!( - !original_owner.is_zero(), - "Original owner could not be identified" - ); - - original_owner - } - - fn check_additional_payments_original_owner(&self, user: &ManagedAddress) { - let payments = self.call_value().all_esdt_transfers().clone_value(); - if payments.len() == 1 { - return; - } - - let farm_token_mapper = self.farm_token(); - let farm_token_id = farm_token_mapper.get_token_id(); - for payment in payments.into_iter() { - if payment.token_identifier != farm_token_id { - continue; - } - - let attributes: FarmTokenAttributes = - farm_token_mapper.get_token_attributes(payment.token_nonce); - - require!( - user == &attributes.original_owner, - "Provided address is not the same as the original owner" - ); - } - } - fn require_user_whitelisted(&self, user: &ManagedAddress, authorized_address: &ManagedAddress) { let permissions_hub_address = self.permissions_hub_address().get(); let is_whitelisted: bool = self diff --git a/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs b/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs index a84387950..6be3e313d 100644 --- a/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs +++ b/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs @@ -564,7 +564,9 @@ where &self.permissions_hub_wrapper, &rust_biguint!(0), |sc| { - sc.whitelist(managed_address!(address_to_whitelist)); + let mut addresses = MultiValueEncoded::new(); + addresses.push(managed_address!(address_to_whitelist)); + sc.whitelist(addresses); }, ) .assert_ok(); diff --git a/dex/farm/src/external_interaction.rs b/dex/farm/src/external_interaction.rs index 12a0b8366..66b594ed6 100644 --- a/dex/farm/src/external_interaction.rs +++ b/dex/farm/src/external_interaction.rs @@ -43,7 +43,13 @@ pub trait ExternalInteractionsModule: let caller = self.blockchain().get_caller(); self.require_user_whitelisted(&user, &caller); - self.check_additional_payments_original_owner(&user); + let payments = self.get_non_empty_payments(); + let farm_token_mapper = self.farm_token(); + self.check_additional_payments_original_owner::>( + &user, + &payments, + &farm_token_mapper, + ); let boosted_rewards = self.claim_only_boosted_payment(&user); @@ -62,8 +68,14 @@ pub trait ExternalInteractionsModule: #[payable("*")] #[endpoint(claimRewardsOnBehalf)] fn claim_rewards_on_behalf(&self) -> ClaimRewardsResultType { - let user = self.check_and_return_original_owner(); + let payments = self.get_non_empty_payments(); + let farm_token_mapper = self.farm_token(); + let caller = self.blockchain().get_caller(); + let user = self.check_and_return_original_owner::>( + &payments, + &farm_token_mapper, + ); self.require_user_whitelisted(&user, &caller); let claim_rewards_result = self.claim_rewards::>(user.clone()); @@ -74,55 +86,6 @@ pub trait ExternalInteractionsModule: claim_rewards_result.into() } - fn check_and_return_original_owner(&self) -> ManagedAddress { - let payments = self.call_value().all_esdt_transfers().clone_value(); - let farm_token_mapper = self.farm_token(); - let mut original_owner = ManagedAddress::zero(); - for payment in payments.into_iter() { - let attributes: FarmTokenAttributes = - farm_token_mapper.get_token_attributes(payment.token_nonce); - - if original_owner.is_zero() { - original_owner = attributes.original_owner; - } else { - require!( - original_owner == attributes.original_owner, - "All position must have the same original owner" - ); - } - } - - require!( - !original_owner.is_zero(), - "Original owner could not be identified" - ); - - original_owner - } - - fn check_additional_payments_original_owner(&self, user: &ManagedAddress) { - let payments = self.call_value().all_esdt_transfers().clone_value(); - if payments.len() == 1 { - return; - } - - let farm_token_mapper = self.farm_token(); - let farm_token_id = farm_token_mapper.get_token_id(); - for payment in payments.into_iter() { - if payment.token_identifier != farm_token_id { - continue; - } - - let attributes: FarmTokenAttributes = - farm_token_mapper.get_token_attributes(payment.token_nonce); - - require!( - user == &attributes.original_owner, - "Provided address is not the same as the original owner" - ); - } - } - fn require_user_whitelisted(&self, user: &ManagedAddress, authorized_address: &ManagedAddress) { let permissions_hub_address = self.permissions_hub_address().get(); let is_whitelisted: bool = self diff --git a/dex/farm/tests/farm_setup/multi_user_farm_setup.rs b/dex/farm/tests/farm_setup/multi_user_farm_setup.rs index b19d14aa9..40010f0ea 100644 --- a/dex/farm/tests/farm_setup/multi_user_farm_setup.rs +++ b/dex/farm/tests/farm_setup/multi_user_farm_setup.rs @@ -657,7 +657,9 @@ where &self.permissions_hub_wrapper, &rust_biguint!(0), |sc| { - sc.whitelist(managed_address!(address_to_whitelist)); + let mut addresses = MultiValueEncoded::new(); + addresses.push(managed_address!(address_to_whitelist)); + sc.whitelist(addresses); }, ) .assert_ok(); @@ -666,7 +668,7 @@ where pub fn remove_whitelist_address_on_behalf( &mut self, user: &Address, - address_to_whitelist: &Address, + address_to_remove: &Address, ) { self.b_mock .execute_tx( @@ -674,7 +676,9 @@ where &self.permissions_hub_wrapper, &rust_biguint!(0), |sc| { - sc.remove_whitelist(managed_address!(address_to_whitelist)); + let mut addresses = MultiValueEncoded::new(); + addresses.push(managed_address!(address_to_remove)); + sc.remove_whitelist(addresses); }, ) .assert_ok(); diff --git a/dex/permissions-hub/src/lib.rs b/dex/permissions-hub/src/lib.rs index 9887fe90c..7dfe4392d 100644 --- a/dex/permissions-hub/src/lib.rs +++ b/dex/permissions-hub/src/lib.rs @@ -11,18 +11,28 @@ pub trait PermissionsHub { #[upgrade] fn upgrade(&self) {} - #[endpoint(whitelist)] - fn whitelist(&self, address_to_whitelist: ManagedAddress) { + #[endpoint] + fn whitelist(&self, addresses_to_whitelist: MultiValueEncoded) { let caller = self.blockchain().get_caller(); - self.user_whitelisted_addresses(&caller) - .insert(address_to_whitelist); + for address_to_whitelist in addresses_to_whitelist.into_iter() { + require!( + self.user_whitelisted_addresses(&caller) + .insert(address_to_whitelist), + "Address is already whitelisted" + ); + } } #[endpoint(removeWhitelist)] - fn remove_whitelist(&self, address_to_remove: ManagedAddress) { + fn remove_whitelist(&self, addresses_to_remove: MultiValueEncoded) { let caller = self.blockchain().get_caller(); - self.user_whitelisted_addresses(&caller) - .swap_remove(&address_to_remove); + for address_to_remove in addresses_to_remove.into_iter() { + require!( + self.user_whitelisted_addresses(&caller) + .swap_remove(&address_to_remove), + "Address is not whitelisted" + ); + } } #[only_owner] diff --git a/dex/permissions-hub/wasm/src/lib.rs b/dex/permissions-hub/wasm/src/lib.rs index afc22eb88..4ea948115 100644 --- a/dex/permissions-hub/wasm/src/lib.rs +++ b/dex/permissions-hub/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 0 +// Endpoints: 6 // Async Callback (empty): 1 -// Total number of exported functions: 3 +// Total number of exported functions: 9 #![no_std] @@ -20,6 +20,12 @@ multiversx_sc_wasm_adapter::endpoints! { ( init => init upgrade => upgrade + whitelist => whitelist + removeWhitelist => remove_whitelist + blacklist => blacklist + removeBlacklist => remove_blacklist + isWhitelisted => is_whitelisted + getBlacklistedAddresses => blacklisted_addresses ) } diff --git a/farm-staking/farm-staking-proxy/src/proxy_actions/claim.rs b/farm-staking/farm-staking-proxy/src/proxy_actions/claim.rs index 057c59206..a3a40a5de 100644 --- a/farm-staking/farm-staking-proxy/src/proxy_actions/claim.rs +++ b/farm-staking/farm-staking-proxy/src/proxy_actions/claim.rs @@ -83,14 +83,12 @@ pub trait ProxyClaimModule: let lp_farm_rewards = lp_farm_claim_rewards_result.lp_farm_rewards; let staking_farm_rewards = staking_farm_claim_rewards_result.staking_farm_rewards; - let claim_result = ClaimDualYieldResult { + dual_yield_token_mapper.nft_burn(payment.token_nonce, &payment.amount); + + ClaimDualYieldResult { lp_farm_rewards, staking_farm_rewards, new_dual_yield_tokens, - }; - - dual_yield_token_mapper.nft_burn(payment.token_nonce, &payment.amount); - - claim_result + } } } diff --git a/farm-staking/farm-staking/src/external_interaction.rs b/farm-staking/farm-staking/src/external_interaction.rs index 46178dd66..b870f5fa3 100644 --- a/farm-staking/farm-staking/src/external_interaction.rs +++ b/farm-staking/farm-staking/src/external_interaction.rs @@ -51,7 +51,12 @@ pub trait ExternalInteractionsModule: self.require_user_whitelisted(&user, &caller); let payments = self.get_non_empty_payments(); - self.check_additional_payments_original_owner(&user, &payments); + let farm_token_mapper = self.farm_token(); + self.check_additional_payments_original_owner::>( + &user, + &payments, + &farm_token_mapper, + ); let boosted_rewards = self.claim_only_boosted_payment(&user); let boosted_rewards_payment = @@ -81,14 +86,18 @@ pub trait ExternalInteractionsModule: #[payable("*")] #[endpoint(claimRewardsOnBehalf)] fn claim_rewards_on_behalf(&self) -> ClaimRewardsResultType { - let payment = self.call_value().single_esdt(); - let user = self.check_and_return_original_owner(&payment); + let payments = self.get_non_empty_payments(); + let farm_token_mapper = self.farm_token(); let caller = self.blockchain().get_caller(); + let user = self.check_and_return_original_owner::>( + &payments, + &farm_token_mapper, + ); self.require_user_whitelisted(&user, &caller); let claim_result = self.claim_rewards_base_no_farm_token_mint::>( user.clone(), - ManagedVec::from_single_item(payment), + payments, ); let mut virtual_farm_token = claim_result.new_farm_token.clone(); @@ -120,45 +129,6 @@ pub trait ExternalInteractionsModule: (virtual_farm_token.payment, claim_result.rewards).into() } - fn check_and_return_original_owner(&self, payment: &EsdtTokenPayment) -> ManagedAddress { - let farm_token_mapper = self.farm_token(); - let attributes: StakingFarmTokenAttributes = - farm_token_mapper.get_token_attributes(payment.token_nonce); - - require!( - !attributes.original_owner.is_zero(), - "Original owner could not be identified" - ); - - attributes.original_owner - } - - fn check_additional_payments_original_owner( - &self, - user: &ManagedAddress, - payments: &ManagedVec, - ) { - if payments.len() == 1 { - return; - } - - let farm_token_mapper = self.farm_token(); - let farm_token_id = farm_token_mapper.get_token_id(); - for payment in payments.into_iter() { - if payment.token_identifier != farm_token_id { - continue; - } - - let attributes: StakingFarmTokenAttributes = - farm_token_mapper.get_token_attributes(payment.token_nonce); - - require!( - user == &attributes.original_owner, - "Provided address is not the same as the original owner" - ); - } - } - fn require_user_whitelisted(&self, user: &ManagedAddress, authorized_address: &ManagedAddress) { let permissions_hub_address = self.permissions_hub_address().get(); let is_whitelisted: bool = self diff --git a/farm-staking/farm-staking/src/token_attributes.rs b/farm-staking/farm-staking/src/token_attributes.rs index 59f8c6326..0fcabeba3 100644 --- a/farm-staking/farm-staking/src/token_attributes.rs +++ b/farm-staking/farm-staking/src/token_attributes.rs @@ -82,6 +82,10 @@ impl FarmToken for StakingFarmTokenAttributes { fn get_initial_farming_tokens(&self) -> BigUint { &self.current_farm_amount - &self.compounded_reward } + + fn get_original_owner(&self) -> ManagedAddress { + self.original_owner.clone() + } } impl FixedSupplyToken for StakingFarmTokenAttributes { diff --git a/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs b/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs index bf732da74..1f6863d86 100644 --- a/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs +++ b/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs @@ -679,7 +679,9 @@ where &self.permissions_hub_wrapper, &rust_biguint!(0), |sc| { - sc.whitelist(managed_address!(address_to_whitelist)); + let mut addresses = MultiValueEncoded::new(); + addresses.push(managed_address!(address_to_whitelist)); + sc.whitelist(addresses); }, ) .assert_ok(); From e233615e0155455565fe552f43b932216ae7675f Mon Sep 17 00:00:00 2001 From: Sorin Petreasca Date: Wed, 20 Nov 2024 02:42:34 +0000 Subject: [PATCH 02/23] fixed unit tests --- .../mod.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs index b1a056345..1418c9161 100644 --- a/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs +++ b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs @@ -7,7 +7,7 @@ use energy_query::Energy; use farm_with_locked_rewards::Farm; use multiversx_sc::{ codec::multi_types::OptionalValue, - types::{Address, BigInt}, + types::{Address, BigInt, MultiValueEncoded}, }; use multiversx_sc_scenario::{ managed_address, managed_biguint, managed_token_id, rust_biguint, @@ -708,7 +708,9 @@ where &self.permissions_hub_wrapper, &rust_biguint!(0), |sc| { - sc.whitelist(managed_address!(address_to_whitelist)); + let mut addresses = MultiValueEncoded::new(); + addresses.push(managed_address!(address_to_whitelist)); + sc.whitelist(addresses); }, ) .assert_ok(); From 6b1fbc16a3e2e14bcd7a416c1448d2e06a6d07b9 Mon Sep 17 00:00:00 2001 From: Sorin Petreasca Date: Wed, 20 Nov 2024 03:00:02 +0000 Subject: [PATCH 03/23] added permissions hub module --- Cargo.lock | 12 +++++++ .../modules/permissions_hub_module/Cargo.toml | 15 +++++++++ .../src/permissions_hub_module.rs | 32 +++++++++++++++++++ dex/farm-with-locked-rewards/Cargo.toml | 3 ++ .../src/external_interaction.rs | 26 +-------------- dex/farm-with-locked-rewards/src/lib.rs | 1 + dex/farm-with-locked-rewards/wasm/Cargo.lock | 10 ++++++ dex/farm-with-locked-rewards/wasm/src/lib.rs | 2 +- dex/farm/Cargo.toml | 3 ++ dex/farm/src/external_interaction.rs | 26 +-------------- dex/farm/src/lib.rs | 1 + dex/farm/wasm/Cargo.lock | 9 ++++++ dex/farm/wasm/src/lib.rs | 2 +- farm-staking/farm-staking-proxy/Cargo.toml | 3 ++ farm-staking/farm-staking-proxy/src/lib.rs | 1 + .../src/proxy_actions/external_interaction.rs | 26 +-------------- .../mod.rs | 1 + farm-staking/farm-staking/Cargo.toml | 3 ++ .../farm-staking/src/external_interaction.rs | 26 +-------------- farm-staking/farm-staking/src/lib.rs | 3 +- .../tests/farm_staking_setup/mod.rs | 1 + farm-staking/farm-staking/wasm/Cargo.lock | 10 ++++++ farm-staking/farm-staking/wasm/src/lib.rs | 2 +- 23 files changed, 114 insertions(+), 104 deletions(-) create mode 100644 common/modules/permissions_hub_module/Cargo.toml create mode 100644 common/modules/permissions_hub_module/src/permissions_hub_module.rs diff --git a/Cargo.lock b/Cargo.lock index 72759ef35..432affd11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -533,6 +533,7 @@ dependencies = [ "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -590,6 +591,7 @@ dependencies = [ "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -631,6 +633,7 @@ dependencies = [ "pair", "pausable", "permissions-hub", + "permissions_hub_module", "rewards", "sc_whitelist_module", "simple-lock", @@ -771,6 +774,7 @@ dependencies = [ "num-bigint", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -1464,6 +1468,14 @@ dependencies = [ "permissions-hub", ] +[[package]] +name = "permissions_hub_module" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "permissions-hub", +] + [[package]] name = "permissions_module" version = "0.0.0" diff --git a/common/modules/permissions_hub_module/Cargo.toml b/common/modules/permissions_hub_module/Cargo.toml new file mode 100644 index 000000000..503fe9d60 --- /dev/null +++ b/common/modules/permissions_hub_module/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "permissions_hub_module" +version = "0.0.0" +authors = ["MultiversX "] +edition = "2021" + +[lib] +path = "src/permissions_hub_module.rs" + +[dependencies.permissions-hub] +path = "../../../dex/permissions-hub" + +[dependencies.multiversx-sc] +version = "=0.53.2" +features = ["esdt-token-payment-legacy-decode"] diff --git a/common/modules/permissions_hub_module/src/permissions_hub_module.rs b/common/modules/permissions_hub_module/src/permissions_hub_module.rs new file mode 100644 index 000000000..3b7832d06 --- /dev/null +++ b/common/modules/permissions_hub_module/src/permissions_hub_module.rs @@ -0,0 +1,32 @@ +#![no_std] + +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +#[multiversx_sc::module] +pub trait PermissionsHubModule { + fn require_user_whitelisted(&self, user: &ManagedAddress, authorized_address: &ManagedAddress) { + let permissions_hub_address = self.permissions_hub_address().get(); + let is_whitelisted: bool = self + .permissions_hub_proxy(permissions_hub_address) + .is_whitelisted(user, authorized_address) + .execute_on_dest_context(); + + require!(is_whitelisted, "Caller is not whitelisted by the user"); + } + + #[only_owner] + #[endpoint(setPermissionsHubAddress)] + fn set_permissions_hub_address(&self, address: ManagedAddress) { + self.permissions_hub_address().set(&address); + } + + #[proxy] + fn permissions_hub_proxy( + &self, + sc_address: ManagedAddress, + ) -> permissions_hub::Proxy; + + #[storage_mapper("permissionsHubAddress")] + fn permissions_hub_address(&self) -> SingleValueMapper; +} diff --git a/dex/farm-with-locked-rewards/Cargo.toml b/dex/farm-with-locked-rewards/Cargo.toml index f637b3249..3a5a753e1 100644 --- a/dex/farm-with-locked-rewards/Cargo.toml +++ b/dex/farm-with-locked-rewards/Cargo.toml @@ -41,6 +41,9 @@ path = "../../common/modules/utils" [dependencies.permissions_module] path = "../../common/modules/permissions_module" +[dependencies.permissions_hub_module] +path = "../../common/modules/permissions_hub_module" + [dependencies.sc_whitelist_module] path = "../../common/modules/sc_whitelist_module" diff --git a/dex/farm-with-locked-rewards/src/external_interaction.rs b/dex/farm-with-locked-rewards/src/external_interaction.rs index 3fd724465..77445dbe3 100644 --- a/dex/farm-with-locked-rewards/src/external_interaction.rs +++ b/dex/farm-with-locked-rewards/src/external_interaction.rs @@ -16,6 +16,7 @@ pub trait ExternalInteractionsModule: + farm_token::FarmTokenModule + pausable::PausableModule + permissions_module::PermissionsModule + + permissions_hub_module::PermissionsHubModule + sc_whitelist_module::SCWhitelistModule + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule @@ -105,29 +106,4 @@ pub trait ExternalInteractionsModule: (claim_rewards_result.new_farm_token, locked_rewards_payment).into() } - - fn require_user_whitelisted(&self, user: &ManagedAddress, authorized_address: &ManagedAddress) { - let permissions_hub_address = self.permissions_hub_address().get(); - let is_whitelisted: bool = self - .permissions_hub_proxy(permissions_hub_address) - .is_whitelisted(user, authorized_address) - .execute_on_dest_context(); - - require!(is_whitelisted, "Caller is not whitelisted by the user"); - } - - #[only_owner] - #[endpoint(setPermissionsHubAddress)] - fn set_permissions_hub_address(&self, address: ManagedAddress) { - self.permissions_hub_address().set(&address); - } - - #[proxy] - fn permissions_hub_proxy( - &self, - sc_address: ManagedAddress, - ) -> permissions_hub::Proxy; - - #[storage_mapper("permissionsHubAddress")] - fn permissions_hub_address(&self) -> SingleValueMapper; } diff --git a/dex/farm-with-locked-rewards/src/lib.rs b/dex/farm-with-locked-rewards/src/lib.rs index fefbf6275..0de59d77e 100644 --- a/dex/farm-with-locked-rewards/src/lib.rs +++ b/dex/farm-with-locked-rewards/src/lib.rs @@ -29,6 +29,7 @@ pub trait Farm: + utils::UtilsModule + pausable::PausableModule + permissions_module::PermissionsModule + + permissions_hub_module::PermissionsHubModule + sc_whitelist_module::SCWhitelistModule + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule diff --git a/dex/farm-with-locked-rewards/wasm/Cargo.lock b/dex/farm-with-locked-rewards/wasm/Cargo.lock index aa7396f98..2e5098f9b 100644 --- a/dex/farm-with-locked-rewards/wasm/Cargo.lock +++ b/dex/farm-with-locked-rewards/wasm/Cargo.lock @@ -139,6 +139,7 @@ dependencies = [ "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -184,6 +185,7 @@ dependencies = [ "multiversx-sc-modules", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -432,6 +434,14 @@ dependencies = [ "multiversx-sc", ] +[[package]] +name = "permissions_hub_module" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "permissions-hub", +] + [[package]] name = "permissions_module" version = "0.0.0" diff --git a/dex/farm-with-locked-rewards/wasm/src/lib.rs b/dex/farm-with-locked-rewards/wasm/src/lib.rs index 6efe13330..81ef9c901 100644 --- a/dex/farm-with-locked-rewards/wasm/src/lib.rs +++ b/dex/farm-with-locked-rewards/wasm/src/lib.rs @@ -56,6 +56,7 @@ multiversx_sc_wasm_adapter::endpoints! { removeAdmin => remove_admin_endpoint updateOwnerOrAdmin => update_owner_or_admin_endpoint getPermissions => permissions + setPermissionsHubAddress => set_permissions_hub_address addSCAddressToWhitelist => add_sc_address_to_whitelist removeSCAddressFromWhitelist => remove_sc_address_from_whitelist isSCAddressWhitelisted => is_sc_address_whitelisted @@ -68,7 +69,6 @@ multiversx_sc_wasm_adapter::endpoints! { getPairContractManagedAddress => pair_contract_address enterFarmOnBehalf => enter_farm_on_behalf claimRewardsOnBehalf => claim_rewards_on_behalf - setPermissionsHubAddress => set_permissions_hub_address collectUndistributedBoostedRewards => collect_undistributed_boosted_rewards getBoostedYieldsRewardsPercentage => boosted_yields_rewards_percentage getAccumulatedRewardsForWeek => accumulated_rewards_for_week diff --git a/dex/farm/Cargo.toml b/dex/farm/Cargo.toml index 1c60a80ce..12cb0ffa0 100644 --- a/dex/farm/Cargo.toml +++ b/dex/farm/Cargo.toml @@ -38,6 +38,9 @@ path = "../../common/modules/pausable" [dependencies.permissions_module] path = "../../common/modules/permissions_module" +[dependencies.permissions_hub_module] +path = "../../common/modules/permissions_hub_module" + [dependencies.sc_whitelist_module] path = "../../common/modules/sc_whitelist_module" diff --git a/dex/farm/src/external_interaction.rs b/dex/farm/src/external_interaction.rs index 66b594ed6..d840b4e19 100644 --- a/dex/farm/src/external_interaction.rs +++ b/dex/farm/src/external_interaction.rs @@ -15,6 +15,7 @@ pub trait ExternalInteractionsModule: + farm_token::FarmTokenModule + pausable::PausableModule + permissions_module::PermissionsModule + + permissions_hub_module::PermissionsHubModule + sc_whitelist_module::SCWhitelistModule + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule @@ -85,29 +86,4 @@ pub trait ExternalInteractionsModule: claim_rewards_result.into() } - - fn require_user_whitelisted(&self, user: &ManagedAddress, authorized_address: &ManagedAddress) { - let permissions_hub_address = self.permissions_hub_address().get(); - let is_whitelisted: bool = self - .permissions_hub_proxy(permissions_hub_address) - .is_whitelisted(user, authorized_address) - .execute_on_dest_context(); - - require!(is_whitelisted, "Caller is not whitelisted by the user"); - } - - #[only_owner] - #[endpoint(setPermissionsHubAddress)] - fn set_permissions_hub_address(&self, address: ManagedAddress) { - self.permissions_hub_address().set(&address); - } - - #[proxy] - fn permissions_hub_proxy( - &self, - sc_address: ManagedAddress, - ) -> permissions_hub::Proxy; - - #[storage_mapper("permissionsHubAddress")] - fn permissions_hub_address(&self) -> SingleValueMapper; } diff --git a/dex/farm/src/lib.rs b/dex/farm/src/lib.rs index 50883f52f..acaca9b0b 100644 --- a/dex/farm/src/lib.rs +++ b/dex/farm/src/lib.rs @@ -30,6 +30,7 @@ pub trait Farm: + farm_token::FarmTokenModule + pausable::PausableModule + permissions_module::PermissionsModule + + permissions_hub_module::PermissionsHubModule + sc_whitelist_module::SCWhitelistModule + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule diff --git a/dex/farm/wasm/Cargo.lock b/dex/farm/wasm/Cargo.lock index 18594d924..a080bf9ba 100644 --- a/dex/farm/wasm/Cargo.lock +++ b/dex/farm/wasm/Cargo.lock @@ -139,6 +139,7 @@ dependencies = [ "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -401,6 +402,14 @@ dependencies = [ "multiversx-sc", ] +[[package]] +name = "permissions_hub_module" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "permissions-hub", +] + [[package]] name = "permissions_module" version = "0.0.0" diff --git a/dex/farm/wasm/src/lib.rs b/dex/farm/wasm/src/lib.rs index 3902fdb5d..235653731 100644 --- a/dex/farm/wasm/src/lib.rs +++ b/dex/farm/wasm/src/lib.rs @@ -53,6 +53,7 @@ multiversx_sc_wasm_adapter::endpoints! { removeAdmin => remove_admin_endpoint updateOwnerOrAdmin => update_owner_or_admin_endpoint getPermissions => permissions + setPermissionsHubAddress => set_permissions_hub_address addSCAddressToWhitelist => add_sc_address_to_whitelist removeSCAddressFromWhitelist => remove_sc_address_from_whitelist isSCAddressWhitelisted => is_sc_address_whitelisted @@ -65,7 +66,6 @@ multiversx_sc_wasm_adapter::endpoints! { getPairContractManagedAddress => pair_contract_address enterFarmOnBehalf => enter_farm_on_behalf claimRewardsOnBehalf => claim_rewards_on_behalf - setPermissionsHubAddress => set_permissions_hub_address collectUndistributedBoostedRewards => collect_undistributed_boosted_rewards getBoostedYieldsRewardsPercentage => boosted_yields_rewards_percentage getAccumulatedRewardsForWeek => accumulated_rewards_for_week diff --git a/farm-staking/farm-staking-proxy/Cargo.toml b/farm-staking/farm-staking-proxy/Cargo.toml index 0da624de0..34d8c7151 100644 --- a/farm-staking/farm-staking-proxy/Cargo.toml +++ b/farm-staking/farm-staking-proxy/Cargo.toml @@ -66,6 +66,9 @@ path = "../../energy-integration/common-modules/energy-query" [dependencies.permissions-hub] path = "../../dex/permissions-hub" +[dependencies.permissions_hub_module] +path = "../../common/modules/permissions_hub_module" + [dev-dependencies] num-bigint = "0.4.2" diff --git a/farm-staking/farm-staking-proxy/src/lib.rs b/farm-staking/farm-staking-proxy/src/lib.rs index 4840bd965..f28d5d083 100644 --- a/farm-staking/farm-staking-proxy/src/lib.rs +++ b/farm-staking/farm-staking-proxy/src/lib.rs @@ -14,6 +14,7 @@ pub trait FarmStakingProxy: + external_contracts_interactions::ExternalContractsInteractionsModule + lp_farm_token::LpFarmTokenModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + + permissions_hub_module::PermissionsHubModule + utils::UtilsModule + token_send::TokenSendModule + energy_query::EnergyQueryModule diff --git a/farm-staking/farm-staking-proxy/src/proxy_actions/external_interaction.rs b/farm-staking/farm-staking-proxy/src/proxy_actions/external_interaction.rs index 12d8b257d..722bc2eb8 100644 --- a/farm-staking/farm-staking-proxy/src/proxy_actions/external_interaction.rs +++ b/farm-staking/farm-staking-proxy/src/proxy_actions/external_interaction.rs @@ -15,6 +15,7 @@ pub trait ProxyExternalInteractionsModule: + crate::proxy_actions::stake::ProxyStakeModule + crate::proxy_actions::claim::ProxyClaimModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + + permissions_hub_module::PermissionsHubModule + utils::UtilsModule + token_send::TokenSendModule + energy_query::EnergyQueryModule @@ -115,29 +116,4 @@ pub trait ProxyExternalInteractionsModule: attributes.original_owner } - - fn require_user_whitelisted(&self, user: &ManagedAddress, authorized_address: &ManagedAddress) { - let permissions_hub_address = self.permissions_hub_address().get(); - let is_whitelisted: bool = self - .permissions_hub_proxy(permissions_hub_address) - .is_whitelisted(user, authorized_address) - .execute_on_dest_context(); - - require!(is_whitelisted, "Caller is not whitelisted by the user"); - } - - #[only_owner] - #[endpoint(setPermissionsHubAddress)] - fn set_permissions_hub_address(&self, address: ManagedAddress) { - self.permissions_hub_address().set(&address); - } - - #[proxy] - fn permissions_hub_proxy( - &self, - sc_address: ManagedAddress, - ) -> permissions_hub::Proxy; - - #[storage_mapper("permissionsHubAddress")] - fn permissions_hub_address(&self) -> SingleValueMapper; } diff --git a/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs index 1418c9161..7bc22b29a 100644 --- a/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs +++ b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs @@ -32,6 +32,7 @@ use farm_staking_proxy::proxy_actions::stake::ProxyStakeModule; use farm_staking_proxy::proxy_actions::unstake::ProxyUnstakeModule; use permissions_hub::PermissionsHub; +use permissions_hub_module::PermissionsHubModule; use sc_whitelist_module::SCWhitelistModule; use crate::{ diff --git a/farm-staking/farm-staking/Cargo.toml b/farm-staking/farm-staking/Cargo.toml index e19231477..b99ae9927 100644 --- a/farm-staking/farm-staking/Cargo.toml +++ b/farm-staking/farm-staking/Cargo.toml @@ -53,6 +53,9 @@ path = "../../common/modules/pausable" [dependencies.permissions_module] path = "../../common/modules/permissions_module" +[dependencies.permissions_hub_module] +path = "../../common/modules/permissions_hub_module" + [dependencies.sc_whitelist_module] path = "../../common/modules/sc_whitelist_module" diff --git a/farm-staking/farm-staking/src/external_interaction.rs b/farm-staking/farm-staking/src/external_interaction.rs index b870f5fa3..ab450a4b3 100644 --- a/farm-staking/farm-staking/src/external_interaction.rs +++ b/farm-staking/farm-staking/src/external_interaction.rs @@ -19,6 +19,7 @@ pub trait ExternalInteractionsModule: + sc_whitelist_module::SCWhitelistModule + pausable::PausableModule + permissions_module::PermissionsModule + + permissions_hub_module::PermissionsHubModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + farm_base_impl::base_farm_init::BaseFarmInitModule + farm_base_impl::base_farm_validation::BaseFarmValidationModule @@ -128,29 +129,4 @@ pub trait ExternalInteractionsModule: (virtual_farm_token.payment, claim_result.rewards).into() } - - fn require_user_whitelisted(&self, user: &ManagedAddress, authorized_address: &ManagedAddress) { - let permissions_hub_address = self.permissions_hub_address().get(); - let is_whitelisted: bool = self - .permissions_hub_proxy(permissions_hub_address) - .is_whitelisted(user, authorized_address) - .execute_on_dest_context(); - - require!(is_whitelisted, "Caller is not whitelisted by the user"); - } - - #[only_owner] - #[endpoint(setPermissionsHubAddress)] - fn set_permissions_hub_address(&self, address: ManagedAddress) { - self.permissions_hub_address().set(&address); - } - - #[proxy] - fn permissions_hub_proxy( - &self, - sc_address: ManagedAddress, - ) -> permissions_hub::Proxy; - - #[storage_mapper("permissionsHubAddress")] - fn permissions_hub_address(&self) -> SingleValueMapper; } diff --git a/farm-staking/farm-staking/src/lib.rs b/farm-staking/farm-staking/src/lib.rs index 3f4f9363b..3907e38ce 100644 --- a/farm-staking/farm-staking/src/lib.rs +++ b/farm-staking/farm-staking/src/lib.rs @@ -18,12 +18,12 @@ pub mod claim_only_boosted_staking_rewards; pub mod claim_stake_farm_rewards; pub mod compound_stake_farm_rewards; pub mod custom_rewards; +pub mod external_interaction; pub mod farm_token_roles; pub mod stake_farm; pub mod token_attributes; pub mod unbond_farm; pub mod unstake_farm; -pub mod external_interaction; #[multiversx_sc::contract] pub trait FarmStaking: @@ -36,6 +36,7 @@ pub trait FarmStaking: + sc_whitelist_module::SCWhitelistModule + pausable::PausableModule + permissions_module::PermissionsModule + + permissions_hub_module::PermissionsHubModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + farm_base_impl::base_farm_init::BaseFarmInitModule + farm_base_impl::base_farm_validation::BaseFarmValidationModule diff --git a/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs b/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs index 1f6863d86..35ed665bc 100644 --- a/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs +++ b/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs @@ -27,6 +27,7 @@ use farm_staking::*; use farm_token::FarmTokenModule; use pausable::{PausableModule, State}; use permissions_hub::PermissionsHub; +use permissions_hub_module::PermissionsHubModule; use rewards::RewardsModule; pub static REWARD_TOKEN_ID: &[u8] = b"RIDE-abcdef"; // reward token ID diff --git a/farm-staking/farm-staking/wasm/Cargo.lock b/farm-staking/farm-staking/wasm/Cargo.lock index 267c19b5d..e0155a29d 100644 --- a/farm-staking/farm-staking/wasm/Cargo.lock +++ b/farm-staking/farm-staking/wasm/Cargo.lock @@ -139,6 +139,7 @@ dependencies = [ "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -185,6 +186,7 @@ dependencies = [ "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -433,6 +435,14 @@ dependencies = [ "multiversx-sc", ] +[[package]] +name = "permissions_hub_module" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "permissions-hub", +] + [[package]] name = "permissions_module" version = "0.0.0" diff --git a/farm-staking/farm-staking/wasm/src/lib.rs b/farm-staking/farm-staking/wasm/src/lib.rs index f2e25d699..e0fdd5bb3 100644 --- a/farm-staking/farm-staking/wasm/src/lib.rs +++ b/farm-staking/farm-staking/wasm/src/lib.rs @@ -59,6 +59,7 @@ multiversx_sc_wasm_adapter::endpoints! { removeAdmin => remove_admin_endpoint updateOwnerOrAdmin => update_owner_or_admin_endpoint getPermissions => permissions + setPermissionsHubAddress => set_permissions_hub_address setBurnRoleForAddress => set_burn_role_for_address stakeFarmThroughProxy => stake_farm_through_proxy stakeFarm => stake_farm_endpoint @@ -70,7 +71,6 @@ multiversx_sc_wasm_adapter::endpoints! { unbondFarm => unbond_farm stakeFarmOnBehalf => stake_farm_on_behalf claimRewardsOnBehalf => claim_rewards_on_behalf - setPermissionsHubAddress => set_permissions_hub_address claimBoostedRewards => claim_boosted_rewards collectUndistributedBoostedRewards => collect_undistributed_boosted_rewards getBoostedYieldsRewardsPercentage => boosted_yields_rewards_percentage From 6d2132547cbc46f6d17d73fce628eea230d1490c Mon Sep 17 00:00:00 2001 From: Sorin Petreasca Date: Wed, 20 Nov 2024 03:02:39 +0000 Subject: [PATCH 04/23] unit tests fix --- dex/farm/tests/farm_setup/multi_user_farm_setup.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/dex/farm/tests/farm_setup/multi_user_farm_setup.rs b/dex/farm/tests/farm_setup/multi_user_farm_setup.rs index 40010f0ea..3398fd679 100644 --- a/dex/farm/tests/farm_setup/multi_user_farm_setup.rs +++ b/dex/farm/tests/farm_setup/multi_user_farm_setup.rs @@ -25,6 +25,7 @@ use farm_boosted_yields::FarmBoostedYieldsModule; use farm_token::FarmTokenModule; use pausable::{PausableModule, State}; use permissions_hub::PermissionsHub; +use permissions_hub_module::PermissionsHubModule; use sc_whitelist_module::SCWhitelistModule; use week_timekeeping::Epoch; use weekly_rewards_splitting::update_claim_progress_energy::UpdateClaimProgressEnergyModule; From dcb640793de9a7b6977c9c55d640cf328733c526 Mon Sep 17 00:00:00 2001 From: Sorin Petreasca Date: Wed, 20 Nov 2024 03:04:57 +0000 Subject: [PATCH 05/23] farm with locked rewards unit tests fix --- .../tests/farm_with_locked_rewards_setup/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs b/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs index 6be3e313d..4d2a2819a 100644 --- a/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs +++ b/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs @@ -26,6 +26,7 @@ use locking_module::lock_with_energy_module::LockWithEnergyModule; use multiversx_sc_modules::pause::PauseModule; use pausable::{PausableModule, State}; use permissions_hub::PermissionsHub; +use permissions_hub_module::PermissionsHubModule; use rewards::RewardsModule; use sc_whitelist_module::SCWhitelistModule; use simple_lock::locked_token::LockedTokenModule; From a2f526f67a6deeb39b6f7e015820e3600c3531e0 Mon Sep 17 00:00:00 2001 From: Sorin Petreasca Date: Wed, 20 Nov 2024 09:43:45 +0000 Subject: [PATCH 06/23] added OriginalOwnerHelperModule --- Cargo.lock | 11 ++++ .../modules/original_owner_helper/Cargo.toml | 15 +++++ .../modules/original_owner_helper/src/lib.rs | 62 +++++++++++++++++++ common/modules/utils/src/lib.rs | 56 +---------------- dex/farm-with-locked-rewards/Cargo.toml | 3 + .../src/external_interaction.rs | 1 + dex/farm-with-locked-rewards/src/lib.rs | 1 + dex/farm-with-locked-rewards/wasm/Cargo.lock | 10 +++ dex/farm/Cargo.toml | 3 + dex/farm/src/external_interaction.rs | 1 + dex/farm/src/lib.rs | 1 + dex/farm/wasm/Cargo.lock | 9 +++ farm-staking/farm-staking/Cargo.toml | 3 + .../farm-staking/src/external_interaction.rs | 1 + farm-staking/farm-staking/src/lib.rs | 1 + farm-staking/farm-staking/wasm/Cargo.lock | 10 +++ 16 files changed, 133 insertions(+), 55 deletions(-) create mode 100644 common/modules/original_owner_helper/Cargo.toml create mode 100644 common/modules/original_owner_helper/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 432affd11..4b4c525d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -530,6 +530,7 @@ dependencies = [ "multiversx-sc-modules", "multiversx-sc-scenario", "num-bigint", + "original_owner_helper", "pair", "pausable", "permissions-hub", @@ -588,6 +589,7 @@ dependencies = [ "multiversx-sc-modules", "multiversx-sc-scenario", "num-bigint", + "original_owner_helper", "pair", "pausable", "permissions-hub", @@ -772,6 +774,7 @@ dependencies = [ "multiversx-sc-modules", "multiversx-sc-scenario", "num-bigint", + "original_owner_helper", "pausable", "permissions-hub", "permissions_hub_module", @@ -1373,6 +1376,14 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "original_owner_helper" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "pair" version = "0.0.0" diff --git a/common/modules/original_owner_helper/Cargo.toml b/common/modules/original_owner_helper/Cargo.toml new file mode 100644 index 000000000..21fa393dc --- /dev/null +++ b/common/modules/original_owner_helper/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "original_owner_helper" +version = "0.0.0" +authors = ["MultiversX "] +edition = "2021" + +[lib] +path = "src/lib.rs" + +[dependencies.multiversx-sc] +version = "=0.53.2" +features = ["esdt-token-payment-legacy-decode"] + +[dependencies.common_structs] +path = "../../common_structs" diff --git a/common/modules/original_owner_helper/src/lib.rs b/common/modules/original_owner_helper/src/lib.rs new file mode 100644 index 000000000..3f5126929 --- /dev/null +++ b/common/modules/original_owner_helper/src/lib.rs @@ -0,0 +1,62 @@ +#![no_std] + +multiversx_sc::imports!(); + +use common_structs::{FarmToken, PaymentsVec}; + +#[multiversx_sc::module] +pub trait OriginalOwnerHelperModule { + fn check_and_return_original_owner + TopDecode>( + &self, + payments: &PaymentsVec, + farm_token_mapper: &NonFungibleTokenMapper, + ) -> ManagedAddress { + let mut original_owner = ManagedAddress::zero(); + for payment in payments.iter() { + let attributes: T = farm_token_mapper.get_token_attributes(payment.token_nonce); + let payment_original_owner = attributes.get_original_owner(); + + if original_owner.is_zero() { + original_owner = payment_original_owner; + } else { + require!( + original_owner == payment_original_owner, + "All position must have the same original owner" + ); + } + } + + require!( + !original_owner.is_zero(), + "Original owner could not be identified" + ); + + original_owner + } + + fn check_additional_payments_original_owner + TopDecode>( + &self, + user: &ManagedAddress, + payments: &PaymentsVec, + farm_token_mapper: &NonFungibleTokenMapper, + ) { + if payments.len() == 1 { + return; + } + + let farm_token_id = farm_token_mapper.get_token_id(); + for payment in payments.into_iter() { + if payment.token_identifier != farm_token_id { + continue; + } + + let attributes: T = farm_token_mapper.get_token_attributes(payment.token_nonce); + let payment_original_owner = attributes.get_original_owner(); + + require!( + user == &payment_original_owner, + "Provided address is not the same as the original owner" + ); + } + } +} diff --git a/common/modules/utils/src/lib.rs b/common/modules/utils/src/lib.rs index 861061b28..990b88329 100644 --- a/common/modules/utils/src/lib.rs +++ b/common/modules/utils/src/lib.rs @@ -2,7 +2,7 @@ multiversx_sc::imports!(); -use common_structs::{FarmToken, PaymentAttributesPair, PaymentsVec}; +use common_structs::{PaymentAttributesPair, PaymentsVec}; use fixed_supply_token::FixedSupplyToken; use mergeable::Mergeable; @@ -116,60 +116,6 @@ pub trait UtilsModule { } } - fn check_and_return_original_owner + TopDecode>( - &self, - payments: &PaymentsVec, - farm_token_mapper: &NonFungibleTokenMapper, - ) -> ManagedAddress { - let mut original_owner = ManagedAddress::zero(); - for payment in payments.iter() { - let attributes: T = farm_token_mapper.get_token_attributes(payment.token_nonce); - let payment_original_owner = attributes.get_original_owner(); - - if original_owner.is_zero() { - original_owner = payment_original_owner; - } else { - require!( - original_owner == payment_original_owner, - "All position must have the same original owner" - ); - } - } - - require!( - !original_owner.is_zero(), - "Original owner could not be identified" - ); - - original_owner - } - - fn check_additional_payments_original_owner + TopDecode>( - &self, - user: &ManagedAddress, - payments: &PaymentsVec, - farm_token_mapper: &NonFungibleTokenMapper, - ) { - if payments.len() == 1 { - return; - } - - let farm_token_id = farm_token_mapper.get_token_id(); - for payment in payments.into_iter() { - if payment.token_identifier != farm_token_id { - continue; - } - - let attributes: T = farm_token_mapper.get_token_attributes(payment.token_nonce); - let payment_original_owner = attributes.get_original_owner(); - - require!( - user == &payment_original_owner, - "Provided address is not the same as the original owner" - ); - } - } - fn require_valid_token_id(&self, token_id: &TokenIdentifier) { require!(token_id.is_valid_esdt_identifier(), "Invalid token ID"); } diff --git a/dex/farm-with-locked-rewards/Cargo.toml b/dex/farm-with-locked-rewards/Cargo.toml index 3a5a753e1..d39dd6ed1 100644 --- a/dex/farm-with-locked-rewards/Cargo.toml +++ b/dex/farm-with-locked-rewards/Cargo.toml @@ -44,6 +44,9 @@ path = "../../common/modules/permissions_module" [dependencies.permissions_hub_module] path = "../../common/modules/permissions_hub_module" +[dependencies.original_owner_helper] +path = "../../common/modules/original_owner_helper" + [dependencies.sc_whitelist_module] path = "../../common/modules/sc_whitelist_module" diff --git a/dex/farm-with-locked-rewards/src/external_interaction.rs b/dex/farm-with-locked-rewards/src/external_interaction.rs index 77445dbe3..be29004f0 100644 --- a/dex/farm-with-locked-rewards/src/external_interaction.rs +++ b/dex/farm-with-locked-rewards/src/external_interaction.rs @@ -17,6 +17,7 @@ pub trait ExternalInteractionsModule: + pausable::PausableModule + permissions_module::PermissionsModule + permissions_hub_module::PermissionsHubModule + + original_owner_helper::OriginalOwnerHelperModule + sc_whitelist_module::SCWhitelistModule + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule diff --git a/dex/farm-with-locked-rewards/src/lib.rs b/dex/farm-with-locked-rewards/src/lib.rs index 0de59d77e..69b5dc4a1 100644 --- a/dex/farm-with-locked-rewards/src/lib.rs +++ b/dex/farm-with-locked-rewards/src/lib.rs @@ -30,6 +30,7 @@ pub trait Farm: + pausable::PausableModule + permissions_module::PermissionsModule + permissions_hub_module::PermissionsHubModule + + original_owner_helper::OriginalOwnerHelperModule + sc_whitelist_module::SCWhitelistModule + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule diff --git a/dex/farm-with-locked-rewards/wasm/Cargo.lock b/dex/farm-with-locked-rewards/wasm/Cargo.lock index 2e5098f9b..1ec1e747a 100644 --- a/dex/farm-with-locked-rewards/wasm/Cargo.lock +++ b/dex/farm-with-locked-rewards/wasm/Cargo.lock @@ -136,6 +136,7 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pair", "pausable", "permissions-hub", @@ -183,6 +184,7 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pausable", "permissions-hub", "permissions_hub_module", @@ -403,6 +405,14 @@ dependencies = [ "autocfg", ] +[[package]] +name = "original_owner_helper" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "pair" version = "0.0.0" diff --git a/dex/farm/Cargo.toml b/dex/farm/Cargo.toml index 12cb0ffa0..b91a99066 100644 --- a/dex/farm/Cargo.toml +++ b/dex/farm/Cargo.toml @@ -41,6 +41,9 @@ path = "../../common/modules/permissions_module" [dependencies.permissions_hub_module] path = "../../common/modules/permissions_hub_module" +[dependencies.original_owner_helper] +path = "../../common/modules/original_owner_helper" + [dependencies.sc_whitelist_module] path = "../../common/modules/sc_whitelist_module" diff --git a/dex/farm/src/external_interaction.rs b/dex/farm/src/external_interaction.rs index d840b4e19..0af8fe5a5 100644 --- a/dex/farm/src/external_interaction.rs +++ b/dex/farm/src/external_interaction.rs @@ -16,6 +16,7 @@ pub trait ExternalInteractionsModule: + pausable::PausableModule + permissions_module::PermissionsModule + permissions_hub_module::PermissionsHubModule + + original_owner_helper::OriginalOwnerHelperModule + sc_whitelist_module::SCWhitelistModule + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule diff --git a/dex/farm/src/lib.rs b/dex/farm/src/lib.rs index acaca9b0b..5eb7ea834 100644 --- a/dex/farm/src/lib.rs +++ b/dex/farm/src/lib.rs @@ -31,6 +31,7 @@ pub trait Farm: + pausable::PausableModule + permissions_module::PermissionsModule + permissions_hub_module::PermissionsHubModule + + original_owner_helper::OriginalOwnerHelperModule + sc_whitelist_module::SCWhitelistModule + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule diff --git a/dex/farm/wasm/Cargo.lock b/dex/farm/wasm/Cargo.lock index a080bf9ba..c85e89764 100644 --- a/dex/farm/wasm/Cargo.lock +++ b/dex/farm/wasm/Cargo.lock @@ -136,6 +136,7 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pair", "pausable", "permissions-hub", @@ -371,6 +372,14 @@ dependencies = [ "autocfg", ] +[[package]] +name = "original_owner_helper" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "pair" version = "0.0.0" diff --git a/farm-staking/farm-staking/Cargo.toml b/farm-staking/farm-staking/Cargo.toml index b99ae9927..51876247b 100644 --- a/farm-staking/farm-staking/Cargo.toml +++ b/farm-staking/farm-staking/Cargo.toml @@ -56,6 +56,9 @@ path = "../../common/modules/permissions_module" [dependencies.permissions_hub_module] path = "../../common/modules/permissions_hub_module" +[dependencies.original_owner_helper] +path = "../../common/modules/original_owner_helper" + [dependencies.sc_whitelist_module] path = "../../common/modules/sc_whitelist_module" diff --git a/farm-staking/farm-staking/src/external_interaction.rs b/farm-staking/farm-staking/src/external_interaction.rs index ab450a4b3..1ece48d9a 100644 --- a/farm-staking/farm-staking/src/external_interaction.rs +++ b/farm-staking/farm-staking/src/external_interaction.rs @@ -20,6 +20,7 @@ pub trait ExternalInteractionsModule: + pausable::PausableModule + permissions_module::PermissionsModule + permissions_hub_module::PermissionsHubModule + + original_owner_helper::OriginalOwnerHelperModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + farm_base_impl::base_farm_init::BaseFarmInitModule + farm_base_impl::base_farm_validation::BaseFarmValidationModule diff --git a/farm-staking/farm-staking/src/lib.rs b/farm-staking/farm-staking/src/lib.rs index 3907e38ce..4cf1c3ebf 100644 --- a/farm-staking/farm-staking/src/lib.rs +++ b/farm-staking/farm-staking/src/lib.rs @@ -37,6 +37,7 @@ pub trait FarmStaking: + pausable::PausableModule + permissions_module::PermissionsModule + permissions_hub_module::PermissionsHubModule + + original_owner_helper::OriginalOwnerHelperModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + farm_base_impl::base_farm_init::BaseFarmInitModule + farm_base_impl::base_farm_validation::BaseFarmValidationModule diff --git a/farm-staking/farm-staking/wasm/Cargo.lock b/farm-staking/farm-staking/wasm/Cargo.lock index e0155a29d..7da9c7389 100644 --- a/farm-staking/farm-staking/wasm/Cargo.lock +++ b/farm-staking/farm-staking/wasm/Cargo.lock @@ -136,6 +136,7 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pair", "pausable", "permissions-hub", @@ -183,6 +184,7 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pair", "pausable", "permissions-hub", @@ -404,6 +406,14 @@ dependencies = [ "autocfg", ] +[[package]] +name = "original_owner_helper" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "pair" version = "0.0.0" From 8fd716c74aa9e43c49d0a481309bd87a2339dfbe Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Tue, 26 Nov 2024 14:27:39 +0200 Subject: [PATCH 07/23] impl --- dex/proxy-deployer/src/deploy.rs | 134 ++++++++++++++++++++++++++ dex/proxy-deployer/src/farm_deploy.rs | 87 ----------------- dex/proxy-deployer/src/lib.rs | 25 ++++- dex/proxy-deployer/src/storage.rs | 25 +++++ dex/proxy-deployer/src/views.rs | 81 ++++++++++++++++ dex/proxy-deployer/wasm/src/lib.rs | 14 +-- 6 files changed, 268 insertions(+), 98 deletions(-) create mode 100644 dex/proxy-deployer/src/deploy.rs delete mode 100644 dex/proxy-deployer/src/farm_deploy.rs create mode 100644 dex/proxy-deployer/src/storage.rs create mode 100644 dex/proxy-deployer/src/views.rs diff --git a/dex/proxy-deployer/src/deploy.rs b/dex/proxy-deployer/src/deploy.rs new file mode 100644 index 000000000..e88d347e1 --- /dev/null +++ b/dex/proxy-deployer/src/deploy.rs @@ -0,0 +1,134 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +#[derive(TypeAbi, TopEncode, TopDecode, NestedEncode, NestedDecode, ManagedVecItem)] +pub struct ForcedDeployArg { + pub arg_nr: usize, + pub value: ManagedBuffer, +} + +pub type ForcedDeployArgsType = MultiValueEncoded>>; + +#[multiversx_sc::module] +pub trait DeployModule: crate::storage::StorageModule { + /// Forced deploy args contain the index of the arg, and the argument itself. + /// + /// They must be provided in the order expected by the deployed SCs arguments order. + #[only_owner] + #[endpoint(overwriteForcedDeployArgs)] + fn overwrite_forced_deploy_args(&self, forced_deploy_args: ForcedDeployArgsType) { + let mut forced_args = ManagedVec::new(); + for forced_arg_multi in forced_deploy_args { + let (index, arg) = forced_arg_multi.into_tuple(); + let forced_arg = ForcedDeployArg { + arg_nr: index, + value: arg, + }; + forced_args.push(forced_arg); + } + + self.forced_deploy_args().set(forced_args); + } + + #[endpoint(deployContract)] + fn deploy_contract( + &self, + token_used_by_sc: TokenIdentifier, + args: MultiValueEncoded, + ) -> ManagedAddress { + require!( + !self.all_used_tokens().contains(&token_used_by_sc), + "Token already used" + ); + + let arg_buffer = self.prepare_deploy_args(args.into_vec_of_buffers()); + let deployed_sc_address = self.deploy_from_source(&arg_buffer); + + let address_id = self.address_id().insert_new(&deployed_sc_address); + let _ = self.all_deployed_contracts().insert(address_id); + self.address_for_token(&token_used_by_sc).set(address_id); + + let _ = self.all_used_tokens().insert(token_used_by_sc); + + deployed_sc_address + } + + fn prepare_deploy_args( + &self, + provided_args: ManagedVec, + ) -> ManagedArgBuffer { + let mut arg_buffer = ManagedArgBuffer::new(); + + let mut forced_args = self.forced_deploy_args().get(); + let mut opt_current_forced_arg = self.get_next_forced_arg(&mut forced_args); + + let mut all_args_index = 0; + let mut provided_args_index = 0; + let provided_args_len = provided_args.len(); + while provided_args_index < provided_args_len { + if let Some(current_forced_arg) = &opt_current_forced_arg { + if current_forced_arg.arg_nr == all_args_index { + arg_buffer.push_arg_raw(current_forced_arg.value.clone()); + opt_current_forced_arg = self.get_next_forced_arg(&mut forced_args); + + all_args_index += 1; + + continue; + } + } + + let provided_arg = provided_args.get(provided_args_index); + arg_buffer.push_arg_raw((*provided_arg).clone()); + + provided_args_index += 1; + all_args_index += 1; + } + + while let Some(current_forced_arg) = &opt_current_forced_arg { + if current_forced_arg.arg_nr == all_args_index { + arg_buffer.push_arg_raw(current_forced_arg.value.clone()); + opt_current_forced_arg = self.get_next_forced_arg(&mut forced_args); + + all_args_index += 1; + } else { + break; + } + } + + // All contracts have the admins list as last argument + let caller = self.blockchain().get_caller(); + arg_buffer.push_arg_raw(caller.as_managed_buffer().clone()); + + arg_buffer + } + + fn get_next_forced_arg( + &self, + forced_args: &mut ManagedVec>, + ) -> Option> { + if forced_args.is_empty() { + return None; + } + + let arg = forced_args.get(0); + forced_args.remove(0); + + Some(arg) + } + + fn deploy_from_source(&self, args: &ManagedArgBuffer) -> ManagedAddress { + let template = self.template_address().get(); + let code_metadata = + CodeMetadata::PAYABLE_BY_SC | CodeMetadata::READABLE | CodeMetadata::UPGRADEABLE; + let gas_left = self.blockchain().get_gas_left(); + let (deployed_sc_address, _) = self.send_raw().deploy_from_source_contract( + gas_left, + &BigUint::zero(), + &template, + code_metadata, + args, + ); + + deployed_sc_address + } +} diff --git a/dex/proxy-deployer/src/farm_deploy.rs b/dex/proxy-deployer/src/farm_deploy.rs deleted file mode 100644 index eb1c88e53..000000000 --- a/dex/proxy-deployer/src/farm_deploy.rs +++ /dev/null @@ -1,87 +0,0 @@ -multiversx_sc::imports!(); - -use farm::ProxyTrait as _; - -const DIVISION_SAFETY_CONST: u64 = 1_000_000_000_000_000_000; - -#[multiversx_sc::module] -pub trait FarmDeployModule { - #[endpoint(deployFarm)] - fn deploy_farm( - &self, - reward_token_id: TokenIdentifier, - farming_token_id: TokenIdentifier, - ) -> ManagedAddress { - let owner = self.blockchain().get_owner_address(); - let caller = self.blockchain().get_caller(); - let mut admins_list = MultiValueEncoded::new(); - admins_list.push(caller.clone()); - - let farm_template = self.farm_template_address().get(); - let code_metadata = - CodeMetadata::PAYABLE_BY_SC | CodeMetadata::READABLE | CodeMetadata::UPGRADEABLE; - let (new_farm_address, ()) = self - .farm_deploy_proxy() - .init( - reward_token_id, - farming_token_id, - DIVISION_SAFETY_CONST, - owner, - admins_list, - ) - .deploy_from_source(&farm_template, code_metadata); - - self.deployer_farm_addresses(&caller) - .update(|farm_addresses| { - farm_addresses.push(new_farm_address.clone()); - }); - self.deployers_list().insert(caller); - - new_farm_address - } - - #[only_owner] - #[endpoint(callFarmEndpoint)] - fn call_farm_endpoint( - &self, - farm_address: ManagedAddress, - function_name: ManagedBuffer, - args: MultiValueEncoded, - ) { - let gas_left = self.blockchain().get_gas_left(); - let mut contract_call = self - .send() - .contract_call::<()>(farm_address, function_name) - .with_gas_limit(gas_left); - - for arg in args { - contract_call.push_raw_argument(arg); - } - let _: IgnoreValue = contract_call.execute_on_dest_context(); - } - - #[view(getAllDeployedFarms)] - fn get_all_deployed_farms(&self) -> ManagedVec { - let mut all_farm_addresses = ManagedVec::new(); - for deployer in self.deployers_list().iter() { - all_farm_addresses.append_vec(self.deployer_farm_addresses(&deployer).get()); - } - all_farm_addresses - } - - #[proxy] - fn farm_deploy_proxy(&self) -> farm::Proxy; - - #[storage_mapper("farmTemplateAddress")] - fn farm_template_address(&self) -> SingleValueMapper; - - #[storage_mapper("deployersList")] - fn deployers_list(&self) -> UnorderedSetMapper; - - #[view(getDeployerFarmAddresses)] - #[storage_mapper("deployerFarmAddresses")] - fn deployer_farm_addresses( - &self, - deployer_address: &ManagedAddress, - ) -> SingleValueMapper>; -} diff --git a/dex/proxy-deployer/src/lib.rs b/dex/proxy-deployer/src/lib.rs index 7f7f0c16a..0e80e074c 100644 --- a/dex/proxy-deployer/src/lib.rs +++ b/dex/proxy-deployer/src/lib.rs @@ -1,19 +1,34 @@ #![no_std] +use deploy::ForcedDeployArgsType; + multiversx_sc::imports!(); -pub mod farm_deploy; +pub mod deploy; +pub mod storage; +pub mod views; #[multiversx_sc::contract] -pub trait ProxyDeployer: farm_deploy::FarmDeployModule { +pub trait ProxyDeployer: deploy::DeployModule + storage::StorageModule + views::ViewModule { + /// Forced deploy args contain the index of the arg, and the argument itself. + /// + /// They must be provided in the order expected by the deployed SCs arguments order. + /// + /// Indexes start from 0 #[init] - fn init(&self, farm_template_address: ManagedAddress) { + fn init( + &self, + template_address: ManagedAddress, + forced_deploy_args: ForcedDeployArgsType, + ) { require!( - self.blockchain().is_smart_contract(&farm_template_address), + self.blockchain().is_smart_contract(&template_address), "Invalid farm template address" ); - self.farm_template_address().set(&farm_template_address); + self.overwrite_forced_deploy_args(forced_deploy_args); + + self.template_address().set(template_address); } #[upgrade] diff --git a/dex/proxy-deployer/src/storage.rs b/dex/proxy-deployer/src/storage.rs new file mode 100644 index 000000000..21c42dc41 --- /dev/null +++ b/dex/proxy-deployer/src/storage.rs @@ -0,0 +1,25 @@ +use crate::deploy::ForcedDeployArg; + +multiversx_sc::imports!(); + +#[multiversx_sc::module] +pub trait StorageModule { + #[view(getTemplateAddress)] + #[storage_mapper("templateAddress")] + fn template_address(&self) -> SingleValueMapper; + + #[storage_mapper("addressId")] + fn address_id(&self) -> AddressToIdMapper; + + #[storage_mapper("addrForTok")] + fn address_for_token(&self, token_id: &TokenIdentifier) -> SingleValueMapper; + + #[storage_mapper("allUsedTokens")] + fn all_used_tokens(&self) -> UnorderedSetMapper; + + #[storage_mapper("allDeployedContracts")] + fn all_deployed_contracts(&self) -> UnorderedSetMapper; + + #[storage_mapper("forcedDeployArgs")] + fn forced_deploy_args(&self) -> SingleValueMapper>>; +} diff --git a/dex/proxy-deployer/src/views.rs b/dex/proxy-deployer/src/views.rs new file mode 100644 index 000000000..b9ec9ddd1 --- /dev/null +++ b/dex/proxy-deployer/src/views.rs @@ -0,0 +1,81 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +#[multiversx_sc::module] +pub trait ViewModule: crate::storage::StorageModule { + #[view(getAddressForToken)] + fn get_address_for_token(&self, token_id: TokenIdentifier) -> OptionalValue { + let mapper = self.address_for_token(&token_id); + if mapper.is_empty() { + return OptionalValue::None; + } + + let id = mapper.get(); + let addr = self.get_by_id(&self.address_id(), id); + + OptionalValue::Some(addr) + } + + /// Indexes start at 1 + #[view(getAllUsedTokens)] + fn get_all_used_tokens( + &self, + start_index: usize, + max_entries: usize, + ) -> MultiValueEncoded { + let mapper = self.all_used_tokens(); + self.get_entries(&mapper, start_index, max_entries) + } + + /// Indexes start at 1 + #[view(getAllDeployedContracts)] + fn get_all_deployed_contracts( + &self, + start_index: usize, + max_entries: usize, + ) -> MultiValueEncoded { + let mapper = self.all_deployed_contracts(); + let ids = self.get_entries(&mapper, start_index, max_entries); + + let id_mapper = self.address_id(); + let mut result = MultiValueEncoded::new(); + for id in ids { + let address = self.get_by_id(&id_mapper, id); + result.push(address); + } + + result + } + + fn get_entries( + &self, + mapper: &UnorderedSetMapper, + start_index: usize, + max_entries: usize, + ) -> MultiValueEncoded { + require!(start_index > 0, "Invalid start index"); + + let mut items = MultiValueEncoded::new(); + let mut current_index = start_index; + let mapper_len = mapper.len(); + for _ in 0..max_entries { + if current_index > mapper_len { + break; + } + + let current_item = mapper.get_by_index(current_index); + items.push(current_item); + + current_index += 1; + } + + items + } + + fn get_by_id(&self, id_mapper: &AddressToIdMapper, id: AddressId) -> ManagedAddress { + let opt_address = id_mapper.get_address(id); + require!(opt_address.is_some(), "Invalid setup"); + + unsafe { opt_address.unwrap_unchecked() } + } +} diff --git a/dex/proxy-deployer/wasm/src/lib.rs b/dex/proxy-deployer/wasm/src/lib.rs index 620fcb058..ec41a1894 100644 --- a/dex/proxy-deployer/wasm/src/lib.rs +++ b/dex/proxy-deployer/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 4 +// Endpoints: 6 // Async Callback (empty): 1 -// Total number of exported functions: 7 +// Total number of exported functions: 9 #![no_std] @@ -20,10 +20,12 @@ multiversx_sc_wasm_adapter::endpoints! { ( init => init upgrade => upgrade - deployFarm => deploy_farm - callFarmEndpoint => call_farm_endpoint - getAllDeployedFarms => get_all_deployed_farms - getDeployerFarmAddresses => deployer_farm_addresses + overwriteForcedDeployArgs => overwrite_forced_deploy_args + deployContract => deploy_contract + getTemplateAddress => template_address + getAddressForToken => get_address_for_token + getAllUsedTokens => get_all_used_tokens + getAllDeployedContracts => get_all_deployed_contracts ) } From 0bedd08b4087c0c699f083d57c79e697c3884e85 Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Wed, 27 Nov 2024 09:32:03 +0200 Subject: [PATCH 08/23] change deployer impl --- Cargo.lock | 6 +- dex/proxy-deployer/Cargo.toml | 18 ++-- dex/proxy-deployer/elrond.json | 3 - dex/proxy-deployer/src/deploy.rs | 150 +++++++++-------------------- dex/proxy-deployer/src/lib.rs | 17 +--- dex/proxy-deployer/src/storage.rs | 17 +++- dex/proxy-deployer/wasm/Cargo.lock | 38 +++++++- dex/proxy-deployer/wasm/src/lib.rs | 4 +- 8 files changed, 107 insertions(+), 146 deletions(-) delete mode 100644 dex/proxy-deployer/elrond.json diff --git a/Cargo.lock b/Cargo.lock index 4ac1016f6..04e14f925 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1558,13 +1558,11 @@ dependencies = [ name = "proxy-deployer" version = "0.0.0" dependencies = [ - "config", - "farm", - "farm_token", + "common_structs", + "farm-staking", "multiversx-sc", "multiversx-sc-scenario", "num-bigint", - "pausable", ] [[package]] diff --git a/dex/proxy-deployer/Cargo.toml b/dex/proxy-deployer/Cargo.toml index d703dda15..0d3941758 100644 --- a/dex/proxy-deployer/Cargo.toml +++ b/dex/proxy-deployer/Cargo.toml @@ -8,22 +8,16 @@ publish = false [lib] path = "src/lib.rs" -[dependencies.farm] -path = "../farm" - -[dependencies.pausable] -path = "../../common/modules/pausable" - -[dependencies.config] -path = "../../common/modules/farm/config" - -[dependencies.farm_token] -path = "../../common/modules/farm/farm_token" - [dependencies.multiversx-sc] version = "=0.53.2" features = ["esdt-token-payment-legacy-decode"] +[dependencies.farm-staking] +path = "../../farm-staking/farm-staking" + +[dependencies.common_structs] +path = "../../common/common_structs" + [dev-dependencies] num-bigint = "0.4.2" diff --git a/dex/proxy-deployer/elrond.json b/dex/proxy-deployer/elrond.json deleted file mode 100644 index 736553962..000000000 --- a/dex/proxy-deployer/elrond.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "language": "rust" -} \ No newline at end of file diff --git a/dex/proxy-deployer/src/deploy.rs b/dex/proxy-deployer/src/deploy.rs index e88d347e1..d10740e79 100644 --- a/dex/proxy-deployer/src/deploy.rs +++ b/dex/proxy-deployer/src/deploy.rs @@ -1,134 +1,78 @@ +use common_structs::Epoch; + +use crate::storage::DeployerType; + multiversx_sc::imports!(); multiversx_sc::derive_imports!(); -#[derive(TypeAbi, TopEncode, TopDecode, NestedEncode, NestedDecode, ManagedVecItem)] -pub struct ForcedDeployArg { - pub arg_nr: usize, - pub value: ManagedBuffer, -} - -pub type ForcedDeployArgsType = MultiValueEncoded>>; +const DIVISION_SAFETY_CONST: u64 = 1_000_000_000_000_000_000; #[multiversx_sc::module] pub trait DeployModule: crate::storage::StorageModule { - /// Forced deploy args contain the index of the arg, and the argument itself. - /// - /// They must be provided in the order expected by the deployed SCs arguments order. - #[only_owner] - #[endpoint(overwriteForcedDeployArgs)] - fn overwrite_forced_deploy_args(&self, forced_deploy_args: ForcedDeployArgsType) { - let mut forced_args = ManagedVec::new(); - for forced_arg_multi in forced_deploy_args { - let (index, arg) = forced_arg_multi.into_tuple(); - let forced_arg = ForcedDeployArg { - arg_nr: index, - value: arg, - }; - forced_args.push(forced_arg); - } - - self.forced_deploy_args().set(forced_args); - } - - #[endpoint(deployContract)] - fn deploy_contract( + #[endpoint(deployFarmStakingContract)] + fn deploy_farm_staking_contract( &self, - token_used_by_sc: TokenIdentifier, - args: MultiValueEncoded, + farming_token_id: TokenIdentifier, + max_apr: BigUint, + min_unbond_epochs: Epoch, ) -> ManagedAddress { + self.require_correct_deployer_type(DeployerType::FarmStaking); require!( - !self.all_used_tokens().contains(&token_used_by_sc), + !self.all_used_tokens().contains(&farming_token_id), "Token already used" ); - let arg_buffer = self.prepare_deploy_args(args.into_vec_of_buffers()); - let deployed_sc_address = self.deploy_from_source(&arg_buffer); + let deployed_sc_address = self.deploy_farm_staking_from_source( + farming_token_id.clone(), + max_apr, + min_unbond_epochs, + ); let address_id = self.address_id().insert_new(&deployed_sc_address); let _ = self.all_deployed_contracts().insert(address_id); - self.address_for_token(&token_used_by_sc).set(address_id); + self.address_for_token(&farming_token_id).set(address_id); - let _ = self.all_used_tokens().insert(token_used_by_sc); + let _ = self.all_used_tokens().insert(farming_token_id); deployed_sc_address } - fn prepare_deploy_args( + fn deploy_farm_staking_from_source( &self, - provided_args: ManagedVec, - ) -> ManagedArgBuffer { - let mut arg_buffer = ManagedArgBuffer::new(); - - let mut forced_args = self.forced_deploy_args().get(); - let mut opt_current_forced_arg = self.get_next_forced_arg(&mut forced_args); - - let mut all_args_index = 0; - let mut provided_args_index = 0; - let provided_args_len = provided_args.len(); - while provided_args_index < provided_args_len { - if let Some(current_forced_arg) = &opt_current_forced_arg { - if current_forced_arg.arg_nr == all_args_index { - arg_buffer.push_arg_raw(current_forced_arg.value.clone()); - opt_current_forced_arg = self.get_next_forced_arg(&mut forced_args); - - all_args_index += 1; - - continue; - } - } - - let provided_arg = provided_args.get(provided_args_index); - arg_buffer.push_arg_raw((*provided_arg).clone()); - - provided_args_index += 1; - all_args_index += 1; - } - - while let Some(current_forced_arg) = &opt_current_forced_arg { - if current_forced_arg.arg_nr == all_args_index { - arg_buffer.push_arg_raw(current_forced_arg.value.clone()); - opt_current_forced_arg = self.get_next_forced_arg(&mut forced_args); - - all_args_index += 1; - } else { - break; - } - } + farming_token_id: TokenIdentifier, + max_apr: BigUint, + min_unbond_epochs: Epoch, + ) -> ManagedAddress { + let owner = self.blockchain().get_owner_address(); - // All contracts have the admins list as last argument let caller = self.blockchain().get_caller(); - arg_buffer.push_arg_raw(caller.as_managed_buffer().clone()); - - arg_buffer - } - - fn get_next_forced_arg( - &self, - forced_args: &mut ManagedVec>, - ) -> Option> { - if forced_args.is_empty() { - return None; - } - - let arg = forced_args.get(0); - forced_args.remove(0); + let mut admins = MultiValueEncoded::new(); + admins.push(caller); - Some(arg) - } - - fn deploy_from_source(&self, args: &ManagedArgBuffer) -> ManagedAddress { let template = self.template_address().get(); let code_metadata = CodeMetadata::PAYABLE_BY_SC | CodeMetadata::READABLE | CodeMetadata::UPGRADEABLE; - let gas_left = self.blockchain().get_gas_left(); - let (deployed_sc_address, _) = self.send_raw().deploy_from_source_contract( - gas_left, - &BigUint::zero(), - &template, - code_metadata, - args, - ); + + let (deployed_sc_address, ()) = self + .farm_staking_deploy_proxy() + .init( + farming_token_id, + DIVISION_SAFETY_CONST, + max_apr, + min_unbond_epochs, + owner, + admins, + ) + .deploy_from_source(&template, code_metadata); deployed_sc_address } + + fn require_correct_deployer_type(&self, requested_type: DeployerType) { + let deployer_type = self.deployer_type().get(); + require!(deployer_type == requested_type, "Invalid deployer type"); + } + + #[proxy] + fn farm_staking_deploy_proxy(&self) -> farm_staking::Proxy; } diff --git a/dex/proxy-deployer/src/lib.rs b/dex/proxy-deployer/src/lib.rs index 0e80e074c..088adc173 100644 --- a/dex/proxy-deployer/src/lib.rs +++ b/dex/proxy-deployer/src/lib.rs @@ -1,6 +1,6 @@ #![no_std] -use deploy::ForcedDeployArgsType; +use storage::DeployerType; multiversx_sc::imports!(); @@ -10,25 +10,16 @@ pub mod views; #[multiversx_sc::contract] pub trait ProxyDeployer: deploy::DeployModule + storage::StorageModule + views::ViewModule { - /// Forced deploy args contain the index of the arg, and the argument itself. - /// - /// They must be provided in the order expected by the deployed SCs arguments order. - /// - /// Indexes start from 0 #[init] - fn init( - &self, - template_address: ManagedAddress, - forced_deploy_args: ForcedDeployArgsType, - ) { + fn init(&self, template_address: ManagedAddress, deployer_type: DeployerType) { require!( self.blockchain().is_smart_contract(&template_address), "Invalid farm template address" ); - - self.overwrite_forced_deploy_args(forced_deploy_args); + require!(deployer_type != DeployerType::None, "Invalid deployer type"); self.template_address().set(template_address); + self.deployer_type().set(deployer_type); } #[upgrade] diff --git a/dex/proxy-deployer/src/storage.rs b/dex/proxy-deployer/src/storage.rs index 21c42dc41..88617e46e 100644 --- a/dex/proxy-deployer/src/storage.rs +++ b/dex/proxy-deployer/src/storage.rs @@ -1,9 +1,19 @@ -use crate::deploy::ForcedDeployArg; - multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +#[derive(TypeAbi, TopEncode, TopDecode, Clone, Copy, PartialEq)] +pub enum DeployerType { + None, + FarmStaking, + FarmWithTopUp, +} #[multiversx_sc::module] pub trait StorageModule { + #[view(getDeployerType)] + #[storage_mapper("deployerType")] + fn deployer_type(&self) -> SingleValueMapper; + #[view(getTemplateAddress)] #[storage_mapper("templateAddress")] fn template_address(&self) -> SingleValueMapper; @@ -19,7 +29,4 @@ pub trait StorageModule { #[storage_mapper("allDeployedContracts")] fn all_deployed_contracts(&self) -> UnorderedSetMapper; - - #[storage_mapper("forcedDeployArgs")] - fn forced_deploy_args(&self) -> SingleValueMapper>>; } diff --git a/dex/proxy-deployer/wasm/Cargo.lock b/dex/proxy-deployer/wasm/Cargo.lock index d012a5597..f53b5cfd9 100644 --- a/dex/proxy-deployer/wasm/Cargo.lock +++ b/dex/proxy-deployer/wasm/Cargo.lock @@ -158,6 +158,38 @@ dependencies = [ "weekly-rewards-splitting", ] +[[package]] +name = "farm-staking" +version = "0.0.0" +dependencies = [ + "common_errors", + "common_structs", + "config", + "contexts", + "energy-factory", + "energy-query", + "events", + "farm", + "farm-boosted-yields", + "farm_base_impl", + "farm_token", + "fixed-supply-token", + "math", + "mergeable", + "multiversx-sc", + "multiversx-sc-modules", + "pair", + "pausable", + "permissions-hub", + "permissions_module", + "rewards", + "sc_whitelist_module", + "token_send", + "utils", + "week-timekeeping", + "weekly-rewards-splitting", +] + [[package]] name = "farm_base_impl" version = "0.0.0" @@ -407,11 +439,9 @@ dependencies = [ name = "proxy-deployer" version = "0.0.0" dependencies = [ - "config", - "farm", - "farm_token", + "common_structs", + "farm-staking", "multiversx-sc", - "pausable", ] [[package]] diff --git a/dex/proxy-deployer/wasm/src/lib.rs b/dex/proxy-deployer/wasm/src/lib.rs index ec41a1894..1d559d6dd 100644 --- a/dex/proxy-deployer/wasm/src/lib.rs +++ b/dex/proxy-deployer/wasm/src/lib.rs @@ -20,8 +20,8 @@ multiversx_sc_wasm_adapter::endpoints! { ( init => init upgrade => upgrade - overwriteForcedDeployArgs => overwrite_forced_deploy_args - deployContract => deploy_contract + deployFarmStakingContract => deploy_farm_staking_contract + getDeployerType => deployer_type getTemplateAddress => template_address getAddressForToken => get_address_for_token getAllUsedTokens => get_all_used_tokens From d5881f72718b22d0f65dfa9275f0c18b380ac7b7 Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Wed, 27 Nov 2024 10:02:53 +0200 Subject: [PATCH 09/23] more views, more storage, todo --- Cargo.lock | 1 + dex/proxy-deployer/Cargo.toml | 3 ++ dex/proxy-deployer/src/deploy.rs | 23 +++++++--- dex/proxy-deployer/src/lib.rs | 8 +++- dex/proxy-deployer/src/remove_contracts.rs | 26 +++++++++++ dex/proxy-deployer/src/storage.rs | 6 +++ dex/proxy-deployer/src/views.rs | 53 ++++++++++++++++++++-- dex/proxy-deployer/wasm/Cargo.lock | 1 + dex/proxy-deployer/wasm/src/lib.rs | 9 ++-- 9 files changed, 115 insertions(+), 15 deletions(-) create mode 100644 dex/proxy-deployer/src/remove_contracts.rs diff --git a/Cargo.lock b/Cargo.lock index 04e14f925..1cbd44336 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1563,6 +1563,7 @@ dependencies = [ "multiversx-sc", "multiversx-sc-scenario", "num-bigint", + "permissions_module", ] [[package]] diff --git a/dex/proxy-deployer/Cargo.toml b/dex/proxy-deployer/Cargo.toml index 0d3941758..4d46d90a6 100644 --- a/dex/proxy-deployer/Cargo.toml +++ b/dex/proxy-deployer/Cargo.toml @@ -18,6 +18,9 @@ path = "../../farm-staking/farm-staking" [dependencies.common_structs] path = "../../common/common_structs" +[dependencies.permissions_module] +path = "../../common/modules/permissions_module" + [dev-dependencies] num-bigint = "0.4.2" diff --git a/dex/proxy-deployer/src/deploy.rs b/dex/proxy-deployer/src/deploy.rs index d10740e79..76861a626 100644 --- a/dex/proxy-deployer/src/deploy.rs +++ b/dex/proxy-deployer/src/deploy.rs @@ -27,12 +27,7 @@ pub trait DeployModule: crate::storage::StorageModule { max_apr, min_unbond_epochs, ); - - let address_id = self.address_id().insert_new(&deployed_sc_address); - let _ = self.all_deployed_contracts().insert(address_id); - self.address_for_token(&farming_token_id).set(address_id); - - let _ = self.all_used_tokens().insert(farming_token_id); + self.add_new_contract(&deployed_sc_address, farming_token_id); deployed_sc_address } @@ -68,6 +63,22 @@ pub trait DeployModule: crate::storage::StorageModule { deployed_sc_address } + fn add_new_contract( + &self, + deployed_sc_address: &ManagedAddress, + farming_token_id: TokenIdentifier, + ) { + let contract_id = self.address_id().insert_new(deployed_sc_address); + let _ = self.all_deployed_contracts().insert(contract_id); + self.address_for_token(&farming_token_id).set(contract_id); + let _ = self.all_used_tokens().insert(farming_token_id); + + let caller = self.blockchain().get_caller(); + let caller_id = self.address_id().get_id_or_insert(&caller); + let _ = self.contracts_by_address(caller_id).insert(contract_id); + self.contract_owner(contract_id).set(caller_id); + } + fn require_correct_deployer_type(&self, requested_type: DeployerType) { let deployer_type = self.deployer_type().get(); require!(deployer_type == requested_type, "Invalid deployer type"); diff --git a/dex/proxy-deployer/src/lib.rs b/dex/proxy-deployer/src/lib.rs index 088adc173..ad174fed6 100644 --- a/dex/proxy-deployer/src/lib.rs +++ b/dex/proxy-deployer/src/lib.rs @@ -5,11 +5,17 @@ use storage::DeployerType; multiversx_sc::imports!(); pub mod deploy; +pub mod remove_contracts; pub mod storage; pub mod views; #[multiversx_sc::contract] -pub trait ProxyDeployer: deploy::DeployModule + storage::StorageModule + views::ViewModule { +pub trait ProxyDeployer: + deploy::DeployModule + + remove_contracts::RemoveContractsModule + + storage::StorageModule + + views::ViewModule +{ #[init] fn init(&self, template_address: ManagedAddress, deployer_type: DeployerType) { require!( diff --git a/dex/proxy-deployer/src/remove_contracts.rs b/dex/proxy-deployer/src/remove_contracts.rs new file mode 100644 index 000000000..986b83115 --- /dev/null +++ b/dex/proxy-deployer/src/remove_contracts.rs @@ -0,0 +1,26 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +#[derive(TypeAbi, TopEncode)] +pub struct RemoveResult { + pub any_farms_left: bool, +} + +#[multiversx_sc::module] +pub trait RemoveContractsModule: crate::storage::StorageModule { + #[only_owner] + #[endpoint(removeAllByDeployer)] + fn remove_all_by_deployer( + &self, + deployer_address: ManagedAddress, + max_farms_to_remove: usize, + ) -> RemoveResult { + // TODO: Remove admin from farm/farm_staking, then remove the farm/farm_staking from internal storage + + // TODO: Maybe also blacklist user? + + RemoveResult { + any_farms_left: false, + } + } +} diff --git a/dex/proxy-deployer/src/storage.rs b/dex/proxy-deployer/src/storage.rs index 88617e46e..56ce09129 100644 --- a/dex/proxy-deployer/src/storage.rs +++ b/dex/proxy-deployer/src/storage.rs @@ -21,6 +21,12 @@ pub trait StorageModule { #[storage_mapper("addressId")] fn address_id(&self) -> AddressToIdMapper; + #[storage_mapper("contractOwner")] + fn contract_owner(&self, contract_id: AddressId) -> SingleValueMapper; + + #[storage_mapper("contractByAddress")] + fn contracts_by_address(&self, address_id: AddressId) -> UnorderedSetMapper; + #[storage_mapper("addrForTok")] fn address_for_token(&self, token_id: &TokenIdentifier) -> SingleValueMapper; diff --git a/dex/proxy-deployer/src/views.rs b/dex/proxy-deployer/src/views.rs index b9ec9ddd1..0b54d4370 100644 --- a/dex/proxy-deployer/src/views.rs +++ b/dex/proxy-deployer/src/views.rs @@ -16,6 +16,24 @@ pub trait ViewModule: crate::storage::StorageModule { OptionalValue::Some(addr) } + #[view(getContractOwner)] + fn get_contract_owner( + &self, + contract_address: ManagedAddress, + ) -> OptionalValue { + let contract_id = self.address_id().get_id(&contract_address); + if contract_id == 0 { + return OptionalValue::None; + } + + let owner_id = self.contract_owner(contract_id).get(); + let opt_address = self.address_id().get_address(owner_id); + match opt_address { + Some(addr) => OptionalValue::Some(addr), + None => OptionalValue::None, + } + } + /// Indexes start at 1 #[view(getAllUsedTokens)] fn get_all_used_tokens( @@ -28,19 +46,44 @@ pub trait ViewModule: crate::storage::StorageModule { } /// Indexes start at 1 - #[view(getAllDeployedContracts)] - fn get_all_deployed_contracts( + #[view(getAllDeployedContractsBySc)] + fn get_all_deployed_contracts_by_sc( &self, start_index: usize, max_entries: usize, ) -> MultiValueEncoded { + let id_mapper = self.address_id(); let mapper = self.all_deployed_contracts(); - let ids = self.get_entries(&mapper, start_index, max_entries); + let contract_ids = self.get_entries(&mapper, start_index, max_entries); + + let mut result = MultiValueEncoded::new(); + for contract_id in contract_ids { + let address = self.get_by_id(&id_mapper, contract_id); + result.push(address); + } + + result + } + #[view(getAllDeployedContractsByUser)] + fn get_all_deployed_contracts_by_user( + &self, + user: ManagedAddress, + start_index: usize, + max_entries: usize, + ) -> MultiValueEncoded { let id_mapper = self.address_id(); + let user_id = id_mapper.get_id(&user); + if user_id == 0 { + return MultiValueEncoded::new(); + } + + let mapper = self.contracts_by_address(user_id); + let contract_ids = self.get_entries(&mapper, start_index, max_entries); + let mut result = MultiValueEncoded::new(); - for id in ids { - let address = self.get_by_id(&id_mapper, id); + for contract_id in contract_ids { + let address = self.get_by_id(&id_mapper, contract_id); result.push(address); } diff --git a/dex/proxy-deployer/wasm/Cargo.lock b/dex/proxy-deployer/wasm/Cargo.lock index f53b5cfd9..c742b6af0 100644 --- a/dex/proxy-deployer/wasm/Cargo.lock +++ b/dex/proxy-deployer/wasm/Cargo.lock @@ -442,6 +442,7 @@ dependencies = [ "common_structs", "farm-staking", "multiversx-sc", + "permissions_module", ] [[package]] diff --git a/dex/proxy-deployer/wasm/src/lib.rs b/dex/proxy-deployer/wasm/src/lib.rs index 1d559d6dd..35a25232e 100644 --- a/dex/proxy-deployer/wasm/src/lib.rs +++ b/dex/proxy-deployer/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 6 +// Endpoints: 9 // Async Callback (empty): 1 -// Total number of exported functions: 9 +// Total number of exported functions: 12 #![no_std] @@ -21,11 +21,14 @@ multiversx_sc_wasm_adapter::endpoints! { init => init upgrade => upgrade deployFarmStakingContract => deploy_farm_staking_contract + removeAllByDeployer => remove_all_by_deployer getDeployerType => deployer_type getTemplateAddress => template_address getAddressForToken => get_address_for_token + getContractOwner => get_contract_owner getAllUsedTokens => get_all_used_tokens - getAllDeployedContracts => get_all_deployed_contracts + getAllDeployedContractsBySc => get_all_deployed_contracts_by_sc + getAllDeployedContractsByUser => get_all_deployed_contracts_by_user ) } From 76f1a4d955d534ac28328ab8358ad116ee947425 Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Wed, 27 Nov 2024 10:38:36 +0200 Subject: [PATCH 10/23] move test to separate file --- .../weekly-rewards-splitting/src/lib.rs | 57 ------------------- .../tests/encode_decode_test.rs | 57 +++++++++++++++++++ 2 files changed, 57 insertions(+), 57 deletions(-) create mode 100644 energy-integration/common-modules/weekly-rewards-splitting/tests/encode_decode_test.rs diff --git a/energy-integration/common-modules/weekly-rewards-splitting/src/lib.rs b/energy-integration/common-modules/weekly-rewards-splitting/src/lib.rs index 52c71d4dc..5b6686739 100644 --- a/energy-integration/common-modules/weekly-rewards-splitting/src/lib.rs +++ b/energy-integration/common-modules/weekly-rewards-splitting/src/lib.rs @@ -184,60 +184,3 @@ pub trait WeeklyRewardsSplittingModule: } } } - -#[cfg(test)] -mod tests { - use multiversx_sc_scenario::{managed_biguint, DebugApi}; - - use super::*; - - #[derive(TypeAbi, TopEncode, Clone, PartialEq, Debug)] - pub struct OldClaimProgress { - pub energy: Energy, - pub week: Week, - } - - #[test] - fn decode_old_claim_progress_to_new_test() { - DebugApi::dummy(); - - let old_progress = OldClaimProgress { - energy: Energy::new(BigInt::::zero(), 10, managed_biguint!(20)), - week: 2, - }; - let mut old_progress_encoded = ManagedBuffer::::new(); - let _ = old_progress.top_encode(&mut old_progress_encoded); - - let new_progress_decoded = ClaimProgress::top_decode(old_progress_encoded).unwrap(); - assert_eq!( - new_progress_decoded, - ClaimProgress { - energy: Energy::new(BigInt::::zero(), 10, managed_biguint!(20)), - week: 2, - enter_timestamp: 0, - } - ); - } - - #[test] - fn encoded_decode_new_progress_test() { - DebugApi::dummy(); - - let new_progress = ClaimProgress { - energy: Energy::new(BigInt::::zero(), 10, managed_biguint!(20)), - week: 2, - enter_timestamp: 0, - }; - let mut new_progress_encoded = ManagedBuffer::::new(); - let _ = new_progress.top_encode(&mut new_progress_encoded); - let new_progress_decoded = ClaimProgress::top_decode(new_progress_encoded).unwrap(); - assert_eq!( - new_progress_decoded, - ClaimProgress { - energy: Energy::new(BigInt::::zero(), 10, managed_biguint!(20)), - week: 2, - enter_timestamp: 0, - } - ); - } -} diff --git a/energy-integration/common-modules/weekly-rewards-splitting/tests/encode_decode_test.rs b/energy-integration/common-modules/weekly-rewards-splitting/tests/encode_decode_test.rs new file mode 100644 index 000000000..0d917c71c --- /dev/null +++ b/energy-integration/common-modules/weekly-rewards-splitting/tests/encode_decode_test.rs @@ -0,0 +1,57 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +use common_structs::Week; +use energy_query::Energy; +use multiversx_sc_scenario::{managed_biguint, DebugApi}; +use weekly_rewards_splitting::ClaimProgress; + +#[derive(TypeAbi, TopEncode, Clone, PartialEq, Debug)] +pub struct OldClaimProgress { + pub energy: Energy, + pub week: Week, +} + +#[test] +fn decode_old_claim_progress_to_new_test() { + DebugApi::dummy(); + + let old_progress = OldClaimProgress { + energy: Energy::new(BigInt::::zero(), 10, managed_biguint!(20)), + week: 2, + }; + let mut old_progress_encoded = ManagedBuffer::::new(); + let _ = old_progress.top_encode(&mut old_progress_encoded); + + let new_progress_decoded = ClaimProgress::top_decode(old_progress_encoded).unwrap(); + assert_eq!( + new_progress_decoded, + ClaimProgress { + energy: Energy::new(BigInt::::zero(), 10, managed_biguint!(20)), + week: 2, + enter_timestamp: 0, + } + ); +} + +#[test] +fn encoded_decode_new_progress_test() { + DebugApi::dummy(); + + let new_progress = ClaimProgress { + energy: Energy::new(BigInt::::zero(), 10, managed_biguint!(20)), + week: 2, + enter_timestamp: 0, + }; + let mut new_progress_encoded = ManagedBuffer::::new(); + let _ = new_progress.top_encode(&mut new_progress_encoded); + let new_progress_decoded = ClaimProgress::top_decode(new_progress_encoded).unwrap(); + assert_eq!( + new_progress_decoded, + ClaimProgress { + energy: Energy::new(BigInt::::zero(), 10, managed_biguint!(20)), + week: 2, + enter_timestamp: 0, + } + ); +} From a250f01115effa840f1d44aa65dcd4806b8616ed Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Wed, 27 Nov 2024 11:26:03 +0200 Subject: [PATCH 11/23] removing options --- dex/proxy-deployer/src/deploy.rs | 22 +++++++++-- dex/proxy-deployer/src/remove_contracts.rs | 43 ++++++++++++++++++++-- dex/proxy-deployer/src/storage.rs | 13 +++++++ dex/proxy-deployer/src/views.rs | 27 ++++++++++---- dex/proxy-deployer/wasm/src/lib.rs | 5 ++- 5 files changed, 93 insertions(+), 17 deletions(-) diff --git a/dex/proxy-deployer/src/deploy.rs b/dex/proxy-deployer/src/deploy.rs index 76861a626..d4525178c 100644 --- a/dex/proxy-deployer/src/deploy.rs +++ b/dex/proxy-deployer/src/deploy.rs @@ -22,25 +22,38 @@ pub trait DeployModule: crate::storage::StorageModule { "Token already used" ); + let caller = self.get_caller_not_blacklisted(); let deployed_sc_address = self.deploy_farm_staking_from_source( + caller.clone(), farming_token_id.clone(), max_apr, min_unbond_epochs, ); - self.add_new_contract(&deployed_sc_address, farming_token_id); + self.add_new_contract(&caller, &deployed_sc_address, farming_token_id); deployed_sc_address } + fn get_caller_not_blacklisted(&self) -> ManagedAddress { + let caller = self.blockchain().get_caller(); + let caller_id = self.address_id().get_id_or_insert(&caller); + require!( + !self.user_blacklist().contains(&caller_id), + "user blacklisted" + ); + + caller + } + fn deploy_farm_staking_from_source( &self, + caller: ManagedAddress, farming_token_id: TokenIdentifier, max_apr: BigUint, min_unbond_epochs: Epoch, ) -> ManagedAddress { let owner = self.blockchain().get_owner_address(); - let caller = self.blockchain().get_caller(); let mut admins = MultiValueEncoded::new(); admins.push(caller); @@ -65,16 +78,17 @@ pub trait DeployModule: crate::storage::StorageModule { fn add_new_contract( &self, + caller: &ManagedAddress, deployed_sc_address: &ManagedAddress, farming_token_id: TokenIdentifier, ) { let contract_id = self.address_id().insert_new(deployed_sc_address); let _ = self.all_deployed_contracts().insert(contract_id); self.address_for_token(&farming_token_id).set(contract_id); + self.token_for_address(contract_id).set(&farming_token_id); let _ = self.all_used_tokens().insert(farming_token_id); - let caller = self.blockchain().get_caller(); - let caller_id = self.address_id().get_id_or_insert(&caller); + let caller_id = self.address_id().get_id_non_zero(caller); let _ = self.contracts_by_address(caller_id).insert(contract_id); self.contract_owner(contract_id).set(caller_id); } diff --git a/dex/proxy-deployer/src/remove_contracts.rs b/dex/proxy-deployer/src/remove_contracts.rs index 986b83115..e407394bc 100644 --- a/dex/proxy-deployer/src/remove_contracts.rs +++ b/dex/proxy-deployer/src/remove_contracts.rs @@ -1,6 +1,8 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); +use permissions_module::ProxyTrait as _; + #[derive(TypeAbi, TopEncode)] pub struct RemoveResult { pub any_farms_left: bool, @@ -13,14 +15,47 @@ pub trait RemoveContractsModule: crate::storage::StorageModule { fn remove_all_by_deployer( &self, deployer_address: ManagedAddress, - max_farms_to_remove: usize, + max_to_remove: usize, ) -> RemoveResult { - // TODO: Remove admin from farm/farm_staking, then remove the farm/farm_staking from internal storage + let id_mapper = self.address_id(); + let deployer_id = id_mapper.get_id_non_zero(&deployer_address); + self.user_blacklist().add(&deployer_id); + + let mut contracts_mapper = self.contracts_by_address(deployer_id); - // TODO: Maybe also blacklist user? + let total_contracts = contracts_mapper.len(); + let to_remove = core::cmp::min(total_contracts, max_to_remove); + for _ in 0..to_remove { + let contract_id = contracts_mapper.get_by_index(0); + let contract_address = self.get_by_id(&id_mapper, contract_id); + let _ = contracts_mapper.swap_remove(&contract_id); + + self.remove_admin(contract_address, deployer_address.clone()); + self.remove_contract(contract_id); + } RemoveResult { - any_farms_left: false, + any_farms_left: total_contracts > max_to_remove, } } + + fn remove_admin(&self, contract: ManagedAddress, user: ManagedAddress) { + self.remove_user_proxy(contract) + .remove_admin_endpoint(user) + .execute_on_dest_context() + } + + fn remove_contract(&self, contract_id: AddressId) { + let _ = self.all_deployed_contracts().swap_remove(&contract_id); + let token_for_address = self.token_for_address(contract_id).take(); + let _ = self.all_used_tokens().swap_remove(&token_for_address); + self.address_for_token(&token_for_address).clear(); + self.contract_owner(contract_id).clear(); + } + + // For now, both farm and farm_staking use the same internal permissions module. + // + // Create two separate proxies if this if this ever changes. + #[proxy] + fn remove_user_proxy(&self, sc_address: ManagedAddress) -> farm_staking::Proxy; } diff --git a/dex/proxy-deployer/src/storage.rs b/dex/proxy-deployer/src/storage.rs index 56ce09129..208d8810f 100644 --- a/dex/proxy-deployer/src/storage.rs +++ b/dex/proxy-deployer/src/storage.rs @@ -10,6 +10,13 @@ pub enum DeployerType { #[multiversx_sc::module] pub trait StorageModule { + fn get_by_id(&self, id_mapper: &AddressToIdMapper, id: AddressId) -> ManagedAddress { + let opt_address = id_mapper.get_address(id); + require!(opt_address.is_some(), "Invalid setup"); + + unsafe { opt_address.unwrap_unchecked() } + } + #[view(getDeployerType)] #[storage_mapper("deployerType")] fn deployer_type(&self) -> SingleValueMapper; @@ -30,9 +37,15 @@ pub trait StorageModule { #[storage_mapper("addrForTok")] fn address_for_token(&self, token_id: &TokenIdentifier) -> SingleValueMapper; + #[storage_mapper("tokForAddr")] + fn token_for_address(&self, address_id: AddressId) -> SingleValueMapper; + #[storage_mapper("allUsedTokens")] fn all_used_tokens(&self) -> UnorderedSetMapper; #[storage_mapper("allDeployedContracts")] fn all_deployed_contracts(&self) -> UnorderedSetMapper; + + #[storage_mapper("userBlacklist")] + fn user_blacklist(&self) -> WhitelistMapper; } diff --git a/dex/proxy-deployer/src/views.rs b/dex/proxy-deployer/src/views.rs index 0b54d4370..5f5bcc73d 100644 --- a/dex/proxy-deployer/src/views.rs +++ b/dex/proxy-deployer/src/views.rs @@ -16,6 +16,26 @@ pub trait ViewModule: crate::storage::StorageModule { OptionalValue::Some(addr) } + #[view(getTokenForAddress)] + fn get_token_for_address( + &self, + contract_address: ManagedAddress, + ) -> OptionalValue { + let contract_id = self.address_id().get_id(&contract_address); + if contract_id == 0 { + return OptionalValue::None; + } + + let mapper = self.token_for_address(contract_id); + if mapper.is_empty() { + return OptionalValue::None; + } + + let token_id = mapper.get(); + + OptionalValue::Some(token_id) + } + #[view(getContractOwner)] fn get_contract_owner( &self, @@ -114,11 +134,4 @@ pub trait ViewModule: crate::storage::StorageModule { items } - - fn get_by_id(&self, id_mapper: &AddressToIdMapper, id: AddressId) -> ManagedAddress { - let opt_address = id_mapper.get_address(id); - require!(opt_address.is_some(), "Invalid setup"); - - unsafe { opt_address.unwrap_unchecked() } - } } diff --git a/dex/proxy-deployer/wasm/src/lib.rs b/dex/proxy-deployer/wasm/src/lib.rs index 35a25232e..0c0b81935 100644 --- a/dex/proxy-deployer/wasm/src/lib.rs +++ b/dex/proxy-deployer/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 9 +// Endpoints: 10 // Async Callback (empty): 1 -// Total number of exported functions: 12 +// Total number of exported functions: 13 #![no_std] @@ -25,6 +25,7 @@ multiversx_sc_wasm_adapter::endpoints! { getDeployerType => deployer_type getTemplateAddress => template_address getAddressForToken => get_address_for_token + getTokenForAddress => get_token_for_address getContractOwner => get_contract_owner getAllUsedTokens => get_all_used_tokens getAllDeployedContractsBySc => get_all_deployed_contracts_by_sc From b2291f4e5d7b4089f9f06d102533ba537336bcfe Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Wed, 27 Nov 2024 13:10:33 +0200 Subject: [PATCH 12/23] test setup --- .../proxy_deployer_farm_staking_setup/mod.rs | 62 +++++++++++++++++++ .../proxy_deployer_farm_staking_tests.rs | 11 ++++ 2 files changed, 73 insertions(+) create mode 100644 dex/proxy-deployer/tests/proxy_deployer_farm_staking_setup/mod.rs create mode 100644 dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs diff --git a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_setup/mod.rs b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_setup/mod.rs new file mode 100644 index 000000000..1a6f988c8 --- /dev/null +++ b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_setup/mod.rs @@ -0,0 +1,62 @@ +use multiversx_sc::types::Address; +use multiversx_sc_scenario::{ + imports::{BlockchainStateWrapper, ContractObjWrapper}, + managed_address, rust_biguint, DebugApi, +}; +use proxy_deployer::{storage::DeployerType, ProxyDeployer}; + +pub struct ProxyDeployerFarmStakingSetup +where + ProxyDeployerBuilder: 'static + Copy + Fn() -> proxy_deployer::ContractObj, + FarmStakingBuilder: 'static + Copy + Fn() -> farm_staking::ContractObj, +{ + pub b_mock: BlockchainStateWrapper, + pub owner: Address, + pub user: Address, + pub proxy_deployer_wrapper: + ContractObjWrapper, ProxyDeployerBuilder>, + pub template_wrapper: + ContractObjWrapper, FarmStakingBuilder>, +} + +impl + ProxyDeployerFarmStakingSetup +where + ProxyDeployerBuilder: 'static + Copy + Fn() -> proxy_deployer::ContractObj, + FarmStakingBuilder: 'static + Copy + Fn() -> farm_staking::ContractObj, +{ + pub fn new( + proxy_builder: ProxyDeployerBuilder, + farm_staking_builder: FarmStakingBuilder, + ) -> Self { + let rust_zero = rust_biguint!(0); + let mut b_mock = BlockchainStateWrapper::new(); + let owner = b_mock.create_user_account(&rust_zero); + let user = b_mock.create_user_account(&rust_zero); + let proxy_deployer_wrapper = + b_mock.create_sc_account(&rust_zero, Some(&owner), proxy_builder, "proxy deployer"); + let template_wrapper = b_mock.create_sc_account( + &rust_zero, + Some(&owner), + farm_staking_builder, + "farm staking template", + ); + + b_mock + .execute_tx(&owner, &proxy_deployer_wrapper, &rust_zero, |sc| { + sc.init( + managed_address!(template_wrapper.address_ref()), + DeployerType::FarmStaking, + ); + }) + .assert_ok(); + + Self { + b_mock, + owner, + user, + proxy_deployer_wrapper, + template_wrapper, + } + } +} diff --git a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs new file mode 100644 index 000000000..284d313b0 --- /dev/null +++ b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs @@ -0,0 +1,11 @@ +use proxy_deployer_farm_staking_setup::ProxyDeployerFarmStakingSetup; + +pub mod proxy_deployer_farm_staking_setup; + +#[test] +fn setup_test() { + let _ = ProxyDeployerFarmStakingSetup::new( + proxy_deployer::contract_obj, + farm_staking::contract_obj, + ); +} From 58a1c5c6b909591e6d4c62798cc2de15669bf45a Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Wed, 27 Nov 2024 13:46:55 +0200 Subject: [PATCH 13/23] deploy farm staking test + changes in farms --- Cargo.lock | 2 + dex/farm-with-locked-rewards/src/lib.rs | 3 ++ dex/farm/src/lib.rs | 3 ++ .../farm_setup/farm_rewards_distr_setup.rs | 5 +-- .../tests/farm_setup/multi_user_farm_setup.rs | 4 +- .../farm_setup/single_user_farm_setup.rs | 5 +-- dex/proxy-deployer/Cargo.toml | 6 +++ dex/proxy-deployer/src/deploy.rs | 2 + dex/proxy-deployer/src/lib.rs | 14 +++++- dex/proxy-deployer/src/storage.rs | 3 ++ .../proxy_deployer_farm_staking_setup/mod.rs | 21 +++++++++ .../proxy_deployer_farm_staking_tests.rs | 44 +++++++++++++++++++ .../mod.rs | 3 +- .../mod.rs | 3 +- farm-staking/farm-staking/src/lib.rs | 3 ++ .../tests/farm_staking_setup/mod.rs | 4 +- 16 files changed, 106 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1cbd44336..fb6ea6ba9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1560,10 +1560,12 @@ version = "0.0.0" dependencies = [ "common_structs", "farm-staking", + "farm_token", "multiversx-sc", "multiversx-sc-scenario", "num-bigint", "permissions_module", + "timestamp-oracle", ] [[package]] diff --git a/dex/farm-with-locked-rewards/src/lib.rs b/dex/farm-with-locked-rewards/src/lib.rs index 30877509f..499dc993e 100644 --- a/dex/farm-with-locked-rewards/src/lib.rs +++ b/dex/farm-with-locked-rewards/src/lib.rs @@ -55,6 +55,7 @@ pub trait Farm: farming_token_id: TokenIdentifier, division_safety_constant: BigUint, owner: ManagedAddress, + timestamp_oracle_address: ManagedAddress, admins: MultiValueEncoded, ) { self.base_farm_init( @@ -65,6 +66,8 @@ pub trait Farm: admins, ); + self.set_timestamp_oracle_address(timestamp_oracle_address); + let current_epoch = self.blockchain().get_block_epoch(); self.first_week_start_epoch().set(current_epoch); diff --git a/dex/farm/src/lib.rs b/dex/farm/src/lib.rs index 4a211d10e..3e3a86e92 100644 --- a/dex/farm/src/lib.rs +++ b/dex/farm/src/lib.rs @@ -56,6 +56,7 @@ pub trait Farm: farming_token_id: TokenIdentifier, division_safety_constant: BigUint, owner: ManagedAddress, + timestamp_oracle_address: ManagedAddress, admins: MultiValueEncoded, ) { self.base_farm_init( @@ -66,6 +67,8 @@ pub trait Farm: admins, ); + self.set_timestamp_oracle_address(timestamp_oracle_address); + let current_epoch = self.blockchain().get_block_epoch(); self.first_week_start_epoch().set(current_epoch); } diff --git a/dex/farm/tests/farm_setup/farm_rewards_distr_setup.rs b/dex/farm/tests/farm_setup/farm_rewards_distr_setup.rs index 38ed867fd..23dada913 100644 --- a/dex/farm/tests/farm_setup/farm_rewards_distr_setup.rs +++ b/dex/farm/tests/farm_setup/farm_rewards_distr_setup.rs @@ -1,6 +1,5 @@ #![allow(dead_code)] -use farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule; use multiversx_sc::codec::multi_types::OptionalValue; use multiversx_sc::storage::mappers::StorageTokenWrapper; use multiversx_sc::types::{Address, BigUint, EsdtLocalRole, ManagedAddress, MultiValueEncoded}; @@ -114,6 +113,7 @@ where farming_token_id, division_safety_constant, ManagedAddress::::zero(), + managed_address!(timestamp_oracle_wrapper.address_ref()), MultiValueEncoded::new(), ); @@ -125,9 +125,6 @@ where sc.state().set(State::Active); sc.produce_rewards_enabled().set(true); - sc.set_timestamp_oracle_address(managed_address!( - timestamp_oracle_wrapper.address_ref() - )); }) .assert_ok(); diff --git a/dex/farm/tests/farm_setup/multi_user_farm_setup.rs b/dex/farm/tests/farm_setup/multi_user_farm_setup.rs index fdec4ef02..344f688b0 100644 --- a/dex/farm/tests/farm_setup/multi_user_farm_setup.rs +++ b/dex/farm/tests/farm_setup/multi_user_farm_setup.rs @@ -179,6 +179,7 @@ where farming_token_id, division_safety_constant, managed_address!(&owner), + managed_address!(timestamp_oracle_wrapper.address_ref()), MultiValueEncoded::new(), ); @@ -193,9 +194,6 @@ where sc.set_energy_factory_address(managed_address!( energy_factory_wrapper.address_ref() )); - sc.set_timestamp_oracle_address(managed_address!( - timestamp_oracle_wrapper.address_ref() - )); sc.set_permissions_hub_address(managed_address!( permissions_hub_wrapper.address_ref() diff --git a/dex/farm/tests/farm_setup/single_user_farm_setup.rs b/dex/farm/tests/farm_setup/single_user_farm_setup.rs index 87eb38ca4..a5b1c0f54 100644 --- a/dex/farm/tests/farm_setup/single_user_farm_setup.rs +++ b/dex/farm/tests/farm_setup/single_user_farm_setup.rs @@ -1,7 +1,6 @@ #![allow(dead_code)] use common_structs::FarmTokenAttributes; -use farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule; use multiversx_sc::codec::multi_types::{MultiValue3, OptionalValue}; use multiversx_sc::storage::mappers::StorageTokenWrapper; use multiversx_sc::types::{Address, EsdtLocalRole, ManagedAddress, MultiValueEncoded}; @@ -141,6 +140,7 @@ where farming_token_id, division_safety_constant, ManagedAddress::::zero(), + managed_address!(timestamp_oracle_wrapper.address_ref()), MultiValueEncoded::new(), ); @@ -152,9 +152,6 @@ where sc.state().set(State::Active); sc.produce_rewards_enabled().set(true); - sc.set_timestamp_oracle_address(managed_address!( - timestamp_oracle_wrapper.address_ref() - )); }) .assert_ok(); diff --git a/dex/proxy-deployer/Cargo.toml b/dex/proxy-deployer/Cargo.toml index 4d46d90a6..02596c440 100644 --- a/dex/proxy-deployer/Cargo.toml +++ b/dex/proxy-deployer/Cargo.toml @@ -26,3 +26,9 @@ num-bigint = "0.4.2" [dev-dependencies.multiversx-sc-scenario] version = "=0.53.2" + +[dev-dependencies.farm_token] +path = "../../common/modules/farm/farm_token" + +[dev-dependencies.timestamp-oracle] +path = "../../energy-integration/timestamp-oracle" diff --git a/dex/proxy-deployer/src/deploy.rs b/dex/proxy-deployer/src/deploy.rs index d4525178c..3579a23e6 100644 --- a/dex/proxy-deployer/src/deploy.rs +++ b/dex/proxy-deployer/src/deploy.rs @@ -60,6 +60,7 @@ pub trait DeployModule: crate::storage::StorageModule { let template = self.template_address().get(); let code_metadata = CodeMetadata::PAYABLE_BY_SC | CodeMetadata::READABLE | CodeMetadata::UPGRADEABLE; + let timestamp_oracle_address = self.timestamp_oracle_address().get(); let (deployed_sc_address, ()) = self .farm_staking_deploy_proxy() @@ -69,6 +70,7 @@ pub trait DeployModule: crate::storage::StorageModule { max_apr, min_unbond_epochs, owner, + timestamp_oracle_address, admins, ) .deploy_from_source(&template, code_metadata); diff --git a/dex/proxy-deployer/src/lib.rs b/dex/proxy-deployer/src/lib.rs index ad174fed6..6586e88c3 100644 --- a/dex/proxy-deployer/src/lib.rs +++ b/dex/proxy-deployer/src/lib.rs @@ -17,15 +17,27 @@ pub trait ProxyDeployer: + views::ViewModule { #[init] - fn init(&self, template_address: ManagedAddress, deployer_type: DeployerType) { + fn init( + &self, + template_address: ManagedAddress, + deployer_type: DeployerType, + timestamp_oracle_address: ManagedAddress, + ) { require!( self.blockchain().is_smart_contract(&template_address), "Invalid farm template address" ); require!(deployer_type != DeployerType::None, "Invalid deployer type"); + require!( + self.blockchain() + .is_smart_contract(×tamp_oracle_address), + "Invalid timestamp oracle address" + ); self.template_address().set(template_address); self.deployer_type().set(deployer_type); + self.timestamp_oracle_address() + .set(timestamp_oracle_address); } #[upgrade] diff --git a/dex/proxy-deployer/src/storage.rs b/dex/proxy-deployer/src/storage.rs index 208d8810f..181f0d6e0 100644 --- a/dex/proxy-deployer/src/storage.rs +++ b/dex/proxy-deployer/src/storage.rs @@ -48,4 +48,7 @@ pub trait StorageModule { #[storage_mapper("userBlacklist")] fn user_blacklist(&self) -> WhitelistMapper; + + #[storage_mapper("timestampOracleAddress")] + fn timestamp_oracle_address(&self) -> SingleValueMapper; } diff --git a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_setup/mod.rs b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_setup/mod.rs index 1a6f988c8..726789f72 100644 --- a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_setup/mod.rs +++ b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_setup/mod.rs @@ -1,9 +1,13 @@ +use common_structs::Timestamp; use multiversx_sc::types::Address; use multiversx_sc_scenario::{ imports::{BlockchainStateWrapper, ContractObjWrapper}, managed_address, rust_biguint, DebugApi, }; use proxy_deployer::{storage::DeployerType, ProxyDeployer}; +use timestamp_oracle::{epoch_to_timestamp::EpochToTimestampModule, TimestampOracle}; + +pub const TIMESTAMP_PER_EPOCH: Timestamp = 24 * 60 * 60; pub struct ProxyDeployerFarmStakingSetup where @@ -42,11 +46,28 @@ where "farm staking template", ); + let timestamp_oracle_wrapper = b_mock.create_sc_account( + &rust_zero, + Some(&owner), + timestamp_oracle::contract_obj, + "timestamp oracle", + ); + b_mock + .execute_tx(&owner, ×tamp_oracle_wrapper, &rust_zero, |sc| { + sc.init(0); + + for i in 0..=21 { + sc.set_start_timestamp_for_epoch(i, i * TIMESTAMP_PER_EPOCH + 1); + } + }) + .assert_ok(); + b_mock .execute_tx(&owner, &proxy_deployer_wrapper, &rust_zero, |sc| { sc.init( managed_address!(template_wrapper.address_ref()), DeployerType::FarmStaking, + managed_address!(timestamp_oracle_wrapper.address_ref()), ); }) .assert_ok(); diff --git a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs index 284d313b0..048c657aa 100644 --- a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs +++ b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs @@ -1,3 +1,8 @@ +use farm_staking::custom_rewards::CustomRewardsModule; +use farm_token::FarmTokenModule; +use multiversx_sc::imports::StorageTokenWrapper; +use multiversx_sc_scenario::{managed_biguint, managed_token_id, rust_biguint}; +use proxy_deployer::deploy::DeployModule; use proxy_deployer_farm_staking_setup::ProxyDeployerFarmStakingSetup; pub mod proxy_deployer_farm_staking_setup; @@ -9,3 +14,42 @@ fn setup_test() { farm_staking::contract_obj, ); } + +#[test] +fn deploy_farm_staking_test() { + let mut setup = ProxyDeployerFarmStakingSetup::new( + proxy_deployer::contract_obj, + farm_staking::contract_obj, + ); + + let new_sc_wrapper = setup.b_mock.prepare_deploy_from_sc( + setup.proxy_deployer_wrapper.address_ref(), + farm_staking::contract_obj, + ); + setup + .b_mock + .execute_tx( + &setup.user, + &setup.proxy_deployer_wrapper, + &rust_biguint!(0), + |sc| { + sc.deploy_farm_staking_contract( + managed_token_id!(b"COOLTOK-123456"), + managed_biguint!(7_500), + 10, + ); + }, + ) + .assert_ok(); + + // user call admin function on new farm staking + setup + .b_mock + .execute_tx(&setup.user, &new_sc_wrapper, &rust_biguint!(0), |sc| { + sc.farm_token() + .set_token_id(managed_token_id!(b"MYCOOLFARM-123456")); + + sc.set_per_block_rewards(managed_biguint!(1_000)); + }) + .assert_ok(); +} diff --git a/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_external_contracts/mod.rs b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_external_contracts/mod.rs index 277d13e7e..1a6ca5dc9 100644 --- a/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_external_contracts/mod.rs +++ b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_external_contracts/mod.rs @@ -1,7 +1,6 @@ use energy_factory::token_whitelist::TokenWhitelistModule; use energy_factory::SimpleLockEnergy; use energy_query::EnergyQueryModule; -use farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule; use locking_module::lock_with_energy_module::LockWithEnergyModule; use multiversx_sc::codec::multi_types::{MultiValue3, OptionalValue}; use multiversx_sc::storage::mappers::StorageTokenWrapper; @@ -273,6 +272,7 @@ where farming_token_id, division_safety_constant, ManagedAddress::::zero(), + managed_address!(timestamp_oracle_address), MultiValueEncoded::new(), ); @@ -290,7 +290,6 @@ where .set(managed_address!(energy_factory_address)); sc.energy_factory_address() .set(managed_address!(energy_factory_address)); - sc.set_timestamp_oracle_address(managed_address!(timestamp_oracle_address)); }) .assert_ok(); diff --git a/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_setup/mod.rs b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_setup/mod.rs index 14095b958..834cc75fb 100644 --- a/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_setup/mod.rs +++ b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_setup/mod.rs @@ -1,6 +1,5 @@ use energy_query::EnergyQueryModule; use farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule; -use farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule; use multiversx_sc::storage::mappers::StorageTokenWrapper; use multiversx_sc::types::{Address, EsdtLocalRole, ManagedAddress, MultiValueEncoded}; use multiversx_sc_scenario::{ @@ -49,6 +48,7 @@ where max_apr, UNBOND_EPOCHS, ManagedAddress::::zero(), + managed_address!(timestamp_oracle_address), MultiValueEncoded::new(), ); @@ -64,7 +64,6 @@ where sc.last_reward_block_nonce() .set(BLOCK_NONCE_AFTER_PAIR_SETUP); sc.reward_capacity().set(&managed_biguint!(REWARD_CAPACITY)); - sc.set_timestamp_oracle_address(managed_address!(timestamp_oracle_address)); }) .assert_ok(); diff --git a/farm-staking/farm-staking/src/lib.rs b/farm-staking/farm-staking/src/lib.rs index 16d73d80c..59d497ba3 100644 --- a/farm-staking/farm-staking/src/lib.rs +++ b/farm-staking/farm-staking/src/lib.rs @@ -71,6 +71,7 @@ pub trait FarmStaking: max_apr: BigUint, min_unbond_epochs: u64, owner: ManagedAddress, + timestamp_oracle_address: ManagedAddress, admins: MultiValueEncoded, ) { // farming and reward token are the same @@ -91,6 +92,8 @@ pub trait FarmStaking: ); self.min_unbond_epochs().set(min_unbond_epochs); + self.set_timestamp_oracle_address(timestamp_oracle_address); + let current_epoch = self.blockchain().get_block_epoch(); self.first_week_start_epoch().set(current_epoch); } diff --git a/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs b/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs index 0e16b4ae4..2a11a67ed 100644 --- a/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs +++ b/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs @@ -156,6 +156,7 @@ where managed_biguint!(MAX_APR), MIN_UNBOND_EPOCHS, ManagedAddress::::zero(), + managed_address!(timestamp_oracle_wrapper.address_ref()), MultiValueEncoded::new(), ); @@ -170,9 +171,6 @@ where sc.energy_factory_address() .set(managed_address!(energy_factory_wrapper.address_ref())); - sc.set_timestamp_oracle_address(managed_address!( - timestamp_oracle_wrapper.address_ref() - )); sc.set_permissions_hub_address(managed_address!( permissions_hub_wrapper.address_ref() From a6d4df3215852fd87e76673731a99d87e94ae09c Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Wed, 27 Nov 2024 13:58:41 +0200 Subject: [PATCH 14/23] fix other tests --- Cargo.lock | 2 ++ .../farm_with_locked_rewards_setup/mod.rs | 9 ++----- dex/fuzz/Cargo.toml | 3 +++ dex/fuzz/src/fuzz_data.rs | 22 ++++++++++++++++ .../tests/farm_staking_setup/mod.rs | 1 - .../tests/proxy_dex_test_setup/mod.rs | 7 ++---- pause-all/Cargo.toml | 3 +++ pause-all/tests/pause_all_test.rs | 25 +++++++++++++++++++ 8 files changed, 59 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb6ea6ba9..334159e4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -883,6 +883,7 @@ dependencies = [ "rewards", "router", "simple-lock", + "timestamp-oracle", ] [[package]] @@ -1433,6 +1434,7 @@ dependencies = [ "multiversx-sc-scenario", "pair", "pausable", + "timestamp-oracle", ] [[package]] diff --git a/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs b/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs index 990b5bddd..df53f285f 100644 --- a/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs +++ b/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs @@ -17,10 +17,7 @@ use fees_collector_mock::*; use energy_factory::{energy::EnergyModule, SimpleLockEnergy}; use energy_query::{Energy, EnergyQueryModule}; -use farm_boosted_yields::{ - boosted_yields_factors::BoostedYieldsFactorsModule, - custom_reward_logic::CustomRewardLogicModule, -}; +use farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule; use farm_token::FarmTokenModule; use farm_with_locked_rewards::{external_interaction::ExternalInteractionsModule, Farm}; use locking_module::lock_with_energy_module::LockWithEnergyModule; @@ -197,6 +194,7 @@ where farming_token_id, division_safety_constant, managed_address!(&owner), + managed_address!(timestamp_oracle_wrapper.address_ref()), MultiValueEncoded::new(), ); @@ -220,9 +218,6 @@ where sc.set_energy_factory_address(managed_address!( energy_factory_wrapper.address_ref() )); - sc.set_timestamp_oracle_address(managed_address!( - timestamp_oracle_wrapper.address_ref() - )); sc.set_permissions_hub_address(managed_address!( permissions_hub_wrapper.address_ref() )); diff --git a/dex/fuzz/Cargo.toml b/dex/fuzz/Cargo.toml index 7278d4708..ff72ad77c 100644 --- a/dex/fuzz/Cargo.toml +++ b/dex/fuzz/Cargo.toml @@ -53,3 +53,6 @@ path = "../pair" [dependencies.router] path = "../router" + +[dependencies.timestamp-oracle] +path = "../../energy-integration/timestamp-oracle" diff --git a/dex/fuzz/src/fuzz_data.rs b/dex/fuzz/src/fuzz_data.rs index 8bc2be8f3..c7ecdbd0f 100644 --- a/dex/fuzz/src/fuzz_data.rs +++ b/dex/fuzz/src/fuzz_data.rs @@ -5,6 +5,7 @@ pub mod fuzz_data_tests { multiversx_sc::derive_imports!(); use ::config::ConfigModule; + use common_structs::Timestamp; use farm::*; use farm_token::FarmTokenModule; use multiversx_sc::codec::Empty; @@ -24,6 +25,8 @@ pub mod fuzz_data_tests { use rand::SeedableRng; use std::cell::Cell; use std::collections::HashMap; + use timestamp_oracle::epoch_to_timestamp::EpochToTimestampModule; + use timestamp_oracle::TimestampOracle; type RustBigUint = num_bigint::BigUint; @@ -66,6 +69,8 @@ pub mod fuzz_data_tests { pub const FIXED_PENALTY_PHASE_DURATION_BLOCKS: u64 = 25; pub const UNLOCK_EPOCH: u64 = 20; + pub const TIMESTAMP_PER_EPOCH: Timestamp = 24 * 60 * 60; + #[derive(Clone, TopEncode)] pub struct FuzzDexExecutorInitArgs { pub num_users: u64, @@ -394,6 +399,22 @@ pub mod fuzz_data_tests { FARM_WASM_PATH, ); + let timestamp_oracle_wrapper = blockchain_wrapper.create_sc_account( + &rust_zero, + Some(&owner_addr), + timestamp_oracle::contract_obj, + "timestamp oracle", + ); + blockchain_wrapper + .execute_tx(&owner_addr, ×tamp_oracle_wrapper, &rust_zero, |sc| { + sc.init(0); + + for i in 0..=21 { + sc.set_start_timestamp_for_epoch(i, i * TIMESTAMP_PER_EPOCH + 1); + } + }) + .assert_ok(); + blockchain_wrapper .execute_tx(owner_addr, &farm_wrapper, &rust_zero, |sc| { let reward_token_id = managed_token_id!(reward_token); @@ -405,6 +426,7 @@ pub mod fuzz_data_tests { farming_token_id, division_safety_constant, ManagedAddress::::zero(), + managed_address!(timestamp_oracle_wrapper.address_ref()), MultiValueEncoded::new(), ); diff --git a/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs b/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs index 2a11a67ed..f887b7e7b 100644 --- a/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs +++ b/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs @@ -1,6 +1,5 @@ use common_structs::Timestamp; use external_interaction::ExternalInteractionsModule; -use farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule; use farm_staking::claim_only_boosted_staking_rewards::ClaimOnlyBoostedStakingRewardsModule; use farm_staking::compound_stake_farm_rewards::CompoundStakeFarmRewardsModule; use multiversx_sc::codec::multi_types::OptionalValue; diff --git a/locked-asset/proxy_dex/tests/proxy_dex_test_setup/mod.rs b/locked-asset/proxy_dex/tests/proxy_dex_test_setup/mod.rs index 64fb27a0d..a35bb84e4 100644 --- a/locked-asset/proxy_dex/tests/proxy_dex_test_setup/mod.rs +++ b/locked-asset/proxy_dex/tests/proxy_dex_test_setup/mod.rs @@ -6,10 +6,7 @@ use common_structs::{ use config::ConfigModule; use energy_factory::{locked_token_transfer::LockedTokenTransferModule, SimpleLockEnergy}; use energy_query::EnergyQueryModule; -use farm_boosted_yields::{ - boosted_yields_factors::BoostedYieldsFactorsModule, - custom_reward_logic::CustomRewardLogicModule, -}; +use farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule; use farm_token::FarmTokenModule; use farm_with_locked_rewards::Farm as FarmLocked; use locking_module::lock_with_energy_module::LockWithEnergyModule; @@ -363,6 +360,7 @@ where farming_token_id, division_safety_constant, managed_address!(owner), + managed_address!(timestamp_oracle_addr), MultiValueEncoded::new(), ); @@ -386,7 +384,6 @@ where sc.set_lock_epochs(EPOCHS_IN_YEAR); sc.energy_factory_address() .set(managed_address!(simple_lock_addr)); - sc.set_timestamp_oracle_address(managed_address!(timestamp_oracle_addr)); }) .assert_ok(); diff --git a/pause-all/Cargo.toml b/pause-all/Cargo.toml index 6f03bfb68..b4ddeec43 100644 --- a/pause-all/Cargo.toml +++ b/pause-all/Cargo.toml @@ -26,3 +26,6 @@ path = "../dex/farm" [dev-dependencies.pair] path = "../dex/pair" + +[dev-dependencies.timestamp-oracle] +path = "../energy-integration/timestamp-oracle" diff --git a/pause-all/tests/pause_all_test.rs b/pause-all/tests/pause_all_test.rs index 0605891da..138987026 100644 --- a/pause-all/tests/pause_all_test.rs +++ b/pause-all/tests/pause_all_test.rs @@ -6,6 +6,7 @@ use multiversx_sc_scenario::{ use pair::Pair; use pausable::{PausableModule, State}; use pause_all::*; +use timestamp_oracle::{epoch_to_timestamp::EpochToTimestampModule, TimestampOracle}; static REWARD_TOKEN_ID: &[u8] = b"REWARD-123456"; static FARMING_TOKEN_ID: &[u8] = b"FARMING-123456"; @@ -16,6 +17,8 @@ static SECOND_TOKEN_ID: &[u8] = b"BEST-123456"; static TOTAL_FEE_PERCENT: u64 = 50; static SPECIAL_FEE_PERCENT: u64 = 50; +pub const TIMESTAMP_PER_EPOCH: u64 = 24 * 60 * 60; + #[test] fn pause_all_test() { let rust_zero = rust_biguint!(0u64); @@ -40,6 +43,27 @@ fn pause_all_test() { "output/pair.wasm", ); + let timestamp_oracle_wrapper = b_mock.create_sc_account( + &rust_zero, + Some(&owner_address), + timestamp_oracle::contract_obj, + "timestamp oracle", + ); + b_mock + .execute_tx( + &owner_address, + ×tamp_oracle_wrapper, + &rust_zero, + |sc| { + sc.init(0); + + for i in 0..=21 { + sc.set_start_timestamp_for_epoch(i, i * TIMESTAMP_PER_EPOCH + 1); + } + }, + ) + .assert_ok(); + // init farm b_mock .execute_tx(&owner_address, &farm_sc, &rust_zero, |sc| { @@ -48,6 +72,7 @@ fn pause_all_test() { managed_token_id!(FARMING_TOKEN_ID), managed_biguint!(DIV_SAFETY), ManagedAddress::::zero(), + managed_address!(timestamp_oracle_wrapper.address_ref()), MultiValueEncoded::new(), ); From 88270c2482a07d3fbd64f754f48139bda747c03a Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Wed, 27 Nov 2024 14:09:04 +0200 Subject: [PATCH 15/23] additional endpoint --- dex/proxy-deployer/src/remove_contracts.rs | 19 +++++++++++++- .../proxy_deployer_farm_staking_tests.rs | 26 +++++++++++++++++-- dex/proxy-deployer/wasm/src/lib.rs | 5 ++-- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/dex/proxy-deployer/src/remove_contracts.rs b/dex/proxy-deployer/src/remove_contracts.rs index e407394bc..b941602e0 100644 --- a/dex/proxy-deployer/src/remove_contracts.rs +++ b/dex/proxy-deployer/src/remove_contracts.rs @@ -26,7 +26,7 @@ pub trait RemoveContractsModule: crate::storage::StorageModule { let total_contracts = contracts_mapper.len(); let to_remove = core::cmp::min(total_contracts, max_to_remove); for _ in 0..to_remove { - let contract_id = contracts_mapper.get_by_index(0); + let contract_id = contracts_mapper.get_by_index(1); let contract_address = self.get_by_id(&id_mapper, contract_id); let _ = contracts_mapper.swap_remove(&contract_id); @@ -39,6 +39,23 @@ pub trait RemoveContractsModule: crate::storage::StorageModule { } } + #[only_owner] + #[endpoint(removeSingleContract)] + fn remove_single_contract(&self, contract: ManagedAddress) { + let id_mapper = self.address_id(); + let contract_id = id_mapper.get_id_non_zero(&contract); + let deployer_id = self.contract_owner(contract_id).get(); + require!(deployer_id != 0, "Contract already removed"); + + let _ = self + .contracts_by_address(deployer_id) + .swap_remove(&contract_id); + + let deployer_address = self.get_by_id(&id_mapper, deployer_id); + self.remove_admin(contract, deployer_address); + self.remove_contract(contract_id); + } + fn remove_admin(&self, contract: ManagedAddress, user: ManagedAddress) { self.remove_user_proxy(contract) .remove_admin_endpoint(user) diff --git a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs index 048c657aa..87cd119d1 100644 --- a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs +++ b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs @@ -1,8 +1,8 @@ use farm_staking::custom_rewards::CustomRewardsModule; use farm_token::FarmTokenModule; use multiversx_sc::imports::StorageTokenWrapper; -use multiversx_sc_scenario::{managed_biguint, managed_token_id, rust_biguint}; -use proxy_deployer::deploy::DeployModule; +use multiversx_sc_scenario::{managed_address, managed_biguint, managed_token_id, rust_biguint}; +use proxy_deployer::{deploy::DeployModule, remove_contracts::RemoveContractsModule}; use proxy_deployer_farm_staking_setup::ProxyDeployerFarmStakingSetup; pub mod proxy_deployer_farm_staking_setup; @@ -52,4 +52,26 @@ fn deploy_farm_staking_test() { sc.set_per_block_rewards(managed_biguint!(1_000)); }) .assert_ok(); + + // owner remove the contracts + let user_addr = setup.user.clone(); + setup + .b_mock + .execute_tx( + &setup.owner, + &setup.proxy_deployer_wrapper, + &rust_biguint!(0), + |sc| { + sc.remove_all_by_deployer(managed_address!(&user_addr), 1); + }, + ) + .assert_ok(); + + // user try call admin function after removed + setup + .b_mock + .execute_tx(&setup.user, &new_sc_wrapper, &rust_biguint!(0), |sc| { + sc.set_per_block_rewards(managed_biguint!(1_000)); + }) + .assert_user_error("Permission denied"); } diff --git a/dex/proxy-deployer/wasm/src/lib.rs b/dex/proxy-deployer/wasm/src/lib.rs index 0c0b81935..25362983e 100644 --- a/dex/proxy-deployer/wasm/src/lib.rs +++ b/dex/proxy-deployer/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 10 +// Endpoints: 11 // Async Callback (empty): 1 -// Total number of exported functions: 13 +// Total number of exported functions: 14 #![no_std] @@ -22,6 +22,7 @@ multiversx_sc_wasm_adapter::endpoints! { upgrade => upgrade deployFarmStakingContract => deploy_farm_staking_contract removeAllByDeployer => remove_all_by_deployer + removeSingleContract => remove_single_contract getDeployerType => deployer_type getTemplateAddress => template_address getAddressForToken => get_address_for_token From 6193e89e0d47e2203a4ea4514ba924a1ab8f4a6e Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Wed, 27 Nov 2024 14:11:21 +0200 Subject: [PATCH 16/23] new test --- .../proxy_deployer_farm_staking_tests.rs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs index 87cd119d1..51b37bfc8 100644 --- a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs +++ b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs @@ -75,3 +75,44 @@ fn deploy_farm_staking_test() { }) .assert_user_error("Permission denied"); } + +#[test] +fn remove_single_contract_test() { + let mut setup = ProxyDeployerFarmStakingSetup::new( + proxy_deployer::contract_obj, + farm_staking::contract_obj, + ); + + let new_sc_wrapper = setup.b_mock.prepare_deploy_from_sc( + setup.proxy_deployer_wrapper.address_ref(), + farm_staking::contract_obj, + ); + setup + .b_mock + .execute_tx( + &setup.user, + &setup.proxy_deployer_wrapper, + &rust_biguint!(0), + |sc| { + sc.deploy_farm_staking_contract( + managed_token_id!(b"COOLTOK-123456"), + managed_biguint!(7_500), + 10, + ); + }, + ) + .assert_ok(); + + // owner remove the contracts + setup + .b_mock + .execute_tx( + &setup.owner, + &setup.proxy_deployer_wrapper, + &rust_biguint!(0), + |sc| { + sc.remove_single_contract(managed_address!(new_sc_wrapper.address_ref())); + }, + ) + .assert_ok(); +} From 763221c75b35a7e771ee328e1be978b5324ad110 Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Thu, 28 Nov 2024 10:08:22 +0200 Subject: [PATCH 17/23] change some impl --- Cargo.lock | 2 + .../farm/farm_base_impl/src/base_farm_init.rs | 2 + dex/proxy-deployer/Cargo.toml | 6 ++ dex/proxy-deployer/src/deploy.rs | 2 + dex/proxy-deployer/src/lib.rs | 5 ++ dex/proxy-deployer/src/remove_contracts.rs | 14 +++- dex/proxy-deployer/src/set_contract_active.rs | 84 +++++++++++++++++++ dex/proxy-deployer/src/storage.rs | 7 ++ dex/proxy-deployer/src/views.rs | 16 +++- dex/proxy-deployer/wasm/Cargo.lock | 2 + dex/proxy-deployer/wasm/src/lib.rs | 9 +- .../src/boosted_yields_factors.rs | 2 +- 12 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 dex/proxy-deployer/src/set_contract_active.rs diff --git a/Cargo.lock b/Cargo.lock index 334159e4d..0f857da80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1561,11 +1561,13 @@ name = "proxy-deployer" version = "0.0.0" dependencies = [ "common_structs", + "farm-boosted-yields", "farm-staking", "farm_token", "multiversx-sc", "multiversx-sc-scenario", "num-bigint", + "pausable", "permissions_module", "timestamp-oracle", ] diff --git a/common/modules/farm/farm_base_impl/src/base_farm_init.rs b/common/modules/farm/farm_base_impl/src/base_farm_init.rs index 700057a3e..5387f57b4 100644 --- a/common/modules/farm/farm_base_impl/src/base_farm_init.rs +++ b/common/modules/farm/farm_base_impl/src/base_farm_init.rs @@ -50,5 +50,7 @@ pub trait BaseFarmInitModule: self.add_permissions(caller, Permissions::OWNER | Permissions::PAUSE); self.add_permissions_for_all(admins, Permissions::ADMIN); }; + + self.pause(); } } diff --git a/dex/proxy-deployer/Cargo.toml b/dex/proxy-deployer/Cargo.toml index 02596c440..5043ec5a9 100644 --- a/dex/proxy-deployer/Cargo.toml +++ b/dex/proxy-deployer/Cargo.toml @@ -21,6 +21,12 @@ path = "../../common/common_structs" [dependencies.permissions_module] path = "../../common/modules/permissions_module" +[dependencies.pausable] +path = "../../common/modules/pausable" + +[dependencies.farm-boosted-yields] +path = "../../energy-integration/farm-boosted-yields" + [dev-dependencies] num-bigint = "0.4.2" diff --git a/dex/proxy-deployer/src/deploy.rs b/dex/proxy-deployer/src/deploy.rs index 3579a23e6..9e03ee986 100644 --- a/dex/proxy-deployer/src/deploy.rs +++ b/dex/proxy-deployer/src/deploy.rs @@ -54,8 +54,10 @@ pub trait DeployModule: crate::storage::StorageModule { ) -> ManagedAddress { let owner = self.blockchain().get_owner_address(); + let own_sc_address = self.blockchain().get_sc_address(); let mut admins = MultiValueEncoded::new(); admins.push(caller); + admins.push(own_sc_address); let template = self.template_address().get(); let code_metadata = diff --git a/dex/proxy-deployer/src/lib.rs b/dex/proxy-deployer/src/lib.rs index 6586e88c3..fa82e8bee 100644 --- a/dex/proxy-deployer/src/lib.rs +++ b/dex/proxy-deployer/src/lib.rs @@ -1,17 +1,20 @@ #![no_std] +use farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactors; use storage::DeployerType; multiversx_sc::imports!(); pub mod deploy; pub mod remove_contracts; +pub mod set_contract_active; pub mod storage; pub mod views; #[multiversx_sc::contract] pub trait ProxyDeployer: deploy::DeployModule + + set_contract_active::SetContractActiveModule + remove_contracts::RemoveContractsModule + storage::StorageModule + views::ViewModule @@ -22,6 +25,7 @@ pub trait ProxyDeployer: template_address: ManagedAddress, deployer_type: DeployerType, timestamp_oracle_address: ManagedAddress, + boosted_yields_factors: BoostedYieldsFactors, ) { require!( self.blockchain().is_smart_contract(&template_address), @@ -38,6 +42,7 @@ pub trait ProxyDeployer: self.deployer_type().set(deployer_type); self.timestamp_oracle_address() .set(timestamp_oracle_address); + self.boosted_yields_factors().set(boosted_yields_factors); } #[upgrade] diff --git a/dex/proxy-deployer/src/remove_contracts.rs b/dex/proxy-deployer/src/remove_contracts.rs index b941602e0..0e55e21a2 100644 --- a/dex/proxy-deployer/src/remove_contracts.rs +++ b/dex/proxy-deployer/src/remove_contracts.rs @@ -10,6 +10,13 @@ pub struct RemoveResult { #[multiversx_sc::module] pub trait RemoveContractsModule: crate::storage::StorageModule { + #[only_owner] + #[endpoint(blacklistUser)] + fn blacklist_user(&self, user: ManagedAddress) { + let user_id = self.address_id().get_id_or_insert(&user); + self.user_blacklist().add(&user_id); + } + #[only_owner] #[endpoint(removeAllByDeployer)] fn remove_all_by_deployer( @@ -19,8 +26,6 @@ pub trait RemoveContractsModule: crate::storage::StorageModule { ) -> RemoveResult { let id_mapper = self.address_id(); let deployer_id = id_mapper.get_id_non_zero(&deployer_address); - self.user_blacklist().add(&deployer_id); - let mut contracts_mapper = self.contracts_by_address(deployer_id); let total_contracts = contracts_mapper.len(); @@ -70,6 +75,11 @@ pub trait RemoveContractsModule: crate::storage::StorageModule { self.contract_owner(contract_id).clear(); } + // TODO: Remove by deployer + + + + // For now, both farm and farm_staking use the same internal permissions module. // // Create two separate proxies if this if this ever changes. diff --git a/dex/proxy-deployer/src/set_contract_active.rs b/dex/proxy-deployer/src/set_contract_active.rs new file mode 100644 index 000000000..10a73b401 --- /dev/null +++ b/dex/proxy-deployer/src/set_contract_active.rs @@ -0,0 +1,84 @@ +use common_structs::Percent; +use farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactors; +use farm_boosted_yields::boosted_yields_factors::ProxyTrait as _; +use farm_staking::custom_rewards::ProxyTrait as _; +use pausable::ProxyTrait as _; + +multiversx_sc::imports!(); + +#[multiversx_sc::module] +pub trait SetContractActiveModule: crate::storage::StorageModule { + /// Boosted yields percent must be >= 0 (0%) and <= 10_000 (100%) + /// + /// Only callable by contract deployer + /// + /// Calling this endpoint multiple times is the same as calling the specific endpoints in farm by the deployer + #[endpoint(setContractActive)] + fn set_contract_active( + &self, + contract: ManagedAddress, + rewards_per_block: BigUint, + boosted_yields_percent: Percent, + ) { + let id_mapper = self.address_id(); + let contract_id = id_mapper.get_id_non_zero(&contract); + + let caller = self.blockchain().get_caller(); + let caller_id = id_mapper.get_id_non_zero(&caller); + let owner_id = self.contract_owner(contract_id).get(); + require!( + caller_id == owner_id, + "Only contract owner may call this endpoint" + ); + + let boosted_yields_factors = self.boosted_yields_factors().get(); + self.set_rewards_per_block(contract.clone(), rewards_per_block); + self.set_boosted_yields_factors(contract.clone(), boosted_yields_factors); + self.set_boosted_yields_percent(contract.clone(), boosted_yields_percent); + self.unpause_contract(contract); + } + + fn set_rewards_per_block(&self, contract: ManagedAddress, rewards_per_block: BigUint) { + self.set_contract_active_proxy(contract) + .set_per_block_rewards(rewards_per_block) + .execute_on_dest_context() + } + + fn set_boosted_yields_factors( + &self, + contract: ManagedAddress, + factors: BoostedYieldsFactors, + ) { + self.set_contract_active_proxy(contract) + .set_boosted_yields_factors( + factors.max_rewards_factor, + factors.user_rewards_energy_const, + factors.user_rewards_farm_const, + factors.min_energy_amount, + factors.min_farm_amount, + ) + .execute_on_dest_context() + } + + fn set_boosted_yields_percent( + &self, + contract: ManagedAddress, + boosted_yields_percent: Percent, + ) { + self.set_contract_active_proxy(contract) + .set_boosted_yields_rewards_percentage(boosted_yields_percent) + .execute_on_dest_context() + } + + fn unpause_contract(&self, contract: ManagedAddress) { + self.set_contract_active_proxy(contract) + .resume() + .execute_on_dest_context() + } + + #[proxy] + fn set_contract_active_proxy( + &self, + sc_address: ManagedAddress, + ) -> farm_staking::Proxy; +} diff --git a/dex/proxy-deployer/src/storage.rs b/dex/proxy-deployer/src/storage.rs index 181f0d6e0..35beba626 100644 --- a/dex/proxy-deployer/src/storage.rs +++ b/dex/proxy-deployer/src/storage.rs @@ -1,3 +1,5 @@ +use farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactors; + multiversx_sc::imports!(); multiversx_sc::derive_imports!(); @@ -49,6 +51,11 @@ pub trait StorageModule { #[storage_mapper("userBlacklist")] fn user_blacklist(&self) -> WhitelistMapper; + #[view(getTimestampOracleAddress)] #[storage_mapper("timestampOracleAddress")] fn timestamp_oracle_address(&self) -> SingleValueMapper; + + #[view(getBoostedYieldsFactors)] + #[storage_mapper("boostedYieldsFactors")] + fn boosted_yields_factors(&self) -> SingleValueMapper>; } diff --git a/dex/proxy-deployer/src/views.rs b/dex/proxy-deployer/src/views.rs index 5f5bcc73d..6135e0c50 100644 --- a/dex/proxy-deployer/src/views.rs +++ b/dex/proxy-deployer/src/views.rs @@ -3,6 +3,16 @@ multiversx_sc::derive_imports!(); #[multiversx_sc::module] pub trait ViewModule: crate::storage::StorageModule { + #[view(isUserBlacklisted)] + fn is_user_blacklisted(&self, user: ManagedAddress) -> bool { + let user_id = self.address_id().get_id(&user); + if user_id == NULL_ID { + return false; + } + + self.user_blacklist().contains(&user_id) + } + #[view(getAddressForToken)] fn get_address_for_token(&self, token_id: TokenIdentifier) -> OptionalValue { let mapper = self.address_for_token(&token_id); @@ -22,7 +32,7 @@ pub trait ViewModule: crate::storage::StorageModule { contract_address: ManagedAddress, ) -> OptionalValue { let contract_id = self.address_id().get_id(&contract_address); - if contract_id == 0 { + if contract_id == NULL_ID { return OptionalValue::None; } @@ -42,7 +52,7 @@ pub trait ViewModule: crate::storage::StorageModule { contract_address: ManagedAddress, ) -> OptionalValue { let contract_id = self.address_id().get_id(&contract_address); - if contract_id == 0 { + if contract_id == NULL_ID { return OptionalValue::None; } @@ -94,7 +104,7 @@ pub trait ViewModule: crate::storage::StorageModule { ) -> MultiValueEncoded { let id_mapper = self.address_id(); let user_id = id_mapper.get_id(&user); - if user_id == 0 { + if user_id == NULL_ID { return MultiValueEncoded::new(); } diff --git a/dex/proxy-deployer/wasm/Cargo.lock b/dex/proxy-deployer/wasm/Cargo.lock index c742b6af0..00b6cfa66 100644 --- a/dex/proxy-deployer/wasm/Cargo.lock +++ b/dex/proxy-deployer/wasm/Cargo.lock @@ -440,8 +440,10 @@ name = "proxy-deployer" version = "0.0.0" dependencies = [ "common_structs", + "farm-boosted-yields", "farm-staking", "multiversx-sc", + "pausable", "permissions_module", ] diff --git a/dex/proxy-deployer/wasm/src/lib.rs b/dex/proxy-deployer/wasm/src/lib.rs index 25362983e..410486aa8 100644 --- a/dex/proxy-deployer/wasm/src/lib.rs +++ b/dex/proxy-deployer/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 11 +// Endpoints: 16 // Async Callback (empty): 1 -// Total number of exported functions: 14 +// Total number of exported functions: 19 #![no_std] @@ -21,10 +21,15 @@ multiversx_sc_wasm_adapter::endpoints! { init => init upgrade => upgrade deployFarmStakingContract => deploy_farm_staking_contract + setContractActive => set_contract_active + blacklistUser => blacklist_user removeAllByDeployer => remove_all_by_deployer removeSingleContract => remove_single_contract getDeployerType => deployer_type getTemplateAddress => template_address + getTimestampOracleAddress => timestamp_oracle_address + getBoostedYieldsFactors => boosted_yields_factors + isUserBlacklisted => is_user_blacklisted getAddressForToken => get_address_for_token getTokenForAddress => get_token_for_address getContractOwner => get_contract_owner diff --git a/energy-integration/farm-boosted-yields/src/boosted_yields_factors.rs b/energy-integration/farm-boosted-yields/src/boosted_yields_factors.rs index 1bd34eb6c..c355cb490 100644 --- a/energy-integration/farm-boosted-yields/src/boosted_yields_factors.rs +++ b/energy-integration/farm-boosted-yields/src/boosted_yields_factors.rs @@ -109,7 +109,7 @@ pub trait BoostedYieldsFactorsModule: min_energy_amount: BigUint, min_farm_amount: BigUint, ) { - self.require_caller_has_admin_permissions(); + self.require_caller_has_owner_permissions(); require!( min_energy_amount > 0 && min_farm_amount > 0, "Min amounts must be greater than 0" From 79fa39ff3e9a637a676925a2a4f3c1844581bf21 Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Thu, 28 Nov 2024 10:37:52 +0200 Subject: [PATCH 18/23] new endpoint --- dex/proxy-deployer/src/remove_contracts.rs | 26 +++++++++++++++++----- dex/proxy-deployer/wasm/src/lib.rs | 5 +++-- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/dex/proxy-deployer/src/remove_contracts.rs b/dex/proxy-deployer/src/remove_contracts.rs index 0e55e21a2..76d4ba989 100644 --- a/dex/proxy-deployer/src/remove_contracts.rs +++ b/dex/proxy-deployer/src/remove_contracts.rs @@ -61,6 +61,27 @@ pub trait RemoveContractsModule: crate::storage::StorageModule { self.remove_contract(contract_id); } + #[endpoint(removeOwnContract)] + fn remove_own_contract(&self, contract: ManagedAddress) { + let caller = self.blockchain().get_caller(); + let id_mapper = self.address_id(); + let caller_id = id_mapper.get_id_non_zero(&caller); + let contract_id = id_mapper.get_id_non_zero(&contract); + let deployer_id = self.contract_owner(contract_id).get(); + require!( + caller_id == deployer_id, + "Only the contract deployer may call this endpoint" + ); + + let _ = self + .contracts_by_address(deployer_id) + .swap_remove(&contract_id); + + let deployer_address = self.get_by_id(&id_mapper, deployer_id); + self.remove_admin(contract, deployer_address); + self.remove_contract(contract_id); + } + fn remove_admin(&self, contract: ManagedAddress, user: ManagedAddress) { self.remove_user_proxy(contract) .remove_admin_endpoint(user) @@ -75,11 +96,6 @@ pub trait RemoveContractsModule: crate::storage::StorageModule { self.contract_owner(contract_id).clear(); } - // TODO: Remove by deployer - - - - // For now, both farm and farm_staking use the same internal permissions module. // // Create two separate proxies if this if this ever changes. diff --git a/dex/proxy-deployer/wasm/src/lib.rs b/dex/proxy-deployer/wasm/src/lib.rs index 410486aa8..de33813fe 100644 --- a/dex/proxy-deployer/wasm/src/lib.rs +++ b/dex/proxy-deployer/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 16 +// Endpoints: 17 // Async Callback (empty): 1 -// Total number of exported functions: 19 +// Total number of exported functions: 20 #![no_std] @@ -25,6 +25,7 @@ multiversx_sc_wasm_adapter::endpoints! { blacklistUser => blacklist_user removeAllByDeployer => remove_all_by_deployer removeSingleContract => remove_single_contract + removeOwnContract => remove_own_contract getDeployerType => deployer_type getTemplateAddress => template_address getTimestampOracleAddress => timestamp_oracle_address From c79463cdf89150592720bd2d93708ae0ca9530ee Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Thu, 28 Nov 2024 11:17:36 +0200 Subject: [PATCH 19/23] more tests --- dex/proxy-deployer/src/set_contract_active.rs | 2 + .../proxy_deployer_farm_staking_setup/mod.rs | 51 ++++- .../proxy_deployer_farm_staking_tests.rs | 198 +++++++++++++++--- 3 files changed, 221 insertions(+), 30 deletions(-) diff --git a/dex/proxy-deployer/src/set_contract_active.rs b/dex/proxy-deployer/src/set_contract_active.rs index 10a73b401..43095107b 100644 --- a/dex/proxy-deployer/src/set_contract_active.rs +++ b/dex/proxy-deployer/src/set_contract_active.rs @@ -13,6 +13,8 @@ pub trait SetContractActiveModule: crate::storage::StorageModule { /// Only callable by contract deployer /// /// Calling this endpoint multiple times is the same as calling the specific endpoints in farm by the deployer + /// + /// NOTE: Must issue farm token first! #[endpoint(setContractActive)] fn set_contract_active( &self, diff --git a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_setup/mod.rs b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_setup/mod.rs index 726789f72..7b155c6be 100644 --- a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_setup/mod.rs +++ b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_setup/mod.rs @@ -1,10 +1,14 @@ -use common_structs::Timestamp; +use common_structs::{Epoch, Timestamp}; +use farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactors; use multiversx_sc::types::Address; use multiversx_sc_scenario::{ imports::{BlockchainStateWrapper, ContractObjWrapper}, - managed_address, rust_biguint, DebugApi, + managed_address, managed_biguint, managed_token_id, rust_biguint, DebugApi, +}; +use proxy_deployer::{ + deploy::DeployModule, set_contract_active::SetContractActiveModule, storage::DeployerType, + ProxyDeployer, }; -use proxy_deployer::{storage::DeployerType, ProxyDeployer}; use timestamp_oracle::{epoch_to_timestamp::EpochToTimestampModule, TimestampOracle}; pub const TIMESTAMP_PER_EPOCH: Timestamp = 24 * 60 * 60; @@ -68,6 +72,13 @@ where managed_address!(template_wrapper.address_ref()), DeployerType::FarmStaking, managed_address!(timestamp_oracle_wrapper.address_ref()), + BoostedYieldsFactors { + max_rewards_factor: managed_biguint!(10), + user_rewards_energy_const: managed_biguint!(3), + user_rewards_farm_const: managed_biguint!(2), + min_energy_amount: managed_biguint!(1), + min_farm_amount: managed_biguint!(1), + }, ); }) .assert_ok(); @@ -80,4 +91,38 @@ where template_wrapper, } } + + pub fn deploy_farm_staking(&mut self, token_id: &[u8], max_apr: u64, min_unbond_epochs: Epoch) { + self.b_mock + .execute_tx( + &self.user, + &self.proxy_deployer_wrapper, + &rust_biguint!(0), + |sc| { + sc.deploy_farm_staking_contract( + managed_token_id!(token_id), + managed_biguint!(max_apr), + min_unbond_epochs, + ); + }, + ) + .assert_ok(); + } + + pub fn set_contract_active(&mut self, contract: &Address) { + self.b_mock + .execute_tx( + &self.user, + &self.proxy_deployer_wrapper, + &rust_biguint!(0), + |sc| { + sc.set_contract_active( + managed_address!(contract), + managed_biguint!(1_000), + 1_000, // 10% + ); + }, + ) + .assert_ok(); + } } diff --git a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs index 51b37bfc8..d431e9d51 100644 --- a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs +++ b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs @@ -1,8 +1,12 @@ -use farm_staking::custom_rewards::CustomRewardsModule; +use farm_staking::{custom_rewards::CustomRewardsModule, stake_farm::StakeFarmModule}; use farm_token::FarmTokenModule; -use multiversx_sc::imports::StorageTokenWrapper; +use multiversx_sc::{ + codec::Empty, + imports::{OptionalValue, StorageTokenWrapper}, + types::EsdtLocalRole, +}; use multiversx_sc_scenario::{managed_address, managed_biguint, managed_token_id, rust_biguint}; -use proxy_deployer::{deploy::DeployModule, remove_contracts::RemoveContractsModule}; +use proxy_deployer::{remove_contracts::RemoveContractsModule, views::ViewModule}; use proxy_deployer_farm_staking_setup::ProxyDeployerFarmStakingSetup; pub mod proxy_deployer_farm_staking_setup; @@ -26,21 +30,7 @@ fn deploy_farm_staking_test() { setup.proxy_deployer_wrapper.address_ref(), farm_staking::contract_obj, ); - setup - .b_mock - .execute_tx( - &setup.user, - &setup.proxy_deployer_wrapper, - &rust_biguint!(0), - |sc| { - sc.deploy_farm_staking_contract( - managed_token_id!(b"COOLTOK-123456"), - managed_biguint!(7_500), - 10, - ); - }, - ) - .assert_ok(); + setup.deploy_farm_staking(&b"COOLTOK-123456"[..], 7_500, 10); // user call admin function on new farm staking setup @@ -87,32 +77,186 @@ fn remove_single_contract_test() { setup.proxy_deployer_wrapper.address_ref(), farm_staking::contract_obj, ); + setup.deploy_farm_staking(&b"COOLTOK-123456"[..], 7_500, 10); + + // owner remove the contract setup .b_mock .execute_tx( - &setup.user, + &setup.owner, &setup.proxy_deployer_wrapper, &rust_biguint!(0), |sc| { - sc.deploy_farm_staking_contract( - managed_token_id!(b"COOLTOK-123456"), - managed_biguint!(7_500), - 10, - ); + sc.remove_single_contract(managed_address!(new_sc_wrapper.address_ref())); }, ) .assert_ok(); +} - // owner remove the contracts +#[test] +fn user_remove_contract_test() { + let mut setup = ProxyDeployerFarmStakingSetup::new( + proxy_deployer::contract_obj, + farm_staking::contract_obj, + ); + + let new_sc_wrapper = setup.b_mock.prepare_deploy_from_sc( + setup.proxy_deployer_wrapper.address_ref(), + farm_staking::contract_obj, + ); + + setup.deploy_farm_staking(&b"COOLTOK-123456"[..], 7_500, 10); + + // user remove the contract setup .b_mock .execute_tx( - &setup.owner, + &setup.user, &setup.proxy_deployer_wrapper, &rust_biguint!(0), |sc| { - sc.remove_single_contract(managed_address!(new_sc_wrapper.address_ref())); + sc.remove_own_contract(managed_address!(new_sc_wrapper.address_ref())); }, ) .assert_ok(); } + +#[test] +fn set_contract_active_test() { + let mut setup = ProxyDeployerFarmStakingSetup::new( + proxy_deployer::contract_obj, + farm_staking::contract_obj, + ); + + let new_sc_wrapper = setup.b_mock.prepare_deploy_from_sc( + setup.proxy_deployer_wrapper.address_ref(), + farm_staking::contract_obj, + ); + let farming_token_id = b"COOLTOK-123456"; + let farm_token_id = b"MYCOOLFARM-123456"; + setup.deploy_farm_staking(&farming_token_id[..], 7_500, 10); + + // simulate farm token issue + setup + .b_mock + .execute_tx(&setup.user, &new_sc_wrapper, &rust_biguint!(0), |sc| { + sc.farm_token() + .set_token_id(managed_token_id!(farm_token_id)); + }) + .assert_ok(); + + setup.b_mock.set_esdt_local_roles( + new_sc_wrapper.address_ref(), + farm_token_id, + &[EsdtLocalRole::NftCreate, EsdtLocalRole::NftBurn], + ); + + // set user balance + setup + .b_mock + .set_esdt_balance(&setup.user, &farming_token_id[..], &rust_biguint!(1_000)); + + // user try enter farm before it's ready + setup + .b_mock + .execute_esdt_transfer( + &setup.user, + &new_sc_wrapper, + &farming_token_id[..], + 0, + &rust_biguint!(1_000), + |sc| { + sc.stake_farm_endpoint(OptionalValue::None); + }, + ) + .assert_user_error("Not active"); + + setup.set_contract_active(new_sc_wrapper.address_ref()); + + // user enter farm again + setup + .b_mock + .execute_esdt_transfer( + &setup.user, + &new_sc_wrapper, + &farming_token_id[..], + 0, + &rust_biguint!(1_000), + |sc| { + sc.stake_farm_endpoint(OptionalValue::None); + }, + ) + .assert_ok(); + + setup.b_mock.check_nft_balance( + &setup.user, + &farm_token_id[..], + 1, + &rust_biguint!(1_000), + Option::<&Empty>::None, + ); +} + +#[test] +fn views_test() { + let mut setup = ProxyDeployerFarmStakingSetup::new( + proxy_deployer::contract_obj, + farm_staking::contract_obj, + ); + + let new_sc_wrapper = setup.b_mock.prepare_deploy_from_sc( + setup.proxy_deployer_wrapper.address_ref(), + farm_staking::contract_obj, + ); + let farming_token_id = b"COOLTOK-123456"; + setup.deploy_farm_staking(&farming_token_id[..], 7_500, 10); + + let user_addr = setup.user.clone(); + setup + .b_mock + .execute_query(&setup.proxy_deployer_wrapper, |sc| { + let is_blacklisted = sc.is_user_blacklisted(managed_address!(&user_addr)); + assert_eq!(is_blacklisted, false); + + let addr_for_tok = sc + .get_address_for_token(managed_token_id!(farming_token_id)) + .into_option() + .unwrap(); + assert_eq!(addr_for_tok, managed_address!(new_sc_wrapper.address_ref())); + + let token_for_addr = sc + .get_token_for_address(managed_address!(new_sc_wrapper.address_ref())) + .into_option() + .unwrap(); + assert_eq!(token_for_addr, managed_token_id!(farming_token_id)); + + let contract_owner = sc + .get_contract_owner(managed_address!(new_sc_wrapper.address_ref())) + .into_option() + .unwrap(); + assert_eq!(contract_owner, managed_address!(&user_addr)); + + let all_used_tokens = sc.get_all_used_tokens(1, 1_000); + assert_eq!(all_used_tokens.len(), 1); + assert_eq!( + (*all_used_tokens.to_vec().get(0)).clone(), + managed_token_id!(farming_token_id) + ); + + let all_deployed_contracts = sc.get_all_deployed_contracts_by_sc(1, 1_000); + assert_eq!(all_deployed_contracts.len(), 1); + assert_eq!( + (*all_deployed_contracts.to_vec().get(0)).clone(), + managed_address!(new_sc_wrapper.address_ref()) + ); + + let all_deployed_by_user = + sc.get_all_deployed_contracts_by_user(managed_address!(&user_addr), 1, 1_000); + assert_eq!(all_deployed_by_user.len(), 1); + assert_eq!( + (*all_deployed_by_user.to_vec().get(0)).clone(), + managed_address!(new_sc_wrapper.address_ref()) + ); + }) + .assert_ok(); +} From aaee2ccf24e05c1198cec455190c380827188baa Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Mon, 2 Dec 2024 10:31:55 +0200 Subject: [PATCH 20/23] evil clippy --- farm-staking/farm-staking-proxy/src/proxy_actions/stake.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/farm-staking/farm-staking-proxy/src/proxy_actions/stake.rs b/farm-staking/farm-staking-proxy/src/proxy_actions/stake.rs index 26e9b2af7..9c4ee127a 100644 --- a/farm-staking/farm-staking-proxy/src/proxy_actions/stake.rs +++ b/farm-staking/farm-staking-proxy/src/proxy_actions/stake.rs @@ -95,12 +95,11 @@ pub trait ProxyStakeModule: }; let new_dual_yield_tokens = self.create_dual_yield_tokens(&dual_yield_token_mapper, &new_attributes); - let output_payments = StakeProxyResult { + + StakeProxyResult { dual_yield_tokens: new_dual_yield_tokens, staking_boosted_rewards: staking_farm_enter_result.boosted_rewards, lp_farm_boosted_rewards, - }; - - output_payments + } } } From dd58d66b7fe31d7269fdaee550ecf8817b975cbd Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Mon, 2 Dec 2024 10:36:15 +0200 Subject: [PATCH 21/23] clippy in tests --- dex/fuzz/src/fuzz_data.rs | 4 ++-- dex/fuzz/src/fuzz_farm.rs | 6 +++--- dex/fuzz/src/fuzz_price_discovery.rs | 2 +- dex/pair/tests/pair_rs_test.rs | 2 +- .../tests/proxy_deployer_farm_staking_tests.rs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dex/fuzz/src/fuzz_data.rs b/dex/fuzz/src/fuzz_data.rs index c7ecdbd0f..35ad4e864 100644 --- a/dex/fuzz/src/fuzz_data.rs +++ b/dex/fuzz/src/fuzz_data.rs @@ -401,12 +401,12 @@ pub mod fuzz_data_tests { let timestamp_oracle_wrapper = blockchain_wrapper.create_sc_account( &rust_zero, - Some(&owner_addr), + Some(owner_addr), timestamp_oracle::contract_obj, "timestamp oracle", ); blockchain_wrapper - .execute_tx(&owner_addr, ×tamp_oracle_wrapper, &rust_zero, |sc| { + .execute_tx(owner_addr, ×tamp_oracle_wrapper, &rust_zero, |sc| { sc.init(0); for i in 0..=21 { diff --git a/dex/fuzz/src/fuzz_farm.rs b/dex/fuzz/src/fuzz_farm.rs index 1660bc994..96a6a01cf 100644 --- a/dex/fuzz/src/fuzz_farm.rs +++ b/dex/fuzz/src/fuzz_farm.rs @@ -61,7 +61,7 @@ pub mod fuzz_farm_test { //randomly add all existing farm positions for merge let merge_farm_positions: bool = fuzzer_data.rng.gen(); - if merge_farm_positions && farm_setup.farmer_info.get(&caller.address).is_some() { + if merge_farm_positions && farm_setup.farmer_info.contains_key(&caller.address) { for farm_token_nonce in farm_setup.farmer_info.get(&caller.address).unwrap().iter() { let farm_token_amount = fuzzer_data.blockchain_wrapper.get_esdt_balance( &caller.address, @@ -221,7 +221,7 @@ pub mod fuzz_farm_test { // When claiming rewards, the caller uses all his farming positions let mut farm_token_amount_check = rust_biguint!(0u64); let mut payments = Vec::new(); - if farm_setup.farmer_info.get(&caller.address).is_some() { + if farm_setup.farmer_info.contains_key(&caller.address) { for farm_token_nonce in farm_setup.farmer_info.get(&caller.address).unwrap().iter() { let farm_token_amount = fuzzer_data.blockchain_wrapper.get_esdt_balance( &caller.address, @@ -320,7 +320,7 @@ pub mod fuzz_farm_test { // When compounding rewards, the caller uses all his farming positions let mut farm_token_amount_check = rust_biguint!(0u64); let mut payments = Vec::new(); - if farm_setup.farmer_info.get(&caller.address).is_some() { + if farm_setup.farmer_info.contains_key(&caller.address) { for farm_token_nonce in farm_setup.farmer_info.get(&caller.address).unwrap().iter() { let farm_token_amount = fuzzer_data.blockchain_wrapper.get_esdt_balance( &caller.address, diff --git a/dex/fuzz/src/fuzz_price_discovery.rs b/dex/fuzz/src/fuzz_price_discovery.rs index d327f947b..63f0fcc3b 100644 --- a/dex/fuzz/src/fuzz_price_discovery.rs +++ b/dex/fuzz/src/fuzz_price_discovery.rs @@ -289,7 +289,7 @@ pub mod fuzz_price_discovery_test { if redeem_token_before < redeem_token_amount_in { if redeem_token_amount_in > rust_zero { - redeem_token_amount_in = redeem_token_before.clone(); + redeem_token_amount_in.clone_from(&redeem_token_before); } else { println!("Price discovery redeem error: Not enough tokens"); fuzzer_data.statistics.price_discovery_redeem_misses += 1; diff --git a/dex/pair/tests/pair_rs_test.rs b/dex/pair/tests/pair_rs_test.rs index 723b3ddf0..8752ee2f4 100644 --- a/dex/pair/tests/pair_rs_test.rs +++ b/dex/pair/tests/pair_rs_test.rs @@ -1387,7 +1387,7 @@ fn add_liquidity_through_simple_lock_proxy() { pair_setup.b_mock.set_block_epoch(5); // add liquidity through simple-lock SC - one locked (WEGLD) token, one unlocked (MEX) - let transfers = vec![ + let transfers = [ TxTokenTransfer { token_identifier: LOCKED_TOKEN_ID.to_vec(), nonce: 1, diff --git a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs index d431e9d51..ad9db9c74 100644 --- a/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs +++ b/dex/proxy-deployer/tests/proxy_deployer_farm_staking_tests.rs @@ -216,7 +216,7 @@ fn views_test() { .b_mock .execute_query(&setup.proxy_deployer_wrapper, |sc| { let is_blacklisted = sc.is_user_blacklisted(managed_address!(&user_addr)); - assert_eq!(is_blacklisted, false); + assert!(!is_blacklisted); let addr_for_tok = sc .get_address_for_token(managed_token_id!(farming_token_id)) From daa6e2ad7b54b9501543c3b8b8a208e23fcee3ff Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Mon, 2 Dec 2024 10:44:26 +0200 Subject: [PATCH 22/23] update rust and build --- dex/proxy-deployer/wasm/Cargo.lock | 22 +++++++++++++++- .../energy-update/wasm/Cargo.lock | 20 ++++++++++++++- .../farm-staking-proxy/wasm/Cargo.lock | 25 ++++++++++++++++++- .../farm-staking-proxy/wasm/src/lib.rs | 2 +- .../farm-staking-proxy-v13/wasm/Cargo.lock | 22 +++++++++++++++- locked-asset/proxy_dex/wasm/Cargo.lock | 22 +++++++++++++++- 6 files changed, 107 insertions(+), 6 deletions(-) diff --git a/dex/proxy-deployer/wasm/Cargo.lock b/dex/proxy-deployer/wasm/Cargo.lock index 00b6cfa66..ba8ce0e7c 100644 --- a/dex/proxy-deployer/wasm/Cargo.lock +++ b/dex/proxy-deployer/wasm/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "arrayvec" @@ -129,9 +129,11 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -178,9 +180,11 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -386,6 +390,14 @@ dependencies = [ "autocfg", ] +[[package]] +name = "original_owner_helper" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "pair" version = "0.0.0" @@ -417,6 +429,14 @@ dependencies = [ "multiversx-sc", ] +[[package]] +name = "permissions_hub_module" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "permissions-hub", +] + [[package]] name = "permissions_module" version = "0.0.0" diff --git a/energy-integration/energy-update/wasm/Cargo.lock b/energy-integration/energy-update/wasm/Cargo.lock index 5879e51a0..414f83b21 100644 --- a/energy-integration/energy-update/wasm/Cargo.lock +++ b/energy-integration/energy-update/wasm/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "arrayvec" @@ -147,9 +147,11 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -372,6 +374,14 @@ dependencies = [ "autocfg", ] +[[package]] +name = "original_owner_helper" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "pair" version = "0.0.0" @@ -403,6 +413,14 @@ dependencies = [ "multiversx-sc", ] +[[package]] +name = "permissions_hub_module" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "permissions-hub", +] + [[package]] name = "permissions_module" version = "0.0.0" diff --git a/farm-staking/farm-staking-proxy/wasm/Cargo.lock b/farm-staking/farm-staking-proxy/wasm/Cargo.lock index 211fad7a4..fdebecdd2 100644 --- a/farm-staking/farm-staking-proxy/wasm/Cargo.lock +++ b/farm-staking/farm-staking-proxy/wasm/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "arrayvec" @@ -129,9 +129,11 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -178,9 +180,11 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -208,6 +212,7 @@ dependencies = [ "pair", "pausable", "permissions-hub", + "permissions_hub_module", "rewards", "sc_whitelist_module", "token_send", @@ -243,8 +248,10 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -456,6 +463,14 @@ dependencies = [ "autocfg", ] +[[package]] +name = "original_owner_helper" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "pair" version = "0.0.0" @@ -487,6 +502,14 @@ dependencies = [ "multiversx-sc", ] +[[package]] +name = "permissions_hub_module" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "permissions-hub", +] + [[package]] name = "permissions_module" version = "0.0.0" diff --git a/farm-staking/farm-staking-proxy/wasm/src/lib.rs b/farm-staking/farm-staking-proxy/wasm/src/lib.rs index 3632ff09e..f37700a58 100644 --- a/farm-staking/farm-staking-proxy/wasm/src/lib.rs +++ b/farm-staking/farm-staking-proxy/wasm/src/lib.rs @@ -29,6 +29,7 @@ multiversx_sc_wasm_adapter::endpoints! { getFarmTokenId => staking_farm_token_id getLpTokenId => lp_token_id getLpFarmTokenId => lp_farm_token_id + setPermissionsHubAddress => set_permissions_hub_address setEnergyFactoryAddress => set_energy_factory_address getEnergyFactoryAddress => energy_factory_address addSCAddressToWhitelist => add_sc_address_to_whitelist @@ -39,7 +40,6 @@ multiversx_sc_wasm_adapter::endpoints! { unstakeFarmTokens => unstake_farm_tokens stakeFarmOnBehalf => stake_farm_on_behalf claimDualYieldOnBehalf => claim_dual_yield_on_behalf - setPermissionsHubAddress => set_permissions_hub_address ) } diff --git a/legacy-contracts/farm-staking-proxy-v13/wasm/Cargo.lock b/legacy-contracts/farm-staking-proxy-v13/wasm/Cargo.lock index 6c0c145ee..6b1ff77aa 100644 --- a/legacy-contracts/farm-staking-proxy-v13/wasm/Cargo.lock +++ b/legacy-contracts/farm-staking-proxy-v13/wasm/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "arrayvec" @@ -129,9 +129,11 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -178,9 +180,11 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -414,6 +418,14 @@ dependencies = [ "autocfg", ] +[[package]] +name = "original_owner_helper" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "pair" version = "0.0.0" @@ -445,6 +457,14 @@ dependencies = [ "multiversx-sc", ] +[[package]] +name = "permissions_hub_module" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "permissions-hub", +] + [[package]] name = "permissions_module" version = "0.0.0" diff --git a/locked-asset/proxy_dex/wasm/Cargo.lock b/locked-asset/proxy_dex/wasm/Cargo.lock index bfc773ea6..1264b51fa 100644 --- a/locked-asset/proxy_dex/wasm/Cargo.lock +++ b/locked-asset/proxy_dex/wasm/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "arrayvec" @@ -129,9 +129,11 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pair", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -178,8 +180,10 @@ dependencies = [ "mergeable", "multiversx-sc", "multiversx-sc-modules", + "original_owner_helper", "pausable", "permissions-hub", + "permissions_hub_module", "permissions_module", "rewards", "sc_whitelist_module", @@ -385,6 +389,14 @@ dependencies = [ "autocfg", ] +[[package]] +name = "original_owner_helper" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "pair" version = "0.0.0" @@ -416,6 +428,14 @@ dependencies = [ "multiversx-sc", ] +[[package]] +name = "permissions_hub_module" +version = "0.0.0" +dependencies = [ + "multiversx-sc", + "permissions-hub", +] + [[package]] name = "permissions_module" version = "0.0.0" From 90f8d811524993f02b9a426627093f051bf9970d Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Mon, 2 Dec 2024 10:51:57 +0200 Subject: [PATCH 23/23] more clippy --- .../farm/contexts/src/storage_cache.rs | 2 +- .../farm_with_locked_rewards_setup/mod.rs | 2 +- .../farm_setup/farm_rewards_distr_setup.rs | 2 +- .../tests/farm_setup/multi_user_farm_setup.rs | 2 +- dex/farm/tests/farm_single_user_test.rs | 12 ++--- dex/fuzz/src/fuzz_data.rs | 2 +- dex/governance/tests/gov_tests.rs | 10 ++-- dex/pair/src/contexts/base.rs | 2 +- dex/router/src/contract.rs | 2 +- .../energy-factory-mock/src/lib.rs | 2 +- .../tests/fees_collector_test_setup/mod.rs | 2 +- .../governance-v2/src/configurable.rs | 53 +++++++++---------- .../governance-v2/tests/gov_test_setup/mod.rs | 8 +-- .../mod.rs | 2 +- .../tests/farm_staking_setup/mod.rs | 2 +- .../farm-staking/tests/farm_staking_test.rs | 6 +-- 16 files changed, 52 insertions(+), 59 deletions(-) diff --git a/common/modules/farm/contexts/src/storage_cache.rs b/common/modules/farm/contexts/src/storage_cache.rs index 76f4cfc1d..e48e5fc85 100644 --- a/common/modules/farm/contexts/src/storage_cache.rs +++ b/common/modules/farm/contexts/src/storage_cache.rs @@ -41,7 +41,7 @@ impl<'a, C: FarmContracTraitBounds> StorageCache<'a, C> { } } -impl<'a, C: FarmContracTraitBounds> Drop for StorageCache<'a, C> { +impl Drop for StorageCache<'_, C> { fn drop(&mut self) { // commit changes to storage for the mutable fields self.sc_ref.reward_reserve().set(&self.reward_reserve); diff --git a/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs b/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs index d7cc9ab23..826d9ae78 100644 --- a/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs +++ b/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_setup/mod.rs @@ -305,7 +305,7 @@ where &self.energy_factory_wrapper, &rust_biguint!(0), |sc| { - sc.user_energy(&managed_address!(user)).set(&Energy::new( + sc.user_energy(&managed_address!(user)).set(Energy::new( BigInt::from(managed_biguint!(energy)), last_update_epoch, managed_biguint!(locked_tokens), diff --git a/dex/farm/tests/farm_setup/farm_rewards_distr_setup.rs b/dex/farm/tests/farm_setup/farm_rewards_distr_setup.rs index 23dada913..a6603a78d 100644 --- a/dex/farm/tests/farm_setup/farm_rewards_distr_setup.rs +++ b/dex/farm/tests/farm_setup/farm_rewards_distr_setup.rs @@ -121,7 +121,7 @@ where sc.farm_token().set_token_id(farm_token_id); sc.per_block_reward_amount() - .set(&to_managed_biguint(per_block_reward_amount)); + .set(to_managed_biguint(per_block_reward_amount)); sc.state().set(State::Active); sc.produce_rewards_enabled().set(true); diff --git a/dex/farm/tests/farm_setup/multi_user_farm_setup.rs b/dex/farm/tests/farm_setup/multi_user_farm_setup.rs index e9ec051ca..bb790058b 100644 --- a/dex/farm/tests/farm_setup/multi_user_farm_setup.rs +++ b/dex/farm/tests/farm_setup/multi_user_farm_setup.rs @@ -271,7 +271,7 @@ where &self.energy_factory_wrapper, &rust_biguint!(0), |sc| { - sc.user_energy(&managed_address!(user)).set(&Energy::new( + sc.user_energy(&managed_address!(user)).set(Energy::new( BigInt::from(managed_biguint!(energy)), last_update_epoch, managed_biguint!(locked_tokens), diff --git a/dex/farm/tests/farm_single_user_test.rs b/dex/farm/tests/farm_single_user_test.rs index c2bede496..5f2586dcb 100644 --- a/dex/farm/tests/farm_single_user_test.rs +++ b/dex/farm/tests/farm_single_user_test.rs @@ -126,10 +126,8 @@ where let second_reward_share = DIVISION_SAFETY_CONSTANT * 10 * PER_BLOCK_REWARD_AMOUNT / current_farm_supply; let expected_reward_per_share = (first_reward_share * farm_in_amount - + second_reward_share * second_farm_in_amount - + total_amount - - 1) - / total_amount; + + second_reward_share * second_farm_in_amount) + .div_ceil(total_amount); farm_setup.enter_farm( second_farm_in_amount, @@ -174,10 +172,8 @@ fn test_exit_farm_after_enter_twice() { let second_reward_share = DIVISION_SAFETY_CONSTANT * 10 * PER_BLOCK_REWARD_AMOUNT / current_farm_supply; let prev_reward_per_share = (first_reward_share * farm_in_amount - + second_reward_share * second_farm_in_amount - + total_farm_token - - 1) - / total_farm_token; + + second_reward_share * second_farm_in_amount) + .div_ceil(total_farm_token); let new_reward_per_share = prev_reward_per_share + 25 * PER_BLOCK_REWARD_AMOUNT * DIVISION_SAFETY_CONSTANT / total_farm_token; let reward_per_share_diff = new_reward_per_share - prev_reward_per_share; diff --git a/dex/fuzz/src/fuzz_data.rs b/dex/fuzz/src/fuzz_data.rs index 35ad4e864..93e6e7bff 100644 --- a/dex/fuzz/src/fuzz_data.rs +++ b/dex/fuzz/src/fuzz_data.rs @@ -434,7 +434,7 @@ pub mod fuzz_data_tests { sc.farm_token().set_token_id(farm_token_id); sc.per_block_reward_amount() - .set(&to_managed_biguint(per_block_reward_amount)); + .set(to_managed_biguint(per_block_reward_amount)); sc.state().set(State::Active); sc.produce_rewards_enabled().set(true); diff --git a/dex/governance/tests/gov_tests.rs b/dex/governance/tests/gov_tests.rs index 1a05e7180..7a377e307 100644 --- a/dex/governance/tests/gov_tests.rs +++ b/dex/governance/tests/gov_tests.rs @@ -178,7 +178,7 @@ fn test_propose_bad_token() { }); }, ) - .assert_user_error(&String::from_utf8(UNREGISTERED_TOKEN_ID.to_vec()).unwrap()); + .assert_user_error(core::str::from_utf8(UNREGISTERED_TOKEN_ID).unwrap()); } #[test] @@ -200,7 +200,7 @@ fn test_propose_bad_amount() { }); }, ) - .assert_user_error(&String::from_utf8(NOT_ENOUGH_FUNDS_TO_PROPOSE.to_vec()).unwrap()); + .assert_user_error(core::str::from_utf8(NOT_ENOUGH_FUNDS_TO_PROPOSE).unwrap()); } #[test] @@ -418,7 +418,7 @@ fn test_basic_reclaim() { sc.redeem(); }, ) - .assert_user_error(&String::from_utf8(VOTING_PERIOD_NOT_ENDED.to_vec()).unwrap()); + .assert_user_error(core::str::from_utf8(VOTING_PERIOD_NOT_ENDED).unwrap()); gov_setup .blockchain_wrapper @@ -495,7 +495,7 @@ fn test_vote() { sc.upvote(0); }, ) - .assert_user_error(&String::from_utf8(PROPOSAL_NOT_ACTIVE.to_vec()).unwrap()); + .assert_user_error(core::str::from_utf8(PROPOSAL_NOT_ACTIVE).unwrap()); gov_setup .blockchain_wrapper @@ -565,7 +565,7 @@ fn test_vote() { sc.redeem(); }, ) - .assert_user_error(&String::from_utf8(VOTING_PERIOD_NOT_ENDED.to_vec()).unwrap()); + .assert_user_error(core::str::from_utf8(VOTING_PERIOD_NOT_ENDED).unwrap()); gov_setup .blockchain_wrapper diff --git a/dex/pair/src/contexts/base.rs b/dex/pair/src/contexts/base.rs index 751ca7fc1..94ff5c292 100644 --- a/dex/pair/src/contexts/base.rs +++ b/dex/pair/src/contexts/base.rs @@ -97,7 +97,7 @@ where } } -impl<'a, C> Drop for StorageCache<'a, C> +impl Drop for StorageCache<'_, C> where C: crate::config::ConfigModule, { diff --git a/dex/router/src/contract.rs b/dex/router/src/contract.rs index f879e36e6..800a20b91 100644 --- a/dex/router/src/contract.rs +++ b/dex/router/src/contract.rs @@ -39,7 +39,7 @@ pub trait Router: self.pair_creation_enabled().set_if_empty(false); self.init_factory(pair_template_address_opt.into_option()); - self.owner().set(&self.blockchain().get_caller()); + self.owner().set(self.blockchain().get_caller()); } #[upgrade] diff --git a/energy-integration/energy-factory-mock/src/lib.rs b/energy-integration/energy-factory-mock/src/lib.rs index d3354e67e..9ed54cc6c 100644 --- a/energy-integration/energy-factory-mock/src/lib.rs +++ b/energy-integration/energy-factory-mock/src/lib.rs @@ -17,7 +17,7 @@ pub trait EnergyFactoryMock { total_locked_tokens: BigUint, ) { let current_epoch = self.blockchain().get_block_epoch(); - self.user_energy(&user).set(&Energy::new( + self.user_energy(&user).set(Energy::new( BigInt::from(energy_amount), current_epoch, total_locked_tokens, diff --git a/energy-integration/fees-collector/tests/fees_collector_test_setup/mod.rs b/energy-integration/fees-collector/tests/fees_collector_test_setup/mod.rs index 93e6da275..1f1a09b48 100644 --- a/energy-integration/fees-collector/tests/fees_collector_test_setup/mod.rs +++ b/energy-integration/fees-collector/tests/fees_collector_test_setup/mod.rs @@ -253,7 +253,7 @@ where &self.energy_factory_wrapper, &rust_biguint!(0), |sc| { - sc.user_energy(&managed_address!(user)).set(&Energy::new( + sc.user_energy(&managed_address!(user)).set(Energy::new( BigInt::from(managed_biguint!(energy_amount)), current_epoch, managed_biguint!(total_locked_tokens), diff --git a/energy-integration/governance-v2/src/configurable.rs b/energy-integration/governance-v2/src/configurable.rs index 12751ce7f..b74f83b0b 100644 --- a/energy-integration/governance-v2/src/configurable.rs +++ b/energy-integration/governance-v2/src/configurable.rs @@ -2,33 +2,32 @@ use crate::errors::ERROR_NOT_AN_ESDT; multiversx_sc::imports!(); -/// # MultiversX smart contract module - Governance -/// -/// This is a standard smart contract module, that when added to a smart contract offers governance features: -/// - proposing actions -/// - voting/downvoting a certain proposal -/// - after a voting period, either putting the action in a queue (if it reached quorum), or canceling -/// -/// Voting is done through energy. -/// -/// The module provides the following configurable parameters: -/// - `minEnergyForPropose` - the minimum energy required for submitting a proposal -/// - `quorum` - the minimum number of (`votes` minus `downvotes`) at the end of voting period -/// - `maxActionsPerProposal` - Maximum number of actions (transfers and/or smart contract calls) that a proposal may have -/// - `votingDelayInBlocks` - Number of blocks to wait after a block is proposed before being able to vote/downvote that proposal -/// - `votingPeriodInBlocks` - Number of blocks the voting period lasts (voting delay does not count towards this) -/// - `lockTimeAfterVotingEndsInBlocks` - Number of blocks to wait before a successful proposal can be executed -/// -/// The module also provides events for most actions that happen: -/// - `proposalCreated` - triggers when a proposal is created. Also provoides all the relevant information, like proposer, actions etc. -/// - `voteCast` - user voted on a proposal -/// - `downvoteCast` - user downvoted a proposal -/// - `proposalCanceled`, `proposalQueued` and `proposalExecuted` - provides the ID of the specific proposal -/// - `userDeposit` - a user deposited some tokens needed for a future payable action -/// -/// Please note that although the main contract can modify the module's storage directly, it is not recommended to do so, -/// as that defeats the whole purpose of having governance. These parameters should only be modified through actions. -/// +// # MultiversX smart contract module - Governance +// +// This is a standard smart contract module, that when added to a smart contract offers governance features: +// - proposing actions +// - voting/downvoting a certain proposal +// - after a voting period, either putting the action in a queue (if it reached quorum), or canceling +// +// Voting is done through energy. +// +// The module provides the following configurable parameters: +// - `minEnergyForPropose` - the minimum energy required for submitting a proposal +// - `quorum` - the minimum number of (`votes` minus `downvotes`) at the end of voting period +// - `maxActionsPerProposal` - Maximum number of actions (transfers and/or smart contract calls) that a proposal may have +// - `votingDelayInBlocks` - Number of blocks to wait after a block is proposed before being able to vote/downvote that proposal +// - `votingPeriodInBlocks` - Number of blocks the voting period lasts (voting delay does not count towards this) +// - `lockTimeAfterVotingEndsInBlocks` - Number of blocks to wait before a successful proposal can be executed +// +// The module also provides events for most actions that happen: +// - `proposalCreated` - triggers when a proposal is created. Also provoides all the relevant information, like proposer, actions etc. +// - `voteCast` - user voted on a proposal +// - `downvoteCast` - user downvoted a proposal +// - `proposalCanceled`, `proposalQueued` and `proposalExecuted` - provides the ID of the specific proposal +// - `userDeposit` - a user deposited some tokens needed for a future payable action +// +// Please note that although the main contract can modify the module's storage directly, it is not recommended to do so, +// as that defeats the whole purpose of having governance. These parameters should only be modified through actions. const MIN_VOTING_DELAY: u64 = 1; const MAX_VOTING_DELAY: u64 = 100_800; // 1 Week diff --git a/energy-integration/governance-v2/tests/gov_test_setup/mod.rs b/energy-integration/governance-v2/tests/gov_test_setup/mod.rs index 465222293..4809577bf 100644 --- a/energy-integration/governance-v2/tests/gov_test_setup/mod.rs +++ b/energy-integration/governance-v2/tests/gov_test_setup/mod.rs @@ -79,25 +79,25 @@ where .execute_tx(&owner, &energy_factory_wrapper, &rust_zero, |sc| { sc.init(); sc.user_energy(&managed_address!(&first_user)) - .set(&Energy::new( + .set(Energy::new( BigInt::from(managed_biguint!(USER_ENERGY)), 0, managed_biguint!(0), )); sc.user_energy(&managed_address!(&second_user)) - .set(&Energy::new( + .set(Energy::new( BigInt::from(managed_biguint!(USER_ENERGY)), 0, managed_biguint!(0), )); sc.user_energy(&managed_address!(&third_user)) - .set(&Energy::new( + .set(Energy::new( BigInt::from(managed_biguint!(USER_ENERGY + 210_000)), 0, managed_biguint!(0), )); sc.user_energy(&managed_address!(&no_energy_user)) - .set(&Energy::new( + .set(Energy::new( BigInt::from(managed_biguint!(0)), 0, managed_biguint!(0), diff --git a/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs index c0d4ec4d3..640af81b4 100644 --- a/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs +++ b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs @@ -760,7 +760,7 @@ where &self.energy_factory_wrapper, &rust_biguint!(0), |sc| { - sc.user_energy(&managed_address!(user)).set(&Energy::new( + sc.user_energy(&managed_address!(user)).set(Energy::new( BigInt::from(managed_biguint!(energy)), last_update_epoch, managed_biguint!(locked_tokens), diff --git a/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs b/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs index 7a46618cd..66235a25a 100644 --- a/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs +++ b/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs @@ -785,7 +785,7 @@ where &self.energy_factory_wrapper, &rust_biguint!(0), |sc| { - sc.user_energy(&managed_address!(user)).set(&Energy::new( + sc.user_energy(&managed_address!(user)).set(Energy::new( BigInt::from(managed_biguint!(energy)), last_update_epoch, managed_biguint!(locked_tokens), diff --git a/farm-staking/farm-staking/tests/farm_staking_test.rs b/farm-staking/farm-staking/tests/farm_staking_test.rs index 4e00cfdef..4f2471fde 100644 --- a/farm-staking/farm-staking/tests/farm_staking_test.rs +++ b/farm-staking/farm-staking/tests/farm_staking_test.rs @@ -203,10 +203,8 @@ where let first_reward_share = 0; let second_reward_share = 400_000; let expected_reward_per_share = (first_reward_share * farm_in_amount - + second_reward_share * second_farm_in_amount - + total_amount - - 1) - / total_amount; + + second_reward_share * second_farm_in_amount) + .div_ceil(total_amount); farm_setup.stake_farm( &user_address,