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 tests with original caller merge fix #875

Merged
merged 4 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading