diff --git a/Cargo.lock b/Cargo.lock
index bdad2c770c..fa84c23dbc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6390,6 +6390,7 @@ dependencies = [
"pallet-moonbeam-orbiters",
"pallet-multisig",
"pallet-parachain-staking",
+ "pallet-parameters",
"pallet-precompile-benchmarks",
"pallet-preimage",
"pallet-proxy",
@@ -6985,6 +6986,7 @@ dependencies = [
"pallet-moonbeam-orbiters",
"pallet-multisig",
"pallet-parachain-staking",
+ "pallet-parameters",
"pallet-precompile-benchmarks",
"pallet-preimage",
"pallet-proxy",
diff --git a/Cargo.toml b/Cargo.toml
index 0578bfc1bf..c3a8bea3d4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -148,6 +148,7 @@ pallet-identity = { git = "https://github.com/moonbeam-foundation/polkadot-sdk",
pallet-message-queue = { git = "https://github.com/moonbeam-foundation/polkadot-sdk", branch = "moonbeam-polkadot-v1.11.0", default-features = false }
pallet-multisig = { git = "https://github.com/moonbeam-foundation/polkadot-sdk", branch = "moonbeam-polkadot-v1.11.0", default-features = false }
pallet-preimage = { git = "https://github.com/moonbeam-foundation/polkadot-sdk", branch = "moonbeam-polkadot-v1.11.0", default-features = false }
+pallet-parameters = { git = "https://github.com/moonbeam-foundation/polkadot-sdk", branch = "moonbeam-polkadot-v1.11.0", default-features = false }
pallet-proxy = { git = "https://github.com/moonbeam-foundation/polkadot-sdk", branch = "moonbeam-polkadot-v1.11.0", default-features = false }
pallet-referenda = { git = "https://github.com/moonbeam-foundation/polkadot-sdk", branch = "moonbeam-polkadot-v1.11.0", default-features = false }
pallet-root-testing = { git = "https://github.com/moonbeam-foundation/polkadot-sdk", branch = "moonbeam-polkadot-v1.11.0", default-features = false }
diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml
index b94bbbc4ca..8a9ff1de6b 100644
--- a/runtime/common/Cargo.toml
+++ b/runtime/common/Cargo.toml
@@ -44,6 +44,7 @@ pallet-identity = { workspace = true }
pallet-moonbeam-orbiters = { workspace = true }
pallet-multisig = { workspace = true }
pallet-preimage = { workspace = true }
+pallet-parameters = { workspace = true }
pallet-proxy = { workspace = true }
pallet-referenda = { workspace = true }
pallet-scheduler = { workspace = true }
@@ -100,6 +101,7 @@ std = [
"pallet-evm/std",
"pallet-migrations/std",
"pallet-parachain-staking/std",
+ "pallet-parameters/std",
"pallet-randomness/std",
"pallet-referenda/std",
"pallet-scheduler/std",
@@ -139,6 +141,7 @@ runtime-benchmarks = [
"pallet-multisig/runtime-benchmarks",
"pallet-parachain-staking/runtime-benchmarks",
"pallet-preimage/runtime-benchmarks",
+ "pallet-parameters/runtime-benchmarks",
"pallet-proxy/runtime-benchmarks",
"pallet-randomness/runtime-benchmarks",
"pallet-referenda/runtime-benchmarks",
diff --git a/runtime/common/src/apis.rs b/runtime/common/src/apis.rs
index 38912cb7d4..d9aa574eaa 100644
--- a/runtime/common/src/apis.rs
+++ b/runtime/common/src/apis.rs
@@ -1124,6 +1124,13 @@ macro_rules! impl_runtime_apis_plus_common {
hex_literal::hex!( "0d715f2646c8f85767b5d2764bb27826"
"04a74d81251e398fd8a0a4d55023bb3f")
.to_vec().into(),
+ // Parameters Parameters
+ hex_literal::hex!( "c63bdd4a39095ccf55623a6f2872bf8a" // Pallet: "Parameters"
+ "c63bdd4a39095ccf55623a6f2872bf8a" // Storage Prefix: "Parameters"
+ // MoonbaseRuntimeRuntimeParamsRuntimeParametersKey(FeesTreasuryProportion)
+ "71d0aacb690b61280d0c97c6b6a666640000"
+ )
+ .to_vec().into(),
];
diff --git a/runtime/common/src/weights/mod.rs b/runtime/common/src/weights/mod.rs
index 6108d9c228..dae752bd3a 100644
--- a/runtime/common/src/weights/mod.rs
+++ b/runtime/common/src/weights/mod.rs
@@ -36,6 +36,7 @@ pub mod pallet_moonbeam_lazy_migrations;
pub mod pallet_moonbeam_orbiters;
pub mod pallet_multisig;
pub mod pallet_parachain_staking;
+pub mod pallet_parameters;
pub mod pallet_precompile_benchmarks;
pub mod pallet_preimage;
pub mod pallet_proxy;
diff --git a/runtime/common/src/weights/pallet_parameters.rs b/runtime/common/src/weights/pallet_parameters.rs
new file mode 100644
index 0000000000..ed4a72ba2b
--- /dev/null
+++ b/runtime/common/src/weights/pallet_parameters.rs
@@ -0,0 +1,60 @@
+// Copyright 2019-2022 PureStake Inc.
+// This file is part of Moonbeam.
+
+// Moonbeam 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.
+
+// Moonbeam 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 Moonbeam. If not, see .
+
+//! Autogenerated weights for `pallet_parameters`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-08-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! WORST CASE MAP SIZE: `1000000`
+//! HOSTNAME: `COV0706`, CPU: `AMD Ryzen 9 7950X 16-Core Processor`
+//! WASM-EXECUTION: Compiled, CHAIN: Some("moonbase-dev"), DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/moonbeam
+// benchmark
+// pallet
+// --chain=moonbase-dev
+// --steps=50
+// --repeat=20
+// --pallet=pallet_parameters
+// --extrinsic=*
+// --wasm-execution=compiled
+// --header=./file_header.txt
+// --template=./benchmarking/frame-weight-template.hbs
+// --output=./runtime/common/src/weights/
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+
+use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
+use sp_std::marker::PhantomData;
+
+/// Weights for `pallet_parameters`.
+pub struct WeightInfo(PhantomData);
+impl pallet_parameters::WeightInfo for WeightInfo {
+ /// Storage: `Parameters::Parameters` (r:1 w:1)
+ /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(36), added: 2511, mode: `MaxEncodedLen`)
+ fn set_parameter() -> Weight {
+ // Proof Size summary in bytes:
+ // Measured: `3`
+ // Estimated: `3501`
+ // Minimum execution time: 5_480_000 picoseconds.
+ Weight::from_parts(5_610_000, 3501)
+ .saturating_add(T::DbWeight::get().reads(1_u64))
+ .saturating_add(T::DbWeight::get().writes(1_u64))
+ }
+}
diff --git a/runtime/moonbase/Cargo.toml b/runtime/moonbase/Cargo.toml
index f059b33244..b12ede2a83 100644
--- a/runtime/moonbase/Cargo.toml
+++ b/runtime/moonbase/Cargo.toml
@@ -89,6 +89,7 @@ pallet-conviction-voting = { workspace = true }
pallet-identity = { workspace = true }
pallet-multisig = { workspace = true }
pallet-preimage = { workspace = true }
+pallet-parameters = { workspace = true }
pallet-proxy = { workspace = true }
pallet-referenda = { workspace = true }
pallet-root-testing = { workspace = true }
@@ -274,6 +275,7 @@ std = [
"pallet-parachain-staking/std",
"pallet-precompile-benchmarks/std",
"pallet-preimage/std",
+ "pallet-parameters/std",
"pallet-proxy-genesis-companion/std",
"pallet-proxy/std",
"pallet-randomness/std",
@@ -365,6 +367,7 @@ runtime-benchmarks = [
"pallet-parachain-staking/runtime-benchmarks",
"pallet-precompile-benchmarks/runtime-benchmarks",
"pallet-preimage/runtime-benchmarks",
+ "pallet-parameters/runtime-benchmarks",
"pallet-proxy/runtime-benchmarks",
"pallet-randomness/runtime-benchmarks",
"pallet-referenda/runtime-benchmarks",
@@ -406,6 +409,7 @@ try-runtime = [
"pallet-moonbeam-lazy-migrations/try-runtime",
"pallet-parachain-staking/try-runtime",
"pallet-preimage/try-runtime",
+ "pallet-parameters/try-runtime",
"pallet-referenda/try-runtime",
"pallet-relay-storage-roots/try-runtime",
"pallet-root-testing/try-runtime",
diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs
index 6a591538cd..387d2cff66 100644
--- a/runtime/moonbase/src/lib.rs
+++ b/runtime/moonbase/src/lib.rs
@@ -30,6 +30,7 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
pub mod asset_config;
pub mod governance;
+pub mod runtime_params;
pub mod xcm_config;
mod migrations;
@@ -125,6 +126,8 @@ use xcm_config::AssetType;
use xcm_fee_payment_runtime_api::Error as XcmPaymentApiError;
use xcm_primitives::UnitsToWeightRatio;
+use runtime_params::*;
+
use smallvec::smallvec;
use sp_runtime::serde::{Deserialize, Serialize};
@@ -348,8 +351,11 @@ where
mut fees_then_tips: impl Iterator- >>,
) {
if let Some(fees) = fees_then_tips.next() {
- // for fees, 80% are burned, 20% to the treasury
- let (_, to_treasury) = fees.ration(80, 20);
+ let treasury_perbill =
+ runtime_params::dynamic_params::runtime_config::FeesTreasuryProportion::get();
+ let treasury_part = treasury_perbill.deconstruct();
+ let burn_part = Perbill::one().deconstruct() - treasury_part;
+ let (_, to_treasury) = fees.ration(burn_part, treasury_part);
// Balances pallet automatically burns dropped Credits by decreasing
// total_supply accordingly
ResolveTo::, pallet_balances::Pallet>::on_unbalanced(
@@ -1379,6 +1385,13 @@ impl pallet_precompile_benchmarks::Config for Runtime {
type WeightInfo = moonbase_weights::pallet_precompile_benchmarks::WeightInfo;
}
+impl pallet_parameters::Config for Runtime {
+ type AdminOrigin = EnsureRoot;
+ type RuntimeEvent = RuntimeEvent;
+ type RuntimeParameters = RuntimeParameters;
+ type WeightInfo = moonbase_weights::pallet_parameters::WeightInfo;
+}
+
construct_runtime! {
pub enum Runtime
{
@@ -1441,6 +1454,7 @@ construct_runtime! {
MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event} = 54,
EmergencyParaXcm: pallet_emergency_para_xcm::{Pallet, Call, Storage, Event} = 55,
EvmForeignAssets: pallet_moonbeam_foreign_assets::{Pallet, Call, Storage, Event} = 56,
+ Parameters: pallet_parameters = 57,
}
}
@@ -1518,6 +1532,7 @@ mod benches {
[pallet_relay_storage_roots, RelayStorageRoots]
[pallet_precompile_benchmarks, PrecompileBenchmarks]
[pallet_moonbeam_lazy_migrations, MoonbeamLazyMigrations]
+ [pallet_parameters, Parameters]
);
}
diff --git a/runtime/moonbase/src/runtime_params.rs b/runtime/moonbase/src/runtime_params.rs
new file mode 100644
index 0000000000..4916cc27df
--- /dev/null
+++ b/runtime/moonbase/src/runtime_params.rs
@@ -0,0 +1,44 @@
+// Copyright 2024 Moonbeam Foundation.
+// This file is part of Moonbeam.
+
+// Moonbeam 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.
+
+// Moonbeam 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 Moonbeam. If not, see .
+
+//! Dynamic runtime parametes.
+use crate::Runtime;
+use frame_support::dynamic_params::{dynamic_pallet_params, dynamic_params};
+use sp_runtime::Perbill;
+
+#[dynamic_params(RuntimeParameters, pallet_parameters::Parameters::)]
+pub mod dynamic_params {
+ use super::*;
+ #[dynamic_pallet_params]
+ #[codec(index = 0)]
+ pub mod runtime_config {
+ // for fees, 80% are burned, 20% to the treasury
+ #[codec(index = 0)]
+ pub static FeesTreasuryProportion: Perbill = Perbill::from_percent(20);
+ }
+}
+
+#[cfg(feature = "runtime-benchmarks")]
+impl Default for RuntimeParameters {
+ fn default() -> Self {
+ RuntimeParameters::RuntimeConfig(
+ dynamic_params::runtime_config::Parameters::FeesTreasuryProportion(
+ dynamic_params::runtime_config::FeesTreasuryProportion,
+ Some(Perbill::from_percent(20)),
+ ),
+ )
+ }
+}
diff --git a/test/suites/dev/moonbase/test-parameters/test-parameters.ts b/test/suites/dev/moonbase/test-parameters/test-parameters.ts
new file mode 100644
index 0000000000..8ff2b8cd9a
--- /dev/null
+++ b/test/suites/dev/moonbase/test-parameters/test-parameters.ts
@@ -0,0 +1,87 @@
+import { describeSuite, DevModeContext, expect } from "@moonwall/cli";
+import "@moonbeam-network/api-augment";
+import { alith } from "@moonwall/util";
+
+const UNIT = 1_000_000_000_000_000_000n;
+
+const RUNTIME = "MoonbaseRuntime";
+const CRATE = "RuntimeParams";
+const ALL_PARAMS = "DynamicParams";
+
+function parameterType(context: DevModeContext, module: string, name: string, value: unknown) {
+ const paramWrapper = context
+ .polkadotJs()
+ .createType(`${RUNTIME}${CRATE}${ALL_PARAMS}${module}Parameters`, {
+ [name]: [null, value],
+ });
+
+ const runtimeParameter = context.polkadotJs().createType(`${RUNTIME}${CRATE}RuntimeParameters`, {
+ [module]: paramWrapper,
+ });
+
+ return runtimeParameter;
+}
+
+function parameterKey(context: DevModeContext, module: string, name: string) {
+ const key = context
+ .polkadotJs()
+ .createType(`${RUNTIME}${CRATE}${ALL_PARAMS}${module}ParametersKey`, {
+ [name]: null,
+ });
+
+ const keyWrapper = context.polkadotJs().createType(`${RUNTIME}${CRATE}RuntimeParametersKey`, {
+ [module]: key,
+ });
+
+ return keyWrapper;
+}
+
+describeSuite({
+ id: "DTemp01",
+ title: "Parameters",
+ foundationMethods: "dev",
+ testCases: ({ it, context, log }) => {
+ let testCounter = 0;
+ function testParam(module: string, name: string, valueCreation: [string, unknown]) {
+ it({
+ id: `T${testCounter++} - ${module} - ${name}`,
+ title: "Parameters cannot be changed by normal user",
+ test: async () => {
+ const value = context.polkadotJs().createType(valueCreation[0], valueCreation[1]);
+ const param = parameterType(context, module, name, value);
+
+ const res = await context.createBlock(
+ context.polkadotJs().tx.parameters.setParameter(param.toU8a()).signAsync(alith),
+ { allowFailures: true }
+ );
+ expect(res.result?.error?.name).toEqual("BadOrigin");
+ },
+ });
+
+ it({
+ id: `T${testCounter++} - ${module} - ${name}`,
+ title: "Parameters can be changed by root user",
+ test: async () => {
+ const value = context.polkadotJs().createType(valueCreation[0], valueCreation[1]);
+ const param = parameterType(context, module, name, value);
+
+ await context.createBlock(
+ context
+ .polkadotJs()
+ .tx.sudo.sudo(context.polkadotJs().tx.parameters.setParameter(param.toU8a()))
+ .signAsync(alith),
+ { allowFailures: false }
+ );
+
+ const key = parameterKey(context, module, name);
+
+ const wrappedValue = await context.polkadotJs().query.parameters.parameters(key.toU8a());
+ const gotValue = wrappedValue.value.value.value.toU8a();
+ expect(gotValue).toEqual(value.toU8a());
+ },
+ });
+ }
+
+ testParam("RuntimeConfig", "FeesTreasuryProportion", ["Perbill", 200_000_000]);
+ },
+});