Skip to content

Commit

Permalink
metastaking refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
psorinionut committed Sep 18, 2023
1 parent 4b4e0b7 commit c044821
Show file tree
Hide file tree
Showing 16 changed files with 96 additions and 271 deletions.
30 changes: 16 additions & 14 deletions common/modules/farm/config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,22 @@ pub trait ConfigModule: pausable::PausableModule + permissions_module::Permissio
}
}

fn is_old_farm_position(&self, token_nonce: Nonce) -> bool {
let farm_position_migration_block_nonce = self.farm_position_migration_block_nonce().get();
token_nonce < farm_position_migration_block_nonce
}

#[endpoint(allowExternalClaimBoostedRewards)]
fn allow_external_claim_boosted_rewards(&self, allow_external_claim: bool) {
let caller = self.blockchain().get_caller();
let user_total_farm_position_mapper = self.user_total_farm_position(&caller);
if user_total_farm_position_mapper.is_empty() {
require!(
allow_external_claim,
"Can only set to true if there is no farm position"
);
let mut new_user_farm_position: UserTotalFarmPosition<Self::Api> =
UserTotalFarmPosition::default();
new_user_farm_position.allow_external_claim_boosted_rewards = allow_external_claim;
} else {
user_total_farm_position_mapper.update(|user_total_farm_position| {
user_total_farm_position.allow_external_claim_boosted_rewards =
allow_external_claim;
});
}
require!(
!user_total_farm_position_mapper.is_empty(),
"User must have a farm position"
);
user_total_farm_position_mapper.update(|user_total_farm_position| {
user_total_farm_position.allow_external_claim_boosted_rewards = allow_external_claim;
});
}

#[view(getFarmingTokenId)]
Expand Down Expand Up @@ -102,4 +100,8 @@ pub trait ConfigModule: pausable::PausableModule + permissions_module::Permissio
&self,
user: &ManagedAddress,
) -> SingleValueMapper<UserTotalFarmPosition<Self::Api>>;

#[view(getFarmPositionMigrationBlockNonce)]
#[storage_mapper("farm_position_migration_block_nonce")]
fn farm_position_migration_block_nonce(&self) -> SingleValueMapper<Nonce>;
}
45 changes: 13 additions & 32 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,29 +195,20 @@ 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 {
let is_old_farm_position = sc.is_old_farm_position(farm_position.token_nonce);
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 {
if is_old_farm_position {
Self::increase_user_farm_position(sc, user, &farm_position.amount);
} else 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 = sc.get_user_total_farm_position(user);
if user_total_farm_position.total_farm_position == BigUint::zero()
&& total_farm_position > 0
{
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 @@ -240,24 +231,14 @@ pub trait FarmContract {
let token_attributes: FarmTokenAttributes<<Self::FarmSc as ContractBase>::Api> =
farm_token_mapper.get_token_attributes(farm_position.token_nonce);

let mut user_total_farm_position =
sc.get_user_total_farm_position(&token_attributes.original_owner);

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();
}

if user_total_farm_position.total_farm_position == 0
&& user_total_farm_position.allow_external_claim_boosted_rewards == false
{
sc.user_total_farm_position(&token_attributes.original_owner)
.clear();
} else {
sc.user_total_farm_position(&token_attributes.original_owner)
.set(user_total_farm_position);
}
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();
}
});
}
}

Expand Down
5 changes: 3 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: 65
// Endpoints: 66
// Async Callback: 1
// Total number of exported functions: 67
// Total number of exported functions: 68

#![no_std]

Expand Down Expand Up @@ -40,6 +40,7 @@ multiversx_sc_wasm_adapter::endpoints! {
getLastRewardBlockNonce => last_reward_block_nonce
getDivisionSafetyConstant => division_safety_constant
getUserTotalFarmPosition => user_total_farm_position
getFarmPositionMigrationBlockNonce => farm_position_migration_block_nonce
setLockingScAddress => set_locking_sc_address
setLockEpochs => set_lock_epochs
getLockingScAddress => locking_sc_address
Expand Down
7 changes: 1 addition & 6 deletions dex/farm/src/base_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,8 @@ where
) -> BigUint<<<Self as FarmContract>::FarmSc as ContractBase>::Api> {
let user_total_farm_position = sc.get_user_total_farm_position(caller);
let user_farm_position = user_total_farm_position.total_farm_position;
let mut boosted_rewards = BigUint::zero();

if user_farm_position > 0 {
boosted_rewards = sc.claim_boosted_yields_rewards(caller, user_farm_position);
}

boosted_rewards
sc.claim_boosted_yields_rewards(caller, user_farm_position)
}
}

