frame_support/traits/tokens/
currency.rs1use super::{
24 imbalance::{Imbalance, SignedImbalance},
25 misc::{Balance, ExistenceRequirement, WithdrawReasons},
26};
27use crate::{dispatch::DispatchResult, traits::Get};
28use sp_runtime::{traits::MaybeSerializeDeserialize, DispatchError};
29
30mod reservable;
31pub use reservable::{NamedReservableCurrency, ReservableCurrency};
32mod lockable;
33pub use lockable::{InspectLockableCurrency, LockIdentifier, LockableCurrency, VestingSchedule};
34
35pub trait Currency<AccountId> {
37 type Balance: Balance + MaybeSerializeDeserialize;
39
40 type PositiveImbalance: Imbalance<Self::Balance, Opposite = Self::NegativeImbalance>;
43
44 type NegativeImbalance: Imbalance<Self::Balance, Opposite = Self::PositiveImbalance>;
47
48 fn total_balance(who: &AccountId) -> Self::Balance;
52
53 fn can_slash(who: &AccountId, value: Self::Balance) -> bool;
56
57 fn total_issuance() -> Self::Balance;
59
60 fn active_issuance() -> Self::Balance {
63 Self::total_issuance()
64 }
65
66 fn deactivate(_: Self::Balance) {}
68
69 fn reactivate(_: Self::Balance) {}
71
72 fn minimum_balance() -> Self::Balance;
75
76 fn burn(amount: Self::Balance) -> Self::PositiveImbalance;
82
83 fn issue(amount: Self::Balance) -> Self::NegativeImbalance;
90
91 fn pair(amount: Self::Balance) -> (Self::PositiveImbalance, Self::NegativeImbalance) {
96 (Self::burn(amount), Self::issue(amount))
97 }
98
99 fn free_balance(who: &AccountId) -> Self::Balance;
109
110 fn ensure_can_withdraw(
115 who: &AccountId,
116 _amount: Self::Balance,
117 reasons: WithdrawReasons,
118 new_balance: Self::Balance,
119 ) -> DispatchResult;
120
121 fn transfer(
127 source: &AccountId,
128 dest: &AccountId,
129 value: Self::Balance,
130 existence_requirement: ExistenceRequirement,
131 ) -> DispatchResult;
132
133 fn slash(who: &AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance);
141
142 fn deposit_into_existing(
146 who: &AccountId,
147 value: Self::Balance,
148 ) -> Result<Self::PositiveImbalance, DispatchError>;
149
150 fn resolve_into_existing(
153 who: &AccountId,
154 value: Self::NegativeImbalance,
155 ) -> Result<(), Self::NegativeImbalance> {
156 let v = value.peek();
157 match Self::deposit_into_existing(who, v) {
158 Ok(opposite) => Ok(drop(value.offset(opposite))),
159 _ => Err(value),
160 }
161 }
162
163 fn deposit_creating(who: &AccountId, value: Self::Balance) -> Self::PositiveImbalance;
167
168 fn resolve_creating(who: &AccountId, value: Self::NegativeImbalance) {
171 let v = value.peek();
172 drop(value.offset(Self::deposit_creating(who, v)));
173 }
174
175 fn withdraw(
184 who: &AccountId,
185 value: Self::Balance,
186 reasons: WithdrawReasons,
187 liveness: ExistenceRequirement,
188 ) -> Result<Self::NegativeImbalance, DispatchError>;
189
190 fn settle(
192 who: &AccountId,
193 value: Self::PositiveImbalance,
194 reasons: WithdrawReasons,
195 liveness: ExistenceRequirement,
196 ) -> Result<(), Self::PositiveImbalance> {
197 let v = value.peek();
198 match Self::withdraw(who, v, reasons, liveness) {
199 Ok(opposite) => Ok(drop(value.offset(opposite))),
200 _ => Err(value),
201 }
202 }
203
204 fn make_free_balance_be(
210 who: &AccountId,
211 balance: Self::Balance,
212 ) -> SignedImbalance<Self::Balance, Self::PositiveImbalance>;
213}
214
215pub struct TotalIssuanceOf<C: Currency<A>, A>(core::marker::PhantomData<(C, A)>);
218impl<C: Currency<A>, A> Get<C::Balance> for TotalIssuanceOf<C, A> {
219 fn get() -> C::Balance {
220 C::total_issuance()
221 }
222}
223
224pub struct ActiveIssuanceOf<C: Currency<A>, A>(core::marker::PhantomData<(C, A)>);
227impl<C: Currency<A>, A> Get<C::Balance> for ActiveIssuanceOf<C, A> {
228 fn get() -> C::Balance {
229 C::active_issuance()
230 }
231}
232
233#[cfg(feature = "std")]
234impl<AccountId> Currency<AccountId> for () {
235 type Balance = u32;
236 type PositiveImbalance = ();
237 type NegativeImbalance = ();
238 fn total_balance(_: &AccountId) -> Self::Balance {
239 0
240 }
241 fn can_slash(_: &AccountId, _: Self::Balance) -> bool {
242 true
243 }
244 fn total_issuance() -> Self::Balance {
245 0
246 }
247 fn minimum_balance() -> Self::Balance {
248 0
249 }
250 fn burn(_: Self::Balance) -> Self::PositiveImbalance {
251 ()
252 }
253 fn issue(_: Self::Balance) -> Self::NegativeImbalance {
254 ()
255 }
256 fn pair(_: Self::Balance) -> (Self::PositiveImbalance, Self::NegativeImbalance) {
257 ((), ())
258 }
259 fn free_balance(_: &AccountId) -> Self::Balance {
260 0
261 }
262 fn ensure_can_withdraw(
263 _: &AccountId,
264 _: Self::Balance,
265 _: WithdrawReasons,
266 _: Self::Balance,
267 ) -> DispatchResult {
268 Ok(())
269 }
270 fn transfer(
271 _: &AccountId,
272 _: &AccountId,
273 _: Self::Balance,
274 _: ExistenceRequirement,
275 ) -> DispatchResult {
276 Ok(())
277 }
278 fn slash(_: &AccountId, _: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) {
279 ((), 0)
280 }
281 fn deposit_into_existing(
282 _: &AccountId,
283 _: Self::Balance,
284 ) -> Result<Self::PositiveImbalance, DispatchError> {
285 Ok(())
286 }
287 fn resolve_into_existing(
288 _: &AccountId,
289 _: Self::NegativeImbalance,
290 ) -> Result<(), Self::NegativeImbalance> {
291 Ok(())
292 }
293 fn deposit_creating(_: &AccountId, _: Self::Balance) -> Self::PositiveImbalance {
294 ()
295 }
296 fn resolve_creating(_: &AccountId, _: Self::NegativeImbalance) {}
297 fn withdraw(
298 _: &AccountId,
299 _: Self::Balance,
300 _: WithdrawReasons,
301 _: ExistenceRequirement,
302 ) -> Result<Self::NegativeImbalance, DispatchError> {
303 Ok(())
304 }
305 fn settle(
306 _: &AccountId,
307 _: Self::PositiveImbalance,
308 _: WithdrawReasons,
309 _: ExistenceRequirement,
310 ) -> Result<(), Self::PositiveImbalance> {
311 Ok(())
312 }
313 fn make_free_balance_be(
314 _: &AccountId,
315 _: Self::Balance,
316 ) -> SignedImbalance<Self::Balance, Self::PositiveImbalance> {
317 SignedImbalance::Positive(())
318 }
319}