Skip to content

Commit

Permalink
temp commit
Browse files Browse the repository at this point in the history
  • Loading branch information
dorin-iancu committed Oct 22, 2024
1 parent 64b63c2 commit 9c57bbf
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 106 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

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

9 changes: 9 additions & 0 deletions energy-integration/farm-boosted-yields/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,12 @@ path = "../common-modules/energy-query"

[dependencies.common-types]
path = "../common-types"

[dependencies.timestamp-oracle]
path = "../timestamp-oracle"

[dependencies.common_structs]
path = "../../common/common_structs"

[dependencies.utils]
path = "../../common/modules/utils"
143 changes: 143 additions & 0 deletions energy-integration/farm-boosted-yields/src/custom_reward_logic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
use common_structs::{Epoch, Nonce, Timestamp};
use timestamp_oracle::epoch_to_timestamp::ProxyTrait as _;
use week_timekeeping::Week;
use weekly_rewards_splitting::USER_MAX_CLAIM_WEEKS;

multiversx_sc::imports!();

pub struct SplitReward<M: ManagedTypeApi> {
pub base_farm: BigUint<M>,
pub boosted_farm: BigUint<M>,
}

impl<M: ManagedTypeApi> SplitReward<M> {
pub fn new(base_farm: BigUint<M>, boosted_farm: BigUint<M>) -> Self {
SplitReward {
base_farm,
boosted_farm,
}
}
}

pub const MAX_PERCENT: u64 = 10_000;

