From e9a3dc89645a4b222201031aeb75f0347dd074d3 Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Fri, 9 Feb 2024 09:25:48 +0200 Subject: [PATCH 1/7] separate file for setters --- .../farm-staking-nft/src/custom_rewards.rs | 76 ------------- farm-staking/farm-staking-nft/src/lib.rs | 4 +- .../farm-staking-nft/src/rewards_setters.rs | 103 ++++++++++++++++++ farm-staking/farm-staking-nft/wasm/src/lib.rs | 12 +- 4 files changed, 112 insertions(+), 83 deletions(-) create mode 100644 farm-staking/farm-staking-nft/src/rewards_setters.rs diff --git a/farm-staking/farm-staking-nft/src/custom_rewards.rs b/farm-staking/farm-staking-nft/src/custom_rewards.rs index 47d493879..dc4be720e 100644 --- a/farm-staking/farm-staking-nft/src/custom_rewards.rs +++ b/farm-staking/farm-staking-nft/src/custom_rewards.rs @@ -10,7 +10,6 @@ use crate::common::token_attributes::{ pub const MAX_PERCENT: u64 = 10_000; pub const BLOCKS_IN_YEAR: u64 = 31_536_000 / 6; // seconds_in_year / 6_seconds_per_block -pub const MAX_MIN_UNBOND_EPOCHS: u64 = 30; #[multiversx_sc::module] pub trait CustomRewardsModule: @@ -32,81 +31,6 @@ pub trait CustomRewardsModule: + weekly_rewards_splitting::update_claim_progress_energy::UpdateClaimProgressEnergyModule + energy_query::EnergyQueryModule { - #[payable("*")] - #[endpoint(topUpRewards)] - fn top_up_rewards(&self) { - self.require_caller_has_admin_permissions(); - - let (payment_token, payment_amount) = self.call_value().single_fungible_esdt(); - let reward_token_id = self.reward_token_id().get(); - require!(payment_token == reward_token_id, "Invalid token"); - - self.reward_capacity().update(|r| *r += payment_amount); - } - - #[payable("*")] - #[endpoint(withdrawRewards)] - fn withdraw_rewards(&self, withdraw_amount: BigUint) { - self.require_caller_has_admin_permissions(); - - self.reward_capacity().update(|rewards| { - require!( - *rewards >= withdraw_amount, - "Not enough rewards to withdraw" - ); - - *rewards -= withdraw_amount.clone() - }); - - let caller = self.blockchain().get_caller(); - let reward_token_id = self.reward_token_id().get(); - self.send_tokens_non_zero(&caller, &reward_token_id, 0, &withdraw_amount); - } - - #[endpoint(endProduceRewards)] - fn end_produce_rewards(&self) { - self.require_caller_has_admin_permissions(); - - let mut storage_cache = StorageCache::new(self); - self.generate_aggregated_rewards(&mut storage_cache); - self.produce_rewards_enabled().set(false); - } - - #[endpoint(setPerBlockRewardAmount)] - fn set_per_block_rewards(&self, per_block_amount: BigUint) { - self.require_caller_has_admin_permissions(); - require!(per_block_amount != 0, "Amount cannot be zero"); - - let mut storage_cache = StorageCache::new(self); - self.generate_aggregated_rewards(&mut storage_cache); - self.per_block_reward_amount().set(&per_block_amount); - } - - #[endpoint(setMaxApr)] - fn set_max_apr(&self, max_apr: BigUint) { - self.require_caller_has_admin_permissions(); - require!(max_apr != 0, "Max APR cannot be zero"); - - let mut storage_cache = StorageCache::new(self); - self.generate_aggregated_rewards(&mut storage_cache); - self.max_annual_percentage_rewards().set(&max_apr); - } - - #[endpoint(setMinUnbondEpochs)] - fn set_min_unbond_epochs_endpoint(&self, min_unbond_epochs: Epoch) { - self.require_caller_has_admin_permissions(); - self.try_set_min_unbond_epochs(min_unbond_epochs); - } - - fn try_set_min_unbond_epochs(&self, min_unbond_epochs: Epoch) { - require!( - min_unbond_epochs <= MAX_MIN_UNBOND_EPOCHS, - "Invalid min unbond epochs" - ); - - self.min_unbond_epochs().set(min_unbond_epochs); - } - fn get_amount_apr_bounded(&self, amount: &BigUint) -> BigUint { let max_apr = self.max_annual_percentage_rewards().get(); amount * &max_apr / MAX_PERCENT / BLOCKS_IN_YEAR diff --git a/farm-staking/farm-staking-nft/src/lib.rs b/farm-staking/farm-staking-nft/src/lib.rs index 6c0870ea2..fd6200150 100644 --- a/farm-staking/farm-staking-nft/src/lib.rs +++ b/farm-staking/farm-staking-nft/src/lib.rs @@ -9,12 +9,13 @@ use common::result_types::MergeResultType; use common::token_attributes::PartialStakingFarmNftTokenAttributes; use contexts::storage_cache::StorageCache; -use crate::custom_rewards::MAX_MIN_UNBOND_EPOCHS; +use crate::rewards_setters::MAX_MIN_UNBOND_EPOCHS; pub mod common; pub mod custom_rewards; pub mod farm_actions; pub mod farm_hooks; +pub mod rewards_setters; pub mod unbond_token; #[multiversx_sc::contract] @@ -56,6 +57,7 @@ pub trait FarmStaking: + farm_hooks::call_hook::CallHookModule + common::token_info::TokenInfoModule + unbond_token::UnbondTokenModule + + rewards_setters::RewardsSettersModule { #[init] fn init( diff --git a/farm-staking/farm-staking-nft/src/rewards_setters.rs b/farm-staking/farm-staking-nft/src/rewards_setters.rs new file mode 100644 index 000000000..44207bc12 --- /dev/null +++ b/farm-staking/farm-staking-nft/src/rewards_setters.rs @@ -0,0 +1,103 @@ +use common_structs::Epoch; +use contexts::storage_cache::StorageCache; + +multiversx_sc::imports!(); + +pub const MAX_MIN_UNBOND_EPOCHS: u64 = 30; + +#[multiversx_sc::module] +pub trait RewardsSettersModule: + rewards::RewardsModule + + config::ConfigModule + + token_send::TokenSendModule + + farm_token::FarmTokenModule + + utils::UtilsModule + + pausable::PausableModule + + permissions_module::PermissionsModule + + multiversx_sc_modules::default_issue_callbacks::DefaultIssueCallbacksModule + + farm_boosted_yields::FarmBoostedYieldsModule + + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule + + 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 + + crate::custom_rewards::CustomRewardsModule +{ + #[payable("*")] + #[endpoint(topUpRewards)] + fn top_up_rewards(&self) { + self.require_caller_has_admin_permissions(); + + let (payment_token, payment_amount) = self.call_value().single_fungible_esdt(); + let reward_token_id = self.reward_token_id().get(); + require!(payment_token == reward_token_id, "Invalid token"); + + self.reward_capacity().update(|r| *r += payment_amount); + } + + #[payable("*")] + #[endpoint(withdrawRewards)] + fn withdraw_rewards(&self, withdraw_amount: BigUint) { + self.require_caller_has_admin_permissions(); + + self.reward_capacity().update(|rewards| { + require!( + *rewards >= withdraw_amount, + "Not enough rewards to withdraw" + ); + + *rewards -= withdraw_amount.clone() + }); + + let caller = self.blockchain().get_caller(); + let reward_token_id = self.reward_token_id().get(); + self.send_tokens_non_zero(&caller, &reward_token_id, 0, &withdraw_amount); + } + + #[endpoint(endProduceRewards)] + fn end_produce_rewards(&self) { + self.require_caller_has_admin_permissions(); + + let mut storage_cache = StorageCache::new(self); + self.generate_aggregated_rewards(&mut storage_cache); + self.produce_rewards_enabled().set(false); + } + + #[endpoint(setPerBlockRewardAmount)] + fn set_per_block_rewards(&self, per_block_amount: BigUint) { + self.require_caller_has_admin_permissions(); + require!(per_block_amount != 0, "Amount cannot be zero"); + + let mut storage_cache = StorageCache::new(self); + self.generate_aggregated_rewards(&mut storage_cache); + self.per_block_reward_amount().set(&per_block_amount); + } + + #[endpoint(setMaxApr)] + fn set_max_apr(&self, max_apr: BigUint) { + self.require_caller_has_admin_permissions(); + require!(max_apr != 0, "Max APR cannot be zero"); + + let mut storage_cache = StorageCache::new(self); + self.generate_aggregated_rewards(&mut storage_cache); + self.max_annual_percentage_rewards().set(&max_apr); + } + + #[endpoint(setMinUnbondEpochs)] + fn set_min_unbond_epochs_endpoint(&self, min_unbond_epochs: Epoch) { + self.require_caller_has_admin_permissions(); + self.try_set_min_unbond_epochs(min_unbond_epochs); + } + + fn try_set_min_unbond_epochs(&self, min_unbond_epochs: Epoch) { + require!( + min_unbond_epochs <= MAX_MIN_UNBOND_EPOCHS, + "Invalid min unbond epochs" + ); + + self.min_unbond_epochs().set(min_unbond_epochs); + } +} diff --git a/farm-staking/farm-staking-nft/wasm/src/lib.rs b/farm-staking/farm-staking-nft/wasm/src/lib.rs index 475894402..cba3fb991 100644 --- a/farm-staking/farm-staking-nft/wasm/src/lib.rs +++ b/farm-staking/farm-staking-nft/wasm/src/lib.rs @@ -23,12 +23,6 @@ multiversx_sc_wasm_adapter::endpoints! { upgrade => upgrade mergeFarmTokens => merge_farm_tokens_endpoint calculateRewardsForGivenPosition => calculate_rewards_for_given_position - topUpRewards => top_up_rewards - withdrawRewards => withdraw_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 @@ -91,6 +85,12 @@ multiversx_sc_wasm_adapter::endpoints! { removeHook => remove_hook registerUnbondToken => register_unbond_token getUnbondTokenId => unbond_token + topUpRewards => top_up_rewards + withdrawRewards => withdraw_rewards + endProduceRewards => end_produce_rewards + setPerBlockRewardAmount => set_per_block_rewards + setMaxApr => set_max_apr + setMinUnbondEpochs => set_min_unbond_epochs_endpoint ) } From fb25aa93f08f9a7e491a8f2546bfb6b74ba2b24d Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Fri, 9 Feb 2024 09:36:19 +0200 Subject: [PATCH 2/7] add reward nonce --- .../farm-staking-nft/src/common/result_types.rs | 1 + farm-staking/farm-staking-nft/src/custom_rewards.rs | 4 ++++ .../claim_only_boosted_staking_rewards.rs | 3 ++- .../src/farm_actions/claim_stake_farm_rewards.rs | 2 ++ .../src/farm_actions/compound_stake_farm_rewards.rs | 5 ++++- .../farm-staking-nft/src/farm_actions/stake_farm.rs | 3 ++- .../src/farm_actions/unstake_farm.rs | 3 +++ farm-staking/farm-staking-nft/src/lib.rs | 7 +++++-- .../farm-staking-nft/src/rewards_setters.rs | 13 +++++++++---- farm-staking/farm-staking-nft/wasm/src/lib.rs | 5 +++-- 10 files changed, 35 insertions(+), 11 deletions(-) diff --git a/farm-staking/farm-staking-nft/src/common/result_types.rs b/farm-staking/farm-staking-nft/src/common/result_types.rs index 8403a0b0c..238b31ea6 100644 --- a/farm-staking/farm-staking-nft/src/common/result_types.rs +++ b/farm-staking/farm-staking-nft/src/common/result_types.rs @@ -24,6 +24,7 @@ pub struct ClaimRewardsResultType { #[derive(TypeAbi, TopEncode, TopDecode)] pub struct CompoundRewardsResultType { pub new_farm_token: EsdtTokenPayment, + pub compounded_rewards: BigUint, } #[derive(TypeAbi, TopEncode, TopDecode)] diff --git a/farm-staking/farm-staking-nft/src/custom_rewards.rs b/farm-staking/farm-staking-nft/src/custom_rewards.rs index dc4be720e..1d99579d1 100644 --- a/farm-staking/farm-staking-nft/src/custom_rewards.rs +++ b/farm-staking/farm-staking-nft/src/custom_rewards.rs @@ -250,4 +250,8 @@ pub trait CustomRewardsModule: #[view(getMinUnbondEpochs)] #[storage_mapper("minUnbondEpochs")] fn min_unbond_epochs(&self) -> SingleValueMapper; + + #[view(getRewardNonce)] + #[storage_mapper("rewardNonce")] + fn reward_nonce(&self) -> SingleValueMapper; } diff --git a/farm-staking/farm-staking-nft/src/farm_actions/claim_only_boosted_staking_rewards.rs b/farm-staking/farm-staking-nft/src/farm_actions/claim_only_boosted_staking_rewards.rs index af65a2c3d..fd6c9561c 100644 --- a/farm-staking/farm-staking-nft/src/farm_actions/claim_only_boosted_staking_rewards.rs +++ b/farm-staking/farm-staking-nft/src/farm_actions/claim_only_boosted_staking_rewards.rs @@ -39,8 +39,9 @@ pub trait ClaimOnlyBoostedStakingRewardsModule: } let boosted_rewards = self.claim_only_boosted_payment(user); + let reward_nonce = self.reward_nonce().get(); let boosted_rewards_payment = - EsdtTokenPayment::new(self.reward_token_id().get(), 0, boosted_rewards); + EsdtTokenPayment::new(self.reward_token_id().get(), reward_nonce, boosted_rewards); self.send_payment_non_zero(user, &boosted_rewards_payment); diff --git a/farm-staking/farm-staking-nft/src/farm_actions/claim_stake_farm_rewards.rs b/farm-staking/farm-staking-nft/src/farm_actions/claim_stake_farm_rewards.rs index cca17e48c..bc7ddebc1 100644 --- a/farm-staking/farm-staking-nft/src/farm_actions/claim_stake_farm_rewards.rs +++ b/farm-staking/farm-staking-nft/src/farm_actions/claim_stake_farm_rewards.rs @@ -69,6 +69,8 @@ pub trait ClaimStakeFarmRewardsModule: let mut claim_result = self.claim_rewards_base(caller.clone(), ManagedVec::from_single_item(payment)); + let reward_nonce = self.reward_nonce().get(); + claim_result.rewards.token_nonce = reward_nonce; let mut virtual_farm_token = claim_result.new_farm_token.clone(); diff --git a/farm-staking/farm-staking-nft/src/farm_actions/compound_stake_farm_rewards.rs b/farm-staking/farm-staking-nft/src/farm_actions/compound_stake_farm_rewards.rs index 1535ea84e..36a9ea16b 100644 --- a/farm-staking/farm-staking-nft/src/farm_actions/compound_stake_farm_rewards.rs +++ b/farm-staking/farm-staking-nft/src/farm_actions/compound_stake_farm_rewards.rs @@ -95,7 +95,10 @@ pub trait CompoundStakeFarmRewardsModule: // compound_result.storage_cache, // ); - CompoundRewardsResultType { new_farm_token } + CompoundRewardsResultType { + new_farm_token, + compounded_rewards: compound_result.compounded_rewards, + } } fn compound_rewards_base( diff --git a/farm-staking/farm-staking-nft/src/farm_actions/stake_farm.rs b/farm-staking/farm-staking-nft/src/farm_actions/stake_farm.rs index f7132142f..c4fa19023 100644 --- a/farm-staking/farm-staking-nft/src/farm_actions/stake_farm.rs +++ b/farm-staking/farm-staking-nft/src/farm_actions/stake_farm.rs @@ -52,8 +52,9 @@ pub trait StakeFarmModule: ); let boosted_rewards = self.claim_only_boosted_payment(&caller); + let reward_nonce = self.reward_nonce().get(); let boosted_rewards_payment = - EsdtTokenPayment::new(self.reward_token_id().get(), 0, boosted_rewards); + EsdtTokenPayment::new(self.reward_token_id().get(), reward_nonce, boosted_rewards); let farm_token_mapper = self.farm_token(); let farming_token_id = self.farming_token_id().get(); diff --git a/farm-staking/farm-staking-nft/src/farm_actions/unstake_farm.rs b/farm-staking/farm-staking-nft/src/farm_actions/unstake_farm.rs index 7196272e7..7d01546b3 100644 --- a/farm-staking/farm-staking-nft/src/farm_actions/unstake_farm.rs +++ b/farm-staking/farm-staking-nft/src/farm_actions/unstake_farm.rs @@ -69,6 +69,9 @@ pub trait UnstakeFarmModule: let payment = payments_after_hook.get(0); let mut exit_result = self.exit_farm_base(caller.clone(), payment); + let reward_nonce = self.reward_nonce().get(); + exit_result.reward_payment.token_nonce = reward_nonce; + let unbond_farm_token = self.create_unbond_tokens(exit_result.token_parts); let mut output_payments = ManagedVec::new(); diff --git a/farm-staking/farm-staking-nft/src/lib.rs b/farm-staking/farm-staking-nft/src/lib.rs index fd6200150..731dac2a9 100644 --- a/farm-staking/farm-staking-nft/src/lib.rs +++ b/farm-staking/farm-staking-nft/src/lib.rs @@ -7,6 +7,7 @@ multiversx_sc::derive_imports!(); use common::result_types::MergeResultType; use common::token_attributes::PartialStakingFarmNftTokenAttributes; +use common_structs::Nonce; use contexts::storage_cache::StorageCache; use crate::rewards_setters::MAX_MIN_UNBOND_EPOCHS; @@ -67,6 +68,7 @@ pub trait FarmStaking: max_apr: BigUint, min_unbond_epochs: u64, owner: ManagedAddress, + reward_nonce: Nonce, admins: MultiValueEncoded, ) { // farming and reward token are the same @@ -79,13 +81,14 @@ pub trait FarmStaking: ); require!(max_apr > 0u64, "Invalid max APR percentage"); - self.max_annual_percentage_rewards().set_if_empty(&max_apr); + self.max_annual_percentage_rewards().set(&max_apr); require!( min_unbond_epochs <= MAX_MIN_UNBOND_EPOCHS, "Invalid min unbond epochs" ); - self.min_unbond_epochs().set_if_empty(min_unbond_epochs); + self.min_unbond_epochs().set(min_unbond_epochs); + self.reward_nonce().set(reward_nonce); let sc_address = self.blockchain().get_sc_address(); self.banned_addresses().add(&sc_address); diff --git a/farm-staking/farm-staking-nft/src/rewards_setters.rs b/farm-staking/farm-staking-nft/src/rewards_setters.rs index 44207bc12..db11d0664 100644 --- a/farm-staking/farm-staking-nft/src/rewards_setters.rs +++ b/farm-staking/farm-staking-nft/src/rewards_setters.rs @@ -31,11 +31,15 @@ pub trait RewardsSettersModule: fn top_up_rewards(&self) { self.require_caller_has_admin_permissions(); - let (payment_token, payment_amount) = self.call_value().single_fungible_esdt(); + let payment = self.call_value().single_esdt(); let reward_token_id = self.reward_token_id().get(); - require!(payment_token == reward_token_id, "Invalid token"); + let reward_nonce = self.reward_nonce().get(); + require!( + payment.token_identifier == reward_token_id && payment.token_nonce == reward_nonce, + "Invalid token" + ); - self.reward_capacity().update(|r| *r += payment_amount); + self.reward_capacity().update(|r| *r += payment.amount); } #[payable("*")] @@ -54,7 +58,8 @@ pub trait RewardsSettersModule: let caller = self.blockchain().get_caller(); let reward_token_id = self.reward_token_id().get(); - self.send_tokens_non_zero(&caller, &reward_token_id, 0, &withdraw_amount); + let reward_nonce = self.reward_nonce().get(); + self.send_tokens_non_zero(&caller, &reward_token_id, reward_nonce, &withdraw_amount); } #[endpoint(endProduceRewards)] diff --git a/farm-staking/farm-staking-nft/wasm/src/lib.rs b/farm-staking/farm-staking-nft/wasm/src/lib.rs index cba3fb991..7a5b1eb31 100644 --- a/farm-staking/farm-staking-nft/wasm/src/lib.rs +++ b/farm-staking/farm-staking-nft/wasm/src/lib.rs @@ -5,9 +5,9 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 71 +// Endpoints: 72 // Async Callback: 1 -// Total number of exported functions: 73 +// Total number of exported functions: 74 #![no_std] #![allow(internal_features)] @@ -28,6 +28,7 @@ multiversx_sc_wasm_adapter::endpoints! { getRewardCapacity => reward_capacity getAnnualPercentageRewards => max_annual_percentage_rewards getMinUnbondEpochs => min_unbond_epochs + getRewardNonce => reward_nonce getRewardPerShare => reward_per_share getRewardReserve => reward_reserve allowExternalClaimBoostedRewards => allow_external_claim_boosted_rewards From a96a824da35e91d59dc727384027137571561a5a Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Fri, 9 Feb 2024 10:55:10 +0200 Subject: [PATCH 3/7] fix events --- .../src/common/custom_events.rs | 245 ++++++++++++++++++ .../farm-staking-nft/src/common/mod.rs | 1 + .../farm-staking-nft/src/common/token_info.rs | 7 +- .../claim_only_boosted_staking_rewards.rs | 1 - .../farm_actions/claim_stake_farm_rewards.rs | 29 +-- .../compound_stake_farm_rewards.rs | 25 +- .../src/farm_actions/stake_farm.rs | 18 +- .../src/farm_actions/unbond_farm.rs | 1 - .../src/farm_actions/unstake_farm.rs | 2 +- farm-staking/farm-staking-nft/src/lib.rs | 2 +- 10 files changed, 285 insertions(+), 46 deletions(-) create mode 100644 farm-staking/farm-staking-nft/src/common/custom_events.rs diff --git a/farm-staking/farm-staking-nft/src/common/custom_events.rs b/farm-staking/farm-staking-nft/src/common/custom_events.rs new file mode 100644 index 000000000..0b2279fad --- /dev/null +++ b/farm-staking/farm-staking-nft/src/common/custom_events.rs @@ -0,0 +1,245 @@ +multiversx_sc::imports!(); +multiversx_sc::derive_imports!(); + +use common_structs::{PaymentAttributesPair, PaymentsVec}; +use contexts::{ + claim_rewards_context::CompoundRewardsContext, + exit_farm_context::ExitFarmContext, + storage_cache::{FarmContracTraitBounds, StorageCache}, +}; + +use super::token_attributes::StakingFarmNftTokenAttributes; + +#[derive(TypeAbi, TopEncode)] +pub struct EnterFarmEvent { + farming_tokens: PaymentsVec, + farm_token: EsdtTokenPayment, + farm_supply: BigUint, + reward_token_id: TokenIdentifier, + reward_token_reserve: BigUint, + farm_attributes: StakingFarmNftTokenAttributes, + created_with_merge: bool, +} + +#[derive(TypeAbi, TopEncode)] +pub struct ExitFarmEvent { + farming_token_id: TokenIdentifier, + farming_token_amount: BigUint, + farm_token: EsdtTokenPayment, + farm_supply: BigUint, + reward_tokens: EsdtTokenPayment, + reward_reserve: BigUint, + farm_attributes: StakingFarmNftTokenAttributes, +} + +#[derive(TypeAbi, TopEncode)] +pub struct ClaimRewardsEvent { + old_farm_token: EsdtTokenPayment, + new_farm_token: EsdtTokenPayment, + farm_supply: BigUint, + reward_tokens: EsdtTokenPayment, + reward_reserve: BigUint, + old_farm_attributes: StakingFarmNftTokenAttributes, + new_farm_attributes: StakingFarmNftTokenAttributes, + created_with_merge: bool, +} + +#[derive(TypeAbi, TopEncode)] +pub struct CompoundRewardsEvent { + old_farm_token: EsdtTokenPayment, + new_farm_token: EsdtTokenPayment, + farm_supply: BigUint, + reward_token_id: TokenIdentifier, + compounded_reward: BigUint, + reward_reserve: BigUint, + old_farm_attributes: StakingFarmNftTokenAttributes, + new_farm_attributes: StakingFarmNftTokenAttributes, + created_with_merge: bool, +} + +#[multiversx_sc::module] +pub trait CustomEventsModule { + fn emit_enter_farm_event<'a, C: FarmContracTraitBounds>( + &self, + caller: &ManagedAddress, + input_farming_tokens: PaymentsVec, + output_farm_token: PaymentAttributesPair< + Self::Api, + StakingFarmNftTokenAttributes, + >, + created_with_merge: bool, + storage_cache: StorageCache<'a, C>, + ) { + let epoch = self.blockchain().get_block_epoch(); + let block = self.blockchain().get_block_nonce(); + let timestamp = self.blockchain().get_block_timestamp(); + + self.enter_farm_event( + caller, + epoch, + block, + timestamp, + &storage_cache.farming_token_id, + &EnterFarmEvent { + farming_tokens: input_farming_tokens, + farm_token: output_farm_token.payment, + farm_supply: storage_cache.farm_token_supply.clone(), + reward_token_id: storage_cache.reward_token_id.clone(), + reward_token_reserve: storage_cache.reward_reserve.clone(), + farm_attributes: output_farm_token.attributes, + created_with_merge, + }, + ) + } + + fn emit_exit_farm_event<'a, C: FarmContracTraitBounds>( + &self, + caller: &ManagedAddress, + exit_farm_context: ExitFarmContext>, + output_farming_tokens: EsdtTokenPayment, + output_reward: EsdtTokenPayment, + storage_cache: StorageCache<'a, C>, + ) { + let epoch = self.blockchain().get_block_epoch(); + let block = self.blockchain().get_block_nonce(); + let timestamp = self.blockchain().get_block_timestamp(); + + self.exit_farm_event( + caller, + epoch, + block, + timestamp, + &storage_cache.farm_token_id, + &ExitFarmEvent { + farming_token_id: output_farming_tokens.token_identifier, + farming_token_amount: output_farming_tokens.amount, + farm_token: exit_farm_context.farm_token.payment, + farm_supply: storage_cache.farm_token_supply.clone(), + reward_tokens: output_reward, + reward_reserve: storage_cache.reward_reserve.clone(), + farm_attributes: exit_farm_context.farm_token.attributes, + }, + ) + } + + fn emit_claim_rewards_event<'a, C: FarmContracTraitBounds>( + &self, + caller: &ManagedAddress, + input_farm_token: PaymentAttributesPair< + Self::Api, + StakingFarmNftTokenAttributes, + >, + output_farm_token: PaymentAttributesPair< + Self::Api, + StakingFarmNftTokenAttributes, + >, + output_reward: EsdtTokenPayment, + created_with_merge: bool, + storage_cache: StorageCache<'a, C>, + ) { + let epoch = self.blockchain().get_block_epoch(); + let block = self.blockchain().get_block_nonce(); + let timestamp = self.blockchain().get_block_timestamp(); + + self.claim_rewards_event( + caller, + epoch, + block, + timestamp, + &storage_cache.farm_token_id, + &ClaimRewardsEvent { + old_farm_token: input_farm_token.payment, + new_farm_token: output_farm_token.payment, + farm_supply: storage_cache.farm_token_supply.clone(), + reward_tokens: output_reward, + reward_reserve: storage_cache.reward_reserve.clone(), + old_farm_attributes: input_farm_token.attributes, + new_farm_attributes: output_farm_token.attributes, + created_with_merge, + }, + ) + } + + fn emit_compound_rewards_event<'a, C: FarmContracTraitBounds>( + self, + caller: &ManagedAddress, + compound_rewards_context: CompoundRewardsContext< + Self::Api, + StakingFarmNftTokenAttributes, + >, + output_farm_token: PaymentAttributesPair< + Self::Api, + StakingFarmNftTokenAttributes, + >, + compounded_reward_amount: BigUint, + created_with_merge: bool, + storage_cache: StorageCache<'a, C>, + ) { + let epoch = self.blockchain().get_block_epoch(); + let block = self.blockchain().get_block_nonce(); + let timestamp = self.blockchain().get_block_timestamp(); + + self.compound_rewards_event( + caller, + epoch, + block, + timestamp, + &storage_cache.farm_token_id, + &CompoundRewardsEvent { + old_farm_token: compound_rewards_context.first_farm_token.payment, + new_farm_token: output_farm_token.payment, + farm_supply: storage_cache.farm_token_supply.clone(), + reward_token_id: storage_cache.reward_token_id.clone(), + compounded_reward: compounded_reward_amount, + reward_reserve: storage_cache.reward_reserve.clone(), + old_farm_attributes: compound_rewards_context.first_farm_token.attributes, + new_farm_attributes: output_farm_token.attributes, + created_with_merge, + }, + ) + } + + #[event("enter_farm")] + fn enter_farm_event( + &self, + #[indexed] caller: &ManagedAddress, + #[indexed] epoch: u64, + #[indexed] block: u64, + #[indexed] timestamp: u64, + #[indexed] farming_token: &TokenIdentifier, + enter_farm_event: &EnterFarmEvent, + ); + + #[event("exit_farm")] + fn exit_farm_event( + &self, + #[indexed] caller: &ManagedAddress, + #[indexed] epoch: u64, + #[indexed] block: u64, + #[indexed] timestamp: u64, + #[indexed] farm_token: &TokenIdentifier, + exit_farm_event: &ExitFarmEvent, + ); + + #[event("claim_rewards")] + fn claim_rewards_event( + &self, + #[indexed] caller: &ManagedAddress, + #[indexed] epoch: u64, + #[indexed] block: u64, + #[indexed] timestamp: u64, + #[indexed] farm_token: &TokenIdentifier, + claim_rewards_event: &ClaimRewardsEvent, + ); + + #[event("compound_rewards")] + fn compound_rewards_event( + self, + #[indexed] caller: &ManagedAddress, + #[indexed] epoch: u64, + #[indexed] block: u64, + #[indexed] timestamp: u64, + #[indexed] farm_token: &TokenIdentifier, + compound_rewards_event: &CompoundRewardsEvent, + ); +} diff --git a/farm-staking/farm-staking-nft/src/common/mod.rs b/farm-staking/farm-staking-nft/src/common/mod.rs index 54b8059b5..283d79009 100644 --- a/farm-staking/farm-staking-nft/src/common/mod.rs +++ b/farm-staking/farm-staking-nft/src/common/mod.rs @@ -1,3 +1,4 @@ +pub mod custom_events; pub mod farm_token_roles; pub mod result_types; pub mod token_attributes; diff --git a/farm-staking/farm-staking-nft/src/common/token_info.rs b/farm-staking/farm-staking-nft/src/common/token_info.rs index f3a488ca2..26baec393 100644 --- a/farm-staking/farm-staking-nft/src/common/token_info.rs +++ b/farm-staking/farm-staking-nft/src/common/token_info.rs @@ -158,15 +158,16 @@ pub trait TokenInfoModule: utils::UtilsModule { base_attributes: PartialStakingFarmNftTokenAttributes, payments: &PaymentsVec, mapper: &NonFungibleTokenMapper, - ) -> PaymentAttributesPair> { + ) -> PaymentAttributesPair> { let output_attributes = self.merge_attributes_from_payments_nft(base_attributes, payments, mapper); let new_token_amount = output_attributes.current_farm_amount.clone(); - let new_token_payment = mapper.nft_create(new_token_amount, &output_attributes); + let full_attr = output_attributes.into_full(); + let new_token_payment = mapper.nft_create(new_token_amount, &full_attr); PaymentAttributesPair { payment: new_token_payment, - attributes: output_attributes, + attributes: full_attr, } } diff --git a/farm-staking/farm-staking-nft/src/farm_actions/claim_only_boosted_staking_rewards.rs b/farm-staking/farm-staking-nft/src/farm_actions/claim_only_boosted_staking_rewards.rs index fd6c9561c..bf8986ec0 100644 --- a/farm-staking/farm-staking-nft/src/farm_actions/claim_only_boosted_staking_rewards.rs +++ b/farm-staking/farm-staking-nft/src/farm_actions/claim_only_boosted_staking_rewards.rs @@ -16,7 +16,6 @@ pub trait ClaimOnlyBoostedStakingRewardsModule: + weekly_rewards_splitting::update_claim_progress_energy::UpdateClaimProgressEnergyModule + energy_query::EnergyQueryModule + token_send::TokenSendModule - + events::EventsModule + utils::UtilsModule + farm_boosted_yields::FarmBoostedYieldsModule + farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule diff --git a/farm-staking/farm-staking-nft/src/farm_actions/claim_stake_farm_rewards.rs b/farm-staking/farm-staking-nft/src/farm_actions/claim_stake_farm_rewards.rs index bc7ddebc1..b5ca0386f 100644 --- a/farm-staking/farm-staking-nft/src/farm_actions/claim_stake_farm_rewards.rs +++ b/farm-staking/farm-staking-nft/src/farm_actions/claim_stake_farm_rewards.rs @@ -8,10 +8,7 @@ use contexts::{ use crate::{ common::result_types::ClaimRewardsResultType, - common::token_attributes::{ - PartialStakingFarmNftTokenAttributes, StakingFarmNftTokenAttributes, - }, - farm_hooks::hook_type::FarmHookType, + common::token_attributes::StakingFarmNftTokenAttributes, farm_hooks::hook_type::FarmHookType, }; pub struct InternalClaimRewardsResult<'a, C> @@ -21,7 +18,7 @@ where pub context: ClaimRewardsContext>, pub storage_cache: StorageCache<'a, C>, pub rewards: EsdtTokenPayment, - pub new_farm_token: PaymentAttributesPair>, + pub new_farm_token: PaymentAttributesPair>, pub created_with_merge: bool, } @@ -31,7 +28,6 @@ pub trait ClaimStakeFarmRewardsModule: + super::claim_only_boosted_staking_rewards::ClaimOnlyBoostedStakingRewardsModule + rewards::RewardsModule + config::ConfigModule - + events::EventsModule + token_send::TokenSendModule + farm_token::FarmTokenModule + pausable::PausableModule @@ -53,6 +49,7 @@ pub trait ClaimStakeFarmRewardsModule: + crate::farm_hooks::change_hooks::ChangeHooksModule + crate::farm_hooks::call_hook::CallHookModule + crate::common::token_info::TokenInfoModule + + crate::common::custom_events::CustomEventsModule { #[payable("*")] #[endpoint(claimRewards)] @@ -72,7 +69,7 @@ pub trait ClaimStakeFarmRewardsModule: let reward_nonce = self.reward_nonce().get(); claim_result.rewards.token_nonce = reward_nonce; - let mut virtual_farm_token = claim_result.new_farm_token.clone(); + let mut virtual_farm_token = claim_result.new_farm_token; self.update_energy_and_progress(&caller); @@ -93,14 +90,14 @@ pub trait ClaimStakeFarmRewardsModule: self.send_payment_non_zero(&caller, &virtual_farm_token.payment); self.send_payment_non_zero(&caller, &claim_result.rewards); - // self.emit_claim_rewards_event( - // &caller, - // claim_result.context, - // virtual_farm_token.clone(), - // claim_result.rewards.clone(), - // claim_result.created_with_merge, - // claim_result.storage_cache, - // ); + self.emit_claim_rewards_event( + &caller, + claim_result.context.first_farm_token, + virtual_farm_token.clone(), + claim_result.rewards.clone(), + claim_result.created_with_merge, + claim_result.storage_cache, + ); ClaimRewardsResultType { new_farm_token: virtual_farm_token.payment, @@ -175,7 +172,7 @@ pub trait ClaimStakeFarmRewardsModule: 0, new_token_attributes.current_farm_amount.clone(), ), - attributes: new_token_attributes, + attributes: new_token_attributes.into_full(), }; let first_farm_token = &claim_rewards_context.first_farm_token.payment; diff --git a/farm-staking/farm-staking-nft/src/farm_actions/compound_stake_farm_rewards.rs b/farm-staking/farm-staking-nft/src/farm_actions/compound_stake_farm_rewards.rs index 36a9ea16b..8d88cdfb1 100644 --- a/farm-staking/farm-staking-nft/src/farm_actions/compound_stake_farm_rewards.rs +++ b/farm-staking/farm-staking-nft/src/farm_actions/compound_stake_farm_rewards.rs @@ -7,10 +7,7 @@ use contexts::{ use crate::{ common::result_types::CompoundRewardsResultType, - common::token_attributes::{ - PartialStakingFarmNftTokenAttributes, StakingFarmNftTokenAttributes, - }, - farm_hooks::hook_type::FarmHookType, + common::token_attributes::StakingFarmNftTokenAttributes, farm_hooks::hook_type::FarmHookType, }; multiversx_sc::imports!(); @@ -21,7 +18,7 @@ where { pub context: CompoundRewardsContext>, pub storage_cache: StorageCache<'a, C>, - pub new_farm_token: PaymentAttributesPair>, + pub new_farm_token: PaymentAttributesPair>, pub compounded_rewards: BigUint, pub created_with_merge: bool, } @@ -32,7 +29,6 @@ pub trait CompoundStakeFarmRewardsModule: + super::claim_only_boosted_staking_rewards::ClaimOnlyBoostedStakingRewardsModule + rewards::RewardsModule + config::ConfigModule - + events::EventsModule + token_send::TokenSendModule + farm_token::FarmTokenModule + pausable::PausableModule @@ -54,6 +50,7 @@ pub trait CompoundStakeFarmRewardsModule: + crate::farm_hooks::change_hooks::ChangeHooksModule + crate::farm_hooks::call_hook::CallHookModule + crate::common::token_info::TokenInfoModule + + crate::common::custom_events::CustomEventsModule { #[payable("*")] #[endpoint(compoundRewards)] @@ -86,14 +83,14 @@ pub trait CompoundStakeFarmRewardsModule: self.set_farm_supply_for_current_week(&compound_result.storage_cache.farm_token_supply); - // self.emit_compound_rewards_event( - // &caller, - // compound_result.context, - // compound_result.new_farm_token, - // compound_result.compounded_rewards, - // compound_result.created_with_merge, - // compound_result.storage_cache, - // ); + self.emit_compound_rewards_event( + &caller, + compound_result.context, + compound_result.new_farm_token, + compound_result.compounded_rewards.clone(), + compound_result.created_with_merge, + compound_result.storage_cache, + ); CompoundRewardsResultType { new_farm_token, diff --git a/farm-staking/farm-staking-nft/src/farm_actions/stake_farm.rs b/farm-staking/farm-staking-nft/src/farm_actions/stake_farm.rs index c4fa19023..c224c0730 100644 --- a/farm-staking/farm-staking-nft/src/farm_actions/stake_farm.rs +++ b/farm-staking/farm-staking-nft/src/farm_actions/stake_farm.rs @@ -16,7 +16,6 @@ pub trait StakeFarmModule: + super::claim_only_boosted_staking_rewards::ClaimOnlyBoostedStakingRewardsModule + rewards::RewardsModule + config::ConfigModule - + events::EventsModule + token_send::TokenSendModule + farm_token::FarmTokenModule + pausable::PausableModule @@ -38,6 +37,7 @@ pub trait StakeFarmModule: + crate::farm_hooks::change_hooks::ChangeHooksModule + crate::farm_hooks::call_hook::CallHookModule + crate::common::token_info::TokenInfoModule + + crate::common::custom_events::CustomEventsModule { #[payable("*")] #[endpoint(stakeFarm)] @@ -79,14 +79,14 @@ pub trait StakeFarmModule: let mut enter_input_payments = PaymentsVec::from_single_item(farming_token_payment); enter_input_payments.append_vec(other_farm_tokens); - let mut enter_result = + let enter_result = self.enter_farm_base_no_token_create(caller.clone(), enter_input_payments); let new_farm_token = enter_result.new_farm_token.payment.clone(); let mut attributes = enter_result.new_farm_token.attributes; attributes .farming_token_parts - .append_vec(all_farming_tokens); + .append_vec(all_farming_tokens.clone()); let attr_full = attributes.clone().into_full(); let new_farm_token = farm_token_mapper.nft_create(new_farm_token.amount, &attr_full); @@ -109,16 +109,16 @@ pub trait StakeFarmModule: 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(&caller); - enter_result.new_farm_token.payment = new_farm_token.clone(); - enter_result.new_farm_token.attributes = attributes; - + let output_token = PaymentAttributesPair { + payment: new_farm_token.clone(), + attributes: attr_full, + }; self.emit_enter_farm_event( &caller, - enter_result.context.farming_token_payment, - enter_result.new_farm_token, + all_farming_tokens, + output_token, enter_result.created_with_merge, enter_result.storage_cache, ); diff --git a/farm-staking/farm-staking-nft/src/farm_actions/unbond_farm.rs b/farm-staking/farm-staking-nft/src/farm_actions/unbond_farm.rs index 163e3df04..1f3b70f18 100644 --- a/farm-staking/farm-staking-nft/src/farm_actions/unbond_farm.rs +++ b/farm-staking/farm-staking-nft/src/farm_actions/unbond_farm.rs @@ -11,7 +11,6 @@ use crate::{ pub trait UnbondFarmModule: rewards::RewardsModule + config::ConfigModule - + events::EventsModule + token_send::TokenSendModule + farm_token::FarmTokenModule + pausable::PausableModule diff --git a/farm-staking/farm-staking-nft/src/farm_actions/unstake_farm.rs b/farm-staking/farm-staking-nft/src/farm_actions/unstake_farm.rs index 7d01546b3..d9c053c7e 100644 --- a/farm-staking/farm-staking-nft/src/farm_actions/unstake_farm.rs +++ b/farm-staking/farm-staking-nft/src/farm_actions/unstake_farm.rs @@ -30,7 +30,6 @@ pub trait UnstakeFarmModule: + super::claim_only_boosted_staking_rewards::ClaimOnlyBoostedStakingRewardsModule + rewards::RewardsModule + config::ConfigModule - + events::EventsModule + token_send::TokenSendModule + farm_token::FarmTokenModule + pausable::PausableModule @@ -53,6 +52,7 @@ pub trait UnstakeFarmModule: + crate::farm_hooks::call_hook::CallHookModule + crate::common::token_info::TokenInfoModule + crate::unbond_token::UnbondTokenModule + + crate::common::custom_events::CustomEventsModule { #[payable("*")] #[endpoint(unstakeFarm)] diff --git a/farm-staking/farm-staking-nft/src/lib.rs b/farm-staking/farm-staking-nft/src/lib.rs index 731dac2a9..d3ff68004 100644 --- a/farm-staking/farm-staking-nft/src/lib.rs +++ b/farm-staking/farm-staking-nft/src/lib.rs @@ -24,7 +24,6 @@ pub trait FarmStaking: custom_rewards::CustomRewardsModule + rewards::RewardsModule + config::ConfigModule - + events::EventsModule + token_send::TokenSendModule + farm_token::FarmTokenModule + pausable::PausableModule @@ -59,6 +58,7 @@ pub trait FarmStaking: + common::token_info::TokenInfoModule + unbond_token::UnbondTokenModule + rewards_setters::RewardsSettersModule + + common::custom_events::CustomEventsModule { #[init] fn init( From e8feb35e55c93a4b2926edf5d5d387744f0324a2 Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Fri, 9 Feb 2024 10:55:45 +0200 Subject: [PATCH 4/7] imports --- farm-staking/farm-staking-nft/Cargo.toml | 3 --- farm-staking/farm-staking-nft/wasm/Cargo.lock | 1 - 2 files changed, 4 deletions(-) diff --git a/farm-staking/farm-staking-nft/Cargo.toml b/farm-staking/farm-staking-nft/Cargo.toml index fd18f6772..e8fbd6b46 100644 --- a/farm-staking/farm-staking-nft/Cargo.toml +++ b/farm-staking/farm-staking-nft/Cargo.toml @@ -35,9 +35,6 @@ path = "../../common/modules/farm/farm_token" [dependencies.rewards] path = "../../common/modules/farm/rewards" -[dependencies.events] -path = "../../common/modules/farm/events" - [dependencies.contexts] path = "../../common/modules/farm/contexts" diff --git a/farm-staking/farm-staking-nft/wasm/Cargo.lock b/farm-staking/farm-staking-nft/wasm/Cargo.lock index 887fc3b66..c9ae5c457 100644 --- a/farm-staking/farm-staking-nft/wasm/Cargo.lock +++ b/farm-staking/farm-staking-nft/wasm/Cargo.lock @@ -180,7 +180,6 @@ dependencies = [ "contexts", "energy-factory", "energy-query", - "events", "farm", "farm-boosted-yields", "farm_base_impl", From 18fdab50ed530d235b5674db6fc9c360afe79056 Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Fri, 9 Feb 2024 11:09:44 +0200 Subject: [PATCH 5/7] cargo.lock --- Cargo.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index d6367e1ba..a99ba3aa4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -838,7 +838,6 @@ dependencies = [ "contexts", "energy-factory", "energy-query", - "events", "farm", "farm-boosted-yields", "farm_base_impl", From 4585f65c7414716533c56599b33f3d232ca869f6 Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Mon, 12 Feb 2024 11:56:19 +0200 Subject: [PATCH 6/7] first week epoch set --- farm-staking/farm-staking-nft/src/custom_rewards.rs | 12 ++++++++++++ farm-staking/farm-staking-nft/src/lib.rs | 10 +++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/farm-staking/farm-staking-nft/src/custom_rewards.rs b/farm-staking/farm-staking-nft/src/custom_rewards.rs index 1d99579d1..d4ffa5ed9 100644 --- a/farm-staking/farm-staking-nft/src/custom_rewards.rs +++ b/farm-staking/farm-staking-nft/src/custom_rewards.rs @@ -42,6 +42,12 @@ pub trait CustomRewardsModule: token_attributes: &PartialStakingFarmNftTokenAttributes, storage_cache: &StorageCache, ) -> BigUint { + let current_epoch = self.blockchain().get_block_epoch(); + let first_week_start_epoch = self.first_week_start_epoch().get(); + if first_week_start_epoch > current_epoch { + return BigUint::zero(); + } + let token_rps = token_attributes.reward_per_share.clone(); if storage_cache.reward_per_share > token_rps { let rps_diff = &storage_cache.reward_per_share - &token_rps; @@ -52,6 +58,12 @@ pub trait CustomRewardsModule: } fn calculate_boosted_rewards(&self, caller: &ManagedAddress) -> BigUint { + let current_epoch = self.blockchain().get_block_epoch(); + let first_week_start_epoch = self.first_week_start_epoch().get(); + if first_week_start_epoch > current_epoch { + return BigUint::zero(); + } + let user_total_farm_position = self.get_user_total_farm_position(caller); let user_farm_position = user_total_farm_position.total_farm_position; if user_farm_position == 0 { diff --git a/farm-staking/farm-staking-nft/src/lib.rs b/farm-staking/farm-staking-nft/src/lib.rs index d3ff68004..fde2ce329 100644 --- a/farm-staking/farm-staking-nft/src/lib.rs +++ b/farm-staking/farm-staking-nft/src/lib.rs @@ -7,7 +7,7 @@ multiversx_sc::derive_imports!(); use common::result_types::MergeResultType; use common::token_attributes::PartialStakingFarmNftTokenAttributes; -use common_structs::Nonce; +use common_structs::{Epoch, Nonce}; use contexts::storage_cache::StorageCache; use crate::rewards_setters::MAX_MIN_UNBOND_EPOCHS; @@ -69,6 +69,7 @@ pub trait FarmStaking: min_unbond_epochs: u64, owner: ManagedAddress, reward_nonce: Nonce, + first_week_start_epoch: Epoch, admins: MultiValueEncoded, ) { // farming and reward token are the same @@ -80,6 +81,13 @@ pub trait FarmStaking: admins, ); + let current_epoch = self.blockchain().get_block_epoch(); + require!( + first_week_start_epoch >= current_epoch, + "Invalid start epoch" + ); + self.first_week_start_epoch().set(first_week_start_epoch); + require!(max_apr > 0u64, "Invalid max APR percentage"); self.max_annual_percentage_rewards().set(&max_apr); From c220799a371bb2b893f7036e873c459887ffbcc8 Mon Sep 17 00:00:00 2001 From: Dorin Marian Iancu Date: Mon, 12 Feb 2024 12:07:44 +0200 Subject: [PATCH 7/7] allow overwriting reward nonce --- .../farm-staking-nft/src/rewards_setters.rs | 27 +++++++++++++++++++ farm-staking/farm-staking-nft/wasm/src/lib.rs | 5 ++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/farm-staking/farm-staking-nft/src/rewards_setters.rs b/farm-staking/farm-staking-nft/src/rewards_setters.rs index db11d0664..29fab7856 100644 --- a/farm-staking/farm-staking-nft/src/rewards_setters.rs +++ b/farm-staking/farm-staking-nft/src/rewards_setters.rs @@ -42,6 +42,33 @@ pub trait RewardsSettersModule: self.reward_capacity().update(|r| *r += payment.amount); } + #[payable("*")] + #[endpoint(topUpAndSetRewardNonce)] + fn top_up_and_set_reward_nonce(&self) { + self.require_caller_has_admin_permissions(); + + let payment = self.call_value().single_esdt(); + let reward_token_id = self.reward_token_id().get(); + require!(payment.token_identifier == reward_token_id, "Invalid token"); + + let current_reward_nonce = self.reward_nonce().get(); + require!( + payment.token_nonce != current_reward_nonce, + "Same nonce deposited" + ); + + let caller = self.blockchain().get_caller(); + let accumulated_rewards = self.accumulated_rewards().take(); + let reward_capacity = self.reward_capacity().get(); + let remaining_rewards = reward_capacity - accumulated_rewards; + let remaining_rewards_payment = + EsdtTokenPayment::new(reward_token_id, current_reward_nonce, remaining_rewards); + self.send_payment_non_zero(&caller, &remaining_rewards_payment); + + self.reward_capacity().set(payment.amount); + self.reward_nonce().set(payment.token_nonce); + } + #[payable("*")] #[endpoint(withdrawRewards)] fn withdraw_rewards(&self, withdraw_amount: BigUint) { diff --git a/farm-staking/farm-staking-nft/wasm/src/lib.rs b/farm-staking/farm-staking-nft/wasm/src/lib.rs index 7a5b1eb31..4ecb0f2cd 100644 --- a/farm-staking/farm-staking-nft/wasm/src/lib.rs +++ b/farm-staking/farm-staking-nft/wasm/src/lib.rs @@ -5,9 +5,9 @@ //////////////////////////////////////////////////// // Init: 1 -// Endpoints: 72 +// Endpoints: 73 // Async Callback: 1 -// Total number of exported functions: 74 +// Total number of exported functions: 75 #![no_std] #![allow(internal_features)] @@ -87,6 +87,7 @@ multiversx_sc_wasm_adapter::endpoints! { registerUnbondToken => register_unbond_token getUnbondTokenId => unbond_token topUpRewards => top_up_rewards + topUpAndSetRewardNonce => top_up_and_set_reward_nonce withdrawRewards => withdraw_rewards endProduceRewards => end_produce_rewards setPerBlockRewardAmount => set_per_block_rewards