Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5,191 changes: 2,853 additions & 2,338 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions frame/assets/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ codec = { package = "parity-scale-codec", version = "2.0.0", default-features =
scale-info = { version = "1.0", default-features = false, features = ["derive"] }
sp-std = { version = "4.0.0-dev", default-features = false, path = "../../primitives/std" }
# Needed for various traits. In our case, `OnFinalize`.
sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../primitives/runtime" }
sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.13", default-features = false }
# Needed for type-safe access to storage DB.
frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" }
frame-support = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.13", default-features = false }
# `system` module provides us with all sorts of useful stuff and macros depend on it being around.
frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" }
frame-system = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.13", default-features = false }
frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true }

[dev-dependencies]
Expand Down
18 changes: 18 additions & 0 deletions frame/assets/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
amount: T::Balance,
maybe_check_issuer: Option<T::AccountId>,
) -> DispatchResult {
let is_locked = LockedAsset::<T, I>::get(id).map_or(false, |d| !d.mint_allowed);
ensure!(!is_locked, Error::<T, I>::NoPermission);

Self::increase_balance(id, beneficiary, amount, |details| -> DispatchResult {
if let Some(check_issuer) = maybe_check_issuer {
ensure!(&check_issuer == &details.issuer, Error::<T, I>::NoPermission);
Expand Down Expand Up @@ -335,6 +338,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
maybe_check_admin: Option<T::AccountId>,
f: DebitFlags,
) -> Result<T::Balance, DispatchError> {
let is_locked = LockedAsset::<T, I>::contains_key(id);
ensure!(!is_locked, Error::<T, I>::NoPermission);

let actual = Self::decrease_balance(id, target, amount, f, |actual, details| {
// Check admin rights.
if let Some(check_admin) = maybe_check_admin {
Expand Down Expand Up @@ -417,6 +423,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
maybe_need_admin: Option<T::AccountId>,
f: TransferFlags,
) -> Result<T::Balance, DispatchError> {
let is_locked = LockedAsset::<T, I>::get(id).map_or(false, |d| !d.transfer_allowed);
ensure!(!is_locked, Error::<T, I>::NoPermission);

// Early exist if no-op.
if amount.is_zero() {
Self::deposit_event(Event::Transferred {
Expand Down Expand Up @@ -544,6 +553,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
witness: DestroyWitness,
maybe_check_owner: Option<T::AccountId>,
) -> Result<DestroyWitness, DispatchError> {
let is_locked = LockedAsset::<T, I>::contains_key(id);
ensure!(!is_locked, Error::<T, I>::NoPermission);

Asset::<T, I>::try_mutate_exists(id, |maybe_details| {
let mut details = maybe_details.take().ok_or(Error::<T, I>::Unknown)?;
if let Some(check_owner) = maybe_check_owner {
Expand Down Expand Up @@ -588,6 +600,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
delegate: &T::AccountId,
amount: T::Balance,
) -> DispatchResult {
let is_locked = LockedAsset::<T, I>::get(id).map_or(false, |d| !d.transfer_allowed);
ensure!(!is_locked, Error::<T, I>::NoPermission);

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(
Expand Down Expand Up @@ -637,6 +652,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
destination: &T::AccountId,
amount: T::Balance,
) -> DispatchResult {
let is_locked = LockedAsset::<T, I>::contains_key(id);
ensure!(!is_locked, Error::<T, I>::NoPermission);

Approvals::<T, I>::try_mutate_exists(
(id, &owner, delegate),
|maybe_approved| -> DispatchResult {
Expand Down
91 changes: 91 additions & 0 deletions frame/assets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,11 @@ pub mod pallet {
ConstU32<300_000>,
>;

#[pallet::storage]
/// Locked assets.
pub(super) type LockedAsset<T: Config<I>, I: 'static = ()> =
StorageMap<_, Blake2_128Concat, T::AssetId, LockedAssetDetails>;

#[pallet::genesis_config]
pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
/// Genesis assets: id, owner, is_sufficient, min_balance
Expand Down Expand Up @@ -471,6 +476,8 @@ pub mod pallet {
Unapproved,
/// The source account would not survive the transfer and it needs to stay alive.
WouldDie,
/// @TODO
WrongOwner,
}

#[pallet::call]
Expand Down Expand Up @@ -625,6 +632,7 @@ pub mod pallet {
) -> DispatchResult {
let origin = ensure_signed(origin)?;
let beneficiary = T::Lookup::lookup(beneficiary)?;

Self::do_mint(id, &beneficiary, amount, Some(origin))?;
Ok(())
}
Expand Down Expand Up @@ -776,6 +784,9 @@ pub mod pallet {
) -> DispatchResult {
let origin = ensure_signed(origin)?;

let is_locked = LockedAsset::<T, I>::contains_key(id);
ensure!(!is_locked, Error::<T, I>::NoPermission);

let d = Asset::<T, I>::get(id).ok_or(Error::<T, I>::Unknown)?;
ensure!(&origin == &d.freezer, Error::<T, I>::NoPermission);
let who = T::Lookup::lookup(who)?;
Expand Down Expand Up @@ -805,6 +816,9 @@ pub mod pallet {
) -> DispatchResult {
let origin = ensure_signed(origin)?;

let is_locked = LockedAsset::<T, I>::contains_key(id);
ensure!(!is_locked, Error::<T, I>::NoPermission);

let details = Asset::<T, I>::get(id).ok_or(Error::<T, I>::Unknown)?;
ensure!(&origin == &details.admin, Error::<T, I>::NoPermission);
let who = T::Lookup::lookup(who)?;
Expand Down Expand Up @@ -832,6 +846,9 @@ pub mod pallet {
) -> DispatchResult {
let origin = ensure_signed(origin)?;

let is_locked = LockedAsset::<T, I>::contains_key(id);
ensure!(!is_locked, Error::<T, I>::NoPermission);

Asset::<T, I>::try_mutate(id, |maybe_details| {
let d = maybe_details.as_mut().ok_or(Error::<T, I>::Unknown)?;
ensure!(&origin == &d.freezer, Error::<T, I>::NoPermission);
Expand Down Expand Up @@ -859,6 +876,9 @@ pub mod pallet {
) -> DispatchResult {
let origin = ensure_signed(origin)?;

let is_locked = LockedAsset::<T, I>::contains_key(id);
ensure!(!is_locked, Error::<T, I>::NoPermission);

Asset::<T, I>::try_mutate(id, |maybe_details| {
let d = maybe_details.as_mut().ok_or(Error::<T, I>::Unknown)?;
ensure!(&origin == &d.admin, Error::<T, I>::NoPermission);
Expand Down Expand Up @@ -887,6 +907,10 @@ pub mod pallet {
owner: <T::Lookup as StaticLookup>::Source,
) -> DispatchResult {
let origin = ensure_signed(origin)?;

let is_locked = LockedAsset::<T, I>::contains_key(id);
ensure!(!is_locked, Error::<T, I>::NoPermission);

let owner = T::Lookup::lookup(owner)?;

Asset::<T, I>::try_mutate(id, |maybe_details| {
Expand Down Expand Up @@ -930,6 +954,10 @@ pub mod pallet {
freezer: <T::Lookup as StaticLookup>::Source,
) -> DispatchResult {
let origin = ensure_signed(origin)?;

let is_locked = LockedAsset::<T, I>::contains_key(id);
ensure!(!is_locked, Error::<T, I>::NoPermission);

let issuer = T::Lookup::lookup(issuer)?;
let admin = T::Lookup::lookup(admin)?;
let freezer = T::Lookup::lookup(freezer)?;
Expand Down Expand Up @@ -1120,6 +1148,9 @@ pub mod pallet {
) -> DispatchResult {
T::ForceOrigin::ensure_origin(origin)?;

let is_locked = LockedAsset::<T, I>::contains_key(id);
ensure!(!is_locked, Error::<T, I>::NoPermission);

Asset::<T, I>::try_mutate(id, |maybe_asset| {
let mut asset = maybe_asset.take().ok_or(Error::<T, I>::Unknown)?;
asset.owner = T::Lookup::lookup(owner)?;
Expand Down Expand Up @@ -1275,4 +1306,64 @@ pub mod pallet {
Self::do_transfer_approved(id, &owner, &delegate, &destination, amount)
}
}

impl<T: Config<I>, I: 'static> Pallet<T, I> {
pub fn lock_asset(who: &T::AccountId, asset: T::AssetId) -> DispatchResult {
let details = Asset::<T, I>::get(asset).ok_or(Error::<T, I>::Unknown)?;
ensure!(details.owner == *who, Error::<T, I>::WrongOwner);
LockedAsset::<T, I>::insert(
asset,
LockedAssetDetails { mint_allowed: false, transfer_allowed: false },
);

Ok(())
}

pub fn lock_asset_transfer(who: &T::AccountId, asset: T::AssetId) -> DispatchResult {
let details = Asset::<T, I>::get(asset).ok_or(Error::<T, I>::Unknown)?;
ensure!(details.owner == *who, Error::<T, I>::WrongOwner);
LockedAsset::<T, I>::mutate(asset, |maybe_details| {
if let Some(details) = maybe_details {
details.transfer_allowed = false;
}
});
Ok(())
}

pub fn is_asset_locked(asset: T::AssetId) -> bool {
LockedAsset::<T, I>::contains_key(asset)
}

pub fn unlock_asset(who: &T::AccountId, asset: T::AssetId) -> DispatchResult {
let details = Asset::<T, I>::get(asset).ok_or(Error::<T, I>::Unknown)?;
ensure!(details.owner == *who, Error::<T, I>::WrongOwner);
LockedAsset::<T, I>::mutate_exists(asset, |details| {
*details = None;
});

Ok(())
}

pub fn unlock_asset_mint(who: &T::AccountId, asset: T::AssetId) -> DispatchResult {
let details = Asset::<T, I>::get(asset).ok_or(Error::<T, I>::Unknown)?;
ensure!(details.owner == *who, Error::<T, I>::WrongOwner);
LockedAsset::<T, I>::mutate(asset, |maybe_details| {
if let Some(details) = maybe_details {
details.mint_allowed = true;
}
});
Ok(())
}

pub fn unlock_asset_transfer(who: &T::AccountId, asset: T::AssetId) -> DispatchResult {
let details = Asset::<T, I>::get(asset).ok_or(Error::<T, I>::Unknown)?;
ensure!(details.owner == *who, Error::<T, I>::WrongOwner);
LockedAsset::<T, I>::mutate(asset, |maybe_details| {
if let Some(details) = maybe_details {
details.transfer_allowed = true;
}
});
Ok(())
}
}
}
6 changes: 6 additions & 0 deletions frame/assets/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,9 @@ where
.saturating_mul_int(balance))
}
}

#[derive(Clone, Encode, Decode, MaxEncodedLen, Eq, PartialEq, TypeInfo)]
pub struct LockedAssetDetails {
pub mint_allowed: bool,
pub transfer_allowed: bool,
}
6 changes: 3 additions & 3 deletions frame/uniques/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ targets = ["x86_64-unknown-linux-gnu"]
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false }
scale-info = { version = "1.0", default-features = false, features = ["derive"] }
sp-std = { version = "4.0.0-dev", default-features = false, path = "../../primitives/std" }
sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../primitives/runtime" }
frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" }
frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" }
sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.13", default-features = false }
frame-support = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.13", default-features = false }
frame-system = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.13", default-features = false }
frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true }

[dev-dependencies]
Expand Down
10 changes: 10 additions & 0 deletions frame/uniques/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
&mut InstanceDetailsFor<T, I>,
) -> DispatchResult,
) -> DispatchResult {
let is_locked = LockedAsset::<T, I>::get(class, instance)
.map_or(false, |details| !details.transfer_allowed);
ensure!(!is_locked, Error::<T, I>::NoPermission);

let class_details = Class::<T, I>::get(&class).ok_or(Error::<T, I>::Unknown)?;
ensure!(!class_details.is_frozen, Error::<T, I>::Frozen);

Expand Down Expand Up @@ -90,6 +94,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
witness: DestroyWitness,
maybe_check_owner: Option<T::AccountId>,
) -> Result<DestroyWitness, DispatchError> {
let is_locked = LockedAsset::<T, I>::iter_key_prefix(class).next().is_some();
ensure!(!is_locked, Error::<T, I>::NoPermission);

Class::<T, I>::try_mutate_exists(class, |maybe_details| {
let class_details = maybe_details.take().ok_or(Error::<T, I>::Unknown)?;
if let Some(check_owner) = maybe_check_owner {
Expand Down Expand Up @@ -160,6 +167,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
instance: T::InstanceId,
with_details: impl FnOnce(&ClassDetailsFor<T, I>, &InstanceDetailsFor<T, I>) -> DispatchResult,
) -> DispatchResult {
let is_locked = LockedAsset::<T, I>::contains_key(class, instance);
ensure!(!is_locked, Error::<T, I>::NoPermission);

let owner = Class::<T, I>::try_mutate(
&class,
|maybe_class_details| -> Result<T::AccountId, DispatchError> {
Expand Down
Loading