Skip to content

Commit

Permalink
Merge pull request #833 from multiversx/farm-staking-nft-impl-part-4
Browse files Browse the repository at this point in the history
Farm staking NFT impl (part 4)
  • Loading branch information
dorin-iancu authored Feb 13, 2024
2 parents 032eecc + 39614f1 commit 9527a5c
Show file tree
Hide file tree
Showing 14 changed files with 116 additions and 63 deletions.
4 changes: 4 additions & 0 deletions farm-staking/farm-staking-nft/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod farm_token_roles;
pub mod result_types;
pub mod token_attributes;
pub mod token_info;
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use common_structs::PaymentsVec;

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

Expand Down Expand Up @@ -29,3 +31,8 @@ pub struct UnstakeRewardsResultType<M: ManagedTypeApi> {
pub unbond_farm_token: EsdtTokenPayment<M>,
pub reward_payment: EsdtTokenPayment<M>,
}

#[derive(TypeAbi, TopEncode, TopDecode)]
pub struct UnbondResultType<M: ManagedTypeApi> {
pub farming_tokens: PaymentsVec<M>,
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ impl<M: ManagedTypeApi> Mergeable<M> for PartialStakingFarmNftTokenAttributes<M>
}

#[derive(TypeAbi, TopEncode, TopDecode, PartialEq, Debug)]
pub struct UnbondSftAttributes /*<M: ManagedTypeApi>*/ {
pub struct UnbondSftAttributes<M: ManagedTypeApi> {
pub unlock_epoch: u64,
// pub farming_token_parts: PaymentsVec<M>,
pub farming_token_parts: PaymentsVec<M>,
}

#[derive(ManagedVecItem, Clone)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use common_structs::{Nonce, PaymentAttributesPair, PaymentsVec};
use mergeable::Mergeable;

use crate::token_attributes::{
use super::token_attributes::{
PartialStakingFarmNftTokenAttributes, StakingFarmNftTokenAttributes,
};

Expand Down
2 changes: 1 addition & 1 deletion farm-staking/farm-staking-nft/src/custom_rewards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ multiversx_sc::derive_imports!();
use common_structs::{Epoch, Nonce, PaymentsVec};
use contexts::storage_cache::StorageCache;

use crate::token_attributes::{
use crate::common::token_attributes::{
PartialStakingFarmNftTokenAttributes, StakingFarmNftTokenAttributes,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ use contexts::{
};

use crate::{
common::result_types::ClaimRewardsResultType,
common::token_attributes::{
PartialStakingFarmNftTokenAttributes, StakingFarmNftTokenAttributes,
},
farm_hooks::hook_type::FarmHookType,
result_types::ClaimRewardsResultType,
token_attributes::{PartialStakingFarmNftTokenAttributes, StakingFarmNftTokenAttributes},
};

pub struct InternalClaimRewardsResult<'a, C>
Expand Down Expand Up @@ -50,7 +52,7 @@ pub trait ClaimStakeFarmRewardsModule:
+ banned_addresses::BannedAddressModule
+ crate::farm_hooks::change_hooks::ChangeHooksModule
+ crate::farm_hooks::call_hook::CallHookModule
+ crate::token_info::TokenInfoModule
+ crate::common::token_info::TokenInfoModule
{
#[payable("*")]
#[endpoint(claimRewards)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ use contexts::{
};

use crate::{
common::result_types::CompoundRewardsResultType,
common::token_attributes::{
PartialStakingFarmNftTokenAttributes, StakingFarmNftTokenAttributes,
},
farm_hooks::hook_type::FarmHookType,
result_types::CompoundRewardsResultType,
token_attributes::{PartialStakingFarmNftTokenAttributes, StakingFarmNftTokenAttributes},
};

multiversx_sc::imports!();
Expand Down Expand Up @@ -51,7 +53,7 @@ pub trait CompoundStakeFarmRewardsModule:
+ banned_addresses::BannedAddressModule
+ crate::farm_hooks::change_hooks::ChangeHooksModule
+ crate::farm_hooks::call_hook::CallHookModule
+ crate::token_info::TokenInfoModule
+ crate::common::token_info::TokenInfoModule
{
#[payable("*")]
#[endpoint(compoundRewards)]
Expand Down
7 changes: 4 additions & 3 deletions farm-staking/farm-staking-nft/src/farm_actions/stake_farm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use contexts::{enter_farm_context::EnterFarmContext, storage_cache::StorageCache
use farm_base_impl::enter_farm::InternalEnterFarmResult;

use crate::{
farm_hooks::hook_type::FarmHookType, result_types::EnterFarmResultType,
token_attributes::PartialStakingFarmNftTokenAttributes,
common::result_types::EnterFarmResultType,
common::token_attributes::PartialStakingFarmNftTokenAttributes,
farm_hooks::hook_type::FarmHookType,
};

#[multiversx_sc::module]
Expand Down Expand Up @@ -36,7 +37,7 @@ pub trait StakeFarmModule:
+ banned_addresses::BannedAddressModule
+ crate::farm_hooks::change_hooks::ChangeHooksModule
+ crate::farm_hooks::call_hook::CallHookModule
+ crate::token_info::TokenInfoModule
+ crate::common::token_info::TokenInfoModule
{
#[payable("*")]
#[endpoint(stakeFarm)]
Expand Down
31 changes: 17 additions & 14 deletions farm-staking/farm-staking-nft/src/farm_actions/unbond_farm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ multiversx_sc::imports!();

use contexts::storage_cache::StorageCache;

use crate::{farm_hooks::hook_type::FarmHookType, token_attributes::UnbondSftAttributes};
use crate::{
common::{result_types::UnbondResultType, token_attributes::UnbondSftAttributes},
farm_hooks::hook_type::FarmHookType,
};

#[multiversx_sc::module]
pub trait UnbondFarmModule:
Expand All @@ -29,17 +32,17 @@ pub trait UnbondFarmModule:
+ banned_addresses::BannedAddressModule
+ crate::farm_hooks::change_hooks::ChangeHooksModule
+ crate::farm_hooks::call_hook::CallHookModule
+ crate::unbond_token::UnbondTokenModule
{
// TODO: Fix to actually send the required token parts
#[payable("*")]
#[endpoint(unbondFarm)]
fn unbond_farm(&self) -> EsdtTokenPayment {
fn unbond_farm(&self) -> UnbondResultType<Self::Api> {
let storage_cache = StorageCache::new(self);
self.validate_contract_state(storage_cache.contract_state, &storage_cache.farm_token_id);

let farm_token_mapper = self.farm_token();
let unbond_token_mapper = self.unbond_token();
let payment = self.call_value().single_esdt();
farm_token_mapper.require_same_token(&payment.token_identifier);
unbond_token_mapper.require_same_token(&payment.token_identifier);

let caller = self.blockchain().get_caller();
let payments_after_hook = self.call_hook(
Expand All @@ -50,29 +53,29 @@ pub trait UnbondFarmModule:
);
let payment = payments_after_hook.get(0);

let attributes: UnbondSftAttributes =
farm_token_mapper.get_token_attributes(payment.token_nonce);
let attributes: UnbondSftAttributes<Self::Api> =
unbond_token_mapper.get_token_attributes(payment.token_nonce);

let current_epoch = self.blockchain().get_block_epoch();
require!(
current_epoch >= attributes.unlock_epoch,
"Unbond period not over"
);

farm_token_mapper.nft_burn(payment.token_nonce, &payment.amount);
unbond_token_mapper.nft_burn(payment.token_nonce, &payment.amount);

let farming_tokens =
EsdtTokenPayment::new(storage_cache.farming_token_id.clone(), 0, payment.amount);
let farming_tokens = attributes.farming_token_parts;
let output_payments_after_hook = self.call_hook(
FarmHookType::AfterUnbond,
caller.clone(),
ManagedVec::from_single_item(farming_tokens),
farming_tokens,
ManagedVec::new(),
);
let farming_tokens = output_payments_after_hook.get(0);

self.send_payment_non_zero(&caller, &farming_tokens);
self.send_multiple_tokens_if_not_zero(&caller, &output_payments_after_hook);

farming_tokens
UnbondResultType {
farming_tokens: output_payments_after_hook,
}
}
}
57 changes: 31 additions & 26 deletions farm-staking/farm-staking-nft/src/farm_actions/unstake_farm.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
multiversx_sc::imports!();

use contexts::{exit_farm_context::ExitFarmContext, storage_cache::StorageCache};
use farm_base_impl::exit_farm::InternalExitFarmResult;
use common_structs::PaymentsVec;
use contexts::{
exit_farm_context::ExitFarmContext,
storage_cache::{FarmContracTraitBounds, StorageCache},
};

use crate::{
common::result_types::UnstakeRewardsResultType,
common::token_attributes::{StakingFarmNftTokenAttributes, UnbondSftAttributes},
farm_hooks::hook_type::FarmHookType,
result_types::UnstakeRewardsResultType,
token_attributes::{StakingFarmNftTokenAttributes, UnbondSftAttributes},
};

const NFT_AMOUNT: u32 = 1;

pub struct InternalExitFarmResult<'a, C>
where
C: FarmContracTraitBounds,
{
pub context: ExitFarmContext<C::Api, StakingFarmNftTokenAttributes<C::Api>>,
pub storage_cache: StorageCache<'a, C>,
pub token_parts: PaymentsVec<C::Api>,
pub reward_payment: EsdtTokenPayment<C::Api>,
}

#[multiversx_sc::module]
pub trait UnstakeFarmModule:
crate::custom_rewards::CustomRewardsModule
Expand Down Expand Up @@ -36,7 +51,8 @@ pub trait UnstakeFarmModule:
+ banned_addresses::BannedAddressModule
+ crate::farm_hooks::change_hooks::ChangeHooksModule
+ crate::farm_hooks::call_hook::CallHookModule
+ crate::token_info::TokenInfoModule
+ crate::common::token_info::TokenInfoModule
+ crate::unbond_token::UnbondTokenModule
{
#[payable("*")]
#[endpoint(unstakeFarm)]
Expand All @@ -53,10 +69,7 @@ pub trait UnstakeFarmModule:
let payment = payments_after_hook.get(0);

let mut exit_result = self.exit_farm_base(caller.clone(), payment);

let unbond_token_amount = exit_result.farming_token_payment.amount;
let farm_token_id = exit_result.storage_cache.farm_token_id.clone();
let unbond_farm_token = self.create_unbond_tokens(farm_token_id, unbond_token_amount);
let unbond_farm_token = self.create_unbond_tokens(exit_result.token_parts);

let mut output_payments = ManagedVec::new();
output_payments.push(unbond_farm_token);
Expand Down Expand Up @@ -95,27 +108,25 @@ pub trait UnstakeFarmModule:

fn create_unbond_tokens(
&self,
farm_token_id: TokenIdentifier,
amount: BigUint,
farming_token_parts: PaymentsVec<Self::Api>,
) -> EsdtTokenPayment {
let min_unbond_epochs = self.min_unbond_epochs().get();
let current_epoch = self.blockchain().get_block_epoch();
let nft_nonce = self.send().esdt_nft_create_compact(
&farm_token_id,
&amount,

self.unbond_token().nft_create(
BigUint::from(NFT_AMOUNT),
&UnbondSftAttributes {
unlock_epoch: current_epoch + min_unbond_epochs,
farming_token_parts,
},
);

EsdtTokenPayment::new(farm_token_id, nft_nonce, amount)
)
}

fn exit_farm_base(
&self,
caller: ManagedAddress,
payment: EsdtTokenPayment<Self::Api>,
) -> InternalExitFarmResult<Self, StakingFarmNftTokenAttributes<Self::Api>> {
) -> InternalExitFarmResult<Self> {
let mut storage_cache = StorageCache::new(self);
self.validate_contract_state(storage_cache.contract_state, &storage_cache.farm_token_id);

Expand Down Expand Up @@ -144,12 +155,6 @@ pub trait UnstakeFarmModule:

self.decrease_user_farm_position(&payment);

let farming_token_amount = token_attributes.current_farm_amount;
let farming_token_payment = EsdtTokenPayment::new(
storage_cache.farming_token_id.clone(),
0,
farming_token_amount,
);
let reward_payment =
EsdtTokenPayment::new(storage_cache.reward_token_id.clone(), 0, reward);

Expand All @@ -160,11 +165,11 @@ pub trait UnstakeFarmModule:
&farm_token_payment.amount,
);

storage_cache.farm_token_supply -= &farming_token_payment.amount;
storage_cache.farm_token_supply -= &token_attributes.current_farm_amount;

InternalExitFarmResult {
context: exit_farm_context,
farming_token_payment,
token_parts: token_attributes.farming_token_parts,
reward_payment,
storage_cache,
}
Expand Down
15 changes: 7 additions & 8 deletions farm-staking/farm-staking-nft/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,17 @@
multiversx_sc::imports!();
multiversx_sc::derive_imports!();

use common::result_types::MergeResultType;
use common::token_attributes::PartialStakingFarmNftTokenAttributes;
use contexts::storage_cache::StorageCache;
use result_types::MergeResultType;
use token_attributes::PartialStakingFarmNftTokenAttributes;

use crate::custom_rewards::MAX_MIN_UNBOND_EPOCHS;

pub mod common;
pub mod custom_rewards;
pub mod farm_actions;
pub mod farm_hooks;
pub mod farm_token_roles;
pub mod result_types;
pub mod token_attributes;
pub mod token_info;
pub mod unbond_token;

#[multiversx_sc::contract]
pub trait FarmStaking:
Expand All @@ -37,7 +35,7 @@ pub trait FarmStaking:
+ farm_base_impl::compound_rewards::BaseCompoundRewardsModule
+ farm_base_impl::exit_farm::BaseExitFarmModule
+ utils::UtilsModule
+ farm_token_roles::FarmTokenRolesModule
+ common::farm_token_roles::FarmTokenRolesModule
+ farm_actions::stake_farm::StakeFarmModule
+ farm_actions::claim_stake_farm_rewards::ClaimStakeFarmRewardsModule
+ farm_actions::compound_stake_farm_rewards::CompoundStakeFarmRewardsModule
Expand All @@ -56,7 +54,8 @@ pub trait FarmStaking:
+ banned_addresses::BannedAddressModule
+ farm_hooks::change_hooks::ChangeHooksModule
+ farm_hooks::call_hook::CallHookModule
+ token_info::TokenInfoModule
+ common::token_info::TokenInfoModule
+ unbond_token::UnbondTokenModule
{
#[init]
fn init(
Expand Down
28 changes: 28 additions & 0 deletions farm-staking/farm-staking-nft/src/unbond_token.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
multiversx_sc::imports!();

#[multiversx_sc::module]
pub trait UnbondTokenModule: permissions_module::PermissionsModule {
#[payable("EGLD")]
#[endpoint(registerUnbondToken)]
fn register_unbond_token(
&self,
token_display_name: ManagedBuffer,
token_ticker: ManagedBuffer,
) {
self.require_caller_has_owner_or_admin_permissions();

let payment_amount = self.call_value().egld_value().clone_value();
self.unbond_token().issue_and_set_all_roles(
EsdtTokenType::NonFungible,
payment_amount,
token_display_name,
token_ticker,
0,
None,
);
}

#[view(getUnbondTokenId)]
#[storage_mapper("unbond_token_id")]
fn unbond_token(&self) -> NonFungibleTokenMapper;
}
Loading

0 comments on commit 9527a5c

Please sign in to comment.