Skip to content

Commit

Permalink
Merge pull request #772 from multiversx/farm-position-fixes
Browse files Browse the repository at this point in the history
farm position first audit fixes
  • Loading branch information
psorinionut authored Sep 29, 2023
2 parents 249c3ee + 36be963 commit ff4f6b1
Show file tree
Hide file tree
Showing 71 changed files with 1,843 additions and 1,961 deletions.
1 change: 0 additions & 1 deletion .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ on:
push:
branches: [ main, feat/* ]
pull_request:
branches: [ main, feat/* ]
workflow_dispatch:

permissions:
Expand Down
71 changes: 60 additions & 11 deletions common/modules/farm/config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -19,30 +20,74 @@ pub const DEFAULT_NFT_DEPOSIT_MAX_LEN: usize = 10;
PartialEq,
Debug,
)]
pub struct UserTotalFarmPositionStruct<M: ManagedTypeApi> {
pub struct UserTotalFarmPosition<M: ManagedTypeApi> {
pub total_farm_position: BigUint<M>,
pub allow_external_claim_boosted_rewards: bool,
}

impl<M: ManagedTypeApi> Default for UserTotalFarmPosition<M> {
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::Api> {
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<Self::Api> {
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<Self::Api>,
) {
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)]
Expand Down Expand Up @@ -73,5 +118,9 @@ pub trait ConfigModule: pausable::PausableModule + permissions_module::Permissio
fn user_total_farm_position(
&self,
user: &ManagedAddress,
) -> SingleValueMapper<UserTotalFarmPositionStruct<Self::Api>>;
) -> SingleValueMapper<UserTotalFarmPosition<Self::Api>>;

#[view(getFarmPositionMigrationNonce)]
#[storage_mapper("farm_position_migration_nonce")]
fn farm_position_migration_nonce(&self) -> SingleValueMapper<Nonce>;
}
37 changes: 16 additions & 21 deletions common/modules/farm/farm_base_impl/src/base_traits_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,27 +195,21 @@ pub trait FarmContract {
farm_positions: &PaymentsVec<<Self::FarmSc as ContractBase>::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<<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);
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]
Expand All @@ -224,30 +218,31 @@ pub trait FarmContract {
user: &ManagedAddress<<Self::FarmSc as ContractBase>::Api>,
increase_farm_position_amount: &BigUint<<Self::FarmSc as ContractBase>::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<<Self::FarmSc as ContractBase>::Api>,
) {
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)
.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;
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions common/modules/farm/farm_base_impl/src/claim_rewards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion common/modules/farm/farm_base_impl/src/compound_rewards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions common/modules/farm/farm_base_impl/src/exit_farm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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(),
Expand Down
Loading

0 comments on commit ff4f6b1

Please sign in to comment.