Expand Down
5 changes: 5 additions & 0 deletions dex/farm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ pub trait Farm:

let current_epoch = self.blockchain().get_block_epoch();
self.first_week_start_epoch().set_if_empty(current_epoch);

// Farm position migration code
let block_nonce = self.blockchain().get_block_nonce();
self.farm_position_migration_block_nonce()
.set_if_empty(block_nonce);
}

#[payable("*")]
Expand Down
5 changes: 3 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: 62
// Endpoints: 63
// Async Callback: 1
// Total number of exported functions: 64
// Total number of exported functions: 65

#![no_std]

Expand Down Expand Up @@ -41,6 +41,7 @@ multiversx_sc_wasm_adapter::endpoints! {
getLastRewardBlockNonce => last_reward_block_nonce
getDivisionSafetyConstant => division_safety_constant
getUserTotalFarmPosition => user_total_farm_position
getFarmPositionMigrationBlockNonce => farm_position_migration_block_nonce
registerFarmToken => register_farm_token
getFarmTokenId => farm_token
getFarmTokenSupply => farm_token_supply
Expand Down
81 changes: 7 additions & 74 deletions farm-staking/farm-staking-proxy/src/dual_yield_token.rs
Original file line number Diff line number Diff line change
@@ -1,84 +1,19 @@
use fixed_supply_token::FixedSupplyToken;
use multiversx_sc::codec::{NestedDecodeInput, TopDecodeInput};

multiversx_sc::imports!();
multiversx_sc::derive_imports!();

#[derive(TypeAbi, TopEncode, PartialEq, Debug, Clone)]
#[derive(TypeAbi, TopEncode, TopDecode, Clone, PartialEq, Debug)]
pub struct DualYieldTokenAttributes<M: ManagedTypeApi> {
pub lp_farm_token_nonce: u64,
pub lp_farm_token_amount: BigUint<M>,
pub virtual_pos_token_nonce: u64,
pub virtual_pos_token_amount: BigUint<M>,
pub real_pos_token_amount: BigUint<M>,
}

impl<M: ManagedTypeApi> DualYieldTokenAttributes<M> {
pub fn new(
lp_farm_token_nonce: u64,
lp_farm_token_amount: BigUint<M>,
virtual_pos_token_nonce: u64,
virtual_pos_token_amount: BigUint<M>,
) -> Self {
DualYieldTokenAttributes {
lp_farm_token_nonce,
lp_farm_token_amount,
virtual_pos_token_nonce,
virtual_pos_token_amount,
real_pos_token_amount: BigUint::zero(),
}
}

pub fn get_total_staking_token_amount(&self) -> BigUint<M> {
&self.virtual_pos_token_amount + &self.real_pos_token_amount
}
}

impl<M: ManagedTypeApi> TopDecode for DualYieldTokenAttributes<M> {
fn top_decode<I>(input: I) -> Result<Self, DecodeError>
where
I: TopDecodeInput,
{
let mut buffer = input.into_nested_buffer();
Self::dep_decode(&mut buffer)
}
}

impl<M: ManagedTypeApi> NestedDecode for DualYieldTokenAttributes<M> {
fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
let lp_farm_token_nonce = u64::dep_decode(input)?;
let lp_farm_token_amount = BigUint::dep_decode(input)?;
let virtual_pos_token_nonce = u64::dep_decode(input)?;
let virtual_pos_token_amount = BigUint::dep_decode(input)?;

if input.is_depleted() {
return Result::Ok(DualYieldTokenAttributes::new(
lp_farm_token_nonce,
lp_farm_token_amount,
virtual_pos_token_nonce,
virtual_pos_token_amount,
));
}

let real_pos_token_amount = BigUint::dep_decode(input)?;

if !input.is_depleted() {
return Result::Err(DecodeError::INPUT_TOO_LONG);
}

Result::Ok(DualYieldTokenAttributes {
lp_farm_token_nonce,
lp_farm_token_amount,
virtual_pos_token_nonce,
virtual_pos_token_amount,
real_pos_token_amount,
})
}
pub staking_farm_token_nonce: u64,
pub staking_farm_token_amount: BigUint<M>,
}

