Skip to content

Commit

Permalink
farm energy fix
Browse files Browse the repository at this point in the history
  • Loading branch information
dorin-iancu committed May 13, 2024
1 parent db82bb5 commit c8f3f21
Show file tree
Hide file tree
Showing 22 changed files with 230 additions and 120 deletions.
7 changes: 7 additions & 0 deletions common/common_structs/src/farm_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ pub trait FarmToken<M: ManagedTypeApi> {
fn get_compounded_rewards(&self) -> BigUint<M>;

fn get_initial_farming_tokens(&self) -> BigUint<M>;

fn get_original_owner(&self) -> ManagedAddress<M>;
}

impl<M: ManagedTypeApi> FarmToken<M> for FarmTokenAttributes<M> {
Expand All @@ -97,4 +99,9 @@ impl<M: ManagedTypeApi> FarmToken<M> for FarmTokenAttributes<M> {
fn get_initial_farming_tokens(&self) -> BigUint<M> {
&self.current_farm_amount - &self.compounded_reward
}

#[inline]
fn get_original_owner(&self) -> ManagedAddress<M> {
self.original_owner.clone()
}
}
30 changes: 22 additions & 8 deletions common/modules/farm/contexts/src/claim_rewards_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,70 @@ multiversx_sc::imports!();
multiversx_sc::derive_imports!();

use common_errors::{ERROR_BAD_PAYMENTS, ERROR_EMPTY_PAYMENTS};
use common_structs::PaymentAttributesPair;
use common_structs::{PaymentAttributesPair, PaymentsVec};
use multiversx_sc::api::BlockchainApi;
use multiversx_sc::contract_base::BlockchainWrapper;

pub struct ClaimRewardsContext<M, T>
where
M: ManagedTypeApi,
T: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode,
T: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode + ManagedVecItem,
{
pub first_farm_token: PaymentAttributesPair<M, T>,
pub additional_payments: ManagedVec<M, EsdtTokenPayment<M>>,
pub additional_payments: PaymentsVec<M>,
pub additional_attributes: ManagedVec<M, T>,
pub all_attributes: ManagedVec<M, T>,
}

impl<M, T> ClaimRewardsContext<M, T>
where
M: ManagedTypeApi + BlockchainApi,
T: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode,
T: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode + ManagedVecItem,
{
pub fn new(
mut payments: ManagedVec<M, EsdtTokenPayment<M>>,
mut payments: PaymentsVec<M>,
farm_token_id: &TokenIdentifier<M>,
api_wrapper: BlockchainWrapper<M>,
) -> Self {
if payments.is_empty() {
M::error_api_impl().signal_error(ERROR_EMPTY_PAYMENTS);
}

let own_sc_address = api_wrapper.get_sc_address();
let mut all_attributes = ManagedVec::new();
for p in &payments {
if &p.token_identifier != farm_token_id {
M::error_api_impl().signal_error(ERROR_BAD_PAYMENTS);
}

let token_data =
api_wrapper.get_esdt_token_data(&own_sc_address, farm_token_id, p.token_nonce);
let token_attributes: T = token_data.decode_attributes();
all_attributes.push(token_attributes);
}

let first_payment = payments.get(0);
payments.remove(0);

let own_sc_address = api_wrapper.get_sc_address();
let token_data = api_wrapper.get_esdt_token_data(
// dumb framework errors otherwise
let first_token_data = api_wrapper.get_esdt_token_data(
&own_sc_address,
farm_token_id,
first_payment.token_nonce,
);
let first_token_attributes: T = token_data.decode_attributes();
let first_token_attributes: T = first_token_data.decode_attributes();

let mut additional_attributes = all_attributes.clone();
additional_attributes.remove(0);

ClaimRewardsContext {
first_farm_token: PaymentAttributesPair {
payment: first_payment,
attributes: first_token_attributes,
},
additional_payments: payments,
additional_attributes,
all_attributes,
}
}
}
Expand Down
28 changes: 24 additions & 4 deletions common/modules/farm/contexts/src/enter_farm_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,28 @@ multiversx_sc::imports!();
multiversx_sc::derive_imports!();

use common_errors::{ERROR_BAD_PAYMENTS, ERROR_EMPTY_PAYMENTS};
use common_structs::PaymentsVec;
use multiversx_sc::{api::BlockchainApi, contract_base::BlockchainWrapper};

pub struct EnterFarmContext<M: ManagedTypeApi> {
pub struct EnterFarmContext<
M: ManagedTypeApi,
T: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode + ManagedVecItem,
> {
pub farming_token_payment: EsdtTokenPayment<M>,
pub additional_farm_tokens: ManagedVec<M, EsdtTokenPayment<M>>,
pub additional_farm_tokens: PaymentsVec<M>,
pub additional_attributes: ManagedVec<M, T>,
}

impl<M: ManagedTypeApi> EnterFarmContext<M> {
impl<
M: ManagedTypeApi + BlockchainApi,
T: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode + ManagedVecItem,
> EnterFarmContext<M, T>
{
pub fn new(
mut payments: ManagedVec<M, EsdtTokenPayment<M>>,
mut payments: PaymentsVec<M>,
farming_token_id: &TokenIdentifier<M>,
farm_token_id: &TokenIdentifier<M>,
api_wrapper: BlockchainWrapper<M>,
) -> Self {
if payments.is_empty() {
M::error_api_impl().signal_error(ERROR_EMPTY_PAYMENTS);
Expand All @@ -24,15 +35,24 @@ impl<M: ManagedTypeApi> EnterFarmContext<M> {
}

payments.remove(0);

let own_sc_address = api_wrapper.get_sc_address();
let mut additional_attributes = ManagedVec::new();
for p in &payments {
if &p.token_identifier != farm_token_id {
M::error_api_impl().signal_error(ERROR_BAD_PAYMENTS);
}

let token_data =
api_wrapper.get_esdt_token_data(&own_sc_address, farm_token_id, p.token_nonce);
let token_attributes: T = token_data.decode_attributes();
additional_attributes.push(token_attributes);
}

EnterFarmContext {
farming_token_payment,
additional_farm_tokens: payments,
additional_attributes,
}
}
}
4 changes: 2 additions & 2 deletions common/modules/farm/events/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ pub trait EventsModule {
fn emit_claim_rewards_event<
'a,
C: FarmContracTraitBounds<Api = Self::Api>,
AttributesType: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode,
AttributesType: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode + ManagedVecItem,
>(
&self,
original_caller: &ManagedAddress,
Expand Down Expand Up @@ -189,7 +189,7 @@ pub trait EventsModule {
fn emit_compound_rewards_event<
'a,
C: FarmContracTraitBounds<Api = Self::Api>,
AttributesType: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode,
AttributesType: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode + ManagedVecItem,
>(
self,
original_caller: &ManagedAddress,
Expand Down
34 changes: 12 additions & 22 deletions common/modules/farm/farm_base_impl/src/base_traits_impl.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
multiversx_sc::imports!();

use common_structs::{FarmToken, FarmTokenAttributes, Nonce};
use common_structs::{FarmToken, FarmTokenAttributes, Nonce, PaymentsVec};
use config::ConfigModule;
use contexts::storage_cache::StorageCache;
use core::marker::PhantomData;
use fixed_supply_token::FixedSupplyToken;
use mergeable::Mergeable;
use multiversx_sc_modules::transfer_role_proxy::PaymentsVec;
use rewards::RewardsModule;

pub trait AllBaseFarmImplTraits =
Expand All @@ -30,8 +29,8 @@ pub trait FarmContract {
+ FixedSupplyToken<<Self::FarmSc as ContractBase>::Api>
+ FarmToken<<Self::FarmSc as ContractBase>::Api>
+ From<FarmTokenAttributes<<Self::FarmSc as ContractBase>::Api>>
+ Into<FarmTokenAttributes<<Self::FarmSc as ContractBase>::Api>> =
FarmTokenAttributes<<Self::FarmSc as ContractBase>::Api>;
+ Into<FarmTokenAttributes<<Self::FarmSc as ContractBase>::Api>>
+ ManagedVecItem = FarmTokenAttributes<<Self::FarmSc as ContractBase>::Api>;

#[inline]
fn mint_rewards(
Expand Down Expand Up @@ -192,27 +191,21 @@ pub trait FarmContract {
fn check_and_update_user_farm_position(
sc: &Self::FarmSc,
user: &ManagedAddress<<Self::FarmSc as ContractBase>::Api>,
farm_positions: &PaymentsVec<<Self::FarmSc as ContractBase>::Api>,
farm_tokens: &PaymentsVec<<Self::FarmSc as ContractBase>::Api>,
farm_attributes: &ManagedVec<<Self::FarmSc as ContractBase>::Api, Self::AttributesType>,
) {
let farm_token_mapper = sc.farm_token();
for farm_position in farm_positions {
farm_token_mapper.require_same_token(&farm_position.token_identifier);

if sc.is_old_farm_position(farm_position.token_nonce) {
for (attr, farm_token) in farm_attributes.into_iter().zip(farm_tokens.iter()) {
if sc.is_old_farm_position(farm_token.token_nonce) {
continue;
}

let token_attributes: FarmTokenAttributes<<Self::FarmSc as ContractBase>::Api> =
farm_token_mapper.get_token_attributes(farm_position.token_nonce);

if &token_attributes.original_owner != user {
Self::decrease_user_farm_position(sc, &farm_position);
Self::increase_user_farm_position(sc, user, &farm_position.amount);
if &attr.get_original_owner() != user {
Self::decrease_user_farm_position(sc, &farm_token, &attr);
Self::increase_user_farm_position(sc, user, &farm_token.amount);
}
}
}

#[inline]
fn increase_user_farm_position(
sc: &Self::FarmSc,
user: &ManagedAddress<<Self::FarmSc as ContractBase>::Api>,
Expand All @@ -227,16 +220,13 @@ pub trait FarmContract {
fn decrease_user_farm_position(
sc: &Self::FarmSc,
farm_position: &EsdtTokenPayment<<Self::FarmSc as ContractBase>::Api>,
attributes: &Self::AttributesType,
) {
if sc.is_old_farm_position(farm_position.token_nonce) {
return;
}

let farm_token_mapper = sc.farm_token();
let token_attributes: FarmTokenAttributes<<Self::FarmSc as ContractBase>::Api> =
farm_token_mapper.get_token_attributes(farm_position.token_nonce);

sc.user_total_farm_position(&token_attributes.original_owner)
sc.user_total_farm_position(&attributes.get_original_owner())
.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;
Expand Down
12 changes: 9 additions & 3 deletions common/modules/farm/farm_base_impl/src/claim_rewards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use fixed_supply_token::FixedSupplyToken;
pub struct InternalClaimRewardsResult<'a, C, T>
where
C: FarmContracTraitBounds,
T: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode,
T: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode + ManagedVecItem,
{
pub context: ClaimRewardsContext<C::Api, T>,
pub storage_cache: StorageCache<'a, C>,
Expand Down Expand Up @@ -81,7 +81,12 @@ pub trait BaseClaimRewardsModule:
);
storage_cache.reward_reserve -= &reward;

FC::check_and_update_user_farm_position(self, &caller, &payments);
FC::check_and_update_user_farm_position(
self,
&caller,
&payments,
&claim_rewards_context.all_attributes,
);

let farm_token_mapper = self.farm_token();
let base_attributes = FC::create_claim_rewards_initial_attributes(
Expand All @@ -90,10 +95,11 @@ pub trait BaseClaimRewardsModule:
token_attributes,
storage_cache.reward_per_share.clone(),
);

let new_token_attributes = self.merge_attributes_from_payments(
base_attributes,
&claim_rewards_context.additional_attributes,
&claim_rewards_context.additional_payments,
&farm_token_mapper,
);
let new_farm_token = PaymentAttributesPair {
payment: EsdtTokenPayment::new(
Expand Down
10 changes: 8 additions & 2 deletions common/modules/farm/farm_base_impl/src/compound_rewards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use fixed_supply_token::FixedSupplyToken;
pub struct InternalCompoundRewardsResult<'a, C, T>
where
C: FarmContracTraitBounds,
T: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode,
T: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode + ManagedVecItem,
{
pub context: CompoundRewardsContext<C::Api, T>,
pub storage_cache: StorageCache<'a, C>,
Expand Down Expand Up @@ -70,7 +70,12 @@ pub trait BaseCompoundRewardsModule:
storage_cache.reward_reserve -= &reward;
storage_cache.farm_token_supply += &reward;

FC::check_and_update_user_farm_position(self, &caller, &payments);
FC::check_and_update_user_farm_position(
self,
&caller,
&payments,
&compound_rewards_context.all_attributes,
);

let farm_token_mapper = self.farm_token();
let base_attributes = FC::create_compound_rewards_initial_attributes(
Expand All @@ -82,6 +87,7 @@ pub trait BaseCompoundRewardsModule:
);
let new_farm_token = self.merge_and_create_token(
base_attributes,
&compound_rewards_context.additional_attributes,
&compound_rewards_context.additional_payments,
&farm_token_mapper,
);
Expand Down
7 changes: 5 additions & 2 deletions common/modules/farm/farm_base_impl/src/enter_farm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use contexts::{
pub struct InternalEnterFarmResult<'a, C, T>
where
C: FarmContracTraitBounds,
T: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode,
T: Clone + TopEncode + TopDecode + NestedEncode + NestedDecode + ManagedVecItem,
{
pub context: EnterFarmContext<C::Api>,
pub context: EnterFarmContext<C::Api, T>,
pub storage_cache: StorageCache<'a, C>,
pub new_farm_token: PaymentAttributesPair<C::Api, T>,
pub created_with_merge: bool,
Expand Down Expand Up @@ -42,13 +42,15 @@ pub trait BaseEnterFarmModule:
payments,
&storage_cache.farming_token_id,
&storage_cache.farm_token_id,
self.blockchain(),
);

// The order is important - first check and update, then increase position
FC::check_and_update_user_farm_position(
self,
&caller,
&enter_farm_context.additional_farm_tokens,
&enter_farm_context.additional_attributes,
);
FC::increase_user_farm_position(
self,
Expand All @@ -69,6 +71,7 @@ pub trait BaseEnterFarmModule:
);
let new_farm_token = self.merge_and_create_token(
base_attributes,
&enter_farm_context.additional_attributes,
&enter_farm_context.additional_farm_tokens,
&farm_token_mapper,
);
Expand Down
2 changes: 1 addition & 1 deletion common/modules/farm/farm_base_impl/src/exit_farm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub trait BaseExitFarmModule:
);
storage_cache.reward_reserve -= &reward;

FC::decrease_user_farm_position(self, &payment);
FC::decrease_user_farm_position(self, &payment, &exit_farm_context.farm_token.attributes);

let farming_token_amount = token_attributes.get_total_supply();
let farming_token_payment = EsdtTokenPayment::new(
Expand Down
Loading

0 comments on commit c8f3f21

Please sign in to comment.