diff --git a/pallets/spp/src/lib.rs b/pallets/spp/src/lib.rs index bedd0b5f..863e3f7c 100644 --- a/pallets/spp/src/lib.rs +++ b/pallets/spp/src/lib.rs @@ -698,6 +698,8 @@ pub mod pallet { unlock_duration: Option<(FungibleTokenId, StakingRound)>, iteration_limit: Option, network_fee: Option<(FungibleTokenId, BalanceOf)>, + reward_per_era: Option>, + current_staking_round: Option<(FungibleTokenId, StakingRound)>, ) -> DispatchResult { T::GovernanceOrigin::ensure_origin(origin)?; @@ -711,11 +713,11 @@ pub mod pallet { let current_relay_chain_block = >::block_number(); // let current_relay_chain_block = T::RelayChainBlockNumber::current_block_number(); if !update_era_frequency.is_zero() { - // ensure!( - // change > current_relay_chain_block.saturating_sub(update_era_frequency) - // && change <= current_relay_chain_block, - // Error::::InvalidLastEraUpdatedBlock - // ); + ensure!( + change > current_relay_chain_block.saturating_sub(update_era_frequency) + && change <= current_relay_chain_block, + Error::::InvalidLastEraUpdatedBlock + ); LastEraUpdatedBlock::::put(change); LastStakingRound::::insert(FungibleTokenId::NativeToken(1), last_staking_round); @@ -749,6 +751,14 @@ pub mod pallet { Self::deposit_event(Event::::NetworkFeeUpdated { currency_id, new_fee }); } + if let Some(reward_p_era) = reward_per_era { + RewardEraFrequency::::put(reward_p_era); + } + + if let Some((currency, current_staking_round)) = current_staking_round { + CurrentStakingRound::::insert(currency, current_staking_round); + } + Ok(()) } @@ -789,9 +799,7 @@ pub mod pallet { .1 .add(total_balance.clone()) .ok_or(Error::::ArithmeticOverflow)?; - voting - .prior - .accumulate(unlock_at, votes[i].1.balance.saturating_add(total_balance)) + voting.prior.accumulate(unlock_at, total_balance) } Err(i) => { votes.insert(i, (pool_id, vote.clone())); @@ -1258,6 +1266,9 @@ impl Pallet { RelayChainCurrentEra::::put(new_era); // LastEraUpdatedBlock::::put(T::RelayChainBlockNumber::current_block_number()); LastEraUpdatedBlock::::put(>::block_number()); + + CurrentStakingRound::::insert(FungibleTokenId::NativeToken(1), StakingRound::Era(new_era)); + Self::handle_redeem_requests(new_era)?; Self::handle_reward_distribution_to_network_pool()?; Self::handle_reward_distribution_to_pool_treasury(previous_era, new_era)?; @@ -1282,7 +1293,7 @@ impl Pallet { } fn do_claim_rewards(who: T::AccountId, pool_id: PoolId) -> DispatchResult { - if pool_id.is_zero() { + if !pool_id.is_zero() { >::claim_rewards(&who, &pool_id); PendingRewards::::mutate_exists(pool_id, &who, |maybe_pending_multi_rewards| { diff --git a/pallets/spp/src/tests.rs b/pallets/spp/src/tests.rs index e1afb21b..031ac1c1 100644 --- a/pallets/spp/src/tests.rs +++ b/pallets/spp/src/tests.rs @@ -48,7 +48,6 @@ fn create_ksm_pool_works() { .ksm_setup_for_alice_and_bob() .build() .execute_with(|| { - // Create the first pool assert_ok!(SppModule::create_pool( RuntimeOrigin::signed(ALICE), @@ -77,7 +76,7 @@ fn create_ksm_pool_works() { RuntimeOrigin::signed(BOB), FungibleTokenId::NativeToken(1), 10, - Permill::from_percent(1) + Rate::saturating_from_rational(1, 100), )); // Check Id will increment @@ -88,7 +87,7 @@ fn create_ksm_pool_works() { Pool::::get(next_pool_id - 1).unwrap(), PoolInfo:: { creator: BOB, - commission: Permill::from_percent(1), + commission: Rate::saturating_from_rational(1, 100), currency_id: FungibleTokenId::NativeToken(1), max: 10 } @@ -236,7 +235,8 @@ fn current_era_update_works() { assert_eq!(SppModule::update_era_frequency(), 0); assert_eq!(MockRelayBlockNumberProvider::current_block_number(), 0); // Current relaychain block is 102. - MockRelayBlockNumberProvider::set(102); + // MockRelayBlockNumberProvider::set(102); + run_to_block(102); RelayChainCurrentEra::::put(1); IterationLimit::::put(50); // The correct set up era config is the last era block records is 101 with duration is 100 blocks @@ -245,7 +245,12 @@ fn current_era_update_works() { Some(101), Some(100), StakingRound::Era(1), - Some(Rate::saturating_from_rational(35, 100000)) + Some(Rate::saturating_from_rational(35, 100000)), + Some((FungibleTokenId::NativeToken(1), StakingRound::Era(1))), + Some(50), + Some((FungibleTokenId::NativeToken(1), 0)), + Some(100), + Some((FungibleTokenId::NativeToken(1), StakingRound::Era(1))) )); assert_ok!(SppModule::create_pool( @@ -440,12 +445,12 @@ fn boosting_works() { assert_eq!(NetworkLedger::::get(FungibleTokenId::NativeToken(1)), 20000); // Boosting works - let bob_free_balance = Balances::free_balance(BOB); + let bob_boost_balance = 1000; assert_ok!(SppModule::boost( RuntimeOrigin::signed(BOB), 1, BoostInfo { - balance: bob_free_balance, + balance: bob_boost_balance, conviction: BoostingConviction::None } )); @@ -454,18 +459,65 @@ fn boosting_works() { votes: vec![( 1, BoostInfo { - balance: bob_free_balance, + balance: bob_boost_balance, conviction: BoostingConviction::None, }, )], - prior: PriorLock(1, bob_free_balance), + prior: PriorLock(1, bob_boost_balance), }; assert_eq!(boosting_of, some_record); - assert_eq!(Balances::usable_balance(&BOB), 0); + assert_eq!(Balances::usable_balance(&BOB), 99000); let pool_1_shared_rewards = RewardsModule::shares_and_withdrawn_rewards(1, BOB); let network_shared_rewards = RewardsModule::shares_and_withdrawn_rewards(0, BOB); - assert_eq!(pool_1_shared_rewards, (bob_free_balance, Default::default())); - assert_eq!(network_shared_rewards, (bob_free_balance, Default::default())); + assert_eq!(pool_1_shared_rewards, (bob_boost_balance, Default::default())); + assert_eq!(network_shared_rewards, (bob_boost_balance, Default::default())); + + // Second boost that will make total lock 11000 + assert_ok!(SppModule::boost( + RuntimeOrigin::signed(BOB), + 1, + BoostInfo { + balance: 10000, + conviction: BoostingConviction::None + } + )); + let second_boosting_of = BoostingOf::::get(BOB); + let second_boosting_record = BoostingRecord { + votes: vec![( + 1, + BoostInfo { + balance: 11000, + conviction: BoostingConviction::None, + }, + )], + prior: PriorLock(1, 11000), + }; + let view_votes = &second_boosting_of.votes; + let debug_votes = &second_boosting_of.votes[0]; + assert_eq!(second_boosting_of, second_boosting_record); + + // Third boosting with lower balance than previous boost + assert_ok!(SppModule::boost( + RuntimeOrigin::signed(BOB), + 1, + BoostInfo { + balance: 500, + conviction: BoostingConviction::None + } + )); + let third_boosting_of = BoostingOf::::get(BOB); + let third_boosting_record = BoostingRecord { + votes: vec![( + 1, + BoostInfo { + balance: 11500, + conviction: BoostingConviction::None, + }, + )], + prior: PriorLock(1, 11500), + }; + + assert_eq!(third_boosting_of, third_boosting_record); }); } @@ -477,7 +529,8 @@ fn boosting_and_claim_reward_works() { .execute_with(|| { // Era config set up // Current relaychain block is 102. - MockRelayBlockNumberProvider::set(102); + // MockRelayBlockNumberProvider::set(102); + run_to_block(102); RelayChainCurrentEra::::put(1); IterationLimit::::put(50); // The correct set up era config is the last era block records is 101 with duration is 100 blocks @@ -486,7 +539,12 @@ fn boosting_and_claim_reward_works() { Some(101), Some(100), StakingRound::Era(1), - Some(Rate::saturating_from_rational(35, 100000)) + Some(Rate::saturating_from_rational(35, 100000)), + Some((FungibleTokenId::NativeToken(1), StakingRound::Era(1))), + Some(50), + Some((FungibleTokenId::NativeToken(1), 0)), + Some(100), + Some((FungibleTokenId::NativeToken(1), StakingRound::Era(1))) )); assert_ok!(SppModule::create_pool( @@ -679,7 +737,8 @@ fn reward_distribution_works() { .execute_with(|| { // Era config set up // Current relaychain block is 102. - MockRelayBlockNumberProvider::set(102); + // MockRelayBlockNumberProvider::set(102); + run_to_block(102); RelayChainCurrentEra::::put(1); IterationLimit::::put(50); UnlockDuration::::insert(FungibleTokenId::NativeToken(1), StakingRound::Era(1)); // Bump current staking round to 1 @@ -690,7 +749,12 @@ fn reward_distribution_works() { Some(101), Some(100), StakingRound::Era(1), - Some(Rate::saturating_from_rational(20, 100)) // Set reward rate per era is 20%. + Some(Rate::saturating_from_rational(20, 100)), // Set reward rate per era is 20%. + Some((FungibleTokenId::NativeToken(1), StakingRound::Era(1))), + Some(50), + Some((FungibleTokenId::NativeToken(1), 0)), + Some(100), + Some((FungibleTokenId::NativeToken(1), StakingRound::Era(1))) )); assert_ok!(SppModule::create_pool( diff --git a/pallets/spp/src/utils.rs b/pallets/spp/src/utils.rs index f5c70a68..90202be9 100644 --- a/pallets/spp/src/utils.rs +++ b/pallets/spp/src/utils.rs @@ -156,7 +156,7 @@ impl BoostInfo { } pub fn add(&mut self, balance: Balance) -> Option<()> { - self.balance.saturating_add(balance.into()); + self.balance = self.balance.saturating_add(balance.into()); Some(()) } } @@ -169,7 +169,7 @@ impl PriorLock Balance { diff --git a/runtime/metaverse/src/lib.rs b/runtime/metaverse/src/lib.rs index a0b61b2f..a7cb33bf 100644 --- a/runtime/metaverse/src/lib.rs +++ b/runtime/metaverse/src/lib.rs @@ -182,7 +182,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 98, + spec_version: 99, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1,