From 191cf49bf0dd65cc44090dd7f1e5e6dcd12f7950 Mon Sep 17 00:00:00 2001 From: herryho Date: Thu, 30 Sep 2021 14:13:48 +0800 Subject: [PATCH 1/3] unit tests done --- Cargo.lock | 21 ++ Cargo.toml | 1 + pallets/lightening-redeem/Cargo.toml | 47 ++++ pallets/lightening-redeem/src/lib.rs | 277 +++++++++++++++++++++++ pallets/lightening-redeem/src/mock.rs | 206 +++++++++++++++++ pallets/lightening-redeem/src/tests.rs | 178 +++++++++++++++ pallets/lightening-redeem/src/weights.rs | 63 ++++++ pallets/token-issuer/Cargo.toml | 5 +- runtime/asgard/Cargo.toml | 2 + runtime/asgard/src/lib.rs | 11 + 10 files changed, 809 insertions(+), 2 deletions(-) create mode 100644 pallets/lightening-redeem/Cargo.toml create mode 100644 pallets/lightening-redeem/src/lib.rs create mode 100644 pallets/lightening-redeem/src/mock.rs create mode 100644 pallets/lightening-redeem/src/tests.rs create mode 100644 pallets/lightening-redeem/src/weights.rs diff --git a/Cargo.lock b/Cargo.lock index d183e7637c..1df353b4b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -165,6 +165,7 @@ dependencies = [ "bifrost-bancor-runtime-api", "bifrost-flexible-fee", "bifrost-flexible-fee-rpc-runtime-api", + "bifrost-lightening-redeem", "bifrost-liquidity-mining", "bifrost-liquidity-mining-rpc-runtime-api", "bifrost-minter-reward", @@ -726,6 +727,26 @@ dependencies = [ "sp-api", ] +[[package]] +name = "bifrost-lightening-redeem" +version = "0.8.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "node-primitives", + "orml-tokens 0.4.1-dev (git+https://github.com/open-web3-stack/open-runtime-module-library?rev=8d5432c3458702a7df14b374bddde43a2a20aa43)", + "orml-traits 0.4.1-dev (git+https://github.com/open-web3-stack/open-runtime-module-library?rev=8d5432c3458702a7df14b374bddde43a2a20aa43)", + "pallet-collective", + "parity-scale-codec", + "serde", + "sp-arithmetic", + "sp-core 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9)", + "sp-io", + "sp-runtime", + "sp-std 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9)", +] + [[package]] name = "bifrost-liquidity-mining" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index 65fecdd845..5926c215d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ members = [ "pallets/vtoken-mint", "pallets/vtoken-mint/rpc", "pallets/token-issuer", + "pallets/lightening-redeem", "runtime/asgard", "runtime/bifrost", "utils/subkey", diff --git a/pallets/lightening-redeem/Cargo.toml b/pallets/lightening-redeem/Cargo.toml new file mode 100644 index 0000000000..1baa86f4b1 --- /dev/null +++ b/pallets/lightening-redeem/Cargo.toml @@ -0,0 +1,47 @@ +[package] +name = "bifrost-lightening-redeem" +version = "0.8.0" +authors = ["Herry Ho "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.124", optional = true } +orml-traits = { version = "0.4.1-dev", default-features = false } +orml-tokens = { version = "0.4.1-dev", default-features = false } +node-primitives = { path = "../../node/primitives", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false, optional = true } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } +pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-system/std", + "frame-support/std", + "sp-runtime/std", + "sp-arithmetic/std", + "serde/std", + "orml-traits/std", + "orml-tokens/std", + "node-primitives/std", + "sp-core/std", + "sp-io/std", + "sp-std/std", + "pallet-collective/std", +] + +runtime-benchmarks = [ + "frame-benchmarking", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", +] \ No newline at end of file diff --git a/pallets/lightening-redeem/src/lib.rs b/pallets/lightening-redeem/src/lib.rs new file mode 100644 index 0000000000..9dbf0a4de2 --- /dev/null +++ b/pallets/lightening-redeem/src/lib.rs @@ -0,0 +1,277 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg_attr(not(feature = "std"), no_std)] + +use frame_support::{pallet_prelude::*, PalletId}; +use frame_system::pallet_prelude::*; +use node_primitives::{CurrencyId, TokenSymbol}; +use orml_traits::MultiCurrency; +use sp_arithmetic::per_things::Percent; +use sp_runtime::traits::{AccountIdConversion, Saturating, UniqueSaturatedFrom, Zero}; +pub use weights::WeightInfo; + +mod mock; +mod tests; +pub mod weights; + +// #[cfg(feature = "runtime-benchmarks")] +// mod benchmarking; + +pub use pallet::*; + +type AccountIdOf = ::AccountId; +type BalanceOf = <::MultiCurrency as MultiCurrency>>::Balance; + +const TRILLION: u128 = 1_000_000_000_000; +// These time units are defined in number of blocks. +const BLOCKS_PER_DAY: u32 = 60 / 12 * 60 * 24; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + type Event: From> + IsType<::Event>; + /// Currency operations handler + type MultiCurrency: MultiCurrency, CurrencyId = CurrencyId>; + /// The only origin that can modify bootstrap params + type ControlOrigin: EnsureOrigin; + /// Set default weight. + type WeightInfo: WeightInfo; + + /// ModuleID for creating sub account + #[pallet::constant] + type PalletId: Get; + } + + #[pallet::error] + pub enum Error { + NotKSM, + DenominatorZero, + NotGreaterThanZero, + ExceedPoolAmount, + NotEnoughBalance, + InvalidReleaseInterval, + Overflow, + } + + #[pallet::event] + #[pallet::generate_deposit(pub (crate) fn deposit_event)] + pub enum Event { + /// [exchanger, ksm_amount] + KSMExchanged(AccountIdOf, BalanceOf), + /// [adder, ksm_amount] + KSMAdded(AccountIdOf, BalanceOf), + /// [original_prce, new_price] + PriceEdited(BalanceOf, BalanceOf), + /// [start, end] + BlockIntervalEdited(BlockNumberFor, BlockNumberFor), + /// [originla_amount_per_day, amount_per_day] + ReleasedPerDayEdited(BalanceOf, BalanceOf), + } + + /// The remaining amount which can be exchanged for + #[pallet::storage] + #[pallet::getter(fn get_pool_amount)] + pub type PoolAmount = StorageValue<_, BalanceOf, ValueQuery>; + + /// token amount that is released everyday. + #[pallet::storage] + #[pallet::getter(fn get_token_release_per_round)] + pub type TokenReleasePerDay = + StorageValue<_, BalanceOf, ValueQuery, DefaultReleaseAmount>; + + // Defult release amount is 30 KSM + #[pallet::type_value] + pub fn DefaultReleaseAmount() -> BalanceOf { + BalanceOf::::unique_saturated_from(TRILLION.saturating_mul(30)) + } + + /// Token release start block + #[pallet::storage] + #[pallet::getter(fn get_start_and_end_release_block)] + pub type StartEndReleaseBlock = + StorageValue<_, (BlockNumberFor, BlockNumberFor), ValueQuery>; + + /// Exchange price discount: vsbond + vstoken => token + #[pallet::storage] + #[pallet::getter(fn get_exchange_price_discount)] + pub type ExchangePriceDiscount = + StorageValue<_, Percent, ValueQuery, DefaultPrice>; + + // Defult price is 90% + #[pallet::type_value] + pub fn DefaultPrice() -> Percent { + Percent::from_rational(90u32, 100u32) + } + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + #[pallet::hooks] + impl Hooks for Pallet { + fn on_initialize(n: T::BlockNumber) -> Weight { + let (start, end) = Self::get_start_and_end_release_block(); + // relsease fixed amount every day if within release interval and has enough balance in + // the pool account + if (n <= end) & (n > start) { + if (n - start) % BLOCKS_PER_DAY.into() == Zero::zero() { + let ksm = CurrencyId::Token(TokenSymbol::KSM); + let pool_account: AccountIdOf = T::PalletId::get().into_sub_account(0); + let releae_per_day = Self::get_token_release_per_round(); + let total_amount = Self::get_pool_amount().saturating_add(releae_per_day); + + if T::MultiCurrency::ensure_can_withdraw(ksm, &pool_account, total_amount) + .is_ok() + { + PoolAmount::::mutate(|amt| *amt = total_amount); + } + } + } + T::WeightInfo::on_initialize() + } + } + + #[pallet::call] + impl Pallet { + /// Anyone can add KSM to the pool. + #[pallet::weight(T::WeightInfo::add_ksm_to_pool())] + pub fn add_ksm_to_pool(origin: OriginFor, token_amount: BalanceOf) -> DispatchResult { + let adder = ensure_signed(origin)?; + let ksm_id = CurrencyId::Token(TokenSymbol::KSM); + + let token_balance = T::MultiCurrency::free_balance(ksm_id, &adder); + ensure!(token_balance >= token_amount, Error::::NotEnoughBalance); + + let pool_account: AccountIdOf = T::PalletId::get().into_sub_account(0); + T::MultiCurrency::transfer(ksm_id, &adder, &pool_account, token_amount)?; + + Self::deposit_event(Event::KSMAdded(adder, token_amount)); + + Ok(()) + } + + // exchange vsksm and vsbond for ksm + #[pallet::weight(T::WeightInfo::exchange_for_ksm())] + pub fn exchange_for_ksm( + origin: OriginFor, + token_amount: BalanceOf, // The KSM amount the user exchanges for + ) -> DispatchResult { + // Check origin + let exchanger = ensure_signed(origin)?; + ensure!(token_amount <= Self::get_pool_amount(), Error::::ExceedPoolAmount); + + // Check exchanger's vsksm and vsbond balance + let vsksm = CurrencyId::VSToken(TokenSymbol::KSM); + let vsbond = CurrencyId::VSBond(TokenSymbol::BNC, 2001, 13, 20); + let ksm = CurrencyId::Token(TokenSymbol::KSM); + + ensure!( + Self::get_exchange_price_discount() != Percent::zero(), + Error::::DenominatorZero + ); + let amount_needed = + Self::get_exchange_price_discount().saturating_reciprocal_mul(token_amount); + + let vsksm_balance = T::MultiCurrency::free_balance(vsksm, &exchanger); + let vsbond_balance = T::MultiCurrency::free_balance(vsbond, &exchanger); + ensure!(vsksm_balance >= amount_needed, Error::::NotEnoughBalance); + ensure!(vsbond_balance >= amount_needed, Error::::NotEnoughBalance); + + // Make changes to account token balances + let pool_account: AccountIdOf = T::PalletId::get().into_sub_account(0); + T::MultiCurrency::ensure_can_withdraw(ksm, &pool_account, token_amount)?; + PoolAmount::::mutate(|amt| *amt = amt.saturating_sub(token_amount)); + + T::MultiCurrency::transfer(vsksm, &exchanger, &pool_account, amount_needed)?; + T::MultiCurrency::transfer(vsbond, &exchanger, &pool_account, amount_needed)?; + T::MultiCurrency::transfer(ksm, &pool_account, &exchanger, token_amount)?; + + Self::deposit_event(Event::KSMExchanged(exchanger, token_amount)); + + Ok(()) + } + + // edit exchange discount price + #[pallet::weight(T::WeightInfo::edit_exchange_price())] + pub fn edit_exchange_price( + origin: OriginFor, + price: BalanceOf, /* the mumber of ksm we can get by giving out 100 vsksm and 100 + * vsbond */ + ) -> DispatchResult { + // Check origin + T::ControlOrigin::ensure_origin(origin)?; + ensure!(price <= BalanceOf::::unique_saturated_from(100u128), Error::::Overflow); + + let price_percent: Percent = + Percent::from_rational(price, BalanceOf::::unique_saturated_from(100u128)); + let original_price: BalanceOf = Self::get_exchange_price_discount() + .mul_floor(BalanceOf::::unique_saturated_from(100u128)); + + ExchangePriceDiscount::::mutate(|p| *p = price_percent); + + Self::deposit_event(Event::PriceEdited(original_price, price)); + + Ok(()) + } + + // edit token release amount per day + #[pallet::weight(T::WeightInfo::edit_release_per_day())] + pub fn edit_release_per_day( + origin: OriginFor, + amount_per_day: BalanceOf, + ) -> DispatchResult { + // Check origin + T::ControlOrigin::ensure_origin(origin)?; + ensure!(amount_per_day > Zero::zero(), Error::::NotGreaterThanZero); + + let originla_amount_per_day = Self::get_token_release_per_round(); + TokenReleasePerDay::::mutate(|amt| *amt = amount_per_day); + + Self::deposit_event(Event::ReleasedPerDayEdited( + originla_amount_per_day, + amount_per_day, + )); + + Ok(()) + } + + // edit token release start and end block + #[pallet::weight(T::WeightInfo::edit_release_start_and_end_block())] + pub fn edit_release_start_and_end_block( + origin: OriginFor, + start: BlockNumberFor, + end: BlockNumberFor, + ) -> DispatchResult { + // Check origin + T::ControlOrigin::ensure_origin(origin)?; + + let current_block_number = frame_system::Pallet::::block_number(); // get current block number + ensure!(start > current_block_number, Error::::InvalidReleaseInterval); + ensure!(end >= start, Error::::InvalidReleaseInterval); + + StartEndReleaseBlock::::mutate(|interval| *interval = (start, end)); + + Self::deposit_event(Event::BlockIntervalEdited(start, end)); + + Ok(()) + } + } +} diff --git a/pallets/lightening-redeem/src/mock.rs b/pallets/lightening-redeem/src/mock.rs new file mode 100644 index 0000000000..689f2b8bd9 --- /dev/null +++ b/pallets/lightening-redeem/src/mock.rs @@ -0,0 +1,206 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg(test)] +#![allow(non_upper_case_globals)] + +use frame_support::{ + parameter_types, + traits::{GenesisBuild, OnFinalize, OnInitialize}, + PalletId, +}; +use node_primitives::{CurrencyId, TokenSymbol}; +use sp_core::{ + u32_trait::{_2, _3}, + H256, +}; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + AccountId32, +}; + +use crate as bifrost_lightening_redeem; + +pub type BlockNumber = u64; +pub type Balance = u64; + +pub type AccountId = AccountId32; +pub const BNC: CurrencyId = CurrencyId::Native(TokenSymbol::ASG); +pub const KSM: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); +pub const vsKSM: CurrencyId = CurrencyId::VSToken(TokenSymbol::KSM); +pub const vsBond: CurrencyId = CurrencyId::VSBond(TokenSymbol::BNC, 2001, 13, 20); +pub const ALICE: AccountId = AccountId32::new([0u8; 32]); +pub const BOB: AccountId = AccountId32::new([1u8; 32]); +pub const CHARLIE: AccountId = AccountId32::new([3u8; 32]); + +frame_support::construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + Tokens: orml_tokens::{Pallet, Call, Storage, Config, Event}, + Council: pallet_collective::{Pallet, Call, Storage, Origin, Event, Config}, + LighteningRedeem: bifrost_lightening_redeem::{Pallet, Call, Storage, Event} + } +); + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); +} +impl frame_system::Config for Runtime { + type AccountData = (); + type AccountId = AccountId; + type BaseCallFilter = frame_support::traits::Everything; + type BlockHashCount = BlockHashCount; + type BlockLength = (); + type BlockNumber = u64; + type BlockWeights = (); + type Call = Call; + type DbWeight = (); + type Event = Event; + type Hash = H256; + type Hashing = BlakeTwo256; + type Header = Header; + type Index = u64; + type Lookup = IdentityLookup; + type OnKilledAccount = (); + type OnNewAccount = (); + type OnSetCode = (); + type Origin = Origin; + type PalletInfo = PalletInfo; + type SS58Prefix = (); + type SystemWeightInfo = (); + type Version = (); +} + +orml_traits::parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + 0 + }; +} +impl orml_tokens::Config for Runtime { + type Amount = i128; + type Balance = Balance; + type CurrencyId = CurrencyId; + type DustRemovalWhitelist = (); + type Event = Event; + type ExistentialDeposits = ExistentialDeposits; + type MaxLocks = (); + type OnDust = orml_tokens::TransferDust; + type WeightInfo = (); +} + +parameter_types! { + pub const CouncilMotionDuration: BlockNumber = 2 * 7_200; + pub const CouncilMaxProposals: u32 = 100; + pub const CouncilMaxMembers: u32 = 100; +} + +impl pallet_collective::Config for Runtime { + type DefaultVote = pallet_collective::PrimeDefaultVote; + type Event = Event; + type MaxMembers = CouncilMaxMembers; + type MaxProposals = CouncilMaxProposals; + type MotionDuration = CouncilMotionDuration; + type Origin = Origin; + type Proposal = Call; + type WeightInfo = pallet_collective::weights::SubstrateWeight; +} + +parameter_types! { + pub const LighteningRedeemPalletId: PalletId = PalletId(*b"lighten#"); +} + +impl bifrost_lightening_redeem::Config for Runtime { + type Event = Event; + type MultiCurrency = Tokens; + type ControlOrigin = pallet_collective::EnsureProportionAtLeast<_2, _3, AccountId>; + type PalletId = LighteningRedeemPalletId; + type WeightInfo = (); +} + +pub struct ExtBuilder { + endowed_accounts: Vec<(AccountId, CurrencyId, Balance)>, +} + +impl Default for ExtBuilder { + fn default() -> Self { + Self { endowed_accounts: vec![] } + } +} + +impl ExtBuilder { + pub fn balances(mut self, endowed_accounts: Vec<(AccountId, CurrencyId, Balance)>) -> Self { + self.endowed_accounts = endowed_accounts; + self + } + + pub fn one_hundred_for_alice_n_bob(self) -> Self { + self.balances(vec![ + (ALICE, KSM, 100), + (ALICE, vsBond, 100), + (ALICE, vsKSM, 100), + (BOB, vsBond, 100), + (BOB, vsKSM, 100), + ]) + } + + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); + + orml_tokens::GenesisConfig:: { + balances: self + .endowed_accounts + .clone() + .into_iter() + .filter(|(_, currency_id, _)| *currency_id != BNC) + .collect::>(), + } + .assimilate_storage(&mut t) + .unwrap(); + + // add ALICE, BOB, CHARLIE as the council member + pallet_collective::GenesisConfig:: { + members: vec![ALICE, BOB, CHARLIE], + phantom: Default::default(), + } + .assimilate_storage(&mut t) + .unwrap(); + + t.into() + } +} + +// simulate block production +pub(crate) fn run_to_block(n: u64) { + while System::block_number() < n { + LighteningRedeem::on_finalize(System::block_number()); + System::on_finalize(System::block_number()); + System::set_block_number(System::block_number() + 1); + System::on_initialize(System::block_number()); + LighteningRedeem::on_initialize(System::block_number()); + } +} diff --git a/pallets/lightening-redeem/src/tests.rs b/pallets/lightening-redeem/src/tests.rs new file mode 100644 index 0000000000..ee0febc07b --- /dev/null +++ b/pallets/lightening-redeem/src/tests.rs @@ -0,0 +1,178 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg(test)] + +use frame_support::{assert_noop, assert_ok}; +use sp_runtime::DispatchError::BadOrigin; + +use crate::{mock::*, *}; + +fn initialize_pool() { + assert_ok!(LighteningRedeem::edit_release_start_and_end_block( + pallet_collective::RawOrigin::Members(2, 3).into(), + 10, + 15000 + )); + assert_ok!(LighteningRedeem::edit_release_per_day( + pallet_collective::RawOrigin::Members(2, 3).into(), + BalanceOf::::unique_saturated_from(50) + )); + assert_ok!(LighteningRedeem::add_ksm_to_pool(Origin::signed(ALICE), 100)); +} + +#[test] +fn edit_release_start_and_end_block_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + // Charlie doesn't have the permission to edit. + assert_noop!( + LighteningRedeem::edit_release_start_and_end_block(Origin::signed(CHARLIE), 10, 15000), + BadOrigin + ); + + assert_ok!(LighteningRedeem::edit_release_start_and_end_block( + pallet_collective::RawOrigin::Members(2, 3).into(), + 10, + 15000 + )); + + let (start, end) = LighteningRedeem::get_start_and_end_release_block(); + assert_eq!(start, 10); + assert_eq!(end, 15000); + }); +} + +#[test] +fn edit_exchange_price_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let original_price = LighteningRedeem::get_exchange_price_discount() + .mul_floor(BalanceOf::::unique_saturated_from(100u128)); + assert_eq!(original_price, 90); + + // Charlie doesn't have the permission to edit. + assert_noop!(LighteningRedeem::edit_exchange_price(Origin::signed(CHARLIE), 80), BadOrigin); + + assert_ok!(LighteningRedeem::edit_exchange_price( + pallet_collective::RawOrigin::Members(2, 3).into(), + 80 + )); + + let current_price = LighteningRedeem::get_exchange_price_discount() + .mul_floor(BalanceOf::::unique_saturated_from(100u128)); + assert_eq!(current_price, 80); + }); +} + +#[test] +fn edit_release_per_day_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + let originla_amount_per_day = LighteningRedeem::get_token_release_per_round(); + assert_eq!( + originla_amount_per_day, + BalanceOf::::unique_saturated_from(30 * TRILLION) + ); + + // Charlie doesn't have the permission to edit. + assert_noop!( + LighteningRedeem::edit_release_per_day( + Origin::signed(CHARLIE), + BalanceOf::::unique_saturated_from(50 * TRILLION) + ), + BadOrigin + ); + + assert_ok!(LighteningRedeem::edit_release_per_day( + pallet_collective::RawOrigin::Members(2, 3).into(), + BalanceOf::::unique_saturated_from(50 * TRILLION) + )); + + let current_amount_per_day = LighteningRedeem::get_token_release_per_round(); + assert_eq!( + current_amount_per_day, + BalanceOf::::unique_saturated_from(50 * TRILLION) + ); + }); +} + +#[test] +fn add_ksm_to_pool_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + // Charlie doesn't have KSM. + assert_noop!( + LighteningRedeem::add_ksm_to_pool(Origin::signed(CHARLIE), 80), + Error::::NotEnoughBalance + ); + + // Charlie succuessfully issue 800 unit of ZLK to Alice account + assert_ok!(LighteningRedeem::add_ksm_to_pool(Origin::signed(ALICE), 80)); + assert_eq!(Tokens::free_balance(KSM, &ALICE), 20); + + let pool_account = ::PalletId::get().into_sub_account(0); + assert_eq!(Tokens::free_balance(KSM, &pool_account), 80); + }); +} + +#[test] +fn exchange_for_ksm_should_work() { + ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { + run_to_block(2); + initialize_pool(); + run_to_block(3); + + // In block 9, the pool still dosn't have any KSM which can be redeemed. + run_to_block(20); + assert_noop!( + LighteningRedeem::exchange_for_ksm(Origin::signed(CHARLIE), 90), + Error::::ExceedPoolAmount + ); + + run_to_block(7300); + assert_eq!(LighteningRedeem::get_pool_amount(), 50); + // Charlie doesn't have vsKSM and vsBond. + assert_noop!( + LighteningRedeem::exchange_for_ksm(Origin::signed(CHARLIE), 30), + Error::::NotEnoughBalance + ); + + let pool_account = ::PalletId::get().into_sub_account(0); + + // Before doing exchange + assert_eq!(Tokens::free_balance(vsKSM, &BOB), 100); + assert_eq!(Tokens::free_balance(vsBond, &BOB), 100); + assert_eq!(Tokens::free_balance(KSM, &BOB), 0); + + assert_eq!(Tokens::free_balance(KSM, &pool_account), 100); + assert_eq!(Tokens::free_balance(vsKSM, &pool_account), 0); + assert_eq!(Tokens::free_balance(vsBond, &pool_account), 0); + + run_to_block(14900); + assert_eq!(LighteningRedeem::get_pool_amount(), 100); + + // perform the exchange + assert_ok!(LighteningRedeem::exchange_for_ksm(Origin::signed(BOB), 90)); + assert_eq!(Tokens::free_balance(vsKSM, &BOB), 0); + assert_eq!(Tokens::free_balance(vsBond, &BOB), 0); + assert_eq!(Tokens::free_balance(KSM, &BOB), 90); + + assert_eq!(Tokens::free_balance(KSM, &pool_account), 10); + assert_eq!(Tokens::free_balance(vsKSM, &pool_account), 100); + assert_eq!(Tokens::free_balance(vsBond, &pool_account), 100); + + assert_eq!(LighteningRedeem::get_pool_amount(), 10); + }); +} diff --git a/pallets/lightening-redeem/src/weights.rs b/pallets/lightening-redeem/src/weights.rs new file mode 100644 index 0000000000..380b575e11 --- /dev/null +++ b/pallets/lightening-redeem/src/weights.rs @@ -0,0 +1,63 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{ + traits::Get, + weights::{constants::RocksDbWeight, Weight}, +}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for the pallet. +pub trait WeightInfo { + fn add_ksm_to_pool() -> Weight; + fn exchange_for_ksm() -> Weight; + fn edit_exchange_price() -> Weight; + fn edit_release_per_day() -> Weight; + fn edit_release_start_and_end_block() -> Weight; + fn on_initialize() -> Weight; +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn add_ksm_to_pool() -> Weight { + (50_000_000 as Weight) + } + + fn exchange_for_ksm() -> Weight { + (50_000_000 as Weight) + } + + fn edit_exchange_price() -> Weight { + (50_000_000 as Weight) + } + + fn edit_release_per_day() -> Weight { + (50_000_000 as Weight) + } + + fn edit_release_start_and_end_block() -> Weight { + (50_000_000 as Weight) + } + + fn on_initialize() -> Weight { + (50_000_000 as Weight) + } +} diff --git a/pallets/token-issuer/Cargo.toml b/pallets/token-issuer/Cargo.toml index 9ac7268c61..0df9887c77 100644 --- a/pallets/token-issuer/Cargo.toml +++ b/pallets/token-issuer/Cargo.toml @@ -28,13 +28,14 @@ std = [ "frame-support/std", "frame-system/std", "orml-traits/std", - "sp-core/std", "sp-runtime/std", "sp-io/std", "pallet-collective/std", "orml-tokens/std", "orml-currencies/std", - "pallet-balances/std" + "pallet-balances/std", + "pallet-balances/std", + "sp-core/std" ] runtime-benchmarks = [ diff --git a/runtime/asgard/Cargo.toml b/runtime/asgard/Cargo.toml index 7d94918360..b062533c85 100644 --- a/runtime/asgard/Cargo.toml +++ b/runtime/asgard/Cargo.toml @@ -94,6 +94,7 @@ bifrost-liquidity-mining-rpc-runtime-api = { path = "../../pallets/liquidity-min bifrost-vsbond-auction = { path = "../../pallets/vsbond-auction", default-features = false } bifrost-vtoken-mint = { path = "../../pallets/vtoken-mint", default-features = false } bifrost-token-issuer= { path = "../../pallets/token-issuer", default-features = false } +bifrost-lightening-redeem= { path = "../../pallets/lightening-redeem", default-features = false } pallet-vesting = { package = "bifrost-vesting", path = "../../pallets/vesting", default-features = false } xcm-support = { path = "../../xcm-support", default-features = false } @@ -184,6 +185,7 @@ std = [ "bifrost-liquidity-mining/std", "bifrost-liquidity-mining-rpc-runtime-api/std", "bifrost-token-issuer/std", + "bifrost-lightening-redeem/std", "xcm-support/std", "orml-currencies/std", "orml-traits/std", diff --git a/runtime/asgard/src/lib.rs b/runtime/asgard/src/lib.rs index 2401665065..5bcb9fb975 100644 --- a/runtime/asgard/src/lib.rs +++ b/runtime/asgard/src/lib.rs @@ -195,6 +195,7 @@ parameter_types! { pub const TreasuryPalletId: PalletId = PalletId(*b"bf/trsry"); pub const BifrostCrowdloanId: PalletId = PalletId(*b"bf/salp#"); pub const LiquidityMiningPalletId: PalletId = PalletId(*b"bf/lm###"); + pub const LighteningRedeemPalletId: PalletId = PalletId(*b"lighten#"); } pub fn get_all_pallet_accounts() -> Vec { @@ -1273,6 +1274,15 @@ impl bifrost_token_issuer::Config for Runtime { type WeightInfo = weights::bifrost_token_issuer::WeightInfo; } +impl bifrost_lightening_redeem::Config for Runtime { + type Event = Event; + type MultiCurrency = Tokens; + type ControlOrigin = + EnsureOneOf; + type PalletId = LighteningRedeemPalletId; + type WeightInfo = (); +} + // bifrost runtime end // zenlink runtime start @@ -1451,6 +1461,7 @@ construct_runtime! { VSBondAuction: bifrost_vsbond_auction::{Pallet, Call, Storage, Event} = 107, LiquidityMining: bifrost_liquidity_mining::{Pallet, Call, Storage, Event} = 108, TokenIssuer: bifrost_token_issuer::{Pallet, Call, Storage, Event} = 109, + LighteningRedeem: bifrost_lightening_redeem::{Pallet, Call, Storage, Event} = 110, } } From 2417296ca3f4baa58720576e708f057b5172e548 Mon Sep 17 00:00:00 2001 From: herryho Date: Sat, 9 Oct 2021 18:07:45 +0800 Subject: [PATCH 2/3] add lightening-redeem benchmarking to asgard runtime --- Cargo.lock | 8 +- node/service/src/chain_spec/asgard.rs | 6 ++ pallets/lightening-redeem/Cargo.toml | 18 ++-- pallets/lightening-redeem/src/benchmarking.rs | 83 +++++++++++++++++ pallets/lightening-redeem/src/lib.rs | 10 +-- pallets/lightening-redeem/src/mock.rs | 11 +++ pallets/lightening-redeem/src/tests.rs | 4 +- runtime/asgard/Cargo.toml | 1 + runtime/asgard/src/lib.rs | 11 ++- .../src/weights/bifrost_lightening_redeem.rs | 89 +++++++++++++++++++ runtime/asgard/src/weights/mod.rs | 1 + 11 files changed, 220 insertions(+), 22 deletions(-) create mode 100644 pallets/lightening-redeem/src/benchmarking.rs create mode 100644 runtime/asgard/src/weights/bifrost_lightening_redeem.rs diff --git a/Cargo.lock b/Cargo.lock index 1df353b4b3..a6315f9ed6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -735,16 +735,16 @@ dependencies = [ "frame-support", "frame-system", "node-primitives", - "orml-tokens 0.4.1-dev (git+https://github.com/open-web3-stack/open-runtime-module-library?rev=8d5432c3458702a7df14b374bddde43a2a20aa43)", - "orml-traits 0.4.1-dev (git+https://github.com/open-web3-stack/open-runtime-module-library?rev=8d5432c3458702a7df14b374bddde43a2a20aa43)", + "orml-tokens 0.4.1-dev (git+https://github.com/open-web3-stack/open-runtime-module-library?rev=37e42936c41dbdbaf0117c628c9eab0e06044844)", + "orml-traits 0.4.1-dev (git+https://github.com/open-web3-stack/open-runtime-module-library?rev=37e42936c41dbdbaf0117c628c9eab0e06044844)", "pallet-collective", "parity-scale-codec", "serde", "sp-arithmetic", - "sp-core 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9)", + "sp-core", "sp-io", "sp-runtime", - "sp-std 4.0.0-dev (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.9)", + "sp-std", ] [[package]] diff --git a/node/service/src/chain_spec/asgard.rs b/node/service/src/chain_spec/asgard.rs index 7f1857dd70..555b9f9b32 100644 --- a/node/service/src/chain_spec/asgard.rs +++ b/node/service/src/chain_spec/asgard.rs @@ -217,6 +217,12 @@ fn local_config_genesis(id: ParaId) -> GenesisConfig { (x.clone(), CurrencyId::Stable(TokenSymbol::KUSD), ENDOWMENT * 4_000_000), (x.clone(), CurrencyId::Token(TokenSymbol::KSM), ENDOWMENT * 4_000_000), (x.clone(), CurrencyId::Native(TokenSymbol::ASG), ENDOWMENT * 4_000_000), + (x.clone(), CurrencyId::VSToken(TokenSymbol::KSM), ENDOWMENT * 4_000_000), + ( + x.clone(), + CurrencyId::VSBond(TokenSymbol::BNC, 2001, 13, 20), + ENDOWMENT * 4_000_000, + ), ] }) .collect(); diff --git a/pallets/lightening-redeem/Cargo.toml b/pallets/lightening-redeem/Cargo.toml index 1baa86f4b1..55c391f39b 100644 --- a/pallets/lightening-redeem/Cargo.toml +++ b/pallets/lightening-redeem/Cargo.toml @@ -12,15 +12,15 @@ serde = { version = "1.0.124", optional = true } orml-traits = { version = "0.4.1-dev", default-features = false } orml-tokens = { version = "0.4.1-dev", default-features = false } node-primitives = { path = "../../node/primitives", default-features = false } -frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false, optional = true } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } -frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } -sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } -sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } -pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.9", default-features = false } +frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.10", default-features = false, optional = true } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.10", default-features = false } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.10", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.10", default-features = false } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.10", default-features = false } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.10", default-features = false } +pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.10", default-features = false } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.10", default-features = false } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.10", default-features = false } [features] default = ["std"] diff --git a/pallets/lightening-redeem/src/benchmarking.rs b/pallets/lightening-redeem/src/benchmarking.rs new file mode 100644 index 0000000000..13b476f2f2 --- /dev/null +++ b/pallets/lightening-redeem/src/benchmarking.rs @@ -0,0 +1,83 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#![cfg(feature = "runtime-benchmarks")] + +use frame_benchmarking::{benchmarks, impl_benchmark_test_suite, whitelisted_caller}; +use frame_support::{dispatch::UnfilteredDispatchable, sp_runtime::traits::UniqueSaturatedFrom}; +use frame_system::RawOrigin; + +use super::*; +#[allow(unused_imports)] +use crate::Pallet as LighteningRedeem; +use crate::{PoolAmount, StartEndReleaseBlock}; + +benchmarks! { + add_ksm_to_pool { + let caller: T::AccountId = whitelisted_caller(); + let token_amount = BalanceOf::::unique_saturated_from(1000u32 as u128); + }: _(RawOrigin::Signed(caller), token_amount) + + exchange_for_ksm { + let caller: T::AccountId = whitelisted_caller(); + // add 1000 ksm to the pool + let amount = BalanceOf::::unique_saturated_from(1_000u128); + LighteningRedeem::::add_ksm_to_pool(RawOrigin::Signed(caller.clone()).into(), BalanceOf::::unique_saturated_from(amount))?; + + PoolAmount::::mutate(|amt| *amt += amount); + + let exchange_amount: u128 = 900; + let token_amount = BalanceOf::::unique_saturated_from(exchange_amount); + }: _(RawOrigin::Signed(caller), token_amount) + + edit_exchange_price { + let origin = T::ControlOrigin::successful_origin(); + let price = BalanceOf::::unique_saturated_from(50u128); + let call = Call::::edit_exchange_price(price); + }: {call.dispatch_bypass_filter(origin)?} + + edit_release_per_day { + let origin = T::ControlOrigin::successful_origin(); + let amount_per_day = BalanceOf::::unique_saturated_from(50u128); + let call = Call::::edit_release_per_day(amount_per_day); + }: {call.dispatch_bypass_filter(origin)?} + + edit_release_start_and_end_block { + let origin = T::ControlOrigin::successful_origin(); + let start = BlockNumberFor::::from(50u32); + let end = BlockNumberFor::::from(100u32); + let call = Call::::edit_release_start_and_end_block(start, end); + }: {call.dispatch_bypass_filter(origin)?} + + on_initialize { + let caller: T::AccountId = whitelisted_caller(); + let amount: u128 = 1_000; + LighteningRedeem::::add_ksm_to_pool(RawOrigin::Signed(caller.clone()).into(), BalanceOf::::unique_saturated_from(amount))?; + StartEndReleaseBlock::::mutate(|interval| *interval = (T::BlockNumber::from(0u32), T::BlockNumber::from(100u32))); + + let block_num = T::BlockNumber::from(10u32); + }:{LighteningRedeem::::on_initialize(block_num);} +} + +impl_benchmark_test_suite!( + LighteningRedeem, + crate::mock::ExtBuilder::default() + .one_hundred_precision_for_each_currency_type_for_whitelist_account() + .build(), + crate::mock::Test +); diff --git a/pallets/lightening-redeem/src/lib.rs b/pallets/lightening-redeem/src/lib.rs index 9dbf0a4de2..13abe724ce 100644 --- a/pallets/lightening-redeem/src/lib.rs +++ b/pallets/lightening-redeem/src/lib.rs @@ -30,8 +30,8 @@ mod mock; mod tests; pub mod weights; -// #[cfg(feature = "runtime-benchmarks")] -// mod benchmarking; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; pub use pallet::*; @@ -134,7 +134,7 @@ pub mod pallet { if (n <= end) & (n > start) { if (n - start) % BLOCKS_PER_DAY.into() == Zero::zero() { let ksm = CurrencyId::Token(TokenSymbol::KSM); - let pool_account: AccountIdOf = T::PalletId::get().into_sub_account(0); + let pool_account: AccountIdOf = T::PalletId::get().into_account(); let releae_per_day = Self::get_token_release_per_round(); let total_amount = Self::get_pool_amount().saturating_add(releae_per_day); @@ -160,7 +160,7 @@ pub mod pallet { let token_balance = T::MultiCurrency::free_balance(ksm_id, &adder); ensure!(token_balance >= token_amount, Error::::NotEnoughBalance); - let pool_account: AccountIdOf = T::PalletId::get().into_sub_account(0); + let pool_account: AccountIdOf = T::PalletId::get().into_account(); T::MultiCurrency::transfer(ksm_id, &adder, &pool_account, token_amount)?; Self::deposit_event(Event::KSMAdded(adder, token_amount)); @@ -196,7 +196,7 @@ pub mod pallet { ensure!(vsbond_balance >= amount_needed, Error::::NotEnoughBalance); // Make changes to account token balances - let pool_account: AccountIdOf = T::PalletId::get().into_sub_account(0); + let pool_account: AccountIdOf = T::PalletId::get().into_account(); T::MultiCurrency::ensure_can_withdraw(ksm, &pool_account, token_amount)?; PoolAmount::::mutate(|amt| *amt = amt.saturating_sub(token_amount)); diff --git a/pallets/lightening-redeem/src/mock.rs b/pallets/lightening-redeem/src/mock.rs index 689f2b8bd9..74f607e9c9 100644 --- a/pallets/lightening-redeem/src/mock.rs +++ b/pallets/lightening-redeem/src/mock.rs @@ -168,6 +168,17 @@ impl ExtBuilder { ]) } + #[cfg(feature = "runtime-benchmarks")] + pub fn one_hundred_precision_for_each_currency_type_for_whitelist_account(self) -> Self { + let whitelist_caller: AccountId = whitelisted_caller(); + let pool_account = LighteningRedeemPalletId::get().into_account(); + + self.balances(vec![ + (whitelist_caller.clone(), KSM, 100_000_000_000_000), + (pool_account.clone(), KSM, 100_000_000_000_000), + ]) + } + pub fn build(self) -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); diff --git a/pallets/lightening-redeem/src/tests.rs b/pallets/lightening-redeem/src/tests.rs index ee0febc07b..2fd1abacd5 100644 --- a/pallets/lightening-redeem/src/tests.rs +++ b/pallets/lightening-redeem/src/tests.rs @@ -122,7 +122,7 @@ fn add_ksm_to_pool_should_work() { assert_ok!(LighteningRedeem::add_ksm_to_pool(Origin::signed(ALICE), 80)); assert_eq!(Tokens::free_balance(KSM, &ALICE), 20); - let pool_account = ::PalletId::get().into_sub_account(0); + let pool_account = ::PalletId::get().into_account(); assert_eq!(Tokens::free_balance(KSM, &pool_account), 80); }); } @@ -149,7 +149,7 @@ fn exchange_for_ksm_should_work() { Error::::NotEnoughBalance ); - let pool_account = ::PalletId::get().into_sub_account(0); + let pool_account = ::PalletId::get().into_account(); // Before doing exchange assert_eq!(Tokens::free_balance(vsKSM, &BOB), 100); diff --git a/runtime/asgard/Cargo.toml b/runtime/asgard/Cargo.toml index b062533c85..45316b014a 100644 --- a/runtime/asgard/Cargo.toml +++ b/runtime/asgard/Cargo.toml @@ -213,6 +213,7 @@ runtime-benchmarks = [ "bifrost-minter-reward/runtime-benchmarks", "bifrost-vsbond-auction/runtime-benchmarks", "bifrost-token-issuer/runtime-benchmarks", + "bifrost-lightening-redeem/runtime-benchmarks", ] try-runtime = [ diff --git a/runtime/asgard/src/lib.rs b/runtime/asgard/src/lib.rs index 5bcb9fb975..971596db78 100644 --- a/runtime/asgard/src/lib.rs +++ b/runtime/asgard/src/lib.rs @@ -199,7 +199,11 @@ parameter_types! { } pub fn get_all_pallet_accounts() -> Vec { - vec![TreasuryPalletId::get().into_account(), BifrostCrowdloanId::get().into_account()] + vec![ + TreasuryPalletId::get().into_account(), + BifrostCrowdloanId::get().into_account(), + LighteningRedeemPalletId::get().into_account(), + ] } impl frame_system::Config for Runtime { @@ -977,6 +981,7 @@ orml_traits::parameter_type_with_key! { &CurrencyId::VSToken(TokenSymbol::KSM) => 10 * MILLICENTS, &CurrencyId::VSBond(TokenSymbol::ASG, ..) => 10 * MILLICENTS, &CurrencyId::VSBond(TokenSymbol::KSM, ..) => 10 * MILLICENTS, + &CurrencyId::VSBond(TokenSymbol::BNC, ..) => 10 * MILLICENTS, &CurrencyId::LPToken(..) => 10 * MILLICENTS, _ => Balance::max_value() // unsupported } @@ -1280,7 +1285,7 @@ impl bifrost_lightening_redeem::Config for Runtime { type ControlOrigin = EnsureOneOf; type PalletId = LighteningRedeemPalletId; - type WeightInfo = (); + type WeightInfo = weights::bifrost_lightening_redeem::WeightInfo; } // bifrost runtime end @@ -1745,6 +1750,7 @@ impl_runtime_apis! { list_benchmark!(list, extra, bifrost_minter_reward, MinterReward); list_benchmark!(list, extra, bifrost_vsbond_auction, VSBondAuction); list_benchmark!(list, extra, bifrost_token_issuer, TokenIssuer); + list_benchmark!(list, extra, bifrost_lightening_redeem, LighteningRedeem); let storage_info = AllPalletsWithSystem::storage_info(); @@ -1782,6 +1788,7 @@ impl_runtime_apis! { add_benchmark!(params, batches, bifrost_minter_reward, MinterReward); add_benchmark!(params, batches, bifrost_vsbond_auction, VSBondAuction); add_benchmark!(params, batches, bifrost_token_issuer, TokenIssuer); + add_benchmark!(params, batches, bifrost_lightening_redeem, LighteningRedeem); if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches) diff --git a/runtime/asgard/src/weights/bifrost_lightening_redeem.rs b/runtime/asgard/src/weights/bifrost_lightening_redeem.rs new file mode 100644 index 0000000000..1aeeaa3489 --- /dev/null +++ b/runtime/asgard/src/weights/bifrost_lightening_redeem.rs @@ -0,0 +1,89 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Autogenerated weights for `bifrost_lightening_redeem` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-10-09, STEPS: `50`, REPEAT: 1, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("asgard-local"), DB CACHE: 128 + +// Executed Command: +// target/release/bifrost +// benchmark +// --chain=asgard-local +// --steps=50 +// --repeat=1 +// --pallet=bifrost_lightening_redeem +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./HEADER-GPL3 +// --output=./runtime/asgard/src/weights/bifrost_lightening_redeem.rs + + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; + +/// Weight functions for bifrost_lightening_redeem. +pub struct WeightInfo(PhantomData); +impl bifrost_lightening_redeem::WeightInfo for WeightInfo { + // Storage: Tokens Accounts (r:2 w:2) + // Storage: System Account (r:1 w:1) + fn add_ksm_to_pool() -> Weight { + (89_467_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + // Storage: LighteningRedeem PoolAmount (r:1 w:1) + // Storage: LighteningRedeem ExchangePriceDiscount (r:1 w:0) + // Storage: Tokens Accounts (r:6 w:6) + // Storage: System Account (r:1 w:1) + fn exchange_for_ksm() -> Weight { + (189_565_000 as Weight) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(8 as Weight)) + } + // Storage: LighteningRedeem ExchangePriceDiscount (r:1 w:1) + fn edit_exchange_price() -> Weight { + (25_427_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: LighteningRedeem TokenReleasePerDay (r:1 w:1) + fn edit_release_per_day() -> Weight { + (25_718_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: LighteningRedeem StartEndReleaseBlock (r:1 w:1) + fn edit_release_start_and_end_block() -> Weight { + (25_608_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: LighteningRedeem StartEndReleaseBlock (r:1 w:0) + fn on_initialize() -> Weight { + (5_009_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + } +} diff --git a/runtime/asgard/src/weights/mod.rs b/runtime/asgard/src/weights/mod.rs index 108f9833ec..b96ebc4160 100644 --- a/runtime/asgard/src/weights/mod.rs +++ b/runtime/asgard/src/weights/mod.rs @@ -22,6 +22,7 @@ pub mod bifrost_bancor; pub mod bifrost_flexible_fee; +pub mod bifrost_lightening_redeem; pub mod bifrost_minter_reward; pub mod bifrost_salp; pub mod bifrost_token_issuer; From 53828d6e3545093993dd240adefb5a2a18d7d2a6 Mon Sep 17 00:00:00 2001 From: herryho Date: Sun, 10 Oct 2021 12:35:52 +0800 Subject: [PATCH 3/3] change LighteningRedeemPalletId --- runtime/asgard/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/asgard/src/lib.rs b/runtime/asgard/src/lib.rs index 971596db78..247902e163 100644 --- a/runtime/asgard/src/lib.rs +++ b/runtime/asgard/src/lib.rs @@ -195,7 +195,7 @@ parameter_types! { pub const TreasuryPalletId: PalletId = PalletId(*b"bf/trsry"); pub const BifrostCrowdloanId: PalletId = PalletId(*b"bf/salp#"); pub const LiquidityMiningPalletId: PalletId = PalletId(*b"bf/lm###"); - pub const LighteningRedeemPalletId: PalletId = PalletId(*b"lighten#"); + pub const LighteningRedeemPalletId: PalletId = PalletId(*b"bf/ltnrd"); } pub fn get_all_pallet_accounts() -> Vec {