use crate::{BalanceOf, Config, HoldReason, NegativeImbalanceOf, PositiveImbalanceOf};
use frame_support::traits::{
fungible::{
hold::{Balanced as FunHoldBalanced, Inspect as FunHoldInspect, Mutate as FunHoldMutate},
Balanced, Inspect as FunInspect,
},
tokens::{Fortitude, Precision, Preservation},
};
use sp_runtime::{DispatchResult, Saturating};
pub fn existential_deposit<T: Config>() -> BalanceOf<T> {
T::Currency::minimum_balance()
}
pub fn total_issuance<T: Config>() -> BalanceOf<T> {
T::Currency::total_issuance()
}
pub fn total_balance<T: Config>(who: &T::AccountId) -> BalanceOf<T> {
T::Currency::total_balance(who)
}
pub fn stakeable_balance<T: Config>(who: &T::AccountId) -> BalanceOf<T> {
free_to_stake::<T>(who).saturating_add(staked::<T>(who))
}
pub fn staked<T: Config>(who: &T::AccountId) -> BalanceOf<T> {
T::Currency::balance_on_hold(&HoldReason::Staking.into(), who)
}
pub fn free_to_stake<T: Config>(who: &T::AccountId) -> BalanceOf<T> {
T::Currency::reducible_balance(who, Preservation::Preserve, Fortitude::Force)
}
#[cfg(any(test, feature = "runtime-benchmarks"))]
pub fn set_stakeable_balance<T: Config>(who: &T::AccountId, value: BalanceOf<T>) {
use frame_support::traits::fungible::Mutate;
let ed = existential_deposit::<T>();
let staked_balance = staked::<T>(who);
if value > staked_balance {
let _ = T::Currency::set_balance(who, value - staked_balance + ed);
} else {
update_stake::<T>(who, value).expect("can remove from what is staked");
let _ = T::Currency::set_balance(who, ed);
}
assert_eq!(stakeable_balance::<T>(who), value);
}
pub fn update_stake<T: Config>(who: &T::AccountId, amount: BalanceOf<T>) -> DispatchResult {
T::Currency::set_on_hold(&HoldReason::Staking.into(), who, amount)
}
pub fn kill_stake<T: Config>(who: &T::AccountId) -> DispatchResult {
T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort).map(|_| ())
}
pub fn slash<T: Config>(
who: &T::AccountId,
value: BalanceOf<T>,
) -> (NegativeImbalanceOf<T>, BalanceOf<T>) {
T::Currency::slash(&HoldReason::Staking.into(), who, value)
}
pub fn mint_into_existing<T: Config>(
who: &T::AccountId,
value: BalanceOf<T>,
) -> Option<PositiveImbalanceOf<T>> {
T::Currency::deposit(who, value, Precision::Exact).ok()
}
pub fn mint_creating<T: Config>(who: &T::AccountId, value: BalanceOf<T>) -> PositiveImbalanceOf<T> {
T::Currency::deposit(who, value, Precision::BestEffort).unwrap_or_default()
}
pub fn deposit_slashed<T: Config>(who: &T::AccountId, value: NegativeImbalanceOf<T>) {
let _ = T::Currency::resolve(who, value);
}
pub fn issue<T: Config>(value: BalanceOf<T>) -> NegativeImbalanceOf<T> {
T::Currency::issue(value)
}
#[cfg(feature = "runtime-benchmarks")]
pub fn burn<T: Config>(amount: BalanceOf<T>) -> PositiveImbalanceOf<T> {
T::Currency::rescind(amount)
}