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

allow setting first week epoch in farm #835

Merged
merged 6 commits into from
Feb 22, 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
47 changes: 23 additions & 24 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions common/modules/farm/farm_base_impl/src/base_farm_init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ pub trait BaseFarmInitModule:

self.state().set(State::Inactive);
self.division_safety_constant()
.set_if_empty(&division_safety_constant);
.set(&division_safety_constant);

self.reward_token_id().set_if_empty(&reward_token_id);
self.farming_token_id().set_if_empty(&farming_token_id);
self.reward_token_id().set(&reward_token_id);
self.farming_token_id().set(&farming_token_id);

if !owner.is_zero() {
self.add_permissions(owner, Permissions::OWNER | Permissions::PAUSE);
Expand Down
48 changes: 24 additions & 24 deletions common/modules/farm/farm_base_impl/src/base_traits_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,34 +63,35 @@ pub trait FarmContract {
) -> BigUint<<Self::FarmSc as ContractBase>::Api> {
let current_block_nonce = sc.blockchain().get_block_nonce();
let last_reward_nonce = sc.last_reward_block_nonce().get();
if current_block_nonce > last_reward_nonce {
let to_mint =
Self::calculate_per_block_rewards(sc, current_block_nonce, last_reward_nonce);
if to_mint != 0 {
Self::mint_rewards(sc, token_id, &to_mint);
}

sc.last_reward_block_nonce().set(current_block_nonce);
if current_block_nonce <= last_reward_nonce {
return BigUint::zero();
}

to_mint
} else {
BigUint::zero()
let to_mint = Self::calculate_per_block_rewards(sc, current_block_nonce, last_reward_nonce);
if to_mint != 0 {
Self::mint_rewards(sc, token_id, &to_mint);
}

sc.last_reward_block_nonce().set(current_block_nonce);

to_mint
}

fn generate_aggregated_rewards(
sc: &Self::FarmSc,
storage_cache: &mut StorageCache<Self::FarmSc>,
) {
let total_reward = Self::mint_per_block_rewards(sc, &storage_cache.reward_token_id);
if total_reward > 0u64 {
storage_cache.reward_reserve += &total_reward;
if total_reward == 0u64 {
return;
}

if storage_cache.farm_token_supply != 0u64 {
let increase = (&total_reward * &storage_cache.division_safety_constant)
/ &storage_cache.farm_token_supply;
storage_cache.reward_per_share += &increase;
}
storage_cache.reward_reserve += &total_reward;

if storage_cache.farm_token_supply != 0u64 {
let increase = (&total_reward * &storage_cache.division_safety_constant)
/ &storage_cache.farm_token_supply;
storage_cache.reward_per_share += &increase;
}
}

Expand All @@ -102,12 +103,12 @@ pub trait FarmContract {
storage_cache: &StorageCache<Self::FarmSc>,
) -> BigUint<<Self::FarmSc as ContractBase>::Api> {
let token_rps = token_attributes.get_reward_per_share();
if storage_cache.reward_per_share > token_rps {
let rps_diff = &storage_cache.reward_per_share - &token_rps;
farm_token_amount * &rps_diff / &storage_cache.division_safety_constant
} else {
BigUint::zero()
if storage_cache.reward_per_share <= token_rps {
return BigUint::zero();
}

let rps_diff = &storage_cache.reward_per_share - &token_rps;
farm_token_amount * &rps_diff / &storage_cache.division_safety_constant
}

fn create_enter_farm_initial_attributes(
Expand Down Expand Up @@ -212,7 +213,6 @@ pub trait FarmContract {
}
}

#[inline]
fn increase_user_farm_position(
sc: &Self::FarmSc,
user: &ManagedAddress<<Self::FarmSc as ContractBase>::Api>,
Expand Down
61 changes: 38 additions & 23 deletions 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 week_timekeeping::Epoch;

use farm::{
base_functions::{BaseFunctionsModule, ClaimRewardsResultType, DoubleMultiPayment, Wrapper},
Expand Down Expand Up @@ -57,6 +58,7 @@ pub trait Farm:
division_safety_constant: BigUint,
pair_contract_address: ManagedAddress,
owner: ManagedAddress,
first_week_start_epoch: Epoch,
admins: MultiValueEncoded<ManagedAddress>,
) {
self.base_farm_init(
Expand All @@ -67,18 +69,18 @@ pub trait Farm:
admins,
);

self.penalty_percent().set_if_empty(DEFAULT_PENALTY_PERCENT);
self.minimum_farming_epochs()
.set_if_empty(DEFAULT_MINUMUM_FARMING_EPOCHS);
self.burn_gas_limit().set_if_empty(DEFAULT_BURN_GAS_LIMIT);
self.pair_contract_address().set(&pair_contract_address);

let current_epoch = self.blockchain().get_block_epoch();
self.first_week_start_epoch().set_if_empty(current_epoch);
require!(
first_week_start_epoch >= current_epoch,
"Invalid start epoch"
);
self.first_week_start_epoch().set(first_week_start_epoch);

// Farm position migration code
let farm_token_mapper = self.farm_token();
self.try_set_farm_position_migration_nonce(farm_token_mapper);
self.penalty_percent().set(DEFAULT_PENALTY_PERCENT);
self.minimum_farming_epochs()
.set(DEFAULT_MINUMUM_FARMING_EPOCHS);
self.burn_gas_limit().set(DEFAULT_BURN_GAS_LIMIT);
self.pair_contract_address().set(&pair_contract_address);
}

#[endpoint]
Expand Down Expand Up @@ -120,6 +122,13 @@ pub trait Farm:
&self,
opt_orig_caller: OptionalValue<ManagedAddress>,
) -> ClaimRewardsResultType<Self::Api> {
let current_epoch = self.blockchain().get_block_epoch();
let first_week_start_epoch = self.first_week_start_epoch().get();
require!(
first_week_start_epoch <= current_epoch,
"Cannot claim rewards yet"
);

let caller = self.blockchain().get_caller();
let orig_caller = self.get_orig_caller_from_opt(&caller, opt_orig_caller);

Expand Down Expand Up @@ -209,10 +218,14 @@ pub trait Farm:
}

#[endpoint(claimBoostedRewards)]
fn claim_boosted_rewards(
&self,
opt_user: OptionalValue<ManagedAddress>,
) -> EsdtTokenPayment<Self::Api> {
fn claim_boosted_rewards(&self, opt_user: OptionalValue<ManagedAddress>) -> EsdtTokenPayment {
let current_epoch = self.blockchain().get_block_epoch();
let first_week_start_epoch = self.first_week_start_epoch().get();
require!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the extra check in place? We already have the check when computing the actual rewards. Maybe we accept that until the first_week_start_epoch is reached, we don't fail the endpoint, and just return 0. Then, after we pass that particular epoch, we avoid the 2 extra reads.

first_week_start_epoch <= current_epoch,
"Cannot claim rewards yet"
);

let caller = self.blockchain().get_caller();
let user = match &opt_user {
OptionalValue::Some(user) => user,
Expand Down Expand Up @@ -313,15 +326,17 @@ where
storage_cache: &mut StorageCache<Self::FarmSc>,
) {
let total_reward = Self::mint_per_block_rewards(sc, &storage_cache.reward_token_id);
if total_reward > 0u64 {
storage_cache.reward_reserve += &total_reward;
let split_rewards = sc.take_reward_slice(total_reward);

if storage_cache.farm_token_supply != 0u64 {
let increase = (&split_rewards.base_farm * &storage_cache.division_safety_constant)
/ &storage_cache.farm_token_supply;
storage_cache.reward_per_share += &increase;
}
if total_reward == 0u64 {
return;
}

storage_cache.reward_reserve += &total_reward;
let split_rewards = sc.take_reward_slice(total_reward);

if storage_cache.farm_token_supply != 0u64 {
let increase = (&split_rewards.base_farm * &storage_cache.division_safety_constant)
/ &storage_cache.farm_token_supply;
storage_cache.reward_per_share += &increase;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ where
division_safety_constant,
pair_address,
managed_address!(&owner),
0,
MultiValueEncoded::new(),
);

Expand Down
32 changes: 23 additions & 9 deletions dex/farm/src/base_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,12 @@ where
sc: &<Self as FarmContract>::FarmSc,
caller: &ManagedAddress<<<Self as FarmContract>::FarmSc as ContractBase>::Api>,
) -> BigUint<<<Self as FarmContract>::FarmSc as ContractBase>::Api> {
let current_epoch = sc.blockchain().get_block_epoch();
let first_week_start_epoch = sc.first_week_start_epoch().get();
if first_week_start_epoch > current_epoch {
return BigUint::zero();
}

let user_total_farm_position = sc.get_user_total_farm_position(caller);
let user_farm_position = user_total_farm_position.total_farm_position;

Expand All @@ -304,15 +310,17 @@ where
storage_cache: &mut StorageCache<Self::FarmSc>,
) {
let total_reward = Self::mint_per_block_rewards(sc, &storage_cache.reward_token_id);
if total_reward > 0u64 {
storage_cache.reward_reserve += &total_reward;
let split_rewards = sc.take_reward_slice(total_reward);

if storage_cache.farm_token_supply != 0u64 {
let increase = (&split_rewards.base_farm * &storage_cache.division_safety_constant)
/ &storage_cache.farm_token_supply;
storage_cache.reward_per_share += &increase;
}
if total_reward == 0u64 {
return;
}

storage_cache.reward_reserve += &total_reward;
let split_rewards = sc.take_reward_slice(total_reward);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a check in the startProduceRewards endpoint, to not allow the rewards to start generating, if current_epoch < first_week_start_epoch. This way, we avoid getting to the point where we may call an endpoint (like enterFarm) that calls the take_reward_slice function, which then would throw a SC error.


if storage_cache.farm_token_supply != 0u64 {
let increase = (&split_rewards.base_farm * &storage_cache.division_safety_constant)
/ &storage_cache.farm_token_supply;
storage_cache.reward_per_share += &increase;
}
}

Expand All @@ -323,6 +331,12 @@ where
token_attributes: &Self::AttributesType,
storage_cache: &StorageCache<Self::FarmSc>,
) -> BigUint<<Self::FarmSc as ContractBase>::Api> {
let current_epoch = sc.blockchain().get_block_epoch();
let first_week_start_epoch = sc.first_week_start_epoch().get();
if first_week_start_epoch > current_epoch {
return BigUint::zero();
}

let base_farm_reward = DefaultFarmWrapper::<T>::calculate_rewards(
sc,
caller,
Expand Down
Loading
Loading