diff --git a/pallets/farming/src/boost.rs b/pallets/farming/src/boost.rs index 50ada6193..4d85616ac 100644 --- a/pallets/farming/src/boost.rs +++ b/pallets/farming/src/boost.rs @@ -103,12 +103,12 @@ impl Pallet { ensure!(BoostWhitelist::::iter_keys().count() != 0, Error::::WhitelistEmpty); } - Self::send_boost_rewards(&boost_pool_info)?; let current_block_number: BlockNumberFor = frame_system::Pallet::::block_number(); boost_pool_info.start_round = current_block_number; - boost_pool_info.round_length = round_length; boost_pool_info.end_round = current_block_number.saturating_add(round_length); boost_pool_info.total_votes = Zero::zero(); + boost_pool_info.round_length = round_length; + Self::send_boost_rewards(&boost_pool_info)?; BoostPoolInfos::::set(boost_pool_info); let _ = BoostVotingPools::::clear(u32::max_value(), None); Self::deposit_event(Event::RoundStart { round_length }); diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index 84fbac7f3..b31125d1f 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -1010,6 +1010,11 @@ pub mod pallet { T::ControlOrigin::ensure_origin(origin)?; whitelist.iter().for_each(|pid| { BoostWhitelist::::insert(pid, ()); + BoostVotingPools::::mutate_exists(pid, |maybe_total_votes| { + if maybe_total_votes.is_none() { + *maybe_total_votes = Some(Zero::zero()); + } + }) }); Ok(()) } diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index 3afbc3987..f9eefcb4d 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -426,3 +426,170 @@ fn create_farming_pool() { assert_eq!(Tokens::free_balance(KSM, &ALICE), 3800); }) } + +#[test] +fn add_boost_pool_whitelist() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let mut whitelist = vec![0]; + assert_ok!(Farming::add_boost_pool_whitelist( + RuntimeOrigin::signed(ALICE), + whitelist.clone() + )); + assert_eq!(BoostWhitelist::::iter().count(), 1); + whitelist.push(1); + assert_ok!(Farming::add_boost_pool_whitelist( + RuntimeOrigin::signed(ALICE), + whitelist.clone() + )); + assert_eq!(BoostWhitelist::::iter().count(), 2); + assert_err!( + Farming::add_boost_pool_whitelist(RuntimeOrigin::signed(BOB), whitelist.clone()), + DispatchError::BadOrigin + ); + }) +} + +#[test] +fn set_next_round_whitelist() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let mut whitelist = vec![0]; + assert_ok!(Farming::set_next_round_whitelist( + RuntimeOrigin::signed(ALICE), + whitelist.clone() + )); + assert_eq!(BoostNextRoundWhitelist::::iter().count(), 1); + whitelist.push(1); + assert_ok!(Farming::set_next_round_whitelist( + RuntimeOrigin::signed(ALICE), + whitelist.clone() + )); + assert_eq!(BoostNextRoundWhitelist::::iter().count(), 2); + assert_err!( + Farming::set_next_round_whitelist(RuntimeOrigin::signed(BOB), whitelist.clone()), + DispatchError::BadOrigin + ); + }) +} + +#[test] +fn start_boost_round() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let vote_list = vec![(0u32, Percent::from_percent(100))]; + let whitelist = vec![0]; + assert_ok!(Farming::set_next_round_whitelist( + RuntimeOrigin::signed(ALICE), + whitelist.clone() + )); + assert_ok!(Farming::add_boost_pool_whitelist( + RuntimeOrigin::signed(ALICE), + whitelist.clone() + )); + assert_ok!(Farming::vote(RuntimeOrigin::signed(ALICE), vote_list.clone())); + assert_ok!(Farming::vote(RuntimeOrigin::signed(BOB), vote_list.clone())); + assert_ok!(Farming::vote(RuntimeOrigin::signed(CHARLIE), vote_list.clone())); + assert_ok!(Farming::start_boost_round(RuntimeOrigin::signed(ALICE), 100)); + assert_eq!(BoostVotingPools::::iter().count(), 0); + assert_eq!(UserBoostInfos::::iter().count(), 3); + assert_eq!(BoostWhitelist::::iter().count(), 1); + assert_eq!(BoostNextRoundWhitelist::::iter().count(), 0); + }) +} + +#[test] +fn vote() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + env_logger::try_init().unwrap_or(()); + + BbBNC::set_incentive(0, Some(7 * 86400 / 12), Some(ALICE.clone())); + + let (pid, _tokens) = init_gauge(); + let vote_list = vec![(pid, Percent::from_percent(100))]; + let whitelist = vec![pid]; + assert_ok!(Farming::set_next_round_whitelist( + RuntimeOrigin::signed(ALICE), + whitelist.clone() + )); + assert_ok!(Farming::add_boost_pool_whitelist( + RuntimeOrigin::signed(ALICE), + whitelist.clone() + )); + + let charge_rewards = vec![(KSM, 300_000)]; + assert_ok!(Farming::charge_boost(RuntimeOrigin::signed(CHARLIE), charge_rewards)); + assert_eq!(BoostVotingPools::::iter().count(), 1); + assert_ok!(Farming::start_boost_round(RuntimeOrigin::signed(ALICE), 100)); + let boost_pool_info = + BoostPoolInfo { total_votes: 0, end_round: 100, start_round: 0, round_length: 100 }; + assert_eq!(BoostPoolInfos::::get(), boost_pool_info); + + assert_ok!(Farming::vote(RuntimeOrigin::signed(ALICE), vote_list.clone())); + assert_ok!(Farming::vote(RuntimeOrigin::signed(BOB), vote_list.clone())); + assert_ok!(Farming::vote(RuntimeOrigin::signed(CHARLIE), vote_list.clone())); + assert_eq!(BoostVotingPools::::iter().count(), 1); + assert_eq!(UserBoostInfos::::iter().count(), 3); + + assert_eq!(UserBoostInfos::::get(ALICE).unwrap().vote_amount, 99716198400); + let boost_pool_info = BoostPoolInfo { + total_votes: 99716198400, + end_round: 100, + start_round: 0, + round_length: 100, + }; + assert_eq!(BoostPoolInfos::::get(), boost_pool_info); + assert_ok!(BbBNC::create_lock_inner( + &CHARLIE, + 100_000_000_000, + (365 * 86400 - 7 * 86400) / 12 + )); + assert_eq!(BoostPoolInfos::::get().total_votes, 99716198400); + // vote again to refresh the vote amount of CHARLIE + assert_ok!(Farming::vote(RuntimeOrigin::signed(CHARLIE), vote_list.clone())); + assert_eq!(BoostPoolInfos::::get().total_votes, 124645248000); + + assert_eq!(BoostBasicRewards::::get(pid, KSM), Some(3000)); + Farming::on_initialize(0); + Farming::on_initialize(1); + Farming::on_initialize(2); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Tokens::free_balance(KSM, &ALICE), 10000); + System::set_block_number(System::block_number() + 100); + assert_ok!(Farming::claim(RuntimeOrigin::signed(ALICE), pid)); + assert_eq!(Tokens::free_balance(KSM, &ALICE), 11519); + + assert_ok!(Farming::end_boost_round(RuntimeOrigin::signed(ALICE))); + assert_eq!(BoostPoolInfos::::get().end_round, 0); + }) +} + +#[test] +fn charge_boost() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let vote_list = vec![(0u32, Percent::from_percent(100))]; + let whitelist = vec![0]; + assert_ok!(Farming::set_next_round_whitelist( + RuntimeOrigin::signed(ALICE), + whitelist.clone() + )); + assert_ok!(Farming::add_boost_pool_whitelist( + RuntimeOrigin::signed(ALICE), + whitelist.clone() + )); + assert_ok!(Farming::vote(RuntimeOrigin::signed(ALICE), vote_list.clone())); + assert_ok!(Farming::vote(RuntimeOrigin::signed(BOB), vote_list.clone())); + assert_ok!(Farming::vote(RuntimeOrigin::signed(CHARLIE), vote_list.clone())); + assert_ok!(Farming::start_boost_round(RuntimeOrigin::signed(ALICE), 100)); + assert_eq!(BoostVotingPools::::iter().count(), 0); + assert_eq!(UserBoostInfos::::iter().count(), 3); + assert_eq!(BoostWhitelist::::iter().count(), 1); + assert_eq!(BoostNextRoundWhitelist::::iter().count(), 0); + let charge_rewards = vec![(KSM, 300000)]; + assert_ok!(Farming::charge_boost(RuntimeOrigin::signed(BOB), charge_rewards)); + let boost_pool_info = + BoostPoolInfo { total_votes: 0, end_round: 100, start_round: 0, round_length: 100 }; + assert_eq!(BoostPoolInfos::::get(), boost_pool_info); + assert_eq!(BoostVotingPools::::iter().count(), 0); + assert_eq!(UserBoostInfos::::iter().count(), 3); + assert_eq!(BoostWhitelist::::iter().count(), 1); + assert_eq!(BoostNextRoundWhitelist::::iter().count(), 0); + }) +}