Skip to content

Commit 0f6b573

Browse files
gavofyorkbkchr
andauthored
Repot frame_support::traits; introduce some new currency stuff (paritytech#8435)
* Reservable, Transferrable Fungible(s), plus adapters. * Repot into new dir * Imbalances for Fungibles * Repot and balanced fungible. * Clean up names and bridge-over Imbalanced. * Repot frame_support::trait. Finally. * Make build. * Docs * Good errors * Fix tests. Implement fungible::Inspect for Balances. * Implement additional traits for Balances. * Revert UI test "fixes" * Fix UI error * Fix UI test * Fixes * Update lock * Grumbles * Grumbles * Fixes Co-authored-by: Bastian Köcher <info@kchr.de>
1 parent 56b9d48 commit 0f6b573

File tree

34 files changed

+4741
-2365
lines changed

34 files changed

+4741
-2365
lines changed

frame/assets/src/lib.rs

Lines changed: 86 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,25 @@ use sp_runtime::{
139139
};
140140
use codec::{Encode, Decode, HasCompact};
141141
use 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};
143144
use frame_system::Config as SystemConfig;
145+
144146
pub use weights::WeightInfo;
145147
pub 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

Comments
 (0)