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 20 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
41 changes: 41 additions & 0 deletions common/modules/farm/config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@ use pausable::State;

pub const DEFAULT_NFT_DEPOSIT_MAX_LEN: usize = 10;

#[derive(
ManagedVecItem,
TopEncode,
TopDecode,
NestedEncode,
NestedDecode,
TypeAbi,
Clone,
PartialEq,
Debug,
)]
pub struct UserTotalFarmPositionStruct<M: ManagedTypeApi> {
pub total_farm_position: BigUint<M>,
pub allow_external_claim_boosted_rewards: bool,
}

#[multiversx_sc::module]
pub trait ConfigModule: pausable::PausableModule + permissions_module::PermissionsModule {
#[inline]
Expand All @@ -16,6 +32,24 @@ pub trait ConfigModule: pausable::PausableModule + permissions_module::Permissio
state == State::Active
}

fn get_user_total_farm_position(&self, user: &ManagedAddress) -> BigUint {
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()
.total_farm_position
}

fn get_allow_external_claim_boosted_rewards(&self, user: &ManagedAddress) -> bool {
self.user_total_farm_position(user)
.get()
.allow_external_claim_boosted_rewards
}

#[view(getFarmingTokenId)]
#[storage_mapper("farming_token_id")]
fn farming_token_id(&self) -> SingleValueMapper<TokenIdentifier>;
Expand All @@ -38,4 +72,11 @@ 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<UserTotalFarmPositionStruct<Self::Api>>;
}
62 changes: 62 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,67 @@ 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();
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;
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;
}
}

let user_total_farm_position = sc.get_user_total_farm_position(user);
if user_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]
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>,
new_farm_position_amount: &BigUint<<Self::FarmSc as ContractBase>::Api>,
) {
sc.user_total_farm_position(user)
.update(|user_farm_position_struct| {
user_farm_position_struct.total_farm_position += new_farm_position_amount
});
}

fn decrease_user_farm_position(
sc: &Self::FarmSc,
farm_position: &EsdtTokenPayment<<Self::FarmSc as ContractBase>::Api>,
) {
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_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;
} else {
user_total_farm_position = BigUint::zero();
}
user_farm_position_struct.total_farm_position = user_total_farm_position;
});
}
}

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,11 +58,13 @@ 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(),
);

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 Down
4 changes: 3 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 @@ -46,11 +46,13 @@ pub trait BaseCompoundRewardsModule:
);

let compound_rewards_context = CompoundRewardsContext::<Self::Api, FC::AttributesType>::new(
payments,
payments.clone(),
&storage_cache.farm_token_id,
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 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,11 +39,13 @@ 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(),
);

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 Down
3 changes: 0 additions & 3 deletions dex/farm-with-locked-rewards/elrond.json

This file was deleted.

6 changes: 4 additions & 2 deletions dex/farm-with-locked-rewards/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
////////////////////////////////////////////////////

// Init: 1
// Endpoints: 62
// Endpoints: 64
// Async Callback: 1
// Total number of exported functions: 64
// Total number of exported functions: 66

#![no_std]
#![feature(alloc_error_handler, lang_items)]
Expand All @@ -33,6 +33,7 @@ multiversx_sc_wasm_adapter::endpoints! {
getPerBlockRewardAmount
getLastRewardBlockNonce
getDivisionSafetyConstant
getUserTotalFarmPosition
setLockingScAddress
setLockEpochs
getLockingScAddress
Expand All @@ -59,6 +60,7 @@ multiversx_sc_wasm_adapter::endpoints! {
getMinimumFarmingEpoch
getBurnGasLimit
getPairContractManagedAddress
claimBoostedRewards
setBoostedYieldsRewardsPercentage
collectUndistributedBoostedRewards
getBoostedYieldsRewardsPercentage
Expand Down
20 changes: 11 additions & 9 deletions dex/farm/src/base_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ pub trait BaseFunctionsModule:
let token_mapper = self.farm_token();
token_mapper.require_all_same_token(&payments);

let caller = self.blockchain().get_caller();
FC::check_and_update_user_farm_position(self, &caller, &payments);

let output_attributes: FC::AttributesType =
self.merge_from_payments_and_burn(payments, &token_mapper);
let new_token_amount = output_attributes.get_total_supply();
Expand Down Expand Up @@ -236,15 +239,19 @@ where
sc: &<Self as FarmContract>::FarmSc,
caller: &ManagedAddress<<<Self as FarmContract>::FarmSc as ContractBase>::Api>,
token_attributes: &<Self as FarmContract>::AttributesType,
farm_token_amount: BigUint<<<Self as FarmContract>::FarmSc as ContractBase>::Api>,
) -> BigUint<<<Self as FarmContract>::FarmSc as ContractBase>::Api> {
if &token_attributes.original_owner != caller {
let original_owner = &token_attributes.original_owner;

if original_owner != caller {
sc.update_energy_and_progress(caller);
}

let user_total_farm_position = sc.get_user_total_farm_position(original_owner);
if user_total_farm_position == BigUint::zero() {
return BigUint::zero();
}

sc.claim_boosted_yields_rewards(caller, farm_token_amount)
sc.claim_boosted_yields_rewards(caller, user_total_farm_position)
}
}

Expand Down Expand Up @@ -288,12 +295,7 @@ where
token_attributes,
storage_cache,
);
let boosted_yield_rewards = Self::calculate_boosted_rewards(
sc,
caller,
token_attributes,
farm_token_amount.clone(),
);
let boosted_yield_rewards = Self::calculate_boosted_rewards(sc, caller, token_attributes);

