diff --git a/prdoc/pr_3800.prdoc b/prdoc/pr_3800.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..3396e8c21612d2794deb3a43a977526eb26670cb
--- /dev/null
+++ b/prdoc/pr_3800.prdoc
@@ -0,0 +1,12 @@
+# 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: Remove deprecated calls from treasury pallet
+
+doc:
+  - audience: Runtime Dev
+    description: |
+      This PR remove deprecated calls, relevant tests from `pallet-treasury`
+
+crates:
+  - name: pallet-treasury
diff --git a/substrate/frame/treasury/README.md b/substrate/frame/treasury/README.md
index 4945d79d1429694a1c8db79e8508561f515163da..2bd58a9817aab8efb47dc83752b817d6e11a59a2 100644
--- a/substrate/frame/treasury/README.md
+++ b/substrate/frame/treasury/README.md
@@ -26,6 +26,14 @@ and use the funds to pay developers.
 ### Dispatchable Functions
 
 General spending/proposal protocol:
-- `propose_spend` - Make a spending proposal and stake the required deposit.
-- `reject_proposal` - Reject a proposal, slashing the deposit.
-- `approve_proposal` - Accept the proposal, returning the deposit.
+- `spend_local` - Propose and approve a spend of treasury funds, enables the
+  creation of spends using the native currency of the chain, utilizing the funds
+  stored in the pot
+- `spend` - Propose and approve a spend of treasury funds, allows spending any
+  asset kind managed by the treasury
+- `remove_approval` - Force a previously approved proposal to be removed from
+  the approval queue
+- `payout` - Claim a spend
+- `check_status` - Check the status of the spend and remove it from the storage
+  if processed
+- `void_spend` - Void previously approved spend
diff --git a/substrate/frame/treasury/src/lib.rs b/substrate/frame/treasury/src/lib.rs
index 5e429d3914bd0c60ea24eb53825c4da4b6a07fe5..f7873fe51004fa8d974799fd9215e1ee65b8a6b4 100644
--- a/substrate/frame/treasury/src/lib.rs
+++ b/substrate/frame/treasury/src/lib.rs
@@ -203,9 +203,6 @@ pub mod pallet {
 		/// The staking balance.
 		type Currency: Currency<Self::AccountId> + ReservableCurrency<Self::AccountId>;
 
-		/// Origin from which approvals must come.
-		type ApproveOrigin: EnsureOrigin<Self::RuntimeOrigin>;
-
 		/// Origin from which rejections must come.
 		type RejectOrigin: EnsureOrigin<Self::RuntimeOrigin>;
 
@@ -361,14 +358,10 @@ pub mod pallet {
 	#[pallet::event]
 	#[pallet::generate_deposit(pub(super) fn deposit_event)]
 	pub enum Event<T: Config<I>, I: 'static = ()> {
-		/// New proposal.
-		Proposed { proposal_index: ProposalIndex },
 		/// We have ended a spend period and will now allocate funds.
 		Spending { budget_remaining: BalanceOf<T, I> },
 		/// Some funds have been allocated.
 		Awarded { proposal_index: ProposalIndex, award: BalanceOf<T, I>, account: T::AccountId },
-		/// A proposal was rejected; funds were slashed.
-		Rejected { proposal_index: ProposalIndex, slashed: BalanceOf<T, I> },
 		/// Some of our funds have been burnt.
 		Burnt { burnt_funds: BalanceOf<T, I> },
 		/// Spending has finished; this is the amount that rolls over until next spend.
@@ -406,8 +399,6 @@ pub mod pallet {
 	/// Error for the treasury pallet.
 	#[pallet::error]
 	pub enum Error<T, I = ()> {
-		/// Proposer's balance is too low.
-		InsufficientProposersBalance,
 		/// No proposal, bounty or spend at that index.
 		InvalidIndex,
 		/// Too many approvals in the queue.
@@ -474,123 +465,6 @@ pub mod pallet {
 
 	#[pallet::call]
 	impl<T: Config<I>, I: 'static> Pallet<T, I> {
-		/// Put forward a suggestion for spending.
-		///
-		/// ## Dispatch Origin
-		///
-		/// Must be signed.
-		///
-		/// ## Details
-		/// A deposit proportional to the value is reserved and slashed if the proposal is rejected.
-		/// It is returned once the proposal is awarded.
-		///
-		/// ### Complexity
-		/// - O(1)
-		///
-		/// ## Events
-		///
-		/// Emits [`Event::Proposed`] if successful.
-		#[pallet::call_index(0)]
-		#[pallet::weight(T::WeightInfo::propose_spend())]
-		#[allow(deprecated)]
-		#[deprecated(
-			note = "`propose_spend` will be removed in February 2024. Use `spend` instead."
-		)]
-		pub fn propose_spend(
-			origin: OriginFor<T>,
-			#[pallet::compact] value: BalanceOf<T, I>,
-			beneficiary: AccountIdLookupOf<T>,
-		) -> DispatchResult {
-			let proposer = ensure_signed(origin)?;
-			let beneficiary = T::Lookup::lookup(beneficiary)?;
-
-			let bond = Self::calculate_bond(value);
-			T::Currency::reserve(&proposer, bond)
-				.map_err(|_| Error::<T, I>::InsufficientProposersBalance)?;
-
-			let c = Self::proposal_count();
-			<ProposalCount<T, I>>::put(c + 1);
-			<Proposals<T, I>>::insert(c, Proposal { proposer, value, beneficiary, bond });
-
-			Self::deposit_event(Event::Proposed { proposal_index: c });
-			Ok(())
-		}
-
-		/// Reject a proposed spend.
-		///
-		/// ## Dispatch Origin
-		///
-		/// Must be [`Config::RejectOrigin`].
-		///
-		/// ## Details
-		/// The original deposit will be slashed.
-		///
-		/// ### Complexity
-		/// - O(1)
-		///
-		/// ## Events
-		///
-		/// Emits [`Event::Rejected`] if successful.
-		#[pallet::call_index(1)]
-		#[pallet::weight((T::WeightInfo::reject_proposal(), DispatchClass::Operational))]
-		#[allow(deprecated)]
-		#[deprecated(
-			note = "`reject_proposal` will be removed in February 2024. Use `spend` instead."
-		)]
-		pub fn reject_proposal(
-			origin: OriginFor<T>,
-			#[pallet::compact] proposal_id: ProposalIndex,
-		) -> DispatchResult {
-			T::RejectOrigin::ensure_origin(origin)?;
-
-			let proposal =
-				<Proposals<T, I>>::take(&proposal_id).ok_or(Error::<T, I>::InvalidIndex)?;
-			let value = proposal.bond;
-			let imbalance = T::Currency::slash_reserved(&proposal.proposer, value).0;
-			T::OnSlash::on_unbalanced(imbalance);
-
-			Self::deposit_event(Event::<T, I>::Rejected {
-				proposal_index: proposal_id,
-				slashed: value,
-			});
-			Ok(())
-		}
-
-		/// Approve a proposal.
-		///
-		/// ## Dispatch Origin
-		///
-		/// Must be [`Config::ApproveOrigin`].
-		///
-		/// ## Details
-		///
-		/// At a later time, the proposal will be allocated to the beneficiary and the original
-		/// deposit will be returned.
-		///
-		/// ### Complexity
-		///  - O(1).
-		///
-		/// ## Events
-		///
-		/// No events are emitted from this dispatch.
-		#[pallet::call_index(2)]
-		#[pallet::weight((T::WeightInfo::approve_proposal(T::MaxApprovals::get()), DispatchClass::Operational))]
-		#[allow(deprecated)]
-		#[deprecated(
-			note = "`approve_proposal` will be removed in February 2024. Use `spend` instead."
-		)]
-		pub fn approve_proposal(
-			origin: OriginFor<T>,
-			#[pallet::compact] proposal_id: ProposalIndex,
-		) -> DispatchResult {
-			T::ApproveOrigin::ensure_origin(origin)?;
-
-			ensure!(<Proposals<T, I>>::contains_key(proposal_id), Error::<T, I>::InvalidIndex);
-			Approvals::<T, I>::try_append(proposal_id)
-				.map_err(|_| Error::<T, I>::TooManyApprovals)?;
-			Ok(())
-		}
-
 		/// Propose and approve a spend of treasury funds.
 		///
 		/// ## Dispatch Origin