impl<M: ManagedTypeApi> FixedSupplyToken<M> for DualYieldTokenAttributes<M> {
fn get_total_supply(&self) -> BigUint<M> {
self.virtual_pos_token_amount.clone()
self.staking_farm_token_amount.clone()
}

fn into_part(self, payment_amount: &BigUint<M>) -> Self {
Expand All @@ -88,15 +23,13 @@ impl<M: ManagedTypeApi> FixedSupplyToken<M> for DualYieldTokenAttributes<M> {

let new_lp_farm_token_amount =
self.rule_of_three_non_zero_result(payment_amount, &self.lp_farm_token_amount);
let new_virtual_pos_amount = payment_amount.clone();
let new_real_pos_amount = self.rule_of_three(payment_amount, &self.real_pos_token_amount);
let new_staking_farm_token_amount = payment_amount.clone();

DualYieldTokenAttributes {
lp_farm_token_nonce: self.lp_farm_token_nonce,
lp_farm_token_amount: new_lp_farm_token_amount,
virtual_pos_token_nonce: self.virtual_pos_token_nonce,
virtual_pos_token_amount: new_virtual_pos_amount,
real_pos_token_amount: new_real_pos_amount,
staking_farm_token_nonce: self.staking_farm_token_nonce,
staking_farm_token_amount: new_staking_farm_token_amount,
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,30 +164,6 @@ pub trait ExternalContractsInteractionsModule:
}
}

fn staking_farm_unstake_user_position(
&self,
orig_caller: ManagedAddress,
farm_token_nonce: u64,
farm_token_amount: BigUint,
exit_amount: BigUint,
) -> StakingFarmExitResult<Self::Api> {
let staking_farm_token_id = self.staking_farm_token_id().get();
let staking_farm_address = self.staking_farm_address().get();
let unstake_result: ExitFarmWithPartialPosResultType<Self::Api> = self
.staking_farm_proxy_obj(staking_farm_address)
.unstake_farm(exit_amount, orig_caller)
.with_esdt_transfer((staking_farm_token_id, farm_token_nonce, farm_token_amount))
.execute_on_dest_context();
let (unbond_staking_farm_token, staking_rewards, remaining_farm_tokens) =
unstake_result.into_tuple();

StakingFarmExitResult {
unbond_staking_farm_token,
staking_rewards,
remaining_farm_tokens,
}
}

// pair

fn pair_remove_liquidity(
Expand Down
12 changes: 5 additions & 7 deletions farm-staking/farm-staking-proxy/src/proxy_actions/claim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub trait ProxyClaimModule:
let internal_claim_result = self.claim_dual_yield(
&caller,
opt_orig_caller,
attributes.get_total_staking_token_amount(),
attributes.staking_farm_token_amount.clone(),
attributes,
);

Expand Down Expand Up @@ -66,8 +66,7 @@ pub trait ProxyClaimModule:
attributes.lp_farm_token_nonce,
&attributes.lp_farm_token_amount,
);
let lp_tokens_safe_price = self.get_lp_tokens_safe_price(lp_tokens_in_position);
let new_staking_farm_value = &lp_tokens_safe_price + &attributes.real_pos_token_amount;
let new_staking_farm_value = self.get_lp_tokens_safe_price(lp_tokens_in_position);

let staking_farm_token_id = self.staking_farm_token_id().get();
let lp_farm_token_id = self.lp_farm_token_id().get();
Expand All @@ -80,7 +79,7 @@ pub trait ProxyClaimModule:
let staking_farm_claim_rewards_result = self.staking_farm_claim_rewards(
orig_caller,
staking_farm_token_id,
attributes.virtual_pos_token_nonce,
attributes.staking_farm_token_nonce,
staking_claim_amount,
new_staking_farm_value,
);
Expand All @@ -90,9 +89,8 @@ pub trait ProxyClaimModule:
let new_attributes = DualYieldTokenAttributes {
lp_farm_token_nonce: new_lp_farm_tokens.token_nonce,
lp_farm_token_amount: new_lp_farm_tokens.amount,
virtual_pos_token_nonce: new_staking_farm_tokens.token_nonce,
virtual_pos_token_amount: lp_tokens_safe_price,
real_pos_token_amount: attributes.real_pos_token_amount,
staking_farm_token_nonce: new_staking_farm_tokens.token_nonce,
staking_farm_token_amount: new_staking_farm_tokens.amount,
};

InternalClaimResult {
Expand Down
Loading

0 comments on commit c044821

Please sign in to comment.