---
# System prepended metadata

title: 'Deprecate Currency; introduce holds and freezing into fungible traits - [PR #12951](https://github.com/paritytech/substrate/pull/12951)'

---

# 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. 
    
