|
17 | 17 | //! Extra trait implementations for the `GenericAsset` module |
18 | 18 |
|
19 | 19 | use crate::{Error, Module, NegativeImbalance, PositiveImbalance, SpendingAssetIdAuthority, Trait}; |
20 | | -use codec::Codec; |
21 | 20 | use frame_support::traits::{ExistenceRequirement, Imbalance, SignedImbalance, WithdrawReasons}; |
| 21 | +use prml_support::{AssetIdAuthority, MultiCurrencyAccounting}; |
22 | 22 | use sp_runtime::{ |
23 | | - traits::{AtLeast32BitUnsigned, CheckedSub, MaybeSerializeDeserialize, Zero}, |
| 23 | + traits::{CheckedSub, Zero}, |
24 | 24 | DispatchError, DispatchResult, |
25 | 25 | }; |
26 | | -use sp_std::{fmt::Debug, result}; |
27 | | - |
28 | | -// Note: in the following traits the terms: |
29 | | -// - 'token' / 'asset' / 'currency' and |
30 | | -// - 'balance' / 'value' / 'amount' |
31 | | -// are used interchangeably as they make more sense in certain contexts. |
32 | | - |
33 | | -/// Something which provides an ID with authority from chain storage |
34 | | -pub trait AssetIdAuthority { |
35 | | - /// The asset ID type e.g a `u32` |
36 | | - type AssetId; |
37 | | - /// Return the authoritative asset ID (no `&self`) |
38 | | - fn asset_id() -> Self::AssetId; |
39 | | -} |
40 | | - |
41 | | -/// An abstraction over the accounting behaviour of a fungible, multi-currency system |
42 | | -/// Currencies in the system are identifiable by a unique `CurrencyId` |
43 | | -pub trait MultiCurrencyAccounting { |
44 | | - /// The ID type for an account in the system |
45 | | - type AccountId: Codec + Debug + Default; |
46 | | - /// The balance of an account for a particular currency |
47 | | - type Balance: AtLeast32BitUnsigned + Codec + Copy + MaybeSerializeDeserialize + Debug + Default; |
48 | | - /// The ID type of a currency in the system |
49 | | - type CurrencyId: Codec + Debug + Default; |
50 | | - /// A type the is aware of the default network currency ID |
51 | | - /// When the currency ID is not specified for a `MultiCurrencyAccounting` method, it will be used |
52 | | - /// by default |
53 | | - type DefaultCurrencyId: AssetIdAuthority<AssetId = Self::CurrencyId>; |
54 | | - /// The opaque token type for an imbalance of a particular currency. This is returned by unbalanced operations |
55 | | - /// and must be dealt with. It may be dropped but cannot be cloned. |
56 | | - type NegativeImbalance: Imbalance<Self::Balance, Opposite = Self::PositiveImbalance>; |
57 | | - /// The opaque token type for an imbalance of a particular currency. This is returned by unbalanced operations |
58 | | - /// and must be dealt with. It may be dropped but cannot be cloned. |
59 | | - type PositiveImbalance: Imbalance<Self::Balance, Opposite = Self::NegativeImbalance>; |
60 | | - |
61 | | - // PUBLIC IMMUTABLES |
62 | | - |
63 | | - /// The minimum balance any single account may have. This is equivalent to the `Balances` module's |
64 | | - /// `ExistentialDeposit`. |
65 | | - fn minimum_balance() -> Self::Balance { |
66 | | - Zero::zero() |
67 | | - } |
68 | | - |
69 | | - /// The combined balance (free + reserved) of `who` for the given `currency`. |
70 | | - fn total_balance(who: &Self::AccountId, currency: Option<Self::CurrencyId>) -> Self::Balance; |
71 | | - |
72 | | - /// The 'free' balance of a given account. |
73 | | - /// |
74 | | - /// This is the only balance that matters in terms of most operations on tokens. It alone |
75 | | - /// is used to determine the balance when in the contract execution environment. When this |
76 | | - /// balance falls below the value of `ExistentialDeposit`, then the 'current account' is |
77 | | - /// deleted: specifically `FreeBalance`. Further, the `OnFreeBalanceZero` callback |
78 | | - /// is invoked, giving a chance to external modules to clean up data associated with |
79 | | - /// the deleted account. |
80 | | - /// |
81 | | - /// `system::AccountNonce` is also deleted if `ReservedBalance` is also zero (it also gets |
82 | | - /// collapsed to zero if it ever becomes less than `ExistentialDeposit`. |
83 | | - fn free_balance(who: &Self::AccountId, currency: Option<Self::CurrencyId>) -> Self::Balance; |
84 | | - |
85 | | - /// Returns `Ok` iff the account is able to make a withdrawal of the given amount |
86 | | - /// for the given reason. Basically, it's just a dry-run of `withdraw`. |
87 | | - /// |
88 | | - /// `Err(...)` with the reason why not otherwise. |
89 | | - fn ensure_can_withdraw( |
90 | | - who: &Self::AccountId, |
91 | | - currency: Option<Self::CurrencyId>, |
92 | | - _amount: Self::Balance, |
93 | | - reasons: WithdrawReasons, |
94 | | - new_balance: Self::Balance, |
95 | | - ) -> DispatchResult; |
96 | | - |
97 | | - // PUBLIC MUTABLES (DANGEROUS) |
98 | | - |
99 | | - /// Adds up to `value` to the free balance of `who`. If `who` doesn't exist, it is created. |
100 | | - /// |
101 | | - /// Infallible. |
102 | | - fn deposit_creating( |
103 | | - who: &Self::AccountId, |
104 | | - currency: Option<Self::CurrencyId>, |
105 | | - value: Self::Balance, |
106 | | - ) -> Self::PositiveImbalance; |
107 | | - |
108 | | - /// Mints `value` to the free balance of `who`. |
109 | | - /// |
110 | | - /// If `who` doesn't exist, nothing is done and an Err returned. |
111 | | - fn deposit_into_existing( |
112 | | - who: &Self::AccountId, |
113 | | - currency: Option<Self::CurrencyId>, |
114 | | - value: Self::Balance, |
115 | | - ) -> result::Result<Self::PositiveImbalance, DispatchError>; |
116 | | - |
117 | | - /// Ensure an account's free balance equals some value; this will create the account |
118 | | - /// if needed. |
119 | | - /// |
120 | | - /// Returns a signed imbalance and status to indicate if the account was successfully updated or update |
121 | | - /// has led to killing of the account. |
122 | | - fn make_free_balance_be( |
123 | | - who: &Self::AccountId, |
124 | | - currency: Option<Self::CurrencyId>, |
125 | | - balance: Self::Balance, |
126 | | - ) -> SignedImbalance<Self::Balance, Self::PositiveImbalance>; |
127 | | - |
128 | | - /// Transfer some liquid free balance to another staker. |
129 | | - /// |
130 | | - /// This is a very high-level function. It will ensure all appropriate fees are paid |
131 | | - /// and no imbalance in the system remains. |
132 | | - fn transfer( |
133 | | - source: &Self::AccountId, |
134 | | - dest: &Self::AccountId, |
135 | | - currency: Option<Self::CurrencyId>, |
136 | | - value: Self::Balance, |
137 | | - existence_requirement: ExistenceRequirement, |
138 | | - ) -> DispatchResult; |
139 | | - |
140 | | - /// Removes some free balance from `who` account for `reason` if possible. If `liveness` is |
141 | | - /// `KeepAlive`, then no less than `ExistentialDeposit` must be left remaining. |
142 | | - /// |
143 | | - /// This checks any locks, vesting, and liquidity requirements. If the removal is not possible, |
144 | | - /// then it returns `Err`. |
145 | | - /// |
146 | | - /// If the operation is successful, this will return `Ok` with a `NegativeImbalance` whose value |
147 | | - /// is `value`. |
148 | | - fn withdraw( |
149 | | - who: &Self::AccountId, |
150 | | - currency: Option<Self::CurrencyId>, |
151 | | - value: Self::Balance, |
152 | | - reasons: WithdrawReasons, |
153 | | - liveness: ExistenceRequirement, |
154 | | - ) -> result::Result<Self::NegativeImbalance, DispatchError>; |
155 | | -} |
| 26 | +use sp_std::result; |
156 | 27 |
|
157 | 28 | impl<T: Trait> MultiCurrencyAccounting for Module<T> { |
158 | 29 | type AccountId = T::AccountId; |
|
0 commit comments