Skip to content

Commit

Permalink
add ExistenceRequirement
Browse files Browse the repository at this point in the history
  • Loading branch information
zjb0807 committed Jan 9, 2025
1 parent 286c731 commit 07ad5c4
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 29 deletions.
71 changes: 54 additions & 17 deletions currencies/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,13 @@ pub mod module {
) -> DispatchResult {
let from = ensure_signed(origin)?;
let to = T::Lookup::lookup(dest)?;
<Self as MultiCurrency<T::AccountId>>::transfer(currency_id, &from, &to, amount)
<Self as MultiCurrency<T::AccountId>>::transfer(
currency_id,
&from,
&to,
amount,
ExistenceRequirement::AllowDeath,
)
}

/// Transfer some native currency to another account.
Expand All @@ -150,7 +156,7 @@ pub mod module {
) -> DispatchResult {
let from = ensure_signed(origin)?;
let to = T::Lookup::lookup(dest)?;
T::NativeCurrency::transfer(&from, &to, amount)
T::NativeCurrency::transfer(&from, &to, amount, ExistenceRequirement::AllowDeath)
}

/// update amount of account `who` under `currency_id`.
Expand Down Expand Up @@ -220,14 +226,15 @@ impl<T: Config> MultiCurrency<T::AccountId> for Pallet<T> {
from: &T::AccountId,
to: &T::AccountId,
amount: Self::Balance,
existence_requirement: ExistenceRequirement,
) -> DispatchResult {
if amount.is_zero() || from == to {
return Ok(());
}
if currency_id == T::GetNativeCurrencyId::get() {
T::NativeCurrency::transfer(from, to, amount)
T::NativeCurrency::transfer(from, to, amount, existence_requirement)
} else {
T::MultiCurrency::transfer(currency_id, from, to, amount)
T::MultiCurrency::transfer(currency_id, from, to, amount, existence_requirement)
}
}

Expand All @@ -242,14 +249,19 @@ impl<T: Config> MultiCurrency<T::AccountId> for Pallet<T> {
}
}