diff --git a/substrate/frame/treasury/src/tests.rs b/substrate/frame/treasury/src/tests.rs
index 67d81cb5c30224e68a2b72bcda3255273304b14a..11e9f76c5b8a5d263d3eaa31494250e1f6487c77 100644
--- a/substrate/frame/treasury/src/tests.rs
+++ b/substrate/frame/treasury/src/tests.rs
@@ -152,6 +152,7 @@ impl frame_support::traits::EnsureOrigin<RuntimeOrigin> for TestSpendOrigin {
 			frame_system::RawOrigin::Signed(11) => Ok(10),
 			frame_system::RawOrigin::Signed(12) => Ok(20),
 			frame_system::RawOrigin::Signed(13) => Ok(50),
+			frame_system::RawOrigin::Signed(14) => Ok(500),
 			r => Err(RuntimeOrigin::from(r)),
 		})
 	}
@@ -174,7 +175,6 @@ impl<N: Get<u64>> ConversionFromAssetBalance<u64, u32, u64> for MulBy<N> {
 impl Config for Test {
 	type PalletId = TreasuryPalletId;
 	type Currency = pallet_balances::Pallet<Test>;
-	type ApproveOrigin = frame_system::EnsureRoot<u128>;
 	type RejectOrigin = frame_system::EnsureRoot<u128>;
 	type RuntimeEvent = RuntimeEvent;
 	type OnSlash = ();
@@ -295,56 +295,12 @@ fn minting_works() {
 	});
 }
 
