diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index c5fdba201..f6acbaa50 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -4,7 +4,6 @@ on: push: branches: [ main, feat/* ] pull_request: - branches: [ main, feat/* ] workflow_dispatch: permissions: diff --git a/common/modules/farm/config/src/config.rs b/common/modules/farm/config/src/config.rs index c7768500f..e65056062 100644 --- a/common/modules/farm/config/src/config.rs +++ b/common/modules/farm/config/src/config.rs @@ -7,6 +7,7 @@ use common_structs::Nonce; use pausable::State; pub const DEFAULT_NFT_DEPOSIT_MAX_LEN: usize = 10; +pub const DEFAULT_FARM_POSITION_MIGRATION_NONCE: u64 = 1; #[derive( ManagedVecItem, @@ -19,30 +20,74 @@ pub const DEFAULT_NFT_DEPOSIT_MAX_LEN: usize = 10; PartialEq, Debug, )] -pub struct UserTotalFarmPositionStruct { +pub struct UserTotalFarmPosition { pub total_farm_position: BigUint, pub allow_external_claim_boosted_rewards: bool, } +impl Default for UserTotalFarmPosition { + fn default() -> Self { + Self { + total_farm_position: BigUint::zero(), + allow_external_claim_boosted_rewards: false, + } + } +} + #[multiversx_sc::module] pub trait ConfigModule: pausable::PausableModule + permissions_module::PermissionsModule { + #[endpoint(allowExternalClaimBoostedRewards)] + fn allow_external_claim_boosted_rewards(&self, allow_external_claim: bool) { + let caller = self.blockchain().get_caller(); + let mut user_total_farm_position = self.get_user_total_farm_position(&caller); + user_total_farm_position.allow_external_claim_boosted_rewards = allow_external_claim; + self.user_total_farm_position(&caller) + .set(user_total_farm_position); + } + #[inline] fn is_active(&self) -> bool { let state = self.state().get(); state == State::Active } - fn get_user_total_farm_position_struct( + fn get_user_total_farm_position( &self, user: &ManagedAddress, - ) -> UserTotalFarmPositionStruct { - self.user_total_farm_position(user) - .set_if_empty(UserTotalFarmPositionStruct { - total_farm_position: BigUint::zero(), - allow_external_claim_boosted_rewards: false, - }); - - self.user_total_farm_position(user).get() + ) -> UserTotalFarmPosition { + let user_total_farm_position_mapper = self.user_total_farm_position(user); + if user_total_farm_position_mapper.is_empty() { + UserTotalFarmPosition::default() + } else { + user_total_farm_position_mapper.get() + } + } + + fn is_old_farm_position(&self, token_nonce: Nonce) -> bool { + let farm_position_migration_nonce = self.farm_position_migration_nonce().get(); + token_nonce > 0 && token_nonce < farm_position_migration_nonce + } + + fn try_set_farm_position_migration_nonce( + &self, + farm_token_mapper: NonFungibleTokenMapper, + ) { + if !self.farm_position_migration_nonce().is_empty() { + return; + } + + let migration_farm_token_nonce = if farm_token_mapper.get_token_state().is_set() { + let token_identifier = farm_token_mapper.get_token_id_ref(); + let current_nonce = self + .blockchain() + .get_current_esdt_nft_nonce(&self.blockchain().get_sc_address(), token_identifier); + current_nonce + DEFAULT_FARM_POSITION_MIGRATION_NONCE + } else { + DEFAULT_FARM_POSITION_MIGRATION_NONCE + }; + + self.farm_position_migration_nonce() + .set(migration_farm_token_nonce); } #[view(getFarmingTokenId)] @@ -73,5 +118,9 @@ pub trait ConfigModule: pausable::PausableModule + permissions_module::Permissio fn user_total_farm_position( &self, user: &ManagedAddress, - ) -> SingleValueMapper>; + ) -> SingleValueMapper>; + + #[view(getFarmPositionMigrationNonce)] + #[storage_mapper("farm_position_migration_nonce")] + fn farm_position_migration_nonce(&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 964c014fe..f2ccc293c 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 @@ -195,27 +195,21 @@ pub trait FarmContract { farm_positions: &PaymentsVec<::Api>, ) { let farm_token_mapper = sc.farm_token(); - let mut total_farm_position = BigUint::zero(); - let mut farm_position_increase = BigUint::zero(); for farm_position in farm_positions { farm_token_mapper.require_same_token(&farm_position.token_identifier); - total_farm_position += &farm_position.amount; + 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); - farm_position_increase += &farm_position.amount; + Self::increase_user_farm_position(sc, user, &farm_position.amount); } } - - let user_total_farm_position_struct = sc.get_user_total_farm_position_struct(user); - if user_total_farm_position_struct.total_farm_position == BigUint::zero() { - Self::increase_user_farm_position(sc, user, &total_farm_position); - } else if farm_position_increase > 0 { - Self::increase_user_farm_position(sc, user, &farm_position_increase); - } } #[inline] @@ -224,30 +218,31 @@ pub trait FarmContract { user: &ManagedAddress<::Api>, increase_farm_position_amount: &BigUint<::Api>, ) { + let mut user_total_farm_position = sc.get_user_total_farm_position(user); + user_total_farm_position.total_farm_position += increase_farm_position_amount; sc.user_total_farm_position(user) - .update(|user_farm_position_struct| { - user_farm_position_struct.total_farm_position += increase_farm_position_amount - }); + .set(user_total_farm_position); } 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); sc.user_total_farm_position(&token_attributes.original_owner) - .update(|user_farm_position_struct| { - let mut user_total_farm_position = - user_farm_position_struct.total_farm_position.clone(); - if user_total_farm_position > farm_position.amount { - user_total_farm_position -= &farm_position.amount; + .update(|user_total_farm_position| { + if user_total_farm_position.total_farm_position > farm_position.amount { + user_total_farm_position.total_farm_position -= &farm_position.amount; } else { - user_total_farm_position = BigUint::zero(); + user_total_farm_position.total_farm_position = BigUint::zero(); } - user_farm_position_struct.total_farm_position = user_total_farm_position; }); } } 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 85b0e7ef6..d9dfe293e 100644 --- a/common/modules/farm/farm_base_impl/src/claim_rewards.rs +++ b/common/modules/farm/farm_base_impl/src/claim_rewards.rs @@ -63,8 +63,6 @@ pub trait BaseClaimRewardsModule: self.blockchain(), ); - FC::check_and_update_user_farm_position(self, &caller, &payments); - FC::generate_aggregated_rewards(self, &mut storage_cache); let farm_token_amount = &claim_rewards_context.first_farm_token.payment.amount; @@ -83,6 +81,8 @@ pub trait BaseClaimRewardsModule: ); storage_cache.reward_reserve -= &reward; + FC::check_and_update_user_farm_position(self, &caller, &payments); + let farm_token_mapper = self.farm_token(); let base_attributes = FC::create_claim_rewards_initial_attributes( self, 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 74a5f74d6..06e52585c 100644 --- a/common/modules/farm/farm_base_impl/src/compound_rewards.rs +++ b/common/modules/farm/farm_base_impl/src/compound_rewards.rs @@ -51,7 +51,6 @@ pub trait BaseCompoundRewardsModule: self.blockchain(), ); - FC::check_and_update_user_farm_position(self, &caller, &payments); FC::generate_aggregated_rewards(self, &mut storage_cache); let farm_token_amount = &compound_rewards_context.first_farm_token.payment.amount; @@ -71,6 +70,8 @@ pub trait BaseCompoundRewardsModule: storage_cache.reward_reserve -= &reward; storage_cache.farm_token_supply += &reward; + FC::check_and_update_user_farm_position(self, &caller, &payments); + let farm_token_mapper = self.farm_token(); let base_attributes = FC::create_compound_rewards_initial_attributes( self, 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 eefe7c65f..315abe421 100644 --- a/common/modules/farm/farm_base_impl/src/exit_farm.rs +++ b/common/modules/farm/farm_base_impl/src/exit_farm.rs @@ -44,8 +44,6 @@ pub trait BaseExitFarmModule: self.blockchain(), ); - FC::decrease_user_farm_position(self, &payment); - FC::generate_aggregated_rewards(self, &mut storage_cache); let farm_token_amount = &exit_farm_context.farm_token.payment.amount; @@ -64,6 +62,8 @@ pub trait BaseExitFarmModule: ); storage_cache.reward_reserve -= &reward; + FC::decrease_user_farm_position(self, &payment); + let farming_token_amount = token_attributes.get_total_supply(); let farming_token_payment = EsdtTokenPayment::new( storage_cache.farming_token_id.clone(), diff --git a/dex/farm-with-locked-rewards/src/lib.rs b/dex/farm-with-locked-rewards/src/lib.rs index 948ed0739..27421ac16 100644 --- a/dex/farm-with-locked-rewards/src/lib.rs +++ b/dex/farm-with-locked-rewards/src/lib.rs @@ -8,10 +8,9 @@ multiversx_sc::derive_imports!(); use common_structs::FarmTokenAttributes; use contexts::storage_cache::StorageCache; use core::marker::PhantomData; -use mergeable::Mergeable; use farm::{ - base_functions::{BaseFunctionsModule, ClaimRewardsResultType, Wrapper}, + base_functions::{BaseFunctionsModule, ClaimRewardsResultType, DoubleMultiPayment, Wrapper}, exit_penalty::{ DEFAULT_BURN_GAS_LIMIT, DEFAULT_MINUMUM_FARMING_EPOCHS, DEFAULT_PENALTY_PERCENT, }, @@ -34,8 +33,6 @@ pub trait Farm: + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + farm::base_functions::BaseFunctionsModule + farm::exit_penalty::ExitPenaltyModule - + farm::progress_update::ProgressUpdateModule - + farm::claim_boost_only::ClaimBoostOnlyModule + farm_base_impl::base_farm_init::BaseFarmInitModule + farm_base_impl::base_farm_validation::BaseFarmValidationModule + farm_base_impl::enter_farm::BaseEnterFarmModule @@ -78,6 +75,10 @@ pub trait Farm: 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); } #[payable("*")] @@ -89,19 +90,17 @@ pub trait Farm: let caller = self.blockchain().get_caller(); let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller); - let payments = self.get_non_empty_payments(); - let first_additional_payment_index = 1; - let boosted_rewards = match payments.try_get(first_additional_payment_index) { - Some(p) => { - let unlocked_rewards = self.claim_only_boosted_payment(&orig_caller, &p); - self.send_to_lock_contract_non_zero( - unlocked_rewards.token_identifier, - unlocked_rewards.amount, - caller.clone(), - orig_caller.clone(), - ) - } - None => EsdtTokenPayment::new(self.reward_token_id().get(), 0, BigUint::zero()), + self.migrate_old_farm_positions(&orig_caller); + let boosted_rewards = self.claim_only_boosted_payment(&orig_caller); + let boosted_rewards_payment = if boosted_rewards > 0 { + self.send_to_lock_contract_non_zero( + self.reward_token_id().get(), + boosted_rewards, + caller.clone(), + orig_caller.clone(), + ) + } else { + EsdtTokenPayment::new(self.reward_token_id().get(), 0, BigUint::zero()) }; let new_farm_token = self.enter_farm::>(orig_caller.clone()); @@ -109,7 +108,7 @@ pub trait Farm: self.update_energy_and_progress(&orig_caller); - (new_farm_token, boosted_rewards).into() + (new_farm_token, boosted_rewards_payment).into() } #[payable("*")] @@ -121,6 +120,8 @@ pub trait Farm: 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 payments = self.call_value().all_esdt_transfers().clone_value(); let base_claim_rewards_result = self.claim_rewards_base::>(orig_caller.clone(), payments); @@ -151,33 +152,21 @@ pub trait Farm: #[endpoint(exitFarm)] fn exit_farm_endpoint( &self, - exit_amount: BigUint, opt_orig_caller: OptionalValue, ) -> ExitFarmWithPartialPosResultType { let caller = self.blockchain().get_caller(); let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller); - let mut payment = self.call_value().single_esdt(); - require!( - payment.amount >= exit_amount, - "Exit amount is bigger than the payment amount" - ); + let payment = self.call_value().single_esdt(); - let boosted_rewards_full_position = self.claim_only_boosted_payment(&orig_caller, &payment); - let remaining_farm_payment = EsdtTokenPayment::new( - payment.token_identifier.clone(), - payment.token_nonce, - &payment.amount - &exit_amount, - ); - - payment.amount = exit_amount; + let migrated_amount = self.migrate_old_farm_positions(&orig_caller); let exit_farm_result = self.exit_farm::>(orig_caller.clone(), payment); - let mut rewards = exit_farm_result.rewards; - rewards.merge_with(boosted_rewards_full_position); + self.decrease_old_farm_positions(migrated_amount, &orig_caller); + + let rewards = exit_farm_result.rewards; self.send_payment_non_zero(&caller, &exit_farm_result.farming_tokens); - self.send_payment_non_zero(&caller, &remaining_farm_payment); let locked_rewards_payment = self.send_to_lock_contract_non_zero( rewards.token_identifier.clone(), @@ -186,35 +175,9 @@ pub trait Farm: orig_caller.clone(), ); - self.clear_user_energy_if_needed(&orig_caller, &remaining_farm_payment.amount); + self.clear_user_energy_if_needed(&orig_caller); - ( - exit_farm_result.farming_tokens, - locked_rewards_payment, - remaining_farm_payment, - ) - .into() - } - - #[view(calculateRewardsForGivenPosition)] - fn calculate_rewards_for_given_position( - &self, - user: ManagedAddress, - farm_token_amount: BigUint, - attributes: FarmTokenAttributes, - ) -> BigUint { - self.require_queried(); - - let mut storage_cache = StorageCache::new(self); - NoMintWrapper::::generate_aggregated_rewards(self, &mut storage_cache); - - NoMintWrapper::::calculate_rewards( - self, - &user, - &farm_token_amount, - &attributes, - &storage_cache, - ) + (exit_farm_result.farming_tokens, locked_rewards_payment).into() } #[payable("*")] @@ -222,15 +185,51 @@ pub trait Farm: fn merge_farm_tokens_endpoint( &self, opt_orig_caller: OptionalValue, - ) -> EsdtTokenPayment { + ) -> DoubleMultiPayment { let caller = self.blockchain().get_caller(); let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller); - self.check_claim_progress_for_merge(&orig_caller); + + self.migrate_old_farm_positions(&orig_caller); + let boosted_rewards = self.claim_only_boosted_payment(&orig_caller); let merged_farm_token = self.merge_farm_tokens::>(); + 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, + caller, + orig_caller, + ); + + (merged_farm_token, locked_rewards_payment).into() + } + + #[endpoint(claimBoostedRewards)] + fn claim_boosted_rewards( + &self, + opt_user: OptionalValue, + ) -> EsdtTokenPayment { + let caller = self.blockchain().get_caller(); + let user = match &opt_user { + OptionalValue::Some(user) => user, + OptionalValue::None => &caller, + }; + let user_total_farm_position = self.get_user_total_farm_position(user); + if user != &caller { + require!( + user_total_farm_position.allow_external_claim_boosted_rewards, + "Cannot claim rewards for this address" + ); + } - merged_farm_token + let boosted_rewards = self.claim_only_boosted_payment(user); + self.send_to_lock_contract_non_zero( + self.reward_token_id().get(), + boosted_rewards, + user.clone(), + user.clone(), + ) } #[endpoint(startProduceRewards)] @@ -251,6 +250,27 @@ pub trait Farm: self.set_per_block_rewards::>(per_block_amount); } + #[view(calculateRewardsForGivenPosition)] + fn calculate_rewards_for_given_position( + &self, + user: ManagedAddress, + farm_token_amount: BigUint, + attributes: FarmTokenAttributes, + ) -> BigUint { + self.require_queried(); + + let mut storage_cache = StorageCache::new(self); + NoMintWrapper::::generate_aggregated_rewards(self, &mut storage_cache); + + NoMintWrapper::::calculate_rewards( + self, + &user, + &farm_token_amount, + &attributes, + &storage_cache, + ) + } + fn send_to_lock_contract_non_zero( &self, token_id: TokenIdentifier, 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 f795108e6..f8858aaf8 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 @@ -413,25 +413,16 @@ where result } - pub fn exit_farm( - &mut self, - user: &Address, - farm_token_nonce: u64, - farm_token_amount: u64, - exit_farm_amount: u64, - ) { + pub fn exit_farm(&mut self, user: &Address, farm_token_nonce: u64, exit_farm_amount: u64) { self.b_mock .execute_esdt_transfer( user, &self.farm_wrapper, FARM_TOKEN_ID, farm_token_nonce, - &rust_biguint!(farm_token_amount), + &rust_biguint!(exit_farm_amount), |sc| { - let _ = sc.exit_farm_endpoint( - managed_biguint!(exit_farm_amount), - OptionalValue::Some(managed_address!(user)), - ); + let _ = sc.exit_farm_endpoint(OptionalValue::Some(managed_address!(user))); }, ) .assert_ok(); 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 db4f9e7bc..8a9fb8793 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 @@ -149,7 +149,7 @@ fn farm_with_boosted_yields_no_proxy_test() { 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, 1); + farm_setup.exit_farm(&third_user, 5, 1); // advance 1 week farm_setup.b_mock.set_block_epoch(10); @@ -228,3 +228,110 @@ fn farm_with_boosted_yields_no_proxy_test() { None, ); } + +#[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, + ); + + farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); + farm_setup.set_boosted_yields_factors(); + farm_setup.b_mock.set_block_epoch(2); + + let temp_user = farm_setup.third_user.clone(); + + // first user enter farm + let farm_in_amount = 50_000_000; + let first_user = farm_setup.first_user.clone(); + farm_setup.set_user_energy(&first_user, 1_000, 2, 1); + farm_setup.enter_farm(&first_user, farm_in_amount); + farm_setup.enter_farm(&first_user, farm_in_amount); + + farm_setup.b_mock.check_nft_balance( + &first_user, + FARM_TOKEN_ID, + 1, + &rust_biguint!(farm_in_amount), + Some(&FarmTokenAttributes:: { + reward_per_share: managed_biguint!(0), + compounded_reward: managed_biguint!(0), + entering_epoch: 2, + current_farm_amount: managed_biguint!(farm_in_amount), + original_owner: managed_address!(&first_user), + }), + ); + + farm_setup.b_mock.check_nft_balance( + &first_user, + FARM_TOKEN_ID, + 2, + &rust_biguint!(farm_in_amount), + Some(&FarmTokenAttributes:: { + reward_per_share: managed_biguint!(0), + compounded_reward: managed_biguint!(0), + entering_epoch: 2, + current_farm_amount: managed_biguint!(farm_in_amount), + original_owner: managed_address!(&first_user), + }), + ); + + // users claim rewards to get their energy registered + let _ = farm_setup.claim_rewards(&first_user, 1, farm_in_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.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); + farm_setup.exit_farm(&temp_user, 4, 1); + + // advance 1 week + farm_setup.b_mock.set_block_epoch(10); + farm_setup.set_user_energy(&first_user, 1_000, 10, 1); + + let total_farm_tokens = farm_in_amount * 2; + + // first user claim with half total position + let first_base_farm_amt = farm_in_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) + // (2_500 * 3 * 1_000 / 1_000 + 2_500 * 2 * 100_000_000 / 100_000_000) / (3 + 2) + // (7_500 + 2_500) / (5) = 2_500 + let first_boosted_amt = 2_500; // 1000 energy & 100_000_000 farm tokens + let first_total_rewards = first_base_farm_amt + first_boosted_amt; + + let first_received_reward_amt = farm_setup.claim_rewards(&first_user, 3, farm_in_amount); + + // Should be equal to half base generated rewards + full boosted generated rewards + assert_eq!(first_received_reward_amt, first_total_rewards); + + farm_setup + .b_mock + .check_nft_balance::>( + &first_user, + FARM_TOKEN_ID, + 5, + &rust_biguint!(farm_in_amount), + None, + ); + + // Check user receive locked rewards + farm_setup + .b_mock + .check_nft_balance::>( + &first_user, + LOCKED_REWARD_TOKEN_ID, + 1, + &rust_biguint!(first_received_reward_amt), + None, + ); +} diff --git a/dex/farm-with-locked-rewards/wasm/Cargo.lock b/dex/farm-with-locked-rewards/wasm/Cargo.lock index 83649b5f2..edf24d617 100644 --- a/dex/farm-with-locked-rewards/wasm/Cargo.lock +++ b/dex/farm-with-locked-rewards/wasm/Cargo.lock @@ -8,7 +8,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "once_cell", "version_check", ] @@ -31,12 +31,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -322,12 +316,6 @@ dependencies = [ "utils", ] -[[package]] -name = "libc" -version = "0.2.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" - [[package]] name = "locking_module" version = "0.0.0" @@ -344,12 +332,6 @@ dependencies = [ "multiversx-sc", ] -[[package]] -name = "memory_units" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" - [[package]] name = "mergeable" version = "0.0.0" @@ -359,9 +341,9 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecfb3e03ac6e08114963a54e15a3c78c28e57cc0e31836e870450b35085bdf8d" +checksum = "386c2727eba66bc5e502e470d7afa55fdd69aedff440c508bb9ba85aec36a52a" dependencies = [ "bitflags", "hashbrown", @@ -373,20 +355,19 @@ dependencies = [ [[package]] name = "multiversx-sc-codec" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7638cb46a0e99c636fd55443ac534ff0a5fad0bd772e1037fbac9a75e04c3c9" +checksum = "0f1e15b46c17b87c0c7cdd79b041a4abd7f3a2b45f3c993f6ce38c0f233e82b6" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", - "wee_alloc", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e976002d51367f16140929c10ee695f95dd8d34c150a45db60d3fcd1328a267a" +checksum = "9a7bc0762cd6d88f8bc54805bc652b042a61cd7fbc2d0a325010f088b78fb2ac" dependencies = [ "hex", "proc-macro2", @@ -396,9 +377,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6eb54a7d452eb09f5de159ee9b4d1fb9ec79cf49f1602ebd3efc8532015a4ea" +checksum = "050510b6b9836b24b4a73bb7878c58c268d56bde1c6eb0f9a88dce9a6518507b" dependencies = [ "hex", "proc-macro2", @@ -409,21 +390,20 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12284a3e31c0852b6ca0ce8306d3f404c3712b996a05ed78e97e765c98461f3" +checksum = "3b55fe3585cbc745bd7b9793be4bcb3aa7f1869ced7a0981f3d47e6a832c6311" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee69fa831cdd5a7ea1aedbb6356a55792b821396f48360a6194f4131eddd1045" +checksum = "b059f22dfc3eb45aa015f6f20f28ed34dc42a65b42d282f8ac9b799b12e2942c" dependencies = [ "multiversx-sc", - "wee_alloc", ] [[package]] @@ -484,9 +464,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -605,18 +585,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wee_alloc" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "memory_units", - "winapi", -] - [[package]] name = "week-timekeeping" version = "0.0.0" @@ -636,25 +604,3 @@ dependencies = [ "unwrappable", "week-timekeeping", ] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/dex/farm-with-locked-rewards/wasm/src/lib.rs b/dex/farm-with-locked-rewards/wasm/src/lib.rs index a124d3269..64c73e3cc 100644 --- a/dex/farm-with-locked-rewards/wasm/src/lib.rs +++ b/dex/farm-with-locked-rewards/wasm/src/lib.rs @@ -5,12 +5,15 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 64 +// Endpoints: 66 // Async Callback: 1 -// Total number of exported functions: 66 +// Total number of exported functions: 68 #![no_std] -#![feature(alloc_error_handler, lang_items)] + +// Configuration that works with rustc < 1.73.0. +// TODO: Recommended rustc version: 1.73.0 or newer. +#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -18,70 +21,74 @@ multiversx_sc_wasm_adapter::panic_handler!(); multiversx_sc_wasm_adapter::endpoints! { farm_with_locked_rewards ( - enterFarm - claimRewards - exitFarm - calculateRewardsForGivenPosition - mergeFarmTokens - startProduceRewards - endProduceRewards - setPerBlockRewardAmount - getRewardPerShare - getRewardReserve - getFarmingTokenId - getRewardTokenId - getPerBlockRewardAmount - getLastRewardBlockNonce - getDivisionSafetyConstant - getUserTotalFarmPosition - setLockingScAddress - setLockEpochs - getLockingScAddress - getLockEpochs - registerFarmToken - getFarmTokenId - getFarmTokenSupply - addToPauseWhitelist - removeFromPauseWhitelist - pause - resume - getState - addAdmin - removeAdmin - updateOwnerOrAdmin - getPermissions - addSCAddressToWhitelist - removeSCAddressFromWhitelist - isSCAddressWhitelisted - set_penalty_percent - set_minimum_farming_epochs - set_burn_gas_limit - getPenaltyPercent - getMinimumFarmingEpoch - getBurnGasLimit - getPairContractManagedAddress - claimBoostedRewards - setBoostedYieldsRewardsPercentage - collectUndistributedBoostedRewards - getBoostedYieldsRewardsPercentage - getAccumulatedRewardsForWeek - getFarmSupplyForWeek - getRemainingBoostedRewardsToDistribute - getUndistributedBoostedRewards - setBoostedYieldsFactors - getBoostedYieldsFactors - getCurrentWeek - getFirstWeekStartEpoch - getLastActiveWeekForUser - getUserEnergyForWeek - getLastGlobalUpdateWeek - getTotalRewardsForWeek - getTotalEnergyForWeek - getTotalLockedTokensForWeek - updateEnergyForUser - getCurrentClaimProgress - setEnergyFactoryAddress - getEnergyFactoryAddress - callBack + init => init + enterFarm => enter_farm_endpoint + claimRewards => claim_rewards_endpoint + exitFarm => exit_farm_endpoint + mergeFarmTokens => merge_farm_tokens_endpoint + claimBoostedRewards => claim_boosted_rewards + startProduceRewards => start_produce_rewards_endpoint + endProduceRewards => end_produce_rewards_endpoint + setPerBlockRewardAmount => set_per_block_rewards_endpoint + calculateRewardsForGivenPosition => calculate_rewards_for_given_position + getRewardPerShare => reward_per_share + getRewardReserve => reward_reserve + allowExternalClaimBoostedRewards => allow_external_claim_boosted_rewards + getFarmingTokenId => farming_token_id + getRewardTokenId => reward_token_id + getPerBlockRewardAmount => per_block_reward_amount + getLastRewardBlockNonce => last_reward_block_nonce + getDivisionSafetyConstant => division_safety_constant + getUserTotalFarmPosition => user_total_farm_position + getFarmPositionMigrationNonce => farm_position_migration_nonce + setLockingScAddress => set_locking_sc_address + setLockEpochs => set_lock_epochs + getLockingScAddress => locking_sc_address + getLockEpochs => lock_epochs + registerFarmToken => register_farm_token + getFarmTokenId => farm_token + getFarmTokenSupply => farm_token_supply + addToPauseWhitelist => add_to_pause_whitelist + removeFromPauseWhitelist => remove_from_pause_whitelist + pause => pause + resume => resume + getState => state + addAdmin => add_admin_endpoint + removeAdmin => remove_admin_endpoint + updateOwnerOrAdmin => update_owner_or_admin_endpoint + getPermissions => permissions + 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 + setBoostedYieldsRewardsPercentage => set_boosted_yields_rewards_percentage + 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 + getUserEnergyForWeek => get_user_energy_for_week_view + getLastGlobalUpdateWeek => last_global_update_week + getTotalRewardsForWeek => total_rewards_for_week + getTotalEnergyForWeek => total_energy_for_week + getTotalLockedTokensForWeek => total_locked_tokens_for_week + updateEnergyForUser => update_energy_for_user + getCurrentClaimProgress => current_claim_progress + setEnergyFactoryAddress => set_energy_factory_address + getEnergyFactoryAddress => energy_factory_address ) } + +multiversx_sc_wasm_adapter::async_callback! { farm_with_locked_rewards } diff --git a/dex/farm/src/base_functions.rs b/dex/farm/src/base_functions.rs index 38fd37014..968e3381d 100644 --- a/dex/farm/src/base_functions.rs +++ b/dex/farm/src/base_functions.rs @@ -19,6 +19,8 @@ pub type DoubleMultiPayment = MultiValue2, EsdtTokenPayme pub type ClaimRewardsResultType = DoubleMultiPayment; pub type ExitFarmResultType = DoubleMultiPayment; +pub const DEFAULT_FARM_POSITION_MIGRATION_NONCE: u64 = 1; + pub struct ClaimRewardsResultWrapper { pub new_farm_token: EsdtTokenPayment, pub rewards: EsdtTokenPayment, @@ -195,6 +197,48 @@ pub trait BaseFunctionsModule: token_mapper.nft_create(new_token_amount, &output_attributes) } + fn claim_only_boosted_payment(&self, caller: &ManagedAddress) -> BigUint { + let reward = Wrapper::::calculate_boosted_rewards(self, caller); + if reward > 0 { + self.reward_reserve().update(|reserve| *reserve -= &reward); + } + + reward + } + + fn migrate_old_farm_positions(&self, caller: &ManagedAddress) -> BigUint { + let payments = self.get_non_empty_payments(); + let farm_token_mapper = self.farm_token(); + let farm_token_id = farm_token_mapper.get_token_id(); + let mut migrated_amount = BigUint::zero(); + for farm_position in &payments { + if farm_position.token_identifier == farm_token_id + && self.is_old_farm_position(farm_position.token_nonce) + { + migrated_amount += farm_position.amount; + } + } + + if migrated_amount > 0 { + let mut user_total_farm_position = self.get_user_total_farm_position(caller); + user_total_farm_position.total_farm_position += &migrated_amount; + self.user_total_farm_position(caller) + .set(user_total_farm_position); + } + + migrated_amount + } + + fn decrease_old_farm_positions(&self, migrated_amount: BigUint, caller: &ManagedAddress) { + if migrated_amount == BigUint::zero() { + return; + } + self.user_total_farm_position(caller) + .update(|user_total_farm_position| { + user_total_farm_position.total_farm_position -= migrated_amount; + }); + } + fn end_produce_rewards>(&self) { let mut storage = StorageCache::new(self); FC::generate_aggregated_rewards(self, &mut storage); @@ -238,22 +282,11 @@ where pub fn calculate_boosted_rewards( sc: &::FarmSc, caller: &ManagedAddress<<::FarmSc as ContractBase>::Api>, - token_attributes: &::AttributesType, ) -> BigUint<<::FarmSc as ContractBase>::Api> { - let original_owner = &token_attributes.original_owner; - - if original_owner != caller { - sc.update_energy_and_progress(caller); - } - - let user_total_farm_position_struct = - sc.get_user_total_farm_position_struct(original_owner); - let user_total_farm_position = user_total_farm_position_struct.total_farm_position; - if user_total_farm_position == BigUint::zero() { - return BigUint::zero(); - } + let user_total_farm_position = sc.get_user_total_farm_position(caller); + let user_farm_position = user_total_farm_position.total_farm_position; - sc.claim_boosted_yields_rewards(caller, user_total_farm_position) + sc.claim_boosted_yields_rewards(caller, user_farm_position) } } @@ -297,7 +330,7 @@ where token_attributes, storage_cache, ); - let boosted_yield_rewards = Self::calculate_boosted_rewards(sc, caller, token_attributes); + let boosted_yield_rewards = Self::calculate_boosted_rewards(sc, caller); base_farm_reward + boosted_yield_rewards } diff --git a/dex/farm/src/claim_boost_only.rs b/dex/farm/src/claim_boost_only.rs deleted file mode 100644 index 82a2d4ffc..000000000 --- a/dex/farm/src/claim_boost_only.rs +++ /dev/null @@ -1,90 +0,0 @@ -multiversx_sc::imports!(); - -use crate::base_functions::Wrapper; - -#[multiversx_sc::module] -pub trait ClaimBoostOnlyModule: - config::ConfigModule - + rewards::RewardsModule - + farm_token::FarmTokenModule - + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule - + 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 - + token_send::TokenSendModule - + events::EventsModule - + crate::exit_penalty::ExitPenaltyModule - + farm_base_impl::base_farm_init::BaseFarmInitModule - + farm_base_impl::base_farm_validation::BaseFarmValidationModule - + farm_base_impl::enter_farm::BaseEnterFarmModule - + farm_base_impl::claim_rewards::BaseClaimRewardsModule - + farm_base_impl::compound_rewards::BaseCompoundRewardsModule - + farm_base_impl::exit_farm::BaseExitFarmModule - + utils::UtilsModule - + farm_boosted_yields::FarmBoostedYieldsModule - + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule - + crate::base_functions::BaseFunctionsModule -{ - #[payable("*")] - #[endpoint(claimBoostedRewards)] - fn claim_boosted_rewards( - &self, - opt_user: OptionalValue, - ) -> EsdtTokenPayment { - let caller = self.blockchain().get_caller(); - let user = match &opt_user { - OptionalValue::Some(user) => user, - OptionalValue::None => &caller, - }; - let user_total_farm_position_struct = self.get_user_total_farm_position_struct(user); - if user != &caller { - require!( - user_total_farm_position_struct.allow_external_claim_boosted_rewards, - "Cannot claim rewards for this address" - ); - } - - let reward_token_id = self.reward_token_id().get(); - let user_total_farm_position = user_total_farm_position_struct.total_farm_position; - if user_total_farm_position == BigUint::zero() { - return EsdtTokenPayment::new(reward_token_id, 0, BigUint::zero()); - } - - let reward = self.claim_boosted_yields_rewards(user, user_total_farm_position); - if reward > 0 { - self.reward_reserve().update(|reserve| *reserve -= &reward); - } - - let boosted_rewards = EsdtTokenPayment::new(reward_token_id, 0, reward); - self.send_payment_non_zero(user, &boosted_rewards); - - self.update_energy_and_progress(user); - - boosted_rewards - } - - fn claim_only_boosted_payment( - &self, - caller: &ManagedAddress, - payment: &EsdtTokenPayment, - ) -> EsdtTokenPayment { - let farm_token_mapper = self.farm_token(); - farm_token_mapper.require_same_token(&payment.token_identifier); - - let token_attributes = - self.get_attributes_as_part_of_fixed_supply(payment, &farm_token_mapper); - let reward = Wrapper::::calculate_boosted_rewards(self, caller, &token_attributes); - if reward > 0 { - self.reward_reserve().update(|reserve| *reserve -= &reward); - } - - let reward_token_id = self.reward_token_id().get(); - EsdtTokenPayment::new(reward_token_id, 0, reward) - } -} diff --git a/dex/farm/src/lib.rs b/dex/farm/src/lib.rs index cf53e0b68..5a18d41e3 100644 --- a/dex/farm/src/lib.rs +++ b/dex/farm/src/lib.rs @@ -6,9 +6,7 @@ multiversx_sc::imports!(); multiversx_sc::derive_imports!(); pub mod base_functions; -pub mod claim_boost_only; pub mod exit_penalty; -pub mod progress_update; use base_functions::{ClaimRewardsResultType, DoubleMultiPayment, Wrapper}; use common_structs::FarmTokenAttributes; @@ -18,11 +16,9 @@ use exit_penalty::{ DEFAULT_BURN_GAS_LIMIT, DEFAULT_MINUMUM_FARMING_EPOCHS, DEFAULT_PENALTY_PERCENT, }; use farm_base_impl::base_traits_impl::FarmContract; -use mergeable::Mergeable; pub type EnterFarmResultType = DoubleMultiPayment; -pub type ExitFarmWithPartialPosResultType = - MultiValue3, EsdtTokenPayment, EsdtTokenPayment>; +pub type ExitFarmWithPartialPosResultType = DoubleMultiPayment; #[multiversx_sc::contract] pub trait Farm: @@ -37,8 +33,6 @@ pub trait Farm: + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + base_functions::BaseFunctionsModule + exit_penalty::ExitPenaltyModule - + progress_update::ProgressUpdateModule - + claim_boost_only::ClaimBoostOnlyModule + farm_base_impl::base_farm_init::BaseFarmInitModule + farm_base_impl::base_farm_validation::BaseFarmValidationModule + farm_base_impl::enter_farm::BaseEnterFarmModule @@ -82,6 +76,10 @@ pub trait Farm: 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); } #[payable("*")] @@ -93,20 +91,21 @@ pub trait Farm: let caller = self.blockchain().get_caller(); let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller); - let payments = self.get_non_empty_payments(); - let first_additional_payment_index = 1; - let boosted_rewards = match payments.try_get(first_additional_payment_index) { - Some(p) => self.claim_only_boosted_payment(&orig_caller, &p), - None => EsdtTokenPayment::new(self.reward_token_id().get(), 0, BigUint::zero()), + self.migrate_old_farm_positions(&orig_caller); + let boosted_rewards = self.claim_only_boosted_payment(&orig_caller); + let boosted_rewards_payment = if boosted_rewards > 0 { + EsdtTokenPayment::new(self.reward_token_id().get(), 0, boosted_rewards) + } else { + EsdtTokenPayment::new(self.reward_token_id().get(), 0, BigUint::zero()) }; 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); + self.send_payment_non_zero(&caller, &boosted_rewards_payment); self.update_energy_and_progress(&orig_caller); - (new_farm_token, boosted_rewards).into() + (new_farm_token, boosted_rewards_payment).into() } #[payable("*")] @@ -118,13 +117,13 @@ pub trait Farm: 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); self.send_payment_non_zero(&caller, &claim_rewards_result.rewards); - self.update_energy_and_progress(&orig_caller); - claim_rewards_result.into() } @@ -137,6 +136,8 @@ pub trait Farm: 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 output_farm_token_payment = self.compound_rewards::>(orig_caller.clone()); self.send_payment_non_zero(&caller, &output_farm_token_payment); @@ -150,65 +151,25 @@ pub trait Farm: #[endpoint(exitFarm)] fn exit_farm_endpoint( &self, - exit_amount: BigUint, opt_orig_caller: OptionalValue, ) -> ExitFarmWithPartialPosResultType { let caller = self.blockchain().get_caller(); let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller); - let mut payment = self.call_value().single_esdt(); - require!( - payment.amount >= exit_amount, - "Exit amount is bigger than the payment amount" - ); + let payment = self.call_value().single_esdt(); - let boosted_rewards_full_position = self.claim_only_boosted_payment(&orig_caller, &payment); - let remaining_farm_payment = EsdtTokenPayment::new( - payment.token_identifier.clone(), - payment.token_nonce, - &payment.amount - &exit_amount, - ); + let migrated_amount = self.migrate_old_farm_positions(&orig_caller); - payment.amount = exit_amount; + let exit_farm_result = self.exit_farm::>(orig_caller.clone(), payment); - let mut exit_farm_result = self.exit_farm::>(orig_caller.clone(), payment); - exit_farm_result - .rewards - .merge_with(boosted_rewards_full_position); + 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.send_payment_non_zero(&caller, &remaining_farm_payment); - self.clear_user_energy_if_needed(&orig_caller, &remaining_farm_payment.amount); + self.clear_user_energy_if_needed(&orig_caller); - ( - exit_farm_result.farming_tokens, - exit_farm_result.rewards, - remaining_farm_payment, - ) - .into() - } - - #[view(calculateRewardsForGivenPosition)] - fn calculate_rewards_for_given_position( - &self, - user: ManagedAddress, - farm_token_amount: BigUint, - attributes: FarmTokenAttributes, - ) -> BigUint { - self.require_queried(); - - let mut storage_cache = StorageCache::new(self); - Wrapper::::generate_aggregated_rewards(self, &mut storage_cache); - - Wrapper::::calculate_rewards( - self, - &user, - &farm_token_amount, - &attributes, - &storage_cache, - ) + (exit_farm_result.farming_tokens, exit_farm_result.rewards).into() } #[payable("*")] @@ -216,15 +177,50 @@ pub trait Farm: fn merge_farm_tokens_endpoint( &self, opt_orig_caller: OptionalValue, - ) -> EsdtTokenPayment { + ) -> DoubleMultiPayment { let caller = self.blockchain().get_caller(); let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller); - self.check_claim_progress_for_merge(&orig_caller); + self.migrate_old_farm_positions(&orig_caller); + + let boosted_rewards = self.claim_only_boosted_payment(&orig_caller); + let boosted_rewards_payment = if boosted_rewards > 0 { + EsdtTokenPayment::new(self.reward_token_id().get(), 0, boosted_rewards) + } else { + EsdtTokenPayment::new(self.reward_token_id().get(), 0, BigUint::zero()) + }; let merged_farm_token = self.merge_farm_tokens::>(); self.send_payment_non_zero(&caller, &merged_farm_token); + self.send_payment_non_zero(&caller, &boosted_rewards_payment); + + (merged_farm_token, boosted_rewards_payment).into() + } + + #[endpoint(claimBoostedRewards)] + fn claim_boosted_rewards( + &self, + opt_user: OptionalValue, + ) -> EsdtTokenPayment { + let caller = self.blockchain().get_caller(); + let user = match &opt_user { + OptionalValue::Some(user) => user, + OptionalValue::None => &caller, + }; + let user_total_farm_position = self.get_user_total_farm_position(user); + if user != &caller { + require!( + user_total_farm_position.allow_external_claim_boosted_rewards, + "Cannot claim rewards for this address" + ); + } - merged_farm_token + let boosted_rewards = self.claim_only_boosted_payment(user); + let boosted_rewards_payment = + EsdtTokenPayment::new(self.reward_token_id().get(), 0, boosted_rewards); + + self.send_payment_non_zero(user, &boosted_rewards_payment); + + boosted_rewards_payment } #[endpoint(startProduceRewards)] @@ -244,4 +240,25 @@ pub trait Farm: self.require_caller_has_admin_permissions(); self.set_per_block_rewards::>(per_block_amount); } + + #[view(calculateRewardsForGivenPosition)] + fn calculate_rewards_for_given_position( + &self, + user: ManagedAddress, + farm_token_amount: BigUint, + attributes: FarmTokenAttributes, + ) -> BigUint { + self.require_queried(); + + let mut storage_cache = StorageCache::new(self); + Wrapper::::generate_aggregated_rewards(self, &mut storage_cache); + + Wrapper::::calculate_rewards( + self, + &user, + &farm_token_amount, + &attributes, + &storage_cache, + ) + } } diff --git a/dex/farm/src/progress_update.rs b/dex/farm/src/progress_update.rs deleted file mode 100644 index 48e4b7644..000000000 --- a/dex/farm/src/progress_update.rs +++ /dev/null @@ -1,27 +0,0 @@ -multiversx_sc::imports!(); - -#[multiversx_sc::module] -pub trait ProgressUpdateModule: - week_timekeeping::WeekTimekeepingModule - + 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 -{ - fn check_claim_progress_for_merge(&self, caller: &ManagedAddress) { - let claim_progress_mapper = self.current_claim_progress(caller); - if claim_progress_mapper.is_empty() { - return; - } - - let current_week = self.get_current_week(); - let claim_progress = claim_progress_mapper.get(); - require!( - claim_progress.week == current_week, - "The user claim progress must be up to date." - ) - } -} diff --git a/dex/farm/tests/farm_multi_user_test.rs b/dex/farm/tests/farm_multi_user_test.rs index 182de5c8c..03315b184 100644 --- a/dex/farm/tests/farm_multi_user_test.rs +++ b/dex/farm/tests/farm_multi_user_test.rs @@ -149,7 +149,7 @@ fn farm_with_boosted_yields_test() { 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, 1); + farm_setup.exit_farm(&third_user, 5, 1); // advance 1 week farm_setup.b_mock.set_block_epoch(10); @@ -221,102 +221,6 @@ fn farm_with_boosted_yields_test() { ); } -#[test] -fn farm_claim_boosted_yields_for_other_user_test() { - DebugApi::dummy(); - let mut farm_setup = MultiUserFarmSetup::new( - farm::contract_obj, - energy_factory_mock::contract_obj, - energy_update::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); - - // 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.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.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.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, 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); - - // Second user claims for himself - let total_farm_tokens = first_farm_token_amount + second_farm_token_amount; - let second_base_farm_amt = second_farm_token_amount * 7_500 / total_farm_tokens; - let second_boosted_amt = 1533; // 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, - 6, - &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), - ); - - // 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 - - // Second user claim boosted rewards for first user - farm_setup.allow_external_claim_rewards(&first_user); - - let first_receveived_boosted_amt = - farm_setup.claim_boosted_rewards_for_user(&first_user, &second_user); - assert_eq!(first_receveived_boosted_amt, first_boosted_amt); - - // First user should receive the boosted rewards - farm_setup.b_mock.check_esdt_balance( - &first_user, - REWARD_TOKEN_ID, - &rust_biguint!(first_receveived_boosted_amt), - ); -} - #[test] fn farm_change_boosted_yields_factors_test() { DebugApi::dummy(); @@ -434,7 +338,7 @@ fn farm_boosted_yields_claim_with_different_user_pos_test() { 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, 1); + farm_setup.exit_farm(&third_user, 5, 1); // advance 1 week farm_setup.b_mock.set_block_epoch(10); @@ -459,11 +363,15 @@ fn farm_boosted_yields_claim_with_different_user_pos_test() { ); // second user claim with first user's pos - // user will only receive rewards for base farm, no boosted rewards + // user will receive both base and boosted rewards, as the claims uses his already saved total token amount let second_base_farm_amt = first_farm_token_amount * 7_500 / total_farm_tokens; + let second_boosted_rewards = 1_533; let second_receveived_reward_amt = farm_setup.claim_rewards(&second_user, 3, first_farm_token_amount); - assert_eq!(second_receveived_reward_amt, second_base_farm_amt); + assert_eq!( + second_receveived_reward_amt, + second_base_farm_amt + second_boosted_rewards + ); farm_setup .b_mock @@ -621,7 +529,7 @@ fn farm_multiple_claim_weeks_with_collect_undistributed_rewards_test() { 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, 1); + farm_setup.exit_farm(&third_user, 5, 1); // advance 1 week farm_setup.b_mock.set_block_epoch(10); @@ -702,7 +610,7 @@ fn farm_multiple_claim_weeks_with_collect_undistributed_rewards_test() { farm_setup.set_user_energy(&second_user, 4_000, 13, 1); farm_setup.set_user_energy(&third_user, 1, 13, 1); farm_setup.enter_farm(&third_user, 1); - farm_setup.exit_farm(&third_user, 8, 1, 1); + farm_setup.exit_farm(&third_user, 8, 1); // advance blocks - 10 blocks - 10 * 1_000 = 10_000 total rewards // 7_500 base farm, 2_500 boosted yields @@ -714,7 +622,7 @@ fn farm_multiple_claim_weeks_with_collect_undistributed_rewards_test() { farm_setup.set_user_energy(&second_user, 4_000, 20, 1); farm_setup.set_user_energy(&third_user, 1, 20, 1); farm_setup.enter_farm(&third_user, 1); - farm_setup.exit_farm(&third_user, 9, 1, 1); + farm_setup.exit_farm(&third_user, 9, 1); // advance week farm_setup.b_mock.set_block_epoch(22); @@ -871,7 +779,7 @@ fn farm_enter_with_multiple_farm_token() { 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, 1); + farm_setup.exit_farm(&third_user, 5, 1); // advance 1 week farm_setup.b_mock.set_block_epoch(10); @@ -986,7 +894,7 @@ fn farm_claim_with_minimum_tokens() { farm_setup.set_user_energy(&second_user, 90_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, 1); + farm_setup.exit_farm(&third_user, 5, 1); // advance 1 week farm_setup.b_mock.set_block_epoch(10); 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 7c610556c..4f144d8c4 100644 --- a/dex/farm/tests/farm_setup/farm_rewards_distr_setup.rs +++ b/dex/farm/tests/farm_setup/farm_rewards_distr_setup.rs @@ -185,10 +185,9 @@ where farm_token_nonce, &farm_out_amount.clone(), |sc| { - let exit_amount = to_managed_biguint(farm_out_amount); - let multi_result = sc.exit_farm_endpoint(exit_amount, OptionalValue::None); + let multi_result = sc.exit_farm_endpoint(OptionalValue::None); - let (first_result, second_result, _third_result) = multi_result.into_tuple(); + let (first_result, second_result) = multi_result.into_tuple(); assert_eq!( first_result.token_identifier, 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 9c8926160..2e74ab42c 100644 --- a/dex/farm/tests/farm_setup/multi_user_farm_setup.rs +++ b/dex/farm/tests/farm_setup/multi_user_farm_setup.rs @@ -2,8 +2,7 @@ #![allow(deprecated)] use common_structs::FarmTokenAttributes; -use config::ConfigModule; -use farm::claim_boost_only::ClaimBoostOnlyModule; +use config::{ConfigModule, UserTotalFarmPosition}; use multiversx_sc::codec::multi_types::OptionalValue; use multiversx_sc::{ storage::mappers::StorageTokenWrapper, @@ -336,7 +335,9 @@ where self.b_mock .execute_esdt_multi_transfer(user, &self.farm_wrapper, &payments, |sc| { - let out_farm_token = sc.merge_farm_tokens_endpoint(OptionalValue::None); + let (out_farm_token, _boosted_rewards) = sc + .merge_farm_tokens_endpoint(OptionalValue::None) + .into_tuple(); assert_eq!( out_farm_token.token_identifier, managed_token_id!(FARM_TOKEN_ID) @@ -471,6 +472,18 @@ where result } + pub fn claim_boosted_rewards_for_user_expect_error( + &mut self, + owner: &Address, + broker: &Address, + ) { + self.b_mock + .execute_tx(broker, &self.farm_wrapper, &rust_biguint!(0), |sc| { + let _ = sc.claim_boosted_rewards(OptionalValue::Some(managed_address!(owner))); + }) + .assert_error(4, "Cannot claim rewards for this address"); + } + pub fn claim_rewards_known_proxy( &mut self, user: &Address, @@ -514,25 +527,16 @@ where result } - pub fn exit_farm( - &mut self, - user: &Address, - farm_token_nonce: u64, - farm_token_amount: u64, - exit_farm_amount: u64, - ) { + pub fn exit_farm(&mut self, user: &Address, farm_token_nonce: u64, exit_farm_amount: u64) { self.b_mock .execute_esdt_transfer( user, &self.farm_wrapper, FARM_TOKEN_ID, farm_token_nonce, - &rust_biguint!(farm_token_amount), + &rust_biguint!(exit_farm_amount), |sc| { - let _ = sc.exit_farm_endpoint( - managed_biguint!(exit_farm_amount), - OptionalValue::None, - ); + let _ = sc.exit_farm_endpoint(OptionalValue::None); }, ) .assert_ok(); @@ -542,7 +546,6 @@ where &mut self, user: &Address, farm_token_nonce: u64, - farm_token_amount: u64, exit_farm_amount: u64, known_proxy: &Address, ) { @@ -552,23 +555,21 @@ where &self.farm_wrapper, FARM_TOKEN_ID, farm_token_nonce, - &rust_biguint!(farm_token_amount), + &rust_biguint!(exit_farm_amount), |sc| { - let _ = sc.exit_farm_endpoint( - managed_biguint!(exit_farm_amount), - OptionalValue::Some(managed_address!(user)), - ); + let _ = sc.exit_farm_endpoint(OptionalValue::Some(managed_address!(user))); }, ) .assert_ok(); } - pub fn allow_external_claim_rewards(&mut self, user: &Address) { + pub fn allow_external_claim_rewards(&mut self, user: &Address, allow_external_claim: bool) { self.b_mock .execute_tx(user, &self.farm_wrapper, &rust_biguint!(0), |sc| { sc.user_total_farm_position(&managed_address!(user)).update( - |user_total_farm_position_struct| { - user_total_farm_position_struct.allow_external_claim_boosted_rewards = true; + |user_total_farm_position| { + user_total_farm_position.allow_external_claim_boosted_rewards = + allow_external_claim; }, ); }) @@ -649,4 +650,45 @@ where }) .assert_ok(); } + + pub fn check_farm_token_supply(&mut self, expected_farm_token_supply: u64) { + let b_mock = &mut self.b_mock; + b_mock + .execute_query(&self.farm_wrapper, |sc| { + let actual_farm_supply = sc.farm_token_supply().get(); + assert_eq!( + managed_biguint!(expected_farm_token_supply), + actual_farm_supply + ); + }) + .assert_ok(); + } + + pub fn set_user_total_farm_position(&mut self, user_addr: &Address, new_farm_position: u64) { + self.b_mock + .execute_tx(&self.owner, &self.farm_wrapper, &rust_biguint!(0), |sc| { + let user_farm_position = UserTotalFarmPosition { + total_farm_position: managed_biguint!(new_farm_position), + ..Default::default() + }; + sc.user_total_farm_position(&managed_address!(user_addr)) + .set(user_farm_position); + }) + .assert_ok(); + } + + pub fn check_user_total_farm_position(&mut self, user_addr: &Address, expected_amount: u64) { + self.b_mock + .execute_query(&self.farm_wrapper, |sc| { + let user_total_farm_position_mapper = + sc.user_total_farm_position(&managed_address!(user_addr)); + if expected_amount > 0 && !user_total_farm_position_mapper.is_empty() { + assert_eq!( + managed_biguint!(expected_amount), + user_total_farm_position_mapper.get().total_farm_position + ); + } + }) + .assert_ok(); + } } 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 13644ee88..1e23f999b 100644 --- a/dex/farm/tests/farm_setup/single_user_farm_setup.rs +++ b/dex/farm/tests/farm_setup/single_user_farm_setup.rs @@ -222,13 +222,9 @@ where farm_token_nonce, &rust_biguint!(farm_token_amount), |sc| { - let multi_result = sc.exit_farm_endpoint( - managed_biguint!(farm_token_amount), - OptionalValue::None, - ); + let multi_result = sc.exit_farm_endpoint(OptionalValue::None); - let (first_result, second_result, remaining_farm_amount) = - multi_result.into_tuple(); + let (first_result, second_result) = multi_result.into_tuple(); assert_eq!( first_result.token_identifier, @@ -246,7 +242,6 @@ where ); assert_eq!(second_result.token_nonce, 0); assert_eq!(second_result.amount, managed_biguint!(expected_mex_out)); - assert_eq!(remaining_farm_amount.amount, managed_biguint!(0)); }, ) .assert_ok(); diff --git a/dex/farm/tests/farm_single_user_test.rs b/dex/farm/tests/farm_single_user_test.rs index 9adc893fa..c3df21b83 100644 --- a/dex/farm/tests/farm_single_user_test.rs +++ b/dex/farm/tests/farm_single_user_test.rs @@ -396,7 +396,7 @@ fn test_farm_through_simple_lock() { 2, &rust_biguint!(1_000_000_000), |sc| { - let exit_farm_result = sc.exit_farm_locked_token(managed_biguint!(1_000_000_000)); + let exit_farm_result = sc.exit_farm_locked_token(); let (locked_tokens, reward_tokens) = exit_farm_result.into_tuple(); assert_eq!( @@ -594,7 +594,7 @@ fn test_farm_through_simple_lock() { 7, &rust_biguint!(1_000_000_000), |sc| { - let exit_farm_result = sc.exit_farm_locked_token(managed_biguint!(1_000_000_000)); + let exit_farm_result = sc.exit_farm_locked_token(); let (locked_tokens, _reward_tokens) = exit_farm_result.into_tuple(); assert_eq!( diff --git a/dex/farm/tests/total_farm_position_test.rs b/dex/farm/tests/total_farm_position_test.rs new file mode 100644 index 000000000..26756ebaa --- /dev/null +++ b/dex/farm/tests/total_farm_position_test.rs @@ -0,0 +1,562 @@ +#![allow(deprecated)] + +mod farm_setup; + +use common_structs::FarmTokenAttributes; +use config::ConfigModule; +use farm_setup::multi_user_farm_setup::{MultiUserFarmSetup, BOOSTED_YIELDS_PERCENTAGE}; +use multiversx_sc_scenario::{managed_address, managed_biguint, rust_biguint, DebugApi}; + +use crate::farm_setup::multi_user_farm_setup::{FARM_TOKEN_ID, REWARD_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, + ); + + farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); + farm_setup.set_boosted_yields_factors(); + farm_setup.b_mock.set_block_epoch(2); + + let temp_user = farm_setup.third_user.clone(); + + // first user enter farm + let farm_in_amount = 50_000_000; + let first_user = farm_setup.first_user.clone(); + farm_setup.set_user_energy(&first_user, 1_000, 2, 1); + farm_setup.enter_farm(&first_user, farm_in_amount); + farm_setup.enter_farm(&first_user, farm_in_amount); + + farm_setup.b_mock.check_nft_balance( + &first_user, + FARM_TOKEN_ID, + 1, + &rust_biguint!(farm_in_amount), + Some(&FarmTokenAttributes:: { + reward_per_share: managed_biguint!(0), + compounded_reward: managed_biguint!(0), + entering_epoch: 2, + current_farm_amount: managed_biguint!(farm_in_amount), + original_owner: managed_address!(&first_user), + }), + ); + + farm_setup.b_mock.check_nft_balance( + &first_user, + FARM_TOKEN_ID, + 2, + &rust_biguint!(farm_in_amount), + Some(&FarmTokenAttributes:: { + reward_per_share: managed_biguint!(0), + compounded_reward: managed_biguint!(0), + entering_epoch: 2, + current_farm_amount: managed_biguint!(farm_in_amount), + original_owner: managed_address!(&first_user), + }), + ); + + farm_setup.check_farm_token_supply(farm_in_amount * 2); + + // users claim rewards to get their energy registered + let _ = farm_setup.claim_rewards(&first_user, 1, farm_in_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.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); + farm_setup.exit_farm(&temp_user, 4, 1); + + // advance 1 week + farm_setup.b_mock.set_block_epoch(10); + farm_setup.set_user_energy(&first_user, 1_000, 10, 1); + + let total_farm_tokens = farm_in_amount * 2; + + // first user claim with half total position + let first_base_farm_amt = farm_in_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) + // (2_500 * 3 * 1_000 / 1_000 + 2_500 * 2 * 100_000_000 / 100_000_000) / (3 + 2) + // (7_500 + 2_500) / (5) = 2_500 + let first_boosted_amt = 2_500; // 1000 energy & 100_000_000 farm tokens + let first_total_rewards = first_base_farm_amt + first_boosted_amt; + + let first_received_reward_amt = farm_setup.claim_rewards(&first_user, 3, farm_in_amount); + + // Should be equal to half base generated rewards + full boosted generated rewards + assert_eq!(first_received_reward_amt, first_total_rewards); + + farm_setup + .b_mock + .check_nft_balance::>( + &first_user, + FARM_TOKEN_ID, + 5, + &rust_biguint!(farm_in_amount), + None, + ); + + farm_setup.b_mock.check_esdt_balance( + &first_user, + REWARD_TOKEN_ID, + &rust_biguint!(first_received_reward_amt), + ); +} + +#[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, + ); + + farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); + farm_setup.set_boosted_yields_factors(); + farm_setup.b_mock.set_block_epoch(2); + + // 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.enter_farm(&first_user, first_farm_token_amount); + + // users claim rewards to get their energy registered + let _ = farm_setup.claim_rewards(&first_user, 1, first_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.set_user_energy(&first_user, 1_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, 3, 1); + + // advance 1 week + farm_setup.b_mock.set_block_epoch(10); + farm_setup.set_user_energy(&first_user, 1_000, 10, 1); + + let first_boosted_amt = 2500; + + // Second user claim boosted rewards for first user + farm_setup.allow_external_claim_rewards(&first_user, true); + + let first_received_boosted_amt = + farm_setup.claim_boosted_rewards_for_user(&first_user, &third_user); + assert_eq!(first_received_boosted_amt, first_boosted_amt); + + // First user should receive the boosted rewards + farm_setup.b_mock.check_esdt_balance( + &first_user, + REWARD_TOKEN_ID, + &rust_biguint!(first_received_boosted_amt), + ); + + // User who called the claim function should not receive anything + farm_setup + .b_mock + .check_esdt_balance(&third_user, REWARD_TOKEN_ID, &rust_biguint!(0)); + + // Check allow external claim is set to false + farm_setup.allow_external_claim_rewards(&first_user, false); + + farm_setup.claim_boosted_rewards_for_user_expect_error(&first_user, &third_user); +} + +#[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, + ); + + farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); + farm_setup.set_boosted_yields_factors(); + farm_setup.b_mock.set_block_epoch(2); + + // 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.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.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.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(10); + farm_setup.set_user_energy(&first_user, 1_000, 10, 1); + farm_setup.set_user_energy(&second_user, 4_000, 10, 1); + + // Second user claims for himself + let total_farm_tokens = first_farm_token_amount + second_farm_token_amount; + let second_base_farm_amt = second_farm_token_amount * 7_500 / total_farm_tokens; + let second_boosted_amt = 1533; // 4000 energy & 50_000_000 farm tokens + let second_total = second_base_farm_amt + second_boosted_amt; + + let second_received_reward_amt = + farm_setup.claim_rewards(&second_user, 4, second_farm_token_amount); + assert_eq!(second_received_reward_amt, second_total); + + farm_setup + .b_mock + .check_nft_balance::>( + &second_user, + FARM_TOKEN_ID, + 6, + &rust_biguint!(second_farm_token_amount), + None, + ); + + farm_setup.b_mock.check_esdt_balance( + &second_user, + REWARD_TOKEN_ID, + &rust_biguint!(second_received_reward_amt), + ); + + // 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 + + // Second user claim boosted rewards for first user + farm_setup.allow_external_claim_rewards(&first_user, true); + + let first_received_boosted_amt = + farm_setup.claim_boosted_rewards_for_user(&first_user, &second_user); + assert_eq!(first_received_boosted_amt, first_boosted_amt); + + // First user should receive the boosted rewards + farm_setup.b_mock.check_esdt_balance( + &first_user, + REWARD_TOKEN_ID, + &rust_biguint!(first_received_boosted_amt), + ); + + // Second user has the same amount of reward tokens + farm_setup.b_mock.check_esdt_balance( + &second_user, + REWARD_TOKEN_ID, + &rust_biguint!(second_received_reward_amt), + ); +} + +#[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, + ); + + farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); + farm_setup.set_boosted_yields_factors(); + farm_setup.b_mock.set_block_epoch(2); + + let temp_user = farm_setup.third_user.clone(); + + // first user enter farm + let farm_in_amount = 50_000_000; + let first_user = farm_setup.first_user.clone(); + farm_setup.set_user_energy(&first_user, 1_000, 2, 1); + farm_setup.enter_farm(&first_user, farm_in_amount); + + // Remove current farm position from storage + farm_setup.set_user_total_farm_position(&first_user, 0); + farm_setup.check_user_total_farm_position(&first_user, 0); + + // User enters farm again + farm_setup.enter_farm(&first_user, farm_in_amount); + farm_setup.check_user_total_farm_position(&first_user, farm_in_amount); + + // Set farm position migration nonce + farm_setup + .b_mock + .execute_tx( + &farm_setup.owner, + &farm_setup.farm_wrapper, + &rust_biguint!(0), + |sc| { + sc.farm_position_migration_nonce().set(2); + }, + ) + .assert_ok(); + + farm_setup.check_farm_token_supply(farm_in_amount * 2); + + // users claim rewards to get their energy registered + let _ = farm_setup.claim_rewards(&first_user, 2, farm_in_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.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); + farm_setup.exit_farm(&temp_user, 4, 1); + + // advance 1 week + farm_setup.b_mock.set_block_epoch(10); + farm_setup.set_user_energy(&first_user, 1_000, 10, 1); + + let total_farm_tokens = farm_in_amount * 2; + + // first user claim with half total position + let first_base_farm_amt = farm_in_amount * 7_500 / total_farm_tokens; + + let first_boosted_amt = 2_000; // claim boosted with only half total position - not full rewards + let first_total_rewards = first_base_farm_amt + first_boosted_amt; + + let first_received_reward_amt = farm_setup.claim_rewards(&first_user, 3, farm_in_amount); + + // Should be equal to half base generated rewards + partial boosted generated rewards + assert_eq!(first_received_reward_amt, first_total_rewards); + + farm_setup + .b_mock + .check_nft_balance::>( + &first_user, + FARM_TOKEN_ID, + 5, + &rust_biguint!(farm_in_amount), + None, + ); + + farm_setup.b_mock.check_esdt_balance( + &first_user, + REWARD_TOKEN_ID, + &rust_biguint!(first_received_reward_amt), + ); + + // advance 10 more blocks - 10_000 more total rewards + // 7_500 base farm, 2_500 boosted yields + 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.set_user_energy(&first_user, 1_000, 13, 1); + farm_setup.set_user_energy(&temp_user, 1, 13, 1); + farm_setup.enter_farm(&temp_user, 1); + farm_setup.exit_farm(&temp_user, 6, 1); + + // advance 1 week + farm_setup.b_mock.set_block_epoch(20); + farm_setup.set_user_energy(&first_user, 1_000, 20, 1); + + // user claims with old position - should migrate his entire position + let second_received_reward_amt = farm_setup.claim_rewards(&first_user, 1, farm_in_amount); + + farm_setup.check_user_total_farm_position(&first_user, farm_in_amount * 2); + + let second_base_farm_amt = (farm_in_amount * 7_500 / total_farm_tokens) * 2; // user claims with initial position (2 weeks worth of rewards) + let second_boosted_amt = 2_500; // claim boosted with entire total position - receives full rewards + let second_total_rewards = second_base_farm_amt + second_boosted_amt; + assert_eq!(second_received_reward_amt, second_total_rewards); +} + +#[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, + ); + + farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); + farm_setup.set_boosted_yields_factors(); + farm_setup.b_mock.set_block_epoch(2); + + let temp_user = farm_setup.third_user.clone(); + + // first user enter farm + let farm_in_amount = 50_000_000; + let first_user = farm_setup.first_user.clone(); + farm_setup.set_user_energy(&first_user, 1_000, 2, 1); + farm_setup.enter_farm(&first_user, farm_in_amount); + + // Remove current farm position from storage + farm_setup.set_user_total_farm_position(&first_user, 0); + farm_setup.check_user_total_farm_position(&first_user, 0); + + // User enters farm again + farm_setup.enter_farm(&first_user, farm_in_amount); + farm_setup.check_user_total_farm_position(&first_user, farm_in_amount); + + // Set farm position migration nonce + farm_setup + .b_mock + .execute_tx( + &farm_setup.owner, + &farm_setup.farm_wrapper, + &rust_biguint!(0), + |sc| { + sc.farm_position_migration_nonce().set(2); + }, + ) + .assert_ok(); + + farm_setup.check_farm_token_supply(farm_in_amount * 2); + + // users claim rewards to get their energy registered + let _ = farm_setup.claim_rewards(&first_user, 2, farm_in_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.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); + farm_setup.exit_farm(&temp_user, 4, 1); + + // advance 1 week + farm_setup.b_mock.set_block_epoch(10); + farm_setup.set_user_energy(&first_user, 1_000, 10, 1); + + // first user exist farm with old position + farm_setup.exit_farm(&first_user, 1, farm_in_amount); + + // user farm position should be unchanged + farm_setup.check_user_total_farm_position(&first_user, farm_in_amount); + + // User should receive half base rewards and full boosted rewards + let total_farm_tokens = farm_in_amount * 2; + let first_base_farm_amt = farm_in_amount * 7_500 / total_farm_tokens; + let first_boosted_amt = 2_500; + let first_total_rewards = first_base_farm_amt + first_boosted_amt; + farm_setup.b_mock.check_esdt_balance( + &first_user, + REWARD_TOKEN_ID, + &rust_biguint!(first_total_rewards), + ); +} + +#[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, + ); + + farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); + farm_setup.set_boosted_yields_factors(); + farm_setup.b_mock.set_block_epoch(5); + + let temp_user = farm_setup.third_user.clone(); + + // first user enter farm + let farm_in_amount = 50_000_000; + let first_user = farm_setup.first_user.clone(); + farm_setup.set_user_energy(&first_user, 1_000, 5, 1); + farm_setup.enter_farm(&first_user, farm_in_amount); + farm_setup.enter_farm(&first_user, farm_in_amount); + + // users claim rewards to get their energy registered + let _ = farm_setup.claim_rewards(&first_user, 2, farm_in_amount); + + // advance to week 1 + + // 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 the week, to cummulate rewards + farm_setup.b_mock.set_block_epoch(6); + 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); + farm_setup.exit_farm(&temp_user, 4, 1); + + // advance to week 2 + farm_setup.b_mock.set_block_nonce(20); + farm_setup.b_mock.set_block_epoch(13); + + // User unlocks XMEX and has no energy + farm_setup.set_user_energy(&first_user, 0, 13, 1); + + // random tx on end of the week, to cummulate rewards + farm_setup.set_user_energy(&temp_user, 1, 13, 1); + farm_setup.enter_farm(&temp_user, 1); + farm_setup.exit_farm(&temp_user, 5, 1); + + // advance to week 3 + farm_setup.b_mock.set_block_nonce(30); + + // random tx on end of the week, to cummulate rewards + farm_setup.b_mock.set_block_epoch(20); + 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); + + // first user claims 3 weeks worth of rewards (2-4) + let total_farm_tokens = farm_in_amount * 2; + let first_base_farm_amt = (farm_in_amount * 7_500 / total_farm_tokens) * 3; + let first_boosted_amt = 2_500 * 3; + let first_total_rewards = first_base_farm_amt + first_boosted_amt; + + let first_receveived_reward_amt = farm_setup.claim_rewards(&first_user, 1, farm_in_amount); + + // Should be equal to half base generated rewards + full boosted generated rewards + assert_eq!(first_receveived_reward_amt, first_total_rewards); + + farm_setup.b_mock.check_esdt_balance( + &first_user, + REWARD_TOKEN_ID, + &rust_biguint!(first_receveived_reward_amt), + ); +} diff --git a/dex/farm/wasm/Cargo.lock b/dex/farm/wasm/Cargo.lock index 97ea7e292..c987ae22b 100644 --- a/dex/farm/wasm/Cargo.lock +++ b/dex/farm/wasm/Cargo.lock @@ -8,7 +8,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "once_cell", "version_check", ] @@ -31,12 +31,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -292,12 +286,6 @@ dependencies = [ "utils", ] -[[package]] -name = "libc" -version = "0.2.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" - [[package]] name = "locking_module" version = "0.0.0" @@ -314,12 +302,6 @@ dependencies = [ "multiversx-sc", ] -[[package]] -name = "memory_units" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" - [[package]] name = "mergeable" version = "0.0.0" @@ -329,9 +311,9 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecfb3e03ac6e08114963a54e15a3c78c28e57cc0e31836e870450b35085bdf8d" +checksum = "386c2727eba66bc5e502e470d7afa55fdd69aedff440c508bb9ba85aec36a52a" dependencies = [ "bitflags", "hashbrown", @@ -343,20 +325,19 @@ dependencies = [ [[package]] name = "multiversx-sc-codec" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7638cb46a0e99c636fd55443ac534ff0a5fad0bd772e1037fbac9a75e04c3c9" +checksum = "0f1e15b46c17b87c0c7cdd79b041a4abd7f3a2b45f3c993f6ce38c0f233e82b6" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", - "wee_alloc", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e976002d51367f16140929c10ee695f95dd8d34c150a45db60d3fcd1328a267a" +checksum = "9a7bc0762cd6d88f8bc54805bc652b042a61cd7fbc2d0a325010f088b78fb2ac" dependencies = [ "hex", "proc-macro2", @@ -366,9 +347,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6eb54a7d452eb09f5de159ee9b4d1fb9ec79cf49f1602ebd3efc8532015a4ea" +checksum = "050510b6b9836b24b4a73bb7878c58c268d56bde1c6eb0f9a88dce9a6518507b" dependencies = [ "hex", "proc-macro2", @@ -379,21 +360,20 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12284a3e31c0852b6ca0ce8306d3f404c3712b996a05ed78e97e765c98461f3" +checksum = "3b55fe3585cbc745bd7b9793be4bcb3aa7f1869ced7a0981f3d47e6a832c6311" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee69fa831cdd5a7ea1aedbb6356a55792b821396f48360a6194f4131eddd1045" +checksum = "b059f22dfc3eb45aa015f6f20f28ed34dc42a65b42d282f8ac9b799b12e2942c" dependencies = [ "multiversx-sc", - "wee_alloc", ] [[package]] @@ -454,9 +434,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -575,18 +555,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wee_alloc" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "memory_units", - "winapi", -] - [[package]] name = "week-timekeeping" version = "0.0.0" @@ -606,25 +574,3 @@ dependencies = [ "unwrappable", "week-timekeeping", ] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/dex/farm/wasm/src/lib.rs b/dex/farm/wasm/src/lib.rs index 4f3c13441..78415bd2c 100644 --- a/dex/farm/wasm/src/lib.rs +++ b/dex/farm/wasm/src/lib.rs @@ -5,12 +5,15 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 61 +// Endpoints: 63 // Async Callback: 1 -// Total number of exported functions: 63 +// Total number of exported functions: 65 #![no_std] -#![feature(alloc_error_handler, lang_items)] + +// Configuration that works with rustc < 1.73.0. +// TODO: Recommended rustc version: 1.73.0 or newer. +#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -18,67 +21,71 @@ multiversx_sc_wasm_adapter::panic_handler!(); multiversx_sc_wasm_adapter::endpoints! { farm ( - enterFarm - claimRewards - compoundRewards - exitFarm - calculateRewardsForGivenPosition - mergeFarmTokens - startProduceRewards - endProduceRewards - setPerBlockRewardAmount - getRewardPerShare - getRewardReserve - getFarmingTokenId - getRewardTokenId - getPerBlockRewardAmount - getLastRewardBlockNonce - getDivisionSafetyConstant - getUserTotalFarmPosition - registerFarmToken - getFarmTokenId - getFarmTokenSupply - addToPauseWhitelist - removeFromPauseWhitelist - pause - resume - getState - addAdmin - removeAdmin - updateOwnerOrAdmin - getPermissions - addSCAddressToWhitelist - removeSCAddressFromWhitelist - isSCAddressWhitelisted - set_penalty_percent - set_minimum_farming_epochs - set_burn_gas_limit - getPenaltyPercent - getMinimumFarmingEpoch - getBurnGasLimit - getPairContractManagedAddress - claimBoostedRewards - setBoostedYieldsRewardsPercentage - collectUndistributedBoostedRewards - getBoostedYieldsRewardsPercentage - getAccumulatedRewardsForWeek - getFarmSupplyForWeek - getRemainingBoostedRewardsToDistribute - getUndistributedBoostedRewards - setBoostedYieldsFactors - getBoostedYieldsFactors - getCurrentWeek - getFirstWeekStartEpoch - getLastActiveWeekForUser - getUserEnergyForWeek - getLastGlobalUpdateWeek - getTotalRewardsForWeek - getTotalEnergyForWeek - getTotalLockedTokensForWeek - updateEnergyForUser - getCurrentClaimProgress - setEnergyFactoryAddress - getEnergyFactoryAddress - callBack + init => init + enterFarm => enter_farm_endpoint + claimRewards => claim_rewards_endpoint + compoundRewards => compound_rewards_endpoint + exitFarm => exit_farm_endpoint + mergeFarmTokens => merge_farm_tokens_endpoint + claimBoostedRewards => claim_boosted_rewards + startProduceRewards => start_produce_rewards_endpoint + endProduceRewards => end_produce_rewards_endpoint + setPerBlockRewardAmount => set_per_block_rewards_endpoint + calculateRewardsForGivenPosition => calculate_rewards_for_given_position + getRewardPerShare => reward_per_share + getRewardReserve => reward_reserve + allowExternalClaimBoostedRewards => allow_external_claim_boosted_rewards + getFarmingTokenId => farming_token_id + getRewardTokenId => reward_token_id + getPerBlockRewardAmount => per_block_reward_amount + getLastRewardBlockNonce => last_reward_block_nonce + getDivisionSafetyConstant => division_safety_constant + getUserTotalFarmPosition => user_total_farm_position + getFarmPositionMigrationNonce => farm_position_migration_nonce + registerFarmToken => register_farm_token + getFarmTokenId => farm_token + getFarmTokenSupply => farm_token_supply + addToPauseWhitelist => add_to_pause_whitelist + removeFromPauseWhitelist => remove_from_pause_whitelist + pause => pause + resume => resume + getState => state + addAdmin => add_admin_endpoint + removeAdmin => remove_admin_endpoint + updateOwnerOrAdmin => update_owner_or_admin_endpoint + getPermissions => permissions + 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 + setBoostedYieldsRewardsPercentage => set_boosted_yields_rewards_percentage + 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 + getUserEnergyForWeek => get_user_energy_for_week_view + getLastGlobalUpdateWeek => last_global_update_week + getTotalRewardsForWeek => total_rewards_for_week + getTotalEnergyForWeek => total_energy_for_week + getTotalLockedTokensForWeek => total_locked_tokens_for_week + updateEnergyForUser => update_energy_for_user + getCurrentClaimProgress => current_claim_progress + setEnergyFactoryAddress => set_energy_factory_address + getEnergyFactoryAddress => energy_factory_address ) } + +multiversx_sc_wasm_adapter::async_callback! { farm } diff --git a/dex/fuzz/src/fuzz_farm.rs b/dex/fuzz/src/fuzz_farm.rs index 1ef8e2463..c30e94442 100644 --- a/dex/fuzz/src/fuzz_farm.rs +++ b/dex/fuzz/src/fuzz_farm.rs @@ -8,7 +8,7 @@ pub mod fuzz_farm_test { use std::cmp::Ordering; use multiversx_sc_scenario::whitebox_legacy::TxTokenTransfer; - use multiversx_sc_scenario::{managed_biguint, rust_biguint, DebugApi}; + use multiversx_sc_scenario::{rust_biguint, DebugApi}; use crate::fuzz_data::fuzz_data_tests::*; use farm::*; @@ -179,7 +179,7 @@ pub mod fuzz_farm_test { farm_token_nonce, &farm_out_amount, |sc| { - sc.exit_farm_endpoint(managed_biguint!(seed), OptionalValue::None); + sc.exit_farm_endpoint(OptionalValue::None); }, ); diff --git a/dex/scenarios/exit_farm.scen.json b/dex/scenarios/exit_farm.scen.json index 9a3ec697d..495520be4 100644 --- a/dex/scenarios/exit_farm.scen.json +++ b/dex/scenarios/exit_farm.scen.json @@ -25,9 +25,7 @@ } ], "function": "exitFarm", - "arguments": [ - "100,000" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -42,11 +40,6 @@ "1-token_id": "nested:str:WEGLD-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:0" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:2", - "3-amount": "biguint:0" } ], "status": "0", diff --git a/dex/scenarios/exit_farm_too_soon.scen.json b/dex/scenarios/exit_farm_too_soon.scen.json index 8280af81e..72b596bda 100644 --- a/dex/scenarios/exit_farm_too_soon.scen.json +++ b/dex/scenarios/exit_farm_too_soon.scen.json @@ -47,9 +47,7 @@ } ], "function": "exitFarm", - "arguments": [ - "100,000" - ], + "arguments": [], "gasLimit": "1,000,000,000", "gasPrice": "0" }, @@ -64,11 +62,6 @@ "1-token_id": "nested:str:WEGLD-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:0" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:2", - "3-amount": "biguint:0" } ], "status": "0", @@ -125,9 +118,7 @@ } ], "function": "exitFarm", - "arguments": [ - "100,000" - ], + "arguments": [], "gasLimit": "1,000,000,000", "gasPrice": "0" }, @@ -142,11 +133,6 @@ "1-token_id": "nested:str:WEGLD-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:0" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:2", - "3-amount": "biguint:0" } ], "status": "0", diff --git a/dex/scenarios/exit_mex_farm.scen.json b/dex/scenarios/exit_mex_farm.scen.json index 03e17bb16..3cc9dca89 100644 --- a/dex/scenarios/exit_mex_farm.scen.json +++ b/dex/scenarios/exit_mex_farm.scen.json @@ -26,9 +26,7 @@ } ], "function": "exitFarm", - "arguments": [ - "100,000,000" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -43,11 +41,6 @@ "1-token_id": "nested:str:MEX-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:50,000" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:1", - "3-amount": "biguint:0" } ], "status": "0", diff --git a/dex/scenarios/farm_reward_distr_scen_1.scen.json b/dex/scenarios/farm_reward_distr_scen_1.scen.json index 348847c77..e45afaa8e 100644 --- a/dex/scenarios/farm_reward_distr_scen_1.scen.json +++ b/dex/scenarios/farm_reward_distr_scen_1.scen.json @@ -167,9 +167,7 @@ } ], "function": "exitFarm", - "arguments": [ - "1,000" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -184,11 +182,6 @@ "1-token_id": "nested:str:MEX-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:450" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:1", - "3-amount": "biguint:0" } ], "status": "0", @@ -211,9 +204,7 @@ } ], "function": "exitFarm", - "arguments": [ - "1,000" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -228,11 +219,6 @@ "1-token_id": "nested:str:MEX-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:350" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:2", - "3-amount": "biguint:0" } ], "status": "0", diff --git a/dex/scenarios/farm_reward_distr_scen_2.scen.json b/dex/scenarios/farm_reward_distr_scen_2.scen.json index bcab014a5..fc607055a 100644 --- a/dex/scenarios/farm_reward_distr_scen_2.scen.json +++ b/dex/scenarios/farm_reward_distr_scen_2.scen.json @@ -210,9 +210,7 @@ } ], "function": "exitFarm", - "arguments": [ - "2,000" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -227,11 +225,6 @@ "1-token_id": "nested:str:MEX-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:428" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:2", - "3-amount": "biguint:0" } ], "status": "0", @@ -260,9 +253,7 @@ } ], "function": "exitFarm", - "arguments": [ - "1,000" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -277,11 +268,6 @@ "1-token_id": "nested:str:MEX-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:414" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:1", - "3-amount": "biguint:0" } ], "status": "0", @@ -310,9 +296,7 @@ } ], "function": "exitFarm", - "arguments": [ - "500" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -327,11 +311,6 @@ "1-token_id": "nested:str:MEX-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:457" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:3", - "3-amount": "biguint:0" } ], "status": "0", diff --git a/dex/scenarios/farm_reward_distr_scen_3.scen.json b/dex/scenarios/farm_reward_distr_scen_3.scen.json index b3a3442a4..b850e7bd9 100644 --- a/dex/scenarios/farm_reward_distr_scen_3.scen.json +++ b/dex/scenarios/farm_reward_distr_scen_3.scen.json @@ -260,9 +260,7 @@ } ], "function": "exitFarm", - "arguments": [ - "2,000" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -277,11 +275,6 @@ "1-token_id": "nested:str:MEX-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:371" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:2", - "3-amount": "biguint:0" } ], "status": "0", @@ -310,9 +303,7 @@ } ], "function": "exitFarm", - "arguments": [ - "1,000" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -327,11 +318,6 @@ "1-token_id": "nested:str:MEX-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:285" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:1", - "3-amount": "biguint:0" } ], "status": "0", @@ -360,9 +346,7 @@ } ], "function": "exitFarm", - "arguments": [ - "500" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -377,11 +361,6 @@ "1-token_id": "nested:str:MEX-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:242" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:3", - "3-amount": "biguint:0" } ], "status": "0", diff --git a/dex/scenarios/farm_reward_distr_scen_4.scen.json b/dex/scenarios/farm_reward_distr_scen_4.scen.json index 629b2f5f9..0a9dbaf60 100644 --- a/dex/scenarios/farm_reward_distr_scen_4.scen.json +++ b/dex/scenarios/farm_reward_distr_scen_4.scen.json @@ -260,9 +260,7 @@ } ], "function": "exitFarm", - "arguments": [ - "2,000,000,000,000,000,000,000" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -277,11 +275,6 @@ "1-token_id": "nested:str:MEX-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:3,714,285,714,284,000,000,000" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:2", - "3-amount": "biguint:0" } ], "status": "0", @@ -310,9 +303,7 @@ } ], "function": "exitFarm", - "arguments": [ - "1,000,000,000,000,000,000,000" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -327,11 +318,6 @@ "1-token_id": "nested:str:MEX-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:2,857,142,857,142,000,000,000" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:1", - "3-amount": "biguint:0" } ], "status": "0", @@ -360,9 +346,7 @@ } ], "function": "exitFarm", - "arguments": [ - "500,000,000,000,000,000,000" - ], + "arguments": [], "gasLimit": "100,000,000", "gasPrice": "0" }, @@ -377,11 +361,6 @@ "1-token_id": "nested:str:MEX-abcdef", "2-nonce": "u64:0", "3-amount": "biguint:2,428,571,428,571,000,000,000" - }, - { - "1-token_id": "nested:str:FARM-abcdef", - "2-nonce": "u64:3", - "3-amount": "biguint:0" } ], "status": "0", diff --git a/dex/scenarios/merge_tokens.scen.json b/dex/scenarios/merge_tokens.scen.json index 1a0b187cb..ed059f31b 100644 --- a/dex/scenarios/merge_tokens.scen.json +++ b/dex/scenarios/merge_tokens.scen.json @@ -30,7 +30,8 @@ }, "expect": { "out": [ - "0x0000000b4641524d2d6162636465660000000000000003000000040bebc200" + "0x0000000b4641524d2d6162636465660000000000000003000000040bebc200", + "0x0000000c5745474c442d616263646566000000000000000000000000" ], "status": "0", "message": "", @@ -63,4 +64,4 @@ } } ] -} +} \ No newline at end of file diff --git a/energy-integration/farm-boosted-yields/src/lib.rs b/energy-integration/farm-boosted-yields/src/lib.rs index fc441b515..931c58f9d 100644 --- a/energy-integration/farm-boosted-yields/src/lib.rs +++ b/energy-integration/farm-boosted-yields/src/lib.rs @@ -129,17 +129,14 @@ pub trait FarmBoostedYieldsModule: self.farm_supply_for_week(current_week).set(farm_supply); } - fn clear_user_energy_if_needed( - &self, - original_caller: &ManagedAddress, - user_remaining_farm_tokens: &BigUint, - ) { + fn clear_user_energy_if_needed(&self, original_caller: &ManagedAddress) { let opt_config = self.try_get_boosted_yields_config(); + let user_total_farm_position = self.get_user_total_farm_position(original_caller); if let Some(config) = opt_config { let boosted_yields_factors = config.get_latest_factors(); self.clear_user_energy( original_caller, - user_remaining_farm_tokens, + &user_total_farm_position.total_farm_position, &boosted_yields_factors.min_farm_amount, ); } diff --git a/energy-integration/fees-collector/elrond.json b/energy-integration/fees-collector/elrond.json deleted file mode 100644 index 736553962..000000000 --- a/energy-integration/fees-collector/elrond.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "language": "rust" -} \ No newline at end of file diff --git a/energy-integration/fees-collector/src/config.rs b/energy-integration/fees-collector/src/config.rs index 1e1a850a0..a21dc6d6b 100644 --- a/energy-integration/fees-collector/src/config.rs +++ b/energy-integration/fees-collector/src/config.rs @@ -60,6 +60,13 @@ pub trait ConfigModule { self.all_tokens().set(&all_tokens_vec); } + #[endpoint(setAllowExternalClaimRewards)] + fn set_allow_external_claim_rewards(&self, allow_external_claim_rewards: bool) { + let caller = self.blockchain().get_caller(); + self.allow_external_claim_rewards(&caller) + .set(allow_external_claim_rewards); + } + #[view(getLockedTokenId)] #[storage_mapper("lockedTokenId")] fn locked_token_id(&self) -> SingleValueMapper; diff --git a/energy-integration/fees-collector/wasm/Cargo.lock b/energy-integration/fees-collector/wasm/Cargo.lock index 601610441..86c6f1c94 100644 --- a/energy-integration/fees-collector/wasm/Cargo.lock +++ b/energy-integration/fees-collector/wasm/Cargo.lock @@ -8,7 +8,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "once_cell", "version_check", ] @@ -31,12 +31,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -161,12 +155,6 @@ dependencies = [ "utils", ] -[[package]] -name = "libc" -version = "0.2.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" - [[package]] name = "locking_module" version = "0.0.0" @@ -183,12 +171,6 @@ dependencies = [ "multiversx-sc", ] -[[package]] -name = "memory_units" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" - [[package]] name = "mergeable" version = "0.0.0" @@ -198,9 +180,9 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecfb3e03ac6e08114963a54e15a3c78c28e57cc0e31836e870450b35085bdf8d" +checksum = "386c2727eba66bc5e502e470d7afa55fdd69aedff440c508bb9ba85aec36a52a" dependencies = [ "bitflags", "hashbrown", @@ -212,20 +194,19 @@ dependencies = [ [[package]] name = "multiversx-sc-codec" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7638cb46a0e99c636fd55443ac534ff0a5fad0bd772e1037fbac9a75e04c3c9" +checksum = "0f1e15b46c17b87c0c7cdd79b041a4abd7f3a2b45f3c993f6ce38c0f233e82b6" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", - "wee_alloc", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e976002d51367f16140929c10ee695f95dd8d34c150a45db60d3fcd1328a267a" +checksum = "9a7bc0762cd6d88f8bc54805bc652b042a61cd7fbc2d0a325010f088b78fb2ac" dependencies = [ "hex", "proc-macro2", @@ -235,9 +216,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6eb54a7d452eb09f5de159ee9b4d1fb9ec79cf49f1602ebd3efc8532015a4ea" +checksum = "050510b6b9836b24b4a73bb7878c58c268d56bde1c6eb0f9a88dce9a6518507b" dependencies = [ "hex", "proc-macro2", @@ -248,21 +229,20 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12284a3e31c0852b6ca0ce8306d3f404c3712b996a05ed78e97e765c98461f3" +checksum = "3b55fe3585cbc745bd7b9793be4bcb3aa7f1869ced7a0981f3d47e6a832c6311" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee69fa831cdd5a7ea1aedbb6356a55792b821396f48360a6194f4131eddd1045" +checksum = "b059f22dfc3eb45aa015f6f20f28ed34dc42a65b42d282f8ac9b799b12e2942c" dependencies = [ "multiversx-sc", - "wee_alloc", ] [[package]] @@ -291,9 +271,9 @@ checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -380,18 +360,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wee_alloc" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "memory_units", - "winapi", -] - [[package]] name = "week-timekeeping" version = "0.0.0" @@ -411,25 +379,3 @@ dependencies = [ "unwrappable", "week-timekeeping", ] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/energy-integration/fees-collector/wasm/src/lib.rs b/energy-integration/fees-collector/wasm/src/lib.rs index 141b80dc6..a3065aeaf 100644 --- a/energy-integration/fees-collector/wasm/src/lib.rs +++ b/energy-integration/fees-collector/wasm/src/lib.rs @@ -5,12 +5,15 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 36 +// Endpoints: 37 // Async Callback (empty): 1 -// Total number of exported functions: 38 +// Total number of exported functions: 39 #![no_std] -#![feature(alloc_error_handler, lang_items)] + +// Configuration that works with rustc < 1.73.0. +// TODO: Recommended rustc version: 1.73.0 or newer. +#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -18,43 +21,45 @@ multiversx_sc_wasm_adapter::panic_handler!(); multiversx_sc_wasm_adapter::endpoints! { fees_collector ( - claimRewards - addKnownContracts - removeKnownContracts - addKnownTokens - removeKnownTokens - getLockedTokenId - getAllTokens - getAllKnownContracts - getAllowExternalClaimRewards - getLastActiveWeekForUser - getUserEnergyForWeek - getLastGlobalUpdateWeek - getTotalRewardsForWeek - getTotalEnergyForWeek - getTotalLockedTokensForWeek - updateEnergyForUser - getCurrentClaimProgress - depositSwapFees - getAccumulatedFees - setLockedTokensPerBlock - getLastLockedTokensAddWeek - getLockedTokensPerBlock - setLockingScAddress - setLockEpochs - getLockingScAddress - getLockEpochs - setEnergyFactoryAddress - getEnergyFactoryAddress - getCurrentWeek - getFirstWeekStartEpoch - pause - unpause - isPaused - addSCAddressToWhitelist - removeSCAddressFromWhitelist - isSCAddressWhitelisted + init => init + claimRewards => claim_rewards + addKnownContracts => add_known_contracts + removeKnownContracts => remove_known_contracts + addKnownTokens => add_known_tokens + removeKnownTokens => remove_known_tokens + setAllowExternalClaimRewards => set_allow_external_claim_rewards + getLockedTokenId => locked_token_id + getAllTokens => get_all_tokens + getAllKnownContracts => known_contracts + getAllowExternalClaimRewards => allow_external_claim_rewards + getLastActiveWeekForUser => get_last_active_week_for_user_view + getUserEnergyForWeek => get_user_energy_for_week_view + getLastGlobalUpdateWeek => last_global_update_week + getTotalRewardsForWeek => total_rewards_for_week + getTotalEnergyForWeek => total_energy_for_week + getTotalLockedTokensForWeek => total_locked_tokens_for_week + updateEnergyForUser => update_energy_for_user + getCurrentClaimProgress => current_claim_progress + depositSwapFees => deposit_swap_fees + getAccumulatedFees => accumulated_fees + setLockedTokensPerBlock => set_locked_tokens_per_block + getLastLockedTokensAddWeek => last_locked_token_add_week + getLockedTokensPerBlock => locked_tokens_per_block + setLockingScAddress => set_locking_sc_address + setLockEpochs => set_lock_epochs + getLockingScAddress => locking_sc_address + getLockEpochs => lock_epochs + setEnergyFactoryAddress => set_energy_factory_address + getEnergyFactoryAddress => energy_factory_address + getCurrentWeek => get_current_week + getFirstWeekStartEpoch => first_week_start_epoch + pause => pause_endpoint + unpause => unpause_endpoint + isPaused => paused_status + addSCAddressToWhitelist => add_sc_address_to_whitelist + removeSCAddressFromWhitelist => remove_sc_address_from_whitelist + isSCAddressWhitelisted => is_sc_address_whitelisted ) } -multiversx_sc_wasm_adapter::empty_callback! {} +multiversx_sc_wasm_adapter::async_callback_empty! {} diff --git a/farm-staking/farm-staking-proxy/src/dual_yield_token.rs b/farm-staking/farm-staking-proxy/src/dual_yield_token.rs index f1e2eedd0..56a311d85 100644 --- a/farm-staking/farm-staking-proxy/src/dual_yield_token.rs +++ b/farm-staking/farm-staking-proxy/src/dual_yield_token.rs @@ -1,84 +1,19 @@ use fixed_supply_token::FixedSupplyToken; -use multiversx_sc::codec::{NestedDecodeInput, TopDecodeInput}; multiversx_sc::imports!(); multiversx_sc::derive_imports!(); -#[derive(TypeAbi, TopEncode, PartialEq, Debug, Clone)] +#[derive(TypeAbi, TopEncode, TopDecode, Clone, PartialEq, Debug)] pub struct DualYieldTokenAttributes { pub lp_farm_token_nonce: u64, pub lp_farm_token_amount: BigUint, - pub virtual_pos_token_nonce: u64, - pub virtual_pos_token_amount: BigUint, - pub real_pos_token_amount: BigUint, -} - -impl DualYieldTokenAttributes { - pub fn new( - lp_farm_token_nonce: u64, - lp_farm_token_amount: BigUint, - virtual_pos_token_nonce: u64, - virtual_pos_token_amount: BigUint, - ) -> Self { - DualYieldTokenAttributes { - lp_farm_token_nonce, - lp_farm_token_amount, - virtual_pos_token_nonce, - virtual_pos_token_amount, - real_pos_token_amount: BigUint::zero(), - } - } - - pub fn get_total_staking_token_amount(&self) -> BigUint { - &self.virtual_pos_token_amount + &self.real_pos_token_amount - } -} - -impl TopDecode for DualYieldTokenAttributes { - fn top_decode(input: I) -> Result - where - I: TopDecodeInput, - { - let mut buffer = input.into_nested_buffer(); - Self::dep_decode(&mut buffer) - } -} - -impl NestedDecode for DualYieldTokenAttributes { - fn dep_decode(input: &mut I) -> Result { - let lp_farm_token_nonce = u64::dep_decode(input)?; - let lp_farm_token_amount = BigUint::dep_decode(input)?; - let virtual_pos_token_nonce = u64::dep_decode(input)?; - let virtual_pos_token_amount = BigUint::dep_decode(input)?; - - if input.is_depleted() { - return Result::Ok(DualYieldTokenAttributes::new( - lp_farm_token_nonce, - lp_farm_token_amount, - virtual_pos_token_nonce, - virtual_pos_token_amount, - )); - } - - let real_pos_token_amount = BigUint::dep_decode(input)?; - - if !input.is_depleted() { - return Result::Err(DecodeError::INPUT_TOO_LONG); - } - - Result::Ok(DualYieldTokenAttributes { - lp_farm_token_nonce, - lp_farm_token_amount, - virtual_pos_token_nonce, - virtual_pos_token_amount, - real_pos_token_amount, - }) - } + pub staking_farm_token_nonce: u64, + pub staking_farm_token_amount: BigUint, } impl FixedSupplyToken for DualYieldTokenAttributes { fn get_total_supply(&self) -> BigUint { - self.virtual_pos_token_amount.clone() + self.staking_farm_token_amount.clone() } fn into_part(self, payment_amount: &BigUint) -> Self { @@ -88,15 +23,13 @@ impl FixedSupplyToken for DualYieldTokenAttributes { let new_lp_farm_token_amount = self.rule_of_three_non_zero_result(payment_amount, &self.lp_farm_token_amount); - let new_virtual_pos_amount = payment_amount.clone(); - let new_real_pos_amount = self.rule_of_three(payment_amount, &self.real_pos_token_amount); + let new_staking_farm_token_amount = payment_amount.clone(); DualYieldTokenAttributes { lp_farm_token_nonce: self.lp_farm_token_nonce, lp_farm_token_amount: new_lp_farm_token_amount, - virtual_pos_token_nonce: self.virtual_pos_token_nonce, - virtual_pos_token_amount: new_virtual_pos_amount, - real_pos_token_amount: new_real_pos_amount, + staking_farm_token_nonce: self.staking_farm_token_nonce, + staking_farm_token_amount: new_staking_farm_token_amount, } } } diff --git a/farm-staking/farm-staking-proxy/src/external_contracts_interactions.rs b/farm-staking/farm-staking-proxy/src/external_contracts_interactions.rs index 933a93cfd..17d32d056 100644 --- a/farm-staking/farm-staking-proxy/src/external_contracts_interactions.rs +++ b/farm-staking/farm-staking-proxy/src/external_contracts_interactions.rs @@ -47,21 +47,19 @@ pub trait ExternalContractsInteractionsModule: orig_caller: ManagedAddress, lp_farm_token_nonce: u64, lp_farm_token_amount: BigUint, - exit_amount: BigUint, ) -> LpFarmExitResult { let lp_farm_token_id = self.lp_farm_token_id().get(); let lp_farm_address = self.lp_farm_address().get(); let exit_farm_result: ExitFarmWithPartialPosResultType = self .lp_farm_proxy_obj(lp_farm_address) - .exit_farm_endpoint(exit_amount, orig_caller) + .exit_farm_endpoint(orig_caller) .with_esdt_transfer((lp_farm_token_id, lp_farm_token_nonce, lp_farm_token_amount)) .execute_on_dest_context(); - let (lp_tokens, lp_farm_rewards, remaining_farm_tokens) = exit_farm_result.into_tuple(); + let (lp_tokens, lp_farm_rewards) = exit_farm_result.into_tuple(); LpFarmExitResult { lp_tokens, lp_farm_rewards, - remaining_farm_tokens, } } @@ -138,7 +136,6 @@ pub trait ExternalContractsInteractionsModule: staking_tokens: EsdtTokenPayment, farm_token_nonce: u64, farm_token_amount: BigUint, - exit_amount: BigUint, ) -> StakingFarmExitResult { let staking_farm_token_id = self.staking_farm_token_id().get(); let mut payments = ManagedVec::from_single_item(staking_tokens); @@ -151,40 +148,14 @@ pub trait ExternalContractsInteractionsModule: let staking_farm_address = self.staking_farm_address().get(); let unstake_result: ExitFarmWithPartialPosResultType = self .staking_farm_proxy_obj(staking_farm_address) - .unstake_farm_through_proxy(exit_amount, orig_caller) + .unstake_farm_through_proxy(orig_caller) .with_multi_token_transfer(payments) .execute_on_dest_context(); - let (unbond_staking_farm_token, staking_rewards, remaining_farm_tokens) = - unstake_result.into_tuple(); + let (unbond_staking_farm_token, staking_rewards) = unstake_result.into_tuple(); StakingFarmExitResult { unbond_staking_farm_token, staking_rewards, - remaining_farm_tokens, - } - } - - fn staking_farm_unstake_user_position( - &self, - orig_caller: ManagedAddress, - farm_token_nonce: u64, - farm_token_amount: BigUint, - exit_amount: BigUint, - ) -> StakingFarmExitResult { - let staking_farm_token_id = self.staking_farm_token_id().get(); - let staking_farm_address = self.staking_farm_address().get(); - let unstake_result: ExitFarmWithPartialPosResultType = self - .staking_farm_proxy_obj(staking_farm_address) - .unstake_farm(exit_amount, orig_caller) - .with_esdt_transfer((staking_farm_token_id, farm_token_nonce, farm_token_amount)) - .execute_on_dest_context(); - let (unbond_staking_farm_token, staking_rewards, remaining_farm_tokens) = - unstake_result.into_tuple(); - - StakingFarmExitResult { - unbond_staking_farm_token, - staking_rewards, - remaining_farm_tokens, } } diff --git a/farm-staking/farm-staking-proxy/src/proxy_actions/claim.rs b/farm-staking/farm-staking-proxy/src/proxy_actions/claim.rs index 3f90583e2..fe84fa65d 100644 --- a/farm-staking/farm-staking-proxy/src/proxy_actions/claim.rs +++ b/farm-staking/farm-staking-proxy/src/proxy_actions/claim.rs @@ -34,7 +34,7 @@ pub trait ProxyClaimModule: let internal_claim_result = self.claim_dual_yield( &caller, opt_orig_caller, - attributes.get_total_staking_token_amount(), + attributes.staking_farm_token_amount.clone(), attributes, ); @@ -66,8 +66,7 @@ pub trait ProxyClaimModule: attributes.lp_farm_token_nonce, &attributes.lp_farm_token_amount, ); - let lp_tokens_safe_price = self.get_lp_tokens_safe_price(lp_tokens_in_position); - let new_staking_farm_value = &lp_tokens_safe_price + &attributes.real_pos_token_amount; + let new_staking_farm_value = self.get_lp_tokens_safe_price(lp_tokens_in_position); let staking_farm_token_id = self.staking_farm_token_id().get(); let lp_farm_token_id = self.lp_farm_token_id().get(); @@ -80,7 +79,7 @@ pub trait ProxyClaimModule: let staking_farm_claim_rewards_result = self.staking_farm_claim_rewards( orig_caller, staking_farm_token_id, - attributes.virtual_pos_token_nonce, + attributes.staking_farm_token_nonce, staking_claim_amount, new_staking_farm_value, ); @@ -90,9 +89,8 @@ pub trait ProxyClaimModule: let new_attributes = DualYieldTokenAttributes { lp_farm_token_nonce: new_lp_farm_tokens.token_nonce, lp_farm_token_amount: new_lp_farm_tokens.amount, - virtual_pos_token_nonce: new_staking_farm_tokens.token_nonce, - virtual_pos_token_amount: lp_tokens_safe_price, - real_pos_token_amount: attributes.real_pos_token_amount, + staking_farm_token_nonce: new_staking_farm_tokens.token_nonce, + staking_farm_token_amount: new_staking_farm_tokens.amount, }; InternalClaimResult { diff --git a/farm-staking/farm-staking-proxy/src/proxy_actions/merge_pos.rs b/farm-staking/farm-staking-proxy/src/proxy_actions/merge_pos.rs deleted file mode 100644 index 2a81f2cf4..000000000 --- a/farm-staking/farm-staking-proxy/src/proxy_actions/merge_pos.rs +++ /dev/null @@ -1,108 +0,0 @@ -farm-staking/farm-staking-proxy/tests/composed_pos_test.rsuse common_structs::PaymentsVec; - -use crate::{dual_yield_token::DualYieldTokenAttributes, result_types::MergeResult}; - -use mergeable::Mergeable; -use unwrappable::Unwrappable; - -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); - -#[multiversx_sc::module] -pub trait ProxyMergePosModule: - crate::dual_yield_token::DualYieldTokenModule - + crate::external_contracts_interactions::ExternalContractsInteractionsModule - + crate::lp_farm_token::LpFarmTokenModule - + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule - + utils::UtilsModule - + token_send::TokenSendModule - + sc_whitelist_module::SCWhitelistModule - + super::claim::ProxyClaimModule -{ - #[payable("*")] - #[endpoint(mergeMetastakingWithStakingToken)] - fn merge_metastaking_with_staking_token(&self) -> MergeResult { - let mut payments = self.call_value().all_esdt_transfers().clone_value(); - require!( - payments.len() >= 2, - "Must send metastaking token and at least a staking token" - ); - - let dual_yield_token = self.pop_first_payment(&mut payments); - let dual_yield_token_mapper = self.dual_yield_token(); - dual_yield_token_mapper.require_same_token(&dual_yield_token.token_identifier); - - let mut attributes: DualYieldTokenAttributes = self - .get_attributes_as_part_of_fixed_supply(&dual_yield_token, &dual_yield_token_mapper); - dual_yield_token_mapper.nft_burn(dual_yield_token.token_nonce, &dual_yield_token.amount); - - let caller = self.blockchain().get_caller(); - let staking_farm_rewards = self.claim_staking_rewards_before_merge(&caller, &payments); - - let staking_amount_before_merge = attributes.get_total_staking_token_amount(); - for farm_staking_token in &payments { - attributes.real_pos_token_amount += &farm_staking_token.amount; - } - - let mut dual_yield_claim_result = self.claim_dual_yield( - &caller, - OptionalValue::None, - staking_amount_before_merge, - attributes, - ); - dual_yield_claim_result - .staking_farm_rewards - .merge_with(staking_farm_rewards); - - let new_dual_yield_tokens = self.create_dual_yield_tokens( - &dual_yield_token_mapper, - &dual_yield_claim_result.new_dual_yield_attributes, - ); - let merge_result = MergeResult { - lp_farm_rewards: dual_yield_claim_result.lp_farm_rewards, - staking_farm_rewards: dual_yield_claim_result.staking_farm_rewards, - new_dual_yield_tokens, - }; - - merge_result.send_and_return(self, &caller) - } - - fn claim_staking_rewards_before_merge( - &self, - caller: &ManagedAddress, - farm_staking_tokens: &PaymentsVec, - ) -> EsdtTokenPayment { - let staking_farm_token_id = self.staking_farm_token_id().get(); - let mut opt_staking_farm_rewards = Option::::None; - for farm_staking_token in farm_staking_tokens { - require!( - farm_staking_token.token_identifier == staking_farm_token_id, - "Invalid staking farm token" - ); - - let staking_claim_result = self.staking_farm_claim_rewards( - caller.clone(), - farm_staking_token.token_identifier, - farm_staking_token.token_nonce, - farm_staking_token.amount.clone(), - farm_staking_token.amount, - ); - - match &mut opt_staking_farm_rewards { - Some(rew) => rew.merge_with(staking_claim_result.staking_farm_rewards), - None => { - opt_staking_farm_rewards = Some(staking_claim_result.staking_farm_rewards); - } - }; - - let new_staking_farm_tokens = staking_claim_result.new_staking_farm_tokens; - self.send().esdt_local_burn( - &new_staking_farm_tokens.token_identifier, - new_staking_farm_tokens.token_nonce, - &new_staking_farm_tokens.amount, - ); - } - - opt_staking_farm_rewards.unwrap_or_panic::() - } -} diff --git a/farm-staking/farm-staking-proxy/src/proxy_actions/stake.rs b/farm-staking/farm-staking-proxy/src/proxy_actions/stake.rs index 1cfe2047c..d39dd7f2c 100644 --- a/farm-staking/farm-staking-proxy/src/proxy_actions/stake.rs +++ b/farm-staking/farm-staking-proxy/src/proxy_actions/stake.rs @@ -36,15 +36,14 @@ pub trait ProxyStakeModule: let staking_farm_token_id = self.staking_farm_token_id().get(); let mut additional_staking_farm_tokens = ManagedVec::new(); let mut additional_lp_farm_tokens = ManagedVec::new(); - let mut total_user_real_staking_tokens = BigUint::zero(); for p in &additional_payments { let attributes: DualYieldTokenAttributes = self.get_attributes_as_part_of_fixed_supply(&p, &dual_yield_token_mapper); additional_staking_farm_tokens.push(EsdtTokenPayment::new( staking_farm_token_id.clone(), - attributes.virtual_pos_token_nonce, - attributes.get_total_staking_token_amount(), + attributes.staking_farm_token_nonce, + attributes.staking_farm_token_amount, )); additional_lp_farm_tokens.push(EsdtTokenPayment::new( @@ -53,8 +52,6 @@ pub trait ProxyStakeModule: attributes.lp_farm_token_amount, )); - total_user_real_staking_tokens += attributes.real_pos_token_amount; - dual_yield_token_mapper.nft_burn(p.token_nonce, &p.amount); } @@ -76,14 +73,11 @@ pub trait ProxyStakeModule: additional_lp_farm_tokens, ); - let new_staking_farm_token_amount = - &received_staking_farm_token.amount - &total_user_real_staking_tokens; let new_attributes = DualYieldTokenAttributes { lp_farm_token_nonce: merged_lp_farm_tokens.token_nonce, lp_farm_token_amount: merged_lp_farm_tokens.amount, - virtual_pos_token_nonce: received_staking_farm_token.token_nonce, - virtual_pos_token_amount: new_staking_farm_token_amount, - real_pos_token_amount: total_user_real_staking_tokens, + staking_farm_token_nonce: received_staking_farm_token.token_nonce, + staking_farm_token_amount: received_staking_farm_token.amount, }; let new_dual_yield_tokens = self.create_dual_yield_tokens(&dual_yield_token_mapper, &new_attributes); diff --git a/farm-staking/farm-staking-proxy/src/proxy_actions/unstake.rs b/farm-staking/farm-staking-proxy/src/proxy_actions/unstake.rs index 59e65f4e0..2faf021a3 100644 --- a/farm-staking/farm-staking-proxy/src/proxy_actions/unstake.rs +++ b/farm-staking/farm-staking-proxy/src/proxy_actions/unstake.rs @@ -1,5 +1,4 @@ use fixed_supply_token::FixedSupplyToken; -use mergeable::Mergeable; use crate::{dual_yield_token::DualYieldTokenAttributes, result_types::UnstakeResult}; @@ -21,7 +20,6 @@ pub trait ProxyUnstakeModule: &self, pair_first_token_min_amount: BigUint, pair_second_token_min_amount: BigUint, - exit_amount: BigUint, opt_orig_caller: OptionalValue, ) -> UnstakeResult { let caller = self.blockchain().get_caller(); @@ -32,24 +30,13 @@ pub trait ProxyUnstakeModule: let full_attributes: DualYieldTokenAttributes = dual_yield_token_mapper.get_token_attributes(payment.token_nonce); - let total_for_nonce = full_attributes.get_total_supply(); - require!( - payment.amount == total_for_nonce, - "Must exit with full position as payment" - ); - require!( - exit_amount > 0 && exit_amount <= payment.amount, - "Invalid exit amount" - ); - let full_staking_token_amount = full_attributes.get_total_staking_token_amount(); let exit_attributes: DualYieldTokenAttributes = - full_attributes.clone().into_part(&exit_amount); + full_attributes.into_part(&payment.amount); let lp_farm_exit_result = self.lp_farm_exit( orig_caller.clone(), - full_attributes.lp_farm_token_nonce, - full_attributes.lp_farm_token_amount, + exit_attributes.lp_farm_token_nonce, exit_attributes.lp_farm_token_amount, ); let remove_liq_result = self.pair_remove_liquidity( @@ -58,64 +45,19 @@ pub trait ProxyUnstakeModule: pair_second_token_min_amount, ); - let remaining_total_staking_farm_tokens = - &full_staking_token_amount - &exit_attributes.virtual_pos_token_amount; let staking_farm_exit_result = self.staking_farm_unstake( orig_caller.clone(), remove_liq_result.staking_token_payment, - full_attributes.virtual_pos_token_nonce, - full_staking_token_amount, - exit_attributes.virtual_pos_token_amount.clone(), + exit_attributes.staking_farm_token_nonce, + exit_attributes.staking_farm_token_amount, ); - let opt_unstake_user_pos_result = if exit_attributes.real_pos_token_amount > 0 { - let res = self.staking_farm_unstake_user_position( - orig_caller, - full_attributes.virtual_pos_token_nonce, - remaining_total_staking_farm_tokens, - exit_attributes.real_pos_token_amount.clone(), - ); - Some(res) - } else { - None - }; - - let opt_new_dual_yield_tokens = if exit_amount != total_for_nonce { - let remaining_lp_farm_tokens = lp_farm_exit_result.remaining_farm_tokens.amount; - let remaining_virtual_farm_tokens = - full_attributes.virtual_pos_token_amount - exit_attributes.virtual_pos_token_amount; - let remaining_real_farm_tokens = - full_attributes.real_pos_token_amount - exit_attributes.real_pos_token_amount; - let new_attributes = DualYieldTokenAttributes { - lp_farm_token_nonce: full_attributes.lp_farm_token_nonce, - lp_farm_token_amount: remaining_lp_farm_tokens, - virtual_pos_token_nonce: full_attributes.virtual_pos_token_nonce, - virtual_pos_token_amount: remaining_virtual_farm_tokens, - real_pos_token_amount: remaining_real_farm_tokens, - }; - let new_dual_yield_tokens = - self.create_dual_yield_tokens(&dual_yield_token_mapper, &new_attributes); - - Some(new_dual_yield_tokens) - } else { - None - }; - - let mut total_staking_rewards = staking_farm_exit_result.staking_rewards; - let opt_unbond_token = opt_unstake_user_pos_result.map(|res| { - total_staking_rewards.merge_with(res.staking_rewards); - - res.unbond_staking_farm_token - }); - let caller = self.blockchain().get_caller(); let unstake_result = UnstakeResult { other_token_payment: remove_liq_result.other_token_payment, lp_farm_rewards: lp_farm_exit_result.lp_farm_rewards, - staking_rewards: total_staking_rewards, + staking_rewards: staking_farm_exit_result.staking_rewards, unbond_staking_farm_token: staking_farm_exit_result.unbond_staking_farm_token, - opt_unbond_staking_farm_token_for_user_pos: opt_unbond_token, - opt_new_dual_yield_tokens, }; dual_yield_token_mapper.nft_burn(payment.token_nonce, &payment.amount); diff --git a/farm-staking/farm-staking-proxy/src/result_types.rs b/farm-staking/farm-staking-proxy/src/result_types.rs index f1adc4335..65e0cf238 100644 --- a/farm-staking/farm-staking-proxy/src/result_types.rs +++ b/farm-staking/farm-staking-proxy/src/result_types.rs @@ -13,7 +13,6 @@ pub struct LpFarmClaimRewardsResult { pub struct LpFarmExitResult { pub lp_tokens: EsdtTokenPayment, pub lp_farm_rewards: EsdtTokenPayment, - pub remaining_farm_tokens: EsdtTokenPayment, } // staking farm @@ -31,7 +30,6 @@ pub struct StakingFarmClaimRewardsResult { pub struct StakingFarmExitResult { pub unbond_staking_farm_token: EsdtTokenPayment, pub staking_rewards: EsdtTokenPayment, - pub remaining_farm_tokens: EsdtTokenPayment, } // pair @@ -92,8 +90,6 @@ pub struct UnstakeResult { pub lp_farm_rewards: EsdtTokenPayment, pub staking_rewards: EsdtTokenPayment, pub unbond_staking_farm_token: EsdtTokenPayment, - pub opt_unbond_staking_farm_token_for_user_pos: Option>, - pub opt_new_dual_yield_tokens: Option>, } impl UnstakeResult { @@ -108,14 +104,6 @@ impl UnstakeResult { payments.push(self.staking_rewards.clone()); payments.push(self.unbond_staking_farm_token.clone()); - if let Some(unbond_for_user_pos) = &self.opt_unbond_staking_farm_token_for_user_pos { - payments.push(unbond_for_user_pos.clone()); - } - - if let Some(new_dual_yield_tokens) = &self.opt_new_dual_yield_tokens { - payments.push(new_dual_yield_tokens.clone()); - } - sc.send_multiple_tokens_if_not_zero(to, &payments); self 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 b15c69cc0..c81d579ab 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 @@ -226,26 +226,6 @@ fn unstake_partial_position_test() { let dual_yield_token_amount = 1_001_000_000; - // unstake with half position - wrong payment amount - setup - .b_mock - .execute_esdt_transfer( - &setup.user_addr, - &setup.proxy_wrapper, - DUAL_YIELD_TOKEN_ID, - dual_yield_token_nonce_after_stake, - &rust_biguint!(dual_yield_token_amount / 2), - |sc| { - let _ = sc.unstake_farm_tokens( - managed_biguint!(1), - managed_biguint!(1), - managed_biguint!(dual_yield_token_amount / 4), - OptionalValue::None, - ); - }, - ) - .assert_user_error("Must exit with full position as payment"); - // unstake with half position - ok setup .b_mock @@ -254,12 +234,11 @@ fn unstake_partial_position_test() { &setup.proxy_wrapper, DUAL_YIELD_TOKEN_ID, dual_yield_token_nonce_after_stake, - &rust_biguint!(dual_yield_token_amount), + &rust_biguint!(dual_yield_token_amount / 2), |sc| { let results = sc.unstake_farm_tokens( managed_biguint!(1), managed_biguint!(1), - managed_biguint!(dual_yield_token_amount / 2), OptionalValue::None, ); @@ -268,7 +247,7 @@ fn unstake_partial_position_test() { wegld_payment.token_identifier, managed_token_id!(WEGLD_TOKEN_ID) ); - assert_eq!(wegld_payment.amount, 1_001_000_000 / 2); + assert_eq!(wegld_payment.amount, dual_yield_token_amount / 2); let lp_farm_rewards = results.lp_farm_rewards; assert_eq!( @@ -289,49 +268,24 @@ fn unstake_partial_position_test() { unbond_tokens.token_identifier, managed_token_id!(STAKING_FARM_TOKEN_ID) ); - assert_eq!(unbond_tokens.amount, 1_001_000_000 / 2); - - let new_dual_yield_tokens = results.opt_new_dual_yield_tokens.unwrap(); - assert_eq!( - new_dual_yield_tokens.token_identifier, - managed_token_id!(DUAL_YIELD_TOKEN_ID) - ); - assert_eq!(new_dual_yield_tokens.amount, 1_001_000_000 / 2); + assert_eq!(unbond_tokens.amount, dual_yield_token_amount / 2); }, ) .assert_ok(); - let expected_new_dual_yield_attributes = DualYieldTokenAttributes:: { - lp_farm_token_nonce: 1, - lp_farm_token_amount: managed_biguint!(USER_TOTAL_LP_TOKENS / 2), - virtual_pos_token_nonce: 1, - virtual_pos_token_amount: managed_biguint!(1_001_000_000 / 2), - real_pos_token_amount: managed_biguint!(0), - }; - let new_dual_yield_token_nonce = dual_yield_token_nonce_after_stake + 1; - let new_dual_yield_token_amount = dual_yield_token_amount / 2; - setup.b_mock.check_nft_balance( - &setup.user_addr, - DUAL_YIELD_TOKEN_ID, - new_dual_yield_token_nonce, - &rust_biguint!(new_dual_yield_token_amount), - Some(&expected_new_dual_yield_attributes), - ); - - // unstake with the new dual yield tokens + // unstake with the remaining dual yield tokens setup .b_mock .execute_esdt_transfer( &setup.user_addr, &setup.proxy_wrapper, DUAL_YIELD_TOKEN_ID, - new_dual_yield_token_nonce, - &rust_biguint!(new_dual_yield_token_amount), + dual_yield_token_nonce_after_stake, + &rust_biguint!(dual_yield_token_amount / 2), |sc| { let results = sc.unstake_farm_tokens( managed_biguint!(1), managed_biguint!(1), - managed_biguint!(new_dual_yield_token_amount), OptionalValue::None, ); @@ -362,9 +316,6 @@ fn unstake_partial_position_test() { managed_token_id!(STAKING_FARM_TOKEN_ID) ); assert_eq!(unbond_tokens.amount, 1_001_000_000 / 2); - - // no new dual yield tokens created - assert!(results.opt_new_dual_yield_tokens.is_none()); }, ) .assert_ok(); @@ -464,9 +415,8 @@ fn test_stake_farm_through_proxy_with_merging() { Some(&DualYieldTokenAttributes:: { lp_farm_token_nonce: 1, lp_farm_token_amount: managed_biguint!(400_000_000), - virtual_pos_token_nonce: 1, - virtual_pos_token_amount: managed_biguint!(400_000_000), - real_pos_token_amount: managed_biguint!(0), + staking_farm_token_nonce: 1, + staking_farm_token_amount: managed_biguint!(400_000_000), }), ) }); @@ -495,9 +445,8 @@ fn test_stake_farm_through_proxy_with_merging() { Some(&DualYieldTokenAttributes:: { lp_farm_token_nonce: 2, lp_farm_token_amount: managed_biguint!(1_000_000_000), - virtual_pos_token_nonce: 2, - virtual_pos_token_amount: managed_biguint!(1_000_000_000), - real_pos_token_amount: managed_biguint!(0), + staking_farm_token_nonce: 2, + staking_farm_token_amount: managed_biguint!(1_000_000_000), }), ) }); 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 8be6d9b13..00b2e2e0f 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 @@ -156,9 +156,8 @@ where let expected_dual_yield_attributes = DualYieldTokenAttributes:: { lp_farm_token_nonce, lp_farm_token_amount: managed_biguint!(lp_farm_token_stake_amount), - virtual_pos_token_nonce: expected_staking_farm_token_nonce, - virtual_pos_token_amount: managed_biguint!(expected_staking_token_amount), - real_pos_token_amount: managed_biguint!(0), + staking_farm_token_nonce: expected_staking_farm_token_nonce, + staking_farm_token_amount: managed_biguint!(expected_staking_token_amount), }; self.b_mock.check_nft_balance( @@ -272,7 +271,6 @@ where let received_tokens = sc.unstake_farm_tokens( managed_biguint!(1), managed_biguint!(1), - managed_biguint!(dual_yield_token_amount), OptionalValue::None, ); @@ -406,9 +404,8 @@ where farm_token_nonce, &rust_biguint!(farm_token_amount), |sc| { - let (unbond_farm_tokens, reward_tokens, _) = sc - .unstake_farm(managed_biguint!(farm_token_amount), OptionalValue::None) - .into_tuple(); + let (unbond_farm_tokens, reward_tokens) = + sc.unstake_farm(OptionalValue::None).into_tuple(); unbond_token_nonce = unbond_farm_tokens.token_nonce; assert_eq!(reward_tokens.amount, expected_rewards_amount); diff --git a/farm-staking/farm-staking-proxy/wasm/Cargo.lock b/farm-staking/farm-staking-proxy/wasm/Cargo.lock index 6b8cfa51d..45a3fea4f 100644 --- a/farm-staking/farm-staking-proxy/wasm/Cargo.lock +++ b/farm-staking/farm-staking-proxy/wasm/Cargo.lock @@ -8,7 +8,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "once_cell", "version_check", ] @@ -31,12 +31,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -345,12 +339,6 @@ dependencies = [ "utils", ] -[[package]] -name = "libc" -version = "0.2.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" - [[package]] name = "locking_module" version = "0.0.0" @@ -367,12 +355,6 @@ dependencies = [ "multiversx-sc", ] -[[package]] -name = "memory_units" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" - [[package]] name = "mergeable" version = "0.0.0" @@ -382,9 +364,9 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecfb3e03ac6e08114963a54e15a3c78c28e57cc0e31836e870450b35085bdf8d" +checksum = "386c2727eba66bc5e502e470d7afa55fdd69aedff440c508bb9ba85aec36a52a" dependencies = [ "bitflags", "hashbrown", @@ -396,20 +378,19 @@ dependencies = [ [[package]] name = "multiversx-sc-codec" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7638cb46a0e99c636fd55443ac534ff0a5fad0bd772e1037fbac9a75e04c3c9" +checksum = "0f1e15b46c17b87c0c7cdd79b041a4abd7f3a2b45f3c993f6ce38c0f233e82b6" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", - "wee_alloc", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e976002d51367f16140929c10ee695f95dd8d34c150a45db60d3fcd1328a267a" +checksum = "9a7bc0762cd6d88f8bc54805bc652b042a61cd7fbc2d0a325010f088b78fb2ac" dependencies = [ "hex", "proc-macro2", @@ -419,9 +400,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6eb54a7d452eb09f5de159ee9b4d1fb9ec79cf49f1602ebd3efc8532015a4ea" +checksum = "050510b6b9836b24b4a73bb7878c58c268d56bde1c6eb0f9a88dce9a6518507b" dependencies = [ "hex", "proc-macro2", @@ -432,21 +413,20 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12284a3e31c0852b6ca0ce8306d3f404c3712b996a05ed78e97e765c98461f3" +checksum = "3b55fe3585cbc745bd7b9793be4bcb3aa7f1869ced7a0981f3d47e6a832c6311" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee69fa831cdd5a7ea1aedbb6356a55792b821396f48360a6194f4131eddd1045" +checksum = "b059f22dfc3eb45aa015f6f20f28ed34dc42a65b42d282f8ac9b799b12e2942c" dependencies = [ "multiversx-sc", - "wee_alloc", ] [[package]] @@ -507,9 +487,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -628,18 +608,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wee_alloc" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "memory_units", - "winapi", -] - [[package]] name = "week-timekeeping" version = "0.0.0" @@ -659,25 +627,3 @@ dependencies = [ "unwrappable", "week-timekeeping", ] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/farm-staking/farm-staking-proxy/wasm/src/lib.rs b/farm-staking/farm-staking-proxy/wasm/src/lib.rs index 57bdc0840..4223b260d 100644 --- a/farm-staking/farm-staking-proxy/wasm/src/lib.rs +++ b/farm-staking/farm-staking-proxy/wasm/src/lib.rs @@ -10,7 +10,10 @@ // Total number of exported functions: 17 #![no_std] -#![feature(alloc_error_handler, lang_items)] + +// Configuration that works with rustc < 1.73.0. +// TODO: Recommended rustc version: 1.73.0 or newer. +#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -18,21 +21,23 @@ multiversx_sc_wasm_adapter::panic_handler!(); multiversx_sc_wasm_adapter::endpoints! { farm_staking_proxy ( - registerDualYieldToken - getDualYieldTokenId - getLpFarmAddress - getStakingFarmAddress - getPairAddress - getStakingTokenId - getFarmTokenId - getLpTokenId - getLpFarmTokenId - addSCAddressToWhitelist - removeSCAddressFromWhitelist - isSCAddressWhitelisted - stakeFarmTokens - claimDualYield - unstakeFarmTokens - callBack + init => init + registerDualYieldToken => register_dual_yield_token + getDualYieldTokenId => dual_yield_token + getLpFarmAddress => lp_farm_address + getStakingFarmAddress => staking_farm_address + getPairAddress => pair_address + getStakingTokenId => staking_token_id + getFarmTokenId => staking_farm_token_id + getLpTokenId => lp_token_id + getLpFarmTokenId => lp_farm_token_id + addSCAddressToWhitelist => add_sc_address_to_whitelist + removeSCAddressFromWhitelist => remove_sc_address_from_whitelist + isSCAddressWhitelisted => is_sc_address_whitelisted + stakeFarmTokens => stake_farm_tokens + claimDualYield => claim_dual_yield_endpoint + unstakeFarmTokens => unstake_farm_tokens ) } + +multiversx_sc_wasm_adapter::async_callback! { farm_staking_proxy } diff --git a/farm-staking/farm-staking/elrond.json b/farm-staking/farm-staking/elrond.json deleted file mode 100644 index 736553962..000000000 --- a/farm-staking/farm-staking/elrond.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "language": "rust" -} \ No newline at end of file diff --git a/farm-staking/farm-staking/src/base_impl_wrapper.rs b/farm-staking/farm-staking/src/base_impl_wrapper.rs index adf6136a5..2b671677f 100644 --- a/farm-staking/farm-staking/src/base_impl_wrapper.rs +++ b/farm-staking/farm-staking/src/base_impl_wrapper.rs @@ -47,18 +47,16 @@ where pub fn calculate_boosted_rewards( sc: &::FarmSc, caller: &ManagedAddress<<::FarmSc as ContractBase>::Api>, - token_attributes: &::AttributesType, ) -> BigUint<<::FarmSc as ContractBase>::Api> { - if &token_attributes.original_owner != caller { - sc.update_energy_and_progress(caller); - } - let user_total_farm_position_struct = sc.get_user_total_farm_position_struct(caller); - let user_total_farm_position = user_total_farm_position_struct.total_farm_position; - if user_total_farm_position == BigUint::zero() { - return BigUint::zero(); + let user_total_farm_position = sc.get_user_total_farm_position(caller); + let user_farm_position = user_total_farm_position.total_farm_position; + let mut boosted_rewards = BigUint::zero(); + + if user_farm_position > 0 { + boosted_rewards = sc.claim_boosted_yields_rewards(caller, user_farm_position); } - sc.claim_boosted_yields_rewards(caller, user_total_farm_position) + boosted_rewards } } @@ -137,7 +135,7 @@ where ) -> BigUint<::Api> { let base_farm_reward = Self::calculate_base_farm_rewards(farm_token_amount, token_attributes, storage_cache); - let boosted_yield_rewards = Self::calculate_boosted_rewards(sc, caller, token_attributes); + let boosted_yield_rewards = Self::calculate_boosted_rewards(sc, caller); base_farm_reward + boosted_yield_rewards } @@ -193,50 +191,54 @@ where farm_positions: &PaymentsVec<::Api>, ) { let farm_token_mapper = sc.farm_token(); - let mut total_farm_position = BigUint::zero(); - let mut farm_position_increase = BigUint::zero(); 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); - total_farm_position += &farm_position.amount; 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); - farm_position_increase += &farm_position.amount; + Self::increase_user_farm_position(sc, user, &farm_position.amount); } } - let user_total_farm_position_struct = sc.get_user_total_farm_position_struct(user); - if user_total_farm_position_struct.total_farm_position == BigUint::zero() { - Self::increase_user_farm_position(sc, user, &total_farm_position); - } else if farm_position_increase > 0 { - Self::increase_user_farm_position(sc, user, &farm_position_increase); - } } + #[inline] fn increase_user_farm_position( sc: &Self::FarmSc, user: &ManagedAddress<::Api>, - new_farm_position_amount: &BigUint<::Api>, + increase_farm_position_amount: &BigUint<::Api>, ) { + let mut user_total_farm_position = sc.get_user_total_farm_position(user); + user_total_farm_position.total_farm_position += increase_farm_position_amount; sc.user_total_farm_position(user) - .update(|user_farm_position_struct| { - user_farm_position_struct.total_farm_position += new_farm_position_amount - }); + .set(user_total_farm_position); } 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); sc.user_total_farm_position(&token_attributes.original_owner) - .update(|user_farm_position_struct| { - user_farm_position_struct.total_farm_position -= farm_position.amount.clone() + .update(|user_total_farm_position| { + if user_total_farm_position.total_farm_position > farm_position.amount { + user_total_farm_position.total_farm_position -= &farm_position.amount; + } else { + user_total_farm_position.total_farm_position = BigUint::zero(); + } }); } } 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 03253057b..71e7ab9e3 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 @@ -30,53 +30,65 @@ pub trait ClaimOnlyBoostedStakingRewardsModule: let caller = self.blockchain().get_caller(); let user = match &opt_user { OptionalValue::Some(user) => user, - #[allow(clippy::redundant_clone)] OptionalValue::None => &caller, }; - let user_total_farm_position_struct = self.get_user_total_farm_position_struct(user); + let user_total_farm_position = self.get_user_total_farm_position(user); if user != &caller { require!( - user_total_farm_position_struct.allow_external_claim_boosted_rewards, + user_total_farm_position.allow_external_claim_boosted_rewards, "Cannot claim rewards for this address" ); } - let reward_token_id = self.reward_token_id().get(); - let user_total_farm_position = user_total_farm_position_struct.total_farm_position; - if user_total_farm_position == BigUint::zero() { - return EsdtTokenPayment::new(reward_token_id, 0, BigUint::zero()); - } - let reward = self.claim_boosted_yields_rewards(user, user_total_farm_position); - if reward > 0 { - self.reward_reserve().update(|reserve| *reserve -= &reward); + let boosted_rewards = self.claim_only_boosted_payment(user); + let boosted_rewards_payment = + EsdtTokenPayment::new(self.reward_token_id().get(), 0, boosted_rewards); + + self.send_payment_non_zero(user, &boosted_rewards_payment); + + boosted_rewards_payment + } + + fn migrate_old_farm_positions(&self, caller: &ManagedAddress) -> BigUint { + let payments = self.call_value().all_esdt_transfers().clone_value(); + let farm_token_mapper = self.farm_token(); + let farm_token_id = farm_token_mapper.get_token_id(); + let mut migrated_amount = BigUint::zero(); + for farm_position in &payments { + if farm_position.token_identifier == farm_token_id + && self.is_old_farm_position(farm_position.token_nonce) + { + migrated_amount += farm_position.amount; + } } - let boosted_rewards = EsdtTokenPayment::new(reward_token_id, 0, reward); - self.send_payment_non_zero(user, &boosted_rewards); + if migrated_amount > 0 { + let mut user_total_farm_position = self.get_user_total_farm_position(caller); + user_total_farm_position.total_farm_position += &migrated_amount; + self.user_total_farm_position(caller) + .set(user_total_farm_position); + } - self.update_energy_and_progress(user); + migrated_amount + } - boosted_rewards + fn decrease_old_farm_positions(&self, migrated_amount: BigUint, caller: &ManagedAddress) { + if migrated_amount == BigUint::zero() { + return; + } + self.user_total_farm_position(caller) + .update(|user_total_farm_position| { + user_total_farm_position.total_farm_position -= migrated_amount; + }); } // Cannot import the one from farm, as the Wrapper struct has different dependencies - fn claim_only_boosted_payment( - &self, - caller: &ManagedAddress, - payment: &EsdtTokenPayment, - ) -> EsdtTokenPayment { - let farm_token_mapper = self.farm_token(); - farm_token_mapper.require_same_token(&payment.token_identifier); - - let token_attributes = - self.get_attributes_as_part_of_fixed_supply(payment, &farm_token_mapper); - let reward = - FarmStakingWrapper::::calculate_boosted_rewards(self, caller, &token_attributes); + fn claim_only_boosted_payment(&self, caller: &ManagedAddress) -> BigUint { + let reward = FarmStakingWrapper::::calculate_boosted_rewards(self, caller); if reward > 0 { self.reward_reserve().update(|reserve| *reserve -= &reward); } - let reward_token_id = self.reward_token_id().get(); - EsdtTokenPayment::new(reward_token_id, 0, reward) + reward } } 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 bea77d267..e3d0b1dc4 100644 --- a/farm-staking/farm-staking/src/claim_stake_farm_rewards.rs +++ b/farm-staking/farm-staking/src/claim_stake_farm_rewards.rs @@ -7,6 +7,7 @@ use crate::base_impl_wrapper::FarmStakingWrapper; #[multiversx_sc::module] pub trait ClaimStakeFarmRewardsModule: crate::custom_rewards::CustomRewardsModule + + crate::claim_only_boosted_staking_rewards::ClaimOnlyBoostedStakingRewardsModule + rewards::RewardsModule + config::ConfigModule + events::EventsModule @@ -60,6 +61,7 @@ pub trait ClaimStakeFarmRewardsModule: original_caller: ManagedAddress, 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::>( 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 e51f3b66e..a7d83d574 100644 --- a/farm-staking/farm-staking/src/compound_stake_farm_rewards.rs +++ b/farm-staking/farm-staking/src/compound_stake_farm_rewards.rs @@ -5,6 +5,7 @@ multiversx_sc::imports!(); #[multiversx_sc::module] pub trait CompoundStakeFarmRewardsModule: crate::custom_rewards::CustomRewardsModule + + crate::claim_only_boosted_staking_rewards::ClaimOnlyBoostedStakingRewardsModule + rewards::RewardsModule + config::ConfigModule + events::EventsModule @@ -32,6 +33,7 @@ pub trait CompoundStakeFarmRewardsModule: #[endpoint(compoundRewards)] 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); diff --git a/farm-staking/farm-staking/src/custom_rewards.rs b/farm-staking/farm-staking/src/custom_rewards.rs index 4677cae1d..de7fd29a0 100644 --- a/farm-staking/farm-staking/src/custom_rewards.rs +++ b/farm-staking/farm-staking/src/custom_rewards.rs @@ -9,7 +9,7 @@ use crate::base_impl_wrapper::FarmStakingWrapper; pub const MAX_PERCENT: u64 = 10_000; pub const BLOCKS_IN_YEAR: u64 = 31_536_000 / 6; // seconds_in_year / 6_seconds_per_block -const MAX_MIN_UNBOND_EPOCHS: u64 = 30; +pub const MAX_MIN_UNBOND_EPOCHS: u64 = 30; #[multiversx_sc::module] pub trait CustomRewardsModule: diff --git a/farm-staking/farm-staking/src/lib.rs b/farm-staking/farm-staking/src/lib.rs index d1874d0b4..5bd41cecf 100644 --- a/farm-staking/farm-staking/src/lib.rs +++ b/farm-staking/farm-staking/src/lib.rs @@ -2,14 +2,17 @@ #![allow(clippy::from_over_into)] #![feature(trait_alias)] +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + use base_impl_wrapper::FarmStakingWrapper; use contexts::storage_cache::StorageCache; +use farm::base_functions::DoubleMultiPayment; use farm_base_impl::base_traits_impl::FarmContract; use fixed_supply_token::FixedSupplyToken; use token_attributes::StakingFarmTokenAttributes; -multiversx_sc::imports!(); -multiversx_sc::derive_imports!(); +use crate::custom_rewards::MAX_MIN_UNBOND_EPOCHS; pub mod base_impl_wrapper; pub mod claim_only_boosted_staking_rewards; @@ -40,7 +43,6 @@ pub trait FarmStaking: + farm_base_impl::claim_rewards::BaseClaimRewardsModule + farm_base_impl::compound_rewards::BaseCompoundRewardsModule + farm_base_impl::exit_farm::BaseExitFarmModule - + farm::progress_update::ProgressUpdateModule + utils::UtilsModule + farm_token_roles::FarmTokenRolesModule + stake_farm::StakeFarmModule @@ -79,16 +81,31 @@ pub trait FarmStaking: ); require!(max_apr > 0u64, "Invalid max APR percentage"); - self.max_annual_percentage_rewards().set(&max_apr); + self.max_annual_percentage_rewards().set_if_empty(&max_apr); - self.try_set_min_unbond_epochs(min_unbond_epochs); + require!( + min_unbond_epochs <= MAX_MIN_UNBOND_EPOCHS, + "Invalid min unbond epochs" + ); + self.min_unbond_epochs().set_if_empty(min_unbond_epochs); + + // Farm position migration code + let farm_token_mapper = self.farm_token(); + self.try_set_farm_position_migration_nonce(farm_token_mapper); } #[payable("*")] #[endpoint(mergeFarmTokens)] - fn merge_farm_tokens_endpoint(&self) -> EsdtTokenPayment { + fn merge_farm_tokens_endpoint(&self) -> DoubleMultiPayment { let caller = self.blockchain().get_caller(); - self.check_claim_progress_for_merge(&caller); + self.migrate_old_farm_positions(&caller); + + let boosted_rewards = self.claim_only_boosted_payment(&caller); + let boosted_rewards_payment = if boosted_rewards > 0 { + EsdtTokenPayment::new(self.reward_token_id().get(), 0, boosted_rewards) + } else { + EsdtTokenPayment::new(self.reward_token_id().get(), 0, BigUint::zero()) + }; let payments = self.get_non_empty_payments(); let token_mapper = self.farm_token(); @@ -98,8 +115,9 @@ pub trait FarmStaking: let merged_farm_token = token_mapper.nft_create(new_token_amount, &output_attributes); self.send_payment_non_zero(&caller, &merged_farm_token); + self.send_payment_non_zero(&caller, &boosted_rewards_payment); - merged_farm_token + (merged_farm_token, boosted_rewards_payment).into() } #[view(calculateRewardsForGivenPosition)] diff --git a/farm-staking/farm-staking/src/stake_farm.rs b/farm-staking/farm-staking/src/stake_farm.rs index 8524a2b4f..bd5f6481a 100644 --- a/farm-staking/farm-staking/src/stake_farm.rs +++ b/farm-staking/farm-staking/src/stake_farm.rs @@ -71,22 +71,26 @@ pub trait StakeFarmModule: original_caller: ManagedAddress, payments: PaymentsVec, ) -> EnterFarmResultType { - let first_additional_payment_index = 1; - let boosted_rewards = match payments.try_get(first_additional_payment_index) { - Some(p) => self.claim_only_boosted_payment(&original_caller, &p), - None => EsdtTokenPayment::new(self.reward_token_id().get(), 0, BigUint::zero()), + 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 = if boosted_rewards > 0 { + EsdtTokenPayment::new(self.reward_token_id().get(), 0, boosted_rewards) + } else { + EsdtTokenPayment::new(self.reward_token_id().get(), 0, BigUint::zero()) }; let enter_result = - self.enter_farm_base::>(original_caller, payments); + self.enter_farm_base::>(original_caller.clone(), payments); - let caller = self.blockchain().get_caller(); let new_farm_token = enter_result.new_farm_token.payment.clone(); self.send_payment_non_zero(&caller, &new_farm_token); - self.send_payment_non_zero(&caller, &boosted_rewards); + self.send_payment_non_zero(&caller, &boosted_rewards_payment); self.set_farm_supply_for_current_week(&enter_result.storage_cache.farm_token_supply); + self.update_energy_and_progress(&original_caller); + self.emit_enter_farm_event( &caller, enter_result.context.farming_token_payment, @@ -95,6 +99,6 @@ pub trait StakeFarmModule: enter_result.storage_cache, ); - (new_farm_token, boosted_rewards).into() + (new_farm_token, boosted_rewards_payment).into() } } diff --git a/farm-staking/farm-staking/src/unstake_farm.rs b/farm-staking/farm-staking/src/unstake_farm.rs index 4c9675153..e40642b4f 100644 --- a/farm-staking/farm-staking/src/unstake_farm.rs +++ b/farm-staking/farm-staking/src/unstake_farm.rs @@ -1,7 +1,6 @@ multiversx_sc::imports!(); use farm::ExitFarmWithPartialPosResultType; -use mergeable::Mergeable; use crate::{base_impl_wrapper::FarmStakingWrapper, token_attributes::UnbondSftAttributes}; @@ -36,21 +35,19 @@ pub trait UnstakeFarmModule: #[endpoint(unstakeFarm)] fn unstake_farm( &self, - exit_amount: BigUint, opt_original_caller: OptionalValue, ) -> ExitFarmWithPartialPosResultType { let caller = self.blockchain().get_caller(); let original_caller = self.get_orig_caller_from_opt(&caller, opt_original_caller); let payment = self.call_value().single_esdt(); - self.unstake_farm_common(original_caller, payment, exit_amount, None) + self.unstake_farm_common(original_caller, payment, None) } #[payable("*")] #[endpoint(unstakeFarmThroughProxy)] fn unstake_farm_through_proxy( &self, - exit_amount: BigUint, original_caller: ManagedAddress, ) -> ExitFarmWithPartialPosResultType { let caller = self.blockchain().get_caller(); @@ -66,41 +63,21 @@ pub trait UnstakeFarmModule: "Invalid staking token received" ); - self.unstake_farm_common( - original_caller, - second_payment, - exit_amount, - Some(first_payment.amount), - ) + self.unstake_farm_common(original_caller, second_payment, Some(first_payment.amount)) } fn unstake_farm_common( &self, original_caller: ManagedAddress, - mut payment: EsdtTokenPayment, - exit_amount: BigUint, + payment: EsdtTokenPayment, opt_unbond_amount: Option, ) -> ExitFarmWithPartialPosResultType { - require!( - payment.amount >= exit_amount, - "Exit amount is bigger than the payment amount" - ); - - let boosted_rewards_full_position = - self.claim_only_boosted_payment(&original_caller, &payment); - let remaining_farm_payment = EsdtTokenPayment::new( - payment.token_identifier.clone(), - payment.token_nonce, - &payment.amount - &exit_amount, - ); - - payment.amount = exit_amount; + let migrated_amount = self.migrate_old_farm_positions(&original_caller); - let mut exit_result = + let exit_result = self.exit_farm_base::>(original_caller.clone(), payment); - exit_result - .reward_payment - .merge_with(boosted_rewards_full_position); + + self.decrease_old_farm_positions(migrated_amount, &original_caller); let unbond_token_amount = opt_unbond_amount.unwrap_or(exit_result.farming_token_payment.amount); @@ -111,9 +88,8 @@ pub trait UnstakeFarmModule: self.create_and_send_unbond_tokens(&caller, farm_token_id, unbond_token_amount); self.send_payment_non_zero(&caller, &exit_result.reward_payment); - self.send_payment_non_zero(&caller, &remaining_farm_payment); - self.clear_user_energy_if_needed(&original_caller, &remaining_farm_payment.amount); + self.clear_user_energy_if_needed(&original_caller); self.set_farm_supply_for_current_week(&exit_result.storage_cache.farm_token_supply); self.emit_exit_farm_event( @@ -124,12 +100,7 @@ pub trait UnstakeFarmModule: exit_result.storage_cache, ); - ( - unbond_farm_token, - exit_result.reward_payment, - remaining_farm_payment, - ) - .into() + (unbond_farm_token, exit_result.reward_payment).into() } fn create_and_send_unbond_tokens( 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 9ce3d963e..230d84747 100644 --- a/farm-staking/farm-staking/tests/farm_staking_energy_test.rs +++ b/farm-staking/farm-staking/tests/farm_staking_energy_test.rs @@ -7,7 +7,7 @@ use farm_staking::{ }; use farm_staking_setup::*; use multiversx_sc::codec::multi_types::OptionalValue; -use multiversx_sc_scenario::{managed_biguint, rust_biguint, DebugApi}; +use multiversx_sc_scenario::{rust_biguint, DebugApi}; #[test] fn farm_staking_with_energy_setup_test() { @@ -121,7 +121,7 @@ fn farm_staking_boosted_rewards_with_energy_test() { 3, &rust_biguint!(10), |sc| { - let _ = sc.unstake_farm(managed_biguint!(10), OptionalValue::None); + let _ = sc.unstake_farm(OptionalValue::None); }, ) .assert_ok(); @@ -217,7 +217,7 @@ fn farm_staking_claim_boosted_rewards_for_user_test() { 3, &rust_biguint!(10), |sc| { - let _ = sc.unstake_farm(managed_biguint!(10), OptionalValue::None); + let _ = sc.unstake_farm(OptionalValue::None); }, ) .assert_ok(); @@ -245,3 +245,114 @@ fn farm_staking_claim_boosted_rewards_for_user_test() { ); fs_setup.check_farm_token_supply(farm_in_amount); } + +#[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); + + fs_setup.set_boosted_yields_factors(); + fs_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE); + + fs_setup.set_user_energy(&fs_setup.user_address.clone(), 10_000, 0, 10); + + let farm_in_amount = 50_000_000; + fs_setup.stake_farm(farm_in_amount, &[], 1, 0, 0); + fs_setup.stake_farm(farm_in_amount, &[], 2, 0, 0); + fs_setup.check_farm_token_supply(farm_in_amount * 2); + + // claim to get energy registered + fs_setup + .b_mock + .execute_esdt_transfer( + &fs_setup.user_address, + &fs_setup.farm_wrapper, + FARM_TOKEN_ID, + 1, + &rust_biguint!(farm_in_amount), + |sc| { + let _ = sc.claim_rewards(OptionalValue::None); + }, + ) + .assert_ok(); + + fs_setup.set_block_nonce(10); + + // 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, 5, 1); + fs_setup.set_block_epoch(5); + + 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, + 4, + &rust_biguint!(10), + |sc| { + let _ = sc.unstake_farm(OptionalValue::None); + }, + ) + .assert_ok(); + + fs_setup.set_block_epoch(8); + + fs_setup.set_user_energy(&fs_setup.user_address.clone(), 10_000, 8, 10); + + let expected_base_rewards = 15; + let expected_boosted_rewards = 10; + let mut expected_farming_token_balance = rust_biguint!( + USER_TOTAL_RIDE_TOKENS - (farm_in_amount * 2) + + expected_base_rewards + + expected_boosted_rewards + ); + let expected_reward_per_share = 300_000; // from 400_000 -> 300_000 + + // Should receive half base rewards and full boosted rewards + fs_setup.claim_rewards( + farm_in_amount, + 2, + expected_base_rewards + expected_boosted_rewards, + &expected_farming_token_balance, + &expected_farming_token_balance, + 6, + expected_reward_per_share, + ); + + // Should receive half base rewards and no boosted rewards + expected_farming_token_balance += expected_base_rewards; + fs_setup.claim_rewards( + farm_in_amount, + 3, + expected_base_rewards, + &expected_farming_token_balance, + &expected_farming_token_balance, + 7, + expected_reward_per_share, + ); + fs_setup.check_farm_token_supply(farm_in_amount * 2); +} 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 f46b63dbd..51841149f 100644 --- a/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs +++ b/farm-staking/farm-staking/tests/farm_staking_setup/mod.rs @@ -328,10 +328,9 @@ where farm_token_nonce, &rust_biguint!(farm_token_amount), |sc| { - let multi_result = - sc.unstake_farm(managed_biguint!(farm_token_amount), OptionalValue::None); + let multi_result = sc.unstake_farm(OptionalValue::None); - let (first_result, second_result, _) = multi_result.into_tuple(); + let (first_result, second_result) = multi_result.into_tuple(); assert_eq!( first_result.token_identifier, @@ -421,8 +420,8 @@ where self.b_mock .execute_tx(user, &self.farm_wrapper, &rust_biguint!(0), |sc| { sc.user_total_farm_position(&managed_address!(user)).update( - |user_total_farm_position_struct| { - user_total_farm_position_struct.allow_external_claim_boosted_rewards = true; + |user_total_farm_position| { + user_total_farm_position.allow_external_claim_boosted_rewards = true; }, ); }) diff --git a/farm-staking/farm-staking/wasm/Cargo.lock b/farm-staking/farm-staking/wasm/Cargo.lock index 4584bdf1a..6b4032061 100644 --- a/farm-staking/farm-staking/wasm/Cargo.lock +++ b/farm-staking/farm-staking/wasm/Cargo.lock @@ -8,7 +8,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "once_cell", "version_check", ] @@ -31,12 +31,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -323,12 +317,6 @@ dependencies = [ "utils", ] -[[package]] -name = "libc" -version = "0.2.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" - [[package]] name = "locking_module" version = "0.0.0" @@ -345,12 +333,6 @@ dependencies = [ "multiversx-sc", ] -[[package]] -name = "memory_units" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" - [[package]] name = "mergeable" version = "0.0.0" @@ -360,9 +342,9 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecfb3e03ac6e08114963a54e15a3c78c28e57cc0e31836e870450b35085bdf8d" +checksum = "386c2727eba66bc5e502e470d7afa55fdd69aedff440c508bb9ba85aec36a52a" dependencies = [ "bitflags", "hashbrown", @@ -374,20 +356,19 @@ dependencies = [ [[package]] name = "multiversx-sc-codec" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7638cb46a0e99c636fd55443ac534ff0a5fad0bd772e1037fbac9a75e04c3c9" +checksum = "0f1e15b46c17b87c0c7cdd79b041a4abd7f3a2b45f3c993f6ce38c0f233e82b6" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", - "wee_alloc", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e976002d51367f16140929c10ee695f95dd8d34c150a45db60d3fcd1328a267a" +checksum = "9a7bc0762cd6d88f8bc54805bc652b042a61cd7fbc2d0a325010f088b78fb2ac" dependencies = [ "hex", "proc-macro2", @@ -397,9 +378,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6eb54a7d452eb09f5de159ee9b4d1fb9ec79cf49f1602ebd3efc8532015a4ea" +checksum = "050510b6b9836b24b4a73bb7878c58c268d56bde1c6eb0f9a88dce9a6518507b" dependencies = [ "hex", "proc-macro2", @@ -410,21 +391,20 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12284a3e31c0852b6ca0ce8306d3f404c3712b996a05ed78e97e765c98461f3" +checksum = "3b55fe3585cbc745bd7b9793be4bcb3aa7f1869ced7a0981f3d47e6a832c6311" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee69fa831cdd5a7ea1aedbb6356a55792b821396f48360a6194f4131eddd1045" +checksum = "b059f22dfc3eb45aa015f6f20f28ed34dc42a65b42d282f8ac9b799b12e2942c" dependencies = [ "multiversx-sc", - "wee_alloc", ] [[package]] @@ -485,9 +465,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -606,18 +586,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wee_alloc" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "memory_units", - "winapi", -] - [[package]] name = "week-timekeeping" version = "0.0.0" @@ -637,25 +605,3 @@ dependencies = [ "unwrappable", "week-timekeeping", ] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/farm-staking/farm-staking/wasm/src/lib.rs b/farm-staking/farm-staking/wasm/src/lib.rs index d3322ea4e..fedf1dba8 100644 --- a/farm-staking/farm-staking/wasm/src/lib.rs +++ b/farm-staking/farm-staking/wasm/src/lib.rs @@ -5,12 +5,15 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 66 +// Endpoints: 68 // Async Callback: 1 -// Total number of exported functions: 68 +// Total number of exported functions: 70 #![no_std] -#![feature(alloc_error_handler, lang_items)] + +// Configuration that works with rustc < 1.73.0. +// TODO: Recommended rustc version: 1.73.0 or newer. +#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -18,72 +21,76 @@ multiversx_sc_wasm_adapter::panic_handler!(); multiversx_sc_wasm_adapter::endpoints! { farm_staking ( - mergeFarmTokens - calculateRewardsForGivenPosition - topUpRewards - endProduceRewards - setPerBlockRewardAmount - setMaxApr - setMinUnbondEpochs - startProduceRewards - getAccumulatedRewards - getRewardCapacity - getAnnualPercentageRewards - getMinUnbondEpochs - getRewardPerShare - getRewardReserve - getFarmingTokenId - getRewardTokenId - getPerBlockRewardAmount - getLastRewardBlockNonce - getDivisionSafetyConstant - getUserTotalFarmPosition - registerFarmToken - getFarmTokenId - getFarmTokenSupply - addSCAddressToWhitelist - removeSCAddressFromWhitelist - isSCAddressWhitelisted - addToPauseWhitelist - removeFromPauseWhitelist - pause - resume - getState - addAdmin - removeAdmin - updateOwnerOrAdmin - getPermissions - setBurnRoleForAddress - stakeFarmThroughProxy - stakeFarm - claimRewards - claimRewardsWithNewValue - compoundRewards - unstakeFarm - unstakeFarmThroughProxy - unbondFarm - claimBoostedRewards - setBoostedYieldsRewardsPercentage - collectUndistributedBoostedRewards - getBoostedYieldsRewardsPercentage - getAccumulatedRewardsForWeek - getFarmSupplyForWeek - getRemainingBoostedRewardsToDistribute - getUndistributedBoostedRewards - setBoostedYieldsFactors - getBoostedYieldsFactors - getCurrentWeek - getFirstWeekStartEpoch - getLastActiveWeekForUser - getUserEnergyForWeek - getLastGlobalUpdateWeek - getTotalRewardsForWeek - getTotalEnergyForWeek - getTotalLockedTokensForWeek - updateEnergyForUser - getCurrentClaimProgress - setEnergyFactoryAddress - getEnergyFactoryAddress - callBack + init => init + mergeFarmTokens => merge_farm_tokens_endpoint + calculateRewardsForGivenPosition => calculate_rewards_for_given_position + topUpRewards => top_up_rewards + endProduceRewards => end_produce_rewards + setPerBlockRewardAmount => set_per_block_rewards + setMaxApr => set_max_apr + setMinUnbondEpochs => set_min_unbond_epochs_endpoint + startProduceRewards => start_produce_rewards_endpoint + getAccumulatedRewards => accumulated_rewards + getRewardCapacity => reward_capacity + getAnnualPercentageRewards => max_annual_percentage_rewards + getMinUnbondEpochs => min_unbond_epochs + getRewardPerShare => reward_per_share + getRewardReserve => reward_reserve + allowExternalClaimBoostedRewards => allow_external_claim_boosted_rewards + getFarmingTokenId => farming_token_id + getRewardTokenId => reward_token_id + getPerBlockRewardAmount => per_block_reward_amount + getLastRewardBlockNonce => last_reward_block_nonce + getDivisionSafetyConstant => division_safety_constant + getUserTotalFarmPosition => user_total_farm_position + getFarmPositionMigrationNonce => farm_position_migration_nonce + registerFarmToken => register_farm_token + getFarmTokenId => farm_token + getFarmTokenSupply => farm_token_supply + addSCAddressToWhitelist => add_sc_address_to_whitelist + removeSCAddressFromWhitelist => remove_sc_address_from_whitelist + isSCAddressWhitelisted => is_sc_address_whitelisted + addToPauseWhitelist => add_to_pause_whitelist + removeFromPauseWhitelist => remove_from_pause_whitelist + pause => pause + resume => resume + getState => state + addAdmin => add_admin_endpoint + removeAdmin => remove_admin_endpoint + updateOwnerOrAdmin => update_owner_or_admin_endpoint + getPermissions => permissions + setBurnRoleForAddress => set_burn_role_for_address + stakeFarmThroughProxy => stake_farm_through_proxy + stakeFarm => stake_farm_endpoint + claimRewards => claim_rewards + claimRewardsWithNewValue => claim_rewards_with_new_value + compoundRewards => compound_rewards + unstakeFarm => unstake_farm + unstakeFarmThroughProxy => unstake_farm_through_proxy + unbondFarm => unbond_farm + claimBoostedRewards => claim_boosted_rewards + setBoostedYieldsRewardsPercentage => set_boosted_yields_rewards_percentage + 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 + getUserEnergyForWeek => get_user_energy_for_week_view + getLastGlobalUpdateWeek => last_global_update_week + getTotalRewardsForWeek => total_rewards_for_week + getTotalEnergyForWeek => total_energy_for_week + getTotalLockedTokensForWeek => total_locked_tokens_for_week + updateEnergyForUser => update_energy_for_user + getCurrentClaimProgress => current_claim_progress + setEnergyFactoryAddress => set_energy_factory_address + getEnergyFactoryAddress => energy_factory_address ) } + +multiversx_sc_wasm_adapter::async_callback! { farm_staking } diff --git a/locked-asset/proxy_dex/src/farm_interactions.rs b/locked-asset/proxy_dex/src/farm_interactions.rs index ee9a62f30..0ccabdb33 100644 --- a/locked-asset/proxy_dex/src/farm_interactions.rs +++ b/locked-asset/proxy_dex/src/farm_interactions.rs @@ -13,7 +13,6 @@ pub struct EnterFarmResultWrapper { pub struct ExitFarmResultWrapper { pub farming_tokens: EsdtTokenPayment, pub reward_tokens: EsdtTokenPayment, - pub remaining_farm_tokens: EsdtTokenPayment, } #[multiversx_sc::module] @@ -43,20 +42,18 @@ pub trait FarmInteractionsModule { &self, farm_address: ManagedAddress, farm_token: EsdtTokenPayment, - exit_amount: BigUint, ) -> ExitFarmResultWrapper { let original_caller = self.blockchain().get_caller(); let raw_result: ExitFarmWithPartialPosResultType = self .farm_contract_proxy(farm_address) - .exit_farm_endpoint(exit_amount, original_caller) + .exit_farm_endpoint(original_caller) .with_esdt_transfer(farm_token) .execute_on_dest_context(); - let (farming_tokens, reward_tokens, remaining_farm_tokens) = raw_result.into_tuple(); + let (farming_tokens, reward_tokens) = raw_result.into_tuple(); ExitFarmResultWrapper { farming_tokens, reward_tokens, - remaining_farm_tokens, } } diff --git a/locked-asset/proxy_dex/src/proxy_farm.rs b/locked-asset/proxy_dex/src/proxy_farm.rs index beb6cf425..49db77bd4 100644 --- a/locked-asset/proxy_dex/src/proxy_farm.rs +++ b/locked-asset/proxy_dex/src/proxy_farm.rs @@ -16,8 +16,7 @@ pub struct FarmingFarmTokenPair { pub farm_token: EsdtTokenPayment, } -pub type ExitFarmProxyResultType = - MultiValue3, EsdtTokenPayment, EsdtTokenPayment>; +pub type ExitFarmProxyResultType = MultiValue2, EsdtTokenPayment>; pub type ClaimRewardsFarmProxyResultType = MultiValue2, EsdtTokenPayment>; #[multiversx_sc::module] @@ -152,11 +151,7 @@ pub trait ProxyFarmModule: #[payable("*")] #[endpoint(exitFarmProxy)] - fn exit_farm_proxy( - &self, - farm_address: ManagedAddress, - exit_amount: BigUint, - ) -> ExitFarmProxyResultType { + fn exit_farm_proxy(&self, farm_address: ManagedAddress) -> ExitFarmProxyResultType { self.require_is_intermediated_farm(&farm_address); self.require_wrapped_farm_token_id_not_empty(); self.require_wrapped_lp_token_id_not_empty(); @@ -175,22 +170,14 @@ pub trait ProxyFarmModule: .into_part(&payment.amount); let exit_result = self.call_exit_farm( farm_address.clone(), - wrapped_farm_attributes_for_exit.farm_token, - exit_amount.clone(), + wrapped_farm_attributes_for_exit.farm_token.clone(), ); - let mut remaining_wrapped_tokens = payment.clone(); - remaining_wrapped_tokens.amount = exit_result.remaining_farm_tokens.amount; - self.burn_if_base_asset(&exit_result.farming_tokens); - let mut payment_used_for_exit = payment.clone(); - payment_used_for_exit.amount = exit_amount.clone(); - let wrapped_attributes_used_for_exit_farm: WrappedFarmTokenAttributes = - full_wrapped_farm_attributes.into_part(&exit_amount); let wrapped_farm_tokens_for_initial_tokens = WrappedFarmToken { - payment: payment_used_for_exit, - attributes: wrapped_attributes_used_for_exit_farm.clone(), + payment: payment.clone(), + attributes: wrapped_farm_attributes_for_exit.clone(), }; let caller = self.blockchain().get_caller(); @@ -203,24 +190,18 @@ pub trait ProxyFarmModule: self.send_payment_non_zero(&caller, &initial_proxy_farming_tokens); self.send_payment_non_zero(&caller, &exit_result.reward_tokens); - self.send_payment_non_zero(&caller, &remaining_wrapped_tokens); - wrapped_farm_token_mapper.nft_burn(payment.token_nonce, &exit_amount); + wrapped_farm_token_mapper.nft_burn(payment.token_nonce, &payment.amount); self.emit_exit_farm_proxy_event( &caller, &farm_address, payment, - wrapped_attributes_used_for_exit_farm, + wrapped_farm_attributes_for_exit, exit_result.reward_tokens.clone(), ); - ( - initial_proxy_farming_tokens, - exit_result.reward_tokens, - remaining_wrapped_tokens, - ) - .into() + (initial_proxy_farming_tokens, exit_result.reward_tokens).into() } fn handle_farm_penalty_and_get_output_proxy_farming_token( diff --git a/locked-asset/proxy_dex/tests/proxy_farm_test.rs b/locked-asset/proxy_dex/tests/proxy_farm_test.rs index bfa289fde..8463560e5 100644 --- a/locked-asset/proxy_dex/tests/proxy_farm_test.rs +++ b/locked-asset/proxy_dex/tests/proxy_farm_test.rs @@ -240,8 +240,7 @@ fn farm_proxy_actions_test() { 3, &rust_biguint!(USER_BALANCE), |sc| { - let output = sc - .exit_farm_proxy(managed_address!(&farm_addr), managed_biguint!(USER_BALANCE)); + let output = sc.exit_farm_proxy(managed_address!(&farm_addr)); let output_lp_token = output.0 .0; assert_eq!(output_lp_token.token_nonce, 1); assert_eq!(output_lp_token.amount, USER_BALANCE); @@ -442,12 +441,9 @@ fn farm_with_wrapped_lp_test() { &setup.proxy_wrapper, WRAPPED_FARM_TOKEN_ID, 1, - &expected_lp_token_amount, + &(expected_lp_token_amount.clone() / rust_biguint!(2)), |sc| { - sc.exit_farm_proxy( - managed_address!(&farm_locked_addr), - managed_biguint!(expected_lp_token_amount.to_u64().unwrap() / 2), - ); + sc.exit_farm_proxy(managed_address!(&farm_locked_addr)); }, ) .assert_ok(); @@ -758,12 +754,9 @@ fn farm_proxy_partial_exit_test() { &setup.proxy_wrapper, WRAPPED_FARM_TOKEN_ID, 1, - &rust_biguint!(USER_BALANCE), + &rust_biguint!(USER_BALANCE / 2), |sc| { - sc.exit_farm_proxy( - managed_address!(&farm_locked_addr), - managed_biguint!(USER_BALANCE / 2), - ); + sc.exit_farm_proxy(managed_address!(&farm_locked_addr)); }, ) .assert_ok(); @@ -936,12 +929,9 @@ fn farm_proxy_partial_exit_with_penalty_test() { &setup.proxy_wrapper, WRAPPED_FARM_TOKEN_ID, 1, - &rust_biguint!(USER_BALANCE), + &rust_biguint!(USER_BALANCE / 2), |sc| { - sc.exit_farm_proxy( - managed_address!(&farm_locked_addr), - managed_biguint!(USER_BALANCE / 2), - ); + sc.exit_farm_proxy(managed_address!(&farm_locked_addr)); }, ) .assert_ok(); @@ -1159,10 +1149,7 @@ fn different_farm_locked_token_nonce_merging_test() { 3, &rust_biguint!(USER_BALANCE * 2), |sc| { - sc.exit_farm_proxy( - managed_address!(&farm_addr), - managed_biguint!(USER_BALANCE * 2), - ); + sc.exit_farm_proxy(managed_address!(&farm_addr)); }, ) .assert_ok(); diff --git a/locked-asset/proxy_dex/wasm/Cargo.lock b/locked-asset/proxy_dex/wasm/Cargo.lock index fe099d430..1d5339db2 100644 --- a/locked-asset/proxy_dex/wasm/Cargo.lock +++ b/locked-asset/proxy_dex/wasm/Cargo.lock @@ -8,7 +8,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "once_cell", "version_check", ] @@ -31,12 +31,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -314,12 +308,6 @@ dependencies = [ "utils", ] -[[package]] -name = "libc" -version = "0.2.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" - [[package]] name = "locking_module" version = "0.0.0" @@ -336,12 +324,6 @@ dependencies = [ "multiversx-sc", ] -[[package]] -name = "memory_units" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" - [[package]] name = "mergeable" version = "0.0.0" @@ -351,9 +333,9 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecfb3e03ac6e08114963a54e15a3c78c28e57cc0e31836e870450b35085bdf8d" +checksum = "386c2727eba66bc5e502e470d7afa55fdd69aedff440c508bb9ba85aec36a52a" dependencies = [ "bitflags", "hashbrown", @@ -365,20 +347,19 @@ dependencies = [ [[package]] name = "multiversx-sc-codec" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7638cb46a0e99c636fd55443ac534ff0a5fad0bd772e1037fbac9a75e04c3c9" +checksum = "0f1e15b46c17b87c0c7cdd79b041a4abd7f3a2b45f3c993f6ce38c0f233e82b6" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", - "wee_alloc", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e976002d51367f16140929c10ee695f95dd8d34c150a45db60d3fcd1328a267a" +checksum = "9a7bc0762cd6d88f8bc54805bc652b042a61cd7fbc2d0a325010f088b78fb2ac" dependencies = [ "hex", "proc-macro2", @@ -388,9 +369,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6eb54a7d452eb09f5de159ee9b4d1fb9ec79cf49f1602ebd3efc8532015a4ea" +checksum = "050510b6b9836b24b4a73bb7878c58c268d56bde1c6eb0f9a88dce9a6518507b" dependencies = [ "hex", "proc-macro2", @@ -401,21 +382,20 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12284a3e31c0852b6ca0ce8306d3f404c3712b996a05ed78e97e765c98461f3" +checksum = "3b55fe3585cbc745bd7b9793be4bcb3aa7f1869ced7a0981f3d47e6a832c6311" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee69fa831cdd5a7ea1aedbb6356a55792b821396f48360a6194f4131eddd1045" +checksum = "b059f22dfc3eb45aa015f6f20f28ed34dc42a65b42d282f8ac9b799b12e2942c" dependencies = [ "multiversx-sc", - "wee_alloc", ] [[package]] @@ -476,9 +456,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] @@ -628,18 +608,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wee_alloc" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "memory_units", - "winapi", -] - [[package]] name = "week-timekeeping" version = "0.0.0" @@ -659,25 +627,3 @@ dependencies = [ "unwrappable", "week-timekeeping", ] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/locked-asset/proxy_dex/wasm/src/lib.rs b/locked-asset/proxy_dex/wasm/src/lib.rs index 892463480..096dff097 100644 --- a/locked-asset/proxy_dex/wasm/src/lib.rs +++ b/locked-asset/proxy_dex/wasm/src/lib.rs @@ -10,7 +10,10 @@ // Total number of exported functions: 27 #![no_std] -#![feature(alloc_error_handler, lang_items)] + +// Configuration that works with rustc < 1.73.0. +// TODO: Recommended rustc version: 1.73.0 or newer. +#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -18,31 +21,33 @@ multiversx_sc_wasm_adapter::panic_handler!(); multiversx_sc_wasm_adapter::endpoints! { proxy_dex ( - registerProxyPair - setTransferRoleWrappedLpToken - registerProxyFarm - setTransferRoleWrappedFarmToken - getAssetTokenId - getLockedTokenIds - getOldLockedTokenId - getOldFactoryAddress - getWrappedLpTokenId - getWrappedFarmTokenId - addPairToIntermediate - removeIntermediatedPair - addFarmToIntermediate - removeIntermediatedFarm - getIntermediatedPairs - getIntermediatedFarms - addLiquidityProxy - removeLiquidityProxy - enterFarmProxy - exitFarmProxy - claimRewardsProxy - mergeWrappedFarmTokens - mergeWrappedLpTokens - setEnergyFactoryAddress - getEnergyFactoryAddress - callBack + init => init + registerProxyPair => register_proxy_pair + setTransferRoleWrappedLpToken => set_transfer_role_wrapped_lp_token + registerProxyFarm => register_proxy_farm + setTransferRoleWrappedFarmToken => set_transfer_role_wrapped_farm_token + getAssetTokenId => get_asset_token_id_view + getLockedTokenIds => get_locked_token_ids_view + getOldLockedTokenId => old_locked_token_id + getOldFactoryAddress => old_factory_address + getWrappedLpTokenId => wrapped_lp_token + getWrappedFarmTokenId => wrapped_farm_token + addPairToIntermediate => add_pair_to_intermediate + removeIntermediatedPair => remove_intermediated_pair + addFarmToIntermediate => add_farm_to_intermediate + removeIntermediatedFarm => remove_intermediated_farm + getIntermediatedPairs => intermediated_pairs + getIntermediatedFarms => intermediated_farms + addLiquidityProxy => add_liquidity_proxy + removeLiquidityProxy => remove_liquidity_proxy + enterFarmProxy => enter_farm_proxy_endpoint + exitFarmProxy => exit_farm_proxy + claimRewardsProxy => claim_rewards_proxy + mergeWrappedFarmTokens => merge_wrapped_farm_tokens_endpoint + mergeWrappedLpTokens => merge_wrapped_lp_tokens_endpoint + setEnergyFactoryAddress => set_energy_factory_address + getEnergyFactoryAddress => energy_factory_address ) } + +multiversx_sc_wasm_adapter::async_callback! { proxy_dex } diff --git a/locked-asset/simple-lock/elrond.json b/locked-asset/simple-lock/elrond.json deleted file mode 100644 index 736553962..000000000 --- a/locked-asset/simple-lock/elrond.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "language": "rust" -} \ No newline at end of file diff --git a/locked-asset/simple-lock/src/farm_interactions.rs b/locked-asset/simple-lock/src/farm_interactions.rs index d68e5ae62..4748f8ec5 100644 --- a/locked-asset/simple-lock/src/farm_interactions.rs +++ b/locked-asset/simple-lock/src/farm_interactions.rs @@ -11,7 +11,7 @@ type ClaimRewardsResultType = MultiValue2, EsdtTokenPayment>; const ENTER_FARM_RESULTS_LEN: usize = 2; -const EXIT_FARM_RESULTS_LEN: usize = 3; +const EXIT_FARM_RESULTS_LEN: usize = 2; const CLAIM_REWARDS_RESULTS_LEN: usize = 2; pub struct EnterFarmResultWrapper { @@ -22,7 +22,6 @@ pub struct EnterFarmResultWrapper { pub struct ExitFarmResultWrapper { pub initial_farming_tokens: EsdtTokenPayment, pub reward_tokens: EsdtTokenPayment, - pub remaining_farm_tokens: EsdtTokenPayment, } pub struct FarmClaimRewardsResultWrapper { @@ -51,7 +50,6 @@ mod farm_proxy { #[endpoint(exitFarm)] fn exit_farm( &self, - exit_amount: BigUint, opt_orig_caller: OptionalValue, ) -> ExitFarmResultType; @@ -106,12 +104,11 @@ pub trait FarmInteractionsModule { farm_token: TokenIdentifier, farm_token_nonce: u64, farm_token_amount: BigUint, - exit_amount: BigUint, caller: ManagedAddress, ) -> ExitFarmResultWrapper { let raw_results: RawResultsType = self .farm_proxy(farm_address) - .exit_farm(exit_amount, caller) + .exit_farm(caller) .with_esdt_transfer(EsdtTokenPayment::new( farm_token, farm_token_nonce, @@ -124,12 +121,10 @@ pub trait FarmInteractionsModule { let initial_farming_tokens = results_wrapper.decode_next_result(); let reward_tokens = results_wrapper.decode_next_result(); - let remaining_farm_tokens = results_wrapper.decode_next_result(); ExitFarmResultWrapper { initial_farming_tokens, reward_tokens, - remaining_farm_tokens, } } diff --git a/locked-asset/simple-lock/src/proxy_farm.rs b/locked-asset/simple-lock/src/proxy_farm.rs index 43ea8b6c8..c6ab28659 100644 --- a/locked-asset/simple-lock/src/proxy_farm.rs +++ b/locked-asset/simple-lock/src/proxy_farm.rs @@ -199,18 +199,11 @@ pub trait ProxyFarmModule: /// - farm reward tokens #[payable("*")] #[endpoint(exitFarmLockedToken)] - fn exit_farm_locked_token( - &self, - exit_amount: BigUint, - ) -> ExitFarmThroughProxyResultType { - require!(exit_amount > 0u64, "Exit amount must be greater than 0"); + fn exit_farm_locked_token(&self) -> ExitFarmThroughProxyResultType { let payment: EsdtTokenPayment = self.call_value().single_esdt(); - require!( - exit_amount > 0u64 && exit_amount <= payment.amount, - "Invalid exit amount" - ); + let farm_proxy_token_attributes: FarmProxyTokenAttributes = - self.validate_payment_and_get_farm_proxy_token_attributes(&payment, &exit_amount); + self.validate_payment_and_get_farm_proxy_token_attributes(&payment); let farm_address = self.try_get_farm_address( &farm_proxy_token_attributes.farming_token_id, @@ -222,7 +215,6 @@ pub trait ProxyFarmModule: farm_proxy_token_attributes.farm_token_id, farm_proxy_token_attributes.farm_token_nonce, payment.amount, - exit_amount, caller.clone(), ); require!( @@ -253,15 +245,6 @@ pub trait ProxyFarmModule: ); } - if exit_farm_result.remaining_farm_tokens.amount > 0 { - self.send().direct_esdt( - &caller, - &payment.token_identifier, - payment.token_nonce, - &exit_farm_result.remaining_farm_tokens.amount, - ); - } - (lp_proxy_token_payment, exit_farm_result.reward_tokens).into() } @@ -279,7 +262,7 @@ pub trait ProxyFarmModule: fn farm_claim_rewards_locked_token(&self) -> FarmClaimRewardsThroughProxyResultType { let payment: EsdtTokenPayment = self.call_value().single_esdt(); let mut farm_proxy_token_attributes: FarmProxyTokenAttributes = - self.validate_payment_and_get_farm_proxy_token_attributes(&payment, &payment.amount); + self.validate_payment_and_get_farm_proxy_token_attributes(&payment); let farm_address = self.try_get_farm_address( &farm_proxy_token_attributes.farming_token_id, @@ -337,7 +320,6 @@ pub trait ProxyFarmModule: fn validate_payment_and_get_farm_proxy_token_attributes( &self, payment: &EsdtTokenPayment, - exit_amount: &BigUint, ) -> FarmProxyTokenAttributes { require!(payment.amount > 0, NO_PAYMENT_ERR_MSG); @@ -347,7 +329,7 @@ pub trait ProxyFarmModule: let farm_proxy_token_attributes: FarmProxyTokenAttributes = farm_proxy_token_mapper.get_token_attributes(payment.token_nonce); - farm_proxy_token_mapper.nft_burn(payment.token_nonce, exit_amount); + farm_proxy_token_mapper.nft_burn(payment.token_nonce, &payment.amount); farm_proxy_token_attributes } diff --git a/locked-asset/simple-lock/wasm/Cargo.lock b/locked-asset/simple-lock/wasm/Cargo.lock index 270c2aca4..cb879951a 100644 --- a/locked-asset/simple-lock/wasm/Cargo.lock +++ b/locked-asset/simple-lock/wasm/Cargo.lock @@ -8,7 +8,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "once_cell", "version_check", ] @@ -31,12 +31,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -88,12 +82,6 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" -[[package]] -name = "libc" -version = "0.2.139" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" - [[package]] name = "math" version = "0.0.0" @@ -101,12 +89,6 @@ dependencies = [ "multiversx-sc", ] -[[package]] -name = "memory_units" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" - [[package]] name = "mergeable" version = "0.0.0" @@ -116,9 +98,9 @@ dependencies = [ [[package]] name = "multiversx-sc" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecfb3e03ac6e08114963a54e15a3c78c28e57cc0e31836e870450b35085bdf8d" +checksum = "386c2727eba66bc5e502e470d7afa55fdd69aedff440c508bb9ba85aec36a52a" dependencies = [ "bitflags", "hashbrown", @@ -130,20 +112,19 @@ dependencies = [ [[package]] name = "multiversx-sc-codec" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7638cb46a0e99c636fd55443ac534ff0a5fad0bd772e1037fbac9a75e04c3c9" +checksum = "0f1e15b46c17b87c0c7cdd79b041a4abd7f3a2b45f3c993f6ce38c0f233e82b6" dependencies = [ "arrayvec", "multiversx-sc-codec-derive", - "wee_alloc", ] [[package]] name = "multiversx-sc-codec-derive" -version = "0.17.1" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e976002d51367f16140929c10ee695f95dd8d34c150a45db60d3fcd1328a267a" +checksum = "9a7bc0762cd6d88f8bc54805bc652b042a61cd7fbc2d0a325010f088b78fb2ac" dependencies = [ "hex", "proc-macro2", @@ -153,9 +134,9 @@ dependencies = [ [[package]] name = "multiversx-sc-derive" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6eb54a7d452eb09f5de159ee9b4d1fb9ec79cf49f1602ebd3efc8532015a4ea" +checksum = "050510b6b9836b24b4a73bb7878c58c268d56bde1c6eb0f9a88dce9a6518507b" dependencies = [ "hex", "proc-macro2", @@ -166,21 +147,20 @@ dependencies = [ [[package]] name = "multiversx-sc-modules" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12284a3e31c0852b6ca0ce8306d3f404c3712b996a05ed78e97e765c98461f3" +checksum = "3b55fe3585cbc745bd7b9793be4bcb3aa7f1869ced7a0981f3d47e6a832c6311" dependencies = [ "multiversx-sc", ] [[package]] name = "multiversx-sc-wasm-adapter" -version = "0.39.4" +version = "0.43.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee69fa831cdd5a7ea1aedbb6356a55792b821396f48360a6194f4131eddd1045" +checksum = "b059f22dfc3eb45aa015f6f20f28ed34dc42a65b42d282f8ac9b799b12e2942c" dependencies = [ "multiversx-sc", - "wee_alloc", ] [[package]] @@ -209,9 +189,9 @@ checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "proc-macro2" -version = "1.0.50" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] @@ -287,37 +267,3 @@ name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "wee_alloc" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb3b5a6b2bb17cb6ad44a2e68a43e8d2722c997da10e928665c72ec6c0a0b8e" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "memory_units", - "winapi", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/locked-asset/simple-lock/wasm/src/lib.rs b/locked-asset/simple-lock/wasm/src/lib.rs index 042660883..afe83b5ff 100644 --- a/locked-asset/simple-lock/wasm/src/lib.rs +++ b/locked-asset/simple-lock/wasm/src/lib.rs @@ -10,7 +10,10 @@ // Total number of exported functions: 21 #![no_std] -#![feature(alloc_error_handler, lang_items)] + +// Configuration that works with rustc < 1.73.0. +// TODO: Recommended rustc version: 1.73.0 or newer. +#![feature(lang_items)] multiversx_sc_wasm_adapter::allocator!(); multiversx_sc_wasm_adapter::panic_handler!(); @@ -18,25 +21,27 @@ multiversx_sc_wasm_adapter::panic_handler!(); multiversx_sc_wasm_adapter::endpoints! { simple_lock ( - lockTokens - unlockTokens - issueLockedToken - getLockedTokenId - issueLpProxyToken - addLpToWhitelist - removeLpFromWhitelist - addLiquidityLockedToken - removeLiquidityLockedToken - getKnownLiquidityPools - getLpProxyTokenId - issueFarmProxyToken - addFarmToWhitelist - removeFarmFromWhitelist - enterFarmLockedToken - exitFarmLockedToken - farmClaimRewardsLockedToken - getKnownFarms - getFarmProxyTokenId - callBack + init => init + lockTokens => lock_tokens_endpoint + unlockTokens => unlock_tokens_endpoint + issueLockedToken => issue_locked_token + getLockedTokenId => locked_token + issueLpProxyToken => issue_lp_proxy_token + addLpToWhitelist => add_lp_to_whitelist + removeLpFromWhitelist => remove_lp_from_whitelist + addLiquidityLockedToken => add_liquidity_locked_token + removeLiquidityLockedToken => remove_liquidity_locked_token + getKnownLiquidityPools => known_liquidity_pools + getLpProxyTokenId => lp_proxy_token + issueFarmProxyToken => issue_farm_proxy_token + addFarmToWhitelist => add_farm_to_whitelist + removeFarmFromWhitelist => remove_farm_from_whitelist + enterFarmLockedToken => enter_farm_locked_token + exitFarmLockedToken => exit_farm_locked_token + farmClaimRewardsLockedToken => farm_claim_rewards_locked_token + getKnownFarms => known_farms + getFarmProxyTokenId => farm_proxy_token ) } + +multiversx_sc_wasm_adapter::async_callback! { simple_lock }