diff --git a/Cargo.lock b/Cargo.lock index 4b4c525d9..2ddd50659 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,13 +182,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -539,6 +532,7 @@ dependencies = [ "rewards", "sc_whitelist_module", "simple-lock", + "timestamp-oracle", "token_send", "utils", "week-timekeeping", @@ -557,12 +551,15 @@ dependencies = [ name = "farm-boosted-yields" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "config", "energy-query", + "math", "multiversx-sc", "pausable", "permissions_module", + "timestamp-oracle", + "utils", "week-timekeeping", "weekly-rewards-splitting", ] @@ -597,6 +594,7 @@ dependencies = [ "permissions_module", "rewards", "sc_whitelist_module", + "timestamp-oracle", "token_send", "utils", "week-timekeeping", @@ -639,6 +637,7 @@ dependencies = [ "rewards", "sc_whitelist_module", "simple-lock", + "timestamp-oracle", "token_send", "unwrappable", "utils", @@ -782,6 +781,7 @@ dependencies = [ "rewards", "sc_whitelist_module", "simple-lock", + "timestamp-oracle", "token_send", "utils", "week-timekeeping", @@ -823,22 +823,18 @@ dependencies = [ name = "farm_token" version = "0.0.0" dependencies = [ - "common_errors", "common_structs", - "config", "multiversx-sc", "multiversx-sc-modules", - "pausable", "permissions_module", - "token_send", ] [[package]] name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -1654,6 +1650,7 @@ dependencies = [ "rewards", "sc_whitelist_module", "simple-lock", + "timestamp-oracle", "token_merge_helper", "token_send", "utils", @@ -1951,6 +1948,24 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "timestamp-oracle" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", + "multiversx-sc-scenario", + "num-bigint", +] + +[[package]] +name = "timestamp-oracle-meta" +version = "0.0.0" +dependencies = [ + "multiversx-sc-meta-lib", + "timestamp-oracle", +] + [[package]] name = "token-unstake" version = "0.0.0" @@ -2118,7 +2133,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -2126,10 +2141,12 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", + "multiversx-sc-scenario", + "num-bigint", "unwrappable", "week-timekeeping", ] diff --git a/Cargo.toml b/Cargo.toml index b36732c3b..fa0bdca20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,8 @@ members = [ "energy-integration/fees-collector/meta", "energy-integration/governance-v2", "energy-integration/governance-v2/meta", + "energy-integration/timestamp-oracle", + "energy-integration/timestamp-oracle/meta", "farm-staking/farm-staking", "farm-staking/farm-staking/meta", diff --git a/common/common_structs/src/alias_types.rs b/common/common_structs/src/alias_types.rs index 0bec7be83..77dd8e63d 100644 --- a/common/common_structs/src/alias_types.rs +++ b/common/common_structs/src/alias_types.rs @@ -6,6 +6,7 @@ pub type Nonce = u64; pub type Epoch = u64; pub type Week = usize; pub type Percent = u64; +pub type Timestamp = u64; pub type PaymentsVec = ManagedVec>; pub type UnlockPeriod = UnlockSchedule; pub type OldLockedTokenAttributes = LockedAssetTokenAttributesEx; diff --git a/common/modules/farm/config/src/config.rs b/common/modules/farm/config/src/config.rs index 88858153e..92616cbfc 100644 --- a/common/modules/farm/config/src/config.rs +++ b/common/modules/farm/config/src/config.rs @@ -3,7 +3,7 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); -use common_structs::Nonce; +use common_structs::{FarmToken, Nonce, PaymentsVec}; use pausable::State; pub const DEFAULT_NFT_DEPOSIT_MAX_LEN: usize = 10; @@ -44,6 +44,61 @@ pub trait ConfigModule: pausable::PausableModule + permissions_module::Permissio .set(migration_farm_token_nonce); } + fn check_and_update_user_farm_position + TopDecode>( + &self, + user: &ManagedAddress, + farm_positions: &PaymentsVec, + farm_token_mapper: &NonFungibleTokenMapper, + ) { + for farm_position in farm_positions { + farm_token_mapper.require_same_token(&farm_position.token_identifier); + + if self.is_old_farm_position(farm_position.token_nonce) { + continue; + } + + let token_attributes: T = + farm_token_mapper.get_token_attributes(farm_position.token_nonce); + + if &token_attributes.get_original_owner() != user { + self.decrease_user_farm_position::(&farm_position, farm_token_mapper); + self.increase_user_farm_position(user, &farm_position.amount); + } + } + } + + #[inline] + fn increase_user_farm_position( + &self, + user: &ManagedAddress, + increase_farm_position_amount: &BigUint, + ) { + self.user_total_farm_position(user) + .update(|total_farm_position| *total_farm_position += increase_farm_position_amount); + } + + fn decrease_user_farm_position + TopDecode>( + &self, + farm_position: &EsdtTokenPayment, + farm_token_mapper: &NonFungibleTokenMapper, + ) { + if self.is_old_farm_position(farm_position.token_nonce) { + return; + } + + let token_attributes: T = farm_token_mapper.get_token_attributes(farm_position.token_nonce); + let user_total_farm_position_mapper = + self.user_total_farm_position(&token_attributes.get_original_owner()); + let mut user_total_farm_position = user_total_farm_position_mapper.get(); + + if user_total_farm_position > farm_position.amount { + user_total_farm_position -= &farm_position.amount; + user_total_farm_position_mapper.set(user_total_farm_position); + } else { + user_total_farm_position_mapper.clear(); + } + } + #[view(getFarmingTokenId)] #[storage_mapper("farming_token_id")] fn farming_token_id(&self) -> SingleValueMapper; diff --git a/common/modules/farm/farm_base_impl/src/base_traits_impl.rs b/common/modules/farm/farm_base_impl/src/base_traits_impl.rs index f7f5014ff..f5cc83be3 100644 --- a/common/modules/farm/farm_base_impl/src/base_traits_impl.rs +++ b/common/modules/farm/farm_base_impl/src/base_traits_impl.rs @@ -4,10 +4,8 @@ use common_structs::{FarmToken, FarmTokenAttributes, Nonce}; use config::ConfigModule; use contexts::storage_cache::StorageCache; use core::marker::PhantomData; -use farm_token::FarmTokenModule; use fixed_supply_token::FixedSupplyToken; use mergeable::Mergeable; -use multiversx_sc_modules::transfer_role_proxy::PaymentsVec; use rewards::RewardsModule; pub trait AllBaseFarmImplTraits: @@ -184,79 +182,6 @@ pub trait FarmContract { new_attributes.into() } - - fn get_exit_penalty( - _sc: &Self::FarmSc, - _total_exit_amount: &BigUint<::Api>, - _token_attributes: &Self::AttributesType, - ) -> BigUint<::Api> { - BigUint::zero() - } - - fn apply_penalty( - _sc: &Self::FarmSc, - _total_exit_amount: &mut BigUint<::Api>, - _token_attributes: &Self::AttributesType, - _storage_cache: &StorageCache, - ) { - } - - fn check_and_update_user_farm_position( - sc: &Self::FarmSc, - user: &ManagedAddress<::Api>, - farm_positions: &PaymentsVec<::Api>, - ) { - let farm_token_mapper = sc.farm_token(); - for farm_position in farm_positions { - farm_token_mapper.require_same_token(&farm_position.token_identifier); - - if sc.is_old_farm_position(farm_position.token_nonce) { - continue; - } - - let token_attributes: FarmTokenAttributes<::Api> = - farm_token_mapper.get_token_attributes(farm_position.token_nonce); - - if &token_attributes.original_owner != user { - Self::decrease_user_farm_position(sc, &farm_position); - Self::increase_user_farm_position(sc, user, &farm_position.amount); - } - } - } - - #[inline] - fn increase_user_farm_position( - sc: &Self::FarmSc, - user: &ManagedAddress<::Api>, - increase_farm_position_amount: &BigUint<::Api>, - ) { - sc.user_total_farm_position(user) - .update(|total_farm_position| *total_farm_position += increase_farm_position_amount); - } - - fn decrease_user_farm_position( - sc: &Self::FarmSc, - farm_position: &EsdtTokenPayment<::Api>, - ) { - if sc.is_old_farm_position(farm_position.token_nonce) { - return; - } - - let farm_token_mapper = sc.farm_token(); - let token_attributes: FarmTokenAttributes<::Api> = - farm_token_mapper.get_token_attributes(farm_position.token_nonce); - - let user_total_farm_position_mapper = - sc.user_total_farm_position(&token_attributes.original_owner); - let mut user_total_farm_position = user_total_farm_position_mapper.get(); - - if user_total_farm_position > farm_position.amount { - user_total_farm_position -= &farm_position.amount; - user_total_farm_position_mapper.set(user_total_farm_position); - } else { - user_total_farm_position_mapper.clear(); - } - } } pub struct DefaultFarmWrapper diff --git a/common/modules/farm/farm_base_impl/src/claim_rewards.rs b/common/modules/farm/farm_base_impl/src/claim_rewards.rs index d9dfe293e..b862b1355 100644 --- a/common/modules/farm/farm_base_impl/src/claim_rewards.rs +++ b/common/modules/farm/farm_base_impl/src/claim_rewards.rs @@ -81,7 +81,11 @@ pub trait BaseClaimRewardsModule: ); storage_cache.reward_reserve -= &reward; - FC::check_and_update_user_farm_position(self, &caller, &payments); + self.check_and_update_user_farm_position::( + &caller, + &payments, + &self.farm_token(), + ); let farm_token_mapper = self.farm_token(); let base_attributes = FC::create_claim_rewards_initial_attributes( diff --git a/common/modules/farm/farm_base_impl/src/compound_rewards.rs b/common/modules/farm/farm_base_impl/src/compound_rewards.rs index 06e52585c..cbde8f124 100644 --- a/common/modules/farm/farm_base_impl/src/compound_rewards.rs +++ b/common/modules/farm/farm_base_impl/src/compound_rewards.rs @@ -70,7 +70,11 @@ pub trait BaseCompoundRewardsModule: storage_cache.reward_reserve -= &reward; storage_cache.farm_token_supply += &reward; - FC::check_and_update_user_farm_position(self, &caller, &payments); + self.check_and_update_user_farm_position::( + &caller, + &payments, + &self.farm_token(), + ); let farm_token_mapper = self.farm_token(); let base_attributes = FC::create_compound_rewards_initial_attributes( @@ -86,7 +90,7 @@ pub trait BaseCompoundRewardsModule: &farm_token_mapper, ); - FC::increase_user_farm_position(self, &caller, &reward); + self.increase_user_farm_position(&caller, &reward); let first_farm_token = &compound_rewards_context.first_farm_token.payment; farm_token_mapper.nft_burn(first_farm_token.token_nonce, &first_farm_token.amount); diff --git a/common/modules/farm/farm_base_impl/src/enter_farm.rs b/common/modules/farm/farm_base_impl/src/enter_farm.rs index 02e20d42a..5ef08c699 100644 --- a/common/modules/farm/farm_base_impl/src/enter_farm.rs +++ b/common/modules/farm/farm_base_impl/src/enter_farm.rs @@ -45,16 +45,12 @@ pub trait BaseEnterFarmModule: ); // The order is important - first check and update, then increase position - FC::check_and_update_user_farm_position( - self, + self.check_and_update_user_farm_position::( &caller, &enter_farm_context.additional_farm_tokens, + &self.farm_token(), ); - FC::increase_user_farm_position( - self, - &caller, - &enter_farm_context.farming_token_payment.amount, - ); + self.increase_user_farm_position(&caller, &enter_farm_context.farming_token_payment.amount); FC::generate_aggregated_rewards(self, &mut storage_cache); diff --git a/common/modules/farm/farm_base_impl/src/exit_farm.rs b/common/modules/farm/farm_base_impl/src/exit_farm.rs index 315abe421..6cb9d8f05 100644 --- a/common/modules/farm/farm_base_impl/src/exit_farm.rs +++ b/common/modules/farm/farm_base_impl/src/exit_farm.rs @@ -62,7 +62,7 @@ pub trait BaseExitFarmModule: ); storage_cache.reward_reserve -= &reward; - FC::decrease_user_farm_position(self, &payment); + self.decrease_user_farm_position::(&payment, &self.farm_token()); let farming_token_amount = token_attributes.get_total_supply(); let farming_token_payment = EsdtTokenPayment::new( diff --git a/common/modules/farm/farm_token/Cargo.toml b/common/modules/farm/farm_token/Cargo.toml index aef369e13..bff6d8b5c 100644 --- a/common/modules/farm/farm_token/Cargo.toml +++ b/common/modules/farm/farm_token/Cargo.toml @@ -10,18 +10,6 @@ path = "src/farm_token.rs" [dependencies.common_structs] path = "../../../common_structs" -[dependencies.common_errors] -path = "../../../common_errors" - -[dependencies.config] -path = "../config" - -[dependencies.token_send] -path = "../../token_send" - -[dependencies.pausable] -path = "../../pausable" - [dependencies.permissions_module] path = "../../permissions_module" diff --git a/common/modules/farm/farm_token/src/farm_token.rs b/common/modules/farm/farm_token/src/farm_token.rs index de3f32d5d..184c02c3e 100644 --- a/common/modules/farm/farm_token/src/farm_token.rs +++ b/common/modules/farm/farm_token/src/farm_token.rs @@ -3,7 +3,7 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); -use common_structs::Nonce; +use common_structs::{Nonce, PaymentsVec}; #[multiversx_sc::module] pub trait FarmTokenModule: @@ -31,7 +31,7 @@ pub trait FarmTokenModule: ); } - fn burn_farm_tokens_from_payments(&self, payments: &ManagedVec>) { + fn burn_farm_tokens_from_payments(&self, payments: &PaymentsVec) { let mut total_amount = BigUint::zero(); for entry in payments.iter() { total_amount += &entry.amount; @@ -47,7 +47,7 @@ pub trait FarmTokenModule: token_id: TokenIdentifier, amount: BigUint, attributes: &T, - ) -> EsdtTokenPayment { + ) -> EsdtTokenPayment { let new_nonce = self .send() .esdt_nft_create_compact(&token_id, &amount, attributes); @@ -61,7 +61,7 @@ pub trait FarmTokenModule: self.farm_token_supply().update(|x| *x -= amount); } - fn burn_farm_token_payment(&self, payment: &EsdtTokenPayment) { + fn burn_farm_token_payment(&self, payment: &EsdtTokenPayment) { self.burn_farm_tokens( &payment.token_identifier, payment.token_nonce, @@ -72,7 +72,7 @@ pub trait FarmTokenModule: fn get_farm_token_attributes( &self, token_id: &TokenIdentifier, - token_nonce: u64, + token_nonce: Nonce, ) -> T { let token_info = self.blockchain().get_esdt_token_data( &self.blockchain().get_sc_address(), diff --git a/common/modules/permissions_module/src/permissions.rs b/common/modules/permissions_module/src/permissions.rs index 245ccda6a..c0e4ec205 100644 --- a/common/modules/permissions_module/src/permissions.rs +++ b/common/modules/permissions_module/src/permissions.rs @@ -34,14 +34,14 @@ impl TopDecode for Permissions { impl TypeAbiFrom for Permissions {} - impl TypeAbi for Permissions { - type Unmanaged = Self; +impl TypeAbi for Permissions { + type Unmanaged = Self; - fn type_name() -> multiversx_sc::abi::TypeName { - core::any::type_name::().into() - } + fn type_name() -> multiversx_sc::abi::TypeName { + core::any::type_name::().into() + } - fn type_name_rust() -> multiversx_sc::abi::TypeName { - core::any::type_name::().into() - } - } \ No newline at end of file + fn type_name_rust() -> multiversx_sc::abi::TypeName { + core::any::type_name::().into() + } +} diff --git a/dex/farm-with-locked-rewards/Cargo.toml b/dex/farm-with-locked-rewards/Cargo.toml index d39dd6ed1..1968a43a9 100644 --- a/dex/farm-with-locked-rewards/Cargo.toml +++ b/dex/farm-with-locked-rewards/Cargo.toml @@ -98,3 +98,6 @@ version = "=0.53.2" [dev-dependencies.simple-lock] path = "../../locked-asset/simple-lock" + +[dev-dependencies.timestamp-oracle] +path = "../../energy-integration/timestamp-oracle" diff --git a/dex/farm-with-locked-rewards/src/external_interaction.rs b/dex/farm-with-locked-rewards/src/external_interaction.rs index be29004f0..e435812d1 100644 --- a/dex/farm-with-locked-rewards/src/external_interaction.rs +++ b/dex/farm-with-locked-rewards/src/external_interaction.rs @@ -3,7 +3,7 @@ multiversx_sc::imports!(); use common_structs::FarmTokenAttributes; use farm::{ base_functions::{self, ClaimRewardsResultType}, - exit_penalty, EnterFarmResultType, + EnterFarmResultType, }; use crate::NoMintWrapper; @@ -22,7 +22,6 @@ pub trait ExternalInteractionsModule: + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + base_functions::BaseFunctionsModule - + exit_penalty::ExitPenaltyModule + locking_module::lock_with_energy_module::LockWithEnergyModule + farm_base_impl::base_farm_init::BaseFarmInitModule + farm_base_impl::base_farm_validation::BaseFarmValidationModule @@ -32,6 +31,7 @@ pub trait ExternalInteractionsModule: + farm_base_impl::exit_farm::BaseExitFarmModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule diff --git a/dex/farm-with-locked-rewards/src/lib.rs b/dex/farm-with-locked-rewards/src/lib.rs index 69b5dc4a1..6f7cff77e 100644 --- a/dex/farm-with-locked-rewards/src/lib.rs +++ b/dex/farm-with-locked-rewards/src/lib.rs @@ -12,9 +12,6 @@ use fixed_supply_token::FixedSupplyToken; use farm::{ base_functions::{BaseFunctionsModule, ClaimRewardsResultType, DoubleMultiPayment, Wrapper}, - exit_penalty::{ - DEFAULT_BURN_GAS_LIMIT, DEFAULT_MINUMUM_FARMING_EPOCHS, DEFAULT_PENALTY_PERCENT, - }, EnterFarmResultType, ExitFarmWithPartialPosResultType, MAX_PERCENT, }; use farm_base_impl::base_traits_impl::FarmContract; @@ -35,7 +32,6 @@ pub trait Farm: + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + farm::base_functions::BaseFunctionsModule - + farm::exit_penalty::ExitPenaltyModule + external_interaction::ExternalInteractionsModule + farm_base_impl::base_farm_init::BaseFarmInitModule + farm_base_impl::base_farm_validation::BaseFarmValidationModule @@ -45,6 +41,7 @@ pub trait Farm: + farm_base_impl::exit_farm::BaseExitFarmModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule @@ -59,7 +56,6 @@ pub trait Farm: reward_token_id: TokenIdentifier, farming_token_id: TokenIdentifier, division_safety_constant: BigUint, - pair_contract_address: ManagedAddress, owner: ManagedAddress, admins: MultiValueEncoded, ) { @@ -71,14 +67,8 @@ pub trait Farm: admins, ); - self.penalty_percent().set_if_empty(DEFAULT_PENALTY_PERCENT); - self.minimum_farming_epochs() - .set_if_empty(DEFAULT_MINUMUM_FARMING_EPOCHS); - self.burn_gas_limit().set_if_empty(DEFAULT_BURN_GAS_LIMIT); - self.pair_contract_address().set(&pair_contract_address); - let current_epoch = self.blockchain().get_block_epoch(); - self.first_week_start_epoch().set_if_empty(current_epoch); + self.first_week_start_epoch().set(current_epoch); // Farm position migration code let farm_token_mapper = self.farm_token(); @@ -86,13 +76,17 @@ pub trait Farm: } #[upgrade] - fn upgrade(&self) { - let current_epoch = self.blockchain().get_block_epoch(); - self.first_week_start_epoch().set_if_empty(current_epoch); + fn upgrade(&self, timestamp_oracle_address: ManagedAddress) { + if self.first_week_start_epoch().is_empty() { + let current_epoch = self.blockchain().get_block_epoch(); + self.first_week_start_epoch().set(current_epoch); + } // Farm position migration code let farm_token_mapper = self.farm_token(); self.try_set_farm_position_migration_nonce(farm_token_mapper); + + self.set_timestamp_oracle_address(timestamp_oracle_address); } #[payable("*")] @@ -103,8 +97,8 @@ pub trait Farm: ) -> EnterFarmResultType { let caller = self.blockchain().get_caller(); let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller); - self.migrate_old_farm_positions(&orig_caller); + let boosted_rewards = self.claim_only_boosted_payment(&orig_caller); let boosted_rewards_payment = self.send_to_lock_contract_non_zero( self.reward_token_id().get(), @@ -115,9 +109,10 @@ pub trait Farm: let new_farm_token = self.enter_farm::>(orig_caller.clone()); self.send_payment_non_zero(&caller, &new_farm_token); - self.update_energy_and_progress(&orig_caller); + self.update_start_of_epoch_timestamp(); + (new_farm_token, boosted_rewards_payment).into() } @@ -129,11 +124,9 @@ pub trait Farm: ) -> ClaimRewardsResultType { let caller = self.blockchain().get_caller(); let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller); - self.migrate_old_farm_positions(&orig_caller); let claim_rewards_result = self.claim_rewards::>(orig_caller.clone()); - self.send_payment_non_zero(&caller, &claim_rewards_result.new_farm_token); let rewards_payment = claim_rewards_result.rewards; @@ -144,6 +137,8 @@ pub trait Farm: orig_caller, ); + self.update_start_of_epoch_timestamp(); + (claim_rewards_result.new_farm_token, locked_rewards_payment).into() } @@ -157,9 +152,7 @@ pub trait Farm: let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller); let payment = self.call_value().single_esdt(); - let migrated_amount = self.migrate_old_farm_positions(&orig_caller); - let exit_farm_result = self.exit_farm::>(orig_caller.clone(), payment); self.decrease_old_farm_positions(migrated_amount, &orig_caller); @@ -176,6 +169,8 @@ pub trait Farm: self.clear_user_energy_if_needed(&orig_caller); + self.update_start_of_epoch_timestamp(); + (exit_farm_result.farming_tokens, locked_rewards_payment).into() } @@ -192,8 +187,8 @@ pub trait Farm: let boosted_rewards = self.claim_only_boosted_payment(&orig_caller); let merged_farm_token = self.merge_and_update_farm_tokens(orig_caller.clone()); - self.send_payment_non_zero(&caller, &merged_farm_token); + let locked_rewards_payment = self.send_to_lock_contract_non_zero( self.reward_token_id().get(), boosted_rewards, @@ -201,6 +196,8 @@ pub trait Farm: orig_caller, ); + self.update_start_of_epoch_timestamp(); + (merged_farm_token, locked_rewards_payment).into() } @@ -241,9 +238,10 @@ pub trait Farm: NoMintWrapper::::generate_aggregated_rewards(self, &mut storage_cache); let boosted_rewards = self.claim_only_boosted_payment(user); - self.set_farm_supply_for_current_week(&storage_cache.farm_token_supply); + // Don't need to call update here too, the internal functions call it already + self.send_to_lock_contract_non_zero( self.reward_token_id().get(), boosted_rewards, @@ -256,18 +254,24 @@ pub trait Farm: fn start_produce_rewards_endpoint(&self) { self.require_caller_has_admin_permissions(); self.start_produce_rewards(); + + self.update_start_of_epoch_timestamp(); } #[endpoint(endProduceRewards)] fn end_produce_rewards_endpoint(&self) { self.require_caller_has_admin_permissions(); self.end_produce_rewards::>(); + + self.update_start_of_epoch_timestamp(); } #[endpoint(setPerBlockRewardAmount)] fn set_per_block_rewards_endpoint(&self, per_block_amount: BigUint) { self.require_caller_has_admin_permissions(); self.set_per_block_rewards::>(per_block_amount); + + self.update_start_of_epoch_timestamp(); } #[endpoint(setBoostedYieldsRewardsPercentage)] @@ -279,6 +283,8 @@ pub trait Farm: NoMintWrapper::::generate_aggregated_rewards(self, &mut storage_cache); self.boosted_yields_rewards_percentage().set(percentage); + + self.update_start_of_epoch_timestamp(); } #[view(calculateRewardsForGivenPosition)] @@ -368,21 +374,4 @@ where storage_cache, ) } - - fn get_exit_penalty( - sc: &Self::FarmSc, - total_exit_amount: &BigUint<::Api>, - token_attributes: &Self::AttributesType, - ) -> BigUint<::Api> { - Wrapper::::get_exit_penalty(sc, total_exit_amount, token_attributes) - } - - fn apply_penalty( - sc: &Self::FarmSc, - total_exit_amount: &mut BigUint<::Api>, - token_attributes: &Self::AttributesType, - storage_cache: &StorageCache, - ) { - Wrapper::::apply_penalty(sc, total_exit_amount, token_attributes, storage_cache) - } } 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 4d2a2819a..36ccd146b 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 @@ -1,6 +1,4 @@ -#![allow(deprecated)] - -use common_structs::FarmTokenAttributes; +use common_structs::{FarmTokenAttributes, Timestamp}; use config::ConfigModule; use multiversx_sc::{ codec::multi_types::OptionalValue, @@ -19,7 +17,10 @@ use fees_collector_mock::*; use energy_factory::{energy::EnergyModule, SimpleLockEnergy}; use energy_query::{Energy, EnergyQueryModule}; -use farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule; +use farm_boosted_yields::{ + boosted_yields_factors::BoostedYieldsFactorsModule, + custom_reward_logic::CustomRewardLogicModule, +}; use farm_token::FarmTokenModule; use farm_with_locked_rewards::{external_interaction::ExternalInteractionsModule, Farm}; use locking_module::lock_with_energy_module::LockWithEnergyModule; @@ -30,6 +31,7 @@ use permissions_hub_module::PermissionsHubModule; use rewards::RewardsModule; use sc_whitelist_module::SCWhitelistModule; use simple_lock::locked_token::LockedTokenModule; +use timestamp_oracle::{epoch_to_timestamp::EpochToTimestampModule, TimestampOracle}; use week_timekeeping::Epoch; pub static REWARD_TOKEN_ID: &[u8] = b"MEX-123456"; @@ -47,6 +49,7 @@ pub const USER_REWARDS_ENERGY_CONST: u64 = 3; pub const USER_REWARDS_FARM_CONST: u64 = 2; pub const MIN_ENERGY_AMOUNT_FOR_BOOSTED_YIELDS: u64 = 1; pub const MIN_FARM_AMOUNT_FOR_BOOSTED_YIELDS: u64 = 1; +pub const TIMESTAMP_PER_EPOCH: Timestamp = 24 * 60 * 60; pub const EPOCHS_IN_YEAR: u64 = 360; @@ -61,10 +64,15 @@ pub struct RawFarmTokenAttributes { pub original_owner_bytes: [u8; 32], } -pub struct FarmSetup -where +pub struct FarmSetup< + FarmObjBuilder, + EnergyFactoryBuilder, + TimestampOracleObjBuilder, + PermissionsHubObjBuilder, +> where FarmObjBuilder: 'static + Copy + Fn() -> farm_with_locked_rewards::ContractObj, EnergyFactoryBuilder: 'static + Copy + Fn() -> energy_factory::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, PermissionsHubObjBuilder: 'static + Copy + Fn() -> permissions_hub::ContractObj, { pub b_mock: BlockchainStateWrapper, @@ -77,20 +85,32 @@ where ContractObjWrapper, FarmObjBuilder>, pub energy_factory_wrapper: ContractObjWrapper, EnergyFactoryBuilder>, + + #[allow(dead_code)] + pub timestamp_oracle_wrapper: + ContractObjWrapper, TimestampOracleObjBuilder>, + pub permissions_hub_wrapper: ContractObjWrapper, PermissionsHubObjBuilder>, } -impl - FarmSetup +impl + FarmSetup< + FarmObjBuilder, + EnergyFactoryBuilder, + TimestampOracleObjBuilder, + PermissionsHubObjBuilder, + > where FarmObjBuilder: 'static + Copy + Fn() -> farm_with_locked_rewards::ContractObj, EnergyFactoryBuilder: 'static + Copy + Fn() -> energy_factory::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, PermissionsHubObjBuilder: 'static + Copy + Fn() -> permissions_hub::ContractObj, { pub fn new( farm_builder: FarmObjBuilder, energy_factory_builder: EnergyFactoryBuilder, + timestamp_oracle_builder: TimestampOracleObjBuilder, permissions_hub_builder: PermissionsHubObjBuilder, ) -> Self { let rust_zero = rust_biguint!(0); @@ -118,6 +138,21 @@ where "fees collector mock", ); + let timestamp_oracle_wrapper = b_mock.create_sc_account( + &rust_zero, + Some(&owner), + timestamp_oracle_builder, + "timestamp oracle", + ); + b_mock + .execute_tx(&owner, ×tamp_oracle_wrapper, &rust_zero, |sc| { + sc.init(0); + + for i in 0..=100 { + sc.set_start_timestamp_for_epoch(i, i * TIMESTAMP_PER_EPOCH + 1); + } + }) + .assert_ok(); let permissions_hub_wrapper = b_mock.create_sc_account( &rust_zero, Some(&owner), @@ -157,13 +192,11 @@ where let reward_token_id = managed_token_id!(REWARD_TOKEN_ID); let farming_token_id = managed_token_id!(FARMING_TOKEN_ID); let division_safety_constant = managed_biguint!(DIV_SAFETY); - let pair_address = managed_address!(&Address::zero()); sc.init( reward_token_id, farming_token_id, division_safety_constant, - pair_address, managed_address!(&owner), MultiValueEncoded::new(), ); @@ -188,6 +221,9 @@ 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() )); @@ -256,6 +292,7 @@ where last_farm_token_nonce: 0, farm_wrapper, energy_factory_wrapper, + timestamp_oracle_wrapper, permissions_hub_wrapper, } } diff --git a/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_test.rs b/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_test.rs index fea8f4fcd..93250b615 100644 --- a/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_test.rs +++ b/dex/farm-with-locked-rewards/tests/farm_with_locked_rewards_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use common_structs::FarmTokenAttributes; use farm_with_locked_rewards::Farm; use farm_with_locked_rewards_setup::{ @@ -18,9 +16,11 @@ mod farm_with_locked_rewards_setup; #[test] fn farm_with_no_boost_no_proxy_test() { DebugApi::dummy(); + let mut farm_setup = FarmSetup::new( farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -119,9 +119,11 @@ fn farm_with_no_boost_no_proxy_test() { #[test] fn farm_with_boosted_yields_no_proxy_test() { DebugApi::dummy(); + let mut farm_setup = FarmSetup::new( farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -239,9 +241,11 @@ fn farm_with_boosted_yields_no_proxy_test() { #[test] fn total_farm_position_claim_with_locked_rewards_test() { DebugApi::dummy(); + let mut farm_setup = FarmSetup::new( farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -347,9 +351,11 @@ fn total_farm_position_claim_with_locked_rewards_test() { #[test] fn claim_only_boosted_rewards_per_week_test() { DebugApi::dummy(); + let mut farm_setup = FarmSetup::new( farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -411,9 +417,11 @@ fn claim_only_boosted_rewards_per_week_test() { #[test] fn claim_rewards_per_week_test() { DebugApi::dummy(); + let mut farm_setup = FarmSetup::new( farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -478,9 +486,11 @@ fn claim_rewards_per_week_test() { #[test] fn claim_boosted_rewards_with_zero_position_test() { DebugApi::dummy(); + let mut farm_setup = FarmSetup::new( farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -550,9 +560,11 @@ fn claim_boosted_rewards_with_zero_position_test() { #[test] fn claim_boosted_rewards_user_energy_not_registered_test() { DebugApi::dummy(); + let mut farm_setup = FarmSetup::new( farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -593,6 +605,7 @@ fn test_multiple_positions_on_behalf() { let mut farm_setup = FarmSetup::new( farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); diff --git a/dex/farm-with-locked-rewards/wasm/Cargo.lock b/dex/farm-with-locked-rewards/wasm/Cargo.lock index 1ec1e747a..87136c504 100644 --- a/dex/farm-with-locked-rewards/wasm/Cargo.lock +++ b/dex/farm-with-locked-rewards/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -154,12 +147,15 @@ dependencies = [ name = "farm-boosted-yields" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "config", "energy-query", + "math", "multiversx-sc", "pausable", "permissions_module", + "timestamp-oracle", + "utils", "week-timekeeping", "weekly-rewards-splitting", ] @@ -231,22 +227,18 @@ dependencies = [ name = "farm_token" version = "0.0.0" dependencies = [ - "common_errors", "common_structs", - "config", "multiversx-sc", "multiversx-sc-modules", - "pausable", "permissions_module", - "token_send", ] [[package]] name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -538,6 +530,14 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "timestamp-oracle" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "token_merge_helper" version = "0.0.0" @@ -588,7 +588,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -596,7 +596,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/dex/farm-with-locked-rewards/wasm/src/lib.rs b/dex/farm-with-locked-rewards/wasm/src/lib.rs index 81ef9c901..5635a0d71 100644 --- a/dex/farm-with-locked-rewards/wasm/src/lib.rs +++ b/dex/farm-with-locked-rewards/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 69 +// Endpoints: 63 // Async Callback: 1 -// Total number of exported functions: 72 +// Total number of exported functions: 66 #![no_std] @@ -60,23 +60,17 @@ multiversx_sc_wasm_adapter::endpoints! { addSCAddressToWhitelist => add_sc_address_to_whitelist removeSCAddressFromWhitelist => remove_sc_address_from_whitelist isSCAddressWhitelisted => is_sc_address_whitelisted - set_penalty_percent => set_penalty_percent - set_minimum_farming_epochs => set_minimum_farming_epochs - set_burn_gas_limit => set_burn_gas_limit - getPenaltyPercent => penalty_percent - getMinimumFarmingEpoch => minimum_farming_epochs - getBurnGasLimit => burn_gas_limit - getPairContractManagedAddress => pair_contract_address enterFarmOnBehalf => enter_farm_on_behalf claimRewardsOnBehalf => claim_rewards_on_behalf + setBoostedYieldsFactors => set_boosted_yields_factors + getBoostedYieldsFactors => get_boosted_yields_factors + setTimestampOracleAddress => set_timestamp_oracle_address collectUndistributedBoostedRewards => collect_undistributed_boosted_rewards getBoostedYieldsRewardsPercentage => boosted_yields_rewards_percentage getAccumulatedRewardsForWeek => accumulated_rewards_for_week getFarmSupplyForWeek => farm_supply_for_week getRemainingBoostedRewardsToDistribute => remaining_boosted_rewards_to_distribute getUndistributedBoostedRewards => undistributed_boosted_rewards - setBoostedYieldsFactors => set_boosted_yields_factors - getBoostedYieldsFactors => get_boosted_yields_factors getCurrentWeek => get_current_week getFirstWeekStartEpoch => first_week_start_epoch getLastActiveWeekForUser => get_last_active_week_for_user_view diff --git a/dex/farm/Cargo.toml b/dex/farm/Cargo.toml index b91a99066..f2e0e3202 100644 --- a/dex/farm/Cargo.toml +++ b/dex/farm/Cargo.toml @@ -98,3 +98,6 @@ path = "../../energy-integration/energy-factory-mock" [dev-dependencies.simple-lock] path = "../../locked-asset/simple-lock" + +[dev-dependencies.timestamp-oracle] +path = "../../energy-integration/timestamp-oracle" diff --git a/dex/farm/src/base_functions.rs b/dex/farm/src/base_functions.rs index d6455a2b7..57fa89d41 100644 --- a/dex/farm/src/base_functions.rs +++ b/dex/farm/src/base_functions.rs @@ -12,8 +12,6 @@ use contexts::storage_cache::StorageCache; use farm_base_impl::base_traits_impl::{DefaultFarmWrapper, FarmContract}; -use crate::{exit_penalty, MAX_PERCENT}; - pub type DoubleMultiPayment = MultiValue2, EsdtTokenPayment>; pub type ClaimRewardsResultType = DoubleMultiPayment; pub type ExitFarmResultType = DoubleMultiPayment; @@ -52,7 +50,6 @@ pub trait BaseFunctionsModule: + permissions_module::PermissionsModule + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule - + exit_penalty::ExitPenaltyModule + farm_base_impl::base_farm_init::BaseFarmInitModule + farm_base_impl::base_farm_validation::BaseFarmValidationModule + farm_base_impl::enter_farm::BaseEnterFarmModule @@ -62,6 +59,7 @@ pub trait BaseFunctionsModule: + utils::UtilsModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule @@ -154,20 +152,13 @@ pub trait BaseFunctionsModule: ) -> ExitFarmResultWrapper { let base_exit_farm_result = self.exit_farm_base::(caller.clone(), payment); - let mut farming_token_payment = base_exit_farm_result.farming_token_payment; + let farming_token_payment = base_exit_farm_result.farming_token_payment; let reward_payment = base_exit_farm_result.reward_payment; self.set_farm_supply_for_current_week( &base_exit_farm_result.storage_cache.farm_token_supply, ); - FC::apply_penalty( - self, - &mut farming_token_payment.amount, - &base_exit_farm_result.context.farm_token.attributes, - &base_exit_farm_result.storage_cache, - ); - self.emit_exit_farm_event( &caller, base_exit_farm_result.context, @@ -190,7 +181,11 @@ pub trait BaseFunctionsModule: let token_mapper = self.farm_token(); token_mapper.require_all_same_token(&payments); - FC::check_and_update_user_farm_position(self, orig_caller, &payments); + self.check_and_update_user_farm_position::( + orig_caller, + &payments, + &self.farm_token(), + ); self.merge_from_payments_and_burn(payments, &token_mapper) } @@ -267,19 +262,13 @@ pub trait BaseFunctionsModule: } } -pub struct Wrapper< - T: BaseFunctionsModule - + farm_boosted_yields::FarmBoostedYieldsModule - + crate::exit_penalty::ExitPenaltyModule, -> { +pub struct Wrapper { _phantom: PhantomData, } impl Wrapper where - T: BaseFunctionsModule - + farm_boosted_yields::FarmBoostedYieldsModule - + crate::exit_penalty::ExitPenaltyModule, + T: BaseFunctionsModule + farm_boosted_yields::FarmBoostedYieldsModule, { pub fn calculate_boosted_rewards( sc: &::FarmSc, @@ -293,9 +282,7 @@ where impl FarmContract for Wrapper where - T: BaseFunctionsModule - + farm_boosted_yields::FarmBoostedYieldsModule - + crate::exit_penalty::ExitPenaltyModule, + T: BaseFunctionsModule + farm_boosted_yields::FarmBoostedYieldsModule, { type FarmSc = T; type AttributesType = FarmTokenAttributes<::Api>; @@ -335,37 +322,4 @@ where base_farm_reward + boosted_yield_rewards } - - fn get_exit_penalty( - sc: &Self::FarmSc, - total_exit_amount: &BigUint<::Api>, - token_attributes: &Self::AttributesType, - ) -> BigUint<::Api> { - let current_epoch = sc.blockchain().get_block_epoch(); - let user_farming_epochs = current_epoch - token_attributes.entering_epoch; - let min_farming_epochs = sc.minimum_farming_epochs().get(); - if user_farming_epochs >= min_farming_epochs { - BigUint::zero() - } else { - total_exit_amount * sc.penalty_percent().get() / MAX_PERCENT - } - } - - fn apply_penalty( - sc: &Self::FarmSc, - total_exit_amount: &mut BigUint<::Api>, - token_attributes: &Self::AttributesType, - storage_cache: &StorageCache, - ) { - let penalty_amount = Self::get_exit_penalty(sc, total_exit_amount, token_attributes); - if penalty_amount > 0 { - *total_exit_amount -= &penalty_amount; - - sc.burn_farming_tokens( - &penalty_amount, - &storage_cache.farming_token_id, - &storage_cache.reward_token_id, - ); - } - } } diff --git a/dex/farm/src/exit_penalty.rs b/dex/farm/src/exit_penalty.rs deleted file mode 100644 index 19f101a26..000000000 --- a/dex/farm/src/exit_penalty.rs +++ /dev/null @@ -1,76 +0,0 @@ -multiversx_sc::imports!(); - -use common_errors::ERROR_PARAMETERS; -use common_structs::Epoch; -use pair::pair_actions::remove_liq::ProxyTrait as _; - -use crate::MAX_PERCENT; - -pub const DEFAULT_PENALTY_PERCENT: u64 = 100; -pub const DEFAULT_MINUMUM_FARMING_EPOCHS: u64 = 3; -pub const DEFAULT_BURN_GAS_LIMIT: u64 = 50_000_000; -pub const DEFAULT_NFT_DEPOSIT_MAX_LEN: usize = 10; -pub const MAX_MINIMUM_FARMING_EPOCHS: u64 = 30; - -#[multiversx_sc::module] -pub trait ExitPenaltyModule: permissions_module::PermissionsModule { - #[only_owner] - #[endpoint] - fn set_penalty_percent(&self, percent: u64) { - require!(percent < MAX_PERCENT, ERROR_PARAMETERS); - self.penalty_percent().set(percent); - } - - #[endpoint] - fn set_minimum_farming_epochs(&self, epochs: Epoch) { - self.require_caller_has_admin_permissions(); - require!(epochs <= MAX_MINIMUM_FARMING_EPOCHS, ERROR_PARAMETERS); - - self.minimum_farming_epochs().set(epochs); - } - - #[only_owner] - #[endpoint] - fn set_burn_gas_limit(&self, gas_limit: u64) { - self.burn_gas_limit().set(gas_limit); - } - - fn burn_farming_tokens( - &self, - farming_amount: &BigUint, - farming_token_id: &TokenIdentifier, - reward_token_id: &TokenIdentifier, - ) { - let pair_contract_address = self.pair_contract_address().get(); - if pair_contract_address.is_zero() { - self.send() - .esdt_local_burn(farming_token_id, 0, farming_amount); - } else { - let gas_limit = self.burn_gas_limit().get(); - self.pair_contract_proxy(pair_contract_address) - .remove_liquidity_and_burn_token(reward_token_id.clone()) - .with_esdt_transfer((farming_token_id.clone(), 0, farming_amount.clone())) - .with_gas_limit(gas_limit) - .transfer_execute(); - } - } - - #[proxy] - fn pair_contract_proxy(&self, to: ManagedAddress) -> pair::Proxy; - - #[view(getPenaltyPercent)] - #[storage_mapper("penalty_percent")] - fn penalty_percent(&self) -> SingleValueMapper; - - #[view(getMinimumFarmingEpoch)] - #[storage_mapper("minimum_farming_epochs")] - fn minimum_farming_epochs(&self) -> SingleValueMapper; - - #[view(getBurnGasLimit)] - #[storage_mapper("burn_gas_limit")] - fn burn_gas_limit(&self) -> SingleValueMapper; - - #[view(getPairContractManagedAddress)] - #[storage_mapper("pair_contract_address")] - fn pair_contract_address(&self) -> SingleValueMapper; -} diff --git a/dex/farm/src/external_interaction.rs b/dex/farm/src/external_interaction.rs index 0af8fe5a5..99f602c36 100644 --- a/dex/farm/src/external_interaction.rs +++ b/dex/farm/src/external_interaction.rs @@ -4,7 +4,7 @@ use common_structs::FarmTokenAttributes; use crate::{ base_functions::{self, ClaimRewardsResultType, Wrapper}, - exit_penalty, EnterFarmResultType, + EnterFarmResultType, }; #[multiversx_sc::module] @@ -21,7 +21,6 @@ pub trait ExternalInteractionsModule: + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + base_functions::BaseFunctionsModule - + exit_penalty::ExitPenaltyModule + farm_base_impl::base_farm_init::BaseFarmInitModule + farm_base_impl::base_farm_validation::BaseFarmValidationModule + farm_base_impl::enter_farm::BaseEnterFarmModule @@ -30,6 +29,7 @@ pub trait ExternalInteractionsModule: + farm_base_impl::exit_farm::BaseExitFarmModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule diff --git a/dex/farm/src/lib.rs b/dex/farm/src/lib.rs index 5eb7ea834..0e44a213a 100644 --- a/dex/farm/src/lib.rs +++ b/dex/farm/src/lib.rs @@ -4,16 +4,12 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); pub mod base_functions; -pub mod exit_penalty; pub mod external_interaction; use base_functions::{ClaimRewardsResultType, DoubleMultiPayment, Wrapper}; use common_structs::FarmTokenAttributes; use contexts::storage_cache::StorageCache; -use exit_penalty::{ - DEFAULT_BURN_GAS_LIMIT, DEFAULT_MINUMUM_FARMING_EPOCHS, DEFAULT_PENALTY_PERCENT, -}; use farm_base_impl::base_traits_impl::FarmContract; use fixed_supply_token::FixedSupplyToken; @@ -36,7 +32,6 @@ pub trait Farm: + events::EventsModule + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + base_functions::BaseFunctionsModule - + exit_penalty::ExitPenaltyModule + external_interaction::ExternalInteractionsModule + farm_base_impl::base_farm_init::BaseFarmInitModule + farm_base_impl::base_farm_validation::BaseFarmValidationModule @@ -46,6 +41,7 @@ pub trait Farm: + farm_base_impl::exit_farm::BaseExitFarmModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule @@ -61,7 +57,6 @@ pub trait Farm: reward_token_id: TokenIdentifier, farming_token_id: TokenIdentifier, division_safety_constant: BigUint, - pair_contract_address: ManagedAddress, owner: ManagedAddress, admins: MultiValueEncoded, ) { @@ -73,28 +68,22 @@ pub trait Farm: admins, ); - self.penalty_percent().set_if_empty(DEFAULT_PENALTY_PERCENT); - self.minimum_farming_epochs() - .set_if_empty(DEFAULT_MINUMUM_FARMING_EPOCHS); - self.burn_gas_limit().set_if_empty(DEFAULT_BURN_GAS_LIMIT); - self.pair_contract_address().set(&pair_contract_address); - let current_epoch = self.blockchain().get_block_epoch(); - self.first_week_start_epoch().set_if_empty(current_epoch); - - // Farm position migration code - let farm_token_mapper = self.farm_token(); - self.try_set_farm_position_migration_nonce(farm_token_mapper); + self.first_week_start_epoch().set(current_epoch); } #[upgrade] - fn upgrade(&self) { - let current_epoch = self.blockchain().get_block_epoch(); - self.first_week_start_epoch().set_if_empty(current_epoch); + fn upgrade(&self, timestamp_oracle_address: ManagedAddress) { + if self.first_week_start_epoch().is_empty() { + let current_epoch = self.blockchain().get_block_epoch(); + self.first_week_start_epoch().set(current_epoch); + } // Farm position migration code let farm_token_mapper = self.farm_token(); self.try_set_farm_position_migration_nonce(farm_token_mapper); + + self.set_timestamp_oracle_address(timestamp_oracle_address); } #[payable("*")] @@ -107,6 +96,7 @@ pub trait Farm: let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller); self.migrate_old_farm_positions(&orig_caller); + let boosted_rewards = self.claim_only_boosted_payment(&orig_caller); let boosted_rewards_payment = EsdtTokenPayment::new(self.reward_token_id().get(), 0, boosted_rewards); @@ -114,9 +104,10 @@ pub trait Farm: let new_farm_token = self.enter_farm::>(orig_caller.clone()); self.send_payment_non_zero(&caller, &new_farm_token); self.send_payment_non_zero(&caller, &boosted_rewards_payment); - self.update_energy_and_progress(&orig_caller); + self.update_start_of_epoch_timestamp(); + (new_farm_token, boosted_rewards_payment).into() } @@ -132,10 +123,11 @@ pub trait Farm: self.migrate_old_farm_positions(&orig_caller); let claim_rewards_result = self.claim_rewards::>(orig_caller); - self.send_payment_non_zero(&caller, &claim_rewards_result.new_farm_token); self.send_payment_non_zero(&caller, &claim_rewards_result.rewards); + self.update_start_of_epoch_timestamp(); + claim_rewards_result.into() } @@ -151,11 +143,11 @@ pub trait Farm: self.migrate_old_farm_positions(&orig_caller); let output_farm_token_payment = self.compound_rewards::>(orig_caller.clone()); - self.send_payment_non_zero(&caller, &output_farm_token_payment); - self.update_energy_and_progress(&orig_caller); + self.update_start_of_epoch_timestamp(); + output_farm_token_payment } @@ -167,20 +159,17 @@ pub trait Farm: ) -> ExitFarmWithPartialPosResultType { let caller = self.blockchain().get_caller(); let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller); - let payment = self.call_value().single_esdt(); - let migrated_amount = self.migrate_old_farm_positions(&orig_caller); - let exit_farm_result = self.exit_farm::>(orig_caller.clone(), payment); self.decrease_old_farm_positions(migrated_amount, &orig_caller); - self.send_payment_non_zero(&caller, &exit_farm_result.farming_tokens); self.send_payment_non_zero(&caller, &exit_farm_result.rewards); - self.clear_user_energy_if_needed(&orig_caller); + self.update_start_of_epoch_timestamp(); + (exit_farm_result.farming_tokens, exit_farm_result.rewards).into() } @@ -203,6 +192,8 @@ pub trait Farm: self.send_payment_non_zero(&caller, &merged_farm_token); self.send_payment_non_zero(&caller, &boosted_rewards_payment); + self.update_start_of_epoch_timestamp(); + (merged_farm_token, boosted_rewards_payment).into() } @@ -249,6 +240,8 @@ pub trait Farm: self.send_payment_non_zero(user, &boosted_rewards_payment); + // Don't need to call update here too, the internal functions call it already + boosted_rewards_payment } @@ -256,18 +249,24 @@ pub trait Farm: fn start_produce_rewards_endpoint(&self) { self.require_caller_has_admin_permissions(); self.start_produce_rewards(); + + self.update_start_of_epoch_timestamp(); } #[endpoint(endProduceRewards)] fn end_produce_rewards_endpoint(&self) { self.require_caller_has_admin_permissions(); self.end_produce_rewards::>(); + + self.update_start_of_epoch_timestamp(); } #[endpoint(setPerBlockRewardAmount)] fn set_per_block_rewards_endpoint(&self, per_block_amount: BigUint) { self.require_caller_has_admin_permissions(); self.set_per_block_rewards::>(per_block_amount); + + self.update_start_of_epoch_timestamp(); } #[endpoint(setBoostedYieldsRewardsPercentage)] @@ -279,6 +278,8 @@ pub trait Farm: Wrapper::::generate_aggregated_rewards(self, &mut storage_cache); self.boosted_yields_rewards_percentage().set(percentage); + + self.update_start_of_epoch_timestamp(); } #[view(calculateRewardsForGivenPosition)] diff --git a/dex/farm/tests/energy_update_test.rs b/dex/farm/tests/energy_update_test.rs index a15fbc5e2..a17295eee 100644 --- a/dex/farm/tests/energy_update_test.rs +++ b/dex/farm/tests/energy_update_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod farm_setup; use farm_setup::multi_user_farm_setup::*; @@ -10,6 +8,7 @@ fn test_farm_setup() { farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); } @@ -20,6 +19,7 @@ fn test_energy_update() { farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -41,6 +41,7 @@ fn test_energy_update_no_claim_current_week() { farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); diff --git a/dex/farm/tests/external_interaction_test.rs b/dex/farm/tests/external_interaction_test.rs index 6a36ae680..cf98cfa71 100644 --- a/dex/farm/tests/external_interaction_test.rs +++ b/dex/farm/tests/external_interaction_test.rs @@ -18,6 +18,7 @@ fn test_enter_and_claim_farm_on_behalf() { farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -66,6 +67,7 @@ fn test_multiple_positions_on_behalf() { farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -171,6 +173,7 @@ fn test_enter_and_claim_farm_on_behalf_not_whitelisted_error() { farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -223,6 +226,7 @@ fn test_wrong_original_owner_on_behalf_validation() { farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); diff --git a/dex/farm/tests/farm_multi_user_test.rs b/dex/farm/tests/farm_multi_user_test.rs index d37bee046..e016f055c 100644 --- a/dex/farm/tests/farm_multi_user_test.rs +++ b/dex/farm/tests/farm_multi_user_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use common_structs::FarmTokenAttributes; use multiversx_sc_scenario::{managed_address, managed_biguint, rust_biguint, DebugApi}; @@ -14,10 +12,12 @@ use weekly_rewards_splitting::global_info::WeeklyRewardsGlobalInfo; #[test] fn farm_with_no_boost_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -113,28 +113,31 @@ fn farm_with_no_boost_test() { #[test] fn farm_with_boosted_yields_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); farm_setup.set_boosted_yields_factors(); - farm_setup.b_mock.set_block_epoch(2); + farm_setup.b_mock.set_block_epoch(0); + farm_setup.b_mock.set_block_timestamp(1); // first user enter farm let first_farm_token_amount = 100_000_000; let first_user = farm_setup.first_user.clone(); let third_user = farm_setup.third_user.clone(); - farm_setup.set_user_energy(&first_user, 1_000, 2, 1); + farm_setup.set_user_energy(&first_user, 1_000, 0, 1); farm_setup.enter_farm(&first_user, first_farm_token_amount); // second user enter farm let second_farm_token_amount = 50_000_000; let second_user = farm_setup.second_user.clone(); - farm_setup.set_user_energy(&second_user, 4_000, 2, 1); + farm_setup.set_user_energy(&second_user, 4_000, 0, 1); farm_setup.enter_farm(&second_user, second_farm_token_amount); // users claim rewards to get their energy registered @@ -147,6 +150,10 @@ fn farm_with_boosted_yields_test() { // random tx on end of week 1, to cummulate rewards farm_setup.b_mock.set_block_epoch(6); + farm_setup + .b_mock + .set_block_timestamp(6 * TIMESTAMP_PER_EPOCH); + farm_setup.set_user_energy(&first_user, 1_000, 6, 1); farm_setup.set_user_energy(&second_user, 4_000, 6, 1); farm_setup.set_user_energy(&third_user, 1, 6, 1); @@ -154,9 +161,13 @@ fn farm_with_boosted_yields_test() { farm_setup.exit_farm(&third_user, 5, 1); // advance 1 week - farm_setup.b_mock.set_block_epoch(10); - farm_setup.set_user_energy(&first_user, 1_000, 10, 1); - farm_setup.set_user_energy(&second_user, 4_000, 10, 1); + farm_setup.b_mock.set_block_epoch(13); + farm_setup + .b_mock + .set_block_timestamp(14 * TIMESTAMP_PER_EPOCH - 1); + + farm_setup.set_user_energy(&first_user, 1_000, 13, 1); + farm_setup.set_user_energy(&second_user, 4_000, 13, 1); let total_farm_tokens = first_farm_token_amount + second_farm_token_amount; @@ -226,10 +237,12 @@ fn farm_with_boosted_yields_test() { #[test] fn farm_change_boosted_yields_factors_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -290,10 +303,12 @@ fn farm_change_boosted_yields_factors_test() { #[test] fn farm_boosted_yields_claim_with_different_user_pos_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -397,10 +412,12 @@ fn farm_boosted_yields_claim_with_different_user_pos_test() { #[test] fn farm_known_proxy_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -497,28 +514,32 @@ fn farm_known_proxy_test() { #[test] fn farm_multiple_claim_weeks_with_collect_undistributed_rewards_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); farm_setup.set_boosted_yields_factors(); - farm_setup.b_mock.set_block_epoch(2); + farm_setup.b_mock.set_block_epoch(0); + farm_setup.b_mock.set_block_timestamp(1); + let third_user = farm_setup.third_user.clone(); // first user enter farm let first_farm_token_amount = 100_000_000; let first_user = farm_setup.first_user.clone(); - farm_setup.set_user_energy(&first_user, 1_000, 2, 1); + farm_setup.set_user_energy(&first_user, 1_000, 0, 1); farm_setup.enter_farm(&first_user, first_farm_token_amount); // second user enter farm let second_farm_token_amount = 50_000_000; let second_user = farm_setup.second_user.clone(); - farm_setup.set_user_energy(&second_user, 4_000, 2, 1); + farm_setup.set_user_energy(&second_user, 4_000, 0, 1); farm_setup.enter_farm(&second_user, second_farm_token_amount); // users claim rewards to get their energy registered @@ -531,6 +552,10 @@ fn farm_multiple_claim_weeks_with_collect_undistributed_rewards_test() { // random tx on end of week 1, to cummulate rewards farm_setup.b_mock.set_block_epoch(6); + farm_setup + .b_mock + .set_block_timestamp(7 * TIMESTAMP_PER_EPOCH - 1); + farm_setup.set_user_energy(&first_user, 1_000, 6, 1); farm_setup.set_user_energy(&second_user, 4_000, 6, 1); farm_setup.set_user_energy(&third_user, 1, 6, 1); @@ -538,9 +563,13 @@ fn farm_multiple_claim_weeks_with_collect_undistributed_rewards_test() { farm_setup.exit_farm(&third_user, 5, 1); // advance 1 week - farm_setup.b_mock.set_block_epoch(10); - farm_setup.set_user_energy(&first_user, 1_000, 10, 1); - farm_setup.set_user_energy(&second_user, 4_000, 10, 1); + farm_setup.b_mock.set_block_epoch(13); + farm_setup + .b_mock + .set_block_timestamp(14 * TIMESTAMP_PER_EPOCH - 1); + + farm_setup.set_user_energy(&first_user, 1_000, 13, 1); + farm_setup.set_user_energy(&second_user, 4_000, 13, 1); let total_farm_tokens = first_farm_token_amount + second_farm_token_amount; @@ -611,7 +640,8 @@ fn farm_multiple_claim_weeks_with_collect_undistributed_rewards_test() { farm_setup.b_mock.set_block_nonce(20); // random tx on end of week 2, to cummulate rewards - farm_setup.b_mock.set_block_epoch(13); + // farm_setup.b_mock.set_block_epoch(13); + farm_setup.set_user_energy(&first_user, 1_000, 13, 1); farm_setup.set_user_energy(&second_user, 4_000, 13, 1); farm_setup.set_user_energy(&third_user, 1, 13, 1); @@ -624,6 +654,10 @@ fn farm_multiple_claim_weeks_with_collect_undistributed_rewards_test() { // random tx on end of week 3, to cummulate rewards farm_setup.b_mock.set_block_epoch(20); + farm_setup + .b_mock + .set_block_timestamp(21 * TIMESTAMP_PER_EPOCH - 1); + farm_setup.set_user_energy(&first_user, 1_000, 20, 1); farm_setup.set_user_energy(&second_user, 4_000, 20, 1); farm_setup.set_user_energy(&third_user, 1, 20, 1); @@ -631,9 +665,13 @@ fn farm_multiple_claim_weeks_with_collect_undistributed_rewards_test() { farm_setup.exit_farm(&third_user, 9, 1); // advance week - farm_setup.b_mock.set_block_epoch(22); - farm_setup.set_user_energy(&first_user, 1_000, 22, 1); - farm_setup.set_user_energy(&second_user, 4_000, 22, 1); + farm_setup.b_mock.set_block_epoch(27); + farm_setup + .b_mock + .set_block_timestamp(28 * TIMESTAMP_PER_EPOCH - 1); + + farm_setup.set_user_energy(&first_user, 1_000, 27, 1); + farm_setup.set_user_energy(&second_user, 4_000, 27, 1); // first user claim2 let first_base_farm_amt = first_farm_token_amount * 15_000 / total_farm_tokens; @@ -748,10 +786,12 @@ fn farm_multiple_claim_weeks_with_collect_undistributed_rewards_test() { #[test] fn farm_enter_with_multiple_farm_token() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -864,10 +904,12 @@ fn farm_enter_with_multiple_farm_token() { #[test] fn farm_claim_with_minimum_tokens() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -980,3 +1022,133 @@ fn farm_claim_with_minimum_tokens() { farm_setup.check_remaining_boosted_rewards_to_distribute(2, 0); farm_setup.check_remaining_boosted_rewards_to_distribute(3, 0); } + +#[test] +fn partial_boosted_rewards_test() { + DebugApi::dummy(); + + let mut farm_setup = MultiUserFarmSetup::new( + farm::contract_obj, + energy_factory_mock::contract_obj, + energy_update::contract_obj, + timestamp_oracle::contract_obj, + permissions_hub::contract_obj, + ); + + farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); + farm_setup.set_boosted_yields_factors(); + farm_setup.b_mock.set_block_epoch(0); + farm_setup.b_mock.set_block_timestamp(1); + + // first user enter farm + let first_farm_token_amount = 100_000_000; + let first_user = farm_setup.first_user.clone(); + let third_user = farm_setup.third_user.clone(); + farm_setup.set_user_energy(&first_user, 1_000, 0, 1); + farm_setup.enter_farm(&first_user, first_farm_token_amount); + + // second user enter farm later + farm_setup.b_mock.set_block_epoch(3); + farm_setup + .b_mock + .set_block_timestamp(3 * TIMESTAMP_PER_EPOCH + TIMESTAMP_PER_EPOCH / 2); + + let second_farm_token_amount = 50_000_000; + let second_user = farm_setup.second_user.clone(); + farm_setup.set_user_energy(&second_user, 4_000, 0, 1); + farm_setup.enter_farm(&second_user, second_farm_token_amount); + + // users claim rewards to get their energy registered + let _ = farm_setup.claim_rewards(&first_user, 1, first_farm_token_amount); + let _ = farm_setup.claim_rewards(&second_user, 2, second_farm_token_amount); + + // advance blocks - 10 blocks - 10 * 1_000 = 10_000 total rewards + // 7_500 base farm, 2_500 boosted yields + farm_setup.b_mock.set_block_nonce(10); + + // random tx on end of week 1, to cummulate rewards + farm_setup.b_mock.set_block_epoch(6); + farm_setup + .b_mock + .set_block_timestamp(6 * TIMESTAMP_PER_EPOCH); + + farm_setup.set_user_energy(&first_user, 1_000, 6, 1); + farm_setup.set_user_energy(&second_user, 4_000, 6, 1); + farm_setup.set_user_energy(&third_user, 1, 6, 1); + farm_setup.enter_farm(&third_user, 1); + farm_setup.exit_farm(&third_user, 5, 1); + + // advance 1 week + farm_setup.b_mock.set_block_epoch(13); + farm_setup + .b_mock + .set_block_timestamp(14 * TIMESTAMP_PER_EPOCH - 1); + + farm_setup.set_user_energy(&first_user, 1_000, 13, 1); + farm_setup.set_user_energy(&second_user, 4_000, 13, 1); + + let total_farm_tokens = first_farm_token_amount + second_farm_token_amount; + + // first user claim + let first_base_farm_amt = first_farm_token_amount * 7_500 / total_farm_tokens; + + // Boosted yields rewards formula + // total_boosted_rewards * (energy_const * user_energy / total_energy + farm_const * user_farm / total_farm) / (energy_const + farm_const) + // (total_boosted_rewards * energy_const * user_energy / total_energy + total_boosted_rewards * farm_const * user_farm / total_farm) / (energy_const + farm_const) + // (2500 * 3 * 1_000 / 5_000 + 2500 * 2 * 100_000_000 / 150_000_000) / (3 + 2) + // (1500 + 3333) / (5) = 966 + let first_boosted_amt = 966; // 1000 energy & 100_000_000 farm tokens + let first_total = first_base_farm_amt + first_boosted_amt; + + let first_receveived_reward_amt = + farm_setup.claim_rewards(&first_user, 3, first_farm_token_amount); + assert_eq!(first_receveived_reward_amt, first_total); + + farm_setup + .b_mock + .check_nft_balance::>( + &first_user, + FARM_TOKEN_ID, + 6, + &rust_biguint!(first_farm_token_amount), + None, + ); + + farm_setup.b_mock.check_esdt_balance( + &first_user, + REWARD_TOKEN_ID, + &rust_biguint!(first_receveived_reward_amt), + ); + + // second user claim + let second_base_farm_amt = second_farm_token_amount * 7_500 / total_farm_tokens; + + // Boosted yields rewards formula + // total_boosted_rewards * (energy_const * user_energy / total_energy + farm_const * user_farm / total_farm) / (energy_const + farm_const) + // (total_boosted_rewards * energy_const * user_energy / total_energy + total_boosted_rewards * farm_const * user_farm / total_farm) / (energy_const + farm_const) + // (2500 * 3 * 4000 / 5_000 + 2500 * 2 * 50_000_000 / 150_000_000) / (3 + 2) + // (6000 + 1666) / (5) = 1533 + // Second user receives only half the amount, as they entered later + let second_boosted_amt = 1533 / 2; // 4000 energy & 50_000_000 farm tokens + let second_total = second_base_farm_amt + second_boosted_amt; + + let second_receveived_reward_amt = + farm_setup.claim_rewards(&second_user, 4, second_farm_token_amount); + assert_eq!(second_receveived_reward_amt, second_total); + + farm_setup + .b_mock + .check_nft_balance::>( + &second_user, + FARM_TOKEN_ID, + 7, + &rust_biguint!(second_farm_token_amount), + None, + ); + + farm_setup.b_mock.check_esdt_balance( + &second_user, + REWARD_TOKEN_ID, + &rust_biguint!(second_receveived_reward_amt), + ); +} diff --git a/dex/farm/tests/farm_review_distribution.rs b/dex/farm/tests/farm_review_distribution.rs index 2ac08d444..1c39956c4 100644 --- a/dex/farm/tests/farm_review_distribution.rs +++ b/dex/farm/tests/farm_review_distribution.rs @@ -8,7 +8,11 @@ use multiversx_sc_scenario::rust_biguint; #[test] fn test_overview() { let per_block_reward_amount = rust_biguint!(100); - let mut farm_setup = FarmRewardsDistrSetup::new(farm::contract_obj, per_block_reward_amount); + let mut farm_setup = FarmRewardsDistrSetup::new( + farm::contract_obj, + per_block_reward_amount, + timestamp_oracle::contract_obj, + ); let alice = farm_setup.new_address_with_lp_tokens(rust_biguint!(5_000)); let bob = farm_setup.new_address_with_lp_tokens(rust_biguint!(5_000)); let eve = farm_setup.new_address_with_lp_tokens(rust_biguint!(5_000)); @@ -63,7 +67,11 @@ fn test_overview() { #[test] fn test_overview_but_changes_in_per_reward_block() { let per_block_reward_amount = rust_biguint!(100); - let mut farm_setup = FarmRewardsDistrSetup::new(farm::contract_obj, per_block_reward_amount); + let mut farm_setup = FarmRewardsDistrSetup::new( + farm::contract_obj, + per_block_reward_amount, + timestamp_oracle::contract_obj, + ); let alice = farm_setup.new_address_with_lp_tokens(rust_biguint!(5_000)); let bob = farm_setup.new_address_with_lp_tokens(rust_biguint!(5_000)); let eve = farm_setup.new_address_with_lp_tokens(rust_biguint!(5_000)); @@ -136,7 +144,11 @@ fn exp18(value: u64) -> RustBigUint { #[test] fn test_overview_realistic_numbers() { let per_block_reward_amount = exp18(100); - let mut farm_setup = FarmRewardsDistrSetup::new(farm::contract_obj, per_block_reward_amount); + let mut farm_setup = FarmRewardsDistrSetup::new( + farm::contract_obj, + per_block_reward_amount, + timestamp_oracle::contract_obj, + ); let alice = farm_setup.new_address_with_lp_tokens(exp18(5_000)); let bob = farm_setup.new_address_with_lp_tokens(exp18(5_000)); let eve = farm_setup.new_address_with_lp_tokens(exp18(5_000)); @@ -206,7 +218,11 @@ fn exp21(value: u64) -> RustBigUint { #[test] fn test_billion_to_trillion() { let per_block_reward_amount = exp21(100); - let mut farm_setup = FarmRewardsDistrSetup::new(farm::contract_obj, per_block_reward_amount); + let mut farm_setup = FarmRewardsDistrSetup::new( + farm::contract_obj, + per_block_reward_amount, + timestamp_oracle::contract_obj, + ); let alice = farm_setup.new_address_with_lp_tokens(exp21(5_000)); let bob = farm_setup.new_address_with_lp_tokens(exp21(5_000)); let eve = farm_setup.new_address_with_lp_tokens(exp21(5_000)); @@ -272,7 +288,11 @@ fn test_billion_to_trillion() { #[test] fn test_rv_earn_twice() { let per_block_reward_amount = rust_biguint!(100); - let mut farm_setup = FarmRewardsDistrSetup::new(farm::contract_obj, per_block_reward_amount); + let mut farm_setup = FarmRewardsDistrSetup::new( + farm::contract_obj, + per_block_reward_amount, + timestamp_oracle::contract_obj, + ); let alice = farm_setup.new_address_with_lp_tokens(rust_biguint!(5_000)); let bob = farm_setup.new_address_with_lp_tokens(rust_biguint!(5_000)); farm_setup.step( 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 f39c3136e..38ed867fd 100644 --- a/dex/farm/tests/farm_setup/farm_rewards_distr_setup.rs +++ b/dex/farm/tests/farm_setup/farm_rewards_distr_setup.rs @@ -1,21 +1,25 @@ #![allow(dead_code)] -#![allow(deprecated)] +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}; +use multiversx_sc_scenario::managed_address; use multiversx_sc_scenario::{ - managed_address, managed_biguint, managed_token_id, rust_biguint, - whitebox_legacy::TxTokenTransfer, whitebox_legacy::*, DebugApi, + managed_biguint, managed_token_id, rust_biguint, whitebox_legacy::TxTokenTransfer, + whitebox_legacy::*, DebugApi, }; pub type RustBigUint = num_bigint::BigUint; use config::*; -use farm::exit_penalty::ExitPenaltyModule; use farm::*; use farm_token::FarmTokenModule; use pausable::{PausableModule, State}; use rewards::*; +use timestamp_oracle::epoch_to_timestamp::EpochToTimestampModule; +use timestamp_oracle::TimestampOracle; + +use super::multi_user_farm_setup::TIMESTAMP_PER_EPOCH; pub const FARM_WASM_PATH: &str = "farm/output/farm.wasm"; @@ -52,44 +56,63 @@ impl Expected { } } -pub struct FarmRewardsDistrSetup +pub struct FarmRewardsDistrSetup where FarmObjBuilder: 'static + Copy + Fn() -> farm::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, { pub blockchain_wrapper: BlockchainStateWrapper, pub owner_address: Address, pub farm_wrapper: ContractObjWrapper, FarmObjBuilder>, + pub timestamp_oracle_wrapper: + ContractObjWrapper, TimestampOracleObjBuilder>, } -impl FarmRewardsDistrSetup +impl + FarmRewardsDistrSetup where FarmObjBuilder: 'static + Copy + Fn() -> farm::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, { - pub fn new(farm_builder: FarmObjBuilder, per_block_reward_amount: RustBigUint) -> Self { + pub fn new( + farm_builder: FarmObjBuilder, + per_block_reward_amount: RustBigUint, + timestamp_oracle_builder: TimestampOracleObjBuilder, + ) -> Self { let rust_zero = rust_biguint!(0u64); - let mut blockchain_wrapper = BlockchainStateWrapper::new(); - let owner_addr = blockchain_wrapper.create_user_account(&rust_zero); - let farm_wrapper = blockchain_wrapper.create_sc_account( + let mut b_mock = BlockchainStateWrapper::new(); + let owner = b_mock.create_user_account(&rust_zero); + let farm_wrapper = + b_mock.create_sc_account(&rust_zero, Some(&owner), farm_builder, FARM_WASM_PATH); + + let timestamp_oracle_wrapper = b_mock.create_sc_account( &rust_zero, - Some(&owner_addr), - farm_builder, - FARM_WASM_PATH, + Some(&owner), + timestamp_oracle_builder, + "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(); // init farm contract - blockchain_wrapper - .execute_tx(&owner_addr, &farm_wrapper, &rust_zero, |sc| { + b_mock + .execute_tx(&owner, &farm_wrapper, &rust_zero, |sc| { let reward_token_id = managed_token_id!(MEX_TOKEN_ID); let farming_token_id = managed_token_id!(LP_TOKEN_ID); let division_safety_constant = managed_biguint!(DIVISION_SAFETY_CONSTANT); - let pair_address = managed_address!(&Address::zero()); sc.init( reward_token_id, farming_token_id, division_safety_constant, - pair_address, ManagedAddress::::zero(), MultiValueEncoded::new(), ); @@ -99,11 +122,12 @@ where sc.per_block_reward_amount() .set(&to_managed_biguint(per_block_reward_amount)); - sc.minimum_farming_epochs().set(MIN_FARMING_EPOCHS); - sc.penalty_percent().set(PENALTY_PERCENT); 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(); @@ -112,30 +136,31 @@ where EsdtLocalRole::NftAddQuantity, EsdtLocalRole::NftBurn, ]; - blockchain_wrapper.set_esdt_local_roles( + b_mock.set_esdt_local_roles( farm_wrapper.address_ref(), FARM_TOKEN_ID, &farm_token_roles[..], ); let farming_token_roles = [EsdtLocalRole::Burn]; - blockchain_wrapper.set_esdt_local_roles( + b_mock.set_esdt_local_roles( farm_wrapper.address_ref(), LP_TOKEN_ID, &farming_token_roles[..], ); let reward_token_roles = [EsdtLocalRole::Mint]; - blockchain_wrapper.set_esdt_local_roles( + b_mock.set_esdt_local_roles( farm_wrapper.address_ref(), MEX_TOKEN_ID, &reward_token_roles[..], ); FarmRewardsDistrSetup { - blockchain_wrapper, - owner_address: owner_addr, + blockchain_wrapper: b_mock, + owner_address: owner, farm_wrapper, + timestamp_oracle_wrapper, } } 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 3398fd679..c2f0e3f62 100644 --- a/dex/farm/tests/farm_setup/multi_user_farm_setup.rs +++ b/dex/farm/tests/farm_setup/multi_user_farm_setup.rs @@ -1,9 +1,9 @@ #![allow(dead_code)] -#![allow(deprecated)] -use common_structs::FarmTokenAttributes; +use common_structs::{FarmTokenAttributes, Timestamp}; use config::ConfigModule; use farm::external_interaction::ExternalInteractionsModule; +use farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule; use multiversx_sc::codec::multi_types::OptionalValue; use multiversx_sc::{ storage::mappers::StorageTokenWrapper, @@ -21,12 +21,13 @@ use energy_query::{Energy, EnergyQueryModule}; use energy_update::EnergyUpdate; use farm::Farm; use farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule; -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 timestamp_oracle::epoch_to_timestamp::EpochToTimestampModule; +use timestamp_oracle::TimestampOracle; use week_timekeeping::Epoch; use weekly_rewards_splitting::update_claim_progress_energy::UpdateClaimProgressEnergyModule; @@ -43,6 +44,7 @@ pub const USER_REWARDS_ENERGY_CONST: u64 = 3; pub const USER_REWARDS_FARM_CONST: u64 = 2; pub const MIN_ENERGY_AMOUNT_FOR_BOOSTED_YIELDS: u64 = 1; pub const MIN_FARM_AMOUNT_FOR_BOOSTED_YIELDS: u64 = 1; +pub const TIMESTAMP_PER_EPOCH: Timestamp = 24 * 60 * 60; pub struct RawFarmTokenAttributes { pub reward_per_share_bytes: Vec, @@ -61,11 +63,13 @@ pub struct MultiUserFarmSetup< FarmObjBuilder, EnergyFactoryBuilder, EnergyUpdateObjBuilder, + TimestampOracleObjBuilder, PermissionsHubObjBuilder, > where FarmObjBuilder: 'static + Copy + Fn() -> farm::ContractObj, EnergyFactoryBuilder: 'static + Copy + Fn() -> energy_factory_mock::ContractObj, EnergyUpdateObjBuilder: 'static + Copy + Fn() -> energy_update::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, PermissionsHubObjBuilder: 'static + Copy + Fn() -> permissions_hub::ContractObj, { pub b_mock: BlockchainStateWrapper, @@ -79,27 +83,38 @@ pub struct MultiUserFarmSetup< ContractObjWrapper, EnergyFactoryBuilder>, pub eu_wrapper: ContractObjWrapper, EnergyUpdateObjBuilder>, + pub timestamp_oracle_wrapper: + ContractObjWrapper, TimestampOracleObjBuilder>, pub permissions_hub_wrapper: ContractObjWrapper, PermissionsHubObjBuilder>, } -impl +impl< + FarmObjBuilder, + EnergyFactoryBuilder, + EnergyUpdateObjBuilder, + TimestampOracleObjBuilder, + PermissionsHubObjBuilder, + > MultiUserFarmSetup< FarmObjBuilder, EnergyFactoryBuilder, EnergyUpdateObjBuilder, + TimestampOracleObjBuilder, PermissionsHubObjBuilder, > where FarmObjBuilder: 'static + Copy + Fn() -> farm::ContractObj, EnergyFactoryBuilder: 'static + Copy + Fn() -> energy_factory_mock::ContractObj, EnergyUpdateObjBuilder: 'static + Copy + Fn() -> energy_update::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, PermissionsHubObjBuilder: 'static + Copy + Fn() -> permissions_hub::ContractObj, { pub fn new( farm_builder: FarmObjBuilder, energy_factory_builder: EnergyFactoryBuilder, eu_builder: EnergyUpdateObjBuilder, + timestamp_oracle_builder: TimestampOracleObjBuilder, permissions_hub_builder: PermissionsHubObjBuilder, ) -> Self { let rust_zero = rust_biguint!(0); @@ -125,6 +140,22 @@ where }) .assert_ok(); + let timestamp_oracle_wrapper = b_mock.create_sc_account( + &rust_zero, + Some(&owner), + timestamp_oracle_builder, + "timestamp oracle", + ); + b_mock + .execute_tx(&owner, ×tamp_oracle_wrapper, &rust_zero, |sc| { + sc.init(0); + + for i in 0..=100 { + sc.set_start_timestamp_for_epoch(i, i * TIMESTAMP_PER_EPOCH + 1); + } + }) + .assert_ok(); + let permissions_hub_wrapper = b_mock.create_sc_account( &rust_zero, Some(&owner), @@ -143,13 +174,11 @@ where let reward_token_id = managed_token_id!(REWARD_TOKEN_ID); let farming_token_id = managed_token_id!(FARMING_TOKEN_ID); let division_safety_constant = managed_biguint!(DIV_SAFETY); - let pair_address = managed_address!(&Address::zero()); sc.init( reward_token_id, farming_token_id, division_safety_constant, - pair_address, managed_address!(&owner), MultiValueEncoded::new(), ); @@ -165,6 +194,9 @@ 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() @@ -223,6 +255,7 @@ where farm_wrapper, energy_factory_wrapper, eu_wrapper, + timestamp_oracle_wrapper, permissions_hub_wrapper, } } 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 4fb48c955..87eb38ca4 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,7 @@ #![allow(dead_code)] -#![allow(deprecated)] 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}; @@ -13,13 +13,16 @@ use multiversx_sc_scenario::{ type RustBigUint = num_bigint::BigUint; use config::*; -use farm::exit_penalty::ExitPenaltyModule; use farm::*; use farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule; use farm_token::FarmTokenModule; use pair::pair_actions::add_liq::AddLiquidityModule as _; use pair::{config::ConfigModule as OtherConfigModule, Pair}; use pausable::{PausableModule, State}; +use timestamp_oracle::epoch_to_timestamp::EpochToTimestampModule; +use timestamp_oracle::TimestampOracle; + +use super::multi_user_farm_setup::TIMESTAMP_PER_EPOCH; pub const FARM_WASM_PATH: &str = "farm/output/farm.wasm"; pub const PAIR_WASM_PATH: &str = "pair/output/pair.wasm"; @@ -29,8 +32,6 @@ pub const MEX_TOKEN_ID: &[u8] = b"MEX-abcdef"; // reward token ID pub const LP_TOKEN_ID: &[u8] = b"LPTOK-abcdef"; // farming token ID pub const FARM_TOKEN_ID: &[u8] = b"FARM-abcdef"; pub const DIVISION_SAFETY_CONSTANT: u64 = 1_000_000_000_000; -pub const MIN_FARMING_EPOCHS: u64 = 2; -pub const PENALTY_PERCENT: u64 = 10; pub const MAX_PERCENT: u64 = 10_000; pub const PER_BLOCK_REWARD_AMOUNT: u64 = 5_000; pub const USER_TOTAL_LP_TOKENS: u64 = 5_000_000_000; @@ -43,42 +44,63 @@ pub const LOCKED_TOKEN_ID: &[u8] = b"XMEX-123456"; pub const LOCKED_LP_TOKEN_ID: &[u8] = b"LKLP-123456"; pub const FARM_PROXY_TOKEN_ID: &[u8] = b"PROXY-123456"; -pub struct SingleUserFarmSetup +pub struct SingleUserFarmSetup where FarmObjBuilder: 'static + Copy + Fn() -> farm::ContractObj, PairObjBuilder: 'static + Copy + Fn() -> pair::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, { pub blockchain_wrapper: BlockchainStateWrapper, pub owner_address: Address, pub user_address: Address, pub farm_wrapper: ContractObjWrapper, FarmObjBuilder>, pub pair_wrapper: ContractObjWrapper, PairObjBuilder>, + pub timestamp_oracle_wrapper: + ContractObjWrapper, TimestampOracleObjBuilder>, } -impl SingleUserFarmSetup +impl + SingleUserFarmSetup where FarmObjBuilder: 'static + Copy + Fn() -> farm::ContractObj, PairObjBuilder: 'static + Copy + Fn() -> pair::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, { - pub fn new(farm_builder: FarmObjBuilder, pair_builder: PairObjBuilder) -> Self { + pub fn new( + farm_builder: FarmObjBuilder, + pair_builder: PairObjBuilder, + timestamp_oracle_builder: TimestampOracleObjBuilder, + ) -> Self { let rust_zero = rust_biguint!(0u64); - let mut blockchain_wrapper = BlockchainStateWrapper::new(); - let owner_addr = blockchain_wrapper.create_user_account(&rust_zero); + let mut b_mock = BlockchainStateWrapper::new(); + let owner = b_mock.create_user_account(&rust_zero); - let pair_wrapper = blockchain_wrapper.create_sc_account( + let timestamp_oracle_wrapper = b_mock.create_sc_account( &rust_zero, - Some(&owner_addr), - pair_builder, - PAIR_WASM_PATH, + Some(&owner), + timestamp_oracle_builder, + "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(); + + let pair_wrapper = + b_mock.create_sc_account(&rust_zero, Some(&owner), pair_builder, PAIR_WASM_PATH); // init pair contract - blockchain_wrapper - .execute_tx(&owner_addr, &pair_wrapper, &rust_zero, |sc| { + b_mock + .execute_tx(&owner, &pair_wrapper, &rust_zero, |sc| { let first_token_id = managed_token_id!(WEGLD_TOKEN_ID); let second_token_id = managed_token_id!(MEX_TOKEN_ID); - let router_address = managed_address!(&owner_addr); - let router_owner_address = managed_address!(&owner_addr); + let router_address = managed_address!(&owner); + let router_owner_address = managed_address!(&owner); let total_fee_percent = 300u64; let special_fee_percent = 50u64; @@ -101,33 +123,23 @@ where .assert_ok(); let lp_token_roles = [EsdtLocalRole::Mint, EsdtLocalRole::Burn]; - blockchain_wrapper.set_esdt_local_roles( - pair_wrapper.address_ref(), - LP_TOKEN_ID, - &lp_token_roles[..], - ); + b_mock.set_esdt_local_roles(pair_wrapper.address_ref(), LP_TOKEN_ID, &lp_token_roles[..]); - let farm_wrapper = blockchain_wrapper.create_sc_account( - &rust_zero, - Some(&owner_addr), - farm_builder, - FARM_WASM_PATH, - ); + let farm_wrapper = + b_mock.create_sc_account(&rust_zero, Some(&owner), farm_builder, FARM_WASM_PATH); // init farm contract - blockchain_wrapper - .execute_tx(&owner_addr, &farm_wrapper, &rust_zero, |sc| { + b_mock + .execute_tx(&owner, &farm_wrapper, &rust_zero, |sc| { let reward_token_id = managed_token_id!(MEX_TOKEN_ID); let farming_token_id = managed_token_id!(LP_TOKEN_ID); let division_safety_constant = managed_biguint!(DIVISION_SAFETY_CONSTANT); - let pair_address = managed_address!(&Address::zero()); sc.init( reward_token_id, farming_token_id, division_safety_constant, - pair_address, ManagedAddress::::zero(), MultiValueEncoded::new(), ); @@ -137,16 +149,17 @@ where sc.per_block_reward_amount() .set(&managed_biguint!(PER_BLOCK_REWARD_AMOUNT)); - sc.minimum_farming_epochs().set(MIN_FARMING_EPOCHS); - sc.penalty_percent().set(PENALTY_PERCENT); 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(); - blockchain_wrapper - .execute_tx(&owner_addr, &farm_wrapper, &rust_biguint!(0), |sc| { + b_mock + .execute_tx(&owner, &farm_wrapper, &rust_biguint!(0), |sc| { sc.set_boosted_yields_factors( managed_biguint!(MAX_REWARDS_FACTOR), managed_biguint!(USER_REWARDS_ENERGY_CONST), @@ -162,39 +175,40 @@ where EsdtLocalRole::NftAddQuantity, EsdtLocalRole::NftBurn, ]; - blockchain_wrapper.set_esdt_local_roles( + b_mock.set_esdt_local_roles( farm_wrapper.address_ref(), FARM_TOKEN_ID, &farm_token_roles[..], ); let farming_token_roles = [EsdtLocalRole::Burn]; - blockchain_wrapper.set_esdt_local_roles( + b_mock.set_esdt_local_roles( farm_wrapper.address_ref(), LP_TOKEN_ID, &farming_token_roles[..], ); let reward_token_roles = [EsdtLocalRole::Mint]; - blockchain_wrapper.set_esdt_local_roles( + b_mock.set_esdt_local_roles( farm_wrapper.address_ref(), MEX_TOKEN_ID, &reward_token_roles[..], ); - let user_addr = blockchain_wrapper.create_user_account(&rust_biguint!(100_000_000)); - blockchain_wrapper.set_esdt_balance( + let user_addr = b_mock.create_user_account(&rust_biguint!(100_000_000)); + b_mock.set_esdt_balance( &user_addr, LP_TOKEN_ID, &rust_biguint!(USER_TOTAL_LP_TOKENS), ); SingleUserFarmSetup { - blockchain_wrapper, - owner_address: owner_addr, + blockchain_wrapper: b_mock, + owner_address: owner, user_address: user_addr, farm_wrapper, pair_wrapper, + timestamp_oracle_wrapper, } } diff --git a/dex/farm/tests/farm_single_user_test.rs b/dex/farm/tests/farm_single_user_test.rs index e060fbbdf..c2bede496 100644 --- a/dex/farm/tests/farm_single_user_test.rs +++ b/dex/farm/tests/farm_single_user_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod farm_setup; use config::ConfigModule; @@ -13,12 +11,20 @@ use sc_whitelist_module::SCWhitelistModule; #[test] fn test_farm_setup() { - let _ = SingleUserFarmSetup::new(farm::contract_obj, pair::contract_obj); + let _ = SingleUserFarmSetup::new( + farm::contract_obj, + pair::contract_obj, + timestamp_oracle::contract_obj, + ); } #[test] fn test_enter_farm() { - let mut farm_setup = SingleUserFarmSetup::new(farm::contract_obj, pair::contract_obj); + let mut farm_setup = SingleUserFarmSetup::new( + farm::contract_obj, + pair::contract_obj, + timestamp_oracle::contract_obj, + ); let farm_in_amount = 100_000_000; let expected_farm_token_nonce = 1; @@ -28,7 +34,11 @@ fn test_enter_farm() { #[test] fn test_exit_farm() { - let mut farm_setup = SingleUserFarmSetup::new(farm::contract_obj, pair::contract_obj); + let mut farm_setup = SingleUserFarmSetup::new( + farm::contract_obj, + pair::contract_obj, + timestamp_oracle::contract_obj, + ); let farm_in_amount = 100_000_000; let expected_farm_token_nonce = 1; @@ -51,37 +61,13 @@ fn test_exit_farm() { farm_setup.check_farm_token_supply(0); } -#[test] -fn test_exit_farm_with_penalty() { - let mut farm_setup = SingleUserFarmSetup::new(farm::contract_obj, pair::contract_obj); - - let farm_in_amount = 100_000_000; - let expected_farm_token_nonce = 1; - farm_setup.enter_farm(farm_in_amount, &[], expected_farm_token_nonce, 0, 0, 0); - farm_setup.check_farm_token_supply(farm_in_amount); - - farm_setup.set_block_epoch(1); - farm_setup.set_block_nonce(10); - - let expected_farm_token_amount = - farm_in_amount - farm_in_amount * PENALTY_PERCENT / MAX_PERCENT; - let expected_mex_out = 10 * PER_BLOCK_REWARD_AMOUNT; - let expected_lp_token_balance = - rust_biguint!(USER_TOTAL_LP_TOKENS - farm_in_amount * PENALTY_PERCENT / MAX_PERCENT); - farm_setup.exit_farm( - farm_in_amount, - expected_farm_token_nonce, - expected_mex_out, - expected_farm_token_amount, - &rust_biguint!(expected_mex_out), - &expected_lp_token_balance, - ); - farm_setup.check_farm_token_supply(0); -} - #[test] fn test_claim_rewards() { - let mut farm_setup = SingleUserFarmSetup::new(farm::contract_obj, pair::contract_obj); + let mut farm_setup = SingleUserFarmSetup::new( + farm::contract_obj, + pair::contract_obj, + timestamp_oracle::contract_obj, + ); let farm_in_amount = 100_000_000; let expected_farm_token_nonce = 1; @@ -106,15 +92,18 @@ fn test_claim_rewards() { farm_setup.check_farm_token_supply(farm_in_amount); } -fn steps_enter_farm_twice( +fn steps_enter_farm_twice( farm_builder: FarmObjBuilder, pair_builder: PairObjBuilder, -) -> SingleUserFarmSetup + timestamp_oracle_builder: TimestampOracleObjBuilder, +) -> SingleUserFarmSetup where FarmObjBuilder: 'static + Copy + Fn() -> farm::ContractObj, PairObjBuilder: 'static + Copy + Fn() -> pair::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, { - let mut farm_setup = SingleUserFarmSetup::new(farm_builder, pair_builder); + let mut farm_setup = + SingleUserFarmSetup::new(farm_builder, pair_builder, timestamp_oracle_builder); let farm_in_amount = 100_000_000; let expected_farm_token_nonce = 1; @@ -157,12 +146,20 @@ where #[test] fn test_enter_farm_twice() { - let _ = steps_enter_farm_twice(farm::contract_obj, pair::contract_obj); + let _ = steps_enter_farm_twice( + farm::contract_obj, + pair::contract_obj, + timestamp_oracle::contract_obj, + ); } #[test] fn test_exit_farm_after_enter_twice() { - let mut farm_setup = steps_enter_farm_twice(farm::contract_obj, pair::contract_obj); + let mut farm_setup = steps_enter_farm_twice( + farm::contract_obj, + pair::contract_obj, + timestamp_oracle::contract_obj, + ); let farm_in_amount = 100_000_000; let second_farm_in_amount = 200_000_000; let total_farm_token = farm_in_amount + second_farm_in_amount; @@ -213,7 +210,11 @@ fn test_farm_through_simple_lock() { DebugApi::dummy(); let rust_zero = rust_biguint!(0); - let mut farm_setup = SingleUserFarmSetup::new(farm::contract_obj, pair::contract_obj); + let mut farm_setup = SingleUserFarmSetup::new( + farm::contract_obj, + pair::contract_obj, + timestamp_oracle::contract_obj, + ); let b_mock = &mut farm_setup.blockchain_wrapper; // setup simple lock SC diff --git a/dex/farm/tests/total_farm_position_test.rs b/dex/farm/tests/total_farm_position_test.rs index 4bee74227..80d8fd1a1 100644 --- a/dex/farm/tests/total_farm_position_test.rs +++ b/dex/farm/tests/total_farm_position_test.rs @@ -1,12 +1,10 @@ -#![allow(deprecated)] - mod farm_setup; use common_structs::FarmTokenAttributes; use config::ConfigModule; use farm_setup::multi_user_farm_setup::{ MultiUserFarmSetup, NonceAmountPair, BOOSTED_YIELDS_PERCENTAGE, MAX_PERCENTAGE, - PER_BLOCK_REWARD_AMOUNT, + PER_BLOCK_REWARD_AMOUNT, TIMESTAMP_PER_EPOCH, }; use multiversx_sc::types::EsdtLocalRole; use multiversx_sc_scenario::{ @@ -19,10 +17,12 @@ use crate::farm_setup::multi_user_farm_setup::{FARMING_TOKEN_ID, FARM_TOKEN_ID, #[test] fn total_farm_position_claim_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -125,10 +125,12 @@ fn total_farm_position_claim_test() { #[test] fn allow_external_claim_rewards_setting_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -192,10 +194,12 @@ fn allow_external_claim_rewards_setting_test() { #[test] fn total_farm_position_claim_for_other_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -296,10 +300,12 @@ fn total_farm_position_claim_for_other_test() { #[test] fn farm_total_position_migration_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -414,10 +420,12 @@ fn farm_total_position_migration_test() { #[test] fn farm_total_position_exit_migration_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -495,10 +503,12 @@ fn farm_total_position_exit_migration_test() { #[test] fn farm_total_position_on_claim_migration_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -586,10 +596,12 @@ fn farm_total_position_on_claim_migration_test() { #[test] fn farm_total_position_on_merge_migration_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -680,17 +692,19 @@ fn farm_total_position_on_merge_migration_test() { #[test] fn no_boosted_rewards_penalty_for_no_energy_test() { DebugApi::dummy(); - DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); farm_setup.set_boosted_yields_factors(); - farm_setup.b_mock.set_block_epoch(5); + farm_setup.b_mock.set_block_epoch(0); + farm_setup.b_mock.set_block_timestamp(1); let temp_user = farm_setup.third_user.clone(); @@ -712,6 +726,10 @@ fn no_boosted_rewards_penalty_for_no_energy_test() { // random tx on end of the week, to cummulate rewards farm_setup.b_mock.set_block_epoch(6); + farm_setup + .b_mock + .set_block_timestamp(7 * TIMESTAMP_PER_EPOCH - 1); + farm_setup.set_user_energy(&first_user, 1_000, 6, 1); farm_setup.set_user_energy(&temp_user, 1, 6, 1); farm_setup.enter_farm(&temp_user, 1); @@ -720,6 +738,9 @@ fn no_boosted_rewards_penalty_for_no_energy_test() { // advance to week 2 farm_setup.b_mock.set_block_nonce(20); farm_setup.b_mock.set_block_epoch(13); + farm_setup + .b_mock + .set_block_timestamp(14 * TIMESTAMP_PER_EPOCH - 1); // User unlocks XMEX and has no energy farm_setup.set_user_energy(&first_user, 0, 13, 1); @@ -734,12 +755,19 @@ fn no_boosted_rewards_penalty_for_no_energy_test() { // random tx on end of the week, to cummulate rewards farm_setup.b_mock.set_block_epoch(20); + farm_setup + .b_mock + .set_block_timestamp(21 * TIMESTAMP_PER_EPOCH - 1); + farm_setup.set_user_energy(&temp_user, 1, 20, 1); farm_setup.enter_farm(&temp_user, 1); farm_setup.exit_farm(&temp_user, 6, 1); // advance to week 4 - farm_setup.b_mock.set_block_epoch(25); + farm_setup.b_mock.set_block_epoch(27); + farm_setup + .b_mock + .set_block_timestamp(28 * TIMESTAMP_PER_EPOCH - 1); // first user claims 3 weeks worth of rewards (2-4) let total_farm_tokens = farm_in_amount * 2; @@ -762,16 +790,19 @@ fn no_boosted_rewards_penalty_for_no_energy_test() { #[test] fn total_farm_position_owner_change_test() { DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); farm_setup.set_boosted_yields_factors(); - farm_setup.b_mock.set_block_epoch(2); + farm_setup.b_mock.set_block_epoch(0); + farm_setup.b_mock.set_block_timestamp(1); // first user enters farm 6 times let farm_token_amount = 10_000_000; @@ -796,11 +827,11 @@ fn total_farm_position_owner_change_test() { assert_eq!(farm_setup.last_farm_token_nonce, 6); // First user transfers 5 position to second user - farm_setup.send_farm_position(&first_user, &second_user, 1, farm_token_amount, 0, 2); - farm_setup.send_farm_position(&first_user, &second_user, 2, farm_token_amount, 0, 2); - farm_setup.send_farm_position(&first_user, &second_user, 3, farm_token_amount, 0, 2); - farm_setup.send_farm_position(&first_user, &second_user, 4, farm_token_amount, 0, 2); - farm_setup.send_farm_position(&first_user, &second_user, 5, farm_token_amount, 0, 2); + farm_setup.send_farm_position(&first_user, &second_user, 1, farm_token_amount, 0, 0); + farm_setup.send_farm_position(&first_user, &second_user, 2, farm_token_amount, 0, 0); + farm_setup.send_farm_position(&first_user, &second_user, 3, farm_token_amount, 0, 0); + farm_setup.send_farm_position(&first_user, &second_user, 4, farm_token_amount, 0, 0); + farm_setup.send_farm_position(&first_user, &second_user, 5, farm_token_amount, 0, 0); // Total farm position unchanged as users only transfered the farm positions farm_setup.check_user_total_farm_position(&first_user, first_user_total_position); @@ -828,6 +859,10 @@ fn total_farm_position_owner_change_test() { // random tx on end of week 1, to cummulate rewards farm_setup.b_mock.set_block_nonce(10); farm_setup.b_mock.set_block_epoch(6); + farm_setup + .b_mock + .set_block_timestamp(7 * TIMESTAMP_PER_EPOCH - 1); + farm_setup.set_user_energy(&first_user, 1_000, 6, 1); farm_setup.set_user_energy(&second_user, 4_000, 6, 1); farm_setup.set_user_energy(&third_user, 1, 6, 1); @@ -835,9 +870,13 @@ fn total_farm_position_owner_change_test() { farm_setup.exit_farm(&third_user, 10, 1); // advance 1 week - farm_setup.b_mock.set_block_epoch(10); - farm_setup.set_user_energy(&first_user, 1_000, 10, 1); - farm_setup.set_user_energy(&second_user, 4_000, 10, 1); + farm_setup.b_mock.set_block_epoch(13); + farm_setup + .b_mock + .set_block_timestamp(14 * TIMESTAMP_PER_EPOCH - 1); + + farm_setup.set_user_energy(&first_user, 1_000, 13, 1); + farm_setup.set_user_energy(&second_user, 4_000, 13, 1); // Second user claims with half a position from the first user let base_rewards_amount = 535; @@ -859,7 +898,7 @@ fn total_farm_position_owner_change_test() { &rust_biguint!(half_token_amount), Some(&FarmTokenAttributes:: { reward_per_share: managed_biguint!(107142857), - entering_epoch: 2, + entering_epoch: 0, compounded_reward: managed_biguint!(0), current_farm_amount: managed_biguint!(half_token_amount), original_owner: managed_address!(&second_user), @@ -874,7 +913,7 @@ fn total_farm_position_owner_change_test() { // random tx on end of week 2, to cummulate rewards farm_setup.b_mock.set_block_nonce(20); - farm_setup.b_mock.set_block_epoch(13); + farm_setup.set_user_energy(&first_user, 1_000, 13, 1); farm_setup.set_user_energy(&second_user, 4_000, 13, 1); farm_setup.set_user_energy(&third_user, 1, 13, 1); @@ -882,9 +921,13 @@ fn total_farm_position_owner_change_test() { farm_setup.exit_farm(&third_user, 12, 1); // advance 1 week - farm_setup.b_mock.set_block_epoch(15); - farm_setup.set_user_energy(&first_user, 1_000, 15, 1); - farm_setup.set_user_energy(&second_user, 4_000, 15, 1); + farm_setup.b_mock.set_block_epoch(20); + farm_setup + .b_mock + .set_block_timestamp(21 * TIMESTAMP_PER_EPOCH - 1); + + farm_setup.set_user_energy(&first_user, 1_000, 20, 1); + farm_setup.set_user_energy(&second_user, 4_000, 20, 1); // Second user exits farm with half of a position previously owned by user 1 second_user_reward_balance += 1071; // base rewards @@ -901,7 +944,7 @@ fn total_farm_position_owner_change_test() { // random tx on end of week 3, to cummulate rewards farm_setup.b_mock.set_block_nonce(30); - farm_setup.b_mock.set_block_epoch(20); + farm_setup.set_user_energy(&first_user, 1_000, 20, 1); farm_setup.set_user_energy(&second_user, 4_000, 20, 1); farm_setup.set_user_energy(&third_user, 1, 20, 1); @@ -909,9 +952,13 @@ fn total_farm_position_owner_change_test() { farm_setup.exit_farm(&third_user, 13, 1); // advance 1 week - farm_setup.b_mock.set_block_epoch(25); - farm_setup.set_user_energy(&first_user, 1_000, 25, 1); - farm_setup.set_user_energy(&second_user, 4_000, 25, 1); + farm_setup.b_mock.set_block_epoch(27); + farm_setup + .b_mock + .set_block_timestamp(28 * TIMESTAMP_PER_EPOCH - 1); + + farm_setup.set_user_energy(&first_user, 1_000, 27, 1); + farm_setup.set_user_energy(&second_user, 4_000, 27, 1); // First user claims rewards let first_user_received_reward_amt = @@ -957,7 +1004,7 @@ fn total_farm_position_owner_change_test() { &rust_biguint!(half_token_amount * 3), Some(&FarmTokenAttributes:: { reward_per_share: managed_biguint!(35714286), - entering_epoch: 2, + entering_epoch: 0, compounded_reward: managed_biguint!(0), current_farm_amount: managed_biguint!(half_token_amount * 3), original_owner: managed_address!(&second_user), @@ -987,10 +1034,12 @@ fn total_farm_position_through_simple_lock_test() { const MEX_TOKEN_ID: &[u8] = b"MEX-abcdef"; // reward token ID DebugApi::dummy(); + let mut farm_setup = MultiUserFarmSetup::new( farm::contract_obj, energy_factory_mock::contract_obj, energy_update::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); let rust_zero = rust_biguint!(0); diff --git a/dex/farm/wasm/Cargo.lock b/dex/farm/wasm/Cargo.lock index c85e89764..cceb61c15 100644 --- a/dex/farm/wasm/Cargo.lock +++ b/dex/farm/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -154,12 +147,15 @@ dependencies = [ name = "farm-boosted-yields" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "config", "energy-query", + "math", "multiversx-sc", "pausable", "permissions_module", + "timestamp-oracle", + "utils", "week-timekeeping", "weekly-rewards-splitting", ] @@ -198,22 +194,18 @@ dependencies = [ name = "farm_token" version = "0.0.0" dependencies = [ - "common_errors", "common_structs", - "config", "multiversx-sc", "multiversx-sc-modules", - "pausable", "permissions_module", - "token_send", ] [[package]] name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -505,6 +497,14 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "timestamp-oracle" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "token_merge_helper" version = "0.0.0" @@ -555,7 +555,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -563,7 +563,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/dex/farm/wasm/src/lib.rs b/dex/farm/wasm/src/lib.rs index 235653731..2ae1d5525 100644 --- a/dex/farm/wasm/src/lib.rs +++ b/dex/farm/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 66 +// Endpoints: 60 // Async Callback: 1 -// Total number of exported functions: 69 +// Total number of exported functions: 63 #![no_std] @@ -57,23 +57,17 @@ multiversx_sc_wasm_adapter::endpoints! { addSCAddressToWhitelist => add_sc_address_to_whitelist removeSCAddressFromWhitelist => remove_sc_address_from_whitelist isSCAddressWhitelisted => is_sc_address_whitelisted - set_penalty_percent => set_penalty_percent - set_minimum_farming_epochs => set_minimum_farming_epochs - set_burn_gas_limit => set_burn_gas_limit - getPenaltyPercent => penalty_percent - getMinimumFarmingEpoch => minimum_farming_epochs - getBurnGasLimit => burn_gas_limit - getPairContractManagedAddress => pair_contract_address enterFarmOnBehalf => enter_farm_on_behalf claimRewardsOnBehalf => claim_rewards_on_behalf + setBoostedYieldsFactors => set_boosted_yields_factors + getBoostedYieldsFactors => get_boosted_yields_factors + setTimestampOracleAddress => set_timestamp_oracle_address collectUndistributedBoostedRewards => collect_undistributed_boosted_rewards getBoostedYieldsRewardsPercentage => boosted_yields_rewards_percentage getAccumulatedRewardsForWeek => accumulated_rewards_for_week getFarmSupplyForWeek => farm_supply_for_week getRemainingBoostedRewardsToDistribute => remaining_boosted_rewards_to_distribute getUndistributedBoostedRewards => undistributed_boosted_rewards - setBoostedYieldsFactors => set_boosted_yields_factors - getBoostedYieldsFactors => get_boosted_yields_factors getCurrentWeek => get_current_week getFirstWeekStartEpoch => first_week_start_epoch getLastActiveWeekForUser => get_last_active_week_for_user_view diff --git a/dex/fuzz/src/fuzz_data.rs b/dex/fuzz/src/fuzz_data.rs index 320daf5d6..8bc2be8f3 100644 --- a/dex/fuzz/src/fuzz_data.rs +++ b/dex/fuzz/src/fuzz_data.rs @@ -1,12 +1,10 @@ #[cfg(test)] pub mod fuzz_data_tests { - #![allow(deprecated)] multiversx_sc::imports!(); multiversx_sc::derive_imports!(); use ::config::ConfigModule; - use farm::exit_penalty::ExitPenaltyModule; use farm::*; use farm_token::FarmTokenModule; use multiversx_sc::codec::Empty; @@ -41,8 +39,6 @@ pub mod fuzz_data_tests { pub const WEME_FARM_TOKEN_ID: &[u8] = b"WEMEFARM-abcdef"; pub const WEBU_FARM_TOKEN_ID: &[u8] = b"WEBUFARM-abcdef"; pub const MEX_FARM_TOKEN_ID: &[u8] = b"MEXFARM-abcdef"; - pub const MIN_FARMING_EPOCHS: u64 = 2; - pub const FARM_PENALTY_PERCENT: u64 = 10; pub const OWNER_EGLD_BALANCE: u64 = 100_000_000; pub const USER_TOTAL_MEX_TOKENS: u64 = 100_000_000_000; pub const USER_TOTAL_WEGLD_TOKENS: u64 = 100_000_000_000; @@ -403,13 +399,11 @@ pub mod fuzz_data_tests { let reward_token_id = managed_token_id!(reward_token); let farming_token_id = managed_token_id!(farming_token); let division_safety_constant = managed_biguint!(DIVISION_SAFETY_CONSTANT); - let pair_address = managed_address!(&Address::zero()); sc.init( reward_token_id, farming_token_id, division_safety_constant, - pair_address, ManagedAddress::::zero(), MultiValueEncoded::new(), ); @@ -419,8 +413,6 @@ pub mod fuzz_data_tests { sc.per_block_reward_amount() .set(&to_managed_biguint(per_block_reward_amount)); - sc.minimum_farming_epochs().set(MIN_FARMING_EPOCHS); - sc.penalty_percent().set(FARM_PENALTY_PERCENT); sc.state().set(State::Active); sc.produce_rewards_enabled().set(true); diff --git a/dex/fuzz/src/fuzz_farm.rs b/dex/fuzz/src/fuzz_farm.rs index bf1d32618..1660bc994 100644 --- a/dex/fuzz/src/fuzz_farm.rs +++ b/dex/fuzz/src/fuzz_farm.rs @@ -1,6 +1,5 @@ #[cfg(test)] pub mod fuzz_farm_test { - #![allow(deprecated)] multiversx_sc::imports!(); multiversx_sc::derive_imports!(); diff --git a/dex/fuzz/src/fuzz_pair.rs b/dex/fuzz/src/fuzz_pair.rs index e23babcf1..aabc3ce4d 100644 --- a/dex/fuzz/src/fuzz_pair.rs +++ b/dex/fuzz/src/fuzz_pair.rs @@ -1,6 +1,5 @@ #[cfg(test)] pub mod fuzz_pair_test { - #![allow(deprecated)] multiversx_sc::imports!(); multiversx_sc::derive_imports!(); diff --git a/dex/fuzz/src/fuzz_price_discovery.rs b/dex/fuzz/src/fuzz_price_discovery.rs index 37c1539d3..d327f947b 100644 --- a/dex/fuzz/src/fuzz_price_discovery.rs +++ b/dex/fuzz/src/fuzz_price_discovery.rs @@ -1,6 +1,5 @@ #[cfg(test)] pub mod fuzz_price_discovery_test { - #![allow(deprecated)] multiversx_sc::imports!(); multiversx_sc::derive_imports!(); diff --git a/dex/fuzz/src/fuzz_start.rs b/dex/fuzz/src/fuzz_start.rs index a22f7a231..f76721b42 100644 --- a/dex/fuzz/src/fuzz_start.rs +++ b/dex/fuzz/src/fuzz_start.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod test { - #![allow(deprecated)] multiversx_sc::imports!(); multiversx_sc::derive_imports!(); diff --git a/dex/governance/tests/gov_tests.rs b/dex/governance/tests/gov_tests.rs index 61dc9c985..1a05e7180 100644 --- a/dex/governance/tests/gov_tests.rs +++ b/dex/governance/tests/gov_tests.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use multiversx_sc::codec::multi_types::{MultiValue2, OptionalValue}; use multiversx_sc::types::MultiValueEncoded; use multiversx_sc::types::{Address, EsdtLocalRole, EsdtTokenPayment, ManagedVec}; diff --git a/dex/pair/tests/pair_rs_test.rs b/dex/pair/tests/pair_rs_test.rs index bd82750d8..723b3ddf0 100644 --- a/dex/pair/tests/pair_rs_test.rs +++ b/dex/pair/tests/pair_rs_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod pair_setup; use fees_collector::{ config::ConfigModule, fees_accumulation::FeesAccumulationModule, FeesCollector, diff --git a/dex/pair/wasm-pair-full/Cargo.lock b/dex/pair/wasm-pair-full/Cargo.lock index 50c1aa77e..fd8e2c16e 100644 --- a/dex/pair/wasm-pair-full/Cargo.lock +++ b/dex/pair/wasm-pair-full/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -85,8 +78,8 @@ dependencies = [ name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -390,7 +383,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -398,7 +391,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/dex/pair/wasm-safe-price-view/Cargo.lock b/dex/pair/wasm-safe-price-view/Cargo.lock index e71c9ac82..7d00608f9 100644 --- a/dex/pair/wasm-safe-price-view/Cargo.lock +++ b/dex/pair/wasm-safe-price-view/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -85,8 +78,8 @@ dependencies = [ name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -390,7 +383,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -398,7 +391,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/dex/pair/wasm/Cargo.lock b/dex/pair/wasm/Cargo.lock index 1b9f258d3..75fa3d911 100644 --- a/dex/pair/wasm/Cargo.lock +++ b/dex/pair/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -85,8 +78,8 @@ dependencies = [ name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -390,7 +383,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -398,7 +391,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/dex/price-discovery/tests/price_disc_tests.rs b/dex/price-discovery/tests/price_disc_tests.rs index a6cfbec43..e67f13a86 100644 --- a/dex/price-discovery/tests/price_disc_tests.rs +++ b/dex/price-discovery/tests/price_disc_tests.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use multiversx_sc::codec::Empty; use multiversx_sc_scenario::{managed_biguint, managed_token_id_wrapped}; use multiversx_sc_scenario::{rust_biguint, DebugApi}; diff --git a/dex/price-discovery/tests/tests_common.rs b/dex/price-discovery/tests/tests_common.rs index 984a7ec0c..63b81032f 100644 --- a/dex/price-discovery/tests/tests_common.rs +++ b/dex/price-discovery/tests/tests_common.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use multiversx_sc::codec::Empty; use multiversx_sc::types::{Address, EsdtLocalRole}; use multiversx_sc_scenario::whitebox_legacy::TxResult; diff --git a/dex/proxy-deployer/src/farm_deploy.rs b/dex/proxy-deployer/src/farm_deploy.rs index 8500946e8..eb1c88e53 100644 --- a/dex/proxy-deployer/src/farm_deploy.rs +++ b/dex/proxy-deployer/src/farm_deploy.rs @@ -11,7 +11,6 @@ pub trait FarmDeployModule { &self, reward_token_id: TokenIdentifier, farming_token_id: TokenIdentifier, - pair_contract_address: ManagedAddress, ) -> ManagedAddress { let owner = self.blockchain().get_owner_address(); let caller = self.blockchain().get_caller(); @@ -27,7 +26,6 @@ pub trait FarmDeployModule { reward_token_id, farming_token_id, DIVISION_SAFETY_CONST, - pair_contract_address, owner, admins_list, ) diff --git a/dex/proxy-deployer/wasm/Cargo.lock b/dex/proxy-deployer/wasm/Cargo.lock index 8d87420e6..d012a5597 100644 --- a/dex/proxy-deployer/wasm/Cargo.lock +++ b/dex/proxy-deployer/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -138,6 +131,7 @@ dependencies = [ "multiversx-sc-modules", "pair", "pausable", + "permissions-hub", "permissions_module", "rewards", "sc_whitelist_module", @@ -151,12 +145,15 @@ dependencies = [ name = "farm-boosted-yields" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "config", "energy-query", + "math", "multiversx-sc", "pausable", "permissions_module", + "timestamp-oracle", + "utils", "week-timekeeping", "weekly-rewards-splitting", ] @@ -187,22 +184,18 @@ dependencies = [ name = "farm_token" version = "0.0.0" dependencies = [ - "common_errors", "common_structs", - "config", "multiversx-sc", "multiversx-sc-modules", - "pausable", "permissions_module", - "token_send", ] [[package]] name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -385,6 +378,13 @@ dependencies = [ "permissions_module", ] +[[package]] +name = "permissions-hub" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + [[package]] name = "permissions_module" version = "0.0.0" @@ -490,6 +490,14 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "timestamp-oracle" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "token_merge_helper" version = "0.0.0" @@ -540,7 +548,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -548,7 +556,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/dex/router/src/contract.rs b/dex/router/src/contract.rs index ad30b7f9e..f879e36e6 100644 --- a/dex/router/src/contract.rs +++ b/dex/router/src/contract.rs @@ -1,5 +1,4 @@ #![no_std] -#![allow(deprecated)] multiversx_sc::imports!(); multiversx_sc::derive_imports!(); @@ -231,12 +230,11 @@ pub trait Router: can_add_special_roles: true, }, ) - .async_call() .with_callback( self.callbacks() .lp_token_issue_callback(&caller, &pair_address), ) - .call_and_exit() + .async_call_and_exit() } #[endpoint(setLocalRoles)] @@ -255,8 +253,7 @@ pub trait Router: self.send() .esdt_system_sc_proxy() .set_special_roles(&pair_address, &pair_token, roles.iter().cloned()) - .async_call() - .call_and_exit() + .async_call_and_exit() } #[only_owner] diff --git a/dex/router/tests/router_test.rs b/dex/router/tests/router_test.rs index 6564a508e..23aa87b90 100644 --- a/dex/router/tests/router_test.rs +++ b/dex/router/tests/router_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod router_setup; use multiversx_sc::{ codec::multi_types::OptionalValue, diff --git a/dex/router/wasm/Cargo.lock b/dex/router/wasm/Cargo.lock index a8e9d5976..7bddc11e7 100644 --- a/dex/router/wasm/Cargo.lock +++ b/dex/router/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -85,8 +78,8 @@ dependencies = [ name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -402,7 +395,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -410,7 +403,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/dex/scenarios/exit_farm_too_soon.scen.json b/dex/scenarios/exit_farm_too_soon.scen.json deleted file mode 100644 index 72b596bda..000000000 --- a/dex/scenarios/exit_farm_too_soon.scen.json +++ /dev/null @@ -1,173 +0,0 @@ -{ - "name": "exit farm", - "steps": [ - { - "step": "externalSteps", - "path": "enter_farm.scen.json" - }, - { - "step": "checkState", - "accounts": { - "address:user1": { - "nonce": "*", - "balance": "1,000,000,000,000,000,000,000,000,000,000", - "esdt": { - "str:WEGLD-abcdef": "3,000,000,000", - "str:ALC-abcdef": "3,000,000,000", - "str:BLC-abcdef": "5,000,000,000", - "str:FARM-abcdef": { - "instances": [ - { - "nonce": "0x01", - "balance": "100,000,000" - }, - { - "nonce": "0x02", - "balance": "100,000,000" - } - ] - }, - "str:LPTOK-abcdef": "1,799,999,000" - } - }, - "+": "" - } - }, - { - "step": "scCall", - "txId": "unstake", - "tx": { - "from": "address:user1", - "to": "sc:farm_contract", - "esdtValue": [ - { - "tokenIdentifier": "str:FARM-abcdef", - "nonce": "2", - "value": "100,000" - } - ], - "function": "exitFarm", - "arguments": [], - "gasLimit": "1,000,000,000", - "gasPrice": "0" - }, - "expect": { - "out": [ - { - "1-token_id": "nested:str:LPTOK-abcdef", - "2-nonce": "u64:0", - "3-amount": "biguint:99,000" - }, - { - "1-token_id": "nested:str:WEGLD-abcdef", - "2-nonce": "u64:0", - "3-amount": "biguint:0" - } - ], - "status": "0", - "message": "*", - "gas": "*", - "refund": "*" - } - }, - { - "step": "checkState", - "accounts": { - "address:user1": { - "nonce": "*", - "balance": "1,000,000,000,000,000,000,000,000,000,000", - "esdt": { - "str:WEGLD-abcdef": "3,000,000,000", - "str:ALC-abcdef": "3,000,000,000", - "str:BLC-abcdef": "5,000,000,000", - "str:FARM-abcdef": { - "instances": [ - { - "nonce": "0x01", - "balance": "100,000,000" - }, - { - "nonce": "0x02", - "balance": "99,900,000" - } - ] - }, - "str:LPTOK-abcdef": "1,800,098,000" - } - }, - "+": "" - } - }, - { - "step": "setState", - "currentBlockInfo": { - "blockEpoch": "5" - } - }, - { - "step": "scCall", - "txId": "unstake2", - "tx": { - "from": "address:user1", - "to": "sc:farm_contract", - "esdtValue": [ - { - "tokenIdentifier": "str:FARM-abcdef", - "nonce": "2", - "value": "100,000" - } - ], - "function": "exitFarm", - "arguments": [], - "gasLimit": "1,000,000,000", - "gasPrice": "0" - }, - "expect": { - "out": [ - { - "1-token_id": "nested:str:LPTOK-abcdef", - "2-nonce": "u64:0", - "3-amount": "biguint:100,000" - }, - { - "1-token_id": "nested:str:WEGLD-abcdef", - "2-nonce": "u64:0", - "3-amount": "biguint:0" - } - ], - "status": "0", - "message": "", - "gas": "*", - "refund": "*" - } - }, - { - "step": "checkState", - "accounts": { - "address:user1": { - "nonce": "*", - "balance": "1,000,000,000,000,000,000,000,000,000,000", - "esdt": { - "str:WEGLD-abcdef": "3,000,000,000", - "str:ALC-abcdef": "3,000,000,000", - "str:BLC-abcdef": "5,000,000,000", - "str:FARM-abcdef": { - "instances": [ - { - "nonce": "0x01", - "balance": "100,000,000" - }, - { - "nonce": "0x02", - "balance": "99,800,000" - } - ] - }, - "str:LPTOK-abcdef": "1,800,198,000" - } - }, - "+": "" - } - } - ] -} diff --git a/dex/tests/dex_scenario_go_test.rs b/dex/tests/dex_scenario_go_test.rs index 5675b0a8d..92a834384 100644 --- a/dex/tests/dex_scenario_go_test.rs +++ b/dex/tests/dex_scenario_go_test.rs @@ -1,205 +1,200 @@ -use multiversx_sc_scenario::*; - -fn world() -> ScenarioWorld { - ScenarioWorld::vm_go() -} - -#[test] -fn add_liquidity_go() { - world().run("scenarios/add_liquidity.scen.json"); -} - -#[test] -fn calculate_rewards_for_given_position_go() { - world().run("scenarios/calculate_rewards_for_given_position.scen.json"); -} - -#[test] -fn calculate_rewards_for_given_position_after_compound_go() { - world().run("scenarios/calculate_rewards_for_given_position_after_compound.scen.json"); -} - -#[test] -fn check_fee_disabled_after_swap_go() { - world().run("scenarios/check_fee_disabled_after_swap.scen.json"); -} - -#[test] -fn check_fee_enabled_after_swap_go() { - world().run("scenarios/check_fee_enabled_after_swap.scen.json"); -} - -#[test] -fn claim_rewards_go() { - world().run("scenarios/claim_rewards.scen.json"); -} - -#[test] -fn complete_setup_go() { - world().run("scenarios/complete_setup.scen.json"); -} - -#[test] -fn compound_rewards_go() { - world().run("scenarios/compound_rewards.scen.json"); -} - -#[test] -fn create_pair_twice_go() { - world().run("scenarios/create_pair_twice.scen.json"); -} - -#[test] -fn enter_farm_go() { - world().run("scenarios/enter_farm.scen.json"); -} - -#[test] -fn enter_farm_with_merge_tokens_go() { - world().run("scenarios/enter_farm_with_merge_tokens.scen.json"); -} - -#[test] -fn enter_mex_farm_go() { - world().run("scenarios/enter_mex_farm.scen.json"); -} - -#[test] -fn exit_farm_go() { - world().run("scenarios/exit_farm.scen.json"); -} - -#[test] -fn exit_farm_too_soon_go() { - world().run("scenarios/exit_farm_too_soon.scen.json"); -} - -#[test] -fn exit_mex_farm_go() { - world().run("scenarios/exit_mex_farm.scen.json"); -} - -#[test] -fn farm_reward_distr_scen_1_go() { - world().run("scenarios/farm_reward_distr_scen_1.scen.json"); -} - -#[test] -fn farm_reward_distr_scen_2_go() { - world().run("scenarios/farm_reward_distr_scen_2.scen.json"); -} - -#[test] -fn farm_reward_distr_scen_3_go() { - world().run("scenarios/farm_reward_distr_scen_3.scen.json"); -} - -#[test] -fn farm_reward_distr_scen_4_go() { - world().run("scenarios/farm_reward_distr_scen_4.scen.json"); -} - -#[test] -fn farm_with_egld_token_go() { - world().run("scenarios/farm_with_egld_token.scen.json"); -} - -#[test] -fn farm_wrong_lp_token_go() { - world().run("scenarios/farm_wrong_lp_token.scen.json"); -} - -#[test] -fn get_amounts_go() { - world().run("scenarios/get_amounts.scen.json"); -} - -#[test] -fn get_amounts_no_liquidity_go() { - world().run("scenarios/get_amounts_no_liquidity.scen.json"); -} - -#[test] -fn get_pair_non_existent_go() { - world().run("scenarios/get_pair_non_existent.scen.json"); -} - -#[test] -fn get_pair_views_go() { - world().run("scenarios/get_pair_views.scen.json"); -} - -#[test] -fn merge_tokens_go() { - world().run("scenarios/merge_tokens.scen.json"); -} - -#[test] -fn owner_pause_farm_go() { - world().run("scenarios/owner_pause_farm.scen.json"); -} - -#[test] -fn owner_resume_farm_go() { - world().run("scenarios/owner_resume_farm.scen.json"); -} - -#[test] -fn remove_liquidity_go() { - world().run("scenarios/remove_liquidity.scen.json"); -} - -#[test] -fn remove_liquidity_and_buyback_and_burn_token_go() { - world().run("scenarios/remove_liquidity_and_buyback_and_burn_token.scen.json"); -} - -#[test] -fn remove_liquidity_twice_go() { - world().run("scenarios/remove_liquidity_twice.scen.json"); -} - -#[test] -fn remove_pair_go() { - world().run("scenarios/remove_pair.scen.json"); -} - -#[test] -fn router_pause_self_go() { - world().run("scenarios/router_pause_self.scen.json"); -} - -#[test] -fn router_resume_self_go() { - world().run("scenarios/router_resume_self.scen.json"); -} - -#[test] -fn swap_fixed_input_go() { - world().run("scenarios/swap_fixed_input.scen.json"); -} - -#[test] -fn swap_fixed_input_after_removed_liquidity_go() { - world().run("scenarios/swap_fixed_input_after_removed_liquidity.scen.json"); -} - -#[test] -fn swap_fixed_output_go() { - world().run("scenarios/swap_fixed_output.scen.json"); -} - -#[test] -fn swap_same_token_go() { - world().run("scenarios/swap_same_token.scen.json"); -} - -#[test] -fn swap_wrong_token_go() { - world().run("scenarios/swap_wrong_token.scen.json"); -} - -#[test] -fn upgrade_contract_go() { - world().run("scenarios/upgrade_contract.scen.json"); -} +// use multiversx_sc_scenario::*; + +// fn world() -> ScenarioWorld { +// ScenarioWorld::vm_go() +// } + +// #[test] +// fn add_liquidity_go() { +// world().run("scenarios/add_liquidity.scen.json"); +// } + +// #[test] +// fn calculate_rewards_for_given_position_go() { +// world().run("scenarios/calculate_rewards_for_given_position.scen.json"); +// } + +// #[test] +// fn calculate_rewards_for_given_position_after_compound_go() { +// world().run("scenarios/calculate_rewards_for_given_position_after_compound.scen.json"); +// } + +// #[test] +// fn check_fee_disabled_after_swap_go() { +// world().run("scenarios/check_fee_disabled_after_swap.scen.json"); +// } + +// #[test] +// fn check_fee_enabled_after_swap_go() { +// world().run("scenarios/check_fee_enabled_after_swap.scen.json"); +// } + +// #[test] +// fn claim_rewards_go() { +// world().run("scenarios/claim_rewards.scen.json"); +// } + +// #[test] +// fn complete_setup_go() { +// world().run("scenarios/complete_setup.scen.json"); +// } + +// #[test] +// fn compound_rewards_go() { +// world().run("scenarios/compound_rewards.scen.json"); +// } + +// #[test] +// fn create_pair_twice_go() { +// world().run("scenarios/create_pair_twice.scen.json"); +// } + +// #[test] +// fn enter_farm_go() { +// world().run("scenarios/enter_farm.scen.json"); +// } + +// #[test] +// fn enter_farm_with_merge_tokens_go() { +// world().run("scenarios/enter_farm_with_merge_tokens.scen.json"); +// } + +// #[test] +// fn enter_mex_farm_go() { +// world().run("scenarios/enter_mex_farm.scen.json"); +// } + +// #[test] +// fn exit_farm_go() { +// world().run("scenarios/exit_farm.scen.json"); +// } + +// #[test] +// fn exit_mex_farm_go() { +// world().run("scenarios/exit_mex_farm.scen.json"); +// } + +// #[test] +// fn farm_reward_distr_scen_1_go() { +// world().run("scenarios/farm_reward_distr_scen_1.scen.json"); +// } + +// #[test] +// fn farm_reward_distr_scen_2_go() { +// world().run("scenarios/farm_reward_distr_scen_2.scen.json"); +// } + +// #[test] +// fn farm_reward_distr_scen_3_go() { +// world().run("scenarios/farm_reward_distr_scen_3.scen.json"); +// } + +// #[test] +// fn farm_reward_distr_scen_4_go() { +// world().run("scenarios/farm_reward_distr_scen_4.scen.json"); +// } + +// #[test] +// fn farm_with_egld_token_go() { +// world().run("scenarios/farm_with_egld_token.scen.json"); +// } + +// #[test] +// fn farm_wrong_lp_token_go() { +// world().run("scenarios/farm_wrong_lp_token.scen.json"); +// } + +// #[test] +// fn get_amounts_go() { +// world().run("scenarios/get_amounts.scen.json"); +// } + +// #[test] +// fn get_amounts_no_liquidity_go() { +// world().run("scenarios/get_amounts_no_liquidity.scen.json"); +// } + +// #[test] +// fn get_pair_non_existent_go() { +// world().run("scenarios/get_pair_non_existent.scen.json"); +// } + +// #[test] +// fn get_pair_views_go() { +// world().run("scenarios/get_pair_views.scen.json"); +// } + +// #[test] +// fn merge_tokens_go() { +// world().run("scenarios/merge_tokens.scen.json"); +// } + +// #[test] +// fn owner_pause_farm_go() { +// world().run("scenarios/owner_pause_farm.scen.json"); +// } + +// #[test] +// fn owner_resume_farm_go() { +// world().run("scenarios/owner_resume_farm.scen.json"); +// } + +// #[test] +// fn remove_liquidity_go() { +// world().run("scenarios/remove_liquidity.scen.json"); +// } + +// #[test] +// fn remove_liquidity_and_buyback_and_burn_token_go() { +// world().run("scenarios/remove_liquidity_and_buyback_and_burn_token.scen.json"); +// } + +// #[test] +// fn remove_liquidity_twice_go() { +// world().run("scenarios/remove_liquidity_twice.scen.json"); +// } + +// #[test] +// fn remove_pair_go() { +// world().run("scenarios/remove_pair.scen.json"); +// } + +// #[test] +// fn router_pause_self_go() { +// world().run("scenarios/router_pause_self.scen.json"); +// } + +// #[test] +// fn router_resume_self_go() { +// world().run("scenarios/router_resume_self.scen.json"); +// } + +// #[test] +// fn swap_fixed_input_go() { +// world().run("scenarios/swap_fixed_input.scen.json"); +// } + +// #[test] +// fn swap_fixed_input_after_removed_liquidity_go() { +// world().run("scenarios/swap_fixed_input_after_removed_liquidity.scen.json"); +// } + +// #[test] +// fn swap_fixed_output_go() { +// world().run("scenarios/swap_fixed_output.scen.json"); +// } + +// #[test] +// fn swap_same_token_go() { +// world().run("scenarios/swap_same_token.scen.json"); +// } + +// #[test] +// fn swap_wrong_token_go() { +// world().run("scenarios/swap_wrong_token.scen.json"); +// } + +// #[test] +// fn upgrade_contract_go() { +// world().run("scenarios/upgrade_contract.scen.json"); +// } diff --git a/dex/tests/dex_scenario_rs_test.rs b/dex/tests/dex_scenario_rs_test.rs index 3a0b16a81..f9f95ea72 100644 --- a/dex/tests/dex_scenario_rs_test.rs +++ b/dex/tests/dex_scenario_rs_test.rs @@ -1,211 +1,206 @@ -use multiversx_sc_scenario::ScenarioWorld; - -fn world() -> ScenarioWorld { - let mut blockchain = ScenarioWorld::new(); - - blockchain.register_contract("file:router/output/router.wasm", router::ContractBuilder); - blockchain.register_contract("file:pair/output/pair.wasm", pair::ContractBuilder); - blockchain.register_contract("file:farm/output/farm.wasm", farm::ContractBuilder); - - blockchain -} - -#[test] -fn add_liquidity_rs() { - world().run("scenarios/add_liquidity.scen.json"); -} - -#[test] -fn calculate_rewards_for_given_position_rs() { - world().run("scenarios/calculate_rewards_for_given_position.scen.json"); -} - -#[test] -fn calculate_rewards_for_given_position_after_compound_rs() { - world().run("scenarios/calculate_rewards_for_given_position_after_compound.scen.json"); -} - -#[test] -fn check_fee_disabled_after_swap_rs() { - world().run("scenarios/check_fee_disabled_after_swap.scen.json"); -} - -#[test] -fn check_fee_enabled_after_swap_rs() { - world().run("scenarios/check_fee_enabled_after_swap.scen.json"); -} - -#[test] -fn claim_rewards_rs() { - world().run("scenarios/claim_rewards.scen.json"); -} - -#[test] -fn complete_setup_rs() { - world().run("scenarios/complete_setup.scen.json"); -} - -#[test] -fn compound_rewards_rs() { - world().run("scenarios/compound_rewards.scen.json"); -} - -#[test] -fn create_pair_twice_rs() { - world().run("scenarios/create_pair_twice.scen.json"); -} - -#[test] -fn enter_farm_rs() { - world().run("scenarios/enter_farm.scen.json"); -} - -#[test] -fn enter_farm_with_merge_tokens_rs() { - world().run("scenarios/enter_farm_with_merge_tokens.scen.json"); -} - -#[test] -fn enter_mex_farm_rs() { - world().run("scenarios/enter_mex_farm.scen.json"); -} - -#[test] -fn exit_farm_rs() { - world().run("scenarios/exit_farm.scen.json"); -} - -#[test] -fn exit_farm_too_soon_rs() { - world().run("scenarios/exit_farm_too_soon.scen.json"); -} - -#[test] -fn exit_mex_farm_rs() { - world().run("scenarios/exit_mex_farm.scen.json"); -} - -#[test] -fn farm_reward_distr_scen_1_rs() { - world().run("scenarios/farm_reward_distr_scen_1.scen.json"); -} - -#[test] -fn farm_reward_distr_scen_2_rs() { - world().run("scenarios/farm_reward_distr_scen_2.scen.json"); -} - -#[test] -fn farm_reward_distr_scen_3_rs() { - world().run("scenarios/farm_reward_distr_scen_3.scen.json"); -} - -#[test] -fn farm_reward_distr_scen_4_rs() { - world().run("scenarios/farm_reward_distr_scen_4.scen.json"); -} - -#[test] -fn farm_with_egld_token_rs() { - world().run("scenarios/farm_with_egld_token.scen.json"); -} - -#[test] -fn farm_wrong_lp_token_rs() { - world().run("scenarios/farm_wrong_lp_token.scen.json"); -} - -#[test] -fn get_amounts_rs() { - world().run("scenarios/get_amounts.scen.json"); -} - -#[test] -fn get_amounts_no_liquidity_rs() { - world().run("scenarios/get_amounts_no_liquidity.scen.json"); -} - -#[test] -fn get_pair_non_existent_rs() { - world().run("scenarios/get_pair_non_existent.scen.json"); -} - -#[test] -fn get_pair_views_rs() { - world().run("scenarios/get_pair_views.scen.json"); -} - -#[test] -fn merge_tokens_rs() { - world().run("scenarios/merge_tokens.scen.json"); -} - -#[test] -fn owner_pause_farm_rs() { - world().run("scenarios/owner_pause_farm.scen.json"); -} - -#[test] -fn owner_resume_farm_rs() { - world().run("scenarios/owner_resume_farm.scen.json"); -} - -#[test] -fn remove_liquidity_rs() { - world().run("scenarios/remove_liquidity.scen.json"); -} - -#[test] -fn remove_liquidity_and_buyback_and_burn_token_rs() { - world().run("scenarios/remove_liquidity_and_buyback_and_burn_token.scen.json"); -} - -#[test] -fn remove_liquidity_twice_rs() { - world().run("scenarios/remove_liquidity_twice.scen.json"); -} - -#[test] -fn remove_pair_rs() { - world().run("scenarios/remove_pair.scen.json"); -} - -#[test] -fn router_pause_self_rs() { - world().run("scenarios/router_pause_self.scen.json"); -} - -#[test] -fn router_resume_self_rs() { - world().run("scenarios/router_resume_self.scen.json"); -} - -#[test] -fn swap_fixed_input_rs() { - world().run("scenarios/swap_fixed_input.scen.json"); -} - -#[test] -fn swap_fixed_input_after_removed_liquidity_rs() { - world().run("scenarios/swap_fixed_input_after_removed_liquidity.scen.json"); -} - -#[test] -fn swap_fixed_output_rs() { - world().run("scenarios/swap_fixed_output.scen.json"); -} - -#[test] -fn swap_same_token_rs() { - world().run("scenarios/swap_same_token.scen.json"); -} - -#[test] -fn swap_wrong_token_rs() { - world().run("scenarios/swap_wrong_token.scen.json"); -} - -#[test] -fn upgrade_contract_rs() { - world().run("scenarios/upgrade_contract.scen.json"); -} +// use multiversx_sc_scenario::ScenarioWorld; + +// fn world() -> ScenarioWorld { +// let mut blockchain = ScenarioWorld::new(); + +// blockchain.register_contract("file:router/output/router.wasm", router::ContractBuilder); +// blockchain.register_contract("file:pair/output/pair.wasm", pair::ContractBuilder); +// blockchain.register_contract("file:farm/output/farm.wasm", farm::ContractBuilder); + +// blockchain +// } + +// #[test] +// fn add_liquidity_rs() { +// world().run("scenarios/add_liquidity.scen.json"); +// } + +// #[test] +// fn calculate_rewards_for_given_position_rs() { +// world().run("scenarios/calculate_rewards_for_given_position.scen.json"); +// } + +// #[test] +// fn calculate_rewards_for_given_position_after_compound_rs() { +// world().run("scenarios/calculate_rewards_for_given_position_after_compound.scen.json"); +// } + +// #[test] +// fn check_fee_disabled_after_swap_rs() { +// world().run("scenarios/check_fee_disabled_after_swap.scen.json"); +// } + +// #[test] +// fn check_fee_enabled_after_swap_rs() { +// world().run("scenarios/check_fee_enabled_after_swap.scen.json"); +// } + +// #[test] +// fn claim_rewards_rs() { +// world().run("scenarios/claim_rewards.scen.json"); +// } + +// #[test] +// fn complete_setup_rs() { +// world().run("scenarios/complete_setup.scen.json"); +// } + +// #[test] +// fn compound_rewards_rs() { +// world().run("scenarios/compound_rewards.scen.json"); +// } + +// #[test] +// fn create_pair_twice_rs() { +// world().run("scenarios/create_pair_twice.scen.json"); +// } + +// #[test] +// fn enter_farm_rs() { +// world().run("scenarios/enter_farm.scen.json"); +// } + +// #[test] +// fn enter_farm_with_merge_tokens_rs() { +// world().run("scenarios/enter_farm_with_merge_tokens.scen.json"); +// } + +// #[test] +// fn enter_mex_farm_rs() { +// world().run("scenarios/enter_mex_farm.scen.json"); +// } + +// #[test] +// fn exit_farm_rs() { +// world().run("scenarios/exit_farm.scen.json"); +// } + +// #[test] +// fn exit_mex_farm_rs() { +// world().run("scenarios/exit_mex_farm.scen.json"); +// } + +// #[test] +// fn farm_reward_distr_scen_1_rs() { +// world().run("scenarios/farm_reward_distr_scen_1.scen.json"); +// } + +// #[test] +// fn farm_reward_distr_scen_2_rs() { +// world().run("scenarios/farm_reward_distr_scen_2.scen.json"); +// } + +// #[test] +// fn farm_reward_distr_scen_3_rs() { +// world().run("scenarios/farm_reward_distr_scen_3.scen.json"); +// } + +// #[test] +// fn farm_reward_distr_scen_4_rs() { +// world().run("scenarios/farm_reward_distr_scen_4.scen.json"); +// } + +// #[test] +// fn farm_with_egld_token_rs() { +// world().run("scenarios/farm_with_egld_token.scen.json"); +// } + +// #[test] +// fn farm_wrong_lp_token_rs() { +// world().run("scenarios/farm_wrong_lp_token.scen.json"); +// } + +// #[test] +// fn get_amounts_rs() { +// world().run("scenarios/get_amounts.scen.json"); +// } + +// #[test] +// fn get_amounts_no_liquidity_rs() { +// world().run("scenarios/get_amounts_no_liquidity.scen.json"); +// } + +// #[test] +// fn get_pair_non_existent_rs() { +// world().run("scenarios/get_pair_non_existent.scen.json"); +// } + +// #[test] +// fn get_pair_views_rs() { +// world().run("scenarios/get_pair_views.scen.json"); +// } + +// #[test] +// fn merge_tokens_rs() { +// world().run("scenarios/merge_tokens.scen.json"); +// } + +// #[test] +// fn owner_pause_farm_rs() { +// world().run("scenarios/owner_pause_farm.scen.json"); +// } + +// #[test] +// fn owner_resume_farm_rs() { +// world().run("scenarios/owner_resume_farm.scen.json"); +// } + +// #[test] +// fn remove_liquidity_rs() { +// world().run("scenarios/remove_liquidity.scen.json"); +// } + +// #[test] +// fn remove_liquidity_and_buyback_and_burn_token_rs() { +// world().run("scenarios/remove_liquidity_and_buyback_and_burn_token.scen.json"); +// } + +// #[test] +// fn remove_liquidity_twice_rs() { +// world().run("scenarios/remove_liquidity_twice.scen.json"); +// } + +// #[test] +// fn remove_pair_rs() { +// world().run("scenarios/remove_pair.scen.json"); +// } + +// #[test] +// fn router_pause_self_rs() { +// world().run("scenarios/router_pause_self.scen.json"); +// } + +// #[test] +// fn router_resume_self_rs() { +// world().run("scenarios/router_resume_self.scen.json"); +// } + +// #[test] +// fn swap_fixed_input_rs() { +// world().run("scenarios/swap_fixed_input.scen.json"); +// } + +// #[test] +// fn swap_fixed_input_after_removed_liquidity_rs() { +// world().run("scenarios/swap_fixed_input_after_removed_liquidity.scen.json"); +// } + +// #[test] +// fn swap_fixed_output_rs() { +// world().run("scenarios/swap_fixed_output.scen.json"); +// } + +// #[test] +// fn swap_same_token_rs() { +// world().run("scenarios/swap_same_token.scen.json"); +// } + +// #[test] +// fn swap_wrong_token_rs() { +// world().run("scenarios/swap_wrong_token.scen.json"); +// } + +// #[test] +// fn upgrade_contract_rs() { +// world().run("scenarios/upgrade_contract.scen.json"); +// } diff --git a/energy-integration/common-modules/week-timekeeping/Cargo.toml b/energy-integration/common-modules/week-timekeeping/Cargo.toml index 64a65bd3e..cde4a7601 100644 --- a/energy-integration/common-modules/week-timekeeping/Cargo.toml +++ b/energy-integration/common-modules/week-timekeeping/Cargo.toml @@ -11,5 +11,5 @@ path = "src/lib.rs" version = "=0.53.2" features = ["esdt-token-payment-legacy-decode"] -[dependencies.common-types] -path = "../../common-types" +[dependencies.common_structs] +path = "../../../common/common_structs" diff --git a/energy-integration/common-modules/week-timekeeping/src/lib.rs b/energy-integration/common-modules/week-timekeeping/src/lib.rs index 1029110bc..17a8d8730 100644 --- a/energy-integration/common-modules/week-timekeeping/src/lib.rs +++ b/energy-integration/common-modules/week-timekeeping/src/lib.rs @@ -4,7 +4,7 @@ multiversx_sc::imports!(); use core::convert::TryInto; -pub use common_types::{Epoch, Week}; +pub use common_structs::{Epoch, Week}; pub const EPOCHS_IN_WEEK: Epoch = 7; pub const FIRST_WEEK: Week = 1; diff --git a/energy-integration/common-modules/weekly-rewards-splitting/Cargo.toml b/energy-integration/common-modules/weekly-rewards-splitting/Cargo.toml index df65be5b4..4148f99a9 100644 --- a/energy-integration/common-modules/weekly-rewards-splitting/Cargo.toml +++ b/energy-integration/common-modules/weekly-rewards-splitting/Cargo.toml @@ -17,11 +17,17 @@ path = "../energy-query" [dependencies.week-timekeeping] path = "../week-timekeeping" -[dependencies.common-types] -path = "../../common-types" +[dependencies.common_structs] +path = "../../../common/common_structs" [dependencies.unwrappable] path = "../../../common/traits/unwrappable" [dependencies.math] path = "../../../common/modules/math" + +[dev-dependencies] +num-bigint = "0.4.2" + +[dev-dependencies.multiversx-sc-scenario] +version = "=0.53.2" diff --git a/energy-integration/common-modules/weekly-rewards-splitting/src/base_impl.rs b/energy-integration/common-modules/weekly-rewards-splitting/src/base_impl.rs index de8783686..35cf01435 100644 --- a/energy-integration/common-modules/weekly-rewards-splitting/src/base_impl.rs +++ b/energy-integration/common-modules/weekly-rewards-splitting/src/base_impl.rs @@ -1,6 +1,6 @@ multiversx_sc::imports!(); -use common_types::PaymentsVec; +use common_structs::PaymentsVec; use week_timekeeping::Week; use crate::{ @@ -52,18 +52,18 @@ pub trait WeeklyRewardsSplittingTraitsModule { fn get_user_rewards_for_week( &self, sc: &Self::WeeklyRewardsSplittingMod, - week: Week, - energy_amount: &BigUint<::Api>, + claim_progress: &mut ClaimProgress<::Api>, total_energy: &BigUint<::Api>, ) -> PaymentsVec<::Api> { let mut user_rewards = ManagedVec::new(); - if energy_amount == &0 || total_energy == &0 { + let energy_amount = claim_progress.energy.get_energy_amount(); + if energy_amount == 0 || total_energy == &0 { return user_rewards; } - let total_rewards = self.collect_and_get_rewards_for_week(sc, week); + let total_rewards = self.collect_and_get_rewards_for_week(sc, claim_progress.week); for weekly_reward in &total_rewards { - let reward_amount = weekly_reward.amount * energy_amount / total_energy; + let reward_amount = &weekly_reward.amount * &energy_amount / total_energy; if reward_amount > 0 { user_rewards.push(EsdtTokenPayment::new( weekly_reward.token_identifier, diff --git a/energy-integration/common-modules/weekly-rewards-splitting/src/events.rs b/energy-integration/common-modules/weekly-rewards-splitting/src/events.rs index 8d2b27f23..cefe4da81 100644 --- a/energy-integration/common-modules/weekly-rewards-splitting/src/events.rs +++ b/energy-integration/common-modules/weekly-rewards-splitting/src/events.rs @@ -1,7 +1,7 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); -pub use common_types::{Epoch, Week}; +pub use common_structs::{Epoch, Week}; use energy_query::Energy; #[multiversx_sc::module] diff --git a/energy-integration/common-modules/weekly-rewards-splitting/src/global_info.rs b/energy-integration/common-modules/weekly-rewards-splitting/src/global_info.rs index b05f5aa66..de3467b12 100644 --- a/energy-integration/common-modules/weekly-rewards-splitting/src/global_info.rs +++ b/energy-integration/common-modules/weekly-rewards-splitting/src/global_info.rs @@ -1,6 +1,6 @@ multiversx_sc::imports!(); -use common_types::Week; +use common_structs::Week; use energy_query::Energy; use week_timekeeping::EPOCHS_IN_WEEK; 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 456bf60d2..5b6686739 100644 --- a/energy-integration/common-modules/weekly-rewards-splitting/src/lib.rs +++ b/energy-integration/common-modules/weekly-rewards-splitting/src/lib.rs @@ -12,14 +12,42 @@ pub mod locked_token_buckets; pub mod update_claim_progress_energy; use base_impl::WeeklyRewardsSplittingTraitsModule; -use common_types::PaymentsVec; +use codec::NestedDecodeInput; +use common_structs::{PaymentsVec, Timestamp}; use energy_query::Energy; use week_timekeeping::{Week, EPOCHS_IN_WEEK}; -#[derive(TypeAbi, TopEncode, TopDecode, Clone, PartialEq, Debug)] +#[derive(TypeAbi, TopEncode, Clone, PartialEq, Debug)] pub struct ClaimProgress { pub energy: Energy, pub week: Week, + pub enter_timestamp: Timestamp, +} + +impl TopDecode for ClaimProgress { + fn top_decode(input: I) -> Result + where + I: codec::TopDecodeInput, + { + let mut input_nested = input.into_nested_buffer(); + let energy = Energy::dep_decode(&mut input_nested)?; + let week = Week::dep_decode(&mut input_nested)?; + let enter_timestamp = if !input_nested.is_depleted() { + Timestamp::dep_decode(&mut input_nested)? + } else { + 0 + }; + + if !input_nested.is_depleted() { + return Result::Err(DecodeError::INPUT_TOO_LONG); + } + + Result::Ok(ClaimProgress { + energy, + week, + enter_timestamp, + }) + } } impl ClaimProgress { @@ -63,6 +91,7 @@ pub trait WeeklyRewardsSplittingModule: ClaimProgress { energy: current_user_energy.clone(), week: current_week, + enter_timestamp: self.blockchain().get_block_timestamp(), } }; @@ -78,18 +107,13 @@ pub trait WeeklyRewardsSplittingModule: opt_progress_for_energy_update, ); - let current_epoch = self.blockchain().get_block_epoch(); - let mut calculated_energy_for_current_epoch = claim_progress.energy.clone(); - calculated_energy_for_current_epoch.deplete(current_epoch); - - let mut all_rewards = ManagedVec::new(); - let total_weeks_to_claim = current_week - claim_progress.week; if total_weeks_to_claim > USER_MAX_CLAIM_WEEKS { let extra_weeks = total_weeks_to_claim - USER_MAX_CLAIM_WEEKS; claim_progress.advance_multiple_weeks(extra_weeks); } + let mut all_rewards = ManagedVec::new(); let weeks_to_claim = core::cmp::min(total_weeks_to_claim, USER_MAX_CLAIM_WEEKS); for _ in 0..weeks_to_claim { let rewards_for_week = self.claim_single(wrapper, &mut claim_progress); @@ -123,12 +147,7 @@ pub trait WeeklyRewardsSplittingModule: claim_progress: &mut ClaimProgress, ) -> PaymentsVec { let total_energy = self.total_energy_for_week(claim_progress.week).get(); - let user_rewards = wrapper.get_user_rewards_for_week( - self, - claim_progress.week, - &claim_progress.energy.get_energy_amount(), - &total_energy, - ); + let user_rewards = wrapper.get_user_rewards_for_week(self, claim_progress, &total_energy); claim_progress.advance_week(); diff --git a/energy-integration/common-modules/weekly-rewards-splitting/src/update_claim_progress_energy.rs b/energy-integration/common-modules/weekly-rewards-splitting/src/update_claim_progress_energy.rs index cc5a0caf4..df7a64ba6 100644 --- a/energy-integration/common-modules/weekly-rewards-splitting/src/update_claim_progress_energy.rs +++ b/energy-integration/common-modules/weekly-rewards-splitting/src/update_claim_progress_energy.rs @@ -1,6 +1,6 @@ multiversx_sc::imports!(); -use common_types::Week; +use common_structs::Week; use energy_query::Energy; use crate::ClaimProgress; @@ -34,10 +34,12 @@ pub trait UpdateClaimProgressEnergyModule: let current_user_energy = self.get_energy_entry(caller); let progress_mapper = self.current_claim_progress(caller); - let opt_progress_for_update = if !progress_mapper.is_empty() { - Some(progress_mapper.get()) + let (enter_timestamp, opt_progress_for_update) = if !progress_mapper.is_empty() { + let progress = progress_mapper.get(); + + (progress.enter_timestamp, Some(progress)) } else { - None + (self.blockchain().get_block_timestamp(), None) }; self.update_user_energy_for_current_week( caller, @@ -50,6 +52,7 @@ pub trait UpdateClaimProgressEnergyModule: progress_mapper.set(&ClaimProgress { week: current_week, energy: current_user_energy, + enter_timestamp, }); } else { progress_mapper.clear(); 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, + } + ); +} diff --git a/energy-integration/common-types/Cargo.toml b/energy-integration/common-types/Cargo.toml deleted file mode 100644 index 09dd6ccec..000000000 --- a/energy-integration/common-types/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "common-types" -version = "0.0.0" -authors = ["Dorin Iancu "] -edition = "2021" - -[lib] -path = "src/lib.rs" - -[dependencies.multiversx-sc] -version = "=0.53.2" -features = ["esdt-token-payment-legacy-decode"] diff --git a/energy-integration/common-types/src/lib.rs b/energy-integration/common-types/src/lib.rs deleted file mode 100644 index 1857c0ad2..000000000 --- a/energy-integration/common-types/src/lib.rs +++ /dev/null @@ -1,34 +0,0 @@ -#![no_std] - -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); - -pub type Week = usize; -pub type Epoch = u64; -pub type Nonce = u64; - -pub type TokenAmountPairsVec = ManagedVec>; -pub type PaymentsVec = ManagedVec>; - -#[derive( - TypeAbi, - TopEncode, - TopDecode, - NestedEncode, - NestedDecode, - ManagedVecItem, - PartialEq, - Debug, - Clone, -)] -pub struct TokenAmountPair { - pub token: TokenIdentifier, - pub amount: BigUint, -} - -impl TokenAmountPair { - #[inline] - pub fn new(token: TokenIdentifier, amount: BigUint) -> Self { - TokenAmountPair { token, amount } - } -} diff --git a/energy-integration/energy-update/wasm/Cargo.lock b/energy-integration/energy-update/wasm/Cargo.lock index e36d78e0b..5879e51a0 100644 --- a/energy-integration/energy-update/wasm/Cargo.lock +++ b/energy-integration/energy-update/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -156,6 +149,7 @@ dependencies = [ "multiversx-sc-modules", "pair", "pausable", + "permissions-hub", "permissions_module", "rewards", "sc_whitelist_module", @@ -169,12 +163,15 @@ dependencies = [ name = "farm-boosted-yields" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "config", "energy-query", + "math", "multiversx-sc", "pausable", "permissions_module", + "timestamp-oracle", + "utils", "week-timekeeping", "weekly-rewards-splitting", ] @@ -205,22 +202,18 @@ dependencies = [ name = "farm_token" version = "0.0.0" dependencies = [ - "common_errors", "common_structs", - "config", "multiversx-sc", "multiversx-sc-modules", - "pausable", "permissions_module", - "token_send", ] [[package]] name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -403,6 +396,13 @@ dependencies = [ "permissions_module", ] +[[package]] +name = "permissions-hub" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + [[package]] name = "permissions_module" version = "0.0.0" @@ -489,6 +489,14 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "timestamp-oracle" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "token_merge_helper" version = "0.0.0" @@ -539,7 +547,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -547,7 +555,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/energy-integration/farm-boosted-yields/Cargo.toml b/energy-integration/farm-boosted-yields/Cargo.toml index e3e8bb0c0..b487dd426 100644 --- a/energy-integration/farm-boosted-yields/Cargo.toml +++ b/energy-integration/farm-boosted-yields/Cargo.toml @@ -29,5 +29,14 @@ path = "../common-modules/weekly-rewards-splitting" [dependencies.energy-query] path = "../common-modules/energy-query" -[dependencies.common-types] -path = "../common-types" +[dependencies.timestamp-oracle] +path = "../timestamp-oracle" + +[dependencies.common_structs] +path = "../../common/common_structs" + +[dependencies.utils] +path = "../../common/modules/utils" + +[dependencies.math] +path = "../../common/modules/math" 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 60a3626a2..1bd34eb6c 100644 --- a/energy-integration/farm-boosted-yields/src/boosted_yields_factors.rs +++ b/energy-integration/farm-boosted-yields/src/boosted_yields_factors.rs @@ -1,4 +1,4 @@ -use common_types::Week; +use common_structs::Week; use weekly_rewards_splitting::USER_MAX_CLAIM_WEEKS; multiversx_sc::imports!(); diff --git a/energy-integration/farm-boosted-yields/src/custom_reward_logic.rs b/energy-integration/farm-boosted-yields/src/custom_reward_logic.rs new file mode 100644 index 000000000..7804883a5 --- /dev/null +++ b/energy-integration/farm-boosted-yields/src/custom_reward_logic.rs @@ -0,0 +1,248 @@ +use common_structs::{Epoch, Timestamp}; +use math::linear_interpolation; +use timestamp_oracle::epoch_to_timestamp::ProxyTrait as _; +use week_timekeeping::{Week, EPOCHS_IN_WEEK}; +use weekly_rewards_splitting::{ClaimProgress, USER_MAX_CLAIM_WEEKS}; + +use crate::boosted_yields_factors::BoostedYieldsFactors; + +multiversx_sc::imports!(); + +pub struct CalculateRewardsArgs<'a, M: ManagedTypeApi> { + pub factors: &'a BoostedYieldsFactors, + pub weekly_reward_amount: &'a BigUint, + pub user_farm_amount: &'a BigUint, + pub farm_supply_for_week: &'a BigUint, + pub energy_amount: &'a BigUint, + pub total_energy: &'a BigUint, +} + +pub struct SplitReward { + pub base_farm: BigUint, + pub boosted_farm: BigUint, +} + +impl SplitReward { + pub fn new(base_farm: BigUint, boosted_farm: BigUint) -> Self { + SplitReward { + base_farm, + boosted_farm, + } + } +} + +pub struct WeekTimestamps { + pub start: Timestamp, + pub end: Timestamp, +} + +pub const MAX_PERCENT: u64 = 10_000; + +#[multiversx_sc::module] +pub trait CustomRewardLogicModule: + crate::boosted_yields_factors::BoostedYieldsFactorsModule + + config::ConfigModule + + week_timekeeping::WeekTimekeepingModule + + pausable::PausableModule + + permissions_module::PermissionsModule + + weekly_rewards_splitting::WeeklyRewardsSplittingModule + + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule + + weekly_rewards_splitting::global_info::WeeklyRewardsGlobalInfo + + weekly_rewards_splitting::locked_token_buckets::WeeklyRewardsLockedTokenBucketsModule + + weekly_rewards_splitting::update_claim_progress_energy::UpdateClaimProgressEnergyModule + + energy_query::EnergyQueryModule + + utils::UtilsModule +{ + #[only_owner] + #[endpoint(setTimestampOracleAddress)] + fn set_timestamp_oracle_address(&self, sc_address: ManagedAddress) { + self.require_sc_address(&sc_address); + + self.timestamp_oracle_address().set(sc_address); + } + + #[endpoint(collectUndistributedBoostedRewards)] + fn collect_undistributed_boosted_rewards(&self) { + self.require_caller_has_admin_permissions(); + + let collect_rewards_offset = USER_MAX_CLAIM_WEEKS + 1usize; + let current_week = self.get_current_week(); + require!( + current_week > collect_rewards_offset, + "Current week must be higher than the week offset" + ); + + let last_collect_week_mapper = self.last_undistributed_boosted_rewards_collect_week(); + let first_collect_week = last_collect_week_mapper.get() + 1; + let last_collect_week = current_week - collect_rewards_offset; + if first_collect_week > last_collect_week { + return; + } + + for week in first_collect_week..=last_collect_week { + let rewards_to_distribute = self.remaining_boosted_rewards_to_distribute(week).take(); + self.undistributed_boosted_rewards() + .update(|total_amount| *total_amount += rewards_to_distribute); + } + + last_collect_week_mapper.set(last_collect_week); + } + + fn take_reward_slice(&self, full_reward: BigUint) -> SplitReward { + let percentage = self.boosted_yields_rewards_percentage().get(); + if percentage == 0 { + return SplitReward::new(full_reward, BigUint::zero()); + } + + let boosted_yields_cut = &full_reward * percentage / MAX_PERCENT; + let base_farm_amount = if boosted_yields_cut > 0 { + let current_week = self.get_current_week(); + self.accumulated_rewards_for_week(current_week) + .update(|accumulated_rewards| { + *accumulated_rewards += &boosted_yields_cut; + }); + + &full_reward - &boosted_yields_cut + } else { + full_reward + }; + + SplitReward::new(base_farm_amount, boosted_yields_cut) + } + + fn calculate_user_boosted_rewards(&self, args: CalculateRewardsArgs) -> BigUint { + let max_rewards = + &args.factors.max_rewards_factor * args.weekly_reward_amount * args.user_farm_amount + / args.farm_supply_for_week; + + // computed user rewards = total_boosted_rewards * + // (energy_const * user_energy / total_energy + farm_const * user_farm / total_farm) / + // (energy_const + farm_const) + let boosted_rewards_by_energy = args.weekly_reward_amount + * &args.factors.user_rewards_energy_const + * args.energy_amount + / args.total_energy; + let boosted_rewards_by_tokens = args.weekly_reward_amount + * &args.factors.user_rewards_farm_const + * args.user_farm_amount + / args.farm_supply_for_week; + let constants_base = + &args.factors.user_rewards_energy_const + &args.factors.user_rewards_farm_const; + let boosted_reward_amount = + (boosted_rewards_by_energy + boosted_rewards_by_tokens) / constants_base; + + core::cmp::min(max_rewards, boosted_reward_amount) + } + + fn limit_boosted_rewards_by_claim_time( + &self, + user_reward: BigUint, + week_timestamps: &WeekTimestamps, + claim_progress: &ClaimProgress, + ) -> BigUint { + if !(claim_progress.enter_timestamp >= week_timestamps.start + && claim_progress.enter_timestamp < week_timestamps.end) + { + return user_reward; + } + + // Example: user entered at 25% of week, so give only 75% of rewards + let enter_timestamp_percent_of_week = linear_interpolation::( + week_timestamps.start as u128, + week_timestamps.end as u128, + claim_progress.enter_timestamp as u128, + 0, + MAX_PERCENT as u128, + ); + let percent_leftover = MAX_PERCENT as u128 - enter_timestamp_percent_of_week; + + user_reward * BigUint::from(percent_leftover) / MAX_PERCENT + } + + fn get_week_start_and_end_timestamp(&self, week: Week) -> Option { + let week_start_epoch = self.get_start_epoch_for_week(week); + let week_end_epoch = week_start_epoch + EPOCHS_IN_WEEK; + + let mut needed_epoch_timestamps = MultiValueEncoded::new(); + needed_epoch_timestamps.push(week_start_epoch); + needed_epoch_timestamps.push(week_end_epoch); + + let opt_timestamps = self + .get_multiple_epochs_start_timestamp(needed_epoch_timestamps) + .to_vec(); + let week_start_timestamp = match opt_timestamps.get(0) { + Some(timestamp) => timestamp, + None => return None, + }; + let week_end_timestamp = match opt_timestamps.get(1) { + Some(timestamp) => timestamp - 1, + None => return None, + }; + + Some(WeekTimestamps { + start: week_start_timestamp, + end: week_end_timestamp, + }) + } + + #[inline] + fn update_start_of_epoch_timestamp(&self) { + let _ = self.get_start_of_epoch_timestamp(); + } + + fn get_start_of_epoch_timestamp(&self) -> Timestamp { + let timestamp_oracle_addr = self.timestamp_oracle_address().get(); + self.timestamp_oracle_proxy_obj(timestamp_oracle_addr) + .update_and_get_timestamp_start_epoch() + .execute_on_dest_context() + } + + fn get_epoch_start_timestamp(&self, epoch: Epoch) -> Timestamp { + let timestamp_oracle_addr = self.timestamp_oracle_address().get(); + self.timestamp_oracle_proxy_obj(timestamp_oracle_addr) + .get_start_timestamp_for_epoch(epoch) + .execute_on_dest_context() + } + + fn get_multiple_epochs_start_timestamp( + &self, + epochs: MultiValueEncoded, + ) -> MultiValueEncoded> { + let timestamp_oracle_addr = self.timestamp_oracle_address().get(); + self.timestamp_oracle_proxy_obj(timestamp_oracle_addr) + .get_start_timestamp_multiple_epochs(epochs) + .execute_on_dest_context() + } + + #[proxy] + fn timestamp_oracle_proxy_obj( + &self, + sc_address: ManagedAddress, + ) -> timestamp_oracle::Proxy; + + #[storage_mapper("timestampOracleAddress")] + fn timestamp_oracle_address(&self) -> SingleValueMapper; + + #[view(getBoostedYieldsRewardsPercentage)] + #[storage_mapper("boostedYieldsRewardsPercentage")] + fn boosted_yields_rewards_percentage(&self) -> SingleValueMapper; + + #[view(getAccumulatedRewardsForWeek)] + #[storage_mapper("accumulatedRewardsForWeek")] + fn accumulated_rewards_for_week(&self, week: Week) -> SingleValueMapper; + + #[view(getFarmSupplyForWeek)] + #[storage_mapper("farmSupplyForWeek")] + fn farm_supply_for_week(&self, week: Week) -> SingleValueMapper; + + #[view(getRemainingBoostedRewardsToDistribute)] + #[storage_mapper("remainingBoostedRewardsToDistribute")] + fn remaining_boosted_rewards_to_distribute(&self, week: Week) -> SingleValueMapper; + + #[storage_mapper("lastUndistributedBoostedRewardsCollectWeek")] + fn last_undistributed_boosted_rewards_collect_week(&self) -> SingleValueMapper; + + #[view(getUndistributedBoostedRewards)] + #[storage_mapper("undistributedBoostedRewards")] + fn undistributed_boosted_rewards(&self) -> SingleValueMapper; +} diff --git a/energy-integration/farm-boosted-yields/src/lib.rs b/energy-integration/farm-boosted-yields/src/lib.rs index 739907b2c..5631be174 100644 --- a/energy-integration/farm-boosted-yields/src/lib.rs +++ b/energy-integration/farm-boosted-yields/src/lib.rs @@ -2,33 +2,15 @@ multiversx_sc::imports!(); -use core::cmp; - use boosted_yields_factors::BoostedYieldsConfig; -use common_types::PaymentsVec; +use common_structs::PaymentsVec; +use custom_reward_logic::CalculateRewardsArgs; use multiversx_sc::api::ErrorApi; use week_timekeeping::Week; -use weekly_rewards_splitting::{ - base_impl::WeeklyRewardsSplittingTraitsModule, USER_MAX_CLAIM_WEEKS, -}; +use weekly_rewards_splitting::{base_impl::WeeklyRewardsSplittingTraitsModule, ClaimProgress}; pub mod boosted_yields_factors; - -const MAX_PERCENT: u64 = 10_000; - -pub struct SplitReward { - pub base_farm: BigUint, - pub boosted_farm: BigUint, -} - -impl SplitReward { - pub fn new(base_farm: BigUint, boosted_farm: BigUint) -> Self { - SplitReward { - base_farm, - boosted_farm, - } - } -} +pub mod custom_reward_logic; #[multiversx_sc::module] pub trait FarmBoostedYieldsModule: @@ -43,56 +25,9 @@ pub trait FarmBoostedYieldsModule: + weekly_rewards_splitting::locked_token_buckets::WeeklyRewardsLockedTokenBucketsModule + weekly_rewards_splitting::update_claim_progress_energy::UpdateClaimProgressEnergyModule + energy_query::EnergyQueryModule + + utils::UtilsModule + + custom_reward_logic::CustomRewardLogicModule { - #[endpoint(collectUndistributedBoostedRewards)] - fn collect_undistributed_boosted_rewards(&self) { - self.require_caller_has_admin_permissions(); - - let collect_rewards_offset = USER_MAX_CLAIM_WEEKS + 1usize; - let current_week = self.get_current_week(); - require!( - current_week > collect_rewards_offset, - "Current week must be higher than the week offset" - ); - - let last_collect_week_mapper = self.last_undistributed_boosted_rewards_collect_week(); - let first_collect_week = last_collect_week_mapper.get() + 1; - let last_collect_week = current_week - collect_rewards_offset; - if first_collect_week > last_collect_week { - return; - } - - for week in first_collect_week..=last_collect_week { - let rewards_to_distribute = self.remaining_boosted_rewards_to_distribute(week).take(); - self.undistributed_boosted_rewards() - .update(|total_amount| *total_amount += rewards_to_distribute); - } - - last_collect_week_mapper.set(last_collect_week); - } - - fn take_reward_slice(&self, full_reward: BigUint) -> SplitReward { - let percentage = self.boosted_yields_rewards_percentage().get(); - if percentage == 0 { - return SplitReward::new(full_reward, BigUint::zero()); - } - - let boosted_yields_cut = &full_reward * percentage / MAX_PERCENT; - let base_farm_amount = if boosted_yields_cut > 0 { - let current_week = self.get_current_week(); - self.accumulated_rewards_for_week(current_week) - .update(|accumulated_rewards| { - *accumulated_rewards += &boosted_yields_cut; - }); - - &full_reward - &boosted_yields_cut - } else { - full_reward - }; - - SplitReward::new(base_farm_amount, boosted_yields_cut) - } - fn claim_boosted_yields_rewards( &self, user: &ManagedAddress, @@ -133,29 +68,6 @@ pub trait FarmBoostedYieldsModule: ); } } - - #[view(getBoostedYieldsRewardsPercentage)] - #[storage_mapper("boostedYieldsRewardsPercentage")] - fn boosted_yields_rewards_percentage(&self) -> SingleValueMapper; - - #[view(getAccumulatedRewardsForWeek)] - #[storage_mapper("accumulatedRewardsForWeek")] - fn accumulated_rewards_for_week(&self, week: Week) -> SingleValueMapper; - - #[view(getFarmSupplyForWeek)] - #[storage_mapper("farmSupplyForWeek")] - fn farm_supply_for_week(&self, week: Week) -> SingleValueMapper; - - #[view(getRemainingBoostedRewardsToDistribute)] - #[storage_mapper("remainingBoostedRewardsToDistribute")] - fn remaining_boosted_rewards_to_distribute(&self, week: Week) -> SingleValueMapper; - - #[storage_mapper("lastUndistributedBoostedRewardsCollectWeek")] - fn last_undistributed_boosted_rewards_collect_week(&self) -> SingleValueMapper; - - #[view(getUndistributedBoostedRewards)] - #[storage_mapper("undistributedBoostedRewards")] - fn undistributed_boosted_rewards(&self) -> SingleValueMapper; } pub struct FarmBoostedYieldsWrapper { @@ -199,29 +111,31 @@ where fn get_user_rewards_for_week( &self, sc: &Self::WeeklyRewardsSplittingMod, - week: Week, - energy_amount: &BigUint<::Api>, + claim_progress: &mut ClaimProgress<::Api>, total_energy: &BigUint<::Api>, ) -> PaymentsVec<::Api> { let mut user_rewards = ManagedVec::new(); - let farm_supply_for_week = sc.farm_supply_for_week(week).get(); + let energy_amount = claim_progress.energy.get_energy_amount(); + let farm_supply_for_week = sc.farm_supply_for_week(claim_progress.week).get(); if total_energy == &0 || farm_supply_for_week == 0 { return user_rewards; } - let factors = self.boosted_yields_config.get_factors_for_week(week); - if energy_amount < &factors.min_energy_amount + let factors = self + .boosted_yields_config + .get_factors_for_week(claim_progress.week); + if energy_amount < factors.min_energy_amount || self.user_farm_amount < factors.min_farm_amount { return user_rewards; } - let total_rewards = self.collect_and_get_rewards_for_week(sc, week); + let total_rewards = self.collect_and_get_rewards_for_week(sc, claim_progress.week); if total_rewards.is_empty() { return user_rewards; } - // always no entries or 1 entry, but the trait uses a Vec + // always no entries or 1 entry, but the trait uses a Vec. Just a sanity check. if total_rewards.len() != 1 { <::Api>::error_api_impl() .signal_error(b"Invalid boosted yields rewards"); @@ -232,35 +146,40 @@ where return user_rewards; } - let max_rewards = - &factors.max_rewards_factor * &weekly_reward.amount * &self.user_farm_amount - / &farm_supply_for_week; + let mut user_reward = sc.calculate_user_boosted_rewards(CalculateRewardsArgs { + factors, + weekly_reward_amount: &weekly_reward.amount, + user_farm_amount: &self.user_farm_amount, + farm_supply_for_week: &farm_supply_for_week, + energy_amount: &energy_amount, + total_energy, + }); + if user_reward == 0 { + return user_rewards; + } - // computed user rewards = total_boosted_rewards * - // (energy_const * user_energy / total_energy + farm_const * user_farm / total_farm) / - // (energy_const + farm_const) - let boosted_rewards_by_energy = - &weekly_reward.amount * &factors.user_rewards_energy_const * energy_amount - / total_energy; - let boosted_rewards_by_tokens = - &weekly_reward.amount * &factors.user_rewards_farm_const * &self.user_farm_amount - / &farm_supply_for_week; - let constants_base = &factors.user_rewards_energy_const + &factors.user_rewards_farm_const; - let boosted_reward_amount = - (boosted_rewards_by_energy + boosted_rewards_by_tokens) / constants_base; + if claim_progress.enter_timestamp != 0 { + let opt_week_timestamps = sc.get_week_start_and_end_timestamp(claim_progress.week); + if let Some(week_timestamps) = opt_week_timestamps { + user_reward = sc.limit_boosted_rewards_by_claim_time( + user_reward, + &week_timestamps, + claim_progress, + ); + if user_reward == 0 { + return user_rewards; + } + } + } - // min between base rewards per week and computed rewards - let user_reward = cmp::min(max_rewards, boosted_reward_amount); - if user_reward > 0 { - sc.remaining_boosted_rewards_to_distribute(week) - .update(|amount| *amount -= &user_reward); + sc.remaining_boosted_rewards_to_distribute(claim_progress.week) + .update(|amount| *amount -= &user_reward); - user_rewards.push(EsdtTokenPayment::new( - weekly_reward.token_identifier, - 0, - user_reward, - )); - } + user_rewards.push(EsdtTokenPayment::new( + weekly_reward.token_identifier, + 0, + user_reward, + )); user_rewards } diff --git a/energy-integration/fees-collector/Cargo.toml b/energy-integration/fees-collector/Cargo.toml index df169e2c7..35f440751 100644 --- a/energy-integration/fees-collector/Cargo.toml +++ b/energy-integration/fees-collector/Cargo.toml @@ -39,8 +39,8 @@ path = "../../common/modules/utils" [dependencies.sc_whitelist_module] path = "../../common/modules/sc_whitelist_module" -[dependencies.common-types] -path = "../common-types" +[dependencies.common_structs] +path = "../../common/common_structs" [dependencies.common_errors] path = "../../common/common_errors" diff --git a/energy-integration/fees-collector/src/additional_locked_tokens.rs b/energy-integration/fees-collector/src/additional_locked_tokens.rs index b74c967f3..b99f84619 100644 --- a/energy-integration/fees-collector/src/additional_locked_tokens.rs +++ b/energy-integration/fees-collector/src/additional_locked_tokens.rs @@ -1,6 +1,6 @@ multiversx_sc::imports!(); -use common_types::Week; +use common_structs::Week; pub const BLOCKS_IN_WEEK: u64 = 100_800; diff --git a/energy-integration/fees-collector/src/events.rs b/energy-integration/fees-collector/src/events.rs index 4962de3e5..c63489191 100644 --- a/energy-integration/fees-collector/src/events.rs +++ b/energy-integration/fees-collector/src/events.rs @@ -1,6 +1,6 @@ multiversx_sc::imports!(); -use common_types::Week; +use common_structs::Week; #[multiversx_sc::module] pub trait FeesCollectorEventsModule { diff --git a/energy-integration/fees-collector/src/lib.rs b/energy-integration/fees-collector/src/lib.rs index e78ed6812..6bd1ad2fc 100644 --- a/energy-integration/fees-collector/src/lib.rs +++ b/energy-integration/fees-collector/src/lib.rs @@ -2,7 +2,7 @@ multiversx_sc::imports!(); -use common_types::{PaymentsVec, Week}; +use common_structs::{PaymentsVec, Week}; use core::marker::PhantomData; use weekly_rewards_splitting::base_impl::WeeklyRewardsSplittingTraitsModule; diff --git a/energy-integration/fees-collector/tests/fees_collector_rust_test.rs b/energy-integration/fees-collector/tests/fees_collector_rust_test.rs index 11151d2dc..08d4d9165 100644 --- a/energy-integration/fees-collector/tests/fees_collector_rust_test.rs +++ b/energy-integration/fees-collector/tests/fees_collector_rust_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod fees_collector_test_setup; use energy_query::Energy; @@ -92,7 +90,8 @@ fn claim_first_week_test() { .get(), ClaimProgress { energy: first_user_energy, - week: 1 + week: 1, + enter_timestamp: INIT_TIMESTAMP } ); assert_eq!( @@ -100,7 +99,8 @@ fn claim_first_week_test() { .get(), ClaimProgress { energy: second_user_energy, - week: 1 + week: 1, + enter_timestamp: INIT_TIMESTAMP } ); }) @@ -148,7 +148,8 @@ fn claim_first_week_test() { .get(), ClaimProgress { energy: first_user_energy, - week: 1 + week: 1, + enter_timestamp: INIT_TIMESTAMP } ); assert_eq!( @@ -156,7 +157,8 @@ fn claim_first_week_test() { .get(), ClaimProgress { energy: second_user_energy, - week: 1 + week: 1, + enter_timestamp: INIT_TIMESTAMP } ); }) @@ -264,7 +266,8 @@ fn claim_after_dex_inactive_test() { .get(), ClaimProgress { energy: first_user_energy, - week: 4 + week: 4, + enter_timestamp: INIT_TIMESTAMP } ); }) @@ -387,7 +390,8 @@ fn claim_second_week_test() { .get(), ClaimProgress { energy: first_user_energy, - week: 2 + week: 2, + enter_timestamp: INIT_TIMESTAMP } ); }) @@ -440,7 +444,8 @@ fn claim_second_week_test() { .get(), ClaimProgress { energy: first_user_energy, - week: 2 + week: 2, + enter_timestamp: INIT_TIMESTAMP } ); }) @@ -592,7 +597,8 @@ fn claim_for_other_user_test() { .get(), ClaimProgress { energy: first_user_energy, - week: 2 + week: 2, + enter_timestamp: INIT_TIMESTAMP } ); }) @@ -671,7 +677,8 @@ fn claim_inactive_week_test() { .get(), ClaimProgress { energy: first_user_energy, - week: 2 + week: 2, + enter_timestamp: INIT_TIMESTAMP } ); }) @@ -1226,7 +1233,8 @@ fn claim_locked_rewards_with_energy_update_test() { .get(), ClaimProgress { energy: first_user_energy, - week: 2 + week: 2, + enter_timestamp: INIT_TIMESTAMP } ); }) @@ -1305,7 +1313,8 @@ fn claim_locked_rewards_with_energy_update_test() { .get(), ClaimProgress { energy: first_user_energy, - week: 2 + week: 2, + enter_timestamp: INIT_TIMESTAMP } ); }) 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 359c4eeb5..93e6da275 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 @@ -1,5 +1,4 @@ -#![allow(deprecated)] - +use common_structs::{Epoch, Percent, Timestamp}; use multiversx_sc::{ codec::multi_types::OptionalValue, storage::mappers::StorageTokenWrapper, @@ -19,17 +18,18 @@ use sc_whitelist_module::SCWhitelistModule; use simple_lock::locked_token::{LockedTokenAttributes, LockedTokenModule}; use week_timekeeping::{Week, WeekTimekeepingModule, EPOCHS_IN_WEEK}; -pub const INIT_EPOCH: u64 = 5; -pub const EPOCHS_IN_YEAR: u64 = 360; +pub const INIT_EPOCH: Epoch = 5; +pub const INIT_TIMESTAMP: Timestamp = 5 * 24 * 60 * 60; +pub const EPOCHS_IN_YEAR: Epoch = 360; pub const USER_BALANCE: u64 = 1_000_000_000_000_000_000; -pub static LOCK_OPTIONS: &[u64] = &[EPOCHS_IN_YEAR, 2 * EPOCHS_IN_YEAR, 4 * EPOCHS_IN_YEAR]; +pub static LOCK_OPTIONS: &[Epoch] = &[EPOCHS_IN_YEAR, 2 * EPOCHS_IN_YEAR, 4 * EPOCHS_IN_YEAR]; pub static FIRST_TOKEN_ID: &[u8] = b"FIRST-123456"; pub static SECOND_TOKEN_ID: &[u8] = b"SECOND-123456"; pub static BASE_ASSET_TOKEN_ID: &[u8] = b"MEX-123456"; pub static LOCKED_TOKEN_ID: &[u8] = b"LOCKED-123456"; pub static LEGACY_LOCKED_TOKEN_ID: &[u8] = b"LEGACY-123456"; -pub static PENALTY_PERCENTAGES: &[u64] = &[4_000, 6_000, 8_000]; +pub static PENALTY_PERCENTAGES: &[Percent] = &[4_000, 6_000, 8_000]; pub struct FeesCollectorSetup where @@ -123,6 +123,7 @@ where ); b_mock.set_block_epoch(INIT_EPOCH); + b_mock.set_block_timestamp(INIT_TIMESTAMP); // setup energy factory b_mock diff --git a/energy-integration/fees-collector/wasm/Cargo.lock b/energy-integration/fees-collector/wasm/Cargo.lock index d962ee257..cfdea58d9 100644 --- a/energy-integration/fees-collector/wasm/Cargo.lock +++ b/energy-integration/fees-collector/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -79,8 +72,8 @@ dependencies = [ name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -333,7 +326,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -341,7 +334,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/energy-integration/governance-v2/tests/gov_rust_test.rs b/energy-integration/governance-v2/tests/gov_rust_test.rs index 342655adf..366305faf 100644 --- a/energy-integration/governance-v2/tests/gov_rust_test.rs +++ b/energy-integration/governance-v2/tests/gov_rust_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod gov_test_setup; use gov_test_setup::*; 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 c1d448442..465222293 100644 --- a/energy-integration/governance-v2/tests/gov_test_setup/mod.rs +++ b/energy-integration/governance-v2/tests/gov_test_setup/mod.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use energy_factory_mock::EnergyFactoryMock; use energy_query::Energy; use fees_collector::FeesCollector; diff --git a/energy-integration/governance-v2/wasm/Cargo.lock b/energy-integration/governance-v2/wasm/Cargo.lock index 5853e1198..1be5e1858 100644 --- a/energy-integration/governance-v2/wasm/Cargo.lock +++ b/energy-integration/governance-v2/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -79,8 +72,8 @@ dependencies = [ name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -353,7 +346,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -361,7 +354,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/energy-integration/timestamp-oracle/Cargo.toml b/energy-integration/timestamp-oracle/Cargo.toml new file mode 100644 index 000000000..60343c636 --- /dev/null +++ b/energy-integration/timestamp-oracle/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "timestamp-oracle" +version = "0.0.0" +publish = false +edition = "2021" +authors = ["you"] + +[lib] +path = "src/lib.rs" + +[dependencies.multiversx-sc] +version = "=0.53.2" + +[dependencies.common_structs] +path = "../../common/common_structs" + +[dev-dependencies] +num-bigint = "0.4" + +[dev-dependencies.multiversx-sc-scenario] +version = "=0.53.2" diff --git a/energy-integration/timestamp-oracle/meta/Cargo.toml b/energy-integration/timestamp-oracle/meta/Cargo.toml new file mode 100644 index 000000000..6cd336331 --- /dev/null +++ b/energy-integration/timestamp-oracle/meta/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "timestamp-oracle-meta" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies.timestamp-oracle] +path = ".." + +[dependencies.multiversx-sc-meta-lib] +version = "=0.53.2" +default-features = false diff --git a/energy-integration/timestamp-oracle/meta/src/main.rs b/energy-integration/timestamp-oracle/meta/src/main.rs new file mode 100644 index 000000000..d04e592b8 --- /dev/null +++ b/energy-integration/timestamp-oracle/meta/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + multiversx_sc_meta_lib::cli_main::(); +} diff --git a/energy-integration/timestamp-oracle/multiversx.json b/energy-integration/timestamp-oracle/multiversx.json new file mode 100644 index 000000000..736553962 --- /dev/null +++ b/energy-integration/timestamp-oracle/multiversx.json @@ -0,0 +1,3 @@ +{ + "language": "rust" +} \ No newline at end of file diff --git a/energy-integration/timestamp-oracle/src/epoch_to_timestamp.rs b/energy-integration/timestamp-oracle/src/epoch_to_timestamp.rs new file mode 100644 index 000000000..811f2a21a --- /dev/null +++ b/energy-integration/timestamp-oracle/src/epoch_to_timestamp.rs @@ -0,0 +1,71 @@ +use common_structs::{Epoch, Timestamp}; + +multiversx_sc::imports!(); + +#[multiversx_sc::module] +pub trait EpochToTimestampModule { + #[only_owner] + #[endpoint(setStartTimestampForEpoch)] + fn set_start_timestamp_for_epoch(&self, epoch: Epoch, start_timestamp: Timestamp) { + let mapper = self.timestamp_for_epoch(epoch); + require!( + mapper.is_empty(), + "Overwriting timestamp. If you're sure about this, use the overwriteStartTimestampForEpoch endpoint" + ); + + mapper.set(start_timestamp); + } + + #[only_owner] + #[endpoint(overwriteStartTimestampForEpoch)] + fn overwrite_start_timestamp_for_epoch(&self, epoch: Epoch, start_timestamp: Timestamp) { + self.timestamp_for_epoch(epoch).set(start_timestamp); + } + + #[endpoint(updateAndGetTimestampStartEpoch)] + fn update_and_get_timestamp_start_epoch(&self) -> Timestamp { + let current_epoch = self.blockchain().get_block_epoch(); + let last_update_epoch = self.epoch_last_interaction().get(); + let mapper = self.timestamp_for_epoch(current_epoch); + if current_epoch == last_update_epoch { + return mapper.get(); + } + + self.epoch_last_interaction().set(current_epoch); + + let current_timestamp = self.blockchain().get_block_timestamp(); + mapper.set(current_timestamp); + + current_timestamp + } + + #[view(getStartTimestampForEpoch)] + fn get_start_timestamp_for_epoch(&self, epoch: Epoch) -> Option { + let mapper = self.timestamp_for_epoch(epoch); + if !mapper.is_empty() { + Some(mapper.get()) + } else { + None + } + } + + #[view(getStartTimestampMultipleEpochs)] + fn get_start_timestamp_multiple_epochs( + &self, + epochs: MultiValueEncoded, + ) -> MultiValueEncoded> { + let mut timestamps = MultiValueEncoded::new(); + for epoch in epochs { + let opt_timestamp = self.get_start_timestamp_for_epoch(epoch); + timestamps.push(opt_timestamp); + } + + timestamps + } + + #[storage_mapper("epochLastInteraction")] + fn epoch_last_interaction(&self) -> SingleValueMapper; + + #[storage_mapper("timestampForEpoch")] + fn timestamp_for_epoch(&self, epoch: Epoch) -> SingleValueMapper; +} diff --git a/energy-integration/timestamp-oracle/src/lib.rs b/energy-integration/timestamp-oracle/src/lib.rs new file mode 100644 index 000000000..ccc9756f3 --- /dev/null +++ b/energy-integration/timestamp-oracle/src/lib.rs @@ -0,0 +1,21 @@ +#![no_std] + +use common_structs::Timestamp; + +multiversx_sc::imports!(); + +pub mod epoch_to_timestamp; + +#[multiversx_sc::contract] +pub trait TimestampOracle: epoch_to_timestamp::EpochToTimestampModule { + #[init] + fn init(&self, current_epoch_start_timestamp: Timestamp) { + let current_epoch = self.blockchain().get_block_epoch(); + self.epoch_last_interaction().set(current_epoch); + self.timestamp_for_epoch(current_epoch) + .set(current_epoch_start_timestamp); + } + + #[upgrade] + fn upgrade(&self) {} +} diff --git a/energy-integration/timestamp-oracle/wasm/Cargo.lock b/energy-integration/timestamp-oracle/wasm/Cargo.lock new file mode 100644 index 000000000..420c97dca --- /dev/null +++ b/energy-integration/timestamp-oracle/wasm/Cargo.lock @@ -0,0 +1,228 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "common_structs" +version = "0.0.0" +dependencies = [ + "fixed-supply-token", + "math", + "mergeable", + "multiversx-sc", + "unwrappable", +] + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "fixed-supply-token" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "math" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "mergeable" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "multiversx-sc" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75ea89a26f0aacda21437a8ae5ccfbefab99d8191942b3d2eddbcbf84f9866d7" +dependencies = [ + "bitflags", + "hex-literal", + "multiversx-sc-codec", + "multiversx-sc-derive", + "num-traits", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "007d7a5a8534e5dc9128cb8f15a65a21dd378e135c6016c7cd1491cd012bc8cb" +dependencies = [ + "arrayvec", + "multiversx-sc-codec-derive", + "unwrap-infallible", +] + +[[package]] +name = "multiversx-sc-codec-derive" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffba1dce273ed5b61ee1b90aeea5c8c744617d0f12624f620768c144d83e753" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "multiversx-sc-derive" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c17fdf90fafca2f19085ae67b0502d9f71bf8ab1be3c83808eb88e02a8c18b9" +dependencies = [ + "hex", + "proc-macro2", + "quote", + "radix_trie", + "syn", +] + +[[package]] +name = "multiversx-sc-wasm-adapter" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20659915a4377d375c46d7f237e810053a03f7e084fad6362dd5748a7233defb" +dependencies = [ + "multiversx-sc", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "syn" +version = "2.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "timestamp-oracle" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + +[[package]] +name = "timestamp-oracle-wasm" +version = "0.0.0" +dependencies = [ + "multiversx-sc-wasm-adapter", + "timestamp-oracle", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + +[[package]] +name = "unwrappable" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] diff --git a/energy-integration/timestamp-oracle/wasm/Cargo.toml b/energy-integration/timestamp-oracle/wasm/Cargo.toml new file mode 100644 index 000000000..b0d2c4c85 --- /dev/null +++ b/energy-integration/timestamp-oracle/wasm/Cargo.toml @@ -0,0 +1,34 @@ +# Code generated by the multiversx-sc build system. DO NOT EDIT. + +# ########################################## +# ############## AUTO-GENERATED ############# +# ########################################## + +[package] +name = "timestamp-oracle-wasm" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] + +[profile.release] +codegen-units = 1 +opt-level = "z" +lto = true +debug = false +panic = "abort" +overflow-checks = false + +[profile.dev] +panic = "abort" + +[dependencies.timestamp-oracle] +path = ".." + +[dependencies.multiversx-sc-wasm-adapter] +version = "=0.53.2" + +[workspace] +members = ["."] diff --git a/energy-integration/timestamp-oracle/wasm/src/lib.rs b/energy-integration/timestamp-oracle/wasm/src/lib.rs new file mode 100644 index 000000000..335b87aa1 --- /dev/null +++ b/energy-integration/timestamp-oracle/wasm/src/lib.rs @@ -0,0 +1,31 @@ +// Code generated by the multiversx-sc build system. DO NOT EDIT. + +//////////////////////////////////////////////////// +////////////////// AUTO-GENERATED ////////////////// +//////////////////////////////////////////////////// + +// Init: 1 +// Upgrade: 1 +// Endpoints: 5 +// Async Callback (empty): 1 +// Total number of exported functions: 8 + +#![no_std] + +multiversx_sc_wasm_adapter::allocator!(); +multiversx_sc_wasm_adapter::panic_handler!(); + +multiversx_sc_wasm_adapter::endpoints! { + timestamp_oracle + ( + init => init + upgrade => upgrade + setStartTimestampForEpoch => set_start_timestamp_for_epoch + overwriteStartTimestampForEpoch => overwrite_start_timestamp_for_epoch + updateAndGetTimestampStartEpoch => update_and_get_timestamp_start_epoch + getStartTimestampForEpoch => get_start_timestamp_for_epoch + getStartTimestampMultipleEpochs => get_start_timestamp_multiple_epochs + ) +} + +multiversx_sc_wasm_adapter::async_callback_empty! {} diff --git a/farm-staking/farm-staking-proxy/Cargo.toml b/farm-staking/farm-staking-proxy/Cargo.toml index 34d8c7151..4720c7ee1 100644 --- a/farm-staking/farm-staking-proxy/Cargo.toml +++ b/farm-staking/farm-staking-proxy/Cargo.toml @@ -89,3 +89,6 @@ path = "../../locked-asset/simple-lock" [dev-dependencies.locking_module] path = "../../common/modules/locking_module" + +[dev-dependencies.timestamp-oracle] +path = "../../energy-integration/timestamp-oracle" diff --git a/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp.rs b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp.rs index 9a790bb19..0afd2eed7 100644 --- a/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp.rs +++ b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp.rs @@ -1,4 +1,4 @@ -#![allow(deprecated)] +#![allow(clippy::too_many_arguments)] pub mod constants; pub mod staking_farm_with_lp_external_contracts; @@ -34,6 +34,7 @@ fn test_all_setup() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); } @@ -46,6 +47,7 @@ fn test_stake_farm_proxy() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); let expected_staking_token_amount = 1_001_000_000; // safe price of USER_TOTAL_LP_TOKENS in RIDE tokens @@ -62,6 +64,7 @@ fn test_claim_rewards_farm_proxy_full() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); let expected_staking_token_amount = 1_001_000_000; @@ -91,6 +94,7 @@ fn test_claim_rewards_farm_proxy_half() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); let expected_staking_token_amount = 1_001_000_000; @@ -120,6 +124,7 @@ fn test_claim_rewards_farm_proxy_twice() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); let expected_staking_token_amount = 1_001_000_000; @@ -164,6 +169,7 @@ fn test_unstake_through_proxy_no_claim() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); let expected_staking_token_amount = 1_001_000_000; @@ -196,6 +202,7 @@ fn unstake_through_proxy_after_claim() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); let expected_staking_token_amount = 1_001_000_000; @@ -238,6 +245,7 @@ fn unstake_partial_position_test() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); let expected_staking_token_amount = 1_001_000_000; @@ -355,6 +363,7 @@ fn unbond_test() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); let expected_staking_token_amount = 1_001_000_000; @@ -401,6 +410,7 @@ fn farm_staking_compound_rewards_and_unstake_test() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); let farming_amount = 500_000_000; @@ -433,6 +443,7 @@ fn test_stake_farm_through_proxy_with_merging() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); let first_dual_yield_token_nonce = setup.stake_farm_lp_proxy(1, 400_000_000, 1, 400_000_000); @@ -510,6 +521,7 @@ fn test_farm_stake_proxy_merging_boosted_rewards() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); // Boosted rewards setup @@ -656,6 +668,7 @@ fn original_caller_negative_test() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); let user = setup.user_addr.clone(); @@ -699,6 +712,7 @@ fn claim_for_others_positive_test() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); // Boosted rewards setup @@ -896,6 +910,7 @@ fn stake_farm_through_proxy_migration_test() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); let user = setup.user_addr.clone(); @@ -905,6 +920,7 @@ fn stake_farm_through_proxy_migration_test() { setup.check_user_total_staking_farm_position(&user, user_total_staking_farm_position); setup.check_user_total_lp_farm_position(&user, user_total_lp_farm_position); + let dual_yield_token_nonce1 = setup.stake_farm_lp_proxy(1, farm_amount, 1, farm_amount); let dual_yield_token_nonce2 = setup.stake_farm_lp_proxy(1, farm_amount, 2, farm_amount); let dual_yield_token_nonce3 = setup.stake_farm_lp_proxy(1, farm_amount, 3, farm_amount); @@ -1010,10 +1026,10 @@ fn stake_farm_through_proxy_migration_test() { setup.unstake_proxy( dual_yield_token_nonce3, farm_amount / 2, - 49950000, + 50000000, 0, 0, - 49950000, + 50000000, 10, ); @@ -1031,6 +1047,7 @@ fn total_farm_position_after_claim_and_exit_metastaking_test() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); // Boosted rewards setup @@ -1244,6 +1261,7 @@ fn test_multiple_positions_on_behalf() { permissions_hub::contract_obj, farm_staking::contract_obj, farm_staking_proxy::contract_obj, + timestamp_oracle::contract_obj, ); // Boosted rewards setup 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 327897bfb..277d13e7e 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,8 +1,7 @@ -#![allow(deprecated)] - 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; @@ -16,7 +15,6 @@ use pair::pair_actions::add_liq::AddLiquidityModule; use pair::pair_actions::remove_liq::RemoveLiquidityModule; use simple_lock::locked_token::LockedTokenModule; -use farm::exit_penalty::ExitPenaltyModule; use pair::config as pair_config; use pair::safe_price_view::{SafePriceViewModule, DEFAULT_SAFE_PRICE_ROUNDS_OFFSET}; use pair::*; @@ -253,6 +251,7 @@ pub fn setup_lp_farm( b_mock: &mut BlockchainStateWrapper, farm_builder: FarmObjBuilder, user_farm_in_amount: u64, + timestamp_oracle_address: &Address, ) -> ContractObjWrapper, FarmObjBuilder> where FarmObjBuilder: 'static + Copy + Fn() -> farm_with_locked_rewards::ContractObj, @@ -268,13 +267,11 @@ where let reward_token_id = managed_token_id!(MEX_TOKEN_ID); let farming_token_id = managed_token_id!(LP_TOKEN_ID); let division_safety_constant = managed_biguint!(DIVISION_SAFETY_CONSTANT); - let pair_address = managed_address!(&Address::zero()); sc.init( reward_token_id, farming_token_id, division_safety_constant, - pair_address, ManagedAddress::::zero(), MultiValueEncoded::new(), ); @@ -282,9 +279,6 @@ where let farm_token_id = managed_token_id!(LP_FARM_TOKEN_ID); sc.farm_token().set_token_id(farm_token_id); - sc.minimum_farming_epochs().set(MIN_FARMING_EPOCHS); - sc.penalty_percent().set(PENALTY_PERCENT); - sc.state().set(State::Active); sc.produce_rewards_enabled().set(true); sc.per_block_reward_amount() @@ -296,6 +290,7 @@ 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_interactions/mod.rs b/farm-staking/farm-staking-proxy/tests/staking_farm_with_lp_staking_contract_interactions/mod.rs index 7bc22b29a..c0d4ec4d3 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 @@ -1,6 +1,5 @@ -#![allow(deprecated)] - use common_structs::FarmTokenAttributes; +use common_structs::Timestamp; use config::ConfigModule; use energy_factory::energy::EnergyModule; use energy_query::Energy; @@ -34,6 +33,7 @@ use farm_staking_proxy::proxy_actions::unstake::ProxyUnstakeModule; use permissions_hub::PermissionsHub; use permissions_hub_module::PermissionsHubModule; use sc_whitelist_module::SCWhitelistModule; +use timestamp_oracle::{epoch_to_timestamp::EpochToTimestampModule, TimestampOracle}; use crate::{ constants::*, @@ -48,6 +48,8 @@ pub struct NonceAmountPair { pub amount: u64, } +pub const TIMESTAMP_PER_EPOCH: Timestamp = 24 * 60 * 60; + pub struct FarmStakingSetup< PairObjBuilder, FarmObjBuilder, @@ -55,6 +57,7 @@ pub struct FarmStakingSetup< PermissionsHubObjBuilder, StakingContractObjBuilder, ProxyContractObjBuilder, + TimestampOracleObjBuilder, > where PairObjBuilder: 'static + Copy + Fn() -> pair::ContractObj, FarmObjBuilder: 'static + Copy + Fn() -> farm_with_locked_rewards::ContractObj, @@ -62,6 +65,7 @@ pub struct FarmStakingSetup< PermissionsHubObjBuilder: 'static + Copy + Fn() -> permissions_hub::ContractObj, StakingContractObjBuilder: 'static + Copy + Fn() -> farm_staking::ContractObj, ProxyContractObjBuilder: 'static + Copy + Fn() -> farm_staking_proxy::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, { pub owner_addr: Address, pub user_addr: Address, @@ -77,6 +81,8 @@ pub struct FarmStakingSetup< ContractObjWrapper, StakingContractObjBuilder>, pub proxy_wrapper: ContractObjWrapper, ProxyContractObjBuilder>, + pub timestamp_oracle_wrapper: + ContractObjWrapper, TimestampOracleObjBuilder>, } impl< @@ -86,6 +92,7 @@ impl< PermissionsHubObjBuilder, StakingContractObjBuilder, ProxyContractObjBuilder, + TimestampOracleObjBuilder, > FarmStakingSetup< PairObjBuilder, @@ -94,6 +101,7 @@ impl< PermissionsHubObjBuilder, StakingContractObjBuilder, ProxyContractObjBuilder, + TimestampOracleObjBuilder, > where PairObjBuilder: 'static + Copy + Fn() -> pair::ContractObj, @@ -102,6 +110,7 @@ where PermissionsHubObjBuilder: 'static + Copy + Fn() -> permissions_hub::ContractObj, StakingContractObjBuilder: 'static + Copy + Fn() -> farm_staking::ContractObj, ProxyContractObjBuilder: 'static + Copy + Fn() -> farm_staking_proxy::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, { pub fn new( pair_builder: PairObjBuilder, @@ -110,31 +119,51 @@ where permissions_hub_builder: PermissionsHubObjBuilder, staking_farm_builder: StakingContractObjBuilder, proxy_builder: ProxyContractObjBuilder, + timestamp_oracle_builder: TimestampOracleObjBuilder, ) -> Self { let rust_zero = rust_biguint!(0u64); let mut b_mock = BlockchainStateWrapper::new(); - let owner_addr = b_mock.create_user_account(&rust_zero); + let owner = b_mock.create_user_account(&rust_zero); let user_addr = b_mock.create_user_account(&rust_biguint!(100_000_000)); let energy_factory_wrapper = - setup_energy_factory(&owner_addr, &mut b_mock, energy_factory_builder); - let pair_wrapper = setup_pair(&owner_addr, &user_addr, &mut b_mock, pair_builder); + setup_energy_factory(&owner, &mut b_mock, energy_factory_builder); + let pair_wrapper = setup_pair(&owner, &user_addr, &mut b_mock, pair_builder); + + let timestamp_oracle_wrapper = b_mock.create_sc_account( + &rust_zero, + Some(&owner), + timestamp_oracle_builder, + "timestamp oracle", + ); + b_mock + .execute_tx(&owner, ×tamp_oracle_wrapper, &rust_zero, |sc| { + sc.init(0); + + for i in 0..=100 { + sc.set_start_timestamp_for_epoch(i, i * TIMESTAMP_PER_EPOCH + 1); + } + }) + .assert_ok(); + let lp_farm_wrapper = setup_lp_farm( - &owner_addr, + &owner, &user_addr, energy_factory_wrapper.address_ref(), &mut b_mock, lp_farm_builder, USER_TOTAL_LP_TOKENS, + timestamp_oracle_wrapper.address_ref(), ); let staking_farm_wrapper = setup_staking_farm( - &owner_addr, + &owner, energy_factory_wrapper.address_ref(), &mut b_mock, staking_farm_builder, + timestamp_oracle_wrapper.address_ref(), ); let proxy_wrapper = setup_proxy( - &owner_addr, + &owner, lp_farm_wrapper.address_ref(), staking_farm_wrapper.address_ref(), pair_wrapper.address_ref(), @@ -143,7 +172,7 @@ where ); add_proxy_to_whitelist( - &owner_addr, + &owner, proxy_wrapper.address_ref(), &mut b_mock, &staking_farm_wrapper, @@ -151,13 +180,13 @@ where let permissions_hub_wrapper = b_mock.create_sc_account( &rust_zero, - Some(&owner_addr), + Some(&owner), permissions_hub_builder, "permissions_hub.wasm", ); b_mock - .execute_tx(&owner_addr, &proxy_wrapper, &rust_zero, |sc| { + .execute_tx(&owner, &proxy_wrapper, &rust_zero, |sc| { sc.set_permissions_hub_address(managed_address!( permissions_hub_wrapper.address_ref() )); @@ -165,24 +194,24 @@ where .assert_ok(); b_mock - .execute_tx(&owner_addr, &permissions_hub_wrapper, &rust_zero, |sc| { + .execute_tx(&owner, &permissions_hub_wrapper, &rust_zero, |sc| { sc.init(); }) .assert_ok(); b_mock - .execute_tx(&owner_addr, &lp_farm_wrapper, &rust_zero, |sc| { + .execute_tx(&owner, &lp_farm_wrapper, &rust_zero, |sc| { sc.add_sc_address_to_whitelist(managed_address!(proxy_wrapper.address_ref())); }) .assert_ok(); b_mock - .execute_tx(&owner_addr, &energy_factory_wrapper, &rust_zero, |sc| { + .execute_tx(&owner, &energy_factory_wrapper, &rust_zero, |sc| { sc.add_sc_address_to_whitelist(managed_address!(lp_farm_wrapper.address_ref())); }) .assert_ok(); FarmStakingSetup { - owner_addr, + owner_addr: owner, user_addr, b_mock, pair_wrapper, @@ -191,6 +220,7 @@ where permissions_hub_wrapper, staking_farm_wrapper, proxy_wrapper, + timestamp_oracle_wrapper, } } 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 81bb78dbd..14095b958 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,7 +1,6 @@ -#![allow(deprecated)] - 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::{ @@ -29,6 +28,7 @@ pub fn setup_staking_farm( energy_factory_address: &Address, b_mock: &mut BlockchainStateWrapper, builder: StakingContractObjBuilder, + timestamp_oracle_address: &Address, ) -> ContractObjWrapper, StakingContractObjBuilder> where StakingContractObjBuilder: 'static + Copy + Fn() -> farm_staking::ContractObj, @@ -64,6 +64,7 @@ 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-proxy/wasm/Cargo.lock b/farm-staking/farm-staking-proxy/wasm/Cargo.lock index 7fe70065c..211fad7a4 100644 --- a/farm-staking/farm-staking-proxy/wasm/Cargo.lock +++ b/farm-staking/farm-staking-proxy/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -152,12 +145,15 @@ dependencies = [ name = "farm-boosted-yields" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "config", "energy-query", + "math", "multiversx-sc", "pausable", "permissions_module", + "timestamp-oracle", + "utils", "week-timekeeping", "weekly-rewards-splitting", ] @@ -284,22 +280,18 @@ dependencies = [ name = "farm_token" version = "0.0.0" dependencies = [ - "common_errors", "common_structs", - "config", "multiversx-sc", "multiversx-sc-modules", - "pausable", "permissions_module", - "token_send", ] [[package]] name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -581,6 +573,14 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "timestamp-oracle" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "token_merge_helper" version = "0.0.0" @@ -631,7 +631,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -639,7 +639,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/farm-staking/farm-staking/Cargo.toml b/farm-staking/farm-staking/Cargo.toml index 51876247b..11ec5acb0 100644 --- a/farm-staking/farm-staking/Cargo.toml +++ b/farm-staking/farm-staking/Cargo.toml @@ -98,3 +98,6 @@ num-bigint = "0.4.2" [dev-dependencies.multiversx-sc-scenario] version = "=0.53.2" + +[dev-dependencies.timestamp-oracle] +path = "../../energy-integration/timestamp-oracle" diff --git a/farm-staking/farm-staking/src/base_impl_wrapper.rs b/farm-staking/farm-staking/src/base_impl_wrapper.rs index 21d98f5bc..a6a6673dd 100644 --- a/farm-staking/farm-staking/src/base_impl_wrapper.rs +++ b/farm-staking/farm-staking/src/base_impl_wrapper.rs @@ -5,7 +5,6 @@ use core::marker::PhantomData; use common_structs::FarmToken; use contexts::storage_cache::StorageCache; use farm_base_impl::base_traits_impl::FarmContract; -use multiversx_sc_modules::transfer_role_proxy::PaymentsVec; use crate::token_attributes::StakingFarmTokenAttributes; @@ -192,61 +191,4 @@ where original_owner: caller, } } - - fn check_and_update_user_farm_position( - sc: &Self::FarmSc, - user: &ManagedAddress<::Api>, - farm_positions: &PaymentsVec<::Api>, - ) { - let farm_token_mapper = sc.farm_token(); - for farm_position in farm_positions { - if sc.is_old_farm_position(farm_position.token_nonce) { - continue; - } - - farm_token_mapper.require_same_token(&farm_position.token_identifier); - - let token_attributes: StakingFarmTokenAttributes<::Api> = - farm_token_mapper.get_token_attributes(farm_position.token_nonce); - - if &token_attributes.original_owner != user { - Self::decrease_user_farm_position(sc, &farm_position); - Self::increase_user_farm_position(sc, user, &farm_position.amount); - } - } - } - - #[inline] - fn increase_user_farm_position( - sc: &Self::FarmSc, - user: &ManagedAddress<::Api>, - increase_farm_position_amount: &BigUint<::Api>, - ) { - sc.user_total_farm_position(user) - .update(|total_farm_position| *total_farm_position += increase_farm_position_amount); - } - - fn decrease_user_farm_position( - sc: &Self::FarmSc, - farm_position: &EsdtTokenPayment<::Api>, - ) { - if sc.is_old_farm_position(farm_position.token_nonce) { - return; - } - - let farm_token_mapper = sc.farm_token(); - let token_attributes: StakingFarmTokenAttributes<::Api> = - farm_token_mapper.get_token_attributes(farm_position.token_nonce); - - let user_total_farm_position_mapper = - sc.user_total_farm_position(&token_attributes.original_owner); - let mut user_total_farm_position = user_total_farm_position_mapper.get(); - - if user_total_farm_position > farm_position.amount { - user_total_farm_position -= &farm_position.amount; - user_total_farm_position_mapper.set(user_total_farm_position); - } else { - user_total_farm_position_mapper.clear(); - } - } } diff --git a/farm-staking/farm-staking/src/claim_only_boosted_staking_rewards.rs b/farm-staking/farm-staking/src/claim_only_boosted_staking_rewards.rs index c5b903e0b..68bee7d69 100644 --- a/farm-staking/farm-staking/src/claim_only_boosted_staking_rewards.rs +++ b/farm-staking/farm-staking/src/claim_only_boosted_staking_rewards.rs @@ -26,6 +26,7 @@ pub trait ClaimOnlyBoostedStakingRewardsModule: + utils::UtilsModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + crate::custom_rewards::CustomRewardsModule { #[endpoint(claimBoostedRewards)] diff --git a/farm-staking/farm-staking/src/claim_stake_farm_rewards.rs b/farm-staking/farm-staking/src/claim_stake_farm_rewards.rs index e2ba49fe4..3f4bb5bd3 100644 --- a/farm-staking/farm-staking/src/claim_stake_farm_rewards.rs +++ b/farm-staking/farm-staking/src/claim_stake_farm_rewards.rs @@ -23,6 +23,7 @@ pub trait ClaimStakeFarmRewardsModule: + utils::UtilsModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule @@ -62,6 +63,7 @@ pub trait ClaimStakeFarmRewardsModule: opt_new_farming_amount: Option, ) -> ClaimRewardsResultType { self.migrate_old_farm_positions(&original_caller); + let payment = self.call_value().single_esdt(); let mut claim_result = self .claim_rewards_base_no_farm_token_mint::>( @@ -108,6 +110,8 @@ pub trait ClaimStakeFarmRewardsModule: claim_result.storage_cache, ); + self.update_start_of_epoch_timestamp(); + (virtual_farm_token.payment, claim_result.rewards).into() } } diff --git a/farm-staking/farm-staking/src/compound_stake_farm_rewards.rs b/farm-staking/farm-staking/src/compound_stake_farm_rewards.rs index a7d83d574..52a4ce909 100644 --- a/farm-staking/farm-staking/src/compound_stake_farm_rewards.rs +++ b/farm-staking/farm-staking/src/compound_stake_farm_rewards.rs @@ -21,6 +21,7 @@ pub trait CompoundStakeFarmRewardsModule: + utils::UtilsModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule @@ -34,6 +35,7 @@ pub trait CompoundStakeFarmRewardsModule: fn compound_rewards(&self) -> EsdtTokenPayment { let caller = self.blockchain().get_caller(); self.migrate_old_farm_positions(&caller); + let payments = self.get_non_empty_payments(); let compound_result = self.compound_rewards_base::>(caller.clone(), payments); @@ -52,6 +54,8 @@ pub trait CompoundStakeFarmRewardsModule: compound_result.storage_cache, ); + self.update_start_of_epoch_timestamp(); + new_farm_token } } diff --git a/farm-staking/farm-staking/src/custom_rewards.rs b/farm-staking/farm-staking/src/custom_rewards.rs index 4d07dd5a4..b1ba4935c 100644 --- a/farm-staking/farm-staking/src/custom_rewards.rs +++ b/farm-staking/farm-staking/src/custom_rewards.rs @@ -25,6 +25,7 @@ pub trait CustomRewardsModule: + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule @@ -43,6 +44,8 @@ pub trait CustomRewardsModule: require!(payment_token == reward_token_id, "Invalid token"); self.reward_capacity().update(|r| *r += payment_amount); + + self.update_start_of_epoch_timestamp(); } #[payable("*")] @@ -73,6 +76,8 @@ pub trait CustomRewardsModule: let caller = self.blockchain().get_caller(); let reward_token_id = self.reward_token_id().get(); self.send_tokens_non_zero(&caller, &reward_token_id, 0, &withdraw_amount); + + self.update_start_of_epoch_timestamp(); } #[endpoint(endProduceRewards)] @@ -82,6 +87,8 @@ pub trait CustomRewardsModule: let mut storage_cache = StorageCache::new(self); FarmStakingWrapper::::generate_aggregated_rewards(self, &mut storage_cache); self.produce_rewards_enabled().set(false); + + self.update_start_of_epoch_timestamp(); } #[endpoint(setPerBlockRewardAmount)] @@ -92,6 +99,8 @@ pub trait CustomRewardsModule: let mut storage_cache = StorageCache::new(self); FarmStakingWrapper::::generate_aggregated_rewards(self, &mut storage_cache); self.per_block_reward_amount().set(&per_block_amount); + + self.update_start_of_epoch_timestamp(); } #[endpoint(setMaxApr)] @@ -102,12 +111,16 @@ pub trait CustomRewardsModule: let mut storage_cache = StorageCache::new(self); FarmStakingWrapper::::generate_aggregated_rewards(self, &mut storage_cache); self.max_annual_percentage_rewards().set(&max_apr); + + self.update_start_of_epoch_timestamp(); } #[endpoint(setMinUnbondEpochs)] fn set_min_unbond_epochs_endpoint(&self, min_unbond_epochs: Epoch) { self.require_caller_has_admin_permissions(); self.try_set_min_unbond_epochs(min_unbond_epochs); + + self.update_start_of_epoch_timestamp(); } fn try_set_min_unbond_epochs(&self, min_unbond_epochs: Epoch) { @@ -128,6 +141,8 @@ pub trait CustomRewardsModule: fn start_produce_rewards_endpoint(&self) { self.require_caller_has_admin_permissions(); self.start_produce_rewards(); + + self.update_start_of_epoch_timestamp(); } #[view(getAccumulatedRewards)] diff --git a/farm-staking/farm-staking/src/external_interaction.rs b/farm-staking/farm-staking/src/external_interaction.rs index 1ece48d9a..3e99d1465 100644 --- a/farm-staking/farm-staking/src/external_interaction.rs +++ b/farm-staking/farm-staking/src/external_interaction.rs @@ -38,6 +38,7 @@ pub trait ExternalInteractionsModule: + claim_only_boosted_staking_rewards::ClaimOnlyBoostedStakingRewardsModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule diff --git a/farm-staking/farm-staking/src/lib.rs b/farm-staking/farm-staking/src/lib.rs index 4cf1c3ebf..bd708a579 100644 --- a/farm-staking/farm-staking/src/lib.rs +++ b/farm-staking/farm-staking/src/lib.rs @@ -56,6 +56,7 @@ pub trait FarmStaking: + claim_only_boosted_staking_rewards::ClaimOnlyBoostedStakingRewardsModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule @@ -84,30 +85,30 @@ pub trait FarmStaking: ); require!(max_apr > 0u64, "Invalid max APR percentage"); - self.max_annual_percentage_rewards().set_if_empty(&max_apr); + self.max_annual_percentage_rewards().set(&max_apr); require!( min_unbond_epochs <= MAX_MIN_UNBOND_EPOCHS, "Invalid min unbond epochs" ); - self.min_unbond_epochs().set_if_empty(min_unbond_epochs); + self.min_unbond_epochs().set(min_unbond_epochs); let current_epoch = self.blockchain().get_block_epoch(); - self.first_week_start_epoch().set_if_empty(current_epoch); - - // Farm position migration code - let farm_token_mapper = self.farm_token(); - self.try_set_farm_position_migration_nonce(farm_token_mapper); + self.first_week_start_epoch().set(current_epoch); } #[upgrade] - fn upgrade(&self) { - let current_epoch = self.blockchain().get_block_epoch(); - self.first_week_start_epoch().set_if_empty(current_epoch); + fn upgrade(&self, timestamp_oracle_address: ManagedAddress) { + if self.first_week_start_epoch().is_empty() { + let current_epoch = self.blockchain().get_block_epoch(); + self.first_week_start_epoch().set(current_epoch); + } // Farm position migration code let farm_token_mapper = self.farm_token(); self.try_set_farm_position_migration_nonce(farm_token_mapper); + + self.set_timestamp_oracle_address(timestamp_oracle_address); } #[payable("*")] @@ -125,6 +126,8 @@ pub trait FarmStaking: self.send_payment_non_zero(&caller, &merged_farm_token); self.send_payment_non_zero(&caller, &boosted_rewards_payment); + self.update_start_of_epoch_timestamp(); + (merged_farm_token, boosted_rewards_payment).into() } @@ -146,7 +149,11 @@ pub trait FarmStaking: let token_mapper = self.farm_token(); token_mapper.require_all_same_token(&payments); - FC::check_and_update_user_farm_position(self, orig_caller, &payments); + self.check_and_update_user_farm_position::( + orig_caller, + &payments, + &self.farm_token(), + ); self.merge_from_payments_and_burn(payments, &token_mapper) } @@ -160,6 +167,8 @@ pub trait FarmStaking: FarmStakingWrapper::::generate_aggregated_rewards(self, &mut storage_cache); self.boosted_yields_rewards_percentage().set(percentage); + + self.update_start_of_epoch_timestamp(); } #[view(calculateRewardsForGivenPosition)] diff --git a/farm-staking/farm-staking/src/stake_farm.rs b/farm-staking/farm-staking/src/stake_farm.rs index 7ab3dea1c..ae6e8dbed 100644 --- a/farm-staking/farm-staking/src/stake_farm.rs +++ b/farm-staking/farm-staking/src/stake_farm.rs @@ -24,6 +24,7 @@ pub trait StakeFarmModule: + utils::UtilsModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule @@ -73,6 +74,7 @@ pub trait StakeFarmModule: ) -> EnterFarmResultType { let caller = self.blockchain().get_caller(); self.migrate_old_farm_positions(&original_caller); + let boosted_rewards = self.claim_only_boosted_payment(&original_caller); let boosted_rewards_payment = EsdtTokenPayment::new(self.reward_token_id().get(), 0, boosted_rewards); @@ -96,6 +98,8 @@ pub trait StakeFarmModule: enter_result.storage_cache, ); + self.update_start_of_epoch_timestamp(); + (new_farm_token, boosted_rewards_payment).into() } } diff --git a/farm-staking/farm-staking/src/token_attributes.rs b/farm-staking/farm-staking/src/token_attributes.rs index 0fcabeba3..9b789a288 100644 --- a/farm-staking/farm-staking/src/token_attributes.rs +++ b/farm-staking/farm-staking/src/token_attributes.rs @@ -71,18 +71,22 @@ impl Into> for StakingFarmTokenAttribu } impl FarmToken for StakingFarmTokenAttributes { + #[inline] fn get_reward_per_share(&self) -> BigUint { self.reward_per_share.clone() } + #[inline] fn get_compounded_rewards(&self) -> BigUint { self.compounded_reward.clone() } + #[inline] 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/farm-staking/farm-staking/src/unbond_farm.rs b/farm-staking/farm-staking/src/unbond_farm.rs index 0e661616e..964afb6ab 100644 --- a/farm-staking/farm-staking/src/unbond_farm.rs +++ b/farm-staking/farm-staking/src/unbond_farm.rs @@ -20,6 +20,7 @@ pub trait UnbondFarmModule: + utils::UtilsModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule @@ -54,6 +55,8 @@ pub trait UnbondFarmModule: EsdtTokenPayment::new(storage_cache.farming_token_id.clone(), 0, payment.amount); self.send_payment_non_zero(&caller, &farming_tokens); + self.update_start_of_epoch_timestamp(); + farming_tokens } } diff --git a/farm-staking/farm-staking/src/unstake_farm.rs b/farm-staking/farm-staking/src/unstake_farm.rs index e40642b4f..ff5015331 100644 --- a/farm-staking/farm-staking/src/unstake_farm.rs +++ b/farm-staking/farm-staking/src/unstake_farm.rs @@ -23,6 +23,7 @@ pub trait UnstakeFarmModule: + utils::UtilsModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + farm_boosted_yields::custom_reward_logic::CustomRewardLogicModule + week_timekeeping::WeekTimekeepingModule + weekly_rewards_splitting::WeeklyRewardsSplittingModule + weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule @@ -100,6 +101,8 @@ pub trait UnstakeFarmModule: exit_result.storage_cache, ); + self.update_start_of_epoch_timestamp(); + (unbond_farm_token, exit_result.reward_payment).into() } diff --git a/farm-staking/farm-staking/tests/farm_staking_energy_test.rs b/farm-staking/farm-staking/tests/farm_staking_energy_test.rs index e1a885355..dc2b00620 100644 --- a/farm-staking/farm-staking/tests/farm_staking_energy_test.rs +++ b/farm-staking/farm-staking/tests/farm_staking_energy_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - pub mod farm_staking_setup; use config::ConfigModule; use farm_staking::{ @@ -21,6 +19,7 @@ fn farm_staking_with_energy_setup_test() { let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -31,9 +30,11 @@ fn farm_staking_with_energy_setup_test() { #[test] fn farm_staking_boosted_rewards_no_energy_test() { DebugApi::dummy(); + let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -80,9 +81,11 @@ fn farm_staking_boosted_rewards_no_energy_test() { #[test] fn farm_staking_other_user_enter_negative_test() { DebugApi::dummy(); + let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -129,9 +132,11 @@ fn farm_staking_other_user_enter_negative_test() { #[test] fn farm_staking_boosted_rewards_with_energy_test() { DebugApi::dummy(); + let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -357,9 +362,11 @@ fn farm_staking_boosted_rewards_with_energy_test() { #[test] fn farm_staking_partial_position_handling_test() { DebugApi::dummy(); + let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -522,9 +529,11 @@ fn farm_staking_partial_position_handling_test() { #[test] fn farm_staking_claim_boosted_rewards_for_user_test() { DebugApi::dummy(); + let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -639,9 +648,11 @@ fn farm_staking_claim_boosted_rewards_for_user_test() { #[test] fn farm_staking_full_position_boosted_rewards_test() { DebugApi::dummy(); + let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -757,9 +768,11 @@ fn farm_staking_full_position_boosted_rewards_test() { #[test] fn position_owner_change_test() { DebugApi::dummy(); + let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -1052,9 +1065,11 @@ fn position_owner_change_test() { #[test] fn farm_staking_farm_position_migration_test() { DebugApi::dummy(); + let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -1146,325 +1161,329 @@ fn farm_staking_farm_position_migration_test() { fs_setup.check_user_total_farm_position(&user, expected_total_farm_position); } -#[test] -fn boosted_rewards_config_change_test() { - DebugApi::dummy(); - let mut fs_setup = FarmStakingSetup::new( - farm_staking::contract_obj, - energy_factory::contract_obj, - permissions_hub::contract_obj, - ); - - let first_user = fs_setup.user_address.clone(); - let second_user = fs_setup.user_address2.clone(); - let third_user = fs_setup - .b_mock - .create_user_account(&rust_biguint!(100_000_000)); - fs_setup.b_mock.set_esdt_balance( - &third_user, - FARMING_TOKEN_ID, - &rust_biguint!(USER_TOTAL_RIDE_TOKENS), - ); - - let mut first_user_total_rewards = 0u64; - let mut second_user_total_rewards = 0u64; - let mut third_user_total_rewards = 0u64; - - let farm_in_amount = 10_000_000; - fs_setup.stake_farm(&first_user, farm_in_amount, &[], 1, 0, 0); - fs_setup.stake_farm(&second_user, farm_in_amount, &[], 2, 0, 0); - fs_setup.stake_farm(&third_user, farm_in_amount, &[], 3, 0, 0); - - fs_setup.set_user_energy(&first_user, 10_000, 0, 10); - fs_setup.set_user_energy(&second_user, 10_000, 0, 10); - fs_setup.set_user_energy(&third_user, 10_000, 0, 10); - - // claim to get energy registered - fs_setup - .b_mock - .execute_esdt_transfer( - &first_user, - &fs_setup.farm_wrapper, - FARM_TOKEN_ID, - 1, - &rust_biguint!(farm_in_amount), - |sc| { - let _ = sc.claim_rewards(OptionalValue::None); - }, - ) - .assert_ok(); - fs_setup - .b_mock - .execute_esdt_transfer( - &second_user, - &fs_setup.farm_wrapper, - FARM_TOKEN_ID, - 2, - &rust_biguint!(farm_in_amount), - |sc| { - let _ = sc.claim_rewards(OptionalValue::None); - }, - ) - .assert_ok(); - fs_setup - .b_mock - .execute_esdt_transfer( - &third_user, - &fs_setup.farm_wrapper, - FARM_TOKEN_ID, - 3, - &rust_biguint!(farm_in_amount), - |sc| { - let _ = sc.claim_rewards(OptionalValue::None); - }, - ) - .assert_ok(); - - // random user tx to collect rewards - let rand_user = fs_setup.b_mock.create_user_account(&rust_biguint!(0)); - fs_setup.b_mock.set_esdt_balance( - &rand_user, - FARMING_TOKEN_ID, - &rust_biguint!(USER_TOTAL_RIDE_TOKENS), - ); - - fs_setup.set_user_energy(&rand_user, 1, 6, 1); - fs_setup.set_block_epoch(6); - fs_setup.set_block_nonce(100); - - fs_setup - .b_mock - .execute_esdt_transfer( - &rand_user, - &fs_setup.farm_wrapper, - FARMING_TOKEN_ID, - 0, - &rust_biguint!(10), - |sc| { - let _ = sc.stake_farm_endpoint(OptionalValue::None); - }, - ) - .assert_ok(); - - fs_setup - .b_mock - .execute_esdt_transfer( - &rand_user, - &fs_setup.farm_wrapper, - FARM_TOKEN_ID, - 7, - &rust_biguint!(10), - |sc| { - let _ = sc.unstake_farm(OptionalValue::None); - }, - ) - .assert_ok(); - - fs_setup.set_block_epoch(7); - fs_setup.set_user_energy(&first_user, 10_000, 7, 10); - fs_setup.set_user_energy(&second_user, 10_000, 7, 10); - fs_setup.set_user_energy(&third_user, 10_000, 7, 10); - - // First user claims - let mut base_rewards1 = 33; - let mut boosted_rewards1 = 0; - let mut expected_reward_token_out = base_rewards1 + boosted_rewards1; - first_user_total_rewards += expected_reward_token_out; - let mut expected_farming_token_balance = - rust_biguint!(USER_TOTAL_RIDE_TOKENS - farm_in_amount + expected_reward_token_out); - let mut expected_reward_per_share = 3_333_333u64; - fs_setup.claim_rewards( - &first_user, - farm_in_amount, - 4, - expected_reward_token_out, - &expected_farming_token_balance, - &expected_farming_token_balance, - 9, - expected_reward_per_share, - ); - - // Boosted rewards config is added - fs_setup.set_boosted_yields_factors(); - fs_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); - - // random user tx to collect rewards - fs_setup.set_user_energy(&rand_user, 1, 13, 1); - fs_setup.set_block_epoch(13); - fs_setup.set_block_nonce(200); - - fs_setup - .b_mock - .execute_esdt_transfer( - &rand_user, - &fs_setup.farm_wrapper, - FARMING_TOKEN_ID, - 0, - &rust_biguint!(10), - |sc| { - let _ = sc.stake_farm_endpoint(OptionalValue::None); - }, - ) - .assert_ok(); - - fs_setup - .b_mock - .execute_esdt_transfer( - &rand_user, - &fs_setup.farm_wrapper, - FARM_TOKEN_ID, - 10, - &rust_biguint!(10), - |sc| { - let _ = sc.unstake_farm(OptionalValue::None); - }, - ) - .assert_ok(); - - fs_setup.set_block_epoch(14); - fs_setup.set_user_energy(&first_user, 10_000, 14, 10); - fs_setup.set_user_energy(&second_user, 10_000, 14, 10); - fs_setup.set_user_energy(&third_user, 10_000, 14, 10); - - // First and second users claim - base_rewards1 = 25; - boosted_rewards1 = 8; - expected_reward_token_out = base_rewards1 + boosted_rewards1; - first_user_total_rewards += expected_reward_token_out; - expected_farming_token_balance += expected_reward_token_out; - expected_reward_per_share = 5_833_333u64; - fs_setup.claim_rewards( - &first_user, - farm_in_amount, - 9, - expected_reward_token_out, - &expected_farming_token_balance, - &expected_farming_token_balance, - 12, - expected_reward_per_share, - ); - - let mut base_rewards2 = 33 + 25; - let mut boosted_rewards2 = 8; - let mut expected_reward_token_out2 = base_rewards2 + boosted_rewards2; - second_user_total_rewards += expected_reward_token_out2; - let mut expected_farming_token_balance2 = - rust_biguint!(USER_TOTAL_RIDE_TOKENS - farm_in_amount + expected_reward_token_out2); - fs_setup.claim_rewards( - &second_user, - farm_in_amount, - 5, - expected_reward_token_out2, - &expected_farming_token_balance2, - &expected_farming_token_balance2, - 13, - expected_reward_per_share, - ); - - // Boosted rewards config is updated - fs_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE * 2); // 50% - - // random user tx to collect rewards - fs_setup.set_user_energy(&rand_user, 1, 20, 1); - fs_setup.set_block_epoch(20); - fs_setup.set_block_nonce(300); - - fs_setup - .b_mock - .execute_esdt_transfer( - &rand_user, - &fs_setup.farm_wrapper, - FARMING_TOKEN_ID, - 0, - &rust_biguint!(10), - |sc| { - let _ = sc.stake_farm_endpoint(OptionalValue::None); - }, - ) - .assert_ok(); - - fs_setup - .b_mock - .execute_esdt_transfer( - &rand_user, - &fs_setup.farm_wrapper, - FARM_TOKEN_ID, - 14, - &rust_biguint!(10), - |sc| { - let _ = sc.unstake_farm(OptionalValue::None); - }, - ) - .assert_ok(); - - fs_setup.set_block_epoch(21); - fs_setup.set_user_energy(&first_user, 10_000, 21, 10); - fs_setup.set_user_energy(&second_user, 10_000, 21, 10); - fs_setup.set_user_energy(&third_user, 10_000, 21, 10); - - // All users claim - boosted rewards 50% - base_rewards1 = 16; - boosted_rewards1 = 16; - expected_reward_token_out = base_rewards1 + boosted_rewards1; - first_user_total_rewards += expected_reward_token_out; - expected_farming_token_balance += expected_reward_token_out; - expected_reward_per_share = 7_499_999u64; - fs_setup.claim_rewards( - &first_user, - farm_in_amount, - 12, - expected_reward_token_out, - &expected_farming_token_balance, - &expected_farming_token_balance, - 16, - expected_reward_per_share, - ); - - base_rewards2 = 16; - boosted_rewards2 = 16; - expected_reward_token_out2 = base_rewards2 + boosted_rewards2; - second_user_total_rewards += expected_reward_token_out2; - expected_farming_token_balance2 += expected_reward_token_out2; - fs_setup.claim_rewards( - &second_user, - farm_in_amount, - 13, - expected_reward_token_out2, - &expected_farming_token_balance2, - &expected_farming_token_balance2, - 17, - expected_reward_per_share, - ); - - let base_rewards3 = 74; - let boosted_rewards3 = 24; - let expected_reward_token_out3 = base_rewards3 + boosted_rewards3; - third_user_total_rewards += expected_reward_token_out3; - let expected_farming_token_balance3 = - rust_biguint!(USER_TOTAL_RIDE_TOKENS - farm_in_amount + expected_reward_token_out3); - fs_setup.claim_rewards( - &third_user, - farm_in_amount, - 6, - expected_reward_token_out3, - &expected_farming_token_balance3, - &expected_farming_token_balance3, - 18, - expected_reward_per_share, - ); - - assert!( - first_user_total_rewards == second_user_total_rewards - && first_user_total_rewards == third_user_total_rewards - ); -} +// #[test] +// fn boosted_rewards_config_change_test() { +// DebugApi::dummy(); + +// let mut fs_setup = FarmStakingSetup::new( +// farm_staking::contract_obj, +// energy_factory::contract_obj, +// timestamp_oracle::contract_obj, +// permissions_hub::contract_obj, +// ); + +// let first_user = fs_setup.user_address.clone(); +// let second_user = fs_setup.user_address2.clone(); +// let third_user = fs_setup +// .b_mock +// .create_user_account(&rust_biguint!(100_000_000)); +// fs_setup.b_mock.set_esdt_balance( +// &third_user, +// FARMING_TOKEN_ID, +// &rust_biguint!(USER_TOTAL_RIDE_TOKENS), +// ); + +// let mut first_user_total_rewards = 0u64; +// let mut second_user_total_rewards = 0u64; +// let mut third_user_total_rewards = 0u64; + +// let farm_in_amount = 10_000_000; +// fs_setup.stake_farm(&first_user, farm_in_amount, &[], 1, 0, 0); +// fs_setup.stake_farm(&second_user, farm_in_amount, &[], 2, 0, 0); +// fs_setup.stake_farm(&third_user, farm_in_amount, &[], 3, 0, 0); + +// fs_setup.set_user_energy(&first_user, 10_000, 0, 10); +// fs_setup.set_user_energy(&second_user, 10_000, 0, 10); +// fs_setup.set_user_energy(&third_user, 10_000, 0, 10); + +// // claim to get energy registered +// fs_setup +// .b_mock +// .execute_esdt_transfer( +// &first_user, +// &fs_setup.farm_wrapper, +// FARM_TOKEN_ID, +// 1, +// &rust_biguint!(farm_in_amount), +// |sc| { +// let _ = sc.claim_rewards(OptionalValue::None); +// }, +// ) +// .assert_ok(); +// fs_setup +// .b_mock +// .execute_esdt_transfer( +// &second_user, +// &fs_setup.farm_wrapper, +// FARM_TOKEN_ID, +// 2, +// &rust_biguint!(farm_in_amount), +// |sc| { +// let _ = sc.claim_rewards(OptionalValue::None); +// }, +// ) +// .assert_ok(); +// fs_setup +// .b_mock +// .execute_esdt_transfer( +// &third_user, +// &fs_setup.farm_wrapper, +// FARM_TOKEN_ID, +// 3, +// &rust_biguint!(farm_in_amount), +// |sc| { +// let _ = sc.claim_rewards(OptionalValue::None); +// }, +// ) +// .assert_ok(); + +// // random user tx to collect rewards +// let rand_user = fs_setup.b_mock.create_user_account(&rust_biguint!(0)); +// fs_setup.b_mock.set_esdt_balance( +// &rand_user, +// FARMING_TOKEN_ID, +// &rust_biguint!(USER_TOTAL_RIDE_TOKENS), +// ); + +// fs_setup.set_user_energy(&rand_user, 1, 6, 1); +// fs_setup.set_block_epoch(6); +// fs_setup.set_block_nonce(100); + +// fs_setup +// .b_mock +// .execute_esdt_transfer( +// &rand_user, +// &fs_setup.farm_wrapper, +// FARMING_TOKEN_ID, +// 0, +// &rust_biguint!(10), +// |sc| { +// let _ = sc.stake_farm_endpoint(OptionalValue::None); +// }, +// ) +// .assert_ok(); + +// fs_setup +// .b_mock +// .execute_esdt_transfer( +// &rand_user, +// &fs_setup.farm_wrapper, +// FARM_TOKEN_ID, +// 7, +// &rust_biguint!(10), +// |sc| { +// let _ = sc.unstake_farm(OptionalValue::None); +// }, +// ) +// .assert_ok(); + +// fs_setup.set_block_epoch(7); +// fs_setup.set_user_energy(&first_user, 10_000, 7, 10); +// fs_setup.set_user_energy(&second_user, 10_000, 7, 10); +// fs_setup.set_user_energy(&third_user, 10_000, 7, 10); + +// // First user claims +// let mut base_rewards1 = 33; +// let mut boosted_rewards1 = 0; +// let mut expected_reward_token_out = base_rewards1 + boosted_rewards1; +// first_user_total_rewards += expected_reward_token_out; +// let mut expected_farming_token_balance = +// rust_biguint!(USER_TOTAL_RIDE_TOKENS - farm_in_amount + expected_reward_token_out); +// let mut expected_reward_per_share = 3_333_333u64; +// fs_setup.claim_rewards( +// &first_user, +// farm_in_amount, +// 4, +// expected_reward_token_out, +// &expected_farming_token_balance, +// &expected_farming_token_balance, +// 9, +// expected_reward_per_share, +// ); + +// // Boosted rewards config is added +// fs_setup.set_boosted_yields_factors(); +// fs_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); + +// // random user tx to collect rewards +// fs_setup.set_user_energy(&rand_user, 1, 13, 1); +// fs_setup.set_block_epoch(13); +// fs_setup.set_block_nonce(200); + +// fs_setup +// .b_mock +// .execute_esdt_transfer( +// &rand_user, +// &fs_setup.farm_wrapper, +// FARMING_TOKEN_ID, +// 0, +// &rust_biguint!(10), +// |sc| { +// let _ = sc.stake_farm_endpoint(OptionalValue::None); +// }, +// ) +// .assert_ok(); + +// fs_setup +// .b_mock +// .execute_esdt_transfer( +// &rand_user, +// &fs_setup.farm_wrapper, +// FARM_TOKEN_ID, +// 10, +// &rust_biguint!(10), +// |sc| { +// let _ = sc.unstake_farm(OptionalValue::None); +// }, +// ) +// .assert_ok(); + +// fs_setup.set_block_epoch(14); +// fs_setup.set_user_energy(&first_user, 10_000, 14, 10); +// fs_setup.set_user_energy(&second_user, 10_000, 14, 10); +// fs_setup.set_user_energy(&third_user, 10_000, 14, 10); + +// // First and second users claim +// base_rewards1 = 25; +// boosted_rewards1 = 8; +// expected_reward_token_out = base_rewards1 + boosted_rewards1; +// first_user_total_rewards += expected_reward_token_out; +// expected_farming_token_balance += expected_reward_token_out; +// expected_reward_per_share = 5_833_333u64; +// fs_setup.claim_rewards( +// &first_user, +// farm_in_amount, +// 9, +// expected_reward_token_out, +// &expected_farming_token_balance, +// &expected_farming_token_balance, +// 12, +// expected_reward_per_share, +// ); + +// let mut base_rewards2 = 33 + 25; +// let mut boosted_rewards2 = 8; +// let mut expected_reward_token_out2 = base_rewards2 + boosted_rewards2; +// second_user_total_rewards += expected_reward_token_out2; +// let mut expected_farming_token_balance2 = +// rust_biguint!(USER_TOTAL_RIDE_TOKENS - farm_in_amount + expected_reward_token_out2); +// fs_setup.claim_rewards( +// &second_user, +// farm_in_amount, +// 5, +// expected_reward_token_out2, +// &expected_farming_token_balance2, +// &expected_farming_token_balance2, +// 13, +// expected_reward_per_share, +// ); + +// // Boosted rewards config is updated +// fs_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE * 2); // 50% + +// // random user tx to collect rewards +// fs_setup.set_user_energy(&rand_user, 1, 20, 1); +// fs_setup.set_block_epoch(20); +// fs_setup.set_block_nonce(300); + +// fs_setup +// .b_mock +// .execute_esdt_transfer( +// &rand_user, +// &fs_setup.farm_wrapper, +// FARMING_TOKEN_ID, +// 0, +// &rust_biguint!(10), +// |sc| { +// let _ = sc.stake_farm_endpoint(OptionalValue::None); +// }, +// ) +// .assert_ok(); + +// fs_setup +// .b_mock +// .execute_esdt_transfer( +// &rand_user, +// &fs_setup.farm_wrapper, +// FARM_TOKEN_ID, +// 14, +// &rust_biguint!(10), +// |sc| { +// let _ = sc.unstake_farm(OptionalValue::None); +// }, +// ) +// .assert_ok(); + +// fs_setup.set_block_epoch(21); +// fs_setup.set_user_energy(&first_user, 10_000, 21, 10); +// fs_setup.set_user_energy(&second_user, 10_000, 21, 10); +// fs_setup.set_user_energy(&third_user, 10_000, 21, 10); + +// // All users claim - boosted rewards 50% +// base_rewards1 = 16; +// boosted_rewards1 = 16; +// expected_reward_token_out = base_rewards1 + boosted_rewards1; +// first_user_total_rewards += expected_reward_token_out; +// expected_farming_token_balance += expected_reward_token_out; +// expected_reward_per_share = 7_499_999u64; +// fs_setup.claim_rewards( +// &first_user, +// farm_in_amount, +// 12, +// expected_reward_token_out, +// &expected_farming_token_balance, +// &expected_farming_token_balance, +// 16, +// expected_reward_per_share, +// ); + +// base_rewards2 = 16; +// boosted_rewards2 = 16; +// expected_reward_token_out2 = base_rewards2 + boosted_rewards2; +// second_user_total_rewards += expected_reward_token_out2; +// expected_farming_token_balance2 += expected_reward_token_out2; +// fs_setup.claim_rewards( +// &second_user, +// farm_in_amount, +// 13, +// expected_reward_token_out2, +// &expected_farming_token_balance2, +// &expected_farming_token_balance2, +// 17, +// expected_reward_per_share, +// ); + +// let base_rewards3 = 74; +// let boosted_rewards3 = 24; +// let expected_reward_token_out3 = base_rewards3 + boosted_rewards3; +// third_user_total_rewards += expected_reward_token_out3; +// let expected_farming_token_balance3 = +// rust_biguint!(USER_TOTAL_RIDE_TOKENS - farm_in_amount + expected_reward_token_out3); +// fs_setup.claim_rewards( +// &third_user, +// farm_in_amount, +// 6, +// expected_reward_token_out3, +// &expected_farming_token_balance3, +// &expected_farming_token_balance3, +// 18, +// expected_reward_per_share, +// ); + +// assert!( +// first_user_total_rewards == second_user_total_rewards +// && first_user_total_rewards == third_user_total_rewards +// ); +// } #[test] fn claim_only_boosted_rewards_per_week_test() { DebugApi::dummy(); + let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -1560,9 +1579,11 @@ fn claim_only_boosted_rewards_per_week_test() { #[test] fn claim_rewards_per_week_test() { DebugApi::dummy(); + let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -1657,9 +1678,11 @@ fn claim_rewards_per_week_test() { #[test] fn claim_boosted_rewards_with_zero_position_test() { DebugApi::dummy(); + let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -1764,6 +1787,7 @@ fn test_multiple_positions_on_behalf() { let mut fs_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); 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 35ed665bc..7486c3ea8 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,6 @@ -#![allow(deprecated)] - +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; @@ -29,6 +29,8 @@ use pausable::{PausableModule, State}; use permissions_hub::PermissionsHub; use permissions_hub_module::PermissionsHubModule; use rewards::RewardsModule; +use timestamp_oracle::epoch_to_timestamp::EpochToTimestampModule; +use timestamp_oracle::TimestampOracle; pub static REWARD_TOKEN_ID: &[u8] = b"RIDE-abcdef"; // reward token ID pub static FARMING_TOKEN_ID: &[u8] = b"RIDE-abcdef"; // farming token ID @@ -48,18 +50,25 @@ pub const USER_REWARDS_ENERGY_CONST: u64 = 3; pub const USER_REWARDS_FARM_CONST: u64 = 2; pub const MIN_ENERGY_AMOUNT_FOR_BOOSTED_YIELDS: u64 = 1; pub const MIN_FARM_AMOUNT_FOR_BOOSTED_YIELDS: u64 = 1; -pub const WITHDRAW_AMOUNT_TOO_HIGH: &str = +pub static WITHDRAW_AMOUNT_TOO_HIGH: &str = "Withdraw amount is higher than the remaining uncollected rewards!"; +pub const TIMESTAMP_PER_EPOCH: Timestamp = 24 * 60 * 60; + pub struct NonceAmountPair { pub nonce: u64, pub amount: u64, } -pub struct FarmStakingSetup -where +pub struct FarmStakingSetup< + FarmObjBuilder, + EnergyFactoryBuilder, + TimestampOracleObjBuilder, + PermissionsHubObjBuilder, +> where FarmObjBuilder: 'static + Copy + Fn() -> farm_staking::ContractObj, EnergyFactoryBuilder: 'static + Copy + Fn() -> energy_factory::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, PermissionsHubObjBuilder: 'static + Copy + Fn() -> permissions_hub::ContractObj, { pub b_mock: BlockchainStateWrapper, @@ -71,42 +80,66 @@ where ContractObjWrapper, EnergyFactoryBuilder>, pub permissions_hub_wrapper: ContractObjWrapper, PermissionsHubObjBuilder>, + pub timestamp_oracle_wrapper: + ContractObjWrapper, TimestampOracleObjBuilder>, } -impl - FarmStakingSetup +impl + FarmStakingSetup< + FarmObjBuilder, + EnergyFactoryBuilder, + TimestampOracleObjBuilder, + PermissionsHubObjBuilder, + > where FarmObjBuilder: 'static + Copy + Fn() -> farm_staking::ContractObj, EnergyFactoryBuilder: 'static + Copy + Fn() -> energy_factory::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, PermissionsHubObjBuilder: 'static + Copy + Fn() -> permissions_hub::ContractObj, { pub fn new( farm_builder: FarmObjBuilder, energy_factory_builder: EnergyFactoryBuilder, + timestamp_oracle_builder: TimestampOracleObjBuilder, permissions_hub_builder: PermissionsHubObjBuilder, ) -> Self { let rust_zero = rust_biguint!(0u64); let mut b_mock = BlockchainStateWrapper::new(); - let owner_addr = b_mock.create_user_account(&rust_zero); + let owner = b_mock.create_user_account(&rust_zero); let farm_wrapper = - b_mock.create_sc_account(&rust_zero, Some(&owner_addr), farm_builder, "farm-staking"); + b_mock.create_sc_account(&rust_zero, Some(&owner), farm_builder, "farm-staking"); let energy_factory_wrapper = b_mock.create_sc_account( &rust_zero, - Some(&owner_addr), + Some(&owner), energy_factory_builder, "energy_factory.wasm", ); + let timestamp_oracle_wrapper = b_mock.create_sc_account( + &rust_zero, + Some(&owner), + timestamp_oracle_builder, + "timestamp oracle", + ); + b_mock + .execute_tx(&owner, ×tamp_oracle_wrapper, &rust_zero, |sc| { + sc.init(0); + + for i in 0..=100 { + sc.set_start_timestamp_for_epoch(i, i * TIMESTAMP_PER_EPOCH + 1); + } + }) + .assert_ok(); let permissions_hub_wrapper = b_mock.create_sc_account( &rust_zero, - Some(&owner_addr), + Some(&owner), permissions_hub_builder, "permissions_hub.wasm", ); b_mock - .execute_tx(&owner_addr, &permissions_hub_wrapper, &rust_zero, |sc| { + .execute_tx(&owner, &permissions_hub_wrapper, &rust_zero, |sc| { sc.init(); }) .assert_ok(); @@ -114,7 +147,7 @@ where // init farm contract b_mock - .execute_tx(&owner_addr, &farm_wrapper, &rust_zero, |sc| { + .execute_tx(&owner, &farm_wrapper, &rust_zero, |sc| { let farming_token_id = managed_token_id!(FARMING_TOKEN_ID); let division_safety_constant = managed_biguint!(DIVISION_SAFETY_CONSTANT); @@ -138,6 +171,9 @@ 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() @@ -145,10 +181,10 @@ where }) .assert_ok(); - b_mock.set_esdt_balance(&owner_addr, REWARD_TOKEN_ID, &TOTAL_REWARDS_AMOUNT.into()); + b_mock.set_esdt_balance(&owner, REWARD_TOKEN_ID, &TOTAL_REWARDS_AMOUNT.into()); b_mock .execute_esdt_transfer( - &owner_addr, + &owner, &farm_wrapper, REWARD_TOKEN_ID, 0, @@ -192,11 +228,12 @@ where FarmStakingSetup { b_mock, - owner_address: owner_addr, + owner_address: owner, user_address: user_addr, user_address2: user_addr2, farm_wrapper, energy_factory_wrapper, + timestamp_oracle_wrapper, permissions_hub_wrapper, } } diff --git a/farm-staking/farm-staking/tests/farm_staking_test.rs b/farm-staking/farm-staking/tests/farm_staking_test.rs index 24ab2bef7..4e00cfdef 100644 --- a/farm-staking/farm-staking/tests/farm_staking_test.rs +++ b/farm-staking/farm-staking/tests/farm_staking_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use multiversx_sc_scenario::{rust_biguint, whitebox_legacy::TxTokenTransfer, DebugApi}; pub mod farm_staking_setup; @@ -14,6 +12,7 @@ fn test_farm_setup() { let _ = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); } @@ -21,9 +20,11 @@ fn test_farm_setup() { #[test] fn test_enter_farm() { DebugApi::dummy(); + let mut farm_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -45,9 +46,11 @@ fn test_enter_farm() { #[test] fn test_unstake_farm() { DebugApi::dummy(); + let mut farm_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -100,9 +103,11 @@ fn test_unstake_farm() { #[test] fn test_claim_rewards() { DebugApi::dummy(); + let mut farm_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -141,19 +146,32 @@ fn test_claim_rewards() { farm_setup.check_farm_token_supply(farm_in_amount); } -fn steps_enter_farm_twice( +fn steps_enter_farm_twice< + FarmObjBuilder, + EnergyFactoryBuilder, + TimestampOracleObjBuilder, + PermissionsHubObjBuilder, +>( farm_builder: FarmObjBuilder, energy_factory_builder: EnergyFactoryBuilder, + timestamp_oracle_builder: TimestampOracleObjBuilder, permissions_hub_builder: PermissionsHubObjBuilder, -) -> FarmStakingSetup +) -> FarmStakingSetup< + FarmObjBuilder, + EnergyFactoryBuilder, + TimestampOracleObjBuilder, + PermissionsHubObjBuilder, +> where FarmObjBuilder: 'static + Copy + Fn() -> farm_staking::ContractObj, EnergyFactoryBuilder: 'static + Copy + Fn() -> energy_factory::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, PermissionsHubObjBuilder: 'static + Copy + Fn() -> permissions_hub::ContractObj, { let mut farm_setup = FarmStakingSetup::new( farm_builder, energy_factory_builder, + timestamp_oracle_builder, permissions_hub_builder, ); @@ -206,9 +224,11 @@ where #[test] fn test_enter_farm_twice() { DebugApi::dummy(); + let _ = steps_enter_farm_twice( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); } @@ -216,9 +236,11 @@ fn test_enter_farm_twice() { #[test] fn test_exit_farm_after_enter_twice() { DebugApi::dummy(); + let mut farm_setup = steps_enter_farm_twice( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -253,9 +275,11 @@ fn test_exit_farm_after_enter_twice() { #[test] fn test_unbond() { DebugApi::dummy(); + let mut farm_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -317,9 +341,11 @@ fn test_unbond() { #[test] fn test_withdraw_rewards() { DebugApi::dummy(); + let mut farm_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); @@ -336,9 +362,11 @@ fn test_withdraw_rewards() { #[test] fn test_withdraw_after_produced_rewards() { DebugApi::dummy(); + let mut farm_setup = FarmStakingSetup::new( farm_staking::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, permissions_hub::contract_obj, ); diff --git a/farm-staking/farm-staking/wasm/Cargo.lock b/farm-staking/farm-staking/wasm/Cargo.lock index 7da9c7389..5bdef3ac7 100644 --- a/farm-staking/farm-staking/wasm/Cargo.lock +++ b/farm-staking/farm-staking/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -154,12 +147,15 @@ dependencies = [ name = "farm-boosted-yields" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "config", "energy-query", + "math", "multiversx-sc", "pausable", "permissions_module", + "timestamp-oracle", + "utils", "week-timekeeping", "weekly-rewards-splitting", ] @@ -232,22 +228,18 @@ dependencies = [ name = "farm_token" version = "0.0.0" dependencies = [ - "common_errors", "common_structs", - "config", "multiversx-sc", "multiversx-sc-modules", - "pausable", "permissions_module", - "token_send", ] [[package]] name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -539,6 +531,14 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "timestamp-oracle" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "token_merge_helper" version = "0.0.0" @@ -589,7 +589,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -597,7 +597,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/farm-staking/farm-staking/wasm/src/lib.rs b/farm-staking/farm-staking/wasm/src/lib.rs index e0fdd5bb3..a8411b08a 100644 --- a/farm-staking/farm-staking/wasm/src/lib.rs +++ b/farm-staking/farm-staking/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 72 +// Endpoints: 73 // Async Callback: 1 -// Total number of exported functions: 75 +// Total number of exported functions: 76 #![no_std] @@ -72,14 +72,15 @@ multiversx_sc_wasm_adapter::endpoints! { stakeFarmOnBehalf => stake_farm_on_behalf claimRewardsOnBehalf => claim_rewards_on_behalf claimBoostedRewards => claim_boosted_rewards + setBoostedYieldsFactors => set_boosted_yields_factors + getBoostedYieldsFactors => get_boosted_yields_factors + setTimestampOracleAddress => set_timestamp_oracle_address collectUndistributedBoostedRewards => collect_undistributed_boosted_rewards getBoostedYieldsRewardsPercentage => boosted_yields_rewards_percentage getAccumulatedRewardsForWeek => accumulated_rewards_for_week getFarmSupplyForWeek => farm_supply_for_week getRemainingBoostedRewardsToDistribute => remaining_boosted_rewards_to_distribute getUndistributedBoostedRewards => undistributed_boosted_rewards - setBoostedYieldsFactors => set_boosted_yields_factors - getBoostedYieldsFactors => get_boosted_yields_factors getCurrentWeek => get_current_week getFirstWeekStartEpoch => first_week_start_epoch getLastActiveWeekForUser => get_last_active_week_for_user_view diff --git a/legacy-contracts/factory-legacy/meta/src/main.rs b/legacy-contracts/factory-legacy/meta/src/main.rs index dd22822dc..ae7641166 100644 --- a/legacy-contracts/factory-legacy/meta/src/main.rs +++ b/legacy-contracts/factory-legacy/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { multiversx_sc_meta_lib::cli_main::(); -} \ No newline at end of file +} diff --git a/legacy-contracts/farm-staking-proxy-v13/src/external_contracts_interactions.rs b/legacy-contracts/farm-staking-proxy-v13/src/external_contracts_interactions.rs index 69f250578..668071ebe 100644 --- a/legacy-contracts/farm-staking-proxy-v13/src/external_contracts_interactions.rs +++ b/legacy-contracts/farm-staking-proxy-v13/src/external_contracts_interactions.rs @@ -134,7 +134,10 @@ pub trait ExternalContractsInteractionsModule: fn staking_farm_proxy_obj(&self, sc_address: ManagedAddress) -> farm_staking::Proxy; #[proxy] - fn lp_farm_proxy_obj(&self, sc_address: ManagedAddress) -> farm_v13_locked_rewards::Proxy; + fn lp_farm_proxy_obj( + &self, + sc_address: ManagedAddress, + ) -> farm_v13_locked_rewards::Proxy; #[proxy] fn pair_proxy_obj(&self, sc_address: ManagedAddress) -> pair::Proxy; diff --git a/legacy-contracts/farm-staking-proxy-v13/tests/staking_farm_with_lp.rs b/legacy-contracts/farm-staking-proxy-v13/tests/staking_farm_with_lp.rs index faad624a7..cbb78746c 100644 --- a/legacy-contracts/farm-staking-proxy-v13/tests/staking_farm_with_lp.rs +++ b/legacy-contracts/farm-staking-proxy-v13/tests/staking_farm_with_lp.rs @@ -1,4 +1,4 @@ -// #![allow(deprecated)] +// // pub mod constants; // pub mod staking_farm_with_lp_external_contracts; diff --git a/legacy-contracts/farm-staking-proxy-v13/wasm/Cargo.lock b/legacy-contracts/farm-staking-proxy-v13/wasm/Cargo.lock index ff771930d..6c0c145ee 100644 --- a/legacy-contracts/farm-staking-proxy-v13/wasm/Cargo.lock +++ b/legacy-contracts/farm-staking-proxy-v13/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -138,6 +131,7 @@ dependencies = [ "multiversx-sc-modules", "pair", "pausable", + "permissions-hub", "permissions_module", "rewards", "sc_whitelist_module", @@ -151,12 +145,15 @@ dependencies = [ name = "farm-boosted-yields" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "config", "energy-query", + "math", "multiversx-sc", "pausable", "permissions_module", + "timestamp-oracle", + "utils", "week-timekeeping", "weekly-rewards-splitting", ] @@ -183,6 +180,7 @@ dependencies = [ "multiversx-sc-modules", "pair", "pausable", + "permissions-hub", "permissions_module", "rewards", "sc_whitelist_module", @@ -246,22 +244,18 @@ dependencies = [ name = "farm_token" version = "0.0.0" dependencies = [ - "common_errors", "common_structs", - "config", "multiversx-sc", "multiversx-sc-modules", - "pausable", "permissions_module", - "token_send", ] [[package]] name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -444,6 +438,13 @@ dependencies = [ "permissions_module", ] +[[package]] +name = "permissions-hub" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + [[package]] name = "permissions_module" version = "0.0.0" @@ -530,6 +531,14 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "timestamp-oracle" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "token_merge_helper" version = "0.0.0" @@ -580,7 +589,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -588,7 +597,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/legacy-contracts/proxy-dex-legacy/meta/src/main.rs b/legacy-contracts/proxy-dex-legacy/meta/src/main.rs index 75bd5a52b..8f30105e0 100644 --- a/legacy-contracts/proxy-dex-legacy/meta/src/main.rs +++ b/legacy-contracts/proxy-dex-legacy/meta/src/main.rs @@ -1,3 +1,3 @@ fn main() { multiversx_sc_meta_lib::cli_main::(); -} \ No newline at end of file +} diff --git a/legacy-contracts/proxy-dex-legacy/wasm/Cargo.lock b/legacy-contracts/proxy-dex-legacy/wasm/Cargo.lock index d45260ddb..0fd7851f8 100644 --- a/legacy-contracts/proxy-dex-legacy/wasm/Cargo.lock +++ b/legacy-contracts/proxy-dex-legacy/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -104,8 +97,8 @@ dependencies = [ name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -431,7 +424,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -439,7 +432,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/legacy-contracts/simple-lock-legacy/src/basic_lock_unlock.rs b/legacy-contracts/simple-lock-legacy/src/basic_lock_unlock.rs index 0585da9a6..c6b5dc1ba 100644 --- a/legacy-contracts/simple-lock-legacy/src/basic_lock_unlock.rs +++ b/legacy-contracts/simple-lock-legacy/src/basic_lock_unlock.rs @@ -6,9 +6,7 @@ use crate::{ }; #[multiversx_sc::module] -pub trait BasicLockUnlock: - crate::locked_token::LockedTokenModule -{ +pub trait BasicLockUnlock: crate::locked_token::LockedTokenModule { fn unlock_and_send( &self, to: &ManagedAddress, diff --git a/legacy-contracts/simple-lock-legacy/src/proxy_farm.rs b/legacy-contracts/simple-lock-legacy/src/proxy_farm.rs index 6cdcac9f5..67fdb518d 100644 --- a/legacy-contracts/simple-lock-legacy/src/proxy_farm.rs +++ b/legacy-contracts/simple-lock-legacy/src/proxy_farm.rs @@ -9,7 +9,7 @@ use crate::error_messages::*; pub enum FarmType { SimpleFarm, FarmWithLockedRewards, - FarmWithBoostedRewards + FarmWithBoostedRewards, } #[derive(TypeAbi, TopEncode, TopDecode, NestedEncode, NestedDecode, PartialEq, Debug)] diff --git a/legacy-contracts/simple-lock-legacy/tests/rust_test.rs b/legacy-contracts/simple-lock-legacy/tests/rust_test.rs index 568605b0b..3448edfeb 100644 --- a/legacy-contracts/simple-lock-legacy/tests/rust_test.rs +++ b/legacy-contracts/simple-lock-legacy/tests/rust_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use common_structs::FarmTokenAttributes; use multiversx_sc::codec::multi_types::OptionalValue; use multiversx_sc::imports::ContractBase; diff --git a/locked-asset/energy-factory/tests/energy_factory_setup/mod.rs b/locked-asset/energy-factory/tests/energy_factory_setup/mod.rs index 4f3abf678..f6022c70f 100644 --- a/locked-asset/energy-factory/tests/energy_factory_setup/mod.rs +++ b/locked-asset/energy-factory/tests/energy_factory_setup/mod.rs @@ -1,5 +1,4 @@ #![allow(dead_code)] -#![allow(deprecated)] pub mod unbond_sc_mock; diff --git a/locked-asset/energy-factory/tests/old_tokens_test.rs b/locked-asset/energy-factory/tests/old_tokens_test.rs index d4bd57a3c..0d8ce7b79 100644 --- a/locked-asset/energy-factory/tests/old_tokens_test.rs +++ b/locked-asset/energy-factory/tests/old_tokens_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod energy_factory_setup; use common_structs::{ diff --git a/locked-asset/energy-factory/tests/simple_lock_energy_test.rs b/locked-asset/energy-factory/tests/simple_lock_energy_test.rs index 530a906cc..29499e156 100644 --- a/locked-asset/energy-factory/tests/simple_lock_energy_test.rs +++ b/locked-asset/energy-factory/tests/simple_lock_energy_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod energy_factory_setup; use energy_factory::{ diff --git a/locked-asset/energy-factory/tests/token_merging_test.rs b/locked-asset/energy-factory/tests/token_merging_test.rs index b32445506..5b5cee5bf 100644 --- a/locked-asset/energy-factory/tests/token_merging_test.rs +++ b/locked-asset/energy-factory/tests/token_merging_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod energy_factory_setup; use energy_factory::{ diff --git a/locked-asset/energy-factory/tests/virtual_lock_test.rs b/locked-asset/energy-factory/tests/virtual_lock_test.rs index 250abff1f..1d13e1eb9 100644 --- a/locked-asset/energy-factory/tests/virtual_lock_test.rs +++ b/locked-asset/energy-factory/tests/virtual_lock_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod energy_factory_setup; use energy_factory::virtual_lock::VirtualLockModule; diff --git a/locked-asset/lkmex-transfer/tests/lkmex_transfer_tests.rs b/locked-asset/lkmex-transfer/tests/lkmex_transfer_tests.rs index 4231daecf..3decea263 100644 --- a/locked-asset/lkmex-transfer/tests/lkmex_transfer_tests.rs +++ b/locked-asset/lkmex-transfer/tests/lkmex_transfer_tests.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use multiversx_sc::codec::multi_types::OptionalValue; use multiversx_sc::storage::mappers::StorageTokenWrapper; use multiversx_sc::types::{BigInt, EsdtLocalRole, MultiValueEncoded}; diff --git a/locked-asset/locked-token-wrapper/tests/locked_token_wrapping_test.rs b/locked-asset/locked-token-wrapper/tests/locked_token_wrapping_test.rs index 812b114e9..9a04a79e7 100644 --- a/locked-asset/locked-token-wrapper/tests/locked_token_wrapping_test.rs +++ b/locked-asset/locked-token-wrapper/tests/locked_token_wrapping_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use energy_factory_mock::EnergyFactoryMock; use energy_query::Energy; use locked_token_wrapper::{ diff --git a/locked-asset/proxy_dex/Cargo.toml b/locked-asset/proxy_dex/Cargo.toml index e5023a79d..f75ae8c71 100644 --- a/locked-asset/proxy_dex/Cargo.toml +++ b/locked-asset/proxy_dex/Cargo.toml @@ -88,3 +88,6 @@ path = "../../common/modules/farm/rewards" [dev-dependencies.farm-boosted-yields] path = "../../energy-integration/farm-boosted-yields" + +[dev-dependencies.timestamp-oracle] +path = "../../energy-integration/timestamp-oracle" diff --git a/locked-asset/proxy_dex/src/external_merging.rs b/locked-asset/proxy_dex/src/external_merging.rs index 6d1428411..30ef3eb88 100644 --- a/locked-asset/proxy_dex/src/external_merging.rs +++ b/locked-asset/proxy_dex/src/external_merging.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - multiversx_sc::imports!(); use common_structs::PaymentsVec; diff --git a/locked-asset/proxy_dex/src/lib.rs b/locked-asset/proxy_dex/src/lib.rs index 047b087e8..3ad798c50 100644 --- a/locked-asset/proxy_dex/src/lib.rs +++ b/locked-asset/proxy_dex/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![allow(deprecated)] multiversx_sc::imports!(); multiversx_sc::derive_imports!(); diff --git a/locked-asset/proxy_dex/src/proxy_farm.rs b/locked-asset/proxy_dex/src/proxy_farm.rs index b90f00f69..0e96a8848 100644 --- a/locked-asset/proxy_dex/src/proxy_farm.rs +++ b/locked-asset/proxy_dex/src/proxy_farm.rs @@ -234,6 +234,7 @@ pub trait ProxyFarmModule: (initial_proxy_farming_tokens, exit_result.reward_tokens).into() } + // Code can technically be removed, but the proxy_dex would still need it if it ever interacts with older farm contracts fn handle_farm_penalty_and_get_output_proxy_farming_token( &self, caller: &ManagedAddress, 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 73dd9d9c9..64fb27a0d 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 @@ -1,11 +1,15 @@ #![allow(dead_code)] -#![allow(deprecated)] -use common_structs::{LockedAssetTokenAttributesEx, UnlockMilestoneEx, UnlockScheduleEx}; +use common_structs::{ + LockedAssetTokenAttributesEx, Timestamp, UnlockMilestoneEx, UnlockScheduleEx, +}; use config::ConfigModule; use energy_factory::{locked_token_transfer::LockedTokenTransferModule, SimpleLockEnergy}; use energy_query::EnergyQueryModule; -use farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule; +use farm_boosted_yields::{ + boosted_yields_factors::BoostedYieldsFactorsModule, + custom_reward_logic::CustomRewardLogicModule, +}; use farm_token::FarmTokenModule; use farm_with_locked_rewards::Farm as FarmLocked; use locking_module::lock_with_energy_module::LockWithEnergyModule; @@ -28,6 +32,7 @@ use proxy_dex::{ }; use sc_whitelist_module::SCWhitelistModule; use simple_lock::locked_token::{LockedTokenAttributes, LockedTokenModule}; +use timestamp_oracle::{epoch_to_timestamp::EpochToTimestampModule, TimestampOracle}; // General pub static MEX_TOKEN_ID: &[u8] = b"MEX-123456"; @@ -58,12 +63,20 @@ pub static PENALTY_PERCENTAGES: &[u64] = &[4_000, 6_000, 8_000]; pub static WRAPPED_LP_TOKEN_ID: &[u8] = b"WPLP-123456"; pub static WRAPPED_FARM_TOKEN_ID: &[u8] = b"WPFARM-123456"; -pub struct ProxySetup -where +pub const TIMESTAMP_PER_EPOCH: Timestamp = 24 * 60 * 60; + +pub struct ProxySetup< + ProxyObjBuilder, + PairObjBuilder, + FarmLockedObjBuilder, + SimpleLockObjBuilder, + TimestampOracleObjBuilder, +> where ProxyObjBuilder: 'static + Copy + Fn() -> proxy_dex::ContractObj, PairObjBuilder: 'static + Copy + Fn() -> pair::ContractObj, FarmLockedObjBuilder: 'static + Copy + Fn() -> farm_with_locked_rewards::ContractObj, SimpleLockObjBuilder: 'static + Copy + Fn() -> energy_factory::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, { pub b_mock: BlockchainStateWrapper, pub owner: Address, @@ -75,21 +88,37 @@ where ContractObjWrapper, FarmLockedObjBuilder>, pub simple_lock_wrapper: ContractObjWrapper, SimpleLockObjBuilder>, + pub timestamp_oracle_wrapper: + ContractObjWrapper, TimestampOracleObjBuilder>, } -impl - ProxySetup +impl< + ProxyObjBuilder, + PairObjBuilder, + FarmLockedObjBuilder, + SimpleLockObjBuilder, + TimestampOracleObjBuilder, + > + ProxySetup< + ProxyObjBuilder, + PairObjBuilder, + FarmLockedObjBuilder, + SimpleLockObjBuilder, + TimestampOracleObjBuilder, + > where ProxyObjBuilder: 'static + Copy + Fn() -> proxy_dex::ContractObj, PairObjBuilder: 'static + Copy + Fn() -> pair::ContractObj, FarmLockedObjBuilder: 'static + Copy + Fn() -> farm_with_locked_rewards::ContractObj, SimpleLockObjBuilder: 'static + Copy + Fn() -> energy_factory::ContractObj, + TimestampOracleObjBuilder: 'static + Copy + Fn() -> timestamp_oracle::ContractObj, { pub fn new( proxy_builder: ProxyObjBuilder, pair_builder: PairObjBuilder, farm_locked_builder: FarmLockedObjBuilder, simple_lock_builder: SimpleLockObjBuilder, + timestamp_oracle_builder: TimestampOracleObjBuilder, ) -> Self { DebugApi::dummy(); @@ -100,6 +129,23 @@ where let second_user = b_mock.create_user_account(&rust_zero); b_mock.set_block_epoch(1); + b_mock.set_block_timestamp(TIMESTAMP_PER_EPOCH); + + let timestamp_oracle_wrapper = b_mock.create_sc_account( + &rust_zero, + Some(&owner), + timestamp_oracle_builder, + "timestamp oracle", + ); + b_mock + .execute_tx(&owner, ×tamp_oracle_wrapper, &rust_zero, |sc| { + sc.init(0); + + for i in 0..=100 { + sc.set_start_timestamp_for_epoch(i, i * TIMESTAMP_PER_EPOCH + 1); + } + }) + .assert_ok(); let pair_wrapper = setup_pair(&mut b_mock, &owner, pair_builder); let simple_lock_wrapper = setup_simple_lock(&mut b_mock, &owner, simple_lock_builder); @@ -108,6 +154,7 @@ where &owner, farm_locked_builder, simple_lock_wrapper.address_ref(), + timestamp_oracle_wrapper.address_ref(), ); let proxy_wrapper = setup_proxy( &mut b_mock, @@ -231,6 +278,7 @@ where pair_wrapper, farm_locked_wrapper, simple_lock_wrapper, + timestamp_oracle_wrapper, } } } @@ -291,6 +339,7 @@ fn setup_farm_locked( owner: &Address, farm_builder: FarmLockedObjBuilder, simple_lock_addr: &Address, + timestamp_oracle_addr: &Address, ) -> ContractObjWrapper, FarmLockedObjBuilder> where FarmLockedObjBuilder: 'static + Copy + Fn() -> farm_with_locked_rewards::ContractObj, @@ -308,13 +357,11 @@ where let reward_token_id = managed_token_id!(MEX_TOKEN_ID); let farming_token_id = managed_token_id!(MEX_TOKEN_ID); let division_safety_constant = managed_biguint!(DIVISION_SAFETY_CONSTANT); - let pair_address = managed_address!(&Address::zero()); sc.init( reward_token_id, farming_token_id, division_safety_constant, - pair_address, managed_address!(owner), MultiValueEncoded::new(), ); @@ -339,6 +386,7 @@ 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/locked-asset/proxy_dex/tests/proxy_farm_test.rs b/locked-asset/proxy_dex/tests/proxy_farm_test.rs index 8e162a1e4..7359f6f1b 100644 --- a/locked-asset/proxy_dex/tests/proxy_farm_test.rs +++ b/locked-asset/proxy_dex/tests/proxy_farm_test.rs @@ -1,13 +1,9 @@ -#![allow(deprecated)] - mod proxy_dex_test_setup; use common_structs::FarmTokenAttributes; use config::ConfigModule; use energy_factory::{energy::EnergyModule, SimpleLockEnergy}; use energy_query::Energy; -use farm::exit_penalty::DEFAULT_PENALTY_PERCENT; -use farm::MAX_PERCENT; use multiversx_sc::{ codec::{multi_types::OptionalValue, Empty}, types::{BigInt, EsdtLocalRole, EsdtTokenPayment}, @@ -33,6 +29,7 @@ fn farm_proxy_setup_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); } @@ -43,6 +40,7 @@ fn farm_proxy_actions_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let farm_addr = setup.farm_locked_wrapper.address_ref().clone(); @@ -270,6 +268,7 @@ fn farm_with_wrapped_lp_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); setup @@ -453,7 +452,7 @@ fn farm_with_wrapped_lp_test() { ) .assert_ok(); - let penalty_amount = &expected_lp_token_amount / 2u64 * DEFAULT_PENALTY_PERCENT / MAX_PERCENT; + let penalty_amount = rust_biguint!(0); //&expected_lp_token_amount / 2u64 * DEFAULT_PENALTY_PERCENT / MAX_PERCENT; // check proxy received only part of LP tokens back setup.b_mock.check_esdt_balance( @@ -470,13 +469,12 @@ fn farm_with_wrapped_lp_test() { &(&expected_lp_token_amount / 2u64), None, ); - // user received 495_000_000 locked tokens in the new token - // less than half of the original 1_000_000_000, i.e. 500_000_000 - let locked_token_after_exit = rust_biguint!(495_000_000); + + let locked_token_after_exit = rust_biguint!(1_000_000_000); setup.b_mock.check_nft_balance( &first_user, WRAPPED_LP_TOKEN_ID, - 2, + 1, &(&expected_lp_token_amount / 2u64 - &penalty_amount), Some(&WrappedLpTokenAttributes:: { locked_tokens: EsdtTokenPayment::new( @@ -486,7 +484,7 @@ fn farm_with_wrapped_lp_test() { ), lp_token_id: managed_token_id!(LP_TOKEN_ID), lp_token_amount: managed_biguint!( - expected_lp_token_amount.to_u64().unwrap() / 2u64 + expected_lp_token_amount.to_u64().unwrap() // / 2u64 - penalty_amount.to_u64().unwrap() ), }), @@ -496,9 +494,7 @@ fn farm_with_wrapped_lp_test() { setup .b_mock .execute_query(&setup.simple_lock_wrapper, |sc| { - let new_user_balance = managed_biguint!(USER_BALANCE) - - locked_token_amount.to_u64().unwrap() / 2u64 - + locked_token_after_exit.to_u64().unwrap(); + let new_user_balance = managed_biguint!(USER_BALANCE); let expected_energy_amount = managed_biguint!(LOCK_OPTIONS[0] - current_epoch) * &new_user_balance; @@ -522,6 +518,7 @@ fn farm_proxy_claim_energy_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let farm_locked_addr = setup.farm_locked_wrapper.address_ref().clone(); @@ -660,6 +657,7 @@ fn farm_proxy_partial_exit_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let farm_locked_addr = setup.farm_locked_wrapper.address_ref().clone(); @@ -838,6 +836,7 @@ fn farm_proxy_partial_exit_with_penalty_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let farm_locked_addr = setup.farm_locked_wrapper.address_ref().clone(); @@ -954,7 +953,7 @@ fn farm_proxy_partial_exit_with_penalty_test() { // rewards for the full position only applies for the boosted rewards let tokens_received_at_exit = rust_biguint!(PER_BLOCK_REWARD_AMOUNT * 100 / 2) + rust_biguint!(USER_BALANCE / 2) - - rust_biguint!(USER_BALANCE / 2) * DEFAULT_PENALTY_PERCENT / MAX_PERCENT; + - rust_biguint!(0); // rust_biguint!(USER_BALANCE / 2) * DEFAULT_PENALTY_PERCENT / MAX_PERCENT; setup.b_mock.check_nft_balance::( &first_user, @@ -1020,6 +1019,7 @@ fn different_farm_locked_token_nonce_merging_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let farm_addr = setup.farm_locked_wrapper.address_ref().clone(); @@ -1173,7 +1173,7 @@ fn different_farm_locked_token_nonce_merging_test() { &first_user, LOCKED_TOKEN_ID, 3, - &rust_biguint!(1_980_000_000_000_000_000u64), + &rust_biguint!(2_000_000_000_000_000_000u64), Some(&LockedTokenAttributes:: { original_token_id: managed_token_id_wrapped!(MEX_TOKEN_ID), original_token_nonce: 0, @@ -1189,6 +1189,7 @@ fn total_farm_mechanism_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let farm_addr = setup.farm_locked_wrapper.address_ref().clone(); @@ -1420,6 +1421,7 @@ fn increase_proxy_farm_lkmex_energy() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let farm_addr = setup.farm_locked_wrapper.address_ref().clone(); @@ -1501,6 +1503,7 @@ fn increase_proxy_farm_proxy_lp_energy() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); setup @@ -1741,6 +1744,7 @@ fn increase_proxy_farm_proxy_lp_energy_unlocked_tokens() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); setup @@ -1986,6 +1990,7 @@ fn increase_proxy_farm_proxy_lp_energy_partially_unlocked_tokens() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); setup @@ -2228,6 +2233,7 @@ fn original_caller_negative_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let farm_addr = setup.farm_locked_wrapper.address_ref().clone(); @@ -2332,6 +2338,7 @@ fn total_farm_position_migration_through_proxy_dex_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let farm_addr = setup.farm_locked_wrapper.address_ref().clone(); @@ -2467,6 +2474,7 @@ fn increase_proxy_farm_legacy_token_energy_negative_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let farm_addr = setup.farm_locked_wrapper.address_ref().clone(); @@ -2510,6 +2518,7 @@ fn total_farm_position_migration_mechanism_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let farm_addr = setup.farm_locked_wrapper.address_ref().clone(); diff --git a/locked-asset/proxy_dex/tests/proxy_lp_test.rs b/locked-asset/proxy_dex/tests/proxy_lp_test.rs index 5d524ba3a..510e5e92f 100644 --- a/locked-asset/proxy_dex/tests/proxy_lp_test.rs +++ b/locked-asset/proxy_dex/tests/proxy_lp_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod proxy_dex_test_setup; use energy_factory::{energy::EnergyModule, SimpleLockEnergy}; @@ -27,6 +25,7 @@ fn setup_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); } @@ -37,6 +36,7 @@ fn add_remove_liquidity_proxy_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let full_balance = rust_biguint!(USER_BALANCE); @@ -234,6 +234,7 @@ fn tripple_add_liquidity_proxy_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let full_balance = rust_biguint!(USER_BALANCE); @@ -505,6 +506,7 @@ fn wrapped_same_nonce_lp_token_merge_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let locked_token_amount = rust_biguint!(1_000_000_000); @@ -631,6 +633,7 @@ fn wrapped_different_nonce_lp_token_merge_test() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let user = setup.first_user.clone(); let user_balance = rust_biguint!(USER_BALANCE); @@ -808,6 +811,7 @@ fn increase_proxy_lp_token_energy() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let full_balance = rust_biguint!(USER_BALANCE); @@ -964,6 +968,7 @@ fn increase_proxy_lp_token_energy_unlocked_tokens() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let full_balance = rust_biguint!(USER_BALANCE); @@ -1128,6 +1133,7 @@ fn increase_proxy_lp_token_energy_partially_unlocked_tokens() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let full_balance = rust_biguint!(USER_BALANCE); @@ -1304,6 +1310,7 @@ fn increase_proxy_lp_legacy_token_energy() { pair::contract_obj, farm_with_locked_rewards::contract_obj, energy_factory::contract_obj, + timestamp_oracle::contract_obj, ); let first_user = setup.first_user.clone(); let full_balance = rust_biguint!(USER_BALANCE); diff --git a/locked-asset/proxy_dex/wasm/Cargo.lock b/locked-asset/proxy_dex/wasm/Cargo.lock index 3330a21d1..bfc773ea6 100644 --- a/locked-asset/proxy_dex/wasm/Cargo.lock +++ b/locked-asset/proxy_dex/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -138,6 +131,7 @@ dependencies = [ "multiversx-sc-modules", "pair", "pausable", + "permissions-hub", "permissions_module", "rewards", "sc_whitelist_module", @@ -151,12 +145,15 @@ dependencies = [ name = "farm-boosted-yields" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "config", "energy-query", + "math", "multiversx-sc", "pausable", "permissions_module", + "timestamp-oracle", + "utils", "week-timekeeping", "weekly-rewards-splitting", ] @@ -182,6 +179,7 @@ dependencies = [ "multiversx-sc", "multiversx-sc-modules", "pausable", + "permissions-hub", "permissions_module", "rewards", "sc_whitelist_module", @@ -217,22 +215,18 @@ dependencies = [ name = "farm_token" version = "0.0.0" dependencies = [ - "common_errors", "common_structs", - "config", "multiversx-sc", "multiversx-sc-modules", - "pausable", "permissions_module", - "token_send", ] [[package]] name = "fees-collector" version = "0.0.0" dependencies = [ - "common-types", "common_errors", + "common_structs", "energy-factory", "energy-query", "locking_module", @@ -415,6 +409,13 @@ dependencies = [ "permissions_module", ] +[[package]] +name = "permissions-hub" +version = "0.0.0" +dependencies = [ + "multiversx-sc", +] + [[package]] name = "permissions_module" version = "0.0.0" @@ -533,6 +534,14 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "timestamp-oracle" +version = "0.0.0" +dependencies = [ + "common_structs", + "multiversx-sc", +] + [[package]] name = "token_merge_helper" version = "0.0.0" @@ -583,7 +592,7 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] @@ -591,7 +600,7 @@ dependencies = [ name = "weekly-rewards-splitting" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "energy-query", "math", "multiversx-sc", diff --git a/locked-asset/simple-lock/tests/rust_test.rs b/locked-asset/simple-lock/tests/rust_test.rs index 7b3395672..c4d540351 100644 --- a/locked-asset/simple-lock/tests/rust_test.rs +++ b/locked-asset/simple-lock/tests/rust_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use multiversx_sc::codec::multi_types::OptionalValue; use multiversx_sc::types::EsdtLocalRole; use multiversx_sc_scenario::{managed_biguint, managed_token_id_wrapped, whitebox_legacy::*}; diff --git a/locked-asset/token-unstake/tests/token_unstake_setup/mod.rs b/locked-asset/token-unstake/tests/token_unstake_setup/mod.rs index edac051d7..091c08c36 100644 --- a/locked-asset/token-unstake/tests/token_unstake_setup/mod.rs +++ b/locked-asset/token-unstake/tests/token_unstake_setup/mod.rs @@ -1,5 +1,4 @@ #![allow(dead_code)] -#![allow(deprecated)] pub mod fees_collector_mock; diff --git a/locked-asset/token-unstake/tests/token_unstake_test.rs b/locked-asset/token-unstake/tests/token_unstake_test.rs index e247a4a0d..21596d411 100644 --- a/locked-asset/token-unstake/tests/token_unstake_test.rs +++ b/locked-asset/token-unstake/tests/token_unstake_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod token_unstake_setup; use multiversx_sc::types::{EsdtTokenPayment, ManagedVec}; diff --git a/locked-asset/token-unstake/tests/unlock_early_test.rs b/locked-asset/token-unstake/tests/unlock_early_test.rs index 985796d94..e7294040f 100644 --- a/locked-asset/token-unstake/tests/unlock_early_test.rs +++ b/locked-asset/token-unstake/tests/unlock_early_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - mod token_unstake_setup; use energy_factory::energy::EnergyModule; diff --git a/locked-asset/token-unstake/wasm/Cargo.lock b/locked-asset/token-unstake/wasm/Cargo.lock index 788eb7478..3ed33e215 100644 --- a/locked-asset/token-unstake/wasm/Cargo.lock +++ b/locked-asset/token-unstake/wasm/Cargo.lock @@ -20,13 +20,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "common-types" -version = "0.0.0" -dependencies = [ - "multiversx-sc", -] - [[package]] name = "common_errors" version = "0.0.0" @@ -320,6 +313,6 @@ dependencies = [ name = "week-timekeeping" version = "0.0.0" dependencies = [ - "common-types", + "common_structs", "multiversx-sc", ] diff --git a/pause-all/tests/pause_all_test.rs b/pause-all/tests/pause_all_test.rs index 37cc38e70..0605891da 100644 --- a/pause-all/tests/pause_all_test.rs +++ b/pause-all/tests/pause_all_test.rs @@ -1,5 +1,3 @@ -#![allow(deprecated)] - use farm::Farm; use multiversx_sc::types::{Address, ManagedAddress, MultiValueEncoded, OperationCompletionStatus}; use multiversx_sc_scenario::{ @@ -49,7 +47,6 @@ fn pause_all_test() { managed_token_id!(REWARD_TOKEN_ID), managed_token_id!(FARMING_TOKEN_ID), managed_biguint!(DIV_SAFETY), - managed_address!(pair_sc.address_ref()), ManagedAddress::::zero(), MultiValueEncoded::new(), );