use super::{
imbalance::{Imbalance, SignedImbalance},
misc::{Balance, ExistenceRequirement, WithdrawReasons},
};
use crate::{dispatch::DispatchResult, traits::Get};
use subsoil::runtime::{traits::MaybeSerializeDeserialize, DispatchError};
mod reservable;
pub use reservable::{NamedReservableCurrency, ReservableCurrency, ReservableWithName};
mod lockable;
pub use lockable::{
InspectLockableCurrency, LockIdentifier, LockableCurrency, NoVestedTransfers, VestedTransfer,
VestingSchedule,
};
pub trait Currency<AccountId> {
type Balance: Balance + MaybeSerializeDeserialize;
type PositiveImbalance: Imbalance<Self::Balance, Opposite = Self::NegativeImbalance>;
type NegativeImbalance: Imbalance<Self::Balance, Opposite = Self::PositiveImbalance>;
fn total_balance(who: &AccountId) -> Self::Balance;
fn can_slash(who: &AccountId, value: Self::Balance) -> bool;
fn total_issuance() -> Self::Balance;
fn active_issuance() -> Self::Balance {
Self::total_issuance()
}
fn deactivate(_: Self::Balance) {}
fn reactivate(_: Self::Balance) {}
fn minimum_balance() -> Self::Balance;
fn burn(amount: Self::Balance) -> Self::PositiveImbalance;
fn issue(amount: Self::Balance) -> Self::NegativeImbalance;
fn pair(amount: Self::Balance) -> (Self::PositiveImbalance, Self::NegativeImbalance) {
(Self::burn(amount), Self::issue(amount))
}
fn free_balance(who: &AccountId) -> Self::Balance;
fn ensure_can_withdraw(
who: &AccountId,
_amount: Self::Balance,
reasons: WithdrawReasons,
new_balance: Self::Balance,
) -> DispatchResult;
fn transfer(
source: &AccountId,
dest: &AccountId,
value: Self::Balance,
existence_requirement: ExistenceRequirement,
) -> DispatchResult;
fn slash(who: &AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance);
fn deposit_into_existing(
who: &AccountId,
value: Self::Balance,
) -> Result<Self::PositiveImbalance, DispatchError>;
fn resolve_into_existing(
who: &AccountId,
value: Self::NegativeImbalance,
) -> Result<(), Self::NegativeImbalance> {
let v = value.peek();
match Self::deposit_into_existing(who, v) {
Ok(opposite) => Ok(drop(value.offset(opposite))),
_ => Err(value),
}
}
fn deposit_creating(who: &AccountId, value: Self::Balance) -> Self::PositiveImbalance;
fn resolve_creating(who: &AccountId, value: Self::NegativeImbalance) {
let v = value.peek();
drop(value.offset(Self::deposit_creating(who, v)));
}
fn withdraw(
who: &AccountId,
value: Self::Balance,
reasons: WithdrawReasons,
liveness: ExistenceRequirement,
) -> Result<Self::NegativeImbalance, DispatchError>;
fn settle(
who: &AccountId,
value: Self::PositiveImbalance,
reasons: WithdrawReasons,
liveness: ExistenceRequirement,
) -> Result<(), Self::PositiveImbalance> {
let v = value.peek();
match Self::withdraw(who, v, reasons, liveness) {
Ok(opposite) => Ok(drop(value.offset(opposite))),
_ => Err(value),
}
}
fn make_free_balance_be(
who: &AccountId,
balance: Self::Balance,
) -> SignedImbalance<Self::Balance, Self::PositiveImbalance>;
}
pub struct TotalIssuanceOf<C: Currency<A>, A>(core::marker::PhantomData<(C, A)>);
impl<C: Currency<A>, A> Get<C::Balance> for TotalIssuanceOf<C, A> {
fn get() -> C::Balance {
C::total_issuance()
}
}
pub struct ActiveIssuanceOf<C: Currency<A>, A>(core::marker::PhantomData<(C, A)>);
impl<C: Currency<A>, A> Get<C::Balance> for ActiveIssuanceOf<C, A> {
fn get() -> C::Balance {
C::active_issuance()
}
}
#[cfg(feature = "std")]
impl<AccountId> Currency<AccountId> for () {
type Balance = u32;
type PositiveImbalance = ();
type NegativeImbalance = ();
fn total_balance(_: &AccountId) -> Self::Balance {
0
}
fn can_slash(_: &AccountId, _: Self::Balance) -> bool {
true
}
fn total_issuance() -> Self::Balance {
0
}
fn minimum_balance() -> Self::Balance {
0
}
fn burn(_: Self::Balance) -> Self::PositiveImbalance {
()
}
fn issue(_: Self::Balance) -> Self::NegativeImbalance {
()
}
fn pair(_: Self::Balance) -> (Self::PositiveImbalance, Self::NegativeImbalance) {
((), ())
}
fn free_balance(_: &AccountId) -> Self::Balance {
0
}
fn ensure_can_withdraw(
_: &AccountId,
_: Self::Balance,
_: WithdrawReasons,
_: Self::Balance,
) -> DispatchResult {
Ok(())
}
fn transfer(
_: &AccountId,
_: &AccountId,
_: Self::Balance,
_: ExistenceRequirement,
) -> DispatchResult {
Ok(())
}
fn slash(_: &AccountId, _: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) {
((), 0)
}
fn deposit_into_existing(
_: &AccountId,
_: Self::Balance,
) -> Result<Self::PositiveImbalance, DispatchError> {
Ok(())
}
fn resolve_into_existing(
_: &AccountId,
_: Self::NegativeImbalance,
) -> Result<(), Self::NegativeImbalance> {
Ok(())
}
fn deposit_creating(_: &AccountId, _: Self::Balance) -> Self::PositiveImbalance {
()
}
fn resolve_creating(_: &AccountId, _: Self::NegativeImbalance) {}
fn withdraw(
_: &AccountId,
_: Self::Balance,
_: WithdrawReasons,
_: ExistenceRequirement,
) -> Result<Self::NegativeImbalance, DispatchError> {
Ok(())
}
fn settle(
_: &AccountId,
_: Self::PositiveImbalance,
_: WithdrawReasons,
_: ExistenceRequirement,
) -> Result<(), Self::PositiveImbalance> {
Ok(())
}
fn make_free_balance_be(
_: &AccountId,
_: Self::Balance,
) -> SignedImbalance<Self::Balance, Self::PositiveImbalance> {
SignedImbalance::Positive(())
}
}