diff --git a/substrate/bin/node/executor/tests/basic.rs b/substrate/bin/node/executor/tests/basic.rs
index 5b3d8f20e9df7186348739b528c6b6dff7c353dd..758ea1a32e8410644a6ee2bc26053f9242c65a39 100644
--- a/substrate/bin/node/executor/tests/basic.rs
+++ b/substrate/bin/node/executor/tests/basic.rs
@@ -18,7 +18,7 @@ use codec::{Encode, Decode, Joiner};
 use frame_support::{
 	StorageValue, StorageMap,
 	traits::Currency,
-	weights::{GetDispatchInfo, DispatchInfo, DispatchClass},
+	weights::{GetDispatchInfo, DispatchInfo, DispatchClass, Pays},
 };
 use sp_core::{
 	NeverNativeValue, map, traits::Externalities, storage::{well_known_keys, Storage},
@@ -338,7 +338,7 @@ fn full_native_block_import_works() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(0),
 				event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess(
-					DispatchInfo { weight: 10_000_000, class: DispatchClass::Mandatory, pays_fee: true }
+					DispatchInfo { weight: 10_000_000, class: DispatchClass::Mandatory, ..Default::default() }
 				)),
 				topics: vec![],
 			},
@@ -359,7 +359,7 @@ fn full_native_block_import_works() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(1),
 				event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess(
-					DispatchInfo { weight: 200_000_000, class: DispatchClass::Normal, pays_fee: true }
+					DispatchInfo { weight: 200_000_000, ..Default::default() }
 				)),
 				topics: vec![],
 			},
@@ -391,7 +391,7 @@ fn full_native_block_import_works() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(0),
 				event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess(
-					DispatchInfo { weight: 10_000_000, class: DispatchClass::Mandatory, pays_fee: true }
+					DispatchInfo { weight: 10_000_000, class: DispatchClass::Mandatory, pays_fee: Pays::Yes }
 				)),
 				topics: vec![],
 			},
@@ -414,7 +414,7 @@ fn full_native_block_import_works() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(1),
 				event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess(
-					DispatchInfo { weight: 200_000_000, class: DispatchClass::Normal, pays_fee: true }
+					DispatchInfo { weight: 200_000_000, ..Default::default() }
 				)),
 				topics: vec![],
 			},
