From d47369d71da30f7cea4da796fdde45987562035a Mon Sep 17 00:00:00 2001 From: Akagi201 Date: Mon, 4 Jul 2022 10:32:00 +0800 Subject: [PATCH] fix: fix zero pending amount --- pallets/system-staking/src/benchmarking.rs | 40 +++++--- pallets/system-staking/src/lib.rs | 55 +++++++---- pallets/system-staking/src/tests.rs | 110 +++++++++++++++++++++ pallets/system-staking/src/weights.rs | 5 + 4 files changed, 176 insertions(+), 34 deletions(-) diff --git a/pallets/system-staking/src/benchmarking.rs b/pallets/system-staking/src/benchmarking.rs index 9a4d2a1e3..e3c62c6bf 100644 --- a/pallets/system-staking/src/benchmarking.rs +++ b/pallets/system-staking/src/benchmarking.rs @@ -18,34 +18,46 @@ #![cfg(feature = "runtime-benchmarks")] -use frame_benchmarking::{benchmarks, whitelisted_caller}; +use frame_benchmarking::{benchmarks, vec, whitelisted_caller}; +use frame_support::sp_runtime::{Perbill, Permill}; use frame_system::RawOrigin; -use node_primitives::{CurrencyId, TokenSymbol}; -use sp_arithmetic::per_things::Permill; +use node_primitives::{CurrencyId, PoolId, TokenSymbol}; use frame_support::{sp_runtime::traits::UniqueSaturatedFrom, traits::OnInitialize}; use crate::{Pallet as SystemStaking, *}; benchmarks! { - on_initialize {}:{SystemStaking::::on_initialize(T::BlockNumber::from(101u32));} + on_initialize {}:{SystemStaking::::on_initialize(T::BlockNumber::from(101u32));} - token_config { + token_config { const KSM: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); - let token_amount = BalanceOf::::unique_saturated_from(1000u128); - }: _(RawOrigin::Root, KSM, Some(1), Some(Permill::from_percent(80)),Some(false),Some(token_amount),None,None) + let token_amount = BalanceOf::::unique_saturated_from(1000u128); + let pool_id = PoolId::from(1u32); + }: _(RawOrigin::Root, KSM, Some(1), Some(Permill::from_percent(80)),Some(false),Some(token_amount),Some(vec![pool_id]),Some(vec![Perbill::from_percent(100)])) - refresh_token_info { + refresh_token_info { const KSM: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); }: _(RawOrigin::Root,KSM) - payout { + payout { const KSM: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); }: _(RawOrigin::Root,KSM) - on_redeem_success { - const KSM: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); - let caller: T::AccountId = whitelisted_caller(); - let token_amount = BalanceOf::::unique_saturated_from(1000u128); - }:{SystemStaking::::on_redeem_success(KSM,caller,token_amount);} + on_redeem_success { + const KSM: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); + let caller: T::AccountId = whitelisted_caller(); + let token_amount = BalanceOf::::unique_saturated_from(1000u128); + }:{SystemStaking::::on_redeem_success(KSM,caller,token_amount);} + + on_redeemed { + const KSM: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); + let caller: T::AccountId = whitelisted_caller(); + let token_amount = BalanceOf::::unique_saturated_from(1000u128); + let fee_amount = BalanceOf::::unique_saturated_from(1000u128); + }:{SystemStaking::::on_redeemed(caller,KSM,token_amount,token_amount,fee_amount);} + + delete_token { + const KSM: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); + }: _(RawOrigin::Root,KSM) } diff --git a/pallets/system-staking/src/lib.rs b/pallets/system-staking/src/lib.rs index 5a7ac69bf..054b97857 100644 --- a/pallets/system-staking/src/lib.rs +++ b/pallets/system-staking/src/lib.rs @@ -55,9 +55,11 @@ pub type BalanceOf = pub mod pallet { use super::*; use crate::{RoundInfo, TokenInfo}; - use frame_support::pallet_prelude::*; + use frame_support::{ + pallet_prelude::*, + sp_runtime::{Perbill, Permill}, + }; use frame_system::pallet_prelude::*; - use sp_arithmetic::{Perbill, Permill}; pub type RoundIndex = u32; @@ -180,14 +182,6 @@ pub mod pallet { system_shadow_amount: BalanceOf, pending_redeem_amount: BalanceOf, }, - RedeemSuccess { - token: CurrencyIdOf, - amount: BalanceOf, - farming_staking_amount: BalanceOf, - system_stakable_amount: BalanceOf, - system_shadow_amount: BalanceOf, - pending_redeem_amount: BalanceOf, - }, Redeemed { token: CurrencyIdOf, amount: BalanceOf, @@ -366,6 +360,23 @@ pub mod pallet { Ok(().into()) } + /// token config,take effect when next round begins + #[pallet::weight(::WeightInfo::delete_token())] + pub fn delete_token( + origin: OriginFor, + token: CurrencyIdOf, + ) -> DispatchResultWithPostInfo { + T::EnsureConfirmAsGovernance::ensure_origin(origin)?; // Motion + + >::remove(&token); + + let mut token_list = Self::token_list(); + token_list.retain(|&x| x != token); + >::put(token_list); + + Ok(().into()) + } + /// refresh token info,query farming pallet, and update TokenInfo, change to new /// config,ignore exec_delay, execute immediately #[pallet::weight(::WeightInfo::refresh_token_info())] @@ -468,6 +479,10 @@ impl Pallet { .saturating_sub(token_info.current_config.system_stakable_base) }; token_info.system_stakable_amount = stakable_amount; + + // write state before other calls + >::insert(&token_id, token_info.clone()); + if stakable_amount > token_info.system_shadow_amount.saturating_sub(token_info.pending_redeem_amount) { @@ -478,6 +493,8 @@ impl Pallet { Ok(_) => match T::VtokenMintingInterface::mint(account.clone(), token_id, mint_amount) { Ok(_) => { + token_info.system_shadow_amount = + token_info.system_shadow_amount.saturating_add(mint_amount); Self::deposit_event(Event::MintSuccess { token: token_id, amount: mint_amount, @@ -486,8 +503,6 @@ impl Pallet { system_shadow_amount: token_info.system_shadow_amount, pending_redeem_amount: token_info.pending_redeem_amount, }); - token_info.system_shadow_amount = - token_info.system_shadow_amount.saturating_add(mint_amount); }, Err(error) => { Self::deposit_event(Event::MintFailed { @@ -556,14 +571,14 @@ impl Pallet { match T::VtokenMintingInterface::redeem(account, vtoken_id, vredeem_amount) { Ok(_) => { - Self::deposit_event(Event::RedeemSuccess { - token: token_id, - amount: vredeem_amount, - farming_staking_amount: token_info.farming_staking_amount, - system_stakable_amount: token_info.system_stakable_amount, - system_shadow_amount: token_info.system_shadow_amount, - pending_redeem_amount: token_info.pending_redeem_amount, - }); + let new_token_info = + if let Some(state) = >::get(&token_id) { + state + } else { + >>::default() + }; + token_info.pending_redeem_amount = + new_token_info.pending_redeem_amount; }, Err(error) => { Self::deposit_event(Event::RedeemFailed { diff --git a/pallets/system-staking/src/tests.rs b/pallets/system-staking/src/tests.rs index ccf961aa3..3477be6d8 100644 --- a/pallets/system-staking/src/tests.rs +++ b/pallets/system-staking/src/tests.rs @@ -22,6 +22,8 @@ use frame_support::{ assert_ok, sp_runtime::{Perbill, Permill}, }; +use node_primitives::{TimeUnit, VtokenMintingOperator}; +use sp_std::{collections::btree_map::BTreeMap, prelude::*}; #[test] fn token_config_should_work() { @@ -46,6 +48,53 @@ fn token_config_should_work() { }); } +#[test] +fn delete_token_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + assert_ok!(SystemStaking::token_config( + Origin::root(), + KSM, + Some(1), + Some(Permill::from_percent(80)), + Some(false), + Some(100), + None, + None, + )); + + assert_ok!(SystemStaking::token_config( + Origin::root(), + MOVR, + Some(2), + Some(Permill::from_percent(80)), + Some(false), + Some(100), + None, + None, + )); + + assert_ok!(SystemStaking::token_config( + Origin::root(), + MOVR, + Some(2), + Some(Permill::from_percent(80)), + Some(false), + Some(100), + None, + None, + )); + + assert_ok!(SystemStaking::delete_token(Origin::root(), MOVR,)); + + assert!(>::get(MOVR).is_none()); + assert!(>::get(KSM).is_some()); + let token_list = >::get(); + assert_eq!(token_list.len(), 1); + assert!(!token_list.clone().into_inner().contains(&MOVR)); + assert!(token_list.into_inner().contains(&KSM)); + }); +} + #[test] fn round_info_should_correct() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { @@ -66,3 +115,64 @@ fn round_info_should_correct() { assert_eq!(SystemStaking::round().unwrap().first, 1001); }); } + +#[test] +fn refresh_token_info_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let (pid, _tokens) = init_farming_no_gauge(); + + assert_ok!(VtokenMinting::set_minimum_mint(Origin::signed(ALICE), KSM, 10)); + pub const FEE: Permill = Permill::from_percent(5); + assert_ok!(VtokenMinting::set_fees(Origin::root(), FEE, FEE)); + assert_ok!(VtokenMinting::set_unlock_duration( + Origin::signed(ALICE), + KSM, + TimeUnit::Era(1) + )); + assert_ok!(VtokenMinting::increase_token_pool(KSM, 1000)); + assert_ok!(VtokenMinting::update_ongoing_time_unit(KSM, TimeUnit::Era(1))); + assert_ok!(VtokenMinting::set_minimum_redeem(Origin::signed(ALICE), vKSM, 10)); + + assert_ok!(SystemStaking::token_config( + Origin::root(), + KSM, + Some(1), + Some(Permill::from_percent(80)), + Some(false), + Some(100), + Some(vec![pid]), + Some(vec![Perbill::from_percent(100)]), + )); + + assert_ok!(SystemStaking::refresh_token_info(Origin::root(), KSM)); + let token_info = >::get(KSM).unwrap(); + assert_eq!(token_info.new_config, token_info.current_config); + }); +} + +fn init_farming_no_gauge() -> (PoolId, BalanceOf) { + let mut tokens_proportion_map = BTreeMap::, Perbill>::new(); + tokens_proportion_map.entry(KSM).or_insert(Perbill::from_percent(100)); + let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; + let tokens = 1000; + let basic_rewards = vec![(KSM, 1000)]; + let gauge_basic_rewards = vec![(KSM, 1000)]; + + assert_ok!(Farming::create_farming_pool( + Origin::signed(ALICE), + tokens_proportion.clone(), + basic_rewards.clone(), + Some((KSM, 1000, gauge_basic_rewards)), + 0, + 0, + 10, + 0, + 1 + )); + + let pid = 0; + let charge_rewards = vec![(KSM, 100000)]; + assert_ok!(Farming::charge(Origin::signed(BOB), pid, charge_rewards)); + assert_ok!(Farming::deposit(Origin::signed(ALICE), pid, tokens.clone(), None)); + (pid, tokens) +} diff --git a/pallets/system-staking/src/weights.rs b/pallets/system-staking/src/weights.rs index 782e48658..a4774ab44 100644 --- a/pallets/system-staking/src/weights.rs +++ b/pallets/system-staking/src/weights.rs @@ -29,6 +29,7 @@ use sp_std::marker::PhantomData; pub trait WeightInfo { fn on_initialize(x: u32) -> Weight; fn token_config() -> Weight; + fn delete_token() -> Weight; fn refresh_token_info() -> Weight; fn payout() -> Weight; fn on_redeem_success() -> Weight; @@ -46,6 +47,10 @@ impl WeightInfo for SubstrateWeight { (50_000_000 as Weight) } + fn delete_token() -> Weight { + (50_000_000 as Weight) + } + fn refresh_token_info() -> Weight { (100_000_000 as Weight) }