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