Add low level traits to retrieve name, symbol, decimals and allowance in pallet-assets (#9757)

* Add ERC20 compatible trait to retrieve name, symbol, decimals and allowance

* delegate instead of spender

* Remove erc20 trait and divide it into lower level traits

* add import

* approvals and metadata depend on fungibles

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
girazoki
2021-10-07 16:29:48 +02:00
committed by GitHub
parent 44824ae472
commit 48a524c565
7 changed files with 317 additions and 93 deletions
+3 -93
View File
@@ -948,43 +948,7 @@ pub mod pallet {
decimals: u8,
) -> DispatchResult {
let origin = ensure_signed(origin)?;
let bounded_name: BoundedVec<u8, T::StringLimit> =
name.clone().try_into().map_err(|_| Error::<T, I>::BadMetadata)?;
let bounded_symbol: BoundedVec<u8, T::StringLimit> =
symbol.clone().try_into().map_err(|_| Error::<T, I>::BadMetadata)?;
let d = Asset::<T, I>::get(id).ok_or(Error::<T, I>::Unknown)?;
ensure!(&origin == &d.owner, Error::<T, I>::NoPermission);
Metadata::<T, I>::try_mutate_exists(id, |metadata| {
ensure!(
metadata.as_ref().map_or(true, |m| !m.is_frozen),
Error::<T, I>::NoPermission
);
let old_deposit = metadata.take().map_or(Zero::zero(), |m| m.deposit);
let new_deposit = T::MetadataDepositPerByte::get()
.saturating_mul(((name.len() + symbol.len()) as u32).into())
.saturating_add(T::MetadataDepositBase::get());
if new_deposit > old_deposit {
T::Currency::reserve(&origin, new_deposit - old_deposit)?;
} else {
T::Currency::unreserve(&origin, old_deposit - new_deposit);
}
*metadata = Some(AssetMetadata {
deposit: new_deposit,
name: bounded_name,
symbol: bounded_symbol,
decimals,
is_frozen: false,
});
Self::deposit_event(Event::MetadataSet(id, name, symbol, decimals, false));
Ok(())
})
Self::do_set_metadata(id, &origin, name, symbol, decimals)
}
/// Clear the metadata for an asset.
@@ -1171,35 +1135,7 @@ pub mod pallet {
) -> DispatchResult {
let owner = ensure_signed(origin)?;
let delegate = T::Lookup::lookup(delegate)?;
let mut d = Asset::<T, I>::get(id).ok_or(Error::<T, I>::Unknown)?;
ensure!(!d.is_frozen, Error::<T, I>::Frozen);
Approvals::<T, I>::try_mutate(
(id, &owner, &delegate),
|maybe_approved| -> DispatchResult {
let mut approved = match maybe_approved.take() {
// an approval already exists and is being updated
Some(a) => a,
// a new approval is created
None => {
d.approvals.saturating_inc();
Default::default()
},
};
let deposit_required = T::ApprovalDeposit::get();
if approved.deposit < deposit_required {
T::Currency::reserve(&owner, deposit_required - approved.deposit)?;
approved.deposit = deposit_required;
}
approved.amount = approved.amount.saturating_add(amount);
*maybe_approved = Some(approved);
Ok(())
},
)?;
Asset::<T, I>::insert(id, d);
Self::deposit_event(Event::ApprovedTransfer(id, owner, delegate, amount));
Ok(())
Self::do_approve_transfer(id, &owner, &delegate, amount)
}
/// Cancel all of some asset approved for delegated transfer by a third-party account.
@@ -1306,33 +1242,7 @@ pub mod pallet {
let delegate = ensure_signed(origin)?;
let owner = T::Lookup::lookup(owner)?;
let destination = T::Lookup::lookup(destination)?;
Approvals::<T, I>::try_mutate_exists(
(id, &owner, delegate),
|maybe_approved| -> DispatchResult {
let mut approved = maybe_approved.take().ok_or(Error::<T, I>::Unapproved)?;
let remaining =
approved.amount.checked_sub(&amount).ok_or(Error::<T, I>::Unapproved)?;
let f =
TransferFlags { keep_alive: false, best_effort: false, burn_dust: false };
Self::do_transfer(id, &owner, &destination, amount, None, f)?;
if remaining.is_zero() {
T::Currency::unreserve(&owner, approved.deposit);
Asset::<T, I>::mutate(id, |maybe_details| {
if let Some(details) = maybe_details {
details.approvals.saturating_dec();
}
});
} else {
approved.amount = remaining;
*maybe_approved = Some(approved);
}
Ok(())
},
)?;
Ok(())
Self::do_transfer_approved(id, &owner, &delegate, &destination, amount)
}
}
}