Asset Conversion: Pool Account ID derivation with additional Pallet ID seed (#3250)

Introduce `PalletId` as an additional seed parameter for pool's account
id derivation.

The PR also introduces the `pallet_asset_conversion_ops` pallet with a
call to migrate a given pool to thew new account. Additionally
`fungibles::lifetime::ResetTeam` and `fungible::lifetime::Refund`
traits, to facilitate the migration of pools.

---------

Co-authored-by: command-bot <>
This commit is contained in:
Muharem
2024-04-17 12:39:23 +02:00
committed by GitHub
parent e6f3106d89
commit 4e10d3b0a6
31 changed files with 1647 additions and 39 deletions
+32 -3
View File
@@ -368,11 +368,14 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
Ok(())
}
/// Returns a `DepositFrom` of an account only if balance is zero.
/// Refunds the `DepositFrom` of an account only if its balance is zero.
///
/// If the `maybe_check_caller` parameter is specified, it must match the account that provided
/// the deposit or must be the admin of the asset.
pub(super) fn do_refund_other(
id: T::AssetId,
who: &T::AccountId,
caller: &T::AccountId,
maybe_check_caller: Option<T::AccountId>,
) -> DispatchResult {
let mut account = Account::<T, I>::get(&id, &who).ok_or(Error::<T, I>::NoDeposit)?;
let (depositor, deposit) =
@@ -380,7 +383,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
let mut details = Asset::<T, I>::get(&id).ok_or(Error::<T, I>::Unknown)?;
ensure!(details.status == AssetStatus::Live, Error::<T, I>::AssetNotLive);
ensure!(!account.status.is_frozen(), Error::<T, I>::Frozen);
ensure!(caller == &depositor || caller == &details.admin, Error::<T, I>::NoPermission);
if let Some(caller) = maybe_check_caller {
ensure!(caller == depositor || caller == details.admin, Error::<T, I>::NoPermission);
}
ensure!(account.balance.is_zero(), Error::<T, I>::WouldBurn);
T::Currency::unreserve(&depositor, deposit);
@@ -1013,4 +1018,28 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
})
.collect::<Vec<_>>()
}
/// Reset the team for the asset with the given `id`.
///
/// ### Parameters
/// - `id`: The identifier of the asset for which the team is being reset.
/// - `owner`: The new `owner` account for the asset.
/// - `admin`: The new `admin` account for the asset.
/// - `issuer`: The new `issuer` account for the asset.
/// - `freezer`: The new `freezer` account for the asset.
pub(crate) fn do_reset_team(
id: T::AssetId,
owner: T::AccountId,
admin: T::AccountId,
issuer: T::AccountId,
freezer: T::AccountId,
) -> DispatchResult {
let mut d = Asset::<T, I>::get(&id).ok_or(Error::<T, I>::Unknown)?;
d.owner = owner;
d.admin = admin;
d.issuer = issuer;
d.freezer = freezer;
Asset::<T, I>::insert(&id, d);
Ok(())
}
}
@@ -308,3 +308,35 @@ impl<T: Config<I>, I: 'static> fungibles::InspectEnumerable<T::AccountId> for Pa
Asset::<T, I>::iter_keys()
}
}
impl<T: Config<I>, I: 'static> fungibles::roles::ResetTeam<T::AccountId> for Pallet<T, I> {
fn reset_team(
id: T::AssetId,
owner: T::AccountId,
admin: T::AccountId,
issuer: T::AccountId,
freezer: T::AccountId,
) -> DispatchResult {
Self::do_reset_team(id, owner, admin, issuer, freezer)
}
}
impl<T: Config<I>, I: 'static> fungibles::Refund<T::AccountId> for Pallet<T, I> {
type AssetId = T::AssetId;
type Balance = DepositBalanceOf<T, I>;
fn deposit_held(id: Self::AssetId, who: T::AccountId) -> Option<(T::AccountId, Self::Balance)> {
use ExistenceReason::*;
match Account::<T, I>::get(&id, &who).ok_or(Error::<T, I>::NoDeposit).ok()?.reason {
DepositHeld(b) => Some((who, b)),
DepositFrom(d, b) => Some((d, b)),
_ => None,
}
}
fn refund(id: Self::AssetId, who: T::AccountId) -> DispatchResult {
match Self::deposit_held(id.clone(), who.clone()) {
Some((d, _)) if d == who => Self::do_refund(id, who, false),
Some(..) => Self::do_refund_other(id, &who, None),
None => Err(Error::<T, I>::NoDeposit.into()),
}
}
}
+1 -1
View File
@@ -1644,7 +1644,7 @@ pub mod pallet {
let origin = ensure_signed(origin)?;
let who = T::Lookup::lookup(who)?;
let id: T::AssetId = id.into();
Self::do_refund_other(id, &who, &origin)
Self::do_refund_other(id, &who, Some(origin))
}
/// Disallow further unprivileged transfers of an asset `id` to and from an account `who`.