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::{
34 InspectLockableCurrency, LockIdentifier, LockableCurrency, VestedTransfer, VestingSchedule,
35};
36
37pub trait Currency<AccountId> {
39 type Balance: Balance + MaybeSerializeDeserialize;
41
42 type PositiveImbalance: Imbalance<Self::Balance, Opposite = Self::NegativeImbalance>;
45
46 type NegativeImbalance: Imbalance<Self::Balance, Opposite = Self::PositiveImbalance>;
49
50 fn total_balance(who: &AccountId) -> Self::Balance;
54
55 fn can_slash(who: &AccountId, value: Self::Balance) -> bool;
58
59 fn total_issuance() -> Self::Balance;
61
62 fn active_issuance() -> Self::Balance {
65 Self::total_issuance()
66 }
67
68 fn deactivate(_: Self::Balance) {}
70
71 fn reactivate(_: Self::Balance) {}
73
74 fn minimum_balance() -> Self::Balance;
77
78 fn burn(amount: Self::Balance) -> Self::PositiveImbalance;
84
85 fn issue(amount: Self::Balance) -> Self::NegativeImbalance;
92
93 fn pair(amount: Self::Balance) -> (Self::PositiveImbalance, Self::NegativeImbalance) {
98 (Self::burn(amount), Self::issue(amount))
99 }
100
101 fn free_balance(who: &AccountId) -> Self::Balance;
111
112 fn ensure_can_withdraw(
117 who: &AccountId,
118 _amount: Self::Balance,
119 reasons: WithdrawReasons,
120 new_balance: Self::Balance,
121 ) -> DispatchResult;
122
123 fn transfer(
129 source: &AccountId,
130 dest: &AccountId,
131 value: Self::Balance,
132 existence_requirement: ExistenceRequirement,
133 ) -> DispatchResult;
134
135 fn slash(who: &AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance);
143
144 fn deposit_into_existing(
148 who: &AccountId,
149 value: Self::Balance,
150 ) -> Result<Self::PositiveImbalance, DispatchError>;
151
152 fn resolve_into_existing(
155 who: &AccountId,
156 value: Self::NegativeImbalance,
157 ) -> Result<(), Self::NegativeImbalance> {
158 let v = value.peek();
159 match Self::deposit_into_existing(who, v) {
160 Ok(opposite) => Ok(drop(value.offset(opposite))),
161 _ => Err(value),
162 }
163 }
164
165 fn deposit_creating(who: &AccountId, value: Self::Balance) -> Self::PositiveImbalance;
169
170 fn resolve_creating(who: &AccountId, value: Self::NegativeImbalance) {
173 let v = value.peek();
174 drop(value.offset(Self::deposit_creating(who, v)));
175 }
176
177 fn withdraw(
186 who: &AccountId,
187 value: Self::Balance,
188 reasons: WithdrawReasons,
189 liveness: ExistenceRequirement,
190 ) -> Result<Self::NegativeImbalance, DispatchError>;
191
192 fn settle(
194 who: &AccountId,
195 value: Self::PositiveImbalance,
196 reasons: WithdrawReasons,
197 liveness: ExistenceRequirement,
198 ) -> Result<(), Self::PositiveImbalance> {
199 let v = value.peek();
200 match Self::withdraw(who, v, reasons, liveness) {
201 Ok(opposite) => Ok(drop(value.offset(opposite))),
202 _ => Err(value),
203 }
204 }
205
206 fn make_free_balance_be(
212 who: &AccountId,
213 balance: Self::Balance,
214 ) -> SignedImbalance<Self::Balance, Self::PositiveImbalance>;
215}
216
217pub struct TotalIssuanceOf<C: Currency<A>, A>(core::marker::PhantomData<(C, A)>);
220impl<C: Currency<A>, A> Get<C::Balance> for TotalIssuanceOf<C, A> {
221 fn get() -> C::Balance {
222 C::total_issuance()
223 }
224}
225
226pub struct ActiveIssuanceOf<C: Currency<A>, A>(core::marker::PhantomData<(C, A)>);
229impl<C: Currency<A>, A> Get<C::Balance> for ActiveIssuanceOf<C, A> {
230 fn get() -> C::Balance {
231 C::active_issuance()
232 }
233}
234
235#[cfg(feature = "std")]
236impl<AccountId> Currency<AccountId> for () {
237 type Balance = u32;
238 type PositiveImbalance = ();
239 type NegativeImbalance = ();
240 fn total_balance(_: &AccountId) -> Self::Balance {
241 0
242 }
243 fn can_slash(_: &AccountId, _: Self::Balance) -> bool {
244 true
245 }
246 fn total_issuance() -> Self::Balance {
247 0
248 }
249 fn minimum_balance() -> Self::Balance {
250 0
251 }
252 fn burn(_: Self::Balance) -> Self::PositiveImbalance {
253 ()
254 }
255 fn issue(_: Self::Balance) -> Self::NegativeImbalance {
256 ()
257 }
258 fn pair(_: Self::Balance) -> (Self::PositiveImbalance, Self::NegativeImbalance) {
259 ((), ())
260 }
261 fn free_balance(_: &AccountId) -> Self::Balance {
262 0
263 }
264 fn ensure_can_withdraw(
265 _: &AccountId,
266 _: Self::Balance,
267 _: WithdrawReasons,
268 _: Self::Balance,
269 ) -> DispatchResult {
270 Ok(())
271 }
272 fn transfer(
273 _: &AccountId,
274 _: &AccountId,
275 _: Self::Balance,
276 _: ExistenceRequirement,
277 ) -> DispatchResult {
278 Ok(())
279 }
280 fn slash(_: &AccountId, _: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) {
281 ((), 0)
282 }
283 fn deposit_into_existing(
284 _: &AccountId,
285 _: Self::Balance,
286 ) -> Result<Self::PositiveImbalance, DispatchError> {
287 Ok(())
288 }
289 fn resolve_into_existing(
290 _: &AccountId,
291 _: Self::NegativeImbalance,
292 ) -> Result<(), Self::NegativeImbalance> {
293 Ok(())
294 }
295 fn deposit_creating(_: &AccountId, _: Self::Balance) -> Self::PositiveImbalance {
296 ()
297 }
298 fn resolve_creating(_: &AccountId, _: Self::NegativeImbalance) {}
299 fn withdraw(
300 _: &AccountId,
301 _: Self::Balance,
302 _: WithdrawReasons,
303 _: ExistenceRequirement,
304 ) -> Result<Self::NegativeImbalance, DispatchError> {
305 Ok(())
306 }
307 fn settle(
308 _: &AccountId,
309 _: Self::PositiveImbalance,
310 _: WithdrawReasons,
311 _: ExistenceRequirement,
312 ) -> Result<(), Self::PositiveImbalance> {
313 Ok(())
314 }
315 fn make_free_balance_be(
316 _: &AccountId,
317 _: Self::Balance,
318 ) -> SignedImbalance<Self::Balance, Self::PositiveImbalance> {
319 SignedImbalance::Positive(())
320 }
321}