Skip to content

Commit

Permalink
More types test
Browse files Browse the repository at this point in the history
  • Loading branch information
Dinonard committed Oct 9, 2023
1 parent f17772f commit 8baf64b
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 18 deletions.
108 changes: 98 additions & 10 deletions pallets/dapp-staking-v3/src/test/tests_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1363,20 +1363,43 @@ fn contract_stake_info_is_ok() {
);

// 3rd scenario - reduce some of the staked amount from both periods and verify it's as expected.
// For the voting period, we want to unstake it completly, and then some more.
let reduction = vote_stake_amount_1 + 2;
contract_stake_info.unstake(reduction, PeriodType::Voting);
contract_stake_info.unstake(reduction, PeriodType::BuildAndEarn);
let total_staked = contract_stake_info.total_staked_amount();
let vp_reduction = 3;
contract_stake_info.unstake(vp_reduction, PeriodType::Voting);
assert_eq!(
contract_stake_info.total_staked_amount(),
bep_stake_amount_1 - reduction
total_staked - vp_reduction
);
assert_eq!(
contract_stake_info.staked_amount(PeriodType::Voting),
vote_stake_amount_1 - vp_reduction
);

let bp_reduction = 7;
contract_stake_info.unstake(bp_reduction, PeriodType::BuildAndEarn);
assert_eq!(
contract_stake_info.total_staked_amount(),
total_staked - vp_reduction - bp_reduction
);
assert_eq!(
contract_stake_info.staked_amount(PeriodType::BuildAndEarn),
bep_stake_amount_1 - bp_reduction
);

// 4th scenario - unstake everyhting, and some more, from Build&Earn period, chiping away from the voting period.
let overflow = 1;
let overflow_reduction = contract_stake_info.staked_amount(PeriodType::BuildAndEarn) + overflow;
contract_stake_info.unstake(overflow_reduction, PeriodType::BuildAndEarn);
assert_eq!(
contract_stake_info.total_staked_amount(),
vote_stake_amount_1 - vp_reduction - overflow
);
assert!(contract_stake_info
.staked_amount(PeriodType::Voting)
.staked_amount(PeriodType::BuildAndEarn)
.is_zero());
assert_eq!(
contract_stake_info.staked_amount(PeriodType::BuildAndEarn),
bep_stake_amount_1 - reduction
contract_stake_info.staked_amount(PeriodType::Voting),
vote_stake_amount_1 - vp_reduction - overflow
);
}

Expand Down Expand Up @@ -1535,8 +1558,73 @@ fn contract_staking_info_series_stake_with_inconsistent_data_fails() {

#[test]
fn contract_staking_info_series_unstake_is_ok() {
// let mut series = ContractStakingInfoSeries::default();
// TODO
let mut series = ContractStakingInfoSeries::default();

// Prep action - create a stake entry
let era_1 = 2;
let period = 3;
let period_info = PeriodInfo::new(period, PeriodType::Voting, 20);
let stake_amount = 100;
assert!(series.stake(stake_amount, period_info, era_1).is_ok());

// 1st scenario - unstake in the same era
let amount_1 = 5;
assert!(series.unstake(amount_1, period_info, era_1).is_ok());
assert_eq!(series.len(), 1);
assert_eq!(series.total_staked_amount(period), stake_amount - amount_1);
assert_eq!(
series.staked_amount(period, PeriodType::Voting),
stake_amount - amount_1
);

// 2nd scenario - unstake in the future era, creating a 'gap' in the series
// [(era: 2)] ---> [(era: 2), (era: 5)]
let period_info = PeriodInfo::new(period, PeriodType::BuildAndEarn, 40);
let era_2 = era_1 + 3;
let amount_2 = 7;
assert!(series.unstake(amount_2, period_info, era_2).is_ok());
assert_eq!(series.len(), 2);
assert_eq!(
series.total_staked_amount(period),
stake_amount - amount_1 - amount_2
);
assert_eq!(
series.staked_amount(period, PeriodType::Voting),
stake_amount - amount_1 - amount_2
);

// 3rd scenario - unstake in the era right before the last, inserting the new value in-between the old ones
// [(era: 2), (era: 5)] ---> [(era: 2), (era: 4), (era: 5)]
let era_3 = era_2 - 1;
let amount_3 = 11;
assert!(series.unstake(amount_3, period_info, era_3).is_ok());
assert_eq!(series.len(), 3);
assert_eq!(
series.total_staked_amount(period),
stake_amount - amount_1 - amount_2 - amount_3
);
assert_eq!(
series.staked_amount(period, PeriodType::Voting),
stake_amount - amount_1 - amount_2 - amount_3
);

// Check concrete entries
assert_eq!(
series.get(era_1, period).unwrap().total_staked_amount(),
stake_amount - amount_1,
"Oldest entry must remain unchanged."
);
assert_eq!(
series.get(era_2, period).unwrap().total_staked_amount(),
stake_amount - amount_1 - amount_2 - amount_3,
"Future era entry must be updated with all of the reductions."
);
assert_eq!(
series.get(era_3, period).unwrap().total_staked_amount(),
stake_amount - amount_1 - amount_3,
"Second to last era entry must be updated with first & last reduction\
because it derives its initial value from the oldest entry."
);
}

#[test]
Expand Down
24 changes: 16 additions & 8 deletions pallets/dapp-staking-v3/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,8 @@ pub struct RewardInfo {
pub dapps: Balance,
}

// TODO: it would be nice to implement add/subtract logic on this struct and use it everywhere
// we need to keep track of staking amount for periods. Right now I have logic duplication which is not good.
#[derive(Encode, Decode, MaxEncodedLen, Copy, Clone, Debug, PartialEq, Eq, TypeInfo, Default)]
pub struct StakeAmount {
/// Amount of staked funds accounting for the voting period.
Expand Down Expand Up @@ -1000,7 +1002,11 @@ impl ContractStakingInfo {
pub fn unstake(&mut self, amount: Balance, period_type: PeriodType) {
match period_type {
PeriodType::Voting => self.vp_staked_amount.saturating_reduce(amount),
PeriodType::BuildAndEarn => self.bep_staked_amount.saturating_reduce(amount),
PeriodType::BuildAndEarn => {
let overflow = amount.saturating_sub(self.bep_staked_amount);
self.bep_staked_amount.saturating_reduce(amount);
self.vp_staked_amount.saturating_reduce(overflow);
}
}
}

Expand Down Expand Up @@ -1175,13 +1181,14 @@ impl ContractStakingInfoSeries {

// 1st step - remove the last element IFF it's for the next era.
// Unstake the requested amount from it.
let last_era_info = if let Some(last_element) = self.0.last() {
let mut last_element = *last_element;
last_element.unstake(amount, period_info.period_type);
self.0.remove(self.0.len() - 1);
Some(last_element)
} else {
None
let last_era_info = match self.0.last() {
Some(last_element) if last_element.era() == era.saturating_add(1) => {
let mut last_element = *last_element;
last_element.unstake(amount, period_info.period_type);
self.0.remove(self.0.len() - 1);
Some(last_element)
}
_ => None,
};

// 2nd step - 3 options:
Expand All @@ -1195,6 +1202,7 @@ impl ContractStakingInfoSeries {
} else if last_element.period() == period_info.number {
let mut new_entry = *last_element;
new_entry.unstake(amount, period_info.period_type);
new_entry.era = era;
Some(new_entry)
} else {
None
Expand Down

0 comments on commit 8baf64b

Please sign in to comment.