1use crate::{BalanceOf, Config, HoldReason, NegativeImbalanceOf, PositiveImbalanceOf};
22use frame_support::traits::{
23 fungible::{
24 hold::{Balanced as FunHoldBalanced, Inspect as FunHoldInspect, Mutate as FunHoldMutate},
25 Balanced, Inspect as FunInspect,
26 },
27 tokens::{Fortitude, Precision, Preservation},
28};
29use sp_runtime::{DispatchResult, Saturating};
30
31pub fn existential_deposit<T: Config>() -> BalanceOf<T> {
33 T::Currency::minimum_balance()
34}
35
36pub fn total_issuance<T: Config>() -> BalanceOf<T> {
38 T::Currency::total_issuance()
39}
40
41pub fn total_balance<T: Config>(who: &T::AccountId) -> BalanceOf<T> {
43 T::Currency::total_balance(who)
44}
45
46pub fn stakeable_balance<T: Config>(who: &T::AccountId) -> BalanceOf<T> {
50 free_to_stake::<T>(who).saturating_add(staked::<T>(who))
51}
52
53pub fn staked<T: Config>(who: &T::AccountId) -> BalanceOf<T> {
57 T::Currency::balance_on_hold(&HoldReason::Staking.into(), who)
58}
59
60pub fn free_to_stake<T: Config>(who: &T::AccountId) -> BalanceOf<T> {
64 T::Currency::reducible_balance(who, Preservation::Preserve, Fortitude::Force)
66}
67
68#[cfg(any(test, feature = "runtime-benchmarks"))]
74pub fn set_stakeable_balance<T: Config>(who: &T::AccountId, value: BalanceOf<T>) {
75 use frame_support::traits::fungible::Mutate;
76
77 let ed = existential_deposit::<T>();
79 let staked_balance = staked::<T>(who);
81
82 if value > staked_balance {
84 let _ = T::Currency::set_balance(who, value - staked_balance + ed);
85 } else {
86 update_stake::<T>(who, value).expect("can remove from what is staked");
88 let _ = T::Currency::set_balance(who, ed);
90 }
91
92 assert_eq!(stakeable_balance::<T>(who), value);
94}
95
96pub fn update_stake<T: Config>(who: &T::AccountId, amount: BalanceOf<T>) -> DispatchResult {
101 T::Currency::set_on_hold(&HoldReason::Staking.into(), who, amount)
102}
103
104pub fn kill_stake<T: Config>(who: &T::AccountId) -> DispatchResult {
108 T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort).map(|_| ())
109}
110
111pub fn slash<T: Config>(
115 who: &T::AccountId,
116 value: BalanceOf<T>,
117) -> (NegativeImbalanceOf<T>, BalanceOf<T>) {
118 T::Currency::slash(&HoldReason::Staking.into(), who, value)
119}
120
121pub fn mint_into_existing<T: Config>(
125 who: &T::AccountId,
126 value: BalanceOf<T>,
127) -> Option<PositiveImbalanceOf<T>> {
128 T::Currency::deposit(who, value, Precision::Exact).ok()
130}
131
132pub fn mint_creating<T: Config>(who: &T::AccountId, value: BalanceOf<T>) -> PositiveImbalanceOf<T> {
138 T::Currency::deposit(who, value, Precision::BestEffort).unwrap_or_default()
139}
140
141pub fn deposit_slashed<T: Config>(who: &T::AccountId, value: NegativeImbalanceOf<T>) {
143 let _ = T::Currency::resolve(who, value);
144}
145
146pub fn issue<T: Config>(value: BalanceOf<T>) -> NegativeImbalanceOf<T> {
150 T::Currency::issue(value)
151}
152
153#[cfg(feature = "runtime-benchmarks")]
155pub fn burn<T: Config>(amount: BalanceOf<T>) -> PositiveImbalanceOf<T> {
156 T::Currency::rescind(amount)
157}