#[multiversx_sc::module]
pub trait CustomRewardLogicModule:
crate::boosted_yields_factors::BoostedYieldsFactorsModule
+ config::ConfigModule
+ week_timekeeping::WeekTimekeepingModule
+ pausable::PausableModule
+ permissions_module::PermissionsModule
+ weekly_rewards_splitting::WeeklyRewardsSplittingModule
+ weekly_rewards_splitting::events::WeeklyRewardsSplittingEventsModule
+ weekly_rewards_splitting::global_info::WeeklyRewardsGlobalInfo
+ weekly_rewards_splitting::locked_token_buckets::WeeklyRewardsLockedTokenBucketsModule
+ weekly_rewards_splitting::update_claim_progress_energy::UpdateClaimProgressEnergyModule
+ energy_query::EnergyQueryModule
+ utils::UtilsModule
{
#[endpoint(setTimestampOracleAddress)]
fn set_timestamp_oracle_address(&self, sc_address: ManagedAddress) {
self.require_caller_has_admin_permissions();

self.timestamp_oracle_address().set(sc_address);
}

#[endpoint(collectUndistributedBoostedRewards)]
fn collect_undistributed_boosted_rewards(&self) {
self.require_caller_has_admin_permissions();

let collect_rewards_offset = USER_MAX_CLAIM_WEEKS + 1usize;
let current_week = self.get_current_week();
require!(
current_week > collect_rewards_offset,
"Current week must be higher than the week offset"
);

let last_collect_week_mapper = self.last_undistributed_boosted_rewards_collect_week();
let first_collect_week = last_collect_week_mapper.get() + 1;
let last_collect_week = current_week - collect_rewards_offset;
if first_collect_week > last_collect_week {
return;
}

for week in first_collect_week..=last_collect_week {
let rewards_to_distribute = self.remaining_boosted_rewards_to_distribute(week).take();
self.undistributed_boosted_rewards()
.update(|total_amount| *total_amount += rewards_to_distribute);
}

last_collect_week_mapper.set(last_collect_week);
}

fn take_reward_slice(&self, full_reward: BigUint) -> SplitReward<Self::Api> {
let percentage = self.boosted_yields_rewards_percentage().get();
if percentage == 0 {
return SplitReward::new(full_reward, BigUint::zero());
}

let boosted_yields_cut = &full_reward * percentage / MAX_PERCENT;
let base_farm_amount = if boosted_yields_cut > 0 {
let current_week = self.get_current_week();
self.accumulated_rewards_for_week(current_week)
.update(|accumulated_rewards| {
*accumulated_rewards += &boosted_yields_cut;
});

&full_reward - &boosted_yields_cut
} else {
full_reward
};

SplitReward::new(base_farm_amount, boosted_yields_cut)
}

fn get_start_of_epoch_timestamp(&self) -> Timestamp {
let timestamp_oracle_addr = self.timestamp_oracle_address().get();
self.timestamp_oracle_proxy_obj(timestamp_oracle_addr)
.update_and_get_timestamp_start_epoch()
.execute_on_dest_context()
}

fn get_custom_epoch_start_timestamp(&self, epoch: Epoch) -> Timestamp {
let timestamp_oracle_addr = self.timestamp_oracle_address().get();
self.timestamp_oracle_proxy_obj(timestamp_oracle_addr)
.get_start_timestamp_for_epoch(epoch)
.execute_on_dest_context()
}

#[proxy]
fn timestamp_oracle_proxy_obj(
&self,
sc_address: ManagedAddress,
) -> timestamp_oracle::Proxy<Self::Api>;

#[storage_mapper("timestampOracleAddress")]
fn timestamp_oracle_address(&self) -> SingleValueMapper<ManagedAddress>;

#[storage_mapper("posEnterTimestamp")]
fn pos_enter_timestamp(&self, pos_nonce: Nonce) -> SingleValueMapper<Timestamp>;

#[view(getBoostedYieldsRewardsPercentage)]
#[storage_mapper("boostedYieldsRewardsPercentage")]
fn boosted_yields_rewards_percentage(&self) -> SingleValueMapper<u64>;

#[view(getAccumulatedRewardsForWeek)]
#[storage_mapper("accumulatedRewardsForWeek")]
fn accumulated_rewards_for_week(&self, week: Week) -> SingleValueMapper<BigUint>;

#[view(getFarmSupplyForWeek)]
#[storage_mapper("farmSupplyForWeek")]
fn farm_supply_for_week(&self, week: Week) -> SingleValueMapper<BigUint>;

#[view(getRemainingBoostedRewardsToDistribute)]
#[storage_mapper("remainingBoostedRewardsToDistribute")]
fn remaining_boosted_rewards_to_distribute(&self, week: Week) -> SingleValueMapper<BigUint>;

#[storage_mapper("lastUndistributedBoostedRewardsCollectWeek")]
fn last_undistributed_boosted_rewards_collect_week(&self) -> SingleValueMapper<Week>;

#[view(getUndistributedBoostedRewards)]
#[storage_mapper("undistributedBoostedRewards")]
fn undistributed_boosted_rewards(&self) -> SingleValueMapper<BigUint>;
}
124 changes: 24 additions & 100 deletions energy-integration/farm-boosted-yields/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,10 @@ use boosted_yields_factors::BoostedYieldsConfig;
use common_types::PaymentsVec;
use multiversx_sc::api::ErrorApi;
use week_timekeeping::Week;
use weekly_rewards_splitting::{
base_impl::WeeklyRewardsSplittingTraitsModule, USER_MAX_CLAIM_WEEKS,
};
use weekly_rewards_splitting::base_impl::WeeklyRewardsSplittingTraitsModule;

pub mod boosted_yields_factors;

const MAX_PERCENT: u64 = 10_000;

pub struct SplitReward<M: ManagedTypeApi> {
pub base_farm: BigUint<M>,
pub boosted_farm: BigUint<M>,
}

impl<M: ManagedTypeApi> SplitReward<M> {
pub fn new(base_farm: BigUint<M>, boosted_farm: BigUint<M>) -> Self {
SplitReward {
base_farm,
boosted_farm,
}
}
}
pub mod custom_reward_logic;