-#[test]
-fn spend_proposal_takes_min_deposit() {
-	ExtBuilder::default().build().execute_with(|| {
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 1, 3)
-		});
-		assert_eq!(Balances::free_balance(0), 99);
-		assert_eq!(Balances::reserved_balance(0), 1);
-	});
-}
-
-#[test]
-fn spend_proposal_takes_proportional_deposit() {
-	ExtBuilder::default().build().execute_with(|| {
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 100, 3)
-		});
-		assert_eq!(Balances::free_balance(0), 95);
-		assert_eq!(Balances::reserved_balance(0), 5);
-	});
-}
-
-#[test]
-fn spend_proposal_fails_when_proposer_poor() {
-	ExtBuilder::default().build().execute_with(|| {
-		assert_noop!(
-			{
-				#[allow(deprecated)]
-				Treasury::propose_spend(RuntimeOrigin::signed(2), 100, 3)
-			},
-			Error::<Test, _>::InsufficientProposersBalance,
-		);
-	});
-}
-
 #[test]
 fn accepted_spend_proposal_ignored_outside_spend_period() {
 	ExtBuilder::default().build().execute_with(|| {
 		Balances::make_free_balance_be(&Treasury::account_id(), 101);
 
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 100, 3)
-		});
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::approve_proposal(RuntimeOrigin::root(), 0)
-		});
+		assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(14), 100, 3));
 
 		<Treasury as OnInitialize<u64>>::on_initialize(1);
 		assert_eq!(Balances::free_balance(3), 0);
@@ -365,112 +321,13 @@ fn unused_pot_should_diminish() {
 	});
 }
 
-#[test]
-fn rejected_spend_proposal_ignored_on_spend_period() {
-	ExtBuilder::default().build().execute_with(|| {
-		Balances::make_free_balance_be(&Treasury::account_id(), 101);
-
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 100, 3)
-		});
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::reject_proposal(RuntimeOrigin::root(), 0)
-		});
-
-		<Treasury as OnInitialize<u64>>::on_initialize(2);
-		assert_eq!(Balances::free_balance(3), 0);
-		assert_eq!(Treasury::pot(), 50);
-	});
-}
-
-#[test]
-fn reject_already_rejected_spend_proposal_fails() {
-	ExtBuilder::default().build().execute_with(|| {
-		Balances::make_free_balance_be(&Treasury::account_id(), 101);
-
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 100, 3)
-		});
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::reject_proposal(RuntimeOrigin::root(), 0)
-		});
-		assert_noop!(
-			{
-				#[allow(deprecated)]
-				Treasury::reject_proposal(RuntimeOrigin::root(), 0)
-			},
-			Error::<Test, _>::InvalidIndex
-		);
-	});
-}
-
-#[test]
-fn reject_non_existent_spend_proposal_fails() {
-	ExtBuilder::default().build().execute_with(|| {
-		assert_noop!(
-			{
-				#[allow(deprecated)]
-				Treasury::reject_proposal(RuntimeOrigin::root(), 0)
-			},
-			Error::<Test, _>::InvalidIndex
-		);
-	});
-}
-
-#[test]
-fn accept_non_existent_spend_proposal_fails() {
-	ExtBuilder::default().build().execute_with(|| {
-		assert_noop!(
-			{
-				#[allow(deprecated)]
-				Treasury::approve_proposal(RuntimeOrigin::root(), 0)
-			},
-			Error::<Test, _>::InvalidIndex
-		);
-	});
-}
-
-#[test]
-fn accept_already_rejected_spend_proposal_fails() {
-	ExtBuilder::default().build().execute_with(|| {
-		Balances::make_free_balance_be(&Treasury::account_id(), 101);
-
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 100, 3)
-		});
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::reject_proposal(RuntimeOrigin::root(), 0)
-		});
-		assert_noop!(
-			{
-				#[allow(deprecated)]
-				Treasury::approve_proposal(RuntimeOrigin::root(), 0)
-			},
-			Error::<Test, _>::InvalidIndex
-		);
-	});
-}
-
 #[test]
 fn accepted_spend_proposal_enacted_on_spend_period() {
 	ExtBuilder::default().build().execute_with(|| {
 		Balances::make_free_balance_be(&Treasury::account_id(), 101);
 		assert_eq!(Treasury::pot(), 100);
 
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 100, 3)
-		});
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::approve_proposal(RuntimeOrigin::root(), 0)
-		});
+		assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(14), 100, 3));
 
 		<Treasury as OnInitialize<u64>>::on_initialize(2);
 		assert_eq!(Balances::free_balance(3), 100);
