Repository: paritytech/polkadot-sdk (language: rust)

Issue:
Fungible and fungibles adapters should allow account death like burns and mints
The fungible and fungibles adapters set the preservation of the burn operation to `Expendable`: [here](https://github.com/paritytech/polkadot-sdk/blob/f3ab3854e1df9e0498599f01ba4f9f152426432a/polkadot/xcm/xcm-builder/src/fungible_adapter.rs#L217) and [here](https://github.com/paritytech/polkadot-sdk/blob/f3ab3854e1df9e0498599f01ba4f9f152426432a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs#L303).
This allows accounts to transfer all their funds (and getting reaped because of it) out of their account.
However, this only works if they're using the `WithdrawAsset` and `DepositAsset` instructions, which correspond to `burn_from` and `mint_into`.
If `TransferAsset` is used, as is the case with [limited_reserve_assets_transfer](https://github.com/paritytech/polkadot-sdk/blob/f3ab3854e1df9e0498599f01ba4f9f152426432a/polkadot/xcm/pallet-xcm/src/lib.rs#L1881), then the [`transfer` function will be called with `Preserve`](https://github.com/paritytech/polkadot-sdk/blob/f3ab3854e1df9e0498599f01ba4f9f152426432a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs#L61).

This distinction is arbitrary and we should change the way `TransferAsset` is handled to also allow transferring all the funds of an account. It results in confusing errors for users.
If needed, we could add a [Hint](https://github.com/paritytech/polkadot-sdk/blob/f3ab3854e1df9e0498599f01ba4f9f152426432a/polkadot/xcm/src/v5/mod.rs#L1145) for changing the default of ALL operations from `Expendable` to `Preserve`.



Discussion / hints:
Very much needed
I would like to work on this one.
@dhirajs0 Thank you for wanting to work on this! Let me know if everything is understood or if you have any questions. I'm here to help.

@franciscoaguirre 

> This distinction is arbitrary and we should change the way TransferAsset is handled to also allow transferring all the funds of an account. It results in confusing errors for users.

We can change the Preservation of [`transfer ` function](https://github.com/paritytech/polkadot-sdk/blob/f3ab3854e1df9e0498599f01ba4f9f152426432a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs#L61) from Preserve to Expendable so that the behavior will be consistent with the  `WithdrawAsset ` function, as in [fungible](https://github.com/paritytech/polkadot-sdk/blob/f3ab3854e1df9e0498599f01ba4f9f152426432a/polkadot/xcm/xcm-builder/src/fungible_adapter.rs#L217) and [fungibles](url) adapter.

> If needed, we could add a [Hint](https://github.com/paritytech/polkadot-sdk/blob/f3ab3854e1df9e0498599f01ba4f9f152426432a/polkadot/xcm/src/v5/mod.rs#L1145) for changing the default of ALL operations from Expendable to Preserve.

If we add `PreservationType { preservation: Preservation }` to the [Hint](https://github.com/paritytech/polkadot-sdk/blob/f3ab3854e1df9e0498599f01ba4f9f152426432a/polkadot/xcm/src/v5/mod.rs#L1145) and import `use frame_support::traits::tokens::Preservation;` in the same file(mod.rs), and then while building xcm instruction the `set_hints(vec![PreservationType { preservation: Preserve}])` method is called, is this good enough to change the default of ALL operations from Expendable to Preserve or do we need to make more changes for the PreservationType hint to works?
> We can change the Preservation of [`transfer ` function](https://github.com/paritytech/polkadot-sdk/blob/f3ab3854e1df9e0498599f01ba4f9f152426432a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs#L61) from Preserve to Expendable so that the behavior will be consistent with the `WithdrawAsset ` function, as in [fungible](https://github.com/paritytech/polkadot-sdk/blob/f3ab3854e1df9e0498599f01ba4f9f152426432a/polkadot/xcm/xcm-builder/src/fungible_adapter.rs#L217) and [fungibles](url) adapter.

Yes, we should do exactly this.

> If we add `PreservationType { preservation: Preservation }` to the [Hint](https://github.com/paritytech/polkadot-sdk/blob/f3ab3854e1df9e0498599f01ba4f9f152426432a/polkadot/xcm/src/v5/mod.rs#L1145) and import `use frame_support::traits::tokens::Preservation;` in the same file(mod.rs), and then while building xcm instruction the `set_hints(vec![PreservationType { preservation: Preserve}])` method is called, is this good enough to change the default of ALL operations from Expendable to Preserve or do we need to make more changes for the PreservationType hint to works?

We can't add a new Hint now because XCMv5 is already frozen, released in stable2412. But for XCMv6 for example, we can add a hint `PreserveAccounts: bool` that just lets you specify whether you want to make sure to preserve accounts. I think it's much simpler if it's just a bool.
But for now, don't worry about the hint, we can add it later.

Hi @franciscoaguirre,

Thanks for the clarification! 

I’ve raised a PR to address this issue. Would greatly appreciate it if you could review it and share your feedback when you have a moment.

Fix patch:
diff --git a/polkadot/xcm/xcm-builder/src/fungible_adapter.rs b/polkadot/xcm/xcm-builder/src/fungible_adapter.rs
index 25a705a39eb73..2da772deb0ed7 100644
--- a/polkadot/xcm/xcm-builder/src/fungible_adapter.rs
+++ b/polkadot/xcm/xcm-builder/src/fungible_adapter.rs
@@ -20,11 +20,7 @@ use super::MintLocation;
 use core::{marker::PhantomData, result};
 use frame_support::traits::{
 	tokens::{
-		fungible,
-		Fortitude::Polite,
-		Precision::Exact,
-		Preservation::{Expendable, Preserve},
-		Provenance::Minted,
+		fungible, Fortitude::Polite, Precision::Exact, Preservation::Expendable, Provenance::Minted,
 	},
 	Get,
 };
@@ -64,7 +60,7 @@ impl<
 			.ok_or(MatchError::AccountIdConversionFailed)?;
 		let dest = AccountIdConverter::convert_location(to)
 			.ok_or(MatchError::AccountIdConversionFailed)?;
-		Fungible::transfer(&source, &dest, amount, Preserve)
+		Fungible::transfer(&source, &dest, amount, Expendable)
 			.map_err(|error| XcmError::FailedToTransactAsset(error.into()))?;
 		Ok(what.clone().into())
 	}
diff --git a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs b/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs
index a259afc6e6825..59b4ccb13d0c5 100644
--- a/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs
+++ b/polkadot/xcm/xcm-builder/src/fungibles_adapter.rs
@@ -19,10 +19,7 @@
 use core::{marker::PhantomData, result};
 use frame_support::traits::{
 	tokens::{
-		fungibles,
-		Fortitude::Polite,
-		Precision::Exact,
-		Preservation::{Expendable, Preserve},
+		fungibles, Fortitude::Polite, Precision::Exact, Preservation::Expendable,
 		Provenance::Minted,
 	},
 	Contains, Get,
@@ -58,7 +55,7 @@ impl<
 			.ok_or(MatchError::AccountIdConversionFailed)?;
 		let dest = AccountIdConverter::convert_location(to)
 			.ok_or(MatchError::AccountIdConversionFailed)?;
-		Assets::transfer(asset_id, &source, &dest, amount, Preserve)
+		Assets::transfer(asset_id, &source, &dest, amount, Expendable)
 			.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
 		Ok(what.clone().into())
 	}
diff --git a/prdoc/pr_7243.prdoc b/prdoc/pr_7243.prdoc
new file mode 100644
index 0000000000000..c04017c29ce43
--- /dev/null
+++ b/prdoc/pr_7243.prdoc
@@ -0,0 +1,13 @@
+# 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: 'transfer function Preservation is changed to Expendable in fungible and fungibles adapter'
+
+doc:
+  - audience: Runtime Dev
+    description: |
+      The Preservation of transfer method of fungible and fungibles adapters is changed from Preserve to Expendable. So the behavior of the TransferAsset will be consistent with the WithdrawAsset function, as in fungible and fungibles adapter.
+
+crates: 
+- name: staging-xcm-builder
+  bump: patch
\ No newline at end of file


Test patch: