diff --git a/prdoc/pr_4346.prdoc b/prdoc/pr_4346.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..e222dec885ced40df8b4b783078e88b0b1e42f40
--- /dev/null
+++ b/prdoc/pr_4346.prdoc
@@ -0,0 +1,17 @@
+# 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: Allow for 0 existential deposit in benchmarks for pallet_staking, pallet_session, and pallet_balances
+
+doc:
+  - audience: Runtime Dev
+    description: |
+      Changes were made to benchmarks for `pallet_staking`, `pallet_session`, and `pallet-balances` to accommodate runtimes with 0 existential deposit. This should not affect the vast majority of runtimes. For runtimes with 0 existential deposit, the benchmarks for `pallet_staking` and `pallet_session` will still fail when using `U128CurrencyToVote` in the `pallet-staking` config; developers can use or write another `CurrencyToVote` implementation for benchmarking to work around this.
+
+crates:
+  - name: pallet-staking
+    bump: patch
+  - name: pallet-session-benchmarking
+    bump: patch
+  - name: pallet-balances
+    bump: patch
diff --git a/substrate/frame/balances/src/benchmarking.rs b/substrate/frame/balances/src/benchmarking.rs
index 0ce1240eb5d3987e43f7dba2734cec3b6fbea62a..14f0ede5e0f244255c5928060e983b00dce985fa 100644
--- a/substrate/frame/balances/src/benchmarking.rs
+++ b/substrate/frame/balances/src/benchmarking.rs
@@ -44,7 +44,7 @@ mod benchmarks {
 		let caller = whitelisted_caller();
 
 		// Give some multiple of the existential deposit
-		let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into());
+		let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()).max(1u32.into());
 		let _ = <Balances<T, I> as Currency<_>>::make_free_balance_be(&caller, balance);
 
 		// Transfer `e - 1` existential deposits + 1 unit, which guarantees to create one account,
diff --git a/substrate/frame/staking/src/testing_utils.rs b/substrate/frame/staking/src/testing_utils.rs
index 28e08230d701d6cc477c840311b274d0535a88bf..d4938ea43ebe2800b3894a21e17f93e45d591ff5 100644
--- a/substrate/frame/staking/src/testing_utils.rs
+++ b/substrate/frame/staking/src/testing_utils.rs
@@ -77,7 +77,8 @@ pub fn create_stash_controller<T: Config>(
 	destination: RewardDestination<T::AccountId>,
 ) -> Result<(T::AccountId, T::AccountId), &'static str> {
 	let staker = create_funded_user::<T>("stash", n, balance_factor);
-	let amount = T::Currency::minimum_balance() * (balance_factor / 10).max(1).into();
+	let amount =
+		T::Currency::minimum_balance().max(1u64.into()) * (balance_factor / 10).max(1).into();
 	Staking::<T>::bond(RawOrigin::Signed(staker.clone()).into(), amount, destination)?;
 	Ok((staker.clone(), staker))
 }