@@ -484,14 +341,7 @@ fn pot_underflow_should_not_diminish() {
 		Balances::make_free_balance_be(&Treasury::account_id(), 101);
 		assert_eq!(Treasury::pot(), 100);
 
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 150, 3)
-		});
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::approve_proposal(RuntimeOrigin::root(), 0)
-		});
+		assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(14), 150, 3));
 
 		<Treasury as OnInitialize<u64>>::on_initialize(2);
 		assert_eq!(Treasury::pot(), 100); // Pot hasn't changed
@@ -512,26 +362,12 @@ fn treasury_account_doesnt_get_deleted() {
 		assert_eq!(Treasury::pot(), 100);
 		let treasury_balance = Balances::free_balance(&Treasury::account_id());
 
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), treasury_balance, 3)
-		});
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::approve_proposal(RuntimeOrigin::root(), 0)
-		});
+		assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(14), treasury_balance, 3));
 
 		<Treasury as OnInitialize<u64>>::on_initialize(2);
 		assert_eq!(Treasury::pot(), 100); // Pot hasn't changed
 
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), Treasury::pot(), 3)
-		});
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::approve_proposal(RuntimeOrigin::root(), 1)
-		});
+		assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(14), Treasury::pot(), 3));
 
 		<Treasury as OnInitialize<u64>>::on_initialize(4);
 		assert_eq!(Treasury::pot(), 0); // Pot is emptied
@@ -554,22 +390,9 @@ fn inexistent_account_works() {
 		assert_eq!(Balances::free_balance(Treasury::account_id()), 0); // Account does not exist
 		assert_eq!(Treasury::pot(), 0); // Pot is empty
 
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 99, 3)
-		});
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::approve_proposal(RuntimeOrigin::root(), 0)
-		});
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 1, 3)
-		});
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::approve_proposal(RuntimeOrigin::root(), 1)
-		});
+		assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(14), 99, 3));
+		assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(14), 1, 3));
+
 		<Treasury as OnInitialize<u64>>::on_initialize(2);
 		assert_eq!(Treasury::pot(), 0); // Pot hasn't changed
 		assert_eq!(Balances::free_balance(3), 0); // Balance of `3` hasn't changed
@@ -611,26 +434,12 @@ fn max_approvals_limited() {
 		Balances::make_free_balance_be(&0, u64::MAX);
 
 		for _ in 0..<Test as Config>::MaxApprovals::get() {
-			assert_ok!({
-				#[allow(deprecated)]
-				Treasury::propose_spend(RuntimeOrigin::signed(0), 100, 3)
-			});
-			assert_ok!({
-				#[allow(deprecated)]
-				Treasury::approve_proposal(RuntimeOrigin::root(), 0)
-			});
+			assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(14), 100, 3));
 		}
 
 		// One too many will fail
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 100, 3)
-		});
 		assert_noop!(
-			{
-				#[allow(deprecated)]
-				Treasury::approve_proposal(RuntimeOrigin::root(), 0)
-			},
+			Treasury::spend_local(RuntimeOrigin::signed(14), 100, 3),
 			Error::<Test, _>::TooManyApprovals
 		);
 	});
