Skip to content

Commit

Permalink
Merge branch 'rc/v3.0.1' into contract-state-validation-updated-logic
Browse files Browse the repository at this point in the history
  • Loading branch information
psorinionut authored Oct 2, 2024
2 parents 2322419 + 10f1652 commit 58ebca9
Show file tree
Hide file tree
Showing 9 changed files with 334 additions and 16 deletions.
5 changes: 5 additions & 0 deletions dex/farm-with-locked-rewards/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ pub trait Farm:
);
}

require!(
!self.user_total_farm_position(user).is_empty(),
"User total farm position is empty!"
);

let mut storage_cache = StorageCache::new(self);
self.validate_contract_state(storage_cache.contract_state, &storage_cache.farm_token_id);
NoMintWrapper::<Self>::generate_aggregated_rewards(self, &mut storage_cache);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#![allow(deprecated)]

use common_structs::FarmTokenAttributes;
use multiversx_sc::codec::Empty;
use farm_with_locked_rewards::Farm;
use multiversx_sc::{codec::Empty, imports::OptionalValue};
use multiversx_sc_scenario::{managed_address, managed_biguint, rust_biguint, DebugApi};
use simple_lock::locked_token::LockedTokenAttributes;

Expand Down Expand Up @@ -503,11 +504,19 @@ fn claim_boosted_rewards_with_zero_position_test() {
farm_setup.b_mock.set_block_nonce(20);
farm_setup.b_mock.set_block_epoch(13);

let second_week_received_reward_amt =
farm_setup.claim_boosted_rewards_for_user(&temp_user, &temp_user, 0);
farm_setup
.b_mock
.execute_tx(
&temp_user,
&farm_setup.farm_wrapper,
&rust_biguint!(0),
|sc| {
sc.claim_boosted_rewards(OptionalValue::Some(managed_address!(&temp_user)));
},
)
.assert_error(4, "User total farm position is empty!");

assert_eq!(second_week_received_reward_amt, 0);
farm_setup.check_farm_rps(150_000_000u64);
farm_setup.check_farm_rps(75_000_000u64);

// advance 1 week
let boosted_rewards = 2_500;
Expand All @@ -517,14 +526,52 @@ fn claim_boosted_rewards_with_zero_position_test() {
let third_week_received_reward_amt =
farm_setup.claim_boosted_rewards_for_user(&first_user, &first_user, 1);

assert_eq!(third_week_received_reward_amt, boosted_rewards * 2); // user receives rewards for weeks 1 and 2)
assert_eq!(third_week_received_reward_amt, boosted_rewards);
farm_setup.check_farm_rps(225_000_000u64);

farm_setup.b_mock.check_nft_balance::<Empty>(
&first_user,
LOCKED_REWARD_TOKEN_ID,
1,
&rust_biguint!(boosted_rewards * 2),
&rust_biguint!(boosted_rewards),
None,
);
}

#[test]
fn claim_boosted_rewards_user_energy_not_registered_test() {
DebugApi::dummy();
let mut farm_setup = FarmSetup::new(
farm_with_locked_rewards::contract_obj,
energy_factory::contract_obj,
);

farm_setup.set_boosted_yields_rewards_percentage(BOOSTED_YIELDS_PERCENTAGE);
farm_setup.set_boosted_yields_factors();
farm_setup.b_mock.set_block_epoch(2);

let first_user = farm_setup.first_user.clone();
let farm_in_amount = 100_000_000;

farm_setup.set_user_energy(&first_user, 1_000, 2, 1);

// Attempt to claim boosted rewards without entering the farm
farm_setup
.b_mock
.execute_tx(
&first_user,
&farm_setup.farm_wrapper,
&rust_biguint!(0),
|sc| {
sc.claim_boosted_rewards(OptionalValue::Some(managed_address!(&first_user)));
},
)
.assert_error(4, "User total farm position is empty!");

// User enters the farm
farm_setup.enter_farm(&first_user, farm_in_amount);

// Now the user should be able to claim boosted rewards
// Rewards computation is out of scope
farm_setup.claim_boosted_rewards_for_user(&first_user, &first_user, 0);
}
5 changes: 5 additions & 0 deletions dex/farm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ pub trait Farm:
);
}

require!(
!self.user_total_farm_position(user).is_empty(),
"User total farm position is empty!"
);

let mut storage_cache = StorageCache::new(self);
self.validate_contract_state(storage_cache.contract_state, &storage_cache.farm_token_id);
Wrapper::<Self>::generate_aggregated_rewards(self, &mut storage_cache);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ pub trait ClaimOnlyBoostedStakingRewardsModule:
);
}

require!(
!self.user_total_farm_position(user).is_empty(),
"User total farm position is empty!"
);

