Skip to content

Commit

Permalink
Implement do_transfer (related to issue paritytech#151 in Clamor).
Browse files Browse the repository at this point in the history
  • Loading branch information
Alessandro Baffa committed Sep 13, 2022
1 parent 1b6228d commit ab12722
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
Expand Up @@ -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> {
Expand Down Expand Up @@ -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).map(|_| amount)
}
}

Expand Down

0 comments on commit ab12722

Please sign in to comment.