Skip to content
This repository has been archived by the owner on Apr 1, 2024. It is now read-only.

fix: use a dedicated reducible balance for evm #2

Merged
merged 4 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions frame/assets/src/impl_fungibles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ impl<T: Config<I>, I: 'static> fungibles::Inspect<<T as SystemConfig>::AccountId
.unwrap_or(Zero::zero())
}

fn evm_reducible_balance(
asset: Self::AssetId,
who: &<T as SystemConfig>::AccountId,
preservation: Preservation,
_: Fortitude,
) -> Self::Balance {
Pallet::<T, I>::reducible_balance(asset, who, !matches!(preservation, Expendable))
.unwrap_or(Zero::zero())
}

fn can_deposit(
asset: Self::AssetId,
who: &<T as SystemConfig>::AccountId,
Expand Down
48 changes: 37 additions & 11 deletions frame/balances/src/impl_fungible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,43 @@ impl<T: Config<I>, I: 'static> fungible::Inspect<T::AccountId> for Pallet<T, I>
// Liquid balance is what is neither on hold nor frozen/required for provider.
a.free.saturating_sub(untouchable)
}
/// This method will only be used until migrations to fungible traits are done.
fn evm_reducible_balance(
who: &T::AccountId,
preservation: Preservation,
force: Fortitude,
) -> Self::Balance {
let a = Self::account(who);
let mut untouchable = Zero::zero();
if force == Polite {
// In the case for EVM, we only care about frozen balance.
untouchable = a.frozen;
}
// If we want to keep our provider ref..
if preservation == Preserve
// ..or we don't want the account to die and our provider ref is needed for it to live..
|| preservation == Protect && !a.free.is_zero() &&
frame_system::Pallet::<T>::providers(who) == 1
// ..or we don't care about the account dying but our provider ref is required..
|| preservation == Expendable && !a.free.is_zero() &&
!frame_system::Pallet::<T>::can_dec_provider(who)
{
// ..then the ED needed..
untouchable = untouchable.max(T::ExistentialDeposit::get());
}
a.free.saturating_sub(untouchable)
}
fn can_deposit(
who: &T::AccountId,
amount: Self::Balance,
provenance: Provenance,
) -> DepositConsequence {
if amount.is_zero() {
return DepositConsequence::Success
return DepositConsequence::Success;
}

if provenance == Minted && TotalIssuance::<T, I>::get().checked_add(&amount).is_none() {
return DepositConsequence::Overflow
return DepositConsequence::Overflow;
}

let account = Self::account(who);
Expand All @@ -103,11 +129,11 @@ impl<T: Config<I>, I: 'static> fungible::Inspect<T::AccountId> for Pallet<T, I>
amount: Self::Balance,
) -> WithdrawConsequence<Self::Balance> {
if amount.is_zero() {
return WithdrawConsequence::Success
return WithdrawConsequence::Success;
}

if TotalIssuance::<T, I>::get().checked_sub(&amount).is_none() {
return WithdrawConsequence::Underflow
return WithdrawConsequence::Underflow;
}

let account = Self::account(who);
Expand All @@ -118,7 +144,7 @@ impl<T: Config<I>, I: 'static> fungible::Inspect<T::AccountId> for Pallet<T, I>

let liquid = Self::reducible_balance(who, Expendable, Polite);
if amount > liquid {
return WithdrawConsequence::Frozen
return WithdrawConsequence::Frozen;
}

// Provider restriction - total account balance cannot be reduced to zero if it cannot
Expand All @@ -130,7 +156,7 @@ impl<T: Config<I>, I: 'static> fungible::Inspect<T::AccountId> for Pallet<T, I>
if frame_system::Pallet::<T>::can_dec_provider(who) {
WithdrawConsequence::ReducedToZero(new_free_balance)
} else {
return WithdrawConsequence::WouldDie
return WithdrawConsequence::WouldDie;
}
} else {
WithdrawConsequence::Success
Expand All @@ -140,7 +166,7 @@ impl<T: Config<I>, I: 'static> fungible::Inspect<T::AccountId> for Pallet<T, I>

// Eventual free funds must be no less than the frozen balance.
if new_total_balance < account.frozen {
return WithdrawConsequence::Frozen
return WithdrawConsequence::Frozen;
}

success
Expand Down Expand Up @@ -232,11 +258,11 @@ impl<T: Config<I>, I: 'static> fungible::InspectHold<T::AccountId> for Pallet<T,
}
fn hold_available(reason: &Self::Reason, who: &T::AccountId) -> bool {
if frame_system::Pallet::<T>::providers(who) == 0 {
return false
return false;
}
let holds = Holds::<T, I>::get(who);
if holds.is_full() && !holds.iter().any(|x| &x.id == reason) {
return false
return false;
}
true
}
Expand Down Expand Up @@ -302,7 +328,7 @@ impl<T: Config<I>, I: 'static> fungible::InspectFreeze<T::AccountId> for Pallet<
impl<T: Config<I>, I: 'static> fungible::MutateFreeze<T::AccountId> for Pallet<T, I> {
fn set_freeze(id: &Self::Id, who: &T::AccountId, amount: Self::Balance) -> DispatchResult {
if amount.is_zero() {
return Self::thaw(id, who)
return Self::thaw(id, who);
}
let mut locks = Freezes::<T, I>::get(who);
if let Some(i) = locks.iter_mut().find(|x| &x.id == id) {
Expand All @@ -317,7 +343,7 @@ impl<T: Config<I>, I: 'static> fungible::MutateFreeze<T::AccountId> for Pallet<T

fn extend_freeze(id: &Self::Id, who: &T::AccountId, amount: Self::Balance) -> DispatchResult {
if amount.is_zero() {
return Ok(())
return Ok(());
}
let mut locks = Freezes::<T, I>::get(who);
if let Some(i) = locks.iter_mut().find(|x| &x.id == id) {
Expand Down
3 changes: 3 additions & 0 deletions frame/nis/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ impl<T> FunInspect<T> for NoCounterpart<T> {
fn reducible_balance(_: &T, _: Preservation, _: Fortitude) -> u32 {
0
}
fn evm_reducible_balance(_: &T, _: Preservation, _: Fortitude) -> u32 {
0
}
fn can_deposit(_: &T, _: u32, _: Provenance) -> DepositConsequence {
DepositConsequence::Success
}
Expand Down
12 changes: 12 additions & 0 deletions frame/support/src/traits/tokens/fungible/item_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ impl<
) -> Self::Balance {
<F as fungibles::Inspect<AccountId>>::reducible_balance(A::get(), who, preservation, force)
}
fn evm_reducible_balance(
who: &AccountId,
preservation: Preservation,
force: Fortitude,
) -> Self::Balance {
<F as fungibles::Inspect<AccountId>>::evm_reducible_balance(
A::get(),
who,
preservation,
force,
)
}
fn can_deposit(
who: &AccountId,
amount: Self::Balance,
Expand Down
5 changes: 5 additions & 0 deletions frame/support/src/traits/tokens/fungible/regular.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ pub trait Inspect<AccountId>: Sized {
preservation: Preservation,
force: Fortitude,
) -> Self::Balance;
fn evm_reducible_balance(
who: &AccountId,
preservation: Preservation,
force: Fortitude,
) -> Self::Balance;

/// Returns `true` if the balance of `who` may be increased by `amount`.
///
Expand Down
6 changes: 6 additions & 0 deletions frame/support/src/traits/tokens/fungibles/regular.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ pub trait Inspect<AccountId>: Sized {
preservation: Preservation,
force: Fortitude,
) -> Self::Balance;
fn evm_reducible_balance(
asset: Self::AssetId,
who: &AccountId,
preservation: Preservation,
force: Fortitude,
) -> Self::Balance;

/// Returns `true` if the `asset` balance of `who` may be increased by `amount`.
///
Expand Down