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
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
@@ -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,
48 changes: 37 additions & 11 deletions frame/balances/src/impl_fungible.rs
Original file line number Diff line number Diff line change
@@ -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);
@@ -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);
@@ -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
@@ -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
@@ -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
@@ -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
}
@@ -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) {
@@ -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) {
3 changes: 3 additions & 0 deletions frame/nis/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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
}
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
@@ -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,
5 changes: 5 additions & 0 deletions frame/support/src/traits/tokens/fungible/regular.rs
Original file line number Diff line number Diff line change
@@ -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`.
///
6 changes: 6 additions & 0 deletions frame/support/src/traits/tokens/fungibles/regular.rs
Original file line number Diff line number Diff line change
@@ -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`.
///