Skip to content

Commit

Permalink
Merge pull request #875 from multiversx/farm-tests-with-original-call…
Browse files Browse the repository at this point in the history
…er-merge-fix

Farm tests with original caller merge fix
  • Loading branch information
psorinionut authored Apr 12, 2024
2 parents 3fb4c2d + 4aaa01f commit 154b56a
Show file tree
Hide file tree
Showing 6 changed files with 548 additions and 32 deletions.
4 changes: 2 additions & 2 deletions common/common_structs/src/farm_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ impl<M: ManagedTypeApi> FixedSupplyToken<M> for FarmTokenAttributes<M> {

impl<M: ManagedTypeApi> Mergeable<M> for FarmTokenAttributes<M> {
#[inline]
fn can_merge_with(&self, other: &Self) -> bool {
self.original_owner == other.original_owner
fn can_merge_with(&self, _other: &Self) -> bool {
true
}

fn merge_with(&mut self, other: Self) {
Expand Down
9 changes: 8 additions & 1 deletion dex/farm-with-locked-rewards/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ multiversx_sc::derive_imports!();
use common_structs::FarmTokenAttributes;
use contexts::storage_cache::StorageCache;
use core::marker::PhantomData;
use fixed_supply_token::FixedSupplyToken;

use farm::{
base_functions::{BaseFunctionsModule, ClaimRewardsResultType, DoubleMultiPayment, Wrapper},
Expand Down Expand Up @@ -198,7 +199,13 @@ pub trait Farm:
self.migrate_old_farm_positions(&orig_caller);
let boosted_rewards = self.claim_only_boosted_payment(&orig_caller);

let merged_farm_token = self.merge_farm_tokens::<NoMintWrapper<Self>>();
let mut output_attributes = self.merge_and_return_attributes::<NoMintWrapper<Self>>();
output_attributes.original_owner = orig_caller.clone();

let new_token_amount = output_attributes.get_total_supply();
let merged_farm_token = self
.farm_token()
.nft_create(new_token_amount, &output_attributes);

self.send_payment_non_zero(&caller, &merged_farm_token);
let locked_rewards_payment = self.send_to_lock_contract_non_zero(
Expand Down
8 changes: 2 additions & 6 deletions dex/farm/src/base_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use common_structs::FarmTokenAttributes;
use contexts::storage_cache::StorageCache;

use farm_base_impl::base_traits_impl::{DefaultFarmWrapper, FarmContract};
use fixed_supply_token::FixedSupplyToken;

use crate::{exit_penalty, MAX_PERCENT};

Expand Down Expand Up @@ -183,18 +182,15 @@ pub trait BaseFunctionsModule:
}
}

fn merge_farm_tokens<FC: FarmContract<FarmSc = Self>>(&self) -> EsdtTokenPayment<Self::Api> {
fn merge_and_return_attributes<FC: FarmContract<FarmSc = Self>>(&self) -> FC::AttributesType {
let payments = self.get_non_empty_payments();
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();
token_mapper.nft_create(new_token_amount, &output_attributes)
self.merge_from_payments_and_burn(payments, &token_mapper)
}

fn claim_only_boosted_payment(&self, caller: &ManagedAddress) -> BigUint {
Expand Down
10 changes: 9 additions & 1 deletion dex/farm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use exit_penalty::{
DEFAULT_BURN_GAS_LIMIT, DEFAULT_MINUMUM_FARMING_EPOCHS, DEFAULT_PENALTY_PERCENT,
};
use farm_base_impl::base_traits_impl::FarmContract;
use fixed_supply_token::FixedSupplyToken;

pub type EnterFarmResultType<M> = DoubleMultiPayment<M>;
pub type ExitFarmWithPartialPosResultType<M> = DoubleMultiPayment<M>;
Expand Down Expand Up @@ -195,7 +196,14 @@ pub trait Farm:
let boosted_rewards_payment =
EsdtTokenPayment::new(self.reward_token_id().get(), 0, boosted_rewards);

let merged_farm_token = self.merge_farm_tokens::<Wrapper<Self>>();
let mut output_attributes = self.merge_and_return_attributes::<Wrapper<Self>>();
output_attributes.original_owner = orig_caller;

let new_token_amount = output_attributes.get_total_supply();
let merged_farm_token = self
.farm_token()
.nft_create(new_token_amount, &output_attributes);

self.send_payment_non_zero(&caller, &merged_farm_token);
self.send_payment_non_zero(&caller, &boosted_rewards_payment);

Expand Down
171 changes: 150 additions & 21 deletions dex/farm/tests/farm_setup/multi_user_farm_setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub static FARM_TOKEN_ID: &[u8] = b"FARM-123456";
pub const DIV_SAFETY: u64 = 1_000_000_000_000;
pub const PER_BLOCK_REWARD_AMOUNT: u64 = 1_000;
pub const FARMING_TOKEN_BALANCE: u64 = 200_000_000;
pub const MAX_PERCENTAGE: u64 = 10_000; // 100%
pub const BOOSTED_YIELDS_PERCENTAGE: u64 = 2_500; // 25%
pub const MAX_REWARDS_FACTOR: u64 = 10;
pub const USER_REWARDS_ENERGY_CONST: u64 = 3;
Expand All @@ -48,6 +49,11 @@ pub struct RawFarmTokenAttributes {
pub original_owner_bytes: [u8; 32],
}

pub struct NonceAmountPair {
pub nonce: u64,
pub amount: u64,
}

pub struct MultiUserFarmSetup<FarmObjBuilder, EnergyFactoryBuilder, EnergyUpdateObjBuilder>
where
FarmObjBuilder: 'static + Copy + Fn() -> farm::ContractObj<DebugApi>,
Expand Down Expand Up @@ -310,28 +316,18 @@ where
result
}

pub fn merge_farm_tokens(
&mut self,
user: &Address,
first_token_nonce: u64,
first_token_amount: u64,
second_token_nonce: u64,
second_token_amount: u64,
) {
pub fn merge_farm_tokens(&mut self, user: &Address, farm_tokens: Vec<NonceAmountPair>) {
self.last_farm_token_nonce += 1;
let expected_farm_token_nonce = self.last_farm_token_nonce;
let expected_farm_token_amount = first_token_amount + second_token_amount;
let mut expected_farm_token_amount = 0;
let mut payments = Vec::new();
payments.push(TxTokenTransfer {
token_identifier: FARM_TOKEN_ID.to_vec(),
nonce: first_token_nonce,
value: rust_biguint!(first_token_amount),
});
payments.push(TxTokenTransfer {
token_identifier: FARM_TOKEN_ID.to_vec(),
nonce: second_token_nonce,
value: rust_biguint!(second_token_amount),
});
for farm_token in farm_tokens {
expected_farm_token_amount += farm_token.amount;
payments.push(TxTokenTransfer {
token_identifier: FARM_TOKEN_ID.to_vec(),
nonce: farm_token.nonce,
value: rust_biguint!(farm_token.amount),
});
}

self.b_mock
.execute_esdt_multi_transfer(user, &self.farm_wrapper, &payments, |sc| {
Expand All @@ -342,7 +338,7 @@ where
out_farm_token.token_identifier,
managed_token_id!(FARM_TOKEN_ID)
);
assert_eq!(out_farm_token.token_nonce, expected_farm_token_nonce);
assert_eq!(out_farm_token.token_nonce, self.last_farm_token_nonce);
assert_eq!(
out_farm_token.amount,
managed_biguint!(expected_farm_token_amount)
Expand Down Expand Up @@ -451,6 +447,54 @@ where
result
}

pub fn claim_rewards_with_multiple_payments(
&mut self,
user: &Address,
farm_token_payments: Vec<NonceAmountPair>,
) -> u64 {
self.last_farm_token_nonce += 1;

let mut expected_farm_token_amount = 0;
let mut payments = vec![];

for farm_token_payment in farm_token_payments {
expected_farm_token_amount += farm_token_payment.amount;
payments.push(TxTokenTransfer {
token_identifier: FARM_TOKEN_ID.to_vec(),
nonce: farm_token_payment.nonce,
value: rust_biguint!(farm_token_payment.amount),
});
}

let expected_farm_token_nonce = self.last_farm_token_nonce;
let mut result = 0;
self.b_mock
.execute_esdt_multi_transfer(user, &self.farm_wrapper, &payments, |sc| {
let (out_farm_token, out_reward_token) =
sc.claim_rewards_endpoint(OptionalValue::None).into_tuple();
assert_eq!(
out_farm_token.token_identifier,
managed_token_id!(FARM_TOKEN_ID)
);
assert_eq!(out_farm_token.token_nonce, expected_farm_token_nonce);
assert_eq!(
out_farm_token.amount,
managed_biguint!(expected_farm_token_amount)
);

assert_eq!(
out_reward_token.token_identifier,
managed_token_id!(REWARD_TOKEN_ID)
);
assert_eq!(out_reward_token.token_nonce, 0);

result = out_reward_token.amount.to_u64().unwrap();
})
.assert_ok();

result
}

pub fn claim_boosted_rewards_for_user(&mut self, owner: &Address, broker: &Address) -> u64 {
self.last_farm_token_nonce += 1;

Expand Down Expand Up @@ -691,4 +735,89 @@ where
})
.assert_ok();
}

// With the current checks, works only on full position sent (amount/nonce)
pub fn send_farm_position(
&mut self,
sender: &Address,
receiver: &Address,
nonce: u64,
amount: u64,
attr_reward_per_share: u64,
attr_entering_epoch: u64,
) {
self.b_mock.check_nft_balance(
sender,
FARM_TOKEN_ID,
nonce,
&rust_biguint!(amount),
Some(&FarmTokenAttributes::<DebugApi> {
reward_per_share: managed_biguint!(attr_reward_per_share),
entering_epoch: attr_entering_epoch,
compounded_reward: managed_biguint!(0),
current_farm_amount: managed_biguint!(amount),
original_owner: managed_address!(&sender),
}),
);

self.b_mock
.check_nft_balance::<FarmTokenAttributes<DebugApi>>(
receiver,
FARM_TOKEN_ID,
nonce,
&rust_biguint!(0),
None,
);

self.b_mock.set_nft_balance(
sender,
FARM_TOKEN_ID,
nonce,
&rust_biguint!(0),
&FarmTokenAttributes::<DebugApi> {
reward_per_share: managed_biguint!(attr_reward_per_share),
entering_epoch: attr_entering_epoch,
compounded_reward: managed_biguint!(0),
current_farm_amount: managed_biguint!(amount),
original_owner: managed_address!(&sender),
},
);

self.b_mock.set_nft_balance(
receiver,
FARM_TOKEN_ID,
nonce,
&rust_biguint!(amount),
&FarmTokenAttributes::<DebugApi> {
reward_per_share: managed_biguint!(attr_reward_per_share),
entering_epoch: attr_entering_epoch,
compounded_reward: managed_biguint!(0),
current_farm_amount: managed_biguint!(amount),
original_owner: managed_address!(&sender),
},
);

self.b_mock
.check_nft_balance::<FarmTokenAttributes<DebugApi>>(
sender,
FARM_TOKEN_ID,
nonce,
&rust_biguint!(0),
None,
);

self.b_mock.check_nft_balance(
receiver,
FARM_TOKEN_ID,
nonce,
&rust_biguint!(amount),
Some(&FarmTokenAttributes::<DebugApi> {
reward_per_share: managed_biguint!(attr_reward_per_share),
entering_epoch: attr_entering_epoch,
compounded_reward: managed_biguint!(0),
current_farm_amount: managed_biguint!(amount),
original_owner: managed_address!(&sender),
}),
);
}
}
Loading

0 comments on commit 154b56a

Please sign in to comment.