@@ -139,15 +139,25 @@ use sp_runtime::{
139139} ;
140140use codec:: { Encode , Decode , HasCompact } ;
141141use frame_support:: { ensure, dispatch:: { DispatchError , DispatchResult } } ;
142- use frame_support:: traits:: { Currency , ReservableCurrency , BalanceStatus :: Reserved , Fungibles } ;
142+ use frame_support:: traits:: { Currency , ReservableCurrency , BalanceStatus :: Reserved } ;
143+ use frame_support:: traits:: tokens:: { WithdrawConsequence , DepositConsequence , fungibles} ;
143144use frame_system:: Config as SystemConfig ;
145+
144146pub use weights:: WeightInfo ;
145147pub use pallet:: * ;
146148
147- impl < T : Config > Fungibles < <T as SystemConfig >:: AccountId > for Pallet < T > {
149+ impl < T : Config > fungibles :: Inspect < <T as SystemConfig >:: AccountId > for Pallet < T > {
148150 type AssetId = T :: AssetId ;
149151 type Balance = T :: Balance ;
150152
153+ fn total_issuance ( asset : Self :: AssetId ) -> Self :: Balance {
154+ Asset :: < T > :: get ( asset) . map ( |x| x. supply ) . unwrap_or_else ( Zero :: zero)
155+ }
156+
157+ fn minimum_balance ( asset : Self :: AssetId ) -> Self :: Balance {
158+ Asset :: < T > :: get ( asset) . map ( |x| x. min_balance ) . unwrap_or_else ( Zero :: zero)
159+ }
160+
151161 fn balance (
152162 asset : Self :: AssetId ,
153163 who : & <T as SystemConfig >:: AccountId ,
@@ -159,24 +169,45 @@ impl<T: Config> Fungibles<<T as SystemConfig>::AccountId> for Pallet<T> {
159169 asset : Self :: AssetId ,
160170 who : & <T as SystemConfig >:: AccountId ,
161171 amount : Self :: Balance ,
162- ) -> bool {
172+ ) -> DepositConsequence {
163173 Pallet :: < T > :: can_deposit ( asset, who, amount)
164174 }
165175
176+ fn can_withdraw (
177+ asset : Self :: AssetId ,
178+ who : & <T as SystemConfig >:: AccountId ,
179+ amount : Self :: Balance ,
180+ ) -> WithdrawConsequence < Self :: Balance > {
181+ Pallet :: < T > :: can_withdraw ( asset, who, amount)
182+ }
183+ }
184+
185+ impl < T : Config > fungibles:: Mutate < <T as SystemConfig >:: AccountId > for Pallet < T > {
166186 fn deposit (
167187 asset : Self :: AssetId ,
168- who : <T as SystemConfig >:: AccountId ,
188+ who : & <T as SystemConfig >:: AccountId ,
169189 amount : Self :: Balance ,
170190 ) -> DispatchResult {
171- Pallet :: < T > :: increase_balance ( asset, who, amount, None )
191+ Pallet :: < T > :: increase_balance ( asset, who. clone ( ) , amount, None )
172192 }
173193
174194 fn withdraw (
175195 asset : Self :: AssetId ,
176- who : <T as SystemConfig >:: AccountId ,
196+ who : & <T as SystemConfig >:: AccountId ,
177197 amount : Self :: Balance ,
178- ) -> DispatchResult {
179- Pallet :: < T > :: reduce_balance ( asset, who, amount, None )
198+ ) -> Result < Self :: Balance , DispatchError > {
199+ Pallet :: < T > :: reduce_balance ( asset, who. clone ( ) , amount, None )
200+ }
201+ }
202+
203+ impl < T : Config > fungibles:: Transfer < T :: AccountId > for Pallet < T > {
204+ fn transfer (
205+ asset : Self :: AssetId ,
206+ source : & T :: AccountId ,
207+ dest : & T :: AccountId ,
208+ amount : T :: Balance ,
209+ ) -> Result < T :: Balance , DispatchError > {
210+ <Self as fungibles:: Mutate :: < T :: AccountId > >:: transfer ( asset , source , dest , amount )
180211 }
181212}
182213
@@ -671,7 +702,7 @@ pub mod pallet {
671702 let origin = ensure_signed ( origin) ?;
672703 let who = T :: Lookup :: lookup ( who) ?;
673704
674- Self :: reduce_balance ( id, who, amount, Some ( origin) )
705+ Self :: reduce_balance ( id, who, amount, Some ( origin) ) . map ( |_| ( ) )
675706 }
676707
677708 /// Move some assets from the sender account to another.
@@ -1380,21 +1411,57 @@ impl<T: Config> Pallet<T> {
13801411 d. accounts = d. accounts . saturating_sub ( 1 ) ;
13811412 }
13821413
1383- fn can_deposit ( id : T :: AssetId , who : & T :: AccountId , amount : T :: Balance ) -> bool {
1414+ fn can_deposit ( id : T :: AssetId , who : & T :: AccountId , amount : T :: Balance ) -> DepositConsequence {
13841415 let details = match Asset :: < T > :: get ( id) {
13851416 Some ( details) => details,
1386- None => return false ,
1417+ None => return DepositConsequence :: UnknownAsset ,
13871418 } ;
1388- if details. supply . checked_add ( & amount) . is_none ( ) { return false }
1419+ if details. supply . checked_add ( & amount) . is_none ( ) {
1420+ return DepositConsequence :: Overflow
1421+ }
13891422 let account = Account :: < T > :: get ( id, who) ;
1390- if account. balance . checked_add ( & amount) . is_none ( ) { return false }
1423+ if account. balance . checked_add ( & amount) . is_none ( ) {
1424+ return DepositConsequence :: Overflow
1425+ }
13911426 if account. balance . is_zero ( ) {
1392- if amount < details. min_balance { return false }
1393- if !details. is_sufficient && frame_system:: Pallet :: < T > :: providers ( who) == 0 { return false }
1394- if details. is_sufficient && details. sufficients . checked_add ( 1 ) . is_none ( ) { return false }
1427+ if amount < details. min_balance {
1428+ return DepositConsequence :: BelowMinimum
1429+ }
1430+ if !details. is_sufficient && frame_system:: Pallet :: < T > :: providers ( who) == 0 {
1431+ return DepositConsequence :: CannotCreate
1432+ }
1433+ if details. is_sufficient && details. sufficients . checked_add ( 1 ) . is_none ( ) {
1434+ return DepositConsequence :: Overflow
1435+ }
13951436 }
13961437
1397- true
1438+ DepositConsequence :: Success
1439+ }
1440+
1441+ fn can_withdraw (
1442+ id : T :: AssetId ,
1443+ who : & T :: AccountId ,
1444+ amount : T :: Balance ,
1445+ ) -> WithdrawConsequence < T :: Balance > {
1446+ let details = match Asset :: < T > :: get ( id) {
1447+ Some ( details) => details,
1448+ None => return WithdrawConsequence :: UnknownAsset ,
1449+ } ;
1450+ if details. supply . checked_sub ( & amount) . is_none ( ) {
1451+ return WithdrawConsequence :: Underflow
1452+ }
1453+ let account = Account :: < T > :: get ( id, who) ;
1454+ if let Some ( rest) = account. balance . checked_sub ( & amount) {
1455+ if rest < details. min_balance {
1456+ WithdrawConsequence :: ReducedToZero ( rest)
1457+ } else {
1458+ // NOTE: this assumes (correctly) that the token won't be a provider. If that ever
1459+ // changes, this will need to change.
1460+ WithdrawConsequence :: Success
1461+ }
1462+ } else {
1463+ WithdrawConsequence :: NoFunds
1464+ }
13981465 }
13991466
14001467 fn increase_balance (
@@ -1430,7 +1497,7 @@ impl<T: Config> Pallet<T> {
14301497 target : T :: AccountId ,
14311498 amount : T :: Balance ,
14321499 maybe_check_admin : Option < T :: AccountId > ,
1433- ) -> DispatchResult {
1500+ ) -> Result < T :: Balance , DispatchError > {
14341501 Asset :: < T > :: try_mutate ( id, |maybe_details| {
14351502 let d = maybe_details. as_mut ( ) . ok_or ( Error :: < T > :: Unknown ) ?;
14361503 if let Some ( check_admin) = maybe_check_admin {
@@ -1458,7 +1525,7 @@ impl<T: Config> Pallet<T> {
14581525 d. supply = d. supply . saturating_sub ( burned) ;
14591526
14601527 Self :: deposit_event ( Event :: Burned ( id, target, burned) ) ;
1461- Ok ( ( ) )
1528+ Ok ( burned )
14621529 } )
14631530 }
14641531
0 commit comments