Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

farm position functionality #760

Merged
merged 71 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
4ad9758
farm position functionality
psorinionut Aug 14, 2023
b4c924c
updateTotalFarmPosition endpoint fix
psorinionut Aug 14, 2023
667c19a
clippy fix
psorinionut Aug 14, 2023
8348f52
fixes after review
psorinionut Aug 15, 2023
5d2d020
Fixes after review
CostinCarabas Aug 22, 2023
5e05e32
farm-staking: Fixed module dependencies
CostinCarabas Aug 22, 2023
4f6bbd3
farm-staking: farm position functionality
CostinCarabas Aug 23, 2023
97b52fa
farm_position: compilation dependencies
CostinCarabas Aug 23, 2023
6b47ab3
Merge branch 'main' into farm-position-functionality
CostinCarabas Aug 23, 2023
6502c5b
Merge branch 'main' into farm-position-functionality
CostinCarabas Aug 23, 2023
b70b0de
farm-staking: Fix tests
CostinCarabas Aug 23, 2023
8997f70
Remove farm-position code
CostinCarabas Aug 23, 2023
d37f593
farm-staking: Remove merge for dual staking
CostinCarabas Aug 24, 2023
872278b
Merge branch 'main' into farm-position-functionality
CostinCarabas Aug 28, 2023
6580dba
farm/farm-staking: Update energy after claim
CostinCarabas Aug 29, 2023
3c4ffe1
Merge remote-tracking branch 'origin/farm-position-functionality' int…
CostinCarabas Aug 29, 2023
5d7a848
fees-collector: Fixes after review
CostinCarabas Aug 29, 2023
b445da1
Clippy fixes and compiling dependencies
CostinCarabas Aug 29, 2023
e46c4d2
Update common/modules/farm/farm_base_impl/src/base_traits_impl.rs
CostinCarabas Aug 29, 2023
ea612c1
Fixes after review
CostinCarabas Aug 29, 2023
9bdf09c
Fixes after review
CostinCarabas Aug 30, 2023
07f41a3
Fix minor issue
CostinCarabas Aug 31, 2023
14baa0a
fees-collector:Add test for "claim for other user"
CostinCarabas Aug 31, 2023
63de49e
Clippy fixes
CostinCarabas Aug 31, 2023
0e7141c
farm: Add claim boosted for other user test
CostinCarabas Aug 31, 2023
f40d64a
farm-staking:Add test claim for other user
CostinCarabas Aug 31, 2023
ff3f040
Fixes after review
CostinCarabas Aug 31, 2023
f1496d5
farm: compound_rewards_base bug fix
CostinCarabas Aug 31, 2023
98aa836
Refactor clippy fix
CostinCarabas Aug 31, 2023
f371569
Clippy fix for test setup
CostinCarabas Aug 31, 2023
5b00a9c
Give boosted energy even after unlock xMEX
CostinCarabas Sep 4, 2023
4ff1b8a
Merge pull request #767 from multiversx/give-boosted-after-unlock
sasurobert Sep 4, 2023
00dc45d
Fixes after review
CostinCarabas Sep 4, 2023
0f87499
Merge branch 'main' into farm-position-functionality
CostinCarabas Sep 6, 2023
249c3ee
Fix clippy
CostinCarabas Sep 7, 2023
4b4e0b7
farm position first audit fixes
psorinionut Sep 13, 2023
c044821
metastaking refactor
psorinionut Sep 18, 2023
16576f1
readded claim progress check
psorinionut Sep 18, 2023
3fc935a
clippy fixes
psorinionut Sep 18, 2023
be142a3
dedicated migration function for old positions
psorinionut Sep 18, 2023
a77b760
remove caller check in migrate old position func
psorinionut Sep 19, 2023
3fe300e
remove exit amount parameter from farms
psorinionut Sep 19, 2023
37c9ebc
clippy fix
psorinionut Sep 19, 2023
9859e47
tests fixes
psorinionut Sep 19, 2023
d9fd841
remove metastaking ProxyMergePosModule
psorinionut Sep 20, 2023
65930ce
send rewards to user in claim_boosted_rewards
psorinionut Sep 20, 2023
ee6644c
claim boosted in merge endpoints
psorinionut Sep 20, 2023
1e9ec92
clippy and test fix
psorinionut Sep 20, 2023
bbff637
audit fixes (2)
psorinionut Sep 20, 2023
c609e42
Merge pull request #774 from multiversx/claim-boosted-in-merge-endpoints
psorinionut Sep 20, 2023
8ac9c19
Merge pull request #773 from multiversx/remove-exit-amount-parameter
psorinionut Sep 20, 2023
4303c0c
default migration nonce fix
psorinionut Sep 20, 2023
767f452
use GetCurrentESDTNFTNonce VM endpoint
psorinionut Sep 21, 2023
8100d57
try_set_farm_position_migration_nonce: code dup
CostinCarabas Sep 21, 2023
aba2e4e
fix farm_position_migration_nonce set function
psorinionut Sep 22, 2023
1d92432
Merge pull request #775 from multiversx/farm-position-audit-fixes-2
psorinionut Sep 26, 2023
494b301
farm position functionality tests
psorinionut Sep 26, 2023
772779a
allow_external_claim_rewards_setting extra check
psorinionut Sep 26, 2023
d790945
total_farm_position_claim_for_other extra check
psorinionut Sep 26, 2023
0ee2b42
farm position tests updates
psorinionut Sep 26, 2023
4262fa1
farm staking full position claim test
psorinionut Sep 28, 2023
a6e3e00
Merge pull request #776 from multiversx/farm-position-tests
sasurobert Sep 29, 2023
36be963
clippy fix
psorinionut Sep 29, 2023
ff4f6b1
Merge pull request #772 from multiversx/farm-position-fixes
psorinionut Sep 29, 2023
5acf5e4
build & cargo lock
psorinionut Sep 29, 2023
d1a9e72
github actions update
psorinionut Sep 29, 2023
75eba99
Merge branch 'main' into farm-position-functionality
psorinionut Sep 29, 2023
2e36524
clippy fix
psorinionut Sep 29, 2023
67a7d42
cargo lock fix
psorinionut Sep 29, 2023
4dc0203
farm with lock rewards cargo lock fix
psorinionut Sep 29, 2023
3cf4458
Merge branch 'main' into farm-position-functionality
psorinionut Oct 2, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions common/modules/farm/config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,89 @@ 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,
TopEncode,
TopDecode,
NestedEncode,
NestedDecode,
TypeAbi,
Clone,
PartialEq,
Debug,
)]
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(
&self,
user: &ManagedAddress,
) -> 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)]
#[storage_mapper("farming_token_id")]
fn farming_token_id(&self) -> SingleValueMapper<TokenIdentifier>;
Expand All @@ -38,4 +112,15 @@ pub trait ConfigModule: pausable::PausableModule + permissions_module::Permissio
#[view(getDivisionSafetyConstant)]
#[storage_mapper("division_safety_constant")]
fn division_safety_constant(&self) -> SingleValueMapper<BigUint>;