@@ -641,14 +450,8 @@ fn remove_already_removed_approval_fails() {
 	ExtBuilder::default().build().execute_with(|| {
 		Balances::make_free_balance_be(&Treasury::account_id(), 101);
 
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 100, 3)
-		});
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::approve_proposal(RuntimeOrigin::root(), 0)
-		});
+		assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(14), 100, 3));
+
 		assert_eq!(Treasury::approvals(), vec![0]);
 		assert_ok!(Treasury::remove_approval(RuntimeOrigin::root(), 0));
 		assert_eq!(Treasury::approvals(), vec![]);
@@ -978,91 +781,6 @@ fn check_status_works() {
 	});
 }
 
-#[test]
-fn try_state_proposals_invariant_1_works() {
-	ExtBuilder::default().build().execute_with(|| {
-		use frame_support::pallet_prelude::DispatchError::Other;
-		// Add a proposal using `propose_spend`
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 1, 3)
-		});
-		assert_eq!(Proposals::<Test>::iter().count(), 1);
-		assert_eq!(ProposalCount::<Test>::get(), 1);
-		// Check invariant 1 holds
-		assert!(ProposalCount::<Test>::get() as usize >= Proposals::<Test>::iter().count());
-		// Break invariant 1 by decreasing `ProposalCount`
-		ProposalCount::<Test>::put(0);
-		// Invariant 1 should be violated
-		assert_eq!(
-			Treasury::do_try_state(),
-			Err(Other("Actual number of proposals exceeds `ProposalCount`."))
-		);
-	});
-}
-
-#[test]
-fn try_state_proposals_invariant_2_works() {
-	ExtBuilder::default().build().execute_with(|| {
-		use frame_support::pallet_prelude::DispatchError::Other;
-		// Add a proposal using `propose_spend`
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 1, 3)
-		});
-		assert_eq!(Proposals::<Test>::iter().count(), 1);
-		let current_proposal_count = ProposalCount::<Test>::get();
-		assert_eq!(current_proposal_count, 1);
-		// Check invariant 2 holds
-		assert!(
-			Proposals::<Test>::iter_keys()
-			.all(|proposal_index| {
-					proposal_index < current_proposal_count
-			})
-		);
-		// Break invariant 2 by inserting the proposal under key = 1
-		let proposal = Proposals::<Test>::take(0).unwrap();
-		Proposals::<Test>::insert(1, proposal);
-		// Invariant 2 should be violated
-		assert_eq!(
-			Treasury::do_try_state(),
-			Err(Other("`ProposalCount` should by strictly greater than any ProposalIndex used as a key for `Proposals`."))
-		);
-	});
-}
-
-#[test]
-fn try_state_proposals_invariant_3_works() {
-	ExtBuilder::default().build().execute_with(|| {
-		use frame_support::pallet_prelude::DispatchError::Other;
-		// Add a proposal using `propose_spend`
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::propose_spend(RuntimeOrigin::signed(0), 10, 3)
-		});
-		assert_eq!(Proposals::<Test>::iter().count(), 1);
-		// Approve the proposal
-		assert_ok!({
-			#[allow(deprecated)]
-			Treasury::approve_proposal(RuntimeOrigin::root(), 0)
-		});
-		assert_eq!(Approvals::<Test>::get().len(), 1);
-		// Check invariant 3 holds
-		assert!(Approvals::<Test>::get()
-			.iter()
-			.all(|proposal_index| { Proposals::<Test>::contains_key(proposal_index) }));
-		// Break invariant 3 by adding another key to `Approvals`
-		let mut approvals_modified = Approvals::<Test>::get();
-		approvals_modified.try_push(2).unwrap();
-		Approvals::<Test>::put(approvals_modified);
-		// Invariant 3 should be violated
-		assert_eq!(
-			Treasury::do_try_state(),
-			Err(Other("Proposal indices in `Approvals` must also be contained in `Proposals`."))
-		);
-	});
-}
-
 #[test]
 fn try_state_spends_invariant_1_works() {
 	ExtBuilder::default().build().execute_with(|| {