let mut storage_cache = StorageCache::new(self);
self.validate_contract_state(storage_cache.contract_state, &storage_cache.farm_token_id);
FarmStakingWrapper::<Self>::generate_aggregated_rewards(self, &mut storage_cache);
Expand Down
23 changes: 17 additions & 6 deletions farm-staking/farm-staking/tests/farm_staking_energy_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pub mod farm_staking_setup;
use config::ConfigModule;
use farm_staking::{
claim_only_boosted_staking_rewards::ClaimOnlyBoostedStakingRewardsModule,
claim_stake_farm_rewards::ClaimStakeFarmRewardsModule,
stake_farm::StakeFarmModule,
token_attributes::{StakingFarmTokenAttributes, UnbondSftAttributes},
Expand Down Expand Up @@ -1667,9 +1668,19 @@ fn claim_boosted_rewards_with_zero_position_test() {
fs_setup.b_mock.set_block_epoch(13);

let boosted_rewards_for_week = 100;
fs_setup.claim_boosted_rewards_for_user(&second_user, &second_user, 0, &rust_biguint!(0));

current_farm_rps += farm_rps_increase;
fs_setup
.b_mock
.execute_tx(
&second_user,
&fs_setup.farm_wrapper,
&rust_biguint!(0u64),
|sc| {
sc.claim_boosted_rewards(OptionalValue::Some(managed_address!(&second_user)));
},
)
.assert_error(4, "User total farm position is empty!");

fs_setup.check_farm_rps(current_farm_rps);

// advance 1 week
Expand All @@ -1679,16 +1690,16 @@ fn claim_boosted_rewards_with_zero_position_test() {
fs_setup.claim_boosted_rewards_for_user(
&first_user,
&first_user,
boosted_rewards_for_week * 2,
&rust_biguint!(boosted_rewards_for_week * 2),
boosted_rewards_for_week,
&rust_biguint!(boosted_rewards_for_week),
);

current_farm_rps += farm_rps_increase;
current_farm_rps += farm_rps_increase * 2;
fs_setup.check_farm_rps(current_farm_rps);
fs_setup.b_mock.check_esdt_balance(
&first_user,
REWARD_TOKEN_ID,
&rust_biguint!(boosted_rewards_for_week * 2),
&rust_biguint!(boosted_rewards_for_week),
);

let expected_attributes = StakingFarmTokenAttributes::<DebugApi> {
Expand Down
29 changes: 29 additions & 0 deletions locked-asset/energy-factory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,4 +230,33 @@ pub trait SimpleLockEnergy:

output_tokens
}

#[only_owner]
#[endpoint(adjustUserEnergy)]
fn adjust_user_energy(
&self,
args: MultiValueEncoded<MultiValue3<ManagedAddress, BigInt, BigInt>>,
) {
for arg in args {
let (user, energy_amount, token_amount) = arg.into_tuple();
require!(!self.user_energy(&user).is_empty(), "User energy not found");
let old_energy = self.get_updated_energy_entry_for_user(&user);
let new_energy_amount = old_energy.get_energy_amount_raw() + &energy_amount;
let new_total_locked_tokens = if token_amount >= 0 {
old_energy.get_total_locked_tokens() + &token_amount.magnitude()
} else {
let token_amount_magnitude = token_amount.magnitude();
require!(
old_energy.get_total_locked_tokens() >= &token_amount_magnitude,
"Insufficient locked tokens"
);
old_energy.get_total_locked_tokens() - &token_amount_magnitude
};

let current_epoch = self.blockchain().get_block_epoch();
let new_energy = Energy::new(new_energy_amount, current_epoch, new_total_locked_tokens);

self.set_energy_entry(&user, new_energy);
}
}
}
55 changes: 54 additions & 1 deletion locked-asset/energy-factory/tests/energy_factory_setup/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use energy_factory::{
use multiversx_sc::{
codec::multi_types::OptionalValue,
storage::mappers::StorageTokenWrapper,
types::{Address, EsdtLocalRole, MultiValueEncoded},
types::{Address, BigInt, EsdtLocalRole, MultiValueEncoded},
};
use multiversx_sc_modules::pause::PauseModule;
use multiversx_sc_scenario::{
Expand All @@ -19,6 +19,8 @@ use multiversx_sc_scenario::{
whitebox_legacy::{BlockchainStateWrapper, ContractObjWrapper},
DebugApi,
};

use num_bigint::Sign;
use simple_lock::locked_token::LockedTokenModule;

use unbond_sc_mock::*;
Expand Down Expand Up @@ -272,6 +274,47 @@ where

result
}

pub fn get_user_energy_raw(&mut self, user: &Address) -> num_bigint::BigInt {
let mut result = num_bigint::BigInt::from_biguint(Sign::NoSign, rust_biguint!(0));
self.b_mock
.execute_query(&self.sc_wrapper, |sc| {
let user_energy = sc.get_updated_energy_entry_for_user(&managed_address!(user));
result = to_rust_bigint(user_energy.get_energy_amount_raw().clone());
})
.assert_ok();

result
}

pub fn get_user_locked_tokens(&mut self, user: &Address) -> num_bigint::BigUint {
let mut result = rust_biguint!(0);
self.b_mock
.execute_query(&self.sc_wrapper, |sc| {
let user_energy = sc.get_updated_energy_entry_for_user(&managed_address!(user));
result = to_rust_biguint(user_energy.get_total_locked_tokens().clone());
})
.assert_ok();

result
}

pub fn adjust_user_energy(&mut self, user: &Address, energy_amount: i64, token_amount: i64) {
self.b_mock
.execute_tx(&self.owner, &self.sc_wrapper, &rust_biguint!(0), |sc| {
let mut args = MultiValueEncoded::new();
args.push(
(
managed_address!(user),
BigInt::from(energy_amount),
BigInt::from(token_amount),
)
.into(),
);
sc.adjust_user_energy(args);
})
.assert_ok();
}
}

pub fn to_rust_biguint(
Expand All @@ -280,6 +323,16 @@ pub fn to_rust_biguint(
num_bigint::BigUint::from_bytes_be(managed_biguint.to_bytes_be().as_slice())
}

pub fn to_rust_bigint(
managed_biguint: multiversx_sc::types::BigInt<DebugApi>,
) -> num_bigint::BigInt {
if managed_biguint < 0 {
num_bigint::BigInt::from_biguint(Sign::Minus, to_rust_biguint(managed_biguint.magnitude()))
} else {
num_bigint::BigInt::from_biguint(Sign::Plus, to_rust_biguint(managed_biguint.magnitude()))
}
}

pub fn to_start_of_month(unlock_epoch: u64) -> u64 {
unlock_epoch - unlock_epoch % 30
}
Loading

0 comments on commit 58ebca9

Please sign in to comment.