fn withdraw(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> DispatchResult {
fn withdraw(
currency_id: Self::CurrencyId,
who: &T::AccountId,
amount: Self::Balance,
existence_requirement: ExistenceRequirement,
) -> DispatchResult {
if amount.is_zero() {
return Ok(());
}
if currency_id == T::GetNativeCurrencyId::get() {
T::NativeCurrency::withdraw(who, amount)
T::NativeCurrency::withdraw(who, amount, existence_requirement)
} else {
T::MultiCurrency::withdraw(currency_id, who, amount)
T::MultiCurrency::withdraw(currency_id, who, amount, existence_requirement)
}
}

Expand Down Expand Up @@ -475,16 +487,31 @@ where
<Pallet<T>>::ensure_can_withdraw(GetCurrencyId::get(), who, amount)
}

fn transfer(from: &T::AccountId, to: &T::AccountId, amount: Self::Balance) -> DispatchResult {
<Pallet<T> as MultiCurrency<T::AccountId>>::transfer(GetCurrencyId::get(), from, to, amount)
fn transfer(
from: &T::AccountId,
to: &T::AccountId,
amount: Self::Balance,
existence_requirement: ExistenceRequirement,
) -> DispatchResult {
<Pallet<T> as MultiCurrency<T::AccountId>>::transfer(
GetCurrencyId::get(),
from,
to,
amount,
existence_requirement,
)
}

fn deposit(who: &T::AccountId, amount: Self::Balance) -> DispatchResult {
<Pallet<T>>::deposit(GetCurrencyId::get(), who, amount)
}

fn withdraw(who: &T::AccountId, amount: Self::Balance) -> DispatchResult {
<Pallet<T>>::withdraw(GetCurrencyId::get(), who, amount)
fn withdraw(
who: &T::AccountId,
amount: Self::Balance,
existence_requirement: ExistenceRequirement,
) -> DispatchResult {
<Pallet<T>>::withdraw(GetCurrencyId::get(), who, amount, existence_requirement)
}

fn can_slash(who: &T::AccountId, amount: Self::Balance) -> bool {
Expand Down Expand Up @@ -653,8 +680,13 @@ where
Currency::ensure_can_withdraw(who, amount, WithdrawReasons::all(), new_balance)
}

fn transfer(from: &AccountId, to: &AccountId, amount: Self::Balance) -> DispatchResult {
Currency::transfer(from, to, amount, ExistenceRequirement::AllowDeath)
fn transfer(
from: &AccountId,
to: &AccountId,
amount: Self::Balance,
existence_requirement: ExistenceRequirement,
) -> DispatchResult {
Currency::transfer(from, to, amount, existence_requirement)
}

fn deposit(who: &AccountId, amount: Self::Balance) -> DispatchResult {
Expand All @@ -666,8 +698,8 @@ where
Ok(())
}

fn withdraw(who: &AccountId, amount: Self::Balance) -> DispatchResult {
Currency::withdraw(who, amount, WithdrawReasons::all(), ExistenceRequirement::AllowDeath).map(|_| ())
fn withdraw(who: &AccountId, amount: Self::Balance, existence_requirement: ExistenceRequirement) -> DispatchResult {
Currency::withdraw(who, amount, WithdrawReasons::all(), existence_requirement).map(|_| ())
}

fn can_slash(who: &AccountId, amount: Self::Balance) -> bool {
Expand Down Expand Up @@ -707,7 +739,7 @@ where
if by_amount.is_positive() {
Self::deposit(who, by_balance)
} else {
Self::withdraw(who, by_balance)
Self::withdraw(who, by_balance, ExistenceRequirement::AllowDeath)
}
}
}
Expand Down Expand Up @@ -817,7 +849,12 @@ impl<T: Config> TransferAll<T::AccountId> for Pallet<T> {
T::MultiCurrency::transfer_all(source, dest)?;

// transfer all free to dest
T::NativeCurrency::transfer(source, dest, T::NativeCurrency::free_balance(source))
T::NativeCurrency::transfer(
source,
dest,
T::NativeCurrency::free_balance(source),
ExistenceRequirement::AllowDeath,
)
})
}
}
14 changes: 10 additions & 4 deletions tokens/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1161,9 +1161,10 @@ impl<T: Config> MultiCurrency<T::AccountId> for Pallet<T> {
from: &T::AccountId,
to: &T::AccountId,
amount: Self::Balance,
existence_requirement: ExistenceRequirement,
) -> DispatchResult {
// allow death
Self::do_transfer(currency_id, from, to, amount, ExistenceRequirement::AllowDeath)
Self::do_transfer(currency_id, from, to, amount, existence_requirement)
}

fn deposit(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> DispatchResult {
Expand All @@ -1172,9 +1173,14 @@ impl<T: Config> MultiCurrency<T::AccountId> for Pallet<T> {
Ok(())
}

fn withdraw(currency_id: Self::CurrencyId, who: &T::AccountId, amount: Self::Balance) -> DispatchResult {
fn withdraw(
currency_id: Self::CurrencyId,
who: &T::AccountId,
amount: Self::Balance,
existence_requirement: ExistenceRequirement,
) -> DispatchResult {
// allow death
Self::do_withdraw(currency_id, who, amount, ExistenceRequirement::AllowDeath, true)
Self::do_withdraw(currency_id, who, amount, existence_requirement, true)
}

// Check if `value` amount of free balance can be slashed from `who`.
Expand Down Expand Up @@ -1269,7 +1275,7 @@ impl<T: Config> MultiCurrencyExtended<T::AccountId> for Pallet<T> {
if by_amount.is_positive() {
Self::deposit(currency_id, who, by_balance)
} else {
Self::withdraw(currency_id, who, by_balance).map(|_| ())
Self::withdraw(currency_id, who, by_balance, ExistenceRequirement::AllowDeath).map(|_| ())
}
}
}
Expand Down
19 changes: 15 additions & 4 deletions traits/src/currency.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{arithmetic, Happened};
use frame_support::traits::tokens::Balance;
use frame_support::traits::{tokens::Balance, ExistenceRequirement};
pub use frame_support::{
traits::{BalanceStatus, DefensiveSaturating, LockIdentifier},
transactional,
Expand Down Expand Up @@ -56,6 +56,7 @@ pub trait MultiCurrency<AccountId> {
from: &AccountId,
to: &AccountId,
amount: Self::Balance,
existence_requirement: ExistenceRequirement,
) -> DispatchResult;

/// Add `amount` to the balance of `who` under `currency_id` and increase
Expand All @@ -64,7 +65,12 @@ pub trait MultiCurrency<AccountId> {

/// Remove `amount` from the balance of `who` under `currency_id` and reduce
/// total issuance.
fn withdraw(currency_id: Self::CurrencyId, who: &AccountId, amount: Self::Balance) -> DispatchResult;
fn withdraw(
currency_id: Self::CurrencyId,
who: &AccountId,
amount: Self::Balance,
existence_requirement: ExistenceRequirement,
) -> DispatchResult;

/// Same result as `slash(currency_id, who, value)` (but without the
/// side-effects) assuming there are no balance changes in the meantime and
Expand Down Expand Up @@ -381,13 +387,18 @@ pub trait BasicCurrency<AccountId> {
// Public mutables

/// Transfer some amount from one account to another.
fn transfer(from: &AccountId, to: &AccountId, amount: Self::Balance) -> DispatchResult;
fn transfer(
from: &AccountId,
to: &AccountId,
amount: Self::Balance,
existence_requirement: ExistenceRequirement,
) -> DispatchResult;

/// Add `amount` to the balance of `who` and increase total issuance.
fn deposit(who: &AccountId, amount: Self::Balance) -> DispatchResult;

/// Remove `amount` from the balance of `who` and reduce total issuance.
fn withdraw(who: &AccountId, amount: Self::Balance) -> DispatchResult;
fn withdraw(who: &AccountId, amount: Self::Balance, existence_requirement: ExistenceRequirement) -> DispatchResult;

/// Same result as `slash(who, value)` (but without the side-effects)
/// assuming there are no balance changes in the meantime and only the
Expand Down
15 changes: 11 additions & 4 deletions xcm-support/src/currency_adapter.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use frame_support::traits::Get;
use frame_support::traits::{ExistenceRequirement, Get};
use parity_scale_codec::FullCodec;
use sp_runtime::{
traits::{Convert, MaybeSerializeDeserialize, SaturatedConversion},
Expand Down Expand Up @@ -173,7 +173,8 @@ impl<
let amount: MultiCurrency::Balance = Match::matches_fungible(asset)
.ok_or_else(|| XcmError::from(Error::FailedToMatchFungible))?
.saturated_into();
MultiCurrency::withdraw(currency_id, &who, amount).map_err(|e| XcmError::FailedToTransactAsset(e.into()))
MultiCurrency::withdraw(currency_id, &who, amount, ExistenceRequirement::AllowDeath)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))
})?;

Ok(asset.clone().into())
Expand All @@ -194,8 +195,14 @@ impl<
let amount: MultiCurrency::Balance = Match::matches_fungible(asset)
.ok_or_else(|| XcmError::from(Error::FailedToMatchFungible))?
.saturated_into();
MultiCurrency::transfer(currency_id, &from_account, &to_account, amount)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
MultiCurrency::transfer(
currency_id,
&from_account,
&to_account,
amount,
ExistenceRequirement::AllowDeath,
)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;

Ok(asset.clone().into())
}
Expand Down

0 comments on commit 07ad5c4

Please sign in to comment.