Skip to content

Commit 2d07c1b

Browse files
dnjscksdn98alstjd0921
authored andcommitted
fix: add legacy transferrable balance to currency trait (#1)
1 parent d649659 commit 2d07c1b

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,
@@ -510,6 +510,27 @@ where
510510
)
511511
.unwrap_or_else(|_| SignedImbalance::Positive(Self::PositiveImbalance::zero()))
512512
}
513+
514+
fn transferrable_balance(
515+
who: &T::AccountId,
516+
preservation: Preservation,
517+
) -> Self::Balance {
518+
let a = Self::account(who);
519+
let mut untouchable = a.frozen;
520+
// If we want to keep our provider ref..
521+
if preservation == Preserve
522+
// ..or we don't want the account to die and our provider ref is needed for it to live..
523+
|| preservation == Protect && !a.free.is_zero() &&
524+
frame_system::Pallet::<T>::providers(who) == 1
525+
// ..or we don't care about the account dying but our provider ref is required..
526+
|| preservation == Expendable && !a.free.is_zero() &&
527+
!frame_system::Pallet::<T>::can_dec_provider(who)
528+
{
529+
// ..then the ED needed..
530+
untouchable = untouchable.max(T::ExistentialDeposit::get());
531+
}
532+
a.free.saturating_sub(untouchable)
533+
}
513534
}
514535

515536
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};
@@ -212,6 +212,17 @@ pub trait Currency<AccountId> {
212212
who: &AccountId,
213213
balance: Self::Balance,
214214
) -> SignedImbalance<Self::Balance, Self::PositiveImbalance>;
215+
216+
/// Get the maximum amount that `who` can withdraw/transfer successfully based on whether the
217+
/// account should be kept alive (`preservation`) or whether we are willing to force the
218+
/// reduction and potentially go below user-level restrictions on the minimum amount of the
219+
/// account.
220+
///
221+
/// Always less than or equal to `balance()`.
222+
fn transferrable_balance(
223+
who: &AccountId,
224+
preservation: Preservation,
225+
) -> Self::Balance;
215226
}
216227

217228
/// A non-const `Get` implementation parameterised by a `Currency` impl which provides the result
@@ -318,4 +329,7 @@ impl<AccountId> Currency<AccountId> for () {
318329
) -> SignedImbalance<Self::Balance, Self::PositiveImbalance> {
319330
SignedImbalance::Positive(())
320331
}
332+
fn transferrable_balance(_: &AccountId, _: Preservation) -> u32 {
333+
0
334+
}
321335
}

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)