#[multiversx_sc::module]
pub trait FarmBoostedYieldsModule:
Expand All @@ -43,56 +26,9 @@ pub trait FarmBoostedYieldsModule:
+ weekly_rewards_splitting::locked_token_buckets::WeeklyRewardsLockedTokenBucketsModule
+ weekly_rewards_splitting::update_claim_progress_energy::UpdateClaimProgressEnergyModule
+ energy_query::EnergyQueryModule
+ utils::UtilsModule
+ custom_reward_logic::CustomRewardLogicModule
{
#[endpoint(collectUndistributedBoostedRewards)]
fn collect_undistributed_boosted_rewards(&self) {
self.require_caller_has_admin_permissions();

let collect_rewards_offset = USER_MAX_CLAIM_WEEKS + 1usize;
let current_week = self.get_current_week();
require!(
current_week > collect_rewards_offset,
"Current week must be higher than the week offset"
);

let last_collect_week_mapper = self.last_undistributed_boosted_rewards_collect_week();
let first_collect_week = last_collect_week_mapper.get() + 1;
let last_collect_week = current_week - collect_rewards_offset;
if first_collect_week > last_collect_week {
return;
}

for week in first_collect_week..=last_collect_week {
let rewards_to_distribute = self.remaining_boosted_rewards_to_distribute(week).take();
self.undistributed_boosted_rewards()
.update(|total_amount| *total_amount += rewards_to_distribute);
}

last_collect_week_mapper.set(last_collect_week);
}

fn take_reward_slice(&self, full_reward: BigUint) -> SplitReward<Self::Api> {
let percentage = self.boosted_yields_rewards_percentage().get();
if percentage == 0 {
return SplitReward::new(full_reward, BigUint::zero());
}

let boosted_yields_cut = &full_reward * percentage / MAX_PERCENT;
let base_farm_amount = if boosted_yields_cut > 0 {
let current_week = self.get_current_week();
self.accumulated_rewards_for_week(current_week)
.update(|accumulated_rewards| {
*accumulated_rewards += &boosted_yields_cut;
});

&full_reward - &boosted_yields_cut
} else {
full_reward
};

SplitReward::new(base_farm_amount, boosted_yields_cut)
}

fn claim_boosted_yields_rewards(
&self,
user: &ManagedAddress,
Expand Down Expand Up @@ -133,29 +69,6 @@ pub trait FarmBoostedYieldsModule:
);
}
}

#[view(getBoostedYieldsRewardsPercentage)]
#[storage_mapper("boostedYieldsRewardsPercentage")]
fn boosted_yields_rewards_percentage(&self) -> SingleValueMapper<u64>;

#[view(getAccumulatedRewardsForWeek)]
#[storage_mapper("accumulatedRewardsForWeek")]
fn accumulated_rewards_for_week(&self, week: Week) -> SingleValueMapper<BigUint>;

#[view(getFarmSupplyForWeek)]
#[storage_mapper("farmSupplyForWeek")]
fn farm_supply_for_week(&self, week: Week) -> SingleValueMapper<BigUint>;

#[view(getRemainingBoostedRewardsToDistribute)]
#[storage_mapper("remainingBoostedRewardsToDistribute")]
fn remaining_boosted_rewards_to_distribute(&self, week: Week) -> SingleValueMapper<BigUint>;

#[storage_mapper("lastUndistributedBoostedRewardsCollectWeek")]
fn last_undistributed_boosted_rewards_collect_week(&self) -> SingleValueMapper<Week>;

#[view(getUndistributedBoostedRewards)]
#[storage_mapper("undistributedBoostedRewards")]
fn undistributed_boosted_rewards(&self) -> SingleValueMapper<BigUint>;
}