@@ -437,7 +437,7 @@ fn full_native_block_import_works() {
 			EventRecord {
 				phase: Phase::ApplyExtrinsic(2),
 				event: Event::frame_system(frame_system::RawEvent::ExtrinsicSuccess(
-					DispatchInfo { weight: 200_000_000, class: DispatchClass::Normal, pays_fee: true }
+					DispatchInfo { weight: 200_000_000, ..Default::default() }
 				)),
 				topics: vec![],
 			},
diff --git a/substrate/frame/balances/src/tests.rs b/substrate/frame/balances/src/tests.rs
index 7ff7ec0fc45c55c95695a2505792f3255b10a848..7663b8922bc04efa32b1a6fefcc476590436c9c6 100644
--- a/substrate/frame/balances/src/tests.rs
+++ b/substrate/frame/balances/src/tests.rs
@@ -57,7 +57,7 @@ macro_rules! decl_tests {
 
 		/// create a transaction info struct from weight. Handy to avoid building the whole struct.
 		pub fn info_from_weight(w: Weight) -> DispatchInfo {
-			DispatchInfo { weight: w, pays_fee: true, ..Default::default() }
+			DispatchInfo { weight: w, ..Default::default() }
 		}
 
 		#[test]
diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs
index f7170e9172eb46b09e384b32668fa5351eaf8a8d..452a4517dbe6838aeedb8e03904887ffde5b7703 100644
--- a/substrate/frame/contracts/src/tests.rs
+++ b/substrate/frame/contracts/src/tests.rs
@@ -35,7 +35,7 @@ use sp_runtime::{
 use frame_support::{
 	assert_ok, assert_err, impl_outer_dispatch, impl_outer_event, impl_outer_origin, parameter_types,
 	storage::child, StorageMap, StorageValue, traits::{Currency, Get},
-	weights::{DispatchInfo, DispatchClass, Weight},
+	weights::{DispatchInfo, DispatchClass, Weight, Pays},
 };
 use std::{cell::RefCell, sync::atomic::{AtomicUsize, Ordering}};
 use sp_core::storage::well_known_keys;
@@ -1630,7 +1630,7 @@ fn cannot_self_destruct_in_constructor() {
 #[test]
 fn check_block_gas_limit_works() {
 	ExtBuilder::default().block_gas_limit(50).build().execute_with(|| {
-		let info = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: true };
+		let info = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes };
 		let check = CheckBlockGasLimit::<Test>(Default::default());
 		let call: Call = crate::Call::put_code(1000, vec![]).into();
 
diff --git a/substrate/frame/evm/src/lib.rs b/substrate/frame/evm/src/lib.rs
index 48946858dffb6b18d22b2fdf59154f57277add84..eec8bc69d74abf9e74e7e942fef05692ffb16209 100644
--- a/substrate/frame/evm/src/lib.rs
+++ b/substrate/frame/evm/src/lib.rs
@@ -25,7 +25,7 @@ pub use crate::backend::{Account, Log, Vicinity, Backend};
 
 use sp_std::{vec::Vec, marker::PhantomData};
 use frame_support::{ensure, decl_module, decl_storage, decl_event, decl_error};
-use frame_support::weights::{Weight, MINIMUM_WEIGHT, DispatchClass, FunctionOf};
+use frame_support::weights::{Weight, MINIMUM_WEIGHT, DispatchClass, FunctionOf, Pays};
 use frame_support::traits::{Currency, WithdrawReason, ExistenceRequirement};
 use frame_system::{self as system, ensure_signed};
 use sp_runtime::ModuleId;
@@ -235,7 +235,12 @@ decl_module! {
 		}
 
 		/// Issue an EVM call operation. This is similar to a message call transaction in Ethereum.
-		#[weight = FunctionOf(|(_, _, _, gas_limit, gas_price, _): (&H160, &Vec<u8>, &U256, &u32, &U256, &Option<U256>)| (*gas_price).saturated_into::<Weight>().saturating_mul(*gas_limit as Weight), DispatchClass::Normal, true)]
+		#[weight = FunctionOf(
+			|(_, _, _, gas_limit, gas_price, _): (&H160, &Vec<u8>, &U256, &u32, &U256, &Option<U256>)|
+				(*gas_price).saturated_into::<Weight>().saturating_mul(*gas_limit as Weight),
+			DispatchClass::Normal,
+			Pays::Yes,
+		)]
 		fn call(
 			origin,
 			target: H160,
@@ -266,7 +271,12 @@ decl_module! {
 
 		/// Issue an EVM create operation. This is similar to a contract creation transaction in
 		/// Ethereum.
-		#[weight = FunctionOf(|(_, _, gas_limit, gas_price, _): (&Vec<u8>, &U256, &u32, &U256, &Option<U256>)| (*gas_price).saturated_into::<Weight>().saturating_mul(*gas_limit as Weight), DispatchClass::Normal, true)]
+		#[weight = FunctionOf(
+			|(_, _, gas_limit, gas_price, _): (&Vec<u8>, &U256, &u32, &U256, &Option<U256>)|
+				(*gas_price).saturated_into::<Weight>().saturating_mul(*gas_limit as Weight),
+			DispatchClass::Normal,
+			Pays::Yes,
+		)]
 		fn create(
 			origin,
 			init: Vec<u8>,
@@ -301,7 +311,12 @@ decl_module! {
 		}
 
 		/// Issue an EVM create2 operation.
-		#[weight = FunctionOf(|(_, _, _, gas_limit, gas_price, _): (&Vec<u8>, &H256, &U256, &u32, &U256, &Option<U256>)| (*gas_price).saturated_into::<Weight>().saturating_mul(*gas_limit as Weight), DispatchClass::Normal, true)]
+		#[weight = FunctionOf(
+			|(_, _, _, gas_limit, gas_price, _): (&Vec<u8>, &H256, &U256, &u32, &U256, &Option<U256>)|
+				(*gas_price).saturated_into::<Weight>().saturating_mul(*gas_limit as Weight),
+			DispatchClass::Normal,
+			Pays::Yes,
+		)]
 		fn create2(
 			origin,
 			init: Vec<u8>,
diff --git a/substrate/frame/example/src/lib.rs b/substrate/frame/example/src/lib.rs
index e7a5a0c02e5ae6e1f93cd00845bf3bba01ade26e..cfc313ad49c8c38c7059828773cccd6145609a73 100644
--- a/substrate/frame/example/src/lib.rs
+++ b/substrate/frame/example/src/lib.rs
@@ -256,7 +256,7 @@
 use sp_std::marker::PhantomData;
 use frame_support::{
 	dispatch::DispatchResult, decl_module, decl_storage, decl_event,
-	weights::{DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, MINIMUM_WEIGHT},
+	weights::{DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, MINIMUM_WEIGHT, Pays},
 };
 use sp_std::prelude::*;
 use frame_system::{self as system, ensure_signed, ensure_root};
@@ -305,8 +305,8 @@ impl<T: pallet_balances::Trait> ClassifyDispatch<(&BalanceOf<T>,)> for WeightFor
 }
 
 impl<T: pallet_balances::Trait> PaysFee<(&BalanceOf<T>,)> for WeightForSetDummy<T> {
-	fn pays_fee(&self, _target: (&BalanceOf<T>,)) -> bool {
-		true
+	fn pays_fee(&self, _target: (&BalanceOf<T>,)) -> Pays {
+		Pays::Yes
 	}
 }
 
diff --git a/substrate/frame/recovery/src/lib.rs b/substrate/frame/recovery/src/lib.rs
index e0397cc1a5d462137e0cba05b8dd415ae7852826..213696e5fb55d25b8210ff33f80a375c01289871 100644
--- a/substrate/frame/recovery/src/lib.rs
+++ b/substrate/frame/recovery/src/lib.rs
@@ -159,7 +159,7 @@ use codec::{Encode, Decode};
 
 use frame_support::{
 	decl_module, decl_event, decl_storage, decl_error, ensure,
-	Parameter, RuntimeDebug, weights::{MINIMUM_WEIGHT, GetDispatchInfo, FunctionOf},
+	Parameter, RuntimeDebug, weights::{MINIMUM_WEIGHT, GetDispatchInfo, FunctionOf, Pays},
 	traits::{Currency, ReservableCurrency, Get, BalanceStatus},
 	dispatch::PostDispatchInfo,
 };
@@ -338,7 +338,7 @@ decl_module! {
 		#[weight = FunctionOf(
 			|args: (&T::AccountId, &Box<<T as Trait>::Call>)| args.1.get_dispatch_info().weight + 10_000,
 			|args: (&T::AccountId, &Box<<T as Trait>::Call>)| args.1.get_dispatch_info().class,
-			true
+			Pays::Yes,
 		)]
 		fn as_recovered(origin,
 			account: T::AccountId,
diff --git a/substrate/frame/scheduler/src/lib.rs b/substrate/frame/scheduler/src/lib.rs
index 3e53b7a505b1e19ea5c314b5d46961029e761a91..1ff8a7ad795371e0891144a7934c83348740ce5d 100644
--- a/substrate/frame/scheduler/src/lib.rs
+++ b/substrate/frame/scheduler/src/lib.rs
@@ -250,7 +250,7 @@ mod tests {
 	use frame_support::{
 		impl_outer_event, impl_outer_origin, impl_outer_dispatch, parameter_types, assert_ok,
 		traits::{OnInitialize, OnFinalize, schedule::{Anon, Named}},
-		weights::{DispatchClass, FunctionOf}
+		weights::{DispatchClass, FunctionOf, Pays}
 	};
 	use sp_core::H256;
 	// The testing primitives are very useful for avoiding having to work with signatures
@@ -293,7 +293,7 @@ mod tests {
 				#[weight = FunctionOf(
 					|args: (&u32, &Weight)| *args.1,
 					|_: (&u32, &Weight)| DispatchClass::Normal,
-					true
+					Pays::Yes,
 				)]
 				fn log(origin, i: u32, weight: Weight) {
 					ensure_root(origin)?;
diff --git a/substrate/frame/sudo/src/lib.rs b/substrate/frame/sudo/src/lib.rs
index ce0de2027c7138c78a27283a8e9582a7ed8ba15d..edbdc5b8e0502ee8a8495117e82c7aa030fb80ab 100644
--- a/substrate/frame/sudo/src/lib.rs
+++ b/substrate/frame/sudo/src/lib.rs
@@ -93,7 +93,7 @@ use sp_runtime::traits::{StaticLookup, Dispatchable};
 use frame_support::{
 	Parameter, decl_module, decl_event, decl_storage, decl_error, ensure,
 };
-use frame_support::weights::{MINIMUM_WEIGHT, GetDispatchInfo, FunctionOf};
+use frame_support::weights::{MINIMUM_WEIGHT, GetDispatchInfo, FunctionOf, Pays};
 use frame_system::{self as system, ensure_signed};
 
 pub trait Trait: frame_system::Trait {
@@ -124,7 +124,7 @@ decl_module! {
 		#[weight = FunctionOf(
 			|args: (&Box<<T as Trait>::Call>,)| args.0.get_dispatch_info().weight + 10_000,
 			|args: (&Box<<T as Trait>::Call>,)| args.0.get_dispatch_info().class,
-			true
+			Pays::Yes,
 		)]
 		fn sudo(origin, call: Box<<T as Trait>::Call>) {
 			// This is a public call, so we ensure that the origin is some signed account.
@@ -180,7 +180,7 @@ decl_module! {
 			|args: (&<T::Lookup as StaticLookup>::Source, &Box<<T as Trait>::Call>,)| {
 				args.1.get_dispatch_info().class
 			},
-			true
+			Pays::Yes,
 		)]
 		fn sudo_as(origin, who: <T::Lookup as StaticLookup>::Source, call: Box<<T as Trait>::Call>) {
 			// This is a public call, so we ensure that the origin is some signed account.
diff --git a/substrate/frame/support/src/dispatch.rs b/substrate/frame/support/src/dispatch.rs
index e25efec0a91bd882362e568043fab84995df5729..6d3027dbd72fbe7c36e9dae5c682a7c69b03d47b 100644
--- a/substrate/frame/support/src/dispatch.rs
+++ b/substrate/frame/support/src/dispatch.rs
@@ -2045,7 +2045,7 @@ macro_rules! __check_reserved_fn_name {
 #[allow(dead_code)]
 mod tests {
 	use super::*;
-	use crate::weights::{MINIMUM_WEIGHT, DispatchInfo, DispatchClass};
+	use crate::weights::{MINIMUM_WEIGHT, DispatchInfo, DispatchClass, Pays};
 	use crate::traits::{
 		CallMetadata, GetCallMetadata, GetCallName, OnInitialize, OnFinalize, OnRuntimeUpgrade
 	};
@@ -2248,12 +2248,12 @@ mod tests {
 		// operational.
 		assert_eq!(
 			Call::<TraitImpl>::operational().get_dispatch_info(),
-			DispatchInfo { weight: 5, class: DispatchClass::Operational, pays_fee: true },
+			DispatchInfo { weight: 5, class: DispatchClass::Operational, pays_fee: Pays::Yes },
 		);
 		// custom basic
 		assert_eq!(
 			Call::<TraitImpl>::aux_3().get_dispatch_info(),
-			DispatchInfo { weight: 3, class: DispatchClass::Normal, pays_fee: true },
+			DispatchInfo { weight: 3, class: DispatchClass::Normal, pays_fee: Pays::Yes },
 		);
 	}
 
diff --git a/substrate/frame/support/src/weights.rs b/substrate/frame/support/src/weights.rs
index 6cf2047cf6c27e81924ab1ec533a723f605529ff..cffb4f83a4a948938b87095828bdd8d11ec0ad3e 100644
--- a/substrate/frame/support/src/weights.rs
+++ b/substrate/frame/support/src/weights.rs
@@ -35,7 +35,7 @@
 //! configuration:
 //!
 //! 1. Define only weight, **in which case `ClassifyDispatch` will be `Normal` and `PaysFee` will be
-//!    `true`**.
+//!    `Yes`**.
 //!
 //! ```
 //! # use frame_system::{self as system, Trait};
@@ -48,7 +48,7 @@
 //! # fn main() {}
 //! ```
 //!
-//! 2. Define weight and class, **in which case `PaysFee` would be `true`**.
+//! 2.1 Define weight and class, **in which case `PaysFee` would be `Yes`**.
 //!
 //! ```
 //! # use frame_system::{self as system, Trait};
@@ -62,14 +62,28 @@
 //! # fn main() {}
 //! ```
 //!
+//! 2.2 Define weight and `PaysFee`, **in which case `ClassifyDispatch` would be `Normal`**.
+//!
+//! ```
+//! # use frame_system::{self as system, Trait};
+//! # use frame_support::weights::Pays;
+//! frame_support::decl_module! {
+//!     pub struct Module<T: Trait> for enum Call where origin: T::Origin {
+//!         #[weight = (1000, Pays::No)]
+//!         fn dispatching(origin) { unimplemented!() }
+//!     }
+//! }
+//! # fn main() {}
+//! ```
+//!
 //! 3. Define all 3 parameters.
 //!
 //! ```
 //! # use frame_system::{self as system, Trait};
-//! # use frame_support::weights::DispatchClass;
+//! # use frame_support::weights::{DispatchClass, Pays};
 //! frame_support::decl_module! {
 //!     pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-//!         #[weight = (1000, DispatchClass::Operational, false)]
+//!         #[weight = (1000, DispatchClass::Operational, Pays::No)]
 //!         fn dispatching(origin) { unimplemented!() }
 //!     }
 //! }
@@ -86,7 +100,7 @@
 //!
 //! ```
 //! # use frame_system::{self as system, Trait};
-//! # use frame_support::weights::{DispatchClass, FunctionOf};
+//! # use frame_support::weights::{DispatchClass, FunctionOf, Pays};
 //! frame_support::decl_module! {
 //!     pub struct Module<T: Trait> for enum Call where origin: T::Origin {
 //!         #[weight = FunctionOf(
@@ -95,7 +109,7 @@
 //! 			// class, fixed.
 //! 			DispatchClass::Operational,
 //! 			// pays fee, function.
-//! 			|args: (&u32, &u64)| *args.0 > 1000,
+//! 			|args: (&u32, &u64)| if *args.0 > 1000 { Pays::Yes } else { Pays::No },
 //! 		)]
 //!         fn dispatching(origin, a: u32, b: u64) { unimplemented!() }
 //!     }
@@ -146,10 +160,23 @@ pub trait ClassifyDispatch<T> {
 }
 
 /// Indicates if dispatch function should pay fees or not.
-/// If set to false, the block resource limits are applied, yet no fee is deducted.
+/// If set to `Pays::No`, the block resource limits are applied, yet no fee is deducted.
 pub trait PaysFee<T> {
-	fn pays_fee(&self, _target: T) -> bool {
-		true
+	fn pays_fee(&self, _target: T) -> Pays;
+}
+
+/// Explicit enum to denote if a transaction pays fee or not.
+#[derive(Clone, Copy, Eq, PartialEq, RuntimeDebug, Encode, Decode)]
+pub enum Pays {
+	/// Transactor will pay related fees.
+	Yes,
+	/// Transactor will NOT pay related fees.
+	No,
+}
+
+impl Default for Pays {
+	fn default() -> Self {
+		Self::Yes
 	}
 }
 
@@ -191,7 +218,7 @@ pub struct DispatchInfo {
 	/// Class of this transaction.
 	pub class: DispatchClass,
 	/// Does this transaction pay fees.
-	pub pays_fee: bool,
+	pub pays_fee: Pays,
 }
 
 /// A `Dispatchable` function (aka transaction) that can carry some static information along with
@@ -289,25 +316,25 @@ impl<T> ClassifyDispatch<T> for Weight {
 }
 
 impl<T> PaysFee<T> for Weight {
-	fn pays_fee(&self, _: T) -> bool {
-		true
+	fn pays_fee(&self, _: T) -> Pays {
+		Pays::Yes
 	}
 }
 
-impl<T> WeighData<T> for (Weight, DispatchClass, bool) {
+impl<T> WeighData<T> for (Weight, DispatchClass, Pays) {
 	fn weigh_data(&self, _: T) -> Weight {
 		return self.0
 	}
 }
 
-impl<T> ClassifyDispatch<T> for (Weight, DispatchClass, bool) {
+impl<T> ClassifyDispatch<T> for (Weight, DispatchClass, Pays) {
 	fn classify_dispatch(&self, _: T) -> DispatchClass {
 		self.1
 	}
 }
 
-impl<T> PaysFee<T> for (Weight, DispatchClass, bool) {
-	fn pays_fee(&self, _: T) -> bool {
+impl<T> PaysFee<T> for (Weight, DispatchClass, Pays) {
+	fn pays_fee(&self, _: T) -> Pays {
 		self.2
 	}
 }
@@ -325,25 +352,25 @@ impl<T> ClassifyDispatch<T> for (Weight, DispatchClass) {
 }
 
 impl<T> PaysFee<T> for (Weight, DispatchClass) {
-	fn pays_fee(&self, _: T) -> bool {
-		true
+	fn pays_fee(&self, _: T) -> Pays {
+		Pays::Yes
 	}
 }
 
-impl<T> WeighData<T> for (Weight, bool) {
+impl<T> WeighData<T> for (Weight, Pays) {
 	fn weigh_data(&self, _: T) -> Weight {
 		return self.0
 	}
 }
 
-impl<T> ClassifyDispatch<T> for (Weight, bool) {
+impl<T> ClassifyDispatch<T> for (Weight, Pays) {
 	fn classify_dispatch(&self, _: T) -> DispatchClass {
 		DispatchClass::Normal
 	}
 }
 
-impl<T> PaysFee<T> for (Weight, bool) {
-	fn pays_fee(&self, _: T) -> bool {
+impl<T> PaysFee<T> for (Weight, Pays) {
+	fn pays_fee(&self, _: T) -> Pays {
 		self.1
 	}
 }
@@ -355,8 +382,8 @@ impl<T> PaysFee<T> for (Weight, bool) {
 ///   argument list as the dispatched, wrapped in a tuple.
 /// - `CD`: a raw `DispatchClass` value or a closure that returns a `DispatchClass`
 ///   with the same argument list as the dispatched, wrapped in a tuple.
-/// - `PF`: a `bool` for whether this dispatch pays fee or not or a closure that
-///   returns a bool with the same argument list as the dispatched, wrapped in a tuple.
+/// - `PF`: a `Pays` variant for whether this dispatch pays fee or not or a closure that
+///   returns a `Pays` variant with the same argument list as the dispatched, wrapped in a tuple.
 pub struct FunctionOf<WD, CD, PF>(pub WD, pub CD, pub PF);
 
 // `WeighData` as a raw value
@@ -392,17 +419,17 @@ impl<Args, WD, CD, PF> ClassifyDispatch<Args> for FunctionOf<WD, CD, PF> where
 }
 
 // `PaysFee` as a raw value
-impl<Args, WD, CD> PaysFee<Args> for FunctionOf<WD, CD, bool> {
-	fn pays_fee(&self, _: Args) -> bool {
+impl<Args, WD, CD> PaysFee<Args> for FunctionOf<WD, CD, Pays> {
+	fn pays_fee(&self, _: Args) -> Pays {
 		self.2
 	}
 }
 
 // `PaysFee` as a closure
 impl<Args, WD, CD, PF> PaysFee<Args> for FunctionOf<WD, CD, PF> where
-	PF : Fn(Args) -> bool
+	PF : Fn(Args) -> Pays
 {
-	fn pays_fee(&self, args: Args) -> bool {
+	fn pays_fee(&self, args: Args) -> Pays {
 		(self.2)(args)
 	}
 }
@@ -437,7 +464,7 @@ impl<Call: Encode, Extra: Encode> GetDispatchInfo for sp_runtime::testing::TestX
 		// for testing: weight == size.
 		DispatchInfo {
 			weight: self.encode().len() as _,
-			pays_fee: true,
+			pays_fee: Pays::Yes,
 			..Default::default()
 		}
 	}
@@ -504,14 +531,17 @@ mod tests {
 			#[weight = (1000, DispatchClass::Mandatory)]
 			fn f01(_origin) { unimplemented!(); }
 
-			#[weight = (1000, DispatchClass::Operational, false)]
+			#[weight = (1000, Pays::No)]
 			fn f02(_origin) { unimplemented!(); }
 
+			#[weight = (1000, DispatchClass::Operational, Pays::No)]
+			fn f03(_origin) { unimplemented!(); }
+
 			// weight = a x 10 + b
-			#[weight = FunctionOf(|args: (&u32, &u32)| (args.0 * 10 + args.1) as Weight, DispatchClass::Normal, true)]
+			#[weight = FunctionOf(|args: (&u32, &u32)| (args.0 * 10 + args.1) as Weight, DispatchClass::Normal, Pays::Yes)]
 			fn f11(_origin, _a: u32, _eb: u32) { unimplemented!(); }
 
-			#[weight = FunctionOf(|_: (&u32, &u32)| 0, DispatchClass::Operational, true)]
+			#[weight = FunctionOf(|_: (&u32, &u32)| 0, DispatchClass::Operational, Pays::Yes)]
 			fn f12(_origin, _a: u32, _eb: u32) { unimplemented!(); }
 
 			#[weight = T::DbWeight::get().reads(3) + T::DbWeight::get().writes(2) + 10_000]
@@ -529,19 +559,25 @@ mod tests {
 		let info = Call::<TraitImpl>::f00().get_dispatch_info();
 		assert_eq!(info.weight, 1000);
 		assert_eq!(info.class, DispatchClass::Normal);
-		assert_eq!(info.pays_fee, true);
+		assert_eq!(info.pays_fee, Pays::Yes);
 
 		// #[weight = (1000, DispatchClass::Mandatory)]
 		let info = Call::<TraitImpl>::f01().get_dispatch_info();
 		assert_eq!(info.weight, 1000);
 		assert_eq!(info.class, DispatchClass::Mandatory);
-		assert_eq!(info.pays_fee, true);
+		assert_eq!(info.pays_fee, Pays::Yes);
 
-		// #[weight = (1000, DispatchClass::Operational, false)]
+		// #[weight = (1000, Pays::No)]
 		let info = Call::<TraitImpl>::f02().get_dispatch_info();
 		assert_eq!(info.weight, 1000);
+		assert_eq!(info.class, DispatchClass::Normal);
+		assert_eq!(info.pays_fee, Pays::No);
+
+		// #[weight = (1000, DispatchClass::Operational, Pays::No)]
+		let info = Call::<TraitImpl>::f03().get_dispatch_info();
+		assert_eq!(info.weight, 1000);
 		assert_eq!(info.class, DispatchClass::Operational);
-		assert_eq!(info.pays_fee, false);
+		assert_eq!(info.pays_fee, Pays::No);
 
 		assert_eq!(Call::<TraitImpl>::f11(10, 20).get_dispatch_info().weight, 120);
 		assert_eq!(Call::<TraitImpl>::f11(10, 20).get_dispatch_info().class, DispatchClass::Normal);
diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs
index 115b681adc6bfc47951cd88ad6843894d36f3ada..d9b8b681087ba1dbbb7ae9a2d8a01841e712e2b3 100644
--- a/substrate/frame/system/src/lib.rs
+++ b/substrate/frame/system/src/lib.rs
@@ -120,7 +120,10 @@ use frame_support::{
 		Contains, Get, ModuleToIndex, OnNewAccount, OnKilledAccount, IsDeadAccount, Happened,
 		StoredMap, EnsureOrigin,
 	},
-	weights::{Weight, MINIMUM_WEIGHT, RuntimeDbWeight, DispatchInfo, PostDispatchInfo, DispatchClass, FunctionOf}
+	weights::{
+		Weight, MINIMUM_WEIGHT, RuntimeDbWeight, DispatchInfo, PostDispatchInfo, DispatchClass,
+		FunctionOf, Pays,
+	}
 };
 use codec::{Encode, Decode, FullCodec, EncodeLike};
 
@@ -472,13 +475,19 @@ decl_module! {
 	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
 		type Error = Error<T>;
 
+		/// The maximum weight of a block.
+		const MaximumBlockWeight: Weight = T::MaximumBlockWeight::get();
+
+		/// The maximum length of a block (in bytes).
+		const MaximumBlockLength: u32 = T::MaximumBlockLength::get();
+
 		/// A dispatch that will fill the block weight up to the given ratio.
 		// TODO: This should only be available for testing, rather than in general usage, but
 		// that's not possible at present (since it's within the decl_module macro).
 		#[weight = FunctionOf(
 			|(ratio,): (&Perbill,)| *ratio * T::MaximumBlockWeight::get(),
 			DispatchClass::Operational,
-			true,
+			Pays::Yes,
 		)]
 		fn fill_block(origin, _ratio: Perbill) {
 			ensure_root(origin)?;
@@ -1990,7 +1999,7 @@ pub(crate) mod tests {
 	fn signed_ext_check_weight_works_operational_tx() {
 		new_test_ext().execute_with(|| {
 			let normal = DispatchInfo { weight: 100, ..Default::default() };
-			let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: true };
+			let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: Pays::Yes };
 			let len = 0_usize;
 			let normal_limit = normal_weight_limit();
 
@@ -2012,8 +2021,8 @@ pub(crate) mod tests {
 	#[test]
 	fn signed_ext_check_weight_priority_works() {
 		new_test_ext().execute_with(|| {
-			let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: true };
-			let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: true };
+			let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes };
+			let op = DispatchInfo { weight: 100, class: DispatchClass::Operational, pays_fee: Pays::Yes };
 			let len = 0_usize;
 
 			let priority = CheckWeight::<Test>(PhantomData)
@@ -2046,7 +2055,7 @@ pub(crate) mod tests {
 			reset_check_weight(&normal, normal_limit + 1, true);
 
 			// Operational ones don't have this limit.
-			let op = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: true };
+			let op = DispatchInfo { weight: 0, class: DispatchClass::Operational, pays_fee: Pays::Yes };
 			reset_check_weight(&op, normal_limit, false);
 			reset_check_weight(&op, normal_limit + 100, false);
 			reset_check_weight(&op, 1024, false);
@@ -2073,7 +2082,7 @@ pub(crate) mod tests {
 	#[test]
 	fn signed_ext_check_era_should_change_longevity() {
 		new_test_ext().execute_with(|| {
-			let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: true };
+			let normal = DispatchInfo { weight: 100, class: DispatchClass::Normal, pays_fee: Pays::Yes };
 			let len = 0_usize;
 			let ext = (
 				CheckWeight::<Test>(PhantomData),
diff --git a/substrate/frame/transaction-payment/src/lib.rs b/substrate/frame/transaction-payment/src/lib.rs
index 75809e0ed6cabc52244e0a9f653dbb0ba696eb6e..95845990b8e43b017d4aa680908025ef836a6394 100644
--- a/substrate/frame/transaction-payment/src/lib.rs
+++ b/substrate/frame/transaction-payment/src/lib.rs
@@ -36,7 +36,7 @@ use codec::{Encode, Decode};
 use frame_support::{
 	decl_storage, decl_module,
 	traits::{Currency, Get, OnUnbalanced, ExistenceRequirement, WithdrawReason, Imbalance},
-	weights::{Weight, DispatchInfo, PostDispatchInfo, GetDispatchInfo},
+	weights::{Weight, DispatchInfo, PostDispatchInfo, GetDispatchInfo, Pays},
 	dispatch::DispatchResult,
 };
 use sp_runtime::{
@@ -166,7 +166,7 @@ impl<T: Trait> Module<T> where
 		info: &DispatchInfoOf<T::Call>,
 		tip: BalanceOf<T>,
 	) -> BalanceOf<T> {
-		if info.pays_fee {
+		if info.pays_fee == Pays::Yes {
 			let len = <BalanceOf<T>>::from(len);
 			let per_byte = T::TransactionByteFee::get();
 			let len_fee = per_byte.saturating_mul(len);
@@ -505,7 +505,8 @@ mod tests {
 
 	/// create a transaction info struct from weight. Handy to avoid building the whole struct.
 	pub fn info_from_weight(w: Weight) -> DispatchInfo {
-		DispatchInfo { weight: w, pays_fee: true, ..Default::default() }
+		// pays: yes -- class: normal
+		DispatchInfo { weight: w, ..Default::default() }
 	}
 
 	fn post_info_from_weight(w: Weight) -> PostDispatchInfo {
@@ -565,7 +566,7 @@ mod tests {
 			let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
 				.pre_dispatch(&2, CALL, &info_from_weight(100), len)
 				.unwrap();
-			// 5 base fee, 3/2 * 10 byte fee, 3/2 * 100 weight fee, 5 tip 
+			// 5 base fee, 3/2 * 10 byte fee, 3/2 * 100 weight fee, 5 tip
 			assert_eq!(Balances::free_balance(2), 200 - 5 - 15 - 150 - 5);
 
 			assert!(
@@ -617,7 +618,7 @@ mod tests {
 			let operational_transaction = DispatchInfo {
 				weight: 0,
 				class: DispatchClass::Operational,
-				pays_fee: false,
+				pays_fee: Pays::No,
 			};
 			assert!(
 				ChargeTransactionPayment::<Runtime>::from(0)
@@ -629,7 +630,7 @@ mod tests {
 			let free_transaction = DispatchInfo {
 				weight: 0,
 				class: DispatchClass::Normal,
-				pays_fee: true,
+				pays_fee: Pays::Yes,
 			};
 			assert!(
 				ChargeTransactionPayment::<Runtime>::from(0)
@@ -711,14 +712,14 @@ mod tests {
 			let dispatch_info = DispatchInfo {
 				weight: 0,
 				class: DispatchClass::Operational,
-				pays_fee: false,
+				pays_fee: Pays::No,
 			};
 			assert_eq!(Module::<Runtime>::compute_fee(0, &dispatch_info, 10), 10);
 			// No tip, only base fee works
 			let dispatch_info = DispatchInfo {
 				weight: 0,
 				class: DispatchClass::Operational,
-				pays_fee: true,
+				pays_fee: Pays::Yes,
 			};
 			assert_eq!(Module::<Runtime>::compute_fee(0, &dispatch_info, 0), 100);
 			// Tip + base fee works
@@ -729,7 +730,7 @@ mod tests {
 			let dispatch_info = DispatchInfo {
 				weight: 1000,
 				class: DispatchClass::Operational,
-				pays_fee: true,
+				pays_fee: Pays::Yes,
 			};
 			assert_eq!(Module::<Runtime>::compute_fee(0, &dispatch_info, 0), 1100);
 		});
@@ -750,7 +751,7 @@ mod tests {
 			let dispatch_info = DispatchInfo {
 				weight: 0,
 				class: DispatchClass::Operational,
-				pays_fee: true,
+				pays_fee: Pays::Yes,
 			};
 			assert_eq!(Module::<Runtime>::compute_fee(0, &dispatch_info, 0), 100);
 
@@ -758,7 +759,7 @@ mod tests {
 			let dispatch_info = DispatchInfo {
 				weight: 123,
 				class: DispatchClass::Operational,
-				pays_fee: true,
+				pays_fee: Pays::Yes,
 			};
 			// 123 weight, 456 length, 100 base
 			// adjustable fee = (123 * 1) + (456 * 10) = 4683
@@ -781,7 +782,7 @@ mod tests {
 			let dispatch_info = DispatchInfo {
 				weight: Weight::max_value(),
 				class: DispatchClass::Operational,
-				pays_fee: true,
+				pays_fee: Pays::Yes,
 			};
 			assert_eq!(
 				Module::<Runtime>::compute_fee(
diff --git a/substrate/frame/utility/src/lib.rs b/substrate/frame/utility/src/lib.rs
index 4a1c36b5ad2d6c909f3bd763d82d2707cf017a2f..0ad35c3e283772c7e67fa8cabb49e3baee085525 100644
--- a/substrate/frame/utility/src/lib.rs
+++ b/substrate/frame/utility/src/lib.rs
@@ -67,7 +67,7 @@ use sp_core::TypeId;
 use sp_io::hashing::blake2_256;
 use frame_support::{decl_module, decl_event, decl_error, decl_storage, Parameter, ensure, RuntimeDebug};
 use frame_support::{traits::{Get, ReservableCurrency, Currency},
-	weights::{Weight, GetDispatchInfo, DispatchClass, FunctionOf},
+	weights::{Weight, GetDispatchInfo, DispatchClass, FunctionOf, Pays},
 	dispatch::PostDispatchInfo,
 };
 use frame_system::{self as system, ensure_signed};
@@ -242,7 +242,7 @@ decl_module! {
 					DispatchClass::Normal
 				}
 			},
-			true
+			Pays::Yes,
 		)]
 		fn batch(origin, calls: Vec<<T as Trait>::Call>) {
 			for (index, call) in calls.into_iter().enumerate() {
@@ -265,7 +265,7 @@ decl_module! {
 		#[weight = FunctionOf(
 			|args: (&u16, &Box<<T as Trait>::Call>)| args.1.get_dispatch_info().weight + 10_000,
 			|args: (&u16, &Box<<T as Trait>::Call>)| args.1.get_dispatch_info().class,
-			true
+			Pays::Yes,
 		)]
 		fn as_sub(origin, index: u16, call: Box<<T as Trait>::Call>) -> DispatchResult {
 			let who = ensure_signed(origin)?;
@@ -322,7 +322,7 @@ decl_module! {
 			|args: (&u16, &Vec<T::AccountId>, &Option<Timepoint<T::BlockNumber>>, &Box<<T as Trait>::Call>)| {
 				args.3.get_dispatch_info().class
 			},
-			true
+			Pays::Yes,
 		)]
 		fn as_multi(origin,
 			threshold: u16,
@@ -421,7 +421,7 @@ decl_module! {
 				10_000 * (args.1.len() as Weight + 1)
 			},
 			DispatchClass::Normal,
-			true
+			Pays::Yes,
 		)]
 		fn approve_as_multi(origin,
 			threshold: u16,
@@ -496,7 +496,7 @@ decl_module! {
 				10_000 * (args.1.len() as Weight + 1)
 			},
 			DispatchClass::Normal,
-			true
+			Pays::Yes,
 		)]
 		fn cancel_as_multi(origin,
 			threshold: u16,