base_farm_reward + boosted_yield_rewards
}
Expand Down
44 changes: 38 additions & 6 deletions dex/farm/src/claim_boost_only.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,43 @@ pub trait ClaimBoostOnlyModule:
+ farm_boosted_yields::boosted_yields_factors::BoostedYieldsFactorsModule
+ crate::base_functions::BaseFunctionsModule
{
#[payable("*")]
#[endpoint(claimBoostedRewards)]
fn claim_boosted_rewards(
&self,
opt_user: OptionalValue<ManagedAddress>,
) -> EsdtTokenPayment<Self::Api> {
let user = match opt_user {
CostinCarabas marked this conversation as resolved.
Show resolved Hide resolved
OptionalValue::Some(user) => {
require!(
self.get_allow_external_claim_boosted_rewards(&user),
"Cannot claim rewards for this address"
);
user
}
OptionalValue::None => self.blockchain().get_caller(),
};

let reward_token_id = self.reward_token_id().get();

let user_total_farm_position = self.get_user_total_farm_position(&user);
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,
Expand All @@ -41,12 +78,7 @@ pub trait ClaimBoostOnlyModule:

let token_attributes =
self.get_attributes_as_part_of_fixed_supply(payment, &farm_token_mapper);
let reward = Wrapper::<Self>::calculate_boosted_rewards(
self,
caller,
&token_attributes,
payment.amount.clone(),
);
let reward = Wrapper::<Self>::calculate_boosted_rewards(self, caller, &token_attributes);
if reward > 0 {
self.reward_reserve().update(|reserve| *reserve -= &reward);
}
Expand Down
10 changes: 8 additions & 2 deletions dex/farm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,13 @@ pub trait Farm:
let caller = self.blockchain().get_caller();
let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller);

let claim_rewards_result = self.claim_rewards::<Wrapper<Self>>(orig_caller);
let claim_rewards_result = self.claim_rewards::<Wrapper<Self>>(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()
}

Expand All @@ -134,9 +137,12 @@ pub trait Farm:
let caller = self.blockchain().get_caller();
let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller);

let output_farm_token_payment = self.compound_rewards::<Wrapper<Self>>(orig_caller);
let output_farm_token_payment = self.compound_rewards::<Wrapper<Self>>(orig_caller.clone());

self.send_payment_non_zero(&caller, &output_farm_token_payment);

self.update_energy_and_progress(&orig_caller);
Copy link
Contributor

Choose a reason for hiding this comment

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

this only reads from energy contract and writes in the current contract ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes


output_farm_token_payment
}

Expand Down
6 changes: 4 additions & 2 deletions dex/farm/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
////////////////////////////////////////////////////

// Init: 1
// Endpoints: 59
// Endpoints: 61
// Async Callback: 1
// Total number of exported functions: 61
// Total number of exported functions: 63

#![no_std]
#![feature(alloc_error_handler, lang_items)]
Expand All @@ -34,6 +34,7 @@ multiversx_sc_wasm_adapter::endpoints! {
getPerBlockRewardAmount
getLastRewardBlockNonce
getDivisionSafetyConstant
getUserTotalFarmPosition
registerFarmToken
getFarmTokenId
getFarmTokenSupply
Expand All @@ -56,6 +57,7 @@ multiversx_sc_wasm_adapter::endpoints! {
getMinimumFarmingEpoch
getBurnGasLimit
getPairContractManagedAddress
claimBoostedRewards
setBoostedYieldsRewardsPercentage
collectUndistributedBoostedRewards
getBoostedYieldsRewardsPercentage
Expand Down
Loading