pub struct FarmBoostedYieldsWrapper<T: FarmBoostedYieldsModule> {
Expand Down Expand Up @@ -250,18 +163,29 @@ where
(boosted_rewards_by_energy + boosted_rewards_by_tokens) / constants_base;

// min between base rewards per week and computed rewards
let user_reward = cmp::min(max_rewards, boosted_reward_amount);
if user_reward > 0 {
sc.remaining_boosted_rewards_to_distribute(week)
.update(|amount| *amount -= &user_reward);
let mut user_reward = cmp::min(max_rewards, boosted_reward_amount);

Check warning on line 166 in energy-integration/farm-boosted-yields/src/lib.rs

View workflow job for this annotation

GitHub Actions / Contracts / Test Coverage

variable does not need to be mutable

Check warning on line 166 in energy-integration/farm-boosted-yields/src/lib.rs

View workflow job for this annotation

GitHub Actions / Contracts / Wasm tests

variable does not need to be mutable

Check warning on line 166 in energy-integration/farm-boosted-yields/src/lib.rs

View workflow job for this annotation

GitHub Actions / Contracts / Rust tests

variable does not need to be mutable

Check warning on line 166 in energy-integration/farm-boosted-yields/src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] energy-integration/farm-boosted-yields/src/lib.rs#L166

warning: variable does not need to be mutable --> energy-integration/farm-boosted-yields/src/lib.rs:166:13 | 166 | let mut user_reward = cmp::min(max_rewards, boosted_reward_amount); | ----^^^^^^^^^^^ | | | help: remove this `mut` | = note: `#[warn(unused_mut)]` on by default
Raw output
energy-integration/farm-boosted-yields/src/lib.rs:166:13:w:warning: variable does not need to be mutable
   --> energy-integration/farm-boosted-yields/src/lib.rs:166:13
    |
166 |         let mut user_reward = cmp::min(max_rewards, boosted_reward_amount);
    |             ----^^^^^^^^^^^
    |             |
    |             help: remove this `mut`
    |
    = note: `#[warn(unused_mut)]` on by default


__END__
if user_reward == 0 {
return user_rewards;
}

let current_week = sc.get_current_week(); // TODO: Shouldn't be current week.
if current_week == week {
// do magic

user_rewards.push(EsdtTokenPayment::new(
weekly_reward.token_identifier,
0,
user_reward,
));
if user_reward == 0 {
return user_rewards;
}
}

sc.remaining_boosted_rewards_to_distribute(week)
.update(|amount| *amount -= &user_reward);

user_rewards.push(EsdtTokenPayment::new(
weekly_reward.token_identifier,
0,
user_reward,
));

user_rewards
}
}
36 changes: 31 additions & 5 deletions energy-integration/timestamp-oracle/src/epoch_to_timestamp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,52 @@ multiversx_sc::imports!();

#[multiversx_sc::module]
pub trait EpochToTimestampModule {
#[only_owner]
#[endpoint(setStartTimestampForEpoch)]
fn set_start_timestamp_for_epoch(&self, epoch: Epoch, start_timestamp: Timestamp) {
let mapper = self.timestamp_for_epoch(epoch);
require!(
mapper.is_empty(),
"Overwriting timestamp. If you're sure about this, use the overwriteStartTimestampForEpoch endpoint"
);

mapper.set(start_timestamp);
}

#[only_owner]
#[endpoint(overwriteStartTimestampForEpoch)]
fn overwrite_start_timestamp_for_epoch(&self, epoch: Epoch, start_timestamp: Timestamp) {
self.timestamp_for_epoch(epoch).set(start_timestamp);
}

#[endpoint(updateAndGetTimestampStartEpoch)]
fn update_and_get_timestamp_start_epoch(&self) -> Timestamp {
let current_epoch = self.blockchain().get_block_epoch();
let last_update_epoch = self.epoch_last_interaction().get();
let mapper = self.timestamp_for_epoch(current_epoch);
if current_epoch == last_update_epoch {
return self.timestamp_start_epoch_last_interaction().get();
return mapper.get();
}

self.epoch_last_interaction().set(current_epoch);

let current_timestamp = self.blockchain().get_block_timestamp();
self.timestamp_start_epoch_last_interaction()
.set(current_timestamp);
mapper.set(current_timestamp);

current_timestamp
}

#[view(getStartTimestampForEpoch)]
fn get_start_timestamp_for_epoch(&self, epoch: Epoch) -> Timestamp {
let mapper = self.timestamp_for_epoch(epoch);
require!(!mapper.is_empty(), "No timestamp available");

mapper.get()
}

#[storage_mapper("epochLastInteraction")]
fn epoch_last_interaction(&self) -> SingleValueMapper<Epoch>;

#[storage_mapper("timestampStartEpochLastInter")]
fn timestamp_start_epoch_last_interaction(&self) -> SingleValueMapper<Timestamp>;
#[storage_mapper("timestampForEpoch")]
fn timestamp_for_epoch(&self, epoch: Epoch) -> SingleValueMapper<Timestamp>;
}
2 changes: 1 addition & 1 deletion energy-integration/timestamp-oracle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub trait TimestampOracle: epoch_to_timestamp::EpochToTimestampModule {
fn init(&self, current_epoch_start_timestamp: Timestamp) {
let current_epoch = self.blockchain().get_block_epoch();
self.epoch_last_interaction().set(current_epoch);
self.timestamp_start_epoch_last_interaction()
self.timestamp_for_epoch(current_epoch)
.set(current_epoch_start_timestamp);
}

Expand Down

0 comments on commit 9c57bbf

Please sign in to comment.