Skip to content

Commit 8c2a20a

Browse files
committed
fix: add legacy transferrable balance to currency trait (#1)
1 parent 8138511 commit 8c2a20a

3 files changed

Lines changed: 44 additions & 3 deletions

File tree

substrate/frame/balances/src/impl_currency.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use frame_support::{
2525
ensure,
2626
pallet_prelude::DispatchResult,
2727
traits::{
28-
tokens::{fungible, BalanceStatus as Status, Fortitude::Polite, Precision::BestEffort},
28+
tokens::{fungible, BalanceStatus as Status, Fortitude::Polite, Precision::BestEffort, Preservation::{self, Preserve, Protect}},
2929
Currency, DefensiveSaturating, ExistenceRequirement,
3030
ExistenceRequirement::AllowDeath,
3131
Get, Imbalance, InspectLockableCurrency, LockIdentifier, LockableCurrency,
@@ -487,6 +487,27 @@ where
487487
)
488488
.unwrap_or_else(|_| SignedImbalance::Positive(Self::PositiveImbalance::zero()))
489489
}
490+
491+
fn transferrable_balance(
492+
who: &T::AccountId,
493+
preservation: Preservation,
494+
) -> Self::Balance {
495+
let a = Self::account(who);
496+
let mut untouchable = a.frozen;
497+
// If we want to keep our provider ref..
498+
if preservation == Preserve
499+
// ..or we don't want the account to die and our provider ref is needed for it to live..
500+
|| preservation == Protect && !a.free.is_zero() &&
501+
frame_system::Pallet::<T>::providers(who) == 1
502+
// ..or we don't care about the account dying but our provider ref is required..
503+
|| preservation == Expendable && !a.free.is_zero() &&
504+
!frame_system::Pallet::<T>::can_dec_provider(who)
505+
{
506+
// ..then the ED needed..
507+
untouchable = untouchable.max(T::ExistentialDeposit::get());
508+
}
509+
a.free.saturating_sub(untouchable)
510+
}
490511
}
491512

492513
impl<T: Config<I>, I: 'static> ReservableCurrency<T::AccountId> for Pallet<T, I>

substrate/frame/support/src/traits/tokens/currency.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
2323
use super::{
2424
imbalance::{Imbalance, SignedImbalance},
25-
misc::{Balance, ExistenceRequirement, WithdrawReasons},
25+
misc::{Balance, ExistenceRequirement, WithdrawReasons}, Preservation,
2626
};
2727
use crate::{dispatch::DispatchResult, traits::Get};
2828
use sp_runtime::{traits::MaybeSerializeDeserialize, DispatchError};
@@ -210,6 +210,17 @@ pub trait Currency<AccountId> {
210210
who: &AccountId,
211211
balance: Self::Balance,
212212
) -> SignedImbalance<Self::Balance, Self::PositiveImbalance>;
213+
214+
/// Get the maximum amount that `who` can withdraw/transfer successfully based on whether the
215+
/// account should be kept alive (`preservation`) or whether we are willing to force the
216+
/// reduction and potentially go below user-level restrictions on the minimum amount of the
217+
/// account.
218+
///
219+
/// Always less than or equal to `balance()`.
220+
fn transferrable_balance(
221+
who: &AccountId,
222+
preservation: Preservation,
223+
) -> Self::Balance;
213224
}
214225

215226
/// A non-const `Get` implementation parameterised by a `Currency` impl which provides the result
@@ -316,4 +327,7 @@ impl<AccountId> Currency<AccountId> for () {
316327
) -> SignedImbalance<Self::Balance, Self::PositiveImbalance> {
317328
SignedImbalance::Positive(())
318329
}
330+
fn transferrable_balance(_: &AccountId, _: Preservation) -> u32 {
331+
0
332+
}
319333
}

substrate/frame/support/src/traits/tokens/currency/reservable.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use sp_core::Get;
2323
use super::{super::misc::BalanceStatus, Currency};
2424
use crate::{
2525
dispatch::DispatchResult,
26-
traits::{ExistenceRequirement, SignedImbalance, WithdrawReasons},
26+
traits::{ExistenceRequirement, SignedImbalance, WithdrawReasons, tokens::Preservation},
2727
};
2828
use sp_runtime::DispatchError;
2929

@@ -338,6 +338,12 @@ impl<
338338
) -> SignedImbalance<Self::Balance, Self::PositiveImbalance> {
339339
NamedReservable::make_free_balance_be(who, balance)
340340
}
341+
fn transferrable_balance(
342+
who: &AccountId,
343+
preservation: Preservation,
344+
) -> Self::Balance {
345+
NamedReservable::transferrable_balance(who, preservation)
346+
}
341347
}
342348
impl<
343349
NamedReservable: NamedReservableCurrency<AccountId>,

0 commit comments

Comments
 (0)