# Deprecate Currency; introduce holds and freezing into fungible traits - [PR #12951](https://github.com/paritytech/substrate/pull/12951) In general : - **Goodbye** `Currency` (will be deprecated) - **Hello** Holds & Freezes in `fungible` ## 🗓️ Timelines 🗓️ - Timeline for `transfer` to be deprecated https://hackmd.io/@LwMsxe3-SFmNXxugAXOKgg/HkTK8Yq4h ### Timeline for `transfer_allow_death` to become available #### Kusama Expected approx date on Kusama ecosystem : - 11/05/2023 : Referendum Deciding - runtime upgrade v9420 Kusama and System Parachains [#190](https://kusama.subsquare.io/referenda/referendum/190) - 18/05/2023 : Referendum is expected to be Enacted (**1 week** community votes for runtime upgrades) #### Polkadot Expected approx date on Polkadot ecosystem : - 07/03/2023 : Last runtime upgrade of polkadot (v9370) [#107](https://polkadot.polkassembly.io/referendum/107) - ## :collision: Breaking Changes for Integrations :collision: - ❗️ Call [transfer](https://github.com/paritytech/substrate/blob/f5c2cecd7efe6dcbc828906794f3c4c41f23c791/frame/balances/src/lib.rs#L286) renamed to [transfer_allow_death](https://github.com/paritytech/substrate/blob/d7b9969c96f621b9cd93f91ebc8220aa620ac0e8/frame/balances/src/lib.rs#L533) - ❗️ Call [set_balance](https://github.com/paritytech/substrate/blob/f5c2cecd7efe6dcbc828906794f3c4c41f23c791/frame/balances/src/lib.rs#L315) renamed to [force_set_balance](https://github.com/paritytech/substrate/blob/d7b9969c96f621b9cd93f91ebc8220aa620ac0e8/frame/balances/src/lib.rs#L739) - ❗️Accounts now require: - Existential Deposit (`Currency::minimum_balance()`) + - any amount to be reserved *** *Possible failures in tests and benchmarking* - ❗️ExistentialDeposit != 0 (not allowed) - ❗️Balance != 0 (not allowed) - 🔦 Domi : I need to clarify ### Holds & Freezes analogous to Reserves & Locks Holds & Freezes are introduced - ❗️`Holds` ~=(analogous) `Reserves` **BUT** Holds designed to be infallibly slashed. - ❗️`Freezes` ~=(same) `Locks` **BUT** Freezes overlap with Holds. ### Balance - > *Reserve does not contribute to the ED* - > *Reserve does use a Consumer Reference* ❓Is it implemented already ? ❓Where is this change in the code ? #### Locks > WithdrawReasons - ❗️Locks > withdraw reasons : Removed - 🔦 Domi : Change in the code ? - I see in [changed files of the PR](https://github.com/paritytech/substrate/pull/12951/files) that `WithdrawReasons` is removed from `frame/executive/src/lib.rs` - Double checking: - in branch [v0.9.41](https://github.com/paritytech/substrate/blob/980eb16791bab5d63b47c07657bb9dc198d9307b/frame/executive/src/lib.rs#L1303) it is still there - in branch [master](https://github.com/paritytech/substrate/blob/master/frame/executive/src/lib.rs) baaam! gone! - Function `mutate_account` is now PRIVATE - If you use > REPLACE with `make_free_balance_be` ❓But it also says that `make_free_balance_be` might be replaced with `set_balance`(table below) ### Changes in Errors > Some errors have changed to the more general errors - 🔦 Domi - Example in the code ? - `BalancesError::<Test, _>::InsufficientBalance` is replaced with `ArithmeticError::Underflow` in the test files of pallet lottery - `BalancesError::<Test, _>::InsufficientBalance` is replaced with `` ### Within 3 months -❗️Use the fungible trait API for Balances -❗️Do not use Dispatchables - they will be removed -❗️All pallet-access will be through XCM -❗️Use `transfer_allow_death` -❗️Do not use `transfer` (if you use it then replace it since it is deprecated) - for 3 months we will still have it though - 🔦 Domi : 3 months starting from when ? ## TODO : Changes to check - Changes in Events ? - For example what event is triggered after transfer_allow_death - If not, explicitly mention that this is not affected ### TODO : renaming of reserve to holds ### TODO : now everytime there is a freeze you have to add a reason ### TODO : transfer in vesting pallet is changing ## 🦋 NON Breaking Changes for Integrations 🦋 - 4 new items in pallet_balances::[Config](https://github.com/paritytech/substrate/blob/d7b9969c96f621b9cd93f91ebc8220aa620ac0e8/frame/balances/src/lib.rs#L214) trait: - type [MaxHolds](https://github.com/paritytech/substrate/blob/d7b9969c96f621b9cd93f91ebc8220aa620ac0e8/frame/balances/src/lib.rs#L274) - type [MaxFreezes](https://github.com/paritytech/substrate/blob/d7b9969c96f621b9cd93f91ebc8220aa620ac0e8/frame/balances/src/lib.rs#L278) - type [HoldIdentifier](https://github.com/paritytech/substrate/blob/d7b9969c96f621b9cd93f91ebc8220aa620ac0e8/frame/balances/src/lib.rs#L258) - type [FreezeIdentifier](https://github.com/paritytech/substrate/blob/d7b9969c96f621b9cd93f91ebc8220aa620ac0e8/frame/balances/src/lib.rs#L261) - New dispatchable (extrinsic): [upgrade_accounts](https://github.com/paritytech/substrate/blob/d7b9969c96f621b9cd93f91ebc8220aa620ac0e8/frame/balances/src/lib.rs#L692) ### New functions that can be used & replacing old ones <body> <table style="width:100%"> <tr> <th colspan="2">Currency old function</th> <th>------------></th> <th colspan="2">Fungible new function</th> </tr> <tr> <td rowspan="2" style="color:#3498db">Currency:: </td> <td>free_balance </td> <td rowspan="5">may be replaced with </td> <td rowspan="8" style="color:#3498db">fungible::</td> <td>Inspect::balance</td> </tr> <tr> <td>make_free_balance_be </td> <td colspan="7">Mutate::set_balance`</td> </tr> <tr> <td style="color:#3498db">ReservableCurrency:: </td> <td>reserved_balance </td> <td rowspan="3">hold:: </td> <td colspan="7">Inspect::total_balance_on_hold</td> </tr> <tr> <td rowspan="2" style="color:#3498db">NamedReservableCurrency:: </td> <td>reserve </td> <td colspan="7">Mutate::hold</td> </tr> <tr> <td>unreserve </td> <td colspan="7">Mutate::release</td> <td>handle returned Result + inner of Ok = opposite meaning </td> </tr> <tr> <td rowspan="3" style="color:#3498db">LockableCurrency:: </td> <td>set_lock </td> <td>may generally be replaced with </td> <td rowspan="3">freeze:: </td> <td colspan="7">Mutate::set_freeze</td> </tr> <tr> <td>extend_lock </td> <td>may generally be replaced with </td> <td colspan="7">Mutate::extend_freeze</td> </tr> <tr> <td>remove_lock </td> <td>may be replaced with </td> <td colspan="7">Mutate::thaw</td> </tr> </table> </body> ### Pallets affected #### Example changes - in `primitives/runtime/src/lib.rs` in enum `TokenError` : - replaced `NoFunds` with `FundsUnavailable` - replaced `WouldDie` with `OnlyProvider` - added new value `CannotCreateHold` - added new value `NotExpendable` ## Expected Date of inclusion in the runtime - Date : ???? - When : In Release v0.9.42 - Notes - PR will be included in the release (0.9.42) - It will become active and effective in the runtime upgrade (9420) - For Polkadot : upgrade will not happen until the audit is done (?) - For Kusama : changes lands on Kusama without audit ## How it affects [Sidecar](https://github.com/paritytech/substrate-api-sidecar) ### TODO - compile master - pull metadata - test with pjs ### TODO : Changes in STORAGE Query storage for balances what is currently what is changing ### TODO : Changes in Balances, Assets ### Blocks endpoint We should support both calls, `transfer` and `transfer_allow_death` depending on the block height (?) - For all the blocks that come **after** the change becomes active : - calls of `transfer` from `Balances` pallet will appear as `transfer_allow_death` ? - So we need to add tests like this one [transfer call](https://github.com/paritytech/substrate-api-sidecar/blob/4820342978855eaab212ef3eeae1e51013963bed/src/services/blocks/BlocksService.spec.ts#L217) for blocks after change ### Metadata We should have the new version of Metadata in `test-helpers`, e.g. : - As we have [polkadotMetadataV16.json](https://github.com/paritytech/substrate-api-sidecar/blob/master/src/test-helpers/metadata/polkadotMetadataV16.json#L1199) with references to `transfer` or `set_balance` - we should have the new metadata version with references to `transfer_allow_death` and `force_set_balance`. ### Notes https://github.com/paritytech/substrate-api-sidecar/blob/master/src/services/blocks/BlocksService.ts#L674-L716 ## How it affects [txwrapper-core](https://github.com/paritytech/txwrapper-core) ### Calls of `balances.transfer` Replace all calls of `balances.transfer` with `balances.transfer_allow_death` (?) 1. In all `spec` files of `core`, e.g. : [createSigningPayload.spec.ts](https://github.com/paritytech/txwrapper-core/blob/90a231e07e69de96602f92d37897493ac2e7b7f7/packages/txwrapper-core/src/core/construct/createSigningPayload.spec.ts#L14) 2. In `test-helpers`, e.g. [itDecodesBalancesTransferCommon.ts](https://github.com/paritytech/txwrapper-core/blob/90a231e07e69de96602f92d37897493ac2e7b7f7/packages/txwrapper-core/src/test-helpers/itDecodesBalancesTransferCommon.ts#L20) ### Minimum Balance - Check where the new logic of Existential deposit `Currency::minimum_balance()` + `reserved` amount needs to be applied. - [transfer_all](https://github.com/paritytech/txwrapper-core/blob/main/packages/txwrapper-substrate/src/methods/balances/transferAll.ts) (?) - Existential Deposit requirements to be made of the **free** balance, **not** the **total** balance. ## PRs Related - [PR #12951 - Deprecate Currency; introduce holds and freezing into fungible traits](https://github.com/paritytech/substrate/pull/12951) - [Issue #12918 - Tokens: Revamp locking & reserving](https://github.com/paritytech/substrate/issues/12918) - `reserve` -> `hold` - `lock` -> `freeze` - [Issue #13633 - Vision: Tracking issue for deprecating Currency (and friends) trait usage in core FRAME pallets](https://github.com/paritytech/substrate/issues/13633) - [PR #13655 - Make ED of zero (kind of) work](https://github.com/paritytech/substrate/pull/13655) - [PR #13369 - contracts: Don't rely on reserved balances keeping an account alive](https://github.com/paritytech/substrate/pull/13369) - [Report Analysis from Support Team](https://hackmd.io/kNnAEPZ9QtKxtWz1bcpQbw?both) ## Questions 1. Regarding the following change mentioned in the PR description : > *Accounts now require the Existential Deposit (Currency::minimumbalance()) in addition to any amount to be reserved. This is a BREAKING CHANGE and is likely to result in failures in tests and benchmarking.* I am trying to find an example of a change in the code that showcases the change described above. What I found was that in the benchmarking of the `nis` pallet for example, Before we had : > T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value()); and now we have this [code](https://github.com/paritytech/substrate/blob/master/frame/nis/src/benchmarking.rs#L65L67) > let ed = T::Currency::minimum_balance(); > let bid = T::MinBid::get(); > T::Currency::set_balance(&caller, (ed + bid) * BalanceOf::<T>::from(l + 1) + bid); The fact that before we were using [make_free_balance_be](https://github.com/paritytech/substrate/blob/07c77323010d54410143103c2617ebc12e0a12f3/frame/balances/src/impl_currency.rs#L445) with argument `BalanceOf` and now we are using the `set_balance` call with `ed + bid` is an example of the above statement/change introduced with this PR ? 2.