Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement do_transfer (related to issue paritytech#151 in Clamor).
Browse files Browse the repository at this point in the history
Alessandro Baffa committed Sep 13, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 1b6228d commit 41835be
Showing 1 changed file with 67 additions and 2 deletions.
69 changes: 67 additions & 2 deletions frame/balances/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1056,6 +1056,71 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
});
Ok(actual)
}

fn do_transfer(
transactor: &T::AccountId,
dest: &T::AccountId,
value: T::Balance,
existence_requirement: ExistenceRequirement,
) -> Result<T::Balance, DispatchError> {
if value.is_zero() || transactor == dest {
return Ok(value)
}

Self::try_mutate_account_with_dust(
dest,
|to_account, _| -> Result<DustCleaner<T, I>, DispatchError> {
Self::try_mutate_account_with_dust(
transactor,
|from_account, _| -> DispatchResult {
from_account.free = from_account
.free
.checked_sub(&value)
.ok_or(Error::<T, I>::InsufficientBalance)?;

// NOTE: total stake being stored in the same type means that this could
// never overflow but better to be safe than sorry.
to_account.free =
to_account.free.checked_add(&value).ok_or(ArithmeticError::Overflow)?;

let ed = T::ExistentialDeposit::get();
ensure!(to_account.total() >= ed, Error::<T, I>::ExistentialDeposit);

Self::ensure_can_withdraw(
transactor,
value,
WithdrawReasons::TRANSFER,
from_account.free,
)
.map_err(|_| Error::<T, I>::LiquidityRestrictions)?;

// TODO: This is over-conservative. There may now be other providers, and
// this pallet may not even be a provider.
let allow_death = existence_requirement == ExistenceRequirement::AllowDeath;
let allow_death =
allow_death && system::Pallet::<T>::can_dec_provider(transactor);
ensure!(
allow_death || from_account.total() >= ed,
Error::<T, I>::KeepAlive
);

Ok(())
},
)
.map(|(_, maybe_dust_cleaner)| maybe_dust_cleaner)
},
)?;

// Emit transfer event.
Self::deposit_event(Event::Transfer {
from: transactor.clone(),
to: dest.clone(),
amount: value,
});

Ok(value)
}

}

impl<T: Config<I>, I: 'static> fungible::Inspect<T::AccountId> for Pallet<T, I> {
@@ -1139,8 +1204,8 @@ impl<T: Config<I>, I: 'static> fungible::Transfer<T::AccountId> for Pallet<T, I>
amount: T::Balance,
keep_alive: bool,
) -> Result<T::Balance, DispatchError> {
let er = if keep_alive { KeepAlive } else { AllowDeath };
<Self as Currency<T::AccountId>>::transfer(source, dest, amount, er).map(|_| amount)
let existence_requirement = if keep_alive { KeepAlive } else { AllowDeath };
Self::do_transfer(source, dest, amount, existence_requirement)
}
}

0 comments on commit 41835be

Please sign in to comment.