diff --git a/pallets/buy-back/src/benchmarking.rs b/pallets/buy-back/src/benchmarking.rs index f77947dd9..3ffd86ccd 100644 --- a/pallets/buy-back/src/benchmarking.rs +++ b/pallets/buy-back/src/benchmarking.rs @@ -34,7 +34,7 @@ use sp_runtime::traits::UniqueSaturatedFrom; benchmarks! { set_vtoken { let origin = T::ControlOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?; - }: _(origin,VDOT,1_000_000u32.into(),Permill::from_percent(2),1000u32.into(),1000u32.into(),true) + }: _(origin,VDOT,1_000_000u32.into(),Permill::from_percent(2),1000u32.into(),1000u32.into(),true,Some(Permill::from_percent(2))) charge { let test_account: T::AccountId = account("seed",1,1); @@ -51,7 +51,8 @@ benchmarks! { Permill::from_percent(2), 1000u32.into(), 1000u32.into(), - true + true, + Some(Permill::from_percent(2)) )); }: _(origin,VDOT) @@ -65,7 +66,8 @@ benchmarks! { Permill::from_percent(2), 1000u32.into(), 1000u32.into(), - true + true, + Some(Permill::from_percent(2)) )); }: { BuyBack::::on_idle(BlockNumberFor::::from(0u32),Weight::from_parts(0, u64::MAX)); diff --git a/pallets/buy-back/src/lib.rs b/pallets/buy-back/src/lib.rs index 346489d7a..b0b92d414 100644 --- a/pallets/buy-back/src/lib.rs +++ b/pallets/buy-back/src/lib.rs @@ -151,6 +151,7 @@ pub mod pallet { add_liquidity_duration: BlockNumberFor, /// The last time liquidity was added. last_add_liquidity: BlockNumberFor, + destruction_ratio: Option, } #[pallet::hooks] @@ -221,6 +222,7 @@ pub mod pallet { buyback_duration: BlockNumberFor, add_liquidity_duration: BlockNumberFor, if_auto: bool, + destruction_ratio: Option, ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; @@ -237,6 +239,7 @@ pub mod pallet { last_buyback: Zero::zero(), add_liquidity_duration, last_add_liquidity: Zero::zero(), + destruction_ratio, }; Infos::::insert(currency_id, info.clone()); @@ -309,6 +312,11 @@ pub mod pallet { &buyback_address, )?; + if let Some(ratio) = info.destruction_ratio { + let bnc_balance_before_burn = T::MultiCurrency::free_balance(BNC, &buyback_address); + let destruction_amount = ratio * bnc_balance_before_burn; + T::MultiCurrency::withdraw(BNC, &buyback_address, destruction_amount)?; + } let bnc_balance = T::MultiCurrency::free_balance(BNC, &buyback_address); let pool_id = 0; T::VeMinting::notify_reward( diff --git a/pallets/buy-back/src/tests.rs b/pallets/buy-back/src/tests.rs index 8bf91a346..ae69a5fcf 100644 --- a/pallets/buy-back/src/tests.rs +++ b/pallets/buy-back/src/tests.rs @@ -33,6 +33,7 @@ const LIQUID_PROPORTION: Permill = Permill::from_percent(2); #[test] fn set_vtoken_should_not_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let destruction_ratio = Some(Permill::from_percent(2)); assert_noop!( BuyBack::set_vtoken( RuntimeOrigin::signed(ALICE), @@ -42,6 +43,7 @@ fn set_vtoken_should_not_work() { BUYBACK_DURATION, LIQUID_DURATION, true, + destruction_ratio ), Error::::CurrencyIdError ); @@ -55,6 +57,7 @@ fn set_vtoken_should_not_work() { 0, LIQUID_DURATION, true, + destruction_ratio ), Error::::ZeroDuration ); @@ -68,16 +71,54 @@ fn set_vtoken_should_not_work() { BUYBACK_DURATION, LIQUID_DURATION, true, + destruction_ratio ), Error::::ZeroMinSwapValue ); }); } +#[test] +fn buy_back_with_burn_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let zenlink_pair_account_id = init_zenlink(PARAID); + let destruction_ratio = Some(Permill::from_percent(2)); + + assert_ok!(BuyBack::set_vtoken( + RuntimeOrigin::signed(ALICE), + VKSM, + VALUE, + LIQUID_PROPORTION, + BUYBACK_DURATION, + LIQUID_DURATION, + true, + destruction_ratio + )); + let buyback_account = ::BuyBackAccount::get().into_account_truncating(); + let incentive_account = IncentivePalletId::get().into_account_truncating(); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 9000); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 2200); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 2000); + assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 0); + VeMinting::set_incentive(0, Some(7 * 86400 / 12), Some(buyback_account.clone())); + assert_ok!(BuyBack::charge(RuntimeOrigin::signed(ALICE), VKSM, 1000)); + let infos = Infos::::get(VKSM).unwrap(); + assert_ok!(BuyBack::buy_back(&buyback_account, VKSM, &infos)); + System::set_block_number(System::block_number() + 1); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 9000); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 3200); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 1377); + assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 611); + }); +} + #[test] fn buy_back_no_burn_should_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { let zenlink_pair_account_id = init_zenlink(PARAID); + let destruction_ratio = Some(Permill::from_percent(0)); assert_ok!(BuyBack::set_vtoken( RuntimeOrigin::signed(ALICE), @@ -87,6 +128,7 @@ fn buy_back_no_burn_should_work() { BUYBACK_DURATION, LIQUID_DURATION, true, + destruction_ratio )); let buyback_account = ::BuyBackAccount::get().into_account_truncating(); let incentive_account = IncentivePalletId::get().into_account_truncating(); @@ -112,6 +154,7 @@ fn buy_back_no_burn_should_work() { fn on_idle_no_burn_should_work() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { let zenlink_pair_account_id = init_zenlink(PARAID); + let destruction_ratio = None; assert_ok!(BuyBack::set_vtoken( RuntimeOrigin::signed(ALICE), @@ -121,6 +164,7 @@ fn on_idle_no_burn_should_work() { BUYBACK_DURATION, LIQUID_DURATION, true, + destruction_ratio )); let buyback_account = ::BuyBackAccount::get().into_account_truncating(); let incentive_account = IncentivePalletId::get().into_account_truncating(); @@ -144,6 +188,44 @@ fn on_idle_no_burn_should_work() { }); } +#[test] +fn on_idle_with_burn_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let zenlink_pair_account_id = init_zenlink(PARAID); + let destruction_ratio = Some(Permill::from_percent(10)); + + assert_ok!(BuyBack::set_vtoken( + RuntimeOrigin::signed(ALICE), + VKSM, + 1_000_000u128, + LIQUID_PROPORTION, + BUYBACK_DURATION, + LIQUID_DURATION, + true, + destruction_ratio + )); + let buyback_account = ::BuyBackAccount::get().into_account_truncating(); + let incentive_account = IncentivePalletId::get().into_account_truncating(); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 9000); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 2200); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 2000); + assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 0); + VeMinting::set_incentive(0, Some(7 * 86400 / 12), Some(buyback_account.clone())); + assert_ok!(BuyBack::charge(RuntimeOrigin::signed(ALICE), VKSM, 1000)); + BuyBack::on_idle( + >::block_number(), + Weight::from_parts(100000000, 0), + ); + System::set_block_number(System::block_number() + 1); + assert_eq!(Currencies::free_balance(VKSM, &buyback_account), 0); + assert_eq!(Currencies::free_balance(VKSM, &zenlink_pair_account_id), 12200); + assert_eq!(Currencies::free_balance(BNC, &zenlink_pair_account_id), 362); + assert_eq!(Currencies::free_balance(BNC, &buyback_account), 0); + assert_eq!(Currencies::free_balance(BNC, &incentive_account), 1474); // 1638 - 164 + }); +} + fn init_zenlink(_para_id: u32) -> AccountIdOf { let asset_0_currency_id: AssetId = AssetId::try_convert_from(BNC, PARAID).unwrap(); let asset_1_currency_id: AssetId = AssetId::try_convert_from(VKSM, PARAID).unwrap();