1use super::*;
26use crate::traits::{
27 fungible::imbalance,
28 tokens::{
29 fungibles, DepositConsequence, Fortitude, Precision, Preservation, Provenance, Restriction,
30 WithdrawConsequence,
31 },
32};
33use sp_core::Get;
34use sp_runtime::{DispatchError, DispatchResult};
35
36pub struct ItemOf<
39 F: fungibles::Inspect<AccountId>,
40 A: Get<<F as fungibles::Inspect<AccountId>>::AssetId>,
41 AccountId,
42>(core::marker::PhantomData<(F, A, AccountId)>);
43
44impl<
45 F: fungibles::Inspect<AccountId>,
46 A: Get<<F as fungibles::Inspect<AccountId>>::AssetId>,
47 AccountId,
48 > Inspect<AccountId> for ItemOf<F, A, AccountId>
49{
50 type Balance = <F as fungibles::Inspect<AccountId>>::Balance;
51 fn total_issuance() -> Self::Balance {
52 <F as fungibles::Inspect<AccountId>>::total_issuance(A::get())
53 }
54 fn active_issuance() -> Self::Balance {
55 <F as fungibles::Inspect<AccountId>>::active_issuance(A::get())
56 }
57 fn minimum_balance() -> Self::Balance {
58 <F as fungibles::Inspect<AccountId>>::minimum_balance(A::get())
59 }
60 fn balance(who: &AccountId) -> Self::Balance {
61 <F as fungibles::Inspect<AccountId>>::balance(A::get(), who)
62 }
63 fn total_balance(who: &AccountId) -> Self::Balance {
64 <F as fungibles::Inspect<AccountId>>::total_balance(A::get(), who)
65 }
66 fn reducible_balance(
67 who: &AccountId,
68 preservation: Preservation,
69 force: Fortitude,
70 ) -> Self::Balance {
71 <F as fungibles::Inspect<AccountId>>::reducible_balance(A::get(), who, preservation, force)
72 }
73 fn can_deposit(
74 who: &AccountId,
75 amount: Self::Balance,
76 provenance: Provenance,
77 ) -> DepositConsequence {
78 <F as fungibles::Inspect<AccountId>>::can_deposit(A::get(), who, amount, provenance)
79 }
80 fn can_withdraw(who: &AccountId, amount: Self::Balance) -> WithdrawConsequence<Self::Balance> {
81 <F as fungibles::Inspect<AccountId>>::can_withdraw(A::get(), who, amount)
82 }
83}
84
85impl<
86 F: fungibles::InspectHold<AccountId>,
87 A: Get<<F as fungibles::Inspect<AccountId>>::AssetId>,
88 AccountId,
89 > InspectHold<AccountId> for ItemOf<F, A, AccountId>
90{
91 type Reason = F::Reason;
92
93 fn reducible_total_balance_on_hold(who: &AccountId, force: Fortitude) -> Self::Balance {
94 <F as fungibles::InspectHold<AccountId>>::reducible_total_balance_on_hold(
95 A::get(),
96 who,
97 force,
98 )
99 }
100 fn hold_available(reason: &Self::Reason, who: &AccountId) -> bool {
101 <F as fungibles::InspectHold<AccountId>>::hold_available(A::get(), reason, who)
102 }
103 fn total_balance_on_hold(who: &AccountId) -> Self::Balance {
104 <F as fungibles::InspectHold<AccountId>>::total_balance_on_hold(A::get(), who)
105 }
106 fn balance_on_hold(reason: &Self::Reason, who: &AccountId) -> Self::Balance {
107 <F as fungibles::InspectHold<AccountId>>::balance_on_hold(A::get(), reason, who)
108 }
109 fn can_hold(reason: &Self::Reason, who: &AccountId, amount: Self::Balance) -> bool {
110 <F as fungibles::InspectHold<AccountId>>::can_hold(A::get(), reason, who, amount)
111 }
112}
113
114impl<
115 F: fungibles::InspectFreeze<AccountId>,
116 A: Get<<F as fungibles::Inspect<AccountId>>::AssetId>,
117 AccountId,
118 > InspectFreeze<AccountId> for ItemOf<F, A, AccountId>
119{
120 type Id = F::Id;
121 fn balance_frozen(id: &Self::Id, who: &AccountId) -> Self::Balance {
122 <F as fungibles::InspectFreeze<AccountId>>::balance_frozen(A::get(), id, who)
123 }
124 fn balance_freezable(who: &AccountId) -> Self::Balance {
125 <F as fungibles::InspectFreeze<AccountId>>::balance_freezable(A::get(), who)
126 }
127 fn can_freeze(id: &Self::Id, who: &AccountId) -> bool {
128 <F as fungibles::InspectFreeze<AccountId>>::can_freeze(A::get(), id, who)
129 }
130}
131
132impl<
133 F: fungibles::Unbalanced<AccountId>,
134 A: Get<<F as fungibles::Inspect<AccountId>>::AssetId>,
135 AccountId,
136 > Unbalanced<AccountId> for ItemOf<F, A, AccountId>
137{
138 fn handle_dust(dust: regular::Dust<AccountId, Self>)
139 where
140 Self: Sized,
141 {
142 <F as fungibles::Unbalanced<AccountId>>::handle_dust(fungibles::Dust(A::get(), dust.0))
143 }
144 fn write_balance(
145 who: &AccountId,
146 amount: Self::Balance,
147 ) -> Result<Option<Self::Balance>, DispatchError> {
148 <F as fungibles::Unbalanced<AccountId>>::write_balance(A::get(), who, amount)
149 }
150 fn set_total_issuance(amount: Self::Balance) -> () {
151 <F as fungibles::Unbalanced<AccountId>>::set_total_issuance(A::get(), amount)
152 }
153 fn decrease_balance(
154 who: &AccountId,
155 amount: Self::Balance,
156 precision: Precision,
157 preservation: Preservation,
158 force: Fortitude,
159 ) -> Result<Self::Balance, DispatchError> {
160 <F as fungibles::Unbalanced<AccountId>>::decrease_balance(
161 A::get(),
162 who,
163 amount,
164 precision,
165 preservation,
166 force,
167 )
168 }
169 fn increase_balance(
170 who: &AccountId,
171 amount: Self::Balance,
172 precision: Precision,
173 ) -> Result<Self::Balance, DispatchError> {
174 <F as fungibles::Unbalanced<AccountId>>::increase_balance(A::get(), who, amount, precision)
175 }
176}
177
178impl<
179 F: fungibles::UnbalancedHold<AccountId>,
180 A: Get<<F as fungibles::Inspect<AccountId>>::AssetId>,
181 AccountId,
182 > UnbalancedHold<AccountId> for ItemOf<F, A, AccountId>
183{
184 fn set_balance_on_hold(
185 reason: &Self::Reason,
186 who: &AccountId,
187 amount: Self::Balance,
188 ) -> DispatchResult {
189 <F as fungibles::UnbalancedHold<AccountId>>::set_balance_on_hold(
190 A::get(),
191 reason,
192 who,
193 amount,
194 )
195 }
196 fn decrease_balance_on_hold(
197 reason: &Self::Reason,
198 who: &AccountId,
199 amount: Self::Balance,
200 precision: Precision,
201 ) -> Result<Self::Balance, DispatchError> {
202 <F as fungibles::UnbalancedHold<AccountId>>::decrease_balance_on_hold(
203 A::get(),
204 reason,
205 who,
206 amount,
207 precision,
208 )
209 }
210 fn increase_balance_on_hold(
211 reason: &Self::Reason,
212 who: &AccountId,
213 amount: Self::Balance,
214 precision: Precision,
215 ) -> Result<Self::Balance, DispatchError> {
216 <F as fungibles::UnbalancedHold<AccountId>>::increase_balance_on_hold(
217 A::get(),
218 reason,
219 who,
220 amount,
221 precision,
222 )
223 }
224}
225
226impl<
227 F: fungibles::Mutate<AccountId>,
228 A: Get<<F as fungibles::Inspect<AccountId>>::AssetId>,
229 AccountId: Eq,
230 > Mutate<AccountId> for ItemOf<F, A, AccountId>
231{
232 fn mint_into(who: &AccountId, amount: Self::Balance) -> Result<Self::Balance, DispatchError> {
233 <F as fungibles::Mutate<AccountId>>::mint_into(A::get(), who, amount)
234 }
235 fn burn_from(
236 who: &AccountId,
237 amount: Self::Balance,
238 preservation: Preservation,
239 precision: Precision,
240 force: Fortitude,
241 ) -> Result<Self::Balance, DispatchError> {
242 <F as fungibles::Mutate<AccountId>>::burn_from(
243 A::get(),
244 who,
245 amount,
246 preservation,
247 precision,
248 force,
249 )
250 }
251 fn shelve(who: &AccountId, amount: Self::Balance) -> Result<Self::Balance, DispatchError> {
252 <F as fungibles::Mutate<AccountId>>::shelve(A::get(), who, amount)
253 }
254 fn restore(who: &AccountId, amount: Self::Balance) -> Result<Self::Balance, DispatchError> {
255 <F as fungibles::Mutate<AccountId>>::restore(A::get(), who, amount)
256 }
257 fn transfer(
258 source: &AccountId,
259 dest: &AccountId,
260 amount: Self::Balance,
261 preservation: Preservation,
262 ) -> Result<Self::Balance, DispatchError> {
263 <F as fungibles::Mutate<AccountId>>::transfer(A::get(), source, dest, amount, preservation)
264 }
265
266 fn set_balance(who: &AccountId, amount: Self::Balance) -> Self::Balance {
267 <F as fungibles::Mutate<AccountId>>::set_balance(A::get(), who, amount)
268 }
269}
270
271impl<
272 F: fungibles::MutateHold<AccountId>,
273 A: Get<<F as fungibles::Inspect<AccountId>>::AssetId>,
274 AccountId,
275 > MutateHold<AccountId> for ItemOf<F, A, AccountId>
276{
277 fn hold(reason: &Self::Reason, who: &AccountId, amount: Self::Balance) -> DispatchResult {
278 <F as fungibles::MutateHold<AccountId>>::hold(A::get(), reason, who, amount)
279 }
280 fn release(
281 reason: &Self::Reason,
282 who: &AccountId,
283 amount: Self::Balance,
284 precision: Precision,
285 ) -> Result<Self::Balance, DispatchError> {
286 <F as fungibles::MutateHold<AccountId>>::release(A::get(), reason, who, amount, precision)
287 }
288 fn burn_held(
289 reason: &Self::Reason,
290 who: &AccountId,
291 amount: Self::Balance,
292 precision: Precision,
293 force: Fortitude,
294 ) -> Result<Self::Balance, DispatchError> {
295 <F as fungibles::MutateHold<AccountId>>::burn_held(
296 A::get(),
297 reason,
298 who,
299 amount,
300 precision,
301 force,
302 )
303 }
304 fn transfer_on_hold(
305 reason: &Self::Reason,
306 source: &AccountId,
307 dest: &AccountId,
308 amount: Self::Balance,
309 precision: Precision,
310 mode: Restriction,
311 force: Fortitude,
312 ) -> Result<Self::Balance, DispatchError> {
313 <F as fungibles::MutateHold<AccountId>>::transfer_on_hold(
314 A::get(),
315 reason,
316 source,
317 dest,
318 amount,
319 precision,
320 mode,
321 force,
322 )
323 }
324 fn transfer_and_hold(
325 reason: &Self::Reason,
326 source: &AccountId,
327 dest: &AccountId,
328 amount: Self::Balance,
329 precision: Precision,
330 preservation: Preservation,
331 force: Fortitude,
332 ) -> Result<Self::Balance, DispatchError> {
333 <F as fungibles::MutateHold<AccountId>>::transfer_and_hold(
334 A::get(),
335 reason,
336 source,
337 dest,
338 amount,
339 precision,
340 preservation,
341 force,
342 )
343 }
344}
345
346impl<
347 F: fungibles::MutateFreeze<AccountId>,
348 A: Get<<F as fungibles::Inspect<AccountId>>::AssetId>,
349 AccountId,
350 > MutateFreeze<AccountId> for ItemOf<F, A, AccountId>
351{
352 fn set_freeze(id: &Self::Id, who: &AccountId, amount: Self::Balance) -> DispatchResult {
353 <F as fungibles::MutateFreeze<AccountId>>::set_freeze(A::get(), id, who, amount)
354 }
355 fn extend_freeze(id: &Self::Id, who: &AccountId, amount: Self::Balance) -> DispatchResult {
356 <F as fungibles::MutateFreeze<AccountId>>::extend_freeze(A::get(), id, who, amount)
357 }
358 fn thaw(id: &Self::Id, who: &AccountId) -> DispatchResult {
359 <F as fungibles::MutateFreeze<AccountId>>::thaw(A::get(), id, who)
360 }
361}
362
363pub struct ConvertImbalanceDropHandler<AccountId, Balance, AssetIdType, AssetId, Handler>(
364 core::marker::PhantomData<(AccountId, Balance, AssetIdType, AssetId, Handler)>,
365);
366
367impl<
368 AccountId,
369 Balance,
370 AssetIdType,
371 AssetId: Get<AssetIdType>,
372 Handler: crate::traits::fungibles::HandleImbalanceDrop<AssetIdType, Balance>,
373 > HandleImbalanceDrop<Balance>
374 for ConvertImbalanceDropHandler<AccountId, Balance, AssetIdType, AssetId, Handler>
375{
376 fn handle(amount: Balance) {
377 Handler::handle(AssetId::get(), amount)
378 }
379}
380
381impl<
382 F: fungibles::Inspect<AccountId>
383 + fungibles::Unbalanced<AccountId>
384 + fungibles::Balanced<AccountId>,
385 A: Get<<F as fungibles::Inspect<AccountId>>::AssetId>,
386 AccountId,
387 > Balanced<AccountId> for ItemOf<F, A, AccountId>
388{
389 type OnDropDebt =
390 ConvertImbalanceDropHandler<AccountId, Self::Balance, F::AssetId, A, F::OnDropDebt>;
391 type OnDropCredit =
392 ConvertImbalanceDropHandler<AccountId, Self::Balance, F::AssetId, A, F::OnDropCredit>;
393 fn deposit(
394 who: &AccountId,
395 value: Self::Balance,
396 precision: Precision,
397 ) -> Result<Debt<AccountId, Self>, DispatchError> {
398 <F as fungibles::Balanced<AccountId>>::deposit(A::get(), who, value, precision)
399 .map(imbalance::from_fungibles)
400 }
401 fn issue(amount: Self::Balance) -> Credit<AccountId, Self> {
402 let credit = <F as fungibles::Balanced<AccountId>>::issue(A::get(), amount);
403 imbalance::from_fungibles(credit)
404 }
405 fn pair(
406 amount: Self::Balance,
407 ) -> Result<(Debt<AccountId, Self>, Credit<AccountId, Self>), DispatchError> {
408 let (a, b) = <F as fungibles::Balanced<AccountId>>::pair(A::get(), amount)?;
409 Ok((imbalance::from_fungibles(a), imbalance::from_fungibles(b)))
410 }
411 fn rescind(amount: Self::Balance) -> Debt<AccountId, Self> {
412 let debt = <F as fungibles::Balanced<AccountId>>::rescind(A::get(), amount);
413 imbalance::from_fungibles(debt)
414 }
415 fn resolve(
416 who: &AccountId,
417 credit: Credit<AccountId, Self>,
418 ) -> Result<(), Credit<AccountId, Self>> {
419 let credit = fungibles::imbalance::from_fungible(credit, A::get());
420 <F as fungibles::Balanced<AccountId>>::resolve(who, credit)
421 .map_err(imbalance::from_fungibles)
422 }
423 fn settle(
424 who: &AccountId,
425 debt: Debt<AccountId, Self>,
426 preservation: Preservation,
427 ) -> Result<Credit<AccountId, Self>, Debt<AccountId, Self>> {
428 let debt = fungibles::imbalance::from_fungible(debt, A::get());
429 <F as fungibles::Balanced<AccountId>>::settle(who, debt, preservation).map_or_else(
430 |d| Err(imbalance::from_fungibles(d)),
431 |c| Ok(imbalance::from_fungibles(c)),
432 )
433 }
434 fn withdraw(
435 who: &AccountId,
436 value: Self::Balance,
437 precision: Precision,
438 preservation: Preservation,
439 force: Fortitude,
440 ) -> Result<Credit<AccountId, Self>, DispatchError> {
441 <F as fungibles::Balanced<AccountId>>::withdraw(
442 A::get(),
443 who,
444 value,
445 precision,
446 preservation,
447 force,
448 )
449 .map(imbalance::from_fungibles)
450 }
451}
452
453impl<
454 F: fungibles::BalancedHold<AccountId>,
455 A: Get<<F as fungibles::Inspect<AccountId>>::AssetId>,
456 AccountId,
457 > BalancedHold<AccountId> for ItemOf<F, A, AccountId>
458{
459 fn slash(
460 reason: &Self::Reason,
461 who: &AccountId,
462 amount: Self::Balance,
463 ) -> (Credit<AccountId, Self>, Self::Balance) {
464 let (credit, amount) =
465 <F as fungibles::BalancedHold<AccountId>>::slash(A::get(), reason, who, amount);
466 (imbalance::from_fungibles(credit), amount)
467 }
468}
469
470#[test]
471fn test() {}