From bb8ddc46c1e3dcc6f30340b39c1fdb2d07472041 Mon Sep 17 00:00:00 2001
From: Branislav Kontur <bkontur@gmail.com>
Date: Wed, 31 Jan 2024 07:19:16 +0100
Subject: [PATCH] [frame] `#[pallet::composite_enum]` improved variant count
 handling + removed `pallet_balances`'s `MaxHolds` config (#2657)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

I started this investigation/issue based on @liamaharon question
[here](https://github.com/paritytech/polkadot-sdk/pull/1801#discussion_r1410452499).

## Problem

The `pallet_balances` integrity test should correctly detect that the
runtime has correct distinct `HoldReasons` variant count. I assume the
same situation exists for RuntimeFreezeReason.

It is not a critical problem, if we set `MaxHolds` with a sufficiently
large value, everything should be ok. However, in this case, the
integrity_test check becomes less useful.

**Situation for "any" runtime:**
- `HoldReason` enums from different pallets:
```rust
        /// from pallet_nis
        #[pallet::composite_enum]
	pub enum HoldReason {
		NftReceipt,
	}

        /// from pallet_preimage
        #[pallet::composite_enum]
	pub enum HoldReason {
		Preimage,
	}

        // from pallet_state-trie-migration
        #[pallet::composite_enum]
	pub enum HoldReason {
		SlashForContinueMigrate,
		SlashForMigrateCustomTop,
		SlashForMigrateCustomChild,
	}
```

- generated `RuntimeHoldReason` enum looks like:
```rust
pub enum RuntimeHoldReason {

    #[codec(index = 32u8)]
    Preimage(pallet_preimage::HoldReason),

    #[codec(index = 38u8)]
    Nis(pallet_nis::HoldReason),

    #[codec(index = 42u8)]
    StateTrieMigration(pallet_state_trie_migration::HoldReason),
}
```

- composite enum `RuntimeHoldReason` variant count is detected as `3`
- we set `type MaxHolds = ConstU32<3>`
- `pallet_balances::integrity_test` is ok with `3`(at least 3)

However, the real problem can occur in a live runtime where some
functionality might stop working. This is due to a total of 5 distinct
hold reasons (for pallets with multi-instance support, it is even more),
and not all of them can be used because of an incorrect `MaxHolds`,
which is deemed acceptable according to the `integrity_test`:
  ```
  // pseudo-code - if we try to call all of these:

T::Currency::hold(&pallet_nis::HoldReason::NftReceipt.into(),
&nft_owner, deposit)?;
T::Currency::hold(&pallet_preimage::HoldReason::Preimage.into(),
&nft_owner, deposit)?;

T::Currency::hold(&pallet_state_trie_migration::HoldReason::SlashForContinueMigrate.into(),
&nft_owner, deposit)?;

  // With `type MaxHolds = ConstU32<3>` these two will fail

T::Currency::hold(&pallet_state_trie_migration::HoldReason::SlashForMigrateCustomTop.into(),
&nft_owner, deposit)?;

T::Currency::hold(&pallet_state_trie_migration::HoldReason::SlashForMigrateCustomChild.into(),
&nft_owner, deposit)?;
  ```


## Solutions

A macro `#[pallet::*]` expansion is extended of `VariantCount`
implementation for the `#[pallet::composite_enum]` enum type. This
expansion generates the `VariantCount` implementation for pallets'
`HoldReason`, `FreezeReason`, `LockId`, and `SlashReason`. Enum variants
must be plain enum values without fields to ensure a deterministic
count.

The composite runtime enum, `RuntimeHoldReason` and
`RuntimeFreezeReason`, now sets `VariantCount::VARIANT_COUNT` as the sum
of pallets' enum `VariantCount::VARIANT_COUNT`:
```rust
#[frame_support::pallet(dev_mode)]
mod module_single_instance {

	#[pallet::composite_enum]
	pub enum HoldReason {
		ModuleSingleInstanceReason1,
		ModuleSingleInstanceReason2,
	}
...
}

#[frame_support::pallet(dev_mode)]
mod module_multi_instance {

	#[pallet::composite_enum]
	pub enum HoldReason<I: 'static = ()> {
		ModuleMultiInstanceReason1,
		ModuleMultiInstanceReason2,
		ModuleMultiInstanceReason3,
	}
...
}


impl self::sp_api_hidden_includes_construct_runtime::hidden_include::traits::VariantCount
    for RuntimeHoldReason
{
    const VARIANT_COUNT: u32 = 0
        + module_single_instance::HoldReason::VARIANT_COUNT
        + module_multi_instance::HoldReason::<module_multi_instance::Instance1>::VARIANT_COUNT
        + module_multi_instance::HoldReason::<module_multi_instance::Instance2>::VARIANT_COUNT
        + module_multi_instance::HoldReason::<module_multi_instance::Instance3>::VARIANT_COUNT;
}
```

In addition, `MaxHolds` is removed (as suggested
[here](https://github.com/paritytech/polkadot-sdk/pull/2657#discussion_r1443324573))
from `pallet_balances`, and its `Holds` are now bounded to
`RuntimeHoldReason::VARIANT_COUNT`. Therefore, there is no need to let
the runtime specify `MaxHolds`.


## For reviewers

Relevant changes can be found here:
- `substrate/frame/support/procedural/src/lib.rs`
-  `substrate/frame/support/procedural/src/pallet/parse/composite.rs`
-  `substrate/frame/support/procedural/src/pallet/expand/composite.rs`
-
`substrate/frame/support/procedural/src/construct_runtime/expand/composite_helper.rs`
-
`substrate/frame/support/procedural/src/construct_runtime/expand/hold_reason.rs`
-
`substrate/frame/support/procedural/src/construct_runtime/expand/freeze_reason.rs`
- `substrate/frame/support/src/traits/misc.rs`

And the rest of the files is just about removed `MaxHolds` from
`pallet_balances`

## Next steps

Do the same for `MaxFreezes`
https://github.com/paritytech/polkadot-sdk/issues/2997.

---------

Co-authored-by: command-bot <>
Co-authored-by: Bastian Köcher <git@kchr.de>
Co-authored-by: Dónal Murray <donal.murray@parity.io>
Co-authored-by: gupnik <nikhilgupta.iitk@gmail.com>
---
 .../pallets/inbound-queue/src/mock.rs         |   1 -
 .../parachain/pallets/system/src/mock.rs      |   1 -
 .../pallets/collator-selection/src/mock.rs    |   1 -
 cumulus/pallets/xcmp-queue/src/mock.rs        |   1 -
 cumulus/parachain-template/runtime/src/lib.rs |   1 -
 cumulus/parachains/common/src/impls.rs        |   1 -
 .../assets/asset-hub-rococo/src/lib.rs        |   4 -
 .../src/weights/pallet_balances.rs            |  46 +--
 .../assets/asset-hub-westend/src/lib.rs       |   3 -
 .../src/weights/pallet_balances.rs            |  46 +--
 .../bridge-hubs/bridge-hub-rococo/src/lib.rs  |   1 -
 .../src/weights/pallet_balances.rs            |  44 +--
 .../bridge-hubs/bridge-hub-westend/src/lib.rs |   1 -
 .../src/weights/pallet_balances.rs            |  46 +--
 .../collectives-westend/src/lib.rs            |   1 -
 .../src/weights/pallet_balances.rs            |  46 +--
 .../contracts/contracts-rococo/src/lib.rs     |   1 -
 .../coretime/coretime-rococo/src/lib.rs       |   1 -
 .../src/weights/pallet_balances.rs            |  46 +--
 .../coretime/coretime-westend/src/lib.rs      |   1 -
 .../src/weights/pallet_balances.rs            |  46 +--
 .../runtimes/people/people-rococo/src/lib.rs  |   1 -
 .../runtimes/people/people-westend/src/lib.rs |   1 -
 .../runtimes/testing/penpal/src/lib.rs        |   1 -
 .../testing/rococo-parachain/src/lib.rs       |   1 -
 cumulus/test/runtime/src/lib.rs               |   1 -
 .../runtime/common/src/assigned_slots/mod.rs  |   1 -
 polkadot/runtime/common/src/auctions.rs       |   1 -
 polkadot/runtime/common/src/claims.rs         |   1 -
 polkadot/runtime/common/src/crowdloan/mod.rs  |   1 -
 polkadot/runtime/common/src/impls.rs          |   1 -
 .../runtime/common/src/integration_tests.rs   |   1 -
 .../runtime/common/src/paras_registrar/mod.rs |   1 -
 polkadot/runtime/common/src/purchase.rs       |   1 -
 polkadot/runtime/common/src/slots/mod.rs      |   1 -
 polkadot/runtime/parachains/src/mock.rs       |   1 -
 polkadot/runtime/rococo/src/lib.rs            |   4 +-
 polkadot/runtime/test-runtime/src/lib.rs      |   1 -
 polkadot/runtime/westend/src/lib.rs           |   1 -
 polkadot/xcm/pallet-xcm/src/mock.rs           |   1 -
 .../xcm/xcm-builder/src/tests/pay/mock.rs     |   1 -
 polkadot/xcm/xcm-builder/tests/mock/mod.rs    |   1 -
 .../xcm-simulator/example/src/parachain.rs    |   1 -
 .../xcm-simulator/example/src/relay_chain.rs  |   1 -
 .../xcm/xcm-simulator/fuzzer/src/parachain.rs |   1 -
 .../xcm-simulator/fuzzer/src/relay_chain.rs   |   1 -
 prdoc/pr_2657.prdoc                           |  21 ++
 .../bin/node-template/runtime/src/lib.rs      |   1 -
 substrate/bin/node/runtime/src/lib.rs         |   1 -
 substrate/frame/alliance/src/mock.rs          |   1 -
 substrate/frame/asset-conversion/src/mock.rs  |   1 -
 substrate/frame/asset-rate/src/mock.rs        |   1 -
 substrate/frame/assets/src/mock.rs            |   1 -
 substrate/frame/atomic-swap/src/tests.rs      |   1 -
 substrate/frame/babe/src/mock.rs              |   1 -
 substrate/frame/balances/src/lib.rs           |  21 +-
 substrate/frame/balances/src/tests/mod.rs     |   1 -
 substrate/frame/beefy/src/mock.rs             |   1 -
 substrate/frame/bounties/src/tests.rs         |   1 -
 substrate/frame/child-bounties/src/tests.rs   |   1 -
 .../contracts/mock-network/src/parachain.rs   |   1 -
 .../contracts/mock-network/src/relay_chain.rs |   1 -
 substrate/frame/contracts/src/tests.rs        |   1 -
 .../frame/conviction-voting/src/tests.rs      |   1 -
 substrate/frame/democracy/src/tests.rs        |   1 -
 .../election-provider-multi-phase/src/mock.rs |   1 -
 .../test-staking-e2e/src/mock.rs              |   1 -
 substrate/frame/elections-phragmen/src/lib.rs |   1 -
 substrate/frame/examples/basic/src/tests.rs   |   1 -
 .../frame/examples/dev-mode/src/tests.rs      |   1 -
 .../frame/examples/kitchensink/src/tests.rs   |   1 -
 substrate/frame/executive/src/lib.rs          |   1 -
 substrate/frame/fast-unstake/src/mock.rs      |   1 -
 substrate/frame/grandpa/src/mock.rs           |   1 -
 substrate/frame/identity/src/tests.rs         |   1 -
 substrate/frame/indices/src/mock.rs           |   1 -
 substrate/frame/lottery/src/mock.rs           |   1 -
 .../frame/nft-fractionalization/src/mock.rs   |   1 -
 substrate/frame/nfts/src/mock.rs              |   1 -
 substrate/frame/nis/src/mock.rs               |   2 -
 .../nomination-pools/benchmarking/src/mock.rs |   1 -
 substrate/frame/nomination-pools/src/mock.rs  |   1 -
 .../nomination-pools/test-staking/src/mock.rs |   1 -
 .../frame/offences/benchmarking/src/mock.rs   |   1 -
 substrate/frame/preimage/src/mock.rs          |  11 +-
 substrate/frame/preimage/src/tests.rs         |   8 +-
 substrate/frame/recovery/src/mock.rs          |   1 -
 substrate/frame/referenda/src/mock.rs         |   1 -
 substrate/frame/root-offences/src/mock.rs     |   1 -
 substrate/frame/safe-mode/src/mock.rs         |   1 -
 substrate/frame/scored-pool/src/mock.rs       |   1 -
 .../frame/session/benchmarking/src/mock.rs    |   1 -
 substrate/frame/staking/src/mock.rs           |   1 -
 substrate/frame/statement/src/mock.rs         |   1 -
 .../expand/composite_helper.rs                |  31 ++
 .../construct_runtime/expand/freeze_reason.rs |  10 +-
 .../construct_runtime/expand/hold_reason.rs   |  10 +-
 substrate/frame/support/procedural/src/lib.rs |  15 +-
 .../support/procedural/src/no_bound/clone.rs  |   5 +-
 .../support/procedural/src/no_bound/debug.rs  |   5 +-
 .../procedural/src/no_bound/partial_eq.rs     |   5 +-
 .../procedural/src/pallet/expand/composite.rs |  40 +++
 .../procedural/src/pallet/expand/mod.rs       |   3 +
 .../procedural/src/pallet/parse/composite.rs  |  30 +-
 substrate/frame/support/src/traits.rs         |   3 +-
 substrate/frame/support/src/traits/misc.rs    |  10 +-
 .../support/test/tests/composite_enum.rs      | 274 ++++++++++++++++++
 substrate/frame/tips/src/tests.rs             |   1 -
 .../asset-conversion-tx-payment/src/mock.rs   |   1 -
 .../asset-tx-payment/src/mock.rs              |   1 -
 .../frame/transaction-payment/src/mock.rs     |   1 -
 substrate/frame/treasury/src/tests.rs         |   1 -
 substrate/frame/tx-pause/src/mock.rs          |   1 -
 substrate/frame/uniques/src/mock.rs           |   1 -
 substrate/frame/utility/src/tests.rs          |   1 -
 substrate/frame/vesting/src/mock.rs           |   1 -
 substrate/frame/whitelist/src/mock.rs         |   1 -
 substrate/test-utils/runtime/src/lib.rs       |   1 -
 118 files changed, 610 insertions(+), 315 deletions(-)
 create mode 100644 prdoc/pr_2657.prdoc
 create mode 100644 substrate/frame/support/procedural/src/pallet/expand/composite.rs
 create mode 100644 substrate/frame/support/test/tests/composite_enum.rs

diff --git a/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs b/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs
index d75c3c6a186..110f611c676 100644
--- a/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs
+++ b/bridges/snowbridge/parachain/pallets/inbound-queue/src/mock.rs
@@ -88,7 +88,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 parameter_types! {
diff --git a/bridges/snowbridge/parachain/pallets/system/src/mock.rs b/bridges/snowbridge/parachain/pallets/system/src/mock.rs
index bc229578132..edc3f141b07 100644
--- a/bridges/snowbridge/parachain/pallets/system/src/mock.rs
+++ b/bridges/snowbridge/parachain/pallets/system/src/mock.rs
@@ -136,7 +136,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl pallet_xcm_origin::Config for Test {
diff --git a/cumulus/pallets/collator-selection/src/mock.rs b/cumulus/pallets/collator-selection/src/mock.rs
index ab9ad5ec11a..fe41e7318bc 100644
--- a/cumulus/pallets/collator-selection/src/mock.rs
+++ b/cumulus/pallets/collator-selection/src/mock.rs
@@ -95,7 +95,6 @@ impl pallet_balances::Config for Test {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/pallets/xcmp-queue/src/mock.rs b/cumulus/pallets/xcmp-queue/src/mock.rs
index f8b89258f2f..2bf1e3c6425 100644
--- a/cumulus/pallets/xcmp-queue/src/mock.rs
+++ b/cumulus/pallets/xcmp-queue/src/mock.rs
@@ -106,7 +106,6 @@ impl pallet_balances::Config for Test {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachain-template/runtime/src/lib.rs b/cumulus/parachain-template/runtime/src/lib.rs
index 0ab36eba315..d9bc111fcef 100644
--- a/cumulus/parachain-template/runtime/src/lib.rs
+++ b/cumulus/parachain-template/runtime/src/lib.rs
@@ -337,7 +337,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachains/common/src/impls.rs b/cumulus/parachains/common/src/impls.rs
index 69da325dd4f..957538b7cda 100644
--- a/cumulus/parachains/common/src/impls.rs
+++ b/cumulus/parachains/common/src/impls.rs
@@ -257,7 +257,6 @@ mod tests {
 		type RuntimeHoldReason = RuntimeHoldReason;
 		type RuntimeFreezeReason = RuntimeFreezeReason;
 		type FreezeIdentifier = ();
-		type MaxHolds = ConstU32<1>;
 		type MaxFreezes = ConstU32<1>;
 	}
 
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
index b3d403fd33f..d67595b10b4 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
@@ -241,10 +241,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	// We allow each account to have holds on it from:
-	//   - `NftFractionalization`: 1
-	//   - `StateTrieMigration`: 1
-	type MaxHolds = ConstU32<2>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_balances.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_balances.rs
index 938e50aeebe..299a801ebd5 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_balances.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/weights/pallet_balances.rs
@@ -16,10 +16,10 @@
 
 //! Autogenerated weights for `pallet_balances`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-01-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-8idpd4bs-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
@@ -54,8 +54,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 45_402_000 picoseconds.
-		Weight::from_parts(46_086_000, 0)
+		// Minimum execution time: 42_706_000 picoseconds.
+		Weight::from_parts(43_378_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -66,8 +66,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 35_707_000 picoseconds.
-		Weight::from_parts(36_107_000, 0)
+		// Minimum execution time: 33_090_000 picoseconds.
+		Weight::from_parts(33_703_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -78,8 +78,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 13_538_000 picoseconds.
-		Weight::from_parts(13_771_000, 0)
+		// Minimum execution time: 12_678_000 picoseconds.
+		Weight::from_parts(13_068_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -90,8 +90,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 18_488_000 picoseconds.
-		Weight::from_parts(19_136_000, 0)
+		// Minimum execution time: 17_336_000 picoseconds.
+		Weight::from_parts(17_824_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -102,8 +102,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `6196`
-		// Minimum execution time: 48_168_000 picoseconds.
-		Weight::from_parts(48_874_000, 0)
+		// Minimum execution time: 44_817_000 picoseconds.
+		Weight::from_parts(45_453_000, 0)
 			.saturating_add(Weight::from_parts(0, 6196))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -114,8 +114,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 44_463_000 picoseconds.
-		Weight::from_parts(45_320_000, 0)
+		// Minimum execution time: 41_468_000 picoseconds.
+		Weight::from_parts(42_093_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -126,8 +126,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 16_227_000 picoseconds.
-		Weight::from_parts(16_549_000, 0)
+		// Minimum execution time: 15_344_000 picoseconds.
+		Weight::from_parts(15_878_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -139,11 +139,11 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0 + u * (136 ±0)`
 		//  Estimated: `990 + u * (2603 ±0)`
-		// Minimum execution time: 15_992_000 picoseconds.
-		Weight::from_parts(16_243_000, 0)
+		// Minimum execution time: 15_067_000 picoseconds.
+		Weight::from_parts(15_281_000, 0)
 			.saturating_add(Weight::from_parts(0, 990))
-			// Standard Error: 12_426
-			.saturating_add(Weight::from_parts(13_617_673, 0).saturating_mul(u.into()))
+			// Standard Error: 11_009
+			.saturating_add(Weight::from_parts(13_050_024, 0).saturating_mul(u.into()))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into())))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into())))
 			.saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into()))
@@ -154,8 +154,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `1501`
-		// Minimum execution time: 5_713_000 picoseconds.
-		Weight::from_parts(6_054_000, 0)
+		// Minimum execution time: 5_139_000 picoseconds.
+		Weight::from_parts(5_511_000, 0)
 			.saturating_add(Weight::from_parts(0, 1501))
 			.saturating_add(T::DbWeight::get().reads(1))
 	}
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
index baeb360ce22..6424cec675d 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
@@ -199,9 +199,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	// We allow each account to have holds on it from:
-	//   - `NftFractionalization`: 1
-	type MaxHolds = ConstU32<1>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_balances.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_balances.rs
index 08bfc62b7c3..68aceca14c1 100644
--- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_balances.rs
+++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/weights/pallet_balances.rs
@@ -16,10 +16,10 @@
 
 //! Autogenerated weights for `pallet_balances`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-01-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-8idpd4bs-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024
 
 // Executed Command:
@@ -54,8 +54,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 42_658_000 picoseconds.
-		Weight::from_parts(43_649_000, 0)
+		// Minimum execution time: 43_122_000 picoseconds.
+		Weight::from_parts(43_640_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -66,8 +66,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 33_810_000 picoseconds.
-		Weight::from_parts(34_322_000, 0)
+		// Minimum execution time: 33_636_000 picoseconds.
+		Weight::from_parts(34_571_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -78,8 +78,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 11_825_000 picoseconds.
-		Weight::from_parts(12_258_000, 0)
+		// Minimum execution time: 12_101_000 picoseconds.
+		Weight::from_parts(12_511_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -90,8 +90,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 16_540_000 picoseconds.
-		Weight::from_parts(17_058_000, 0)
+		// Minimum execution time: 17_077_000 picoseconds.
+		Weight::from_parts(17_362_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -102,8 +102,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `6196`
-		// Minimum execution time: 45_138_000 picoseconds.
-		Weight::from_parts(45_481_000, 0)
+		// Minimum execution time: 44_352_000 picoseconds.
+		Weight::from_parts(45_045_000, 0)
 			.saturating_add(Weight::from_parts(0, 6196))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -114,8 +114,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 42_147_000 picoseconds.
-		Weight::from_parts(43_120_000, 0)
+		// Minimum execution time: 41_836_000 picoseconds.
+		Weight::from_parts(43_201_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -126,8 +126,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 14_730_000 picoseconds.
-		Weight::from_parts(14_867_000, 0)
+		// Minimum execution time: 14_413_000 picoseconds.
+		Weight::from_parts(14_743_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -139,11 +139,11 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0 + u * (136 ±0)`
 		//  Estimated: `990 + u * (2603 ±0)`
-		// Minimum execution time: 14_425_000 picoseconds.
-		Weight::from_parts(14_590_000, 0)
+		// Minimum execution time: 14_542_000 picoseconds.
+		Weight::from_parts(14_731_000, 0)
 			.saturating_add(Weight::from_parts(0, 990))
-			// Standard Error: 12_643
-			.saturating_add(Weight::from_parts(13_203_227, 0).saturating_mul(u.into()))
+			// Standard Error: 11_213
+			.saturating_add(Weight::from_parts(13_160_721, 0).saturating_mul(u.into()))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into())))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into())))
 			.saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into()))
@@ -154,8 +154,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `1501`
-		// Minimum execution time: 5_397_000 picoseconds.
-		Weight::from_parts(5_689_000, 0)
+		// Minimum execution time: 5_208_000 picoseconds.
+		Weight::from_parts(5_619_000, 0)
 			.saturating_add(Weight::from_parts(0, 1501))
 			.saturating_add(T::DbWeight::get().reads(1))
 	}
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
index e0204d1e75c..94d5772861c 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
@@ -307,7 +307,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_balances.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_balances.rs
index c6969d92a75..861ccfc51fd 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_balances.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/pallet_balances.rs
@@ -16,10 +16,10 @@
 
 //! Autogenerated weights for `pallet_balances`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-01-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-8idpd4bs-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
@@ -54,8 +54,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 43_019_000 picoseconds.
-		Weight::from_parts(43_897_000, 0)
+		// Minimum execution time: 41_696_000 picoseconds.
+		Weight::from_parts(42_201_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -66,8 +66,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 33_615_000 picoseconds.
-		Weight::from_parts(34_331_000, 0)
+		// Minimum execution time: 32_855_000 picoseconds.
+		Weight::from_parts(33_554_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -78,8 +78,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `174`
 		//  Estimated: `3593`
-		// Minimum execution time: 12_917_000 picoseconds.
-		Weight::from_parts(13_310_000, 0)
+		// Minimum execution time: 12_977_000 picoseconds.
+		Weight::from_parts(13_473_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -91,7 +91,7 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		//  Measured:  `174`
 		//  Estimated: `3593`
 		// Minimum execution time: 17_617_000 picoseconds.
-		Weight::from_parts(18_057_000, 0)
+		Weight::from_parts(18_234_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -102,8 +102,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `6196`
-		// Minimum execution time: 44_458_000 picoseconds.
-		Weight::from_parts(45_097_000, 0)
+		// Minimum execution time: 43_174_000 picoseconds.
+		Weight::from_parts(43_685_000, 0)
 			.saturating_add(Weight::from_parts(0, 6196))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -114,8 +114,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 42_431_000 picoseconds.
-		Weight::from_parts(42_910_000, 0)
+		// Minimum execution time: 41_125_000 picoseconds.
+		Weight::from_parts(41_636_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -126,8 +126,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `174`
 		//  Estimated: `3593`
-		// Minimum execution time: 15_726_000 picoseconds.
-		Weight::from_parts(16_245_000, 0)
+		// Minimum execution time: 15_749_000 picoseconds.
+		Weight::from_parts(16_163_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -139,11 +139,11 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0 + u * (136 ±0)`
 		//  Estimated: `990 + u * (2603 ±0)`
-		// Minimum execution time: 13_929_000 picoseconds.
-		Weight::from_parts(14_306_000, 0)
+		// Minimum execution time: 14_238_000 picoseconds.
+		Weight::from_parts(14_469_000, 0)
 			.saturating_add(Weight::from_parts(0, 990))
-			// Standard Error: 10_984
-			.saturating_add(Weight::from_parts(12_919_627, 0).saturating_mul(u.into()))
+			// Standard Error: 11_818
+			.saturating_add(Weight::from_parts(12_621_051, 0).saturating_mul(u.into()))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into())))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into())))
 			.saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into()))
@@ -154,8 +154,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `1501`
-		// Minimum execution time: 5_132_000 picoseconds.
-		Weight::from_parts(5_467_000, 0)
+		// Minimum execution time: 4_904_000 picoseconds.
+		Weight::from_parts(5_459_000, 0)
 			.saturating_add(Weight::from_parts(0, 1501))
 			.saturating_add(T::DbWeight::get().reads(1))
 	}
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs
index 792b5b63391..5637c3552f5 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs
@@ -279,7 +279,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_balances.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_balances.rs
index 46fa4f2a917..3afef6564bd 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_balances.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/weights/pallet_balances.rs
@@ -16,10 +16,10 @@
 
 //! Autogenerated weights for `pallet_balances`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-01-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-8idpd4bs-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("bridge-hub-westend-dev")`, DB CACHE: 1024
 
 // Executed Command:
@@ -54,8 +54,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 43_103_000 picoseconds.
-		Weight::from_parts(43_576_000, 0)
+		// Minimum execution time: 42_912_000 picoseconds.
+		Weight::from_parts(43_690_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -66,8 +66,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 33_412_000 picoseconds.
-		Weight::from_parts(33_984_000, 0)
+		// Minimum execution time: 33_823_000 picoseconds.
+		Weight::from_parts(34_415_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -78,8 +78,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `174`
 		//  Estimated: `3593`
-		// Minimum execution time: 13_412_000 picoseconds.
-		Weight::from_parts(13_907_000, 0)
+		// Minimum execution time: 13_226_000 picoseconds.
+		Weight::from_parts(13_557_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -90,8 +90,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `174`
 		//  Estimated: `3593`
-		// Minimum execution time: 18_143_000 picoseconds.
-		Weight::from_parts(18_756_000, 0)
+		// Minimum execution time: 18_055_000 picoseconds.
+		Weight::from_parts(18_407_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -102,8 +102,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `6196`
-		// Minimum execution time: 43_676_000 picoseconds.
-		Weight::from_parts(44_575_000, 0)
+		// Minimum execution time: 44_442_000 picoseconds.
+		Weight::from_parts(45_101_000, 0)
 			.saturating_add(Weight::from_parts(0, 6196))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -114,8 +114,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 41_403_000 picoseconds.
-		Weight::from_parts(42_162_000, 0)
+		// Minimum execution time: 42_485_000 picoseconds.
+		Weight::from_parts(43_157_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -126,8 +126,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `174`
 		//  Estimated: `3593`
-		// Minimum execution time: 15_791_000 picoseconds.
-		Weight::from_parts(16_298_000, 0)
+		// Minimum execution time: 16_002_000 picoseconds.
+		Weight::from_parts(16_425_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -139,11 +139,11 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0 + u * (136 ±0)`
 		//  Estimated: `990 + u * (2603 ±0)`
-		// Minimum execution time: 14_390_000 picoseconds.
-		Weight::from_parts(14_611_000, 0)
+		// Minimum execution time: 14_526_000 picoseconds.
+		Weight::from_parts(14_825_000, 0)
 			.saturating_add(Weight::from_parts(0, 990))
-			// Standard Error: 11_611
-			.saturating_add(Weight::from_parts(12_871_155, 0).saturating_mul(u.into()))
+			// Standard Error: 10_967
+			.saturating_add(Weight::from_parts(13_376_293, 0).saturating_mul(u.into()))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into())))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into())))
 			.saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into()))
@@ -154,8 +154,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `1501`
-		// Minimum execution time: 5_314_000 picoseconds.
-		Weight::from_parts(5_638_000, 0)
+		// Minimum execution time: 5_151_000 picoseconds.
+		Weight::from_parts(5_419_000, 0)
 			.saturating_add(Weight::from_parts(0, 1501))
 			.saturating_add(T::DbWeight::get().reads(1))
 	}
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs
index 52a5e79de84..3f488d04ef0 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/lib.rs
@@ -213,7 +213,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<1>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_balances.rs b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_balances.rs
index ebfd948f6a2..602e7ca50c1 100644
--- a/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_balances.rs
+++ b/cumulus/parachains/runtimes/collectives/collectives-westend/src/weights/pallet_balances.rs
@@ -16,10 +16,10 @@
 
 //! Autogenerated weights for `pallet_balances`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-01-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-8idpd4bs-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("collectives-westend-dev")`, DB CACHE: 1024
 
 // Executed Command:
@@ -54,8 +54,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 44_910_000 picoseconds.
-		Weight::from_parts(45_866_000, 0)
+		// Minimum execution time: 45_085_000 picoseconds.
+		Weight::from_parts(45_772_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -66,8 +66,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 35_331_000 picoseconds.
-		Weight::from_parts(36_168_000, 0)
+		// Minimum execution time: 35_447_000 picoseconds.
+		Weight::from_parts(36_143_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -78,8 +78,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 12_540_000 picoseconds.
-		Weight::from_parts(12_942_000, 0)
+		// Minimum execution time: 12_314_000 picoseconds.
+		Weight::from_parts(12_679_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -90,8 +90,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 17_385_000 picoseconds.
-		Weight::from_parts(17_926_000, 0)
+		// Minimum execution time: 17_455_000 picoseconds.
+		Weight::from_parts(17_902_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -102,8 +102,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `6196`
-		// Minimum execution time: 47_232_000 picoseconds.
-		Weight::from_parts(47_740_000, 0)
+		// Minimum execution time: 46_785_000 picoseconds.
+		Weight::from_parts(47_436_000, 0)
 			.saturating_add(Weight::from_parts(0, 6196))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -114,8 +114,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 44_311_000 picoseconds.
-		Weight::from_parts(45_264_000, 0)
+		// Minimum execution time: 43_948_000 picoseconds.
+		Weight::from_parts(44_680_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -126,8 +126,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 15_430_000 picoseconds.
-		Weight::from_parts(15_654_000, 0)
+		// Minimum execution time: 15_267_000 picoseconds.
+		Weight::from_parts(15_499_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -139,11 +139,11 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0 + u * (136 ±0)`
 		//  Estimated: `990 + u * (2603 ±0)`
-		// Minimum execution time: 14_919_000 picoseconds.
-		Weight::from_parts(15_212_000, 0)
+		// Minimum execution time: 14_817_000 picoseconds.
+		Weight::from_parts(15_287_000, 0)
 			.saturating_add(Weight::from_parts(0, 990))
-			// Standard Error: 17_333
-			.saturating_add(Weight::from_parts(13_966_554, 0).saturating_mul(u.into()))
+			// Standard Error: 11_738
+			.saturating_add(Weight::from_parts(13_511_800, 0).saturating_mul(u.into()))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into())))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into())))
 			.saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into()))
@@ -154,8 +154,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `1501`
-		// Minimum execution time: 5_438_000 picoseconds.
-		Weight::from_parts(5_736_000, 0)
+		// Minimum execution time: 5_382_000 picoseconds.
+		Weight::from_parts(5_768_000, 0)
 			.saturating_add(Weight::from_parts(0, 1501))
 			.saturating_add(T::DbWeight::get().reads(1))
 	}
diff --git a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs
index eb428487b62..f3ef5e421fb 100644
--- a/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs
@@ -216,7 +216,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<1>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
index 5a5aaea7387..66fc4b28cd2 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/lib.rs
@@ -228,7 +228,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_balances.rs b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_balances.rs
index 0a0ace608d3..aac7e109366 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_balances.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-rococo/src/weights/pallet_balances.rs
@@ -16,10 +16,10 @@
 
 //! Autogenerated weights for `pallet_balances`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-01-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-8idpd4bs-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-rococo-dev")`, DB CACHE: 1024
 
 // Executed Command:
@@ -54,8 +54,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 42_729_000 picoseconds.
-		Weight::from_parts(43_214_000, 0)
+		// Minimum execution time: 41_557_000 picoseconds.
+		Weight::from_parts(42_618_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -66,8 +66,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 33_717_000 picoseconds.
-		Weight::from_parts(34_160_000, 0)
+		// Minimum execution time: 33_046_000 picoseconds.
+		Weight::from_parts(33_550_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -78,8 +78,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 11_581_000 picoseconds.
-		Weight::from_parts(11_822_000, 0)
+		// Minimum execution time: 11_804_000 picoseconds.
+		Weight::from_parts(12_007_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -90,8 +90,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 16_235_000 picoseconds.
-		Weight::from_parts(16_797_000, 0)
+		// Minimum execution time: 16_261_000 picoseconds.
+		Weight::from_parts(16_655_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -102,8 +102,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `6196`
-		// Minimum execution time: 43_581_000 picoseconds.
-		Weight::from_parts(44_465_000, 0)
+		// Minimum execution time: 42_967_000 picoseconds.
+		Weight::from_parts(43_870_000, 0)
 			.saturating_add(Weight::from_parts(0, 6196))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -114,8 +114,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 42_289_000 picoseconds.
-		Weight::from_parts(42_861_000, 0)
+		// Minimum execution time: 41_022_000 picoseconds.
+		Weight::from_parts(41_475_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -126,8 +126,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 14_583_000 picoseconds.
-		Weight::from_parts(15_088_000, 0)
+		// Minimum execution time: 14_339_000 picoseconds.
+		Weight::from_parts(14_641_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -139,11 +139,11 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0 + u * (136 ±0)`
 		//  Estimated: `990 + u * (2603 ±0)`
-		// Minimum execution time: 14_263_000 picoseconds.
-		Weight::from_parts(14_431_000, 0)
+		// Minimum execution time: 14_241_000 picoseconds.
+		Weight::from_parts(14_463_000, 0)
 			.saturating_add(Weight::from_parts(0, 990))
-			// Standard Error: 11_589
-			.saturating_add(Weight::from_parts(13_005_092, 0).saturating_mul(u.into()))
+			// Standard Error: 12_290
+			.saturating_add(Weight::from_parts(12_903_900, 0).saturating_mul(u.into()))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into())))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into())))
 			.saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into()))
@@ -154,8 +154,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `1501`
-		// Minimum execution time: 5_091_000 picoseconds.
-		Weight::from_parts(5_272_000, 0)
+		// Minimum execution time: 5_116_000 picoseconds.
+		Weight::from_parts(5_345_000, 0)
 			.saturating_add(Weight::from_parts(0, 1501))
 			.saturating_add(T::DbWeight::get().reads(1))
 	}
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs
index d0277fcbfae..e1db9158ce9 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/lib.rs
@@ -219,7 +219,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_balances.rs b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_balances.rs
index 589c5d0607d..2fc1495c804 100644
--- a/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_balances.rs
+++ b/cumulus/parachains/runtimes/coretime/coretime-westend/src/weights/pallet_balances.rs
@@ -16,10 +16,10 @@
 
 //! Autogenerated weights for `pallet_balances`
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
-//! DATE: 2024-01-20, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
+//! DATE: 2024-01-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
 //! WORST CASE MAP SIZE: `1000000`
-//! HOSTNAME: `runner-j8vvqcjr-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
+//! HOSTNAME: `runner-8idpd4bs-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("coretime-westend-dev")`, DB CACHE: 1024
 
 // Executed Command:
@@ -54,8 +54,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 42_533_000 picoseconds.
-		Weight::from_parts(43_470_000, 0)
+		// Minimum execution time: 41_147_000 picoseconds.
+		Weight::from_parts(41_829_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -66,8 +66,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 33_442_000 picoseconds.
-		Weight::from_parts(34_851_000, 0)
+		// Minimum execution time: 32_566_000 picoseconds.
+		Weight::from_parts(33_012_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -78,8 +78,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 11_890_000 picoseconds.
-		Weight::from_parts(12_324_000, 0)
+		// Minimum execution time: 11_435_000 picoseconds.
+		Weight::from_parts(11_717_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -90,8 +90,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 16_583_000 picoseconds.
-		Weight::from_parts(17_116_000, 0)
+		// Minimum execution time: 15_941_000 picoseconds.
+		Weight::from_parts(16_341_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -102,8 +102,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `6196`
-		// Minimum execution time: 43_979_000 picoseconds.
-		Weight::from_parts(44_662_000, 0)
+		// Minimum execution time: 42_592_000 picoseconds.
+		Weight::from_parts(43_111_000, 0)
 			.saturating_add(Weight::from_parts(0, 6196))
 			.saturating_add(T::DbWeight::get().reads(2))
 			.saturating_add(T::DbWeight::get().writes(2))
@@ -114,8 +114,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `3593`
-		// Minimum execution time: 43_140_000 picoseconds.
-		Weight::from_parts(43_575_000, 0)
+		// Minimum execution time: 40_925_000 picoseconds.
+		Weight::from_parts(41_743_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -126,8 +126,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `103`
 		//  Estimated: `3593`
-		// Minimum execution time: 14_748_000 picoseconds.
-		Weight::from_parts(15_097_000, 0)
+		// Minimum execution time: 14_117_000 picoseconds.
+		Weight::from_parts(14_418_000, 0)
 			.saturating_add(Weight::from_parts(0, 3593))
 			.saturating_add(T::DbWeight::get().reads(1))
 			.saturating_add(T::DbWeight::get().writes(1))
@@ -139,11 +139,11 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0 + u * (136 ±0)`
 		//  Estimated: `990 + u * (2603 ±0)`
-		// Minimum execution time: 14_502_000 picoseconds.
-		Weight::from_parts(14_803_000, 0)
+		// Minimum execution time: 13_855_000 picoseconds.
+		Weight::from_parts(14_108_000, 0)
 			.saturating_add(Weight::from_parts(0, 990))
-			// Standard Error: 11_903
-			.saturating_add(Weight::from_parts(13_484_935, 0).saturating_mul(u.into()))
+			// Standard Error: 11_673
+			.saturating_add(Weight::from_parts(12_675_264, 0).saturating_mul(u.into()))
 			.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(u.into())))
 			.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(u.into())))
 			.saturating_add(Weight::from_parts(0, 2603).saturating_mul(u.into()))
@@ -154,8 +154,8 @@ impl<T: frame_system::Config> pallet_balances::WeightInfo for WeightInfo<T> {
 		// Proof Size summary in bytes:
 		//  Measured:  `0`
 		//  Estimated: `1501`
-		// Minimum execution time: 5_035_000 picoseconds.
-		Weight::from_parts(5_255_000, 0)
+		// Minimum execution time: 4_820_000 picoseconds.
+		Weight::from_parts(5_152_000, 0)
 			.saturating_add(Weight::from_parts(0, 1501))
 			.saturating_add(T::DbWeight::get().reads(1))
 	}
diff --git a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs
index 37ab6af9568..2074b81c2cc 100644
--- a/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/people/people-rococo/src/lib.rs
@@ -210,7 +210,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs
index 7a397781505..4f650fed3cd 100644
--- a/cumulus/parachains/runtimes/people/people-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/people/people-westend/src/lib.rs
@@ -210,7 +210,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs
index d33f51df5a9..bf8dcbc24c8 100644
--- a/cumulus/parachains/runtimes/testing/penpal/src/lib.rs
+++ b/cumulus/parachains/runtimes/testing/penpal/src/lib.rs
@@ -404,7 +404,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs
index 253a492871b..c43d79271de 100644
--- a/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs
+++ b/cumulus/parachains/runtimes/testing/rococo-parachain/src/lib.rs
@@ -259,7 +259,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/cumulus/test/runtime/src/lib.rs b/cumulus/test/runtime/src/lib.rs
index 3de77cb1e58..6068f895c83 100644
--- a/cumulus/test/runtime/src/lib.rs
+++ b/cumulus/test/runtime/src/lib.rs
@@ -236,7 +236,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs
index 9976a7be548..3419e3497f7 100644
--- a/polkadot/runtime/common/src/assigned_slots/mod.rs
+++ b/polkadot/runtime/common/src/assigned_slots/mod.rs
@@ -724,7 +724,6 @@ mod tests {
 		type RuntimeHoldReason = RuntimeHoldReason;
 		type RuntimeFreezeReason = RuntimeFreezeReason;
 		type FreezeIdentifier = ();
-		type MaxHolds = ConstU32<1>;
 		type MaxFreezes = ConstU32<1>;
 	}
 
diff --git a/polkadot/runtime/common/src/auctions.rs b/polkadot/runtime/common/src/auctions.rs
index 0bd5ed1e733..46ab673a7a0 100644
--- a/polkadot/runtime/common/src/auctions.rs
+++ b/polkadot/runtime/common/src/auctions.rs
@@ -752,7 +752,6 @@ mod tests {
 		type RuntimeHoldReason = RuntimeHoldReason;
 		type RuntimeFreezeReason = RuntimeFreezeReason;
 		type FreezeIdentifier = ();
-		type MaxHolds = ConstU32<1>;
 		type MaxFreezes = ConstU32<1>;
 	}
 
diff --git a/polkadot/runtime/common/src/claims.rs b/polkadot/runtime/common/src/claims.rs
index 5b87cc9619e..86550ea8b4e 100644
--- a/polkadot/runtime/common/src/claims.rs
+++ b/polkadot/runtime/common/src/claims.rs
@@ -782,7 +782,6 @@ mod tests {
 		type RuntimeHoldReason = RuntimeHoldReason;
 		type RuntimeFreezeReason = RuntimeFreezeReason;
 		type FreezeIdentifier = ();
-		type MaxHolds = ConstU32<1>;
 		type MaxFreezes = ConstU32<1>;
 	}
 
diff --git a/polkadot/runtime/common/src/crowdloan/mod.rs b/polkadot/runtime/common/src/crowdloan/mod.rs
index b7dd06aee3a..7d1b892dfa7 100644
--- a/polkadot/runtime/common/src/crowdloan/mod.rs
+++ b/polkadot/runtime/common/src/crowdloan/mod.rs
@@ -944,7 +944,6 @@ mod tests {
 		type RuntimeHoldReason = RuntimeHoldReason;
 		type RuntimeFreezeReason = RuntimeFreezeReason;
 		type FreezeIdentifier = ();
-		type MaxHolds = ConstU32<1>;
 		type MaxFreezes = ConstU32<1>;
 	}
 
diff --git a/polkadot/runtime/common/src/impls.rs b/polkadot/runtime/common/src/impls.rs
index 79ace0972ad..1ddad37831b 100644
--- a/polkadot/runtime/common/src/impls.rs
+++ b/polkadot/runtime/common/src/impls.rs
@@ -304,7 +304,6 @@ mod tests {
 		type RuntimeHoldReason = RuntimeHoldReason;
 		type RuntimeFreezeReason = RuntimeFreezeReason;
 		type FreezeIdentifier = ();
-		type MaxHolds = ConstU32<1>;
 		type MaxFreezes = ConstU32<1>;
 	}
 
diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs
index fe2f7d8365f..f551743b395 100644
--- a/polkadot/runtime/common/src/integration_tests.rs
+++ b/polkadot/runtime/common/src/integration_tests.rs
@@ -189,7 +189,6 @@ impl pallet_balances::Config for Test {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/polkadot/runtime/common/src/paras_registrar/mod.rs b/polkadot/runtime/common/src/paras_registrar/mod.rs
index a41f338e79d..c05c8a1ae00 100644
--- a/polkadot/runtime/common/src/paras_registrar/mod.rs
+++ b/polkadot/runtime/common/src/paras_registrar/mod.rs
@@ -801,7 +801,6 @@ mod tests {
 		type RuntimeHoldReason = RuntimeHoldReason;
 		type RuntimeFreezeReason = RuntimeFreezeReason;
 		type FreezeIdentifier = ();
-		type MaxHolds = ConstU32<1>;
 		type MaxFreezes = ConstU32<1>;
 	}
 
diff --git a/polkadot/runtime/common/src/purchase.rs b/polkadot/runtime/common/src/purchase.rs
index 146a90fca86..301f1f21fbc 100644
--- a/polkadot/runtime/common/src/purchase.rs
+++ b/polkadot/runtime/common/src/purchase.rs
@@ -556,7 +556,6 @@ mod tests {
 		type RuntimeHoldReason = RuntimeHoldReason;
 		type RuntimeFreezeReason = RuntimeFreezeReason;
 		type FreezeIdentifier = ();
-		type MaxHolds = ConstU32<1>;
 		type MaxFreezes = ConstU32<1>;
 	}
 
diff --git a/polkadot/runtime/common/src/slots/mod.rs b/polkadot/runtime/common/src/slots/mod.rs
index be02aa9961c..51bd0ba4deb 100644
--- a/polkadot/runtime/common/src/slots/mod.rs
+++ b/polkadot/runtime/common/src/slots/mod.rs
@@ -574,7 +574,6 @@ mod tests {
 		type RuntimeHoldReason = RuntimeHoldReason;
 		type RuntimeFreezeReason = RuntimeFreezeReason;
 		type FreezeIdentifier = ();
-		type MaxHolds = ConstU32<1>;
 		type MaxFreezes = ConstU32<1>;
 	}
 
diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs
index e3fcf7dd603..1925ca19501 100644
--- a/polkadot/runtime/parachains/src/mock.rs
+++ b/polkadot/runtime/parachains/src/mock.rs
@@ -147,7 +147,6 @@ impl pallet_balances::Config for Test {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs
index 791ac947c58..79c848221fb 100644
--- a/polkadot/runtime/rococo/src/lib.rs
+++ b/polkadot/runtime/rococo/src/lib.rs
@@ -311,10 +311,9 @@ impl pallet_balances::Config for Runtime {
 	type ReserveIdentifier = [u8; 8];
 	type WeightInfo = weights::pallet_balances_balances::WeightInfo<Runtime>;
 	type FreezeIdentifier = ();
-	type MaxFreezes = ConstU32<1>;
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
-	type MaxHolds = ConstU32<3>;
+	type MaxFreezes = ConstU32<1>;
 }
 
 parameter_types! {
@@ -1167,7 +1166,6 @@ impl pallet_balances::Config<NisCounterpartInstance> for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<3>;
 	type MaxFreezes = ConstU32<1>;
 }
 
diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs
index 51c199b7a05..b74def5de8a 100644
--- a/polkadot/runtime/test-runtime/src/lib.rs
+++ b/polkadot/runtime/test-runtime/src/lib.rs
@@ -221,7 +221,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs
index 6d8ba63f269..cd9e57a9bdf 100644
--- a/polkadot/runtime/westend/src/lib.rs
+++ b/polkadot/runtime/westend/src/lib.rs
@@ -304,7 +304,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = RuntimeFreezeReason;
 	type MaxFreezes = ConstU32<1>;
-	type MaxHolds = ConstU32<1>;
 }
 
 parameter_types! {
diff --git a/polkadot/xcm/pallet-xcm/src/mock.rs b/polkadot/xcm/pallet-xcm/src/mock.rs
index ec03a8b8668..434dac1659b 100644
--- a/polkadot/xcm/pallet-xcm/src/mock.rs
+++ b/polkadot/xcm/pallet-xcm/src/mock.rs
@@ -289,7 +289,6 @@ impl pallet_balances::Config for Test {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs
index 91e36b2de4b..9892c500f2e 100644
--- a/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs
+++ b/polkadot/xcm/xcm-builder/src/tests/pay/mock.rs
@@ -77,7 +77,6 @@ impl pallet_balances::Config for Test {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/polkadot/xcm/xcm-builder/tests/mock/mod.rs b/polkadot/xcm/xcm-builder/tests/mock/mod.rs
index 7e08cb779a4..34508d7622c 100644
--- a/polkadot/xcm/xcm-builder/tests/mock/mod.rs
+++ b/polkadot/xcm/xcm-builder/tests/mock/mod.rs
@@ -124,7 +124,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/polkadot/xcm/xcm-simulator/example/src/parachain.rs b/polkadot/xcm/xcm-simulator/example/src/parachain.rs
index 9c9f481242f..64333b4d581 100644
--- a/polkadot/xcm/xcm-simulator/example/src/parachain.rs
+++ b/polkadot/xcm/xcm-simulator/example/src/parachain.rs
@@ -109,7 +109,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs
index d96b39aca63..54c5657c00d 100644
--- a/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs
+++ b/polkadot/xcm/xcm-simulator/example/src/relay_chain.rs
@@ -95,7 +95,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs
index 36db24b35a6..d8327c9b401 100644
--- a/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs
+++ b/polkadot/xcm/xcm-simulator/fuzzer/src/parachain.rs
@@ -100,7 +100,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs
index 7879d781bd3..7e42f558dd6 100644
--- a/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs
+++ b/polkadot/xcm/xcm-simulator/fuzzer/src/relay_chain.rs
@@ -96,7 +96,6 @@ impl pallet_balances::Config for Runtime {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/prdoc/pr_2657.prdoc b/prdoc/pr_2657.prdoc
new file mode 100644
index 00000000000..9c5edf4ceee
--- /dev/null
+++ b/prdoc/pr_2657.prdoc
@@ -0,0 +1,21 @@
+# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
+# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json
+
+title: "[frame] `#[pallet::composite_enum]` improved variant count handling + removed `pallet_balances`'s `MaxHolds` config"
+
+doc:
+  - audience: Runtime Dev
+    description: |
+      The implementation of the `VariantCount` trait for aggregate composite enums,
+      such as `RuntimeHoldReason` and `RuntimeFreezeReason`, has been fixed.
+      It is now calculated as the sum of `VariantCount::VARIANT_COUNT` for all corresponding `#[pallet::composite_enum]`.
+      The `Balances` pallet's `Config` item `type MaxHolds` has been removed,
+      and `type Holds` is now bound to the variant count of the composite enum `RuntimeHoldReason`.
+      Consequently, the runtime does not need to consider setting the correct value for `MaxHolds`.
+
+      notes:
+      - Remove `type MaxHolds` from the `impl pallet_balances::Config for Runtime` in the runtime.
+      - When holds are expected to be used, ensure that `type RuntimeHoldReason = RuntimeHoldReason` is set for `impl pallet_balances::Config for Runtime`.
+
+crates:
+  - name: pallet-balances
diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/substrate/bin/node-template/runtime/src/lib.rs
index bafd3738428..3b6a74be251 100644
--- a/substrate/bin/node-template/runtime/src/lib.rs
+++ b/substrate/bin/node-template/runtime/src/lib.rs
@@ -228,7 +228,6 @@ impl pallet_balances::Config for Runtime {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 parameter_types! {
diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index d0a327fd950..c2472e906de 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -533,7 +533,6 @@ impl pallet_balances::Config for Runtime {
 	type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
 	type FreezeIdentifier = RuntimeFreezeReason;
 	type MaxFreezes = ConstU32<1>;
-	type MaxHolds = ConstU32<7>;
 }
 
 parameter_types! {
diff --git a/substrate/frame/alliance/src/mock.rs b/substrate/frame/alliance/src/mock.rs
index 69c74d0b287..627dde81afa 100644
--- a/substrate/frame/alliance/src/mock.rs
+++ b/substrate/frame/alliance/src/mock.rs
@@ -72,7 +72,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 const MOTION_DURATION_IN_BLOCKS: BlockNumber = 3;
diff --git a/substrate/frame/asset-conversion/src/mock.rs b/substrate/frame/asset-conversion/src/mock.rs
index 12c8fe2eb42..dd1d26ff238 100644
--- a/substrate/frame/asset-conversion/src/mock.rs
+++ b/substrate/frame/asset-conversion/src/mock.rs
@@ -95,7 +95,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl pallet_assets::Config<Instance1> for Test {
diff --git a/substrate/frame/asset-rate/src/mock.rs b/substrate/frame/asset-rate/src/mock.rs
index 041f3740952..d6044e09ccd 100644
--- a/substrate/frame/asset-rate/src/mock.rs
+++ b/substrate/frame/asset-rate/src/mock.rs
@@ -79,7 +79,6 @@ impl pallet_balances::Config for Test {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ();
 	type MaxFreezes = ();
 }
 
diff --git a/substrate/frame/assets/src/mock.rs b/substrate/frame/assets/src/mock.rs
index d60f5358336..6dda08eaff8 100644
--- a/substrate/frame/assets/src/mock.rs
+++ b/substrate/frame/assets/src/mock.rs
@@ -86,7 +86,6 @@ impl pallet_balances::Config for Test {
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
 	type FreezeIdentifier = ();
-	type MaxHolds = ();
 	type MaxFreezes = ();
 }
 
diff --git a/substrate/frame/atomic-swap/src/tests.rs b/substrate/frame/atomic-swap/src/tests.rs
index 58502aa4f93..4a4b96f7aae 100644
--- a/substrate/frame/atomic-swap/src/tests.rs
+++ b/substrate/frame/atomic-swap/src/tests.rs
@@ -82,7 +82,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl Config for Test {
diff --git a/substrate/frame/babe/src/mock.rs b/substrate/frame/babe/src/mock.rs
index 72abbc805db..b693f4fce9b 100644
--- a/substrate/frame/babe/src/mock.rs
+++ b/substrate/frame/babe/src/mock.rs
@@ -126,7 +126,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 pallet_staking_reward_curve::build! {
diff --git a/substrate/frame/balances/src/lib.rs b/substrate/frame/balances/src/lib.rs
index 39df8b153eb..7dd087eabd6 100644
--- a/substrate/frame/balances/src/lib.rs
+++ b/substrate/frame/balances/src/lib.rs
@@ -206,7 +206,7 @@ pub mod pallet {
 	use super::*;
 	use frame_support::{
 		pallet_prelude::*,
-		traits::{fungible::Credit, tokens::Precision, VariantCount},
+		traits::{fungible::Credit, tokens::Precision, VariantCount, VariantCountOf},
 	};
 	use frame_system::pallet_prelude::*;
 
@@ -242,7 +242,6 @@ pub mod pallet {
 			type MaxLocks = ConstU32<100>;
 			type MaxReserves = ConstU32<100>;
 			type MaxFreezes = ConstU32<100>;
-			type MaxHolds = ConstU32<100>;
 
 			type WeightInfo = ();
 		}
@@ -316,10 +315,6 @@ pub mod pallet {
 		#[pallet::constant]
 		type MaxReserves: Get<u32>;
 
-		/// The maximum number of holds that can exist on an account at any time.
-		#[pallet::constant]
-		type MaxHolds: Get<u32>;
-
 		/// The maximum number of individual freeze locks that can exist on an account at any time.
 		#[pallet::constant]
 		type MaxFreezes: Get<u32>;
@@ -407,7 +402,7 @@ pub mod pallet {
 		DeadAccount,
 		/// Number of named reserves exceed `MaxReserves`.
 		TooManyReserves,
-		/// Number of holds exceed `MaxHolds`.
+		/// Number of holds exceed `VariantCountOf<T::RuntimeHoldReason>`.
 		TooManyHolds,
 		/// Number of freezes exceed `MaxFreezes`.
 		TooManyFreezes,
@@ -487,7 +482,10 @@ pub mod pallet {
 		_,
 		Blake2_128Concat,
 		T::AccountId,
-		BoundedVec<IdAmount<T::RuntimeHoldReason, T::Balance>, T::MaxHolds>,
+		BoundedVec<
+			IdAmount<T::RuntimeHoldReason, T::Balance>,
+			VariantCountOf<T::RuntimeHoldReason>,
+		>,
 		ValueQuery,
 	>;
 
@@ -556,13 +554,6 @@ pub mod pallet {
 				"The existential deposit must be greater than zero!"
 			);
 
-			assert!(
-				T::MaxHolds::get() >= <T::RuntimeHoldReason as VariantCount>::VARIANT_COUNT,
-				"MaxHolds should be greater than or equal to the number of hold reasons: {} < {}",
-				T::MaxHolds::get(),
-				<T::RuntimeHoldReason as VariantCount>::VARIANT_COUNT
-			);
-
 			assert!(
 				T::MaxFreezes::get() >= <T::RuntimeFreezeReason as VariantCount>::VARIANT_COUNT,
 				"MaxFreezes should be greater than or equal to the number of freeze reasons: {} < {}",
diff --git a/substrate/frame/balances/src/tests/mod.rs b/substrate/frame/balances/src/tests/mod.rs
index 5ab766fffe7..91452b292b5 100644
--- a/substrate/frame/balances/src/tests/mod.rs
+++ b/substrate/frame/balances/src/tests/mod.rs
@@ -142,7 +142,6 @@ impl Config for Test {
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = TestId;
 	type MaxFreezes = ConstU32<2>;
-	type MaxHolds = ConstU32<3>;
 }
 
 #[derive(Clone)]
diff --git a/substrate/frame/beefy/src/mock.rs b/substrate/frame/beefy/src/mock.rs
index 8828fa36218..9cce479890a 100644
--- a/substrate/frame/beefy/src/mock.rs
+++ b/substrate/frame/beefy/src/mock.rs
@@ -133,7 +133,6 @@ impl pallet_balances::Config for Test {
 	type WeightInfo = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 	type FreezeIdentifier = ();
 	type MaxFreezes = ();
 }
diff --git a/substrate/frame/bounties/src/tests.rs b/substrate/frame/bounties/src/tests.rs
index a7177393a44..b0e3c085e65 100644
--- a/substrate/frame/bounties/src/tests.rs
+++ b/substrate/frame/bounties/src/tests.rs
@@ -100,7 +100,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 parameter_types! {
 	pub const ProposalBond: Permill = Permill::from_percent(5);
diff --git a/substrate/frame/child-bounties/src/tests.rs b/substrate/frame/child-bounties/src/tests.rs
index e57721adad0..d663b8d9961 100644
--- a/substrate/frame/child-bounties/src/tests.rs
+++ b/substrate/frame/child-bounties/src/tests.rs
@@ -103,7 +103,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 parameter_types! {
 	pub const ProposalBond: Permill = Permill::from_percent(5);
diff --git a/substrate/frame/contracts/mock-network/src/parachain.rs b/substrate/frame/contracts/mock-network/src/parachain.rs
index 03fcef1a56c..53839f1fca0 100644
--- a/substrate/frame/contracts/mock-network/src/parachain.rs
+++ b/substrate/frame/contracts/mock-network/src/parachain.rs
@@ -95,7 +95,6 @@ impl pallet_balances::Config for Runtime {
 	type ExistentialDeposit = ExistentialDeposit;
 	type FreezeIdentifier = ();
 	type MaxFreezes = ConstU32<0>;
-	type MaxHolds = ConstU32<1>;
 	type MaxLocks = MaxLocks;
 	type MaxReserves = MaxReserves;
 	type ReserveIdentifier = [u8; 8];
diff --git a/substrate/frame/contracts/mock-network/src/relay_chain.rs b/substrate/frame/contracts/mock-network/src/relay_chain.rs
index 8bb33ff5de8..ce7e22dce2f 100644
--- a/substrate/frame/contracts/mock-network/src/relay_chain.rs
+++ b/substrate/frame/contracts/mock-network/src/relay_chain.rs
@@ -93,7 +93,6 @@ impl pallet_balances::Config for Runtime {
 	type MaxReserves = MaxReserves;
 	type ReserveIdentifier = [u8; 8];
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
diff --git a/substrate/frame/contracts/src/tests.rs b/substrate/frame/contracts/src/tests.rs
index 81539591019..5711d3ccc83 100644
--- a/substrate/frame/contracts/src/tests.rs
+++ b/substrate/frame/contracts/src/tests.rs
@@ -373,7 +373,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
-	type MaxHolds = ConstU32<1>;
 }
 
 impl pallet_timestamp::Config for Test {
diff --git a/substrate/frame/conviction-voting/src/tests.rs b/substrate/frame/conviction-voting/src/tests.rs
index d7bac505a54..b67290e7fec 100644
--- a/substrate/frame/conviction-voting/src/tests.rs
+++ b/substrate/frame/conviction-voting/src/tests.rs
@@ -92,7 +92,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 #[derive(Clone, PartialEq, Eq, Debug)]
diff --git a/substrate/frame/democracy/src/tests.rs b/substrate/frame/democracy/src/tests.rs
index 888d7e59614..8136fa5c4c9 100644
--- a/substrate/frame/democracy/src/tests.rs
+++ b/substrate/frame/democracy/src/tests.rs
@@ -143,7 +143,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 parameter_types! {
 	pub static PreimageByteDeposit: u64 = 0;
diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs
index 507e8f2c39b..18dcd7061c1 100644
--- a/substrate/frame/election-provider-multi-phase/src/mock.rs
+++ b/substrate/frame/election-provider-multi-phase/src/mock.rs
@@ -259,7 +259,6 @@ impl pallet_balances::Config for Runtime {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 #[derive(Default, Eq, PartialEq, Debug, Clone, Copy)]
diff --git a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs
index 04d218acf8f..32633a0ed7d 100644
--- a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs
+++ b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs
@@ -111,7 +111,6 @@ impl pallet_balances::Config for Runtime {
 	type DustRemoval = ();
 	type ExistentialDeposit = ExistentialDeposit;
 	type AccountStore = System;
-	type MaxHolds = ConstU32<1>;
 	type MaxFreezes = traits::ConstU32<1>;
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
diff --git a/substrate/frame/elections-phragmen/src/lib.rs b/substrate/frame/elections-phragmen/src/lib.rs
index 2b599ab5292..5d20a3cfcee 100644
--- a/substrate/frame/elections-phragmen/src/lib.rs
+++ b/substrate/frame/elections-phragmen/src/lib.rs
@@ -1362,7 +1362,6 @@ mod tests {
 		type MaxFreezes = ();
 		type RuntimeHoldReason = ();
 		type RuntimeFreezeReason = ();
-		type MaxHolds = ();
 	}
 
 	frame_support::parameter_types! {
diff --git a/substrate/frame/examples/basic/src/tests.rs b/substrate/frame/examples/basic/src/tests.rs
index 2a6fbf0f054..9434ace35ff 100644
--- a/substrate/frame/examples/basic/src/tests.rs
+++ b/substrate/frame/examples/basic/src/tests.rs
@@ -86,7 +86,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl Config for Test {
diff --git a/substrate/frame/examples/dev-mode/src/tests.rs b/substrate/frame/examples/dev-mode/src/tests.rs
index c1501a5b4cf..c13152533fd 100644
--- a/substrate/frame/examples/dev-mode/src/tests.rs
+++ b/substrate/frame/examples/dev-mode/src/tests.rs
@@ -80,7 +80,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
-	type MaxHolds = ();
 }
 
 impl Config for Test {
diff --git a/substrate/frame/examples/kitchensink/src/tests.rs b/substrate/frame/examples/kitchensink/src/tests.rs
index 3b88f68d1c3..7f626718930 100644
--- a/substrate/frame/examples/kitchensink/src/tests.rs
+++ b/substrate/frame/examples/kitchensink/src/tests.rs
@@ -57,7 +57,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 parameter_types! {
diff --git a/substrate/frame/executive/src/lib.rs b/substrate/frame/executive/src/lib.rs
index cfeb585b0fd..48ff675f808 100644
--- a/substrate/frame/executive/src/lib.rs
+++ b/substrate/frame/executive/src/lib.rs
@@ -959,7 +959,6 @@ mod tests {
 		type MaxFreezes = ConstU32<1>;
 		type RuntimeHoldReason = ();
 		type RuntimeFreezeReason = ();
-		type MaxHolds = ConstU32<1>;
 	}
 
 	parameter_types! {
diff --git a/substrate/frame/fast-unstake/src/mock.rs b/substrate/frame/fast-unstake/src/mock.rs
index de1772264f1..78d881965a5 100644
--- a/substrate/frame/fast-unstake/src/mock.rs
+++ b/substrate/frame/fast-unstake/src/mock.rs
@@ -77,7 +77,6 @@ impl pallet_balances::Config for Runtime {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 pallet_staking_reward_curve::build! {
diff --git a/substrate/frame/grandpa/src/mock.rs b/substrate/frame/grandpa/src/mock.rs
index f1f51e0b118..990a820d3a9 100644
--- a/substrate/frame/grandpa/src/mock.rs
+++ b/substrate/frame/grandpa/src/mock.rs
@@ -143,7 +143,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl pallet_timestamp::Config for Test {
diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs
index a2b26120254..5c9304ca8c1 100644
--- a/substrate/frame/identity/src/tests.rs
+++ b/substrate/frame/identity/src/tests.rs
@@ -94,7 +94,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 parameter_types! {
diff --git a/substrate/frame/indices/src/mock.rs b/substrate/frame/indices/src/mock.rs
index 7ea524a3167..5cf82305178 100644
--- a/substrate/frame/indices/src/mock.rs
+++ b/substrate/frame/indices/src/mock.rs
@@ -79,7 +79,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl Config for Test {
diff --git a/substrate/frame/lottery/src/mock.rs b/substrate/frame/lottery/src/mock.rs
index 884f003aada..0b73bba6135 100644
--- a/substrate/frame/lottery/src/mock.rs
+++ b/substrate/frame/lottery/src/mock.rs
@@ -88,7 +88,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 parameter_types! {
diff --git a/substrate/frame/nft-fractionalization/src/mock.rs b/substrate/frame/nft-fractionalization/src/mock.rs
index 855109adcbe..40cce96d550 100644
--- a/substrate/frame/nft-fractionalization/src/mock.rs
+++ b/substrate/frame/nft-fractionalization/src/mock.rs
@@ -89,7 +89,6 @@ impl pallet_balances::Config for Test {
 	type ReserveIdentifier = [u8; 8];
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
-	type MaxHolds = ConstU32<1>;
 	type FreezeIdentifier = ();
 	type MaxFreezes = ();
 }
diff --git a/substrate/frame/nfts/src/mock.rs b/substrate/frame/nfts/src/mock.rs
index 95443cf41c4..ac6d0d75732 100644
--- a/substrate/frame/nfts/src/mock.rs
+++ b/substrate/frame/nfts/src/mock.rs
@@ -87,7 +87,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 parameter_types! {
diff --git a/substrate/frame/nis/src/mock.rs b/substrate/frame/nis/src/mock.rs
index be6e79ac6f6..98b653635ca 100644
--- a/substrate/frame/nis/src/mock.rs
+++ b/substrate/frame/nis/src/mock.rs
@@ -91,7 +91,6 @@ impl pallet_balances::Config<Instance1> for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
-	type MaxHolds = ConstU32<1>;
 }
 
 impl pallet_balances::Config<Instance2> for Test {
@@ -112,7 +111,6 @@ impl pallet_balances::Config<Instance2> for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 parameter_types! {
diff --git a/substrate/frame/nomination-pools/benchmarking/src/mock.rs b/substrate/frame/nomination-pools/benchmarking/src/mock.rs
index 77124ae3888..4e57c00849f 100644
--- a/substrate/frame/nomination-pools/benchmarking/src/mock.rs
+++ b/substrate/frame/nomination-pools/benchmarking/src/mock.rs
@@ -79,7 +79,6 @@ impl pallet_balances::Config for Runtime {
 	type MaxFreezes = ConstU32<1>;
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 pallet_staking_reward_curve::build! {
diff --git a/substrate/frame/nomination-pools/src/mock.rs b/substrate/frame/nomination-pools/src/mock.rs
index cd91fbb33c1..84c41a15b20 100644
--- a/substrate/frame/nomination-pools/src/mock.rs
+++ b/substrate/frame/nomination-pools/src/mock.rs
@@ -254,7 +254,6 @@ impl pallet_balances::Config for Runtime {
 	type MaxFreezes = ConstU32<1>;
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 pub struct BalanceToU256;
diff --git a/substrate/frame/nomination-pools/test-staking/src/mock.rs b/substrate/frame/nomination-pools/test-staking/src/mock.rs
index cbd7a4d0758..d1b50b9f7ae 100644
--- a/substrate/frame/nomination-pools/test-staking/src/mock.rs
+++ b/substrate/frame/nomination-pools/test-staking/src/mock.rs
@@ -90,7 +90,6 @@ impl pallet_balances::Config for Runtime {
 	type MaxFreezes = ConstU32<1>;
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 pallet_staking_reward_curve::build! {
diff --git a/substrate/frame/offences/benchmarking/src/mock.rs b/substrate/frame/offences/benchmarking/src/mock.rs
index 38c6fb6ea5f..01ad8d64f10 100644
--- a/substrate/frame/offences/benchmarking/src/mock.rs
+++ b/substrate/frame/offences/benchmarking/src/mock.rs
@@ -81,7 +81,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl pallet_timestamp::Config for Test {
diff --git a/substrate/frame/preimage/src/mock.rs b/substrate/frame/preimage/src/mock.rs
index 357f088f5ba..60ffecbb448 100644
--- a/substrate/frame/preimage/src/mock.rs
+++ b/substrate/frame/preimage/src/mock.rs
@@ -21,7 +21,7 @@ use super::*;
 
 use crate as pallet_preimage;
 use frame_support::{
-	derive_impl, ord_parameter_types,
+	derive_impl, ord_parameter_types, parameter_types,
 	traits::{fungible::HoldConsideration, ConstU32, ConstU64, Everything},
 	weights::constants::RocksDbWeight,
 };
@@ -82,15 +82,18 @@ impl pallet_balances::Config for Test {
 	type ReserveIdentifier = [u8; 8];
 	type FreezeIdentifier = ();
 	type MaxFreezes = ConstU32<1>;
-	type RuntimeHoldReason = ();
+	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ConstU32<2>;
 }
 
 ord_parameter_types! {
 	pub const One: u64 = 1;
 }
 
+parameter_types! {
+	pub const PreimageHoldReason: RuntimeHoldReason = RuntimeHoldReason::Preimage(pallet_preimage::HoldReason::Preimage);
+}
+
 pub struct ConvertDeposit;
 impl Convert<Footprint, u64> for ConvertDeposit {
 	fn convert(a: Footprint) -> u64 {
@@ -103,7 +106,7 @@ impl Config for Test {
 	type RuntimeEvent = RuntimeEvent;
 	type Currency = Balances;
 	type ManagerOrigin = EnsureSignedBy<One, u64>;
-	type Consideration = HoldConsideration<u64, Balances, (), ConvertDeposit>;
+	type Consideration = HoldConsideration<u64, Balances, PreimageHoldReason, ConvertDeposit>;
 }
 
 pub fn new_test_ext() -> sp_io::TestExternalities {
diff --git a/substrate/frame/preimage/src/tests.rs b/substrate/frame/preimage/src/tests.rs
index 7609ec83e90..69f6d172ae8 100644
--- a/substrate/frame/preimage/src/tests.rs
+++ b/substrate/frame/preimage/src/tests.rs
@@ -58,7 +58,7 @@ pub fn make_bounded_values() -> (
 fn user_note_preimage_works() {
 	new_test_ext().execute_with(|| {
 		assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(2), vec![1]));
-		assert_eq!(Balances::balance_on_hold(&(), &2), 3);
+		assert_eq!(Balances::balance_on_hold(&PreimageHoldReason::get(), &2), 3);
 		assert_eq!(Balances::free_balance(2), 97);
 
 		let h = hashed([1]);
@@ -255,14 +255,14 @@ fn unrequest_preimage_works() {
 fn user_noted_then_requested_preimage_is_refunded_once_only() {
 	new_test_ext().execute_with(|| {
 		assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(2), vec![1; 3]));
-		assert_eq!(Balances::balance_on_hold(&(), &2), 5);
+		assert_eq!(Balances::balance_on_hold(&PreimageHoldReason::get(), &2), 5);
 		assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(2), vec![1]));
-		assert_eq!(Balances::balance_on_hold(&(), &2), 8);
+		assert_eq!(Balances::balance_on_hold(&PreimageHoldReason::get(), &2), 8);
 		assert_ok!(Preimage::request_preimage(RuntimeOrigin::signed(1), hashed([1])));
 		assert_ok!(Preimage::unrequest_preimage(RuntimeOrigin::signed(1), hashed([1])));
 		assert_ok!(Preimage::unnote_preimage(RuntimeOrigin::signed(2), hashed([1])));
 		// Still have hold from `vec[1; 3]`.
-		assert_eq!(Balances::balance_on_hold(&(), &2), 5);
+		assert_eq!(Balances::balance_on_hold(&PreimageHoldReason::get(), &2), 5);
 	});
 }
 
diff --git a/substrate/frame/recovery/src/mock.rs b/substrate/frame/recovery/src/mock.rs
index 9adb2b80931..ba7958f7dd4 100644
--- a/substrate/frame/recovery/src/mock.rs
+++ b/substrate/frame/recovery/src/mock.rs
@@ -86,7 +86,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 parameter_types! {
diff --git a/substrate/frame/referenda/src/mock.rs b/substrate/frame/referenda/src/mock.rs
index b75558723e9..d9f9042fefc 100644
--- a/substrate/frame/referenda/src/mock.rs
+++ b/substrate/frame/referenda/src/mock.rs
@@ -118,7 +118,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 parameter_types! {
 	pub static AlarmInterval: u64 = 1;
diff --git a/substrate/frame/root-offences/src/mock.rs b/substrate/frame/root-offences/src/mock.rs
index 583ba5b92fb..b0f346032b9 100644
--- a/substrate/frame/root-offences/src/mock.rs
+++ b/substrate/frame/root-offences/src/mock.rs
@@ -125,7 +125,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 pallet_staking_reward_curve::build! {
diff --git a/substrate/frame/safe-mode/src/mock.rs b/substrate/frame/safe-mode/src/mock.rs
index 7574d64d59d..b4d7a624ea2 100644
--- a/substrate/frame/safe-mode/src/mock.rs
+++ b/substrate/frame/safe-mode/src/mock.rs
@@ -82,7 +82,6 @@ impl pallet_balances::Config for Test {
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
 	type FreezeIdentifier = ();
-	type MaxHolds = ConstU32<10>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/substrate/frame/scored-pool/src/mock.rs b/substrate/frame/scored-pool/src/mock.rs
index 00818f4aad0..e767b49b983 100644
--- a/substrate/frame/scored-pool/src/mock.rs
+++ b/substrate/frame/scored-pool/src/mock.rs
@@ -92,7 +92,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 parameter_types! {
diff --git a/substrate/frame/session/benchmarking/src/mock.rs b/substrate/frame/session/benchmarking/src/mock.rs
index c305641e185..2ef8989f4b0 100644
--- a/substrate/frame/session/benchmarking/src/mock.rs
+++ b/substrate/frame/session/benchmarking/src/mock.rs
@@ -86,7 +86,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl pallet_timestamp::Config for Test {
diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs
index 73b6f8ccf27..40a5be51ded 100644
--- a/substrate/frame/staking/src/mock.rs
+++ b/substrate/frame/staking/src/mock.rs
@@ -165,7 +165,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 sp_runtime::impl_opaque_keys! {
diff --git a/substrate/frame/statement/src/mock.rs b/substrate/frame/statement/src/mock.rs
index 192baa1f218..c5bee2639dc 100644
--- a/substrate/frame/statement/src/mock.rs
+++ b/substrate/frame/statement/src/mock.rs
@@ -88,7 +88,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
-	type MaxHolds = ();
 }
 
 ord_parameter_types! {
diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/composite_helper.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/composite_helper.rs
index 3c81d2360cb..c9ae94c7dcd 100644
--- a/substrate/frame/support/procedural/src/construct_runtime/expand/composite_helper.rs
+++ b/substrate/frame/support/procedural/src/construct_runtime/expand/composite_helper.rs
@@ -68,3 +68,34 @@ pub(crate) fn expand_variant(
 		}
 	}
 }
+
+pub(crate) fn expand_variant_count(
+	composite_name: &str,
+	path: &PalletPath,
+	instance: Option<&Ident>,
+) -> TokenStream {
+	let composite_name = quote::format_ident!("{}", composite_name);
+
+	if let Some(inst) = instance {
+		quote! {
+			#path::#composite_name::<#path::#inst>::VARIANT_COUNT
+		}
+	} else {
+		// Wrapped `<`..`>` means: use default type parameter for enum.
+		//
+		// This is used for pallets without instance support or pallets with instance support when
+		// we don't specify instance:
+		//
+		// ```nocompile
+		// pub struct Pallet<T, I = ()>{..}
+		//
+		// #[pallet::composite_enum]
+		// pub enum HoldReason<I: 'static = ()> {..}
+		//
+		// Pallet1: pallet_x,  // <- default type parameter
+		// ```
+		quote! {
+			<#path::#composite_name>::VARIANT_COUNT
+		}
+	}
+}
diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/freeze_reason.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/freeze_reason.rs
index 55696cc6c6e..f12f9952664 100644
--- a/substrate/frame/support/procedural/src/construct_runtime/expand/freeze_reason.rs
+++ b/substrate/frame/support/procedural/src/construct_runtime/expand/freeze_reason.rs
@@ -23,6 +23,7 @@ use quote::quote;
 pub fn expand_outer_freeze_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
 	let mut conversion_fns = Vec::new();
 	let mut freeze_reason_variants = Vec::new();
+	let mut freeze_reason_variants_count = Vec::new();
 	for decl in pallet_decls {
 		if let Some(_) = decl.find_part("FreezeReason") {
 			let variant_name = &decl.name;
@@ -44,9 +45,14 @@ pub fn expand_outer_freeze_reason(pallet_decls: &[Pallet], scrate: &TokenStream)
 				instance,
 				variant_name,
 			));
+
+			freeze_reason_variants_count.push(composite_helper::expand_variant_count(
+				"FreezeReason",
+				path,
+				instance,
+			));
 		}
 	}
-	let freeze_reason_variants_count = freeze_reason_variants.len() as u32;
 
 	quote! {
 		/// A reason for placing a freeze on funds.
@@ -61,7 +67,7 @@ pub fn expand_outer_freeze_reason(pallet_decls: &[Pallet], scrate: &TokenStream)
 		}
 
 		impl #scrate::traits::VariantCount for RuntimeFreezeReason {
-			const VARIANT_COUNT: u32 = #freeze_reason_variants_count;
+			const VARIANT_COUNT: u32 = 0 #( + #freeze_reason_variants_count )*;
 		}
 
 		#( #conversion_fns )*
diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/hold_reason.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/hold_reason.rs
index 3856c4a2bb9..cdab92712fd 100644
--- a/substrate/frame/support/procedural/src/construct_runtime/expand/hold_reason.rs
+++ b/substrate/frame/support/procedural/src/construct_runtime/expand/hold_reason.rs
@@ -23,6 +23,7 @@ use quote::quote;
 pub fn expand_outer_hold_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -> TokenStream {
 	let mut conversion_fns = Vec::new();
 	let mut hold_reason_variants = Vec::new();
+	let mut hold_reason_variants_count = Vec::new();
 	for decl in pallet_decls {
 		if let Some(_) = decl.find_part("HoldReason") {
 			let variant_name = &decl.name;
@@ -44,9 +45,14 @@ pub fn expand_outer_hold_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -
 				instance,
 				variant_name,
 			));
+
+			hold_reason_variants_count.push(composite_helper::expand_variant_count(
+				"HoldReason",
+				path,
+				instance,
+			));
 		}
 	}
-	let hold_reason_variants_count = hold_reason_variants.len() as u32;
 
 	quote! {
 		/// A reason for placing a hold on funds.
@@ -61,7 +67,7 @@ pub fn expand_outer_hold_reason(pallet_decls: &[Pallet], scrate: &TokenStream) -
 		}
 
 		impl #scrate::traits::VariantCount for RuntimeHoldReason {
-			const VARIANT_COUNT: u32 = #hold_reason_variants_count;
+			const VARIANT_COUNT: u32 = 0 #( + #hold_reason_variants_count )*;
 		}
 
 		#( #conversion_fns )*
diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs
index 1c4d03448c4..a777a576648 100644
--- a/substrate/frame/support/procedural/src/lib.rs
+++ b/substrate/frame/support/procedural/src/lib.rs
@@ -432,10 +432,7 @@ pub fn derive_runtime_debug_no_bound(input: TokenStream) -> TokenStream {
 	if cfg!(any(feature = "std", feature = "try-runtime")) {
 		no_bound::debug::derive_debug_no_bound(input)
 	} else {
-		let input: syn::DeriveInput = match syn::parse(input) {
-			Ok(input) => input,
-			Err(e) => return e.to_compile_error().into(),
-		};
+		let input = syn::parse_macro_input!(input as syn::DeriveInput);
 
 		let name = &input.ident;
 		let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
@@ -463,10 +460,7 @@ pub fn derive_partial_eq_no_bound(input: TokenStream) -> TokenStream {
 /// Derive [`Eq`] but do no bound any generic. Docs are at `frame_support::EqNoBound`.
 #[proc_macro_derive(EqNoBound)]
 pub fn derive_eq_no_bound(input: TokenStream) -> TokenStream {
-	let input: syn::DeriveInput = match syn::parse(input) {
-		Ok(input) => input,
-		Err(e) => return e.to_compile_error().into(),
-	};
+	let input = syn::parse_macro_input!(input as syn::DeriveInput);
 
 	let name = &input.ident;
 	let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
@@ -1519,13 +1513,14 @@ pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream {
 ///
 /// ```ignore
 /// Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, MaxEncodedLen, TypeInfo,
-/// RuntimeDebug
+/// RuntimeDebug,
 /// ```
 ///
 /// For ease of usage, when no `#[derive]` attributes are found for the enum under
 /// `#[pallet::composite_enum]`, the aforementioned traits are automatically derived for it. The
 /// inverse is also true: if there are any `#[derive]` attributes found for the enum, then no traits
-/// will automatically be derived for it.
+/// will automatically be derived for it (this implies that you need to provide the
+/// `frame_support::traits::VariantCount` implementation).
 #[proc_macro_attribute]
 pub fn composite_enum(_: TokenStream, _: TokenStream) -> TokenStream {
 	pallet_macro_stub()
diff --git a/substrate/frame/support/procedural/src/no_bound/clone.rs b/substrate/frame/support/procedural/src/no_bound/clone.rs
index 8e57a10d34c..346bf450f11 100644
--- a/substrate/frame/support/procedural/src/no_bound/clone.rs
+++ b/substrate/frame/support/procedural/src/no_bound/clone.rs
@@ -19,10 +19,7 @@ use syn::spanned::Spanned;
 
 /// Derive Clone but do not bound any generic.
 pub fn derive_clone_no_bound(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
-	let input: syn::DeriveInput = match syn::parse(input) {
-		Ok(input) => input,
-		Err(e) => return e.to_compile_error().into(),
-	};
+	let input = syn::parse_macro_input!(input as syn::DeriveInput);
 
 	let name = &input.ident;
 	let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
diff --git a/substrate/frame/support/procedural/src/no_bound/debug.rs b/substrate/frame/support/procedural/src/no_bound/debug.rs
index dd14b9cd564..a1b3f4f0d3b 100644
--- a/substrate/frame/support/procedural/src/no_bound/debug.rs
+++ b/substrate/frame/support/procedural/src/no_bound/debug.rs
@@ -19,10 +19,7 @@ use syn::spanned::Spanned;
 
 /// Derive Debug but do not bound any generics.
 pub fn derive_debug_no_bound(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
-	let input: syn::DeriveInput = match syn::parse(input) {
-		Ok(input) => input,
-		Err(e) => return e.to_compile_error().into(),
-	};
+	let input = syn::parse_macro_input!(input as syn::DeriveInput);
 
 	let input_ident = &input.ident;
 	let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
diff --git a/substrate/frame/support/procedural/src/no_bound/partial_eq.rs b/substrate/frame/support/procedural/src/no_bound/partial_eq.rs
index 7cf5701b193..a1be71a9613 100644
--- a/substrate/frame/support/procedural/src/no_bound/partial_eq.rs
+++ b/substrate/frame/support/procedural/src/no_bound/partial_eq.rs
@@ -19,10 +19,7 @@ use syn::spanned::Spanned;
 
 /// Derive PartialEq but do not bound any generic.
 pub fn derive_partial_eq_no_bound(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
-	let input: syn::DeriveInput = match syn::parse(input) {
-		Ok(input) => input,
-		Err(e) => return e.to_compile_error().into(),
-	};
+	let input = syn::parse_macro_input!(input as syn::DeriveInput);
 
 	let name = &input.ident;
 	let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
diff --git a/substrate/frame/support/procedural/src/pallet/expand/composite.rs b/substrate/frame/support/procedural/src/pallet/expand/composite.rs
new file mode 100644
index 00000000000..acfb21f34e9
--- /dev/null
+++ b/substrate/frame/support/procedural/src/pallet/expand/composite.rs
@@ -0,0 +1,40 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use crate::pallet::Def;
+use proc_macro2::TokenStream;
+
+/// Expands `composite_enum` and adds the `VariantCount` implementation for it."
+pub fn expand_composites(def: &mut Def) -> TokenStream {
+	let mut expand = quote::quote!();
+	let frame_support = &def.frame_support;
+
+	for composite in &def.composites {
+		let name = &composite.ident;
+		let (impl_generics, ty_generics, where_clause) = composite.generics.split_for_impl();
+		let variants_count = composite.variant_count;
+
+		// add `VariantCount` implementation for `composite_enum`
+		expand.extend(quote::quote_spanned!(composite.attr_span =>
+			impl #impl_generics #frame_support::traits::VariantCount for #name #ty_generics #where_clause {
+				const VARIANT_COUNT: u32 = #variants_count;
+			}
+		));
+	}
+
+	expand
+}
diff --git a/substrate/frame/support/procedural/src/pallet/expand/mod.rs b/substrate/frame/support/procedural/src/pallet/expand/mod.rs
index db242df781b..3da7d9293c7 100644
--- a/substrate/frame/support/procedural/src/pallet/expand/mod.rs
+++ b/substrate/frame/support/procedural/src/pallet/expand/mod.rs
@@ -16,6 +16,7 @@
 // limitations under the License.
 
 mod call;
+mod composite;
 mod config;
 mod constants;
 mod doc_only;
@@ -76,6 +77,7 @@ pub fn expand(mut def: Def) -> proc_macro2::TokenStream {
 	let validate_unsigned = validate_unsigned::expand_validate_unsigned(&mut def);
 	let tt_default_parts = tt_default_parts::expand_tt_default_parts(&mut def);
 	let doc_only = doc_only::expand_doc_only(&mut def);
+	let composites = composite::expand_composites(&mut def);
 
 	def.item.attrs.insert(
 		0,
@@ -117,6 +119,7 @@ storage item. Otherwise, all storage items are listed among [*Type Definitions*]
 		#validate_unsigned
 		#tt_default_parts
 		#doc_only
+		#composites
 	);
 
 	def.item
diff --git a/substrate/frame/support/procedural/src/pallet/parse/composite.rs b/substrate/frame/support/procedural/src/pallet/parse/composite.rs
index fa5f47dfdfa..601f16971f8 100644
--- a/substrate/frame/support/procedural/src/pallet/parse/composite.rs
+++ b/substrate/frame/support/procedural/src/pallet/parse/composite.rs
@@ -91,8 +91,16 @@ pub struct CompositeDef {
 	pub index: usize,
 	/// The composite keyword used (contains span).
 	pub composite_keyword: keyword::CompositeKeyword,
+
+	/// Name of the associated type.
+	pub ident: syn::Ident,
+	/// Type parameters and where clause attached to a declaration of the pallet::composite_enum.
+	pub generics: syn::Generics,
 	/// The span of the pallet::composite_enum attribute.
 	pub attr_span: proc_macro2::Span,
+
+	/// Variant count of the pallet::composite_enum.
+	pub variant_count: u32,
 }
 
 impl CompositeDef {
@@ -103,6 +111,19 @@ impl CompositeDef {
 		item: &mut syn::Item,
 	) -> syn::Result<Self> {
 		let item = if let syn::Item::Enum(item) = item {
+			// check variants: composite enums support only field-less enum variants. This is
+			// because fields can introduce too many possibilities, making it challenging to compute
+			// a fixed variant count.
+			for variant in &item.variants {
+				match variant.fields {
+					syn::Fields::Named(_) | syn::Fields::Unnamed(_) =>
+						return Err(syn::Error::new(
+							variant.ident.span(),
+							"The composite enum does not support variants with fields!",
+						)),
+					syn::Fields::Unit => (),
+				}
+			}
 			item
 		} else {
 			return Err(syn::Error::new(
@@ -160,6 +181,13 @@ impl CompositeDef {
 		let composite_keyword =
 			syn::parse2::<keyword::CompositeKeyword>(item.ident.to_token_stream())?;
 
-		Ok(CompositeDef { index, composite_keyword, attr_span })
+		Ok(CompositeDef {
+			index,
+			composite_keyword,
+			attr_span,
+			generics: item.generics.clone(),
+			variant_count: item.variants.len() as u32,
+			ident: item.ident.clone(),
+		})
 	}
 }
diff --git a/substrate/frame/support/src/traits.rs b/substrate/frame/support/src/traits.rs
index 9afd9c16130..a18faee6805 100644
--- a/substrate/frame/support/src/traits.rs
+++ b/substrate/frame/support/src/traits.rs
@@ -61,7 +61,8 @@ pub use misc::{
 	DefensiveTruncateFrom, EnsureInherentsAreFirst, EqualPrivilegeOnly, EstimateCallFee,
 	ExecuteBlock, ExtrinsicCall, Get, GetBacking, GetDefault, HandleLifetime, IsSubType, IsType,
 	Len, OffchainWorker, OnKilledAccount, OnNewAccount, PrivilegeCmp, SameOrOther, Time,
-	TryCollect, TryDrop, TypedGet, UnixTime, VariantCount, WrapperKeepOpaque, WrapperOpaque,
+	TryCollect, TryDrop, TypedGet, UnixTime, VariantCount, VariantCountOf, WrapperKeepOpaque,
+	WrapperOpaque,
 };
 #[allow(deprecated)]
 pub use misc::{PreimageProvider, PreimageRecipient};
diff --git a/substrate/frame/support/src/traits/misc.rs b/substrate/frame/support/src/traits/misc.rs
index bf3053a3f8f..eafd9c8abdd 100644
--- a/substrate/frame/support/src/traits/misc.rs
+++ b/substrate/frame/support/src/traits/misc.rs
@@ -37,8 +37,6 @@ pub const DEFENSIVE_OP_PUBLIC_ERROR: &str = "a defensive failure has been trigge
 pub const DEFENSIVE_OP_INTERNAL_ERROR: &str = "Defensive failure has been triggered!";
 
 /// Trait to get the number of variants in any enum.
-///
-/// NOTE: can be removed once <https://doc.rust-lang.org/std/mem/fn.variant_count.html> is stable.
 pub trait VariantCount {
 	/// Get the number of variants.
 	const VARIANT_COUNT: u32;
@@ -48,6 +46,14 @@ impl VariantCount for () {
 	const VARIANT_COUNT: u32 = 0;
 }
 
+/// Adapter for `Get<u32>` to access `VARIANT_COUNT` from `trait pub trait VariantCount {`.
+pub struct VariantCountOf<T: VariantCount>(sp_std::marker::PhantomData<T>);
+impl<T: VariantCount> Get<u32> for VariantCountOf<T> {
+	fn get() -> u32 {
+		T::VARIANT_COUNT
+	}
+}
+
 /// Generic function to mark an execution path as ONLY defensive.
 ///
 /// Similar to mark a match arm or `if/else` branch as `unreachable!`.
diff --git a/substrate/frame/support/test/tests/composite_enum.rs b/substrate/frame/support/test/tests/composite_enum.rs
new file mode 100644
index 00000000000..b9e9c23c4bc
--- /dev/null
+++ b/substrate/frame/support/test/tests/composite_enum.rs
@@ -0,0 +1,274 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! General tests for composite_enum macro and its handling, test for:
+//! * variant_count works
+
+#![recursion_limit = "128"]
+
+use codec::Encode;
+use frame_support::{derive_impl, traits::VariantCount};
+use sp_core::sr25519;
+use sp_runtime::{
+	generic,
+	traits::{BlakeTwo256, Verify},
+};
+
+#[frame_support::pallet(dev_mode)]
+mod module_single_instance {
+
+	#[pallet::composite_enum]
+	pub enum HoldReason {
+		ModuleSingleInstanceReason1,
+		ModuleSingleInstanceReason2,
+	}
+
+	#[pallet::composite_enum]
+	pub enum FreezeReason {
+		ModuleSingleInstanceReason1,
+		ModuleSingleInstanceReason2,
+	}
+
+	#[pallet::pallet]
+	pub struct Pallet<T>(_);
+
+	#[pallet::config]
+	pub trait Config: frame_system::Config {
+		type RuntimeHoldReason: From<HoldReason>;
+		type RuntimeFreezeReason: From<FreezeReason>;
+	}
+}
+
+#[frame_support::pallet(dev_mode)]
+mod module_multi_instance {
+
+	#[pallet::composite_enum]
+	pub enum HoldReason<I: 'static = ()> {
+		ModuleMultiInstanceReason1,
+		ModuleMultiInstanceReason2,
+		ModuleMultiInstanceReason3,
+	}
+
+	#[pallet::composite_enum]
+	pub enum FreezeReason<I: 'static = ()> {
+		ModuleMultiInstanceReason1,
+	}
+
+	#[pallet::pallet]
+	pub struct Pallet<T, I = ()>(_);
+
+	#[pallet::config]
+	pub trait Config<I: 'static = ()>: frame_system::Config {
+		type RuntimeHoldReason: From<HoldReason<I>>;
+		type RuntimeFreezeReason: From<FreezeReason<I>>;
+	}
+}
+
+#[frame_support::pallet(dev_mode)]
+mod module_composite_enum_consumer {
+	use super::*;
+
+	#[pallet::pallet]
+	pub struct Pallet<T, I = ()>(_);
+
+	#[pallet::config]
+	pub trait Config<I: 'static = ()>: frame_system::Config {
+		// consume `HoldReason` `composite_enum`
+		type RuntimeHoldReason: VariantCount;
+		// consume `FreezeReason` `composite_enum`
+		type RuntimeFreezeReason: VariantCount;
+	}
+}
+
+pub type BlockNumber = u64;
+pub type Signature = sr25519::Signature;
+pub type AccountId = <Signature as Verify>::Signer;
+pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
+pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<u32, RuntimeCall, Signature, ()>;
+pub type Block = generic::Block<Header, UncheckedExtrinsic>;
+
+frame_support::construct_runtime!(
+	pub enum Runtime
+	{
+		System: frame_system,
+		ModuleSingleInstance: module_single_instance,
+		ModuleMultiInstance0: module_multi_instance,
+		ModuleMultiInstance1: module_multi_instance::<Instance1>,
+		ModuleMultiInstance2: module_multi_instance::<Instance2>,
+		ModuleMultiInstance3: module_multi_instance::<Instance3>,
+		ModuleCompositeEnumConsumer: module_composite_enum_consumer,
+	}
+);
+
+#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)]
+impl frame_system::Config for Runtime {
+	type Block = Block;
+}
+
+impl module_single_instance::Config for Runtime {
+	type RuntimeHoldReason = RuntimeHoldReason;
+	type RuntimeFreezeReason = RuntimeFreezeReason;
+}
+
+impl module_multi_instance::Config for Runtime {
+	type RuntimeHoldReason = RuntimeHoldReason;
+	type RuntimeFreezeReason = RuntimeFreezeReason;
+}
+impl module_multi_instance::Config<module_multi_instance::Instance1> for Runtime {
+	type RuntimeHoldReason = RuntimeHoldReason;
+	type RuntimeFreezeReason = RuntimeFreezeReason;
+}
+impl module_multi_instance::Config<module_multi_instance::Instance2> for Runtime {
+	type RuntimeHoldReason = RuntimeHoldReason;
+	type RuntimeFreezeReason = RuntimeFreezeReason;
+}
+impl module_multi_instance::Config<module_multi_instance::Instance3> for Runtime {
+	type RuntimeHoldReason = RuntimeHoldReason;
+	type RuntimeFreezeReason = RuntimeFreezeReason;
+}
+
+impl module_composite_enum_consumer::Config for Runtime {
+	type RuntimeHoldReason = RuntimeHoldReason;
+	type RuntimeFreezeReason = RuntimeFreezeReason;
+}
+
+fn list_all_hold_reason_variants() -> Vec<RuntimeHoldReason> {
+	let variants = vec![
+		RuntimeHoldReason::ModuleSingleInstance(module_single_instance::HoldReason::ModuleSingleInstanceReason1),
+		RuntimeHoldReason::ModuleSingleInstance(module_single_instance::HoldReason::ModuleSingleInstanceReason2),
+		RuntimeHoldReason::ModuleMultiInstance0(<module_multi_instance::HoldReason>::ModuleMultiInstanceReason1),
+		RuntimeHoldReason::ModuleMultiInstance0(<module_multi_instance::HoldReason>::ModuleMultiInstanceReason2),
+		RuntimeHoldReason::ModuleMultiInstance0(<module_multi_instance::HoldReason>::ModuleMultiInstanceReason3),
+		RuntimeHoldReason::ModuleMultiInstance0(<module_multi_instance::HoldReason>::__Ignore(Default::default())),
+		RuntimeHoldReason::ModuleMultiInstance1(module_multi_instance::HoldReason::<module_multi_instance::Instance1>::ModuleMultiInstanceReason1),
+		RuntimeHoldReason::ModuleMultiInstance1(module_multi_instance::HoldReason::<module_multi_instance::Instance1>::ModuleMultiInstanceReason2),
+		RuntimeHoldReason::ModuleMultiInstance1(module_multi_instance::HoldReason::<module_multi_instance::Instance1>::ModuleMultiInstanceReason3),
+		RuntimeHoldReason::ModuleMultiInstance1(module_multi_instance::HoldReason::<module_multi_instance::Instance1>::__Ignore(Default::default())),
+		RuntimeHoldReason::ModuleMultiInstance2(module_multi_instance::HoldReason::<module_multi_instance::Instance2>::ModuleMultiInstanceReason1),
+		RuntimeHoldReason::ModuleMultiInstance2(module_multi_instance::HoldReason::<module_multi_instance::Instance2>::ModuleMultiInstanceReason2),
+		RuntimeHoldReason::ModuleMultiInstance2(module_multi_instance::HoldReason::<module_multi_instance::Instance2>::ModuleMultiInstanceReason3),
+		RuntimeHoldReason::ModuleMultiInstance2(module_multi_instance::HoldReason::<module_multi_instance::Instance2>::__Ignore(Default::default())),
+		RuntimeHoldReason::ModuleMultiInstance3(module_multi_instance::HoldReason::<module_multi_instance::Instance3>::ModuleMultiInstanceReason1),
+		RuntimeHoldReason::ModuleMultiInstance3(module_multi_instance::HoldReason::<module_multi_instance::Instance3>::ModuleMultiInstanceReason2),
+		RuntimeHoldReason::ModuleMultiInstance3(module_multi_instance::HoldReason::<module_multi_instance::Instance3>::ModuleMultiInstanceReason3),
+		RuntimeHoldReason::ModuleMultiInstance3(module_multi_instance::HoldReason::<module_multi_instance::Instance3>::__Ignore(Default::default())),
+	];
+	// check that we didn't miss any value
+	for v in &variants {
+		match v {
+			RuntimeHoldReason::ModuleSingleInstance(inner) => match inner {
+				module_single_instance::HoldReason::ModuleSingleInstanceReason1
+				| module_single_instance::HoldReason::ModuleSingleInstanceReason2 => (),
+			}
+			RuntimeHoldReason::ModuleMultiInstance0(inner) => match inner {
+				<module_multi_instance::HoldReason>::ModuleMultiInstanceReason1
+				| <module_multi_instance::HoldReason>::ModuleMultiInstanceReason2
+				| <module_multi_instance::HoldReason>::ModuleMultiInstanceReason3
+				| module_multi_instance::HoldReason::<()>::__Ignore(_) => (),
+			}
+			RuntimeHoldReason::ModuleMultiInstance1(inner) => match inner {
+				module_multi_instance::HoldReason::<module_multi_instance::Instance1>::ModuleMultiInstanceReason1
+				| module_multi_instance::HoldReason::<module_multi_instance::Instance1>::ModuleMultiInstanceReason2
+				| module_multi_instance::HoldReason::<module_multi_instance::Instance1>::ModuleMultiInstanceReason3
+				| module_multi_instance::HoldReason::<module_multi_instance::Instance1>::__Ignore(_) => (),
+			}
+			RuntimeHoldReason::ModuleMultiInstance2(inner) => match inner {
+				module_multi_instance::HoldReason::<module_multi_instance::Instance2>::ModuleMultiInstanceReason1
+				| module_multi_instance::HoldReason::<module_multi_instance::Instance2>::ModuleMultiInstanceReason2
+				| module_multi_instance::HoldReason::<module_multi_instance::Instance2>::ModuleMultiInstanceReason3
+				| module_multi_instance::HoldReason::<module_multi_instance::Instance2>::__Ignore(_) => (),
+			}
+			RuntimeHoldReason::ModuleMultiInstance3(inner) => match inner {
+				module_multi_instance::HoldReason::<module_multi_instance::Instance3>::ModuleMultiInstanceReason1
+				| module_multi_instance::HoldReason::<module_multi_instance::Instance3>::ModuleMultiInstanceReason2
+				| module_multi_instance::HoldReason::<module_multi_instance::Instance3>::ModuleMultiInstanceReason3
+				| module_multi_instance::HoldReason::<module_multi_instance::Instance3>::__Ignore(_) => (),
+			}
+		}
+	}
+	variants
+}
+
+fn list_all_freeze_reason_variants() -> Vec<RuntimeFreezeReason> {
+	let variants = vec![
+		RuntimeFreezeReason::ModuleSingleInstance(module_single_instance::FreezeReason::ModuleSingleInstanceReason1),
+		RuntimeFreezeReason::ModuleSingleInstance(module_single_instance::FreezeReason::ModuleSingleInstanceReason2),
+		RuntimeFreezeReason::ModuleMultiInstance0(<module_multi_instance::FreezeReason>::ModuleMultiInstanceReason1),
+		RuntimeFreezeReason::ModuleMultiInstance0(<module_multi_instance::FreezeReason>::__Ignore(Default::default())),
+		RuntimeFreezeReason::ModuleMultiInstance1(module_multi_instance::FreezeReason::<module_multi_instance::Instance1>::ModuleMultiInstanceReason1),
+		RuntimeFreezeReason::ModuleMultiInstance1(module_multi_instance::FreezeReason::<module_multi_instance::Instance1>::__Ignore(Default::default())),
+		RuntimeFreezeReason::ModuleMultiInstance2(module_multi_instance::FreezeReason::<module_multi_instance::Instance2>::ModuleMultiInstanceReason1),
+		RuntimeFreezeReason::ModuleMultiInstance2(module_multi_instance::FreezeReason::<module_multi_instance::Instance2>::__Ignore(Default::default())),
+		RuntimeFreezeReason::ModuleMultiInstance3(module_multi_instance::FreezeReason::<module_multi_instance::Instance3>::ModuleMultiInstanceReason1),
+		RuntimeFreezeReason::ModuleMultiInstance3(module_multi_instance::FreezeReason::<module_multi_instance::Instance3>::__Ignore(Default::default())),
+	];
+	// check that we didn't miss any value
+	for v in &variants {
+		match v {
+			RuntimeFreezeReason::ModuleSingleInstance(inner) => match inner {
+				module_single_instance::FreezeReason::ModuleSingleInstanceReason1
+				| module_single_instance::FreezeReason::ModuleSingleInstanceReason2 => (),
+			}
+			RuntimeFreezeReason::ModuleMultiInstance0(inner) => match inner {
+				<module_multi_instance::FreezeReason>::ModuleMultiInstanceReason1
+				| module_multi_instance::FreezeReason::<()>::__Ignore(_) => (),
+			}
+			RuntimeFreezeReason::ModuleMultiInstance1(inner) => match inner {
+				module_multi_instance::FreezeReason::<module_multi_instance::Instance1>::ModuleMultiInstanceReason1
+				| module_multi_instance::FreezeReason::<module_multi_instance::Instance1>::__Ignore(_) => (),
+			}
+			RuntimeFreezeReason::ModuleMultiInstance2(inner) => match inner {
+				module_multi_instance::FreezeReason::<module_multi_instance::Instance2>::ModuleMultiInstanceReason1
+				| module_multi_instance::FreezeReason::<module_multi_instance::Instance2>::__Ignore(_) => (),
+			}
+			RuntimeFreezeReason::ModuleMultiInstance3(inner) => match inner {
+				module_multi_instance::FreezeReason::<module_multi_instance::Instance3>::ModuleMultiInstanceReason1
+				| module_multi_instance::FreezeReason::<module_multi_instance::Instance3>::__Ignore(_) => (),
+			}
+		}
+	}
+	variants
+}
+
+#[test]
+fn runtime_hold_reason_variant_count_works() {
+	assert_eq!(RuntimeHoldReason::VARIANT_COUNT as usize, list_all_hold_reason_variants().len());
+}
+
+#[test]
+fn runtime_freeze_reason_variant_count_works() {
+	assert_eq!(
+		RuntimeFreezeReason::VARIANT_COUNT as usize,
+		list_all_freeze_reason_variants().len()
+	);
+}
+
+#[test]
+fn check_unique_encodings_for_hold_reason() {
+	let variants = list_all_hold_reason_variants();
+	let unique_encoded_variants =
+		variants.iter().map(|v| v.encode()).collect::<std::collections::HashSet<_>>();
+	assert_eq!(unique_encoded_variants.len(), variants.len());
+}
+
+#[test]
+fn check_unique_encodings_for_freeze_reason() {
+	let variants = list_all_freeze_reason_variants();
+	let unique_encoded_variants =
+		variants.iter().map(|v| v.encode()).collect::<std::collections::HashSet<_>>();
+	assert_eq!(unique_encoded_variants.len(), variants.len());
+}
diff --git a/substrate/frame/tips/src/tests.rs b/substrate/frame/tips/src/tests.rs
index b8e528bbe7a..9d4047cd80e 100644
--- a/substrate/frame/tips/src/tests.rs
+++ b/substrate/frame/tips/src/tests.rs
@@ -98,7 +98,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 parameter_types! {
 	static TenToFourteenTestValue: Vec<u128> = vec![10,11,12,13,14];
diff --git a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs
index 52ff3eb9905..c8bf2eb8f44 100644
--- a/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs
+++ b/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/mock.rs
@@ -129,7 +129,6 @@ impl pallet_balances::Config for Runtime {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl WeightToFeeT for WeightToFee {
diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs
index 03142d6ae37..1f335b4f6c4 100644
--- a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs
+++ b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs
@@ -116,7 +116,6 @@ impl pallet_balances::Config for Runtime {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl WeightToFeeT for WeightToFee {
diff --git a/substrate/frame/transaction-payment/src/mock.rs b/substrate/frame/transaction-payment/src/mock.rs
index 2f025ae81d2..1ca2e3d7347 100644
--- a/substrate/frame/transaction-payment/src/mock.rs
+++ b/substrate/frame/transaction-payment/src/mock.rs
@@ -111,7 +111,6 @@ impl pallet_balances::Config for Runtime {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl WeightToFeeT for WeightToFee {
diff --git a/substrate/frame/treasury/src/tests.rs b/substrate/frame/treasury/src/tests.rs
index 602159262e4..e35d50e23a3 100644
--- a/substrate/frame/treasury/src/tests.rs
+++ b/substrate/frame/treasury/src/tests.rs
@@ -94,7 +94,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl pallet_utility::Config for Test {
diff --git a/substrate/frame/tx-pause/src/mock.rs b/substrate/frame/tx-pause/src/mock.rs
index 4f1c981abc6..8ccdc43a46c 100644
--- a/substrate/frame/tx-pause/src/mock.rs
+++ b/substrate/frame/tx-pause/src/mock.rs
@@ -80,7 +80,6 @@ impl pallet_balances::Config for Test {
 	type FreezeIdentifier = ();
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
-	type MaxHolds = ConstU32<0>;
 	type MaxFreezes = ConstU32<0>;
 }
 
diff --git a/substrate/frame/uniques/src/mock.rs b/substrate/frame/uniques/src/mock.rs
index 9120108e0d4..16da2b2a2e2 100644
--- a/substrate/frame/uniques/src/mock.rs
+++ b/substrate/frame/uniques/src/mock.rs
@@ -82,7 +82,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl Config for Test {
diff --git a/substrate/frame/utility/src/tests.rs b/substrate/frame/utility/src/tests.rs
index cfdbd6faf0d..1a1196cb4c0 100644
--- a/substrate/frame/utility/src/tests.rs
+++ b/substrate/frame/utility/src/tests.rs
@@ -185,7 +185,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl pallet_root_testing::Config for Test {
diff --git a/substrate/frame/vesting/src/mock.rs b/substrate/frame/vesting/src/mock.rs
index 420edd5e17a..befe8cd3b76 100644
--- a/substrate/frame/vesting/src/mock.rs
+++ b/substrate/frame/vesting/src/mock.rs
@@ -80,7 +80,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 parameter_types! {
 	pub const MinVestedTransfer: u64 = 256 * 2;
diff --git a/substrate/frame/whitelist/src/mock.rs b/substrate/frame/whitelist/src/mock.rs
index 200e589c6aa..c0c38075f29 100644
--- a/substrate/frame/whitelist/src/mock.rs
+++ b/substrate/frame/whitelist/src/mock.rs
@@ -85,7 +85,6 @@ impl pallet_balances::Config for Test {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = ();
 	type RuntimeFreezeReason = ();
-	type MaxHolds = ();
 }
 
 impl pallet_preimage::Config for Test {
diff --git a/substrate/test-utils/runtime/src/lib.rs b/substrate/test-utils/runtime/src/lib.rs
index ea237649396..8bc6f72a82e 100644
--- a/substrate/test-utils/runtime/src/lib.rs
+++ b/substrate/test-utils/runtime/src/lib.rs
@@ -398,7 +398,6 @@ impl pallet_balances::Config for Runtime {
 	type MaxFreezes = ();
 	type RuntimeHoldReason = RuntimeHoldReason;
 	type RuntimeFreezeReason = RuntimeFreezeReason;
-	type MaxHolds = ConstU32<1>;
 }
 
 impl substrate_test_pallet::Config for Runtime {}
-- 
GitLab