#[view(getUserTotalFarmPosition)]
#[storage_mapper("userTotalFarmPosition")]
fn user_total_farm_position(
&self,
user: &ManagedAddress,
) -> SingleValueMapper<UserTotalFarmPosition<Self::Api>>;

#[view(getFarmPositionMigrationNonce)]
#[storage_mapper("farm_position_migration_nonce")]
fn farm_position_migration_nonce(&self) -> SingleValueMapper<Nonce>;
}
58 changes: 58 additions & 0 deletions common/modules/farm/farm_base_impl/src/base_traits_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ 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 Down Expand Up @@ -187,6 +188,63 @@ pub trait FarmContract {
_storage_cache: &StorageCache<Self::FarmSc>,
) {
}

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>,
) {
let farm_token_mapper = sc.farm_token();
for farm_position in farm_positions {
farm_token_mapper.require_same_token(&farm_position.token_identifier);

if sc.is_old_farm_position(farm_position.token_nonce) {
continue;
}

let token_attributes: FarmTokenAttributes<<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);
}
}
}

CostinCarabas marked this conversation as resolved.
Show resolved Hide resolved
#[inline]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add empty line before

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

fn increase_user_farm_position(
sc: &Self::FarmSc,
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)
.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);
Comment on lines +235 to +237
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting attributes a second time, first time on line 204. Why not give them as argument?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use decrease_user_farm_position in other contexts (i.e. BaseExitFarmModule).
I think the improvement here would be less than the expense in exit_farm_base: we would have to get farm_token from storage and then get_token_attributes.


sc.user_total_farm_position(&token_attributes.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;
} else {
user_total_farm_position.total_farm_position = BigUint::zero();
}
});
}
}

pub struct DefaultFarmWrapper<T>
Expand Down
4 changes: 3 additions & 1 deletion common/modules/farm/farm_base_impl/src/claim_rewards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub trait BaseClaimRewardsModule:
self.validate_contract_state(storage_cache.contract_state, &storage_cache.farm_token_id);

let claim_rewards_context = ClaimRewardsContext::<Self::Api, FC::AttributesType>::new(
payments,
payments.clone(),
&storage_cache.farm_token_id,
self.blockchain(),
);
Expand All @@ -81,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
8 changes: 6 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 @@ -46,7 +46,7 @@ pub trait BaseCompoundRewardsModule:
);

let compound_rewards_context = CompoundRewardsContext::<Self::Api, FC::AttributesType>::new(
payments,
payments.clone(),
&storage_cache.farm_token_id,
self.blockchain(),
);
Expand All @@ -70,10 +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);

let farm_token_mapper = self.farm_token();
let base_attributes = FC::create_compound_rewards_initial_attributes(
self,
caller,
caller.clone(),
token_attributes,
storage_cache.reward_per_share.clone(),
&reward,
Expand All @@ -84,6 +86,8 @@ pub trait BaseCompoundRewardsModule:
&farm_token_mapper,
);

FC::increase_user_farm_position(self, &caller, &reward);

let first_farm_token = &compound_rewards_context.first_farm_token.payment;
farm_token_mapper.nft_burn(first_farm_token.token_nonce, &first_farm_token.amount);
self.send()
Expand Down
12 changes: 12 additions & 0 deletions common/modules/farm/farm_base_impl/src/enter_farm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ pub trait BaseEnterFarmModule:
&storage_cache.farm_token_id,
);

// 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,
);
FC::increase_user_farm_position(
self,
&caller,
&enter_farm_context.farming_token_payment.amount,
);

FC::generate_aggregated_rewards(self, &mut storage_cache);

storage_cache.farm_token_supply += &enter_farm_context.farming_token_payment.amount;
Expand Down
4 changes: 3 additions & 1 deletion common/modules/farm/farm_base_impl/src/exit_farm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub trait BaseExitFarmModule:
self.validate_contract_state(storage_cache.contract_state, &storage_cache.farm_token_id);

let exit_farm_context = ExitFarmContext::<Self::Api, FC::AttributesType>::new(
payment,
payment.clone(),
&storage_cache.farm_token_id,
self.blockchain(),
);
Expand All @@ -62,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
3 changes: 0 additions & 3 deletions dex/farm-with-locked-rewards/elrond.json

This file was deleted.

Loading
Loading