diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index e88484e4729584aa1a4b4e61ebc51ee49ae2fb24..92e5dfa7830afbc7d5a5872897646250897250c5 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -979,6 +979,9 @@ impl pallet_lottery::Config for Runtime {
 parameter_types! {
 	pub const AssetDepositBase: Balance = 100 * DOLLARS;
 	pub const AssetDepositPerZombie: Balance = 1 * DOLLARS;
+	pub const StringLimit: u32 = 50;
+	pub const MetadataDepositBase: Balance = 10 * DOLLARS;
+	pub const MetadataDepositPerByte: Balance = 1 * DOLLARS;
 }
 
 impl pallet_assets::Config for Runtime {
@@ -989,6 +992,9 @@ impl pallet_assets::Config for Runtime {
 	type ForceOrigin = EnsureRoot<AccountId>;
 	type AssetDepositBase = AssetDepositBase;
 	type AssetDepositPerZombie = AssetDepositPerZombie;
+	type StringLimit = StringLimit;
+	type MetadataDepositBase = MetadataDepositBase;
+	type MetadataDepositPerByte = MetadataDepositPerByte;
 	type WeightInfo = pallet_assets::weights::SubstrateWeight<Runtime>;
 }
 
diff --git a/substrate/frame/assets/src/benchmarking.rs b/substrate/frame/assets/src/benchmarking.rs
index 63258c2f591b66f4ef535324288c46dba94a8bb5..90b6f65b398907abddee9ee11d843f833ae43441 100644
--- a/substrate/frame/assets/src/benchmarking.rs
+++ b/substrate/frame/assets/src/benchmarking.rs
@@ -18,7 +18,6 @@
 //! Assets pallet benchmarking.
 
 use super::*;
-use sp_std::prelude::*;
 use sp_runtime::traits::Bounded;
 use frame_system::RawOrigin as SystemOrigin;
 use frame_benchmarking::{benchmarks, account, whitelisted_caller};
@@ -154,16 +153,34 @@ benchmarks! {
 
 	thaw {
 		let (caller, caller_lookup) = create_default_minted_asset::<T>(10, 100u32.into());
-		assert!(Assets::<T>::freeze(
+		Assets::<T>::freeze(
 			SystemOrigin::Signed(caller.clone()).into(),
 			Default::default(),
-			caller_lookup.clone()
-		).is_ok());
+			caller_lookup.clone(),
+		)?;
 	}: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup)
 	verify {
 		assert_last_event::<T>(RawEvent::Thawed(Default::default(), caller).into());
 	}
 
+	freeze_asset {
+		let (caller, caller_lookup) = create_default_minted_asset::<T>(10, 100u32.into());
+	}: _(SystemOrigin::Signed(caller.clone()), Default::default())
+	verify {
+		assert_last_event::<T>(RawEvent::AssetFrozen(Default::default()).into());
+	}
+
+	thaw_asset {
+		let (caller, caller_lookup) = create_default_minted_asset::<T>(10, 100u32.into());
+		Assets::<T>::freeze_asset(
+			SystemOrigin::Signed(caller.clone()).into(),
+			Default::default(),
+		)?;
+	}: _(SystemOrigin::Signed(caller.clone()), Default::default())
+	verify {
+		assert_last_event::<T>(RawEvent::AssetThawed(Default::default()).into());
+	}
+
 	transfer_ownership {
 		let (caller, _) = create_default_asset::<T>(10);
 		let target: T::AccountId = account("target", 0, SEED);
@@ -196,6 +213,21 @@ benchmarks! {
 	verify {
 		assert_last_event::<T>(RawEvent::MaxZombiesChanged(Default::default(), max_zombies).into());
 	}
+
+	set_metadata {
+		let n in 0 .. T::StringLimit::get();
+		let s in 0 .. T::StringLimit::get();
+
+		let name = vec![0u8; n as usize];
+		let symbol = vec![0u8; s as usize];
+		let decimals = 12;
+
+		let (caller, _) = create_default_asset::<T>(10);
+		T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
+	}: _(SystemOrigin::Signed(caller), Default::default(), name.clone(), symbol.clone(), decimals)
+	verify {
+		assert_last_event::<T>(RawEvent::MetadataSet(Default::default(), name, symbol, decimals).into());
+	}
 }
 
 #[cfg(test)]
@@ -273,6 +305,20 @@ mod tests {
 		});
 	}
 
+	#[test]
+	fn freeze_asset() {
+		new_test_ext().execute_with(|| {
+			assert!(test_benchmark_freeze_asset::<Test>().is_ok());
+		});
+	}
+
+	#[test]
+	fn thaw_asset() {
+		new_test_ext().execute_with(|| {
+			assert!(test_benchmark_thaw_asset::<Test>().is_ok());
+		});
+	}
+
 	#[test]
 	fn transfer_ownership() {
 		new_test_ext().execute_with(|| {
@@ -293,4 +339,11 @@ mod tests {
 			assert!(test_benchmark_set_max_zombies::<Test>().is_ok());
 		});
 	}
+
+	#[test]
+	fn set_metadata() {
+		new_test_ext().execute_with(|| {
+			assert!(test_benchmark_set_metadata::<Test>().is_ok());
+		});
+	}
 }
diff --git a/substrate/frame/assets/src/lib.rs b/substrate/frame/assets/src/lib.rs
index dcb77cc6ebfd2dea62f9d7117be1418ef725a281..8f1ad02c08bbf7f6caab4d16f3769eea81541ba8 100644
--- a/substrate/frame/assets/src/lib.rs
+++ b/substrate/frame/assets/src/lib.rs
@@ -113,7 +113,7 @@
 mod benchmarking;
 pub mod weights;
 
-use sp_std::{fmt::Debug};
+use sp_std::{fmt::Debug, prelude::*};
 use sp_runtime::{RuntimeDebug, traits::{
 	Member, AtLeast32BitUnsigned, Zero, StaticLookup, Saturating, CheckedSub, CheckedAdd
 }};
@@ -151,6 +151,16 @@ pub trait Config: frame_system::Config {
 	/// supports.
 	type AssetDepositPerZombie: Get<BalanceOf<Self>>;
 
+	/// The maximum length of a name or symbol stored on-chain.
+	type StringLimit: Get<u32>;
+
+	/// The basic amount of funds that must be reserved when adding metadata to your asset.
+	type MetadataDepositBase: Get<BalanceOf<Self>>;
+
+	/// The additional funds that must be reserved for the number of bytes you store in your
+	/// metadata.
+	type MetadataDepositPerByte: Get<BalanceOf<Self>>;
+
 	/// Weight information for extrinsics in this pallet.
 	type WeightInfo: WeightInfo;
 }
@@ -184,6 +194,8 @@ pub struct AssetDetails<
 	zombies: u32,
 	/// The total number of accounts.
 	accounts: u32,
+	/// Whether the asset is frozen for permissionless transfers.
+	is_frozen: bool,
 }
 
 #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default)]
@@ -198,6 +210,20 @@ pub struct AssetBalance<
 	is_zombie: bool,
 }
 
+#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default)]
+pub struct AssetMetadata<DepositBalance> {
+	/// The balance deposited for this metadata.
+	///
+	/// This pays for the data stored in this struct.
+	deposit: DepositBalance,
+	/// The user friendly name of this asset. Limited in length by `StringLimit`.
+	name: Vec<u8>,
+	/// The ticker symbol for this asset. Limited in length by `StringLimit`.
+	symbol: Vec<u8>,
+	/// The number of decimals this asset uses to represent one unit.
+	decimals: u8,
+}
+
 decl_storage! {
 	trait Store for Module<T: Config> as Assets {
 		/// Details of an asset.
@@ -212,6 +238,9 @@ decl_storage! {
 			hasher(blake2_128_concat) T::AssetId,
 			hasher(blake2_128_concat) T::AccountId
 			=> AssetBalance<T::Balance>;
+
+		/// Metadata of an asset.
+		Metadata: map hasher(blake2_128_concat) T::AssetId => AssetMetadata<BalanceOf<T>>;
 	}
 }
 
@@ -239,12 +268,18 @@ decl_event! {
 		Frozen(AssetId, AccountId),
 		/// Some account `who` was thawed. \[asset_id, who\]
 		Thawed(AssetId, AccountId),
+		/// Some asset `asset_id` was frozen. \[asset_id\]
+		AssetFrozen(AssetId),
+		/// Some asset `asset_id` was thawed. \[asset_id\]
+		AssetThawed(AssetId),
 		/// An asset class was destroyed.
 		Destroyed(AssetId),
 		/// Some asset class was force-created. \[asset_id, owner\]
 		ForceCreated(AssetId, AccountId),
 		/// The maximum amount of zombies allowed has changed. \[asset_id, max_zombies\]
 		MaxZombiesChanged(AssetId, u32),
+		/// New metadata has been set for an asset. \[asset_id, name, symbol, decimals\]
+		MetadataSet(AssetId, Vec<u8>, Vec<u8>, u8),
 	}
 }
 
@@ -276,6 +311,8 @@ decl_error! {
 		Overflow,
 		/// Some internal state is broken.
 		BadState,
+		/// Invalid metadata given.
+		BadMetadata,
 	}
 }
 
@@ -337,6 +374,7 @@ decl_module! {
 				min_balance,
 				zombies: Zero::zero(),
 				accounts: Zero::zero(),
+				is_frozen: false,
 			});
 			Self::deposit_event(RawEvent::Created(id, owner, admin));
 		}
@@ -386,6 +424,7 @@ decl_module! {
 				min_balance,
 				zombies: Zero::zero(),
 				accounts: Zero::zero(),
+				is_frozen: false,
 			});
 			Self::deposit_event(RawEvent::ForceCreated(id, owner));
 		}
@@ -412,7 +451,9 @@ decl_module! {
 				ensure!(details.owner == origin, Error::<T>::NoPermission);
 				ensure!(details.accounts == details.zombies, Error::<T>::RefsLeft);
 				ensure!(details.zombies <= zombies_witness, Error::<T>::BadWitness);
-				T::Currency::unreserve(&details.owner, details.deposit);
+
+				let metadata = Metadata::<T>::take(&id);
+				T::Currency::unreserve(&details.owner, details.deposit.saturating_add(metadata.deposit));
 
 				*maybe_details = None;
 				Account::<T>::remove_prefix(&id);
@@ -442,7 +483,9 @@ decl_module! {
 				let details = maybe_details.take().ok_or(Error::<T>::Unknown)?;
 				ensure!(details.accounts == details.zombies, Error::<T>::RefsLeft);
 				ensure!(details.zombies <= zombies_witness, Error::<T>::BadWitness);
-				T::Currency::unreserve(&details.owner, details.deposit);
+
+				let metadata = Metadata::<T>::take(&id);
+				T::Currency::unreserve(&details.owner, details.deposit.saturating_add(metadata.deposit));
 
 				*maybe_details = None;
 				Account::<T>::remove_prefix(&id);
@@ -580,6 +623,7 @@ decl_module! {
 			let dest = T::Lookup::lookup(target)?;
 			Asset::<T>::try_mutate(id, |maybe_details| {
 				let details = maybe_details.as_mut().ok_or(Error::<T>::Unknown)?;
+				ensure!(!details.is_frozen, Error::<T>::Frozen);
 
 				if dest == origin {
 					return Ok(())
@@ -739,6 +783,54 @@ decl_module! {
 			Self::deposit_event(Event::<T>::Thawed(id, who));
 		}
 
+		/// Disallow further unprivileged transfers for the asset class.
+		///
+		/// Origin must be Signed and the sender should be the Freezer of the asset `id`.
+		///
+		/// - `id`: The identifier of the asset to be frozen.
+		///
+		/// Emits `Frozen`.
+		///
+		/// Weight: `O(1)`
+		#[weight = T::WeightInfo::freeze_asset()]
+		fn freeze_asset(origin, #[compact] id: T::AssetId) -> DispatchResult {
+			let origin = ensure_signed(origin)?;
+
+			Asset::<T>::try_mutate(id, |maybe_details| {
+				let d = maybe_details.as_mut().ok_or(Error::<T>::Unknown)?;
+				ensure!(&origin == &d.freezer, Error::<T>::NoPermission);
+
+				d.is_frozen = true;
+
+				Self::deposit_event(Event::<T>::AssetFrozen(id));
+				Ok(())
+			})
+		}
+
+		/// Allow unprivileged transfers for the asset again.
+		///
+		/// Origin must be Signed and the sender should be the Admin of the asset `id`.
+		///
+		/// - `id`: The identifier of the asset to be frozen.
+		///
+		/// Emits `Thawed`.
+		///
+		/// Weight: `O(1)`
+		#[weight = T::WeightInfo::thaw_asset()]
+		fn thaw_asset(origin, #[compact] id: T::AssetId) -> DispatchResult {
+			let origin = ensure_signed(origin)?;
+
+			Asset::<T>::try_mutate(id, |maybe_details| {
+				let d = maybe_details.as_mut().ok_or(Error::<T>::Unknown)?;
+				ensure!(&origin == &d.admin, Error::<T>::NoPermission);
+
+				d.is_frozen = false;
+
+				Self::deposit_event(Event::<T>::AssetThawed(id));
+				Ok(())
+			})
+		}
+
 		/// Change the Owner of an asset.
 		///
 		/// Origin must be Signed and the sender should be the Owner of the asset `id`.
@@ -809,6 +901,20 @@ decl_module! {
 			})
 		}
 
+		/// Set the maximum number of zombie accounts for an asset.
+		///
+		/// Origin must be Signed and the sender should be the Owner of the asset `id`.
+		///
+		/// Funds of sender are reserved according to the formula:
+		/// `AssetDepositBase + AssetDepositPerZombie * max_zombies` taking into account
+		/// any already reserved funds.
+		///
+		/// - `id`: The identifier of the asset to update zombie count.
+		/// - `max_zombies`: The new number of zombies allowed for this asset.
+		///
+		/// Emits `MaxZombiesChanged`.
+		///
+		/// Weight: `O(1)`
 		#[weight = T::WeightInfo::set_max_zombies()]
 		fn set_max_zombies(origin,
 			#[compact] id: T::AssetId,
@@ -837,6 +943,76 @@ decl_module! {
 				Ok(())
 			})
 		}
+
+		/// Set the metadata for an asset.
+		///
+		/// NOTE: There is no `unset_metadata` call. Simply pass an empty name, symbol,
+		/// and 0 decimals to this function to remove the metadata of an asset and
+		/// return your deposit.
+		///
+		/// Origin must be Signed and the sender should be the Owner of the asset `id`.
+		///
+		/// Funds of sender are reserved according to the formula:
+		/// `MetadataDepositBase + MetadataDepositPerByte * (name.len + symbol.len)` taking into
+		/// account any already reserved funds.
+		///
+		/// - `id`: The identifier of the asset to update.
+		/// - `name`: The user friendly name of this asset. Limited in length by `StringLimit`.
+		/// - `symbol`: The exchange symbol for this asset. Limited in length by `StringLimit`.
+		/// - `decimals`: The number of decimals this asset uses to represent one unit.
+		///
+		/// Emits `MaxZombiesChanged`.
+		///
+		/// Weight: `O(1)`
+		#[weight = T::WeightInfo::set_metadata(name.len() as u32, symbol.len() as u32)]
+		fn set_metadata(origin,
+			#[compact] id: T::AssetId,
+			name: Vec<u8>,
+			symbol: Vec<u8>,
+			decimals: u8,
+		) -> DispatchResult {
+			let origin = ensure_signed(origin)?;
+
+			ensure!(name.len() <= T::StringLimit::get() as usize, Error::<T>::BadMetadata);
+			ensure!(symbol.len() <= T::StringLimit::get() as usize, Error::<T>::BadMetadata);
+
+			let d = Asset::<T>::get(id).ok_or(Error::<T>::Unknown)?;
+			ensure!(&origin == &d.owner, Error::<T>::NoPermission);
+
+			Metadata::<T>::try_mutate_exists(id, |metadata| {
+				let bytes_used = name.len() + symbol.len();
+				let old_deposit = match metadata {
+					Some(m) => m.deposit,
+					None => Default::default()
+				};
+
+				// Metadata is being removed
+				if bytes_used.is_zero() && decimals.is_zero() {
+					T::Currency::unreserve(&origin, old_deposit);
+					*metadata = None;
+				} else {
+					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: name.clone(),
+						symbol: symbol.clone(),
+						decimals,
+					})
+				}
+
+				Self::deposit_event(RawEvent::MetadataSet(id, name, symbol, decimals));
+				Ok(())
+			})
+		}
 	}
 }
 
@@ -912,6 +1088,7 @@ mod tests {
 	use frame_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types, impl_outer_event};
 	use sp_core::H256;
 	use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::Header};
+	use pallet_balances::Error as BalancesError;
 
 	mod pallet_assets {
 		pub use crate::Event;
@@ -976,6 +1153,9 @@ mod tests {
 	parameter_types! {
 		pub const AssetDepositBase: u64 = 1;
 		pub const AssetDepositPerZombie: u64 = 1;
+		pub const StringLimit: u32 = 50;
+		pub const MetadataDepositBase: u64 = 1;
+		pub const MetadataDepositPerByte: u64 = 1;
 	}
 
 	impl Config for Test {
@@ -986,6 +1166,9 @@ mod tests {
 		type ForceOrigin = frame_system::EnsureRoot<u64>;
 		type AssetDepositBase = AssetDepositBase;
 		type AssetDepositPerZombie = AssetDepositPerZombie;
+		type StringLimit = StringLimit;
+		type MetadataDepositBase = MetadataDepositBase;
+		type MetadataDepositPerByte = MetadataDepositPerByte;
 		type WeightInfo = ();
 	}
 	type System = frame_system::Module<Test>;
@@ -1013,15 +1196,41 @@ mod tests {
 			Balances::make_free_balance_be(&1, 100);
 			assert_ok!(Assets::create(Origin::signed(1), 0, 1, 10, 1));
 			assert_eq!(Balances::reserved_balance(&1), 11);
+			assert!(Asset::<Test>::contains_key(0));
+
+			assert_ok!(Assets::set_metadata(Origin::signed(1), 0, vec![0], vec![0], 12));
+			assert_eq!(Balances::reserved_balance(&1), 14);
+			assert!(Metadata::<Test>::contains_key(0));
+
+			assert_ok!(Assets::mint(Origin::signed(1), 0, 10, 100));
+			assert_ok!(Assets::mint(Origin::signed(1), 0, 20, 100));
+			assert_eq!(Account::<Test>::iter_prefix(0).count(), 2);
 
 			assert_ok!(Assets::destroy(Origin::signed(1), 0, 100));
 			assert_eq!(Balances::reserved_balance(&1), 0);
 
+			assert!(!Asset::<Test>::contains_key(0));
+			assert!(!Metadata::<Test>::contains_key(0));
+			assert_eq!(Account::<Test>::iter_prefix(0).count(), 0);
+
 			assert_ok!(Assets::create(Origin::signed(1), 0, 1, 10, 1));
 			assert_eq!(Balances::reserved_balance(&1), 11);
+			assert!(Asset::<Test>::contains_key(0));
+
+			assert_ok!(Assets::set_metadata(Origin::signed(1), 0, vec![0], vec![0], 12));
+			assert_eq!(Balances::reserved_balance(&1), 14);
+			assert!(Metadata::<Test>::contains_key(0));
+
+			assert_ok!(Assets::mint(Origin::signed(1), 0, 10, 100));
+			assert_ok!(Assets::mint(Origin::signed(1), 0, 20, 100));
+			assert_eq!(Account::<Test>::iter_prefix(0).count(), 2);
 
 			assert_ok!(Assets::force_destroy(Origin::root(), 0, 100));
 			assert_eq!(Balances::reserved_balance(&1), 0);
+
+			assert!(!Asset::<Test>::contains_key(0));
+			assert!(!Metadata::<Test>::contains_key(0));
+			assert_eq!(Account::<Test>::iter_prefix(0).count(), 0);
 		});
 	}
 
@@ -1172,7 +1381,7 @@ mod tests {
 	}
 
 	#[test]
-	fn transferring_frozen_balance_should_not_work() {
+	fn transferring_frozen_user_should_not_work() {
 		new_test_ext().execute_with(|| {
 			assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1));
 			assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100));
@@ -1184,6 +1393,19 @@ mod tests {
 		});
 	}
 
+	#[test]
+	fn transferring_frozen_asset_should_not_work() {
+		new_test_ext().execute_with(|| {
+			assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1));
+			assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100));
+			assert_eq!(Assets::balance(0, 1), 100);
+			assert_ok!(Assets::freeze_asset(Origin::signed(1), 0));
+			assert_noop!(Assets::transfer(Origin::signed(1), 0, 2, 50), Error::<Test>::Frozen);
+			assert_ok!(Assets::thaw_asset(Origin::signed(1), 0));
+			assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 50));
+		});
+	}
+
 	#[test]
 	fn origin_guards_should_work() {
 		new_test_ext().execute_with(|| {
@@ -1306,4 +1528,53 @@ mod tests {
 			assert_noop!(Assets::burn(Origin::signed(1), 0, 2, u64::max_value()), Error::<Test>::BalanceZero);
 		});
 	}
+
+	#[test]
+	fn set_metadata_should_work() {
+		new_test_ext().execute_with(|| {
+			// Cannot add metadata to unknown asset
+			assert_noop!(
+				Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 10], vec![0u8; 10], 12),
+				Error::<Test>::Unknown,
+			);
+			assert_ok!(Assets::force_create(Origin::root(), 0, 1, 10, 1));
+			// Cannot add metadata to unowned asset
+			assert_noop!(
+				Assets::set_metadata(Origin::signed(2), 0, vec![0u8; 10], vec![0u8; 10], 12),
+				Error::<Test>::NoPermission,
+			);
+
+			// Cannot add oversized metadata
+			assert_noop!(
+				Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 100], vec![0u8; 10], 12),
+				Error::<Test>::BadMetadata,
+			);
+			assert_noop!(
+				Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 10], vec![0u8; 100], 12),
+				Error::<Test>::BadMetadata,
+			);
+
+			// Successfully add metadata and take deposit
+			Balances::make_free_balance_be(&1, 30);
+			assert_ok!(Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 10], vec![0u8; 10], 12));
+			assert_eq!(Balances::free_balance(&1), 9);
+
+			// Update deposit
+			assert_ok!(Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 10], vec![0u8; 5], 12));
+			assert_eq!(Balances::free_balance(&1), 14);
+			assert_ok!(Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 10], vec![0u8; 15], 12));
+			assert_eq!(Balances::free_balance(&1), 4);
+
+			// Cannot over-reserve
+			assert_noop!(
+				Assets::set_metadata(Origin::signed(1), 0, vec![0u8; 20], vec![0u8; 20], 12),
+				BalancesError::<Test, _>::InsufficientBalance,
+			);
+
+			// Clear Metadata
+			assert!(Metadata::<Test>::contains_key(0));
+			assert_ok!(Assets::set_metadata(Origin::signed(1), 0, vec![], vec![], 0));
+			assert!(!Metadata::<Test>::contains_key(0));
+		});
+	}
 }
diff --git a/substrate/frame/assets/src/weights.rs b/substrate/frame/assets/src/weights.rs
index a8e17615d282d234d6c21ddaffcadf293ae5559a..1858fe708e14c66632d36b83be0560a48b7ef865 100644
--- a/substrate/frame/assets/src/weights.rs
+++ b/substrate/frame/assets/src/weights.rs
@@ -1,6 +1,6 @@
 // This file is part of Substrate.
 
-// Copyright (C) 2020-2021 Parity Technologies (UK) Ltd.
+// Copyright (C) 2021 Parity Technologies (UK) Ltd.
 // SPDX-License-Identifier: Apache-2.0
 
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,8 +17,8 @@
 
 //! Autogenerated weights for pallet_assets
 //!
-//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0
-//! DATE: 2020-12-03, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: []
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.1
+//! DATE: 2021-01-18, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: []
 //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128
 
 // Executed Command:
@@ -54,154 +54,199 @@ pub trait WeightInfo {
 	fn force_transfer() -> Weight;
 	fn freeze() -> Weight;
 	fn thaw() -> Weight;
+	fn freeze_asset() -> Weight;
+	fn thaw_asset() -> Weight;
 	fn transfer_ownership() -> Weight;
 	fn set_team() -> Weight;
 	fn set_max_zombies() -> Weight;
+	fn set_metadata(n: u32, s: u32, ) -> Weight;
 }
 
 /// Weights for pallet_assets using the Substrate node and recommended hardware.
 pub struct SubstrateWeight<T>(PhantomData<T>);
 impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
 	fn create() -> Weight {
-		(58_077_000 as Weight)
+		(44_459_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(1 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
 	fn force_create() -> Weight {
-		(30_497_000 as Weight)
+		(21_480_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(1 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
 	fn destroy(z: u32, ) -> Weight {
 		(0 as Weight)
-			.saturating_add((1_153_000 as Weight).saturating_mul(z as Weight))
-			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			// Standard Error: 2_000
+			.saturating_add((1_149_000 as Weight).saturating_mul(z as Weight))
+			.saturating_add(T::DbWeight::get().reads(2 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 			.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(z as Weight)))
 	}
 	fn force_destroy(z: u32, ) -> Weight {
 		(0 as Weight)
-			.saturating_add((1_153_000 as Weight).saturating_mul(z as Weight))
-			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			// Standard Error: 2_000
+			.saturating_add((1_146_000 as Weight).saturating_mul(z as Weight))
+			.saturating_add(T::DbWeight::get().reads(2 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 			.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(z as Weight)))
 	}
 	fn mint() -> Weight {
-		(45_600_000 as Weight)
+		(32_995_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(2 as Weight))
 			.saturating_add(T::DbWeight::get().writes(2 as Weight))
 	}
 	fn burn() -> Weight {
-		(40_143_000 as Weight)
+		(29_245_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(2 as Weight))
 			.saturating_add(T::DbWeight::get().writes(2 as Weight))
 	}
 	fn transfer() -> Weight {
-		(58_903_000 as Weight)
+		(42_211_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(4 as Weight))
 			.saturating_add(T::DbWeight::get().writes(3 as Weight))
 	}
 	fn force_transfer() -> Weight {
-		(59_025_000 as Weight)
+		(42_218_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(4 as Weight))
 			.saturating_add(T::DbWeight::get().writes(3 as Weight))
 	}
 	fn freeze() -> Weight {
-		(43_308_000 as Weight)
+		(31_079_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(2 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
 	fn thaw() -> Weight {
-		(43_383_000 as Weight)
+		(30_853_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(2 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
+	fn freeze_asset() -> Weight {
+		(22_383_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
+	fn thaw_asset() -> Weight {
+		(22_341_000 as Weight)
+			.saturating_add(T::DbWeight::get().reads(1 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
 	fn transfer_ownership() -> Weight {
-		(31_380_000 as Weight)
+		(22_782_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(1 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
 	fn set_team() -> Weight {
-		(32_049_000 as Weight)
+		(23_293_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(1 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
 	fn set_max_zombies() -> Weight {
-		(57_745_000 as Weight)
+		(44_525_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(1 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
+	fn set_metadata(n: u32, s: u32, ) -> Weight {
+		(49_456_000 as Weight)
+			// Standard Error: 0
+			.saturating_add((1_000 as Weight).saturating_mul(n as Weight))
+			// Standard Error: 0
+			.saturating_add((6_000 as Weight).saturating_mul(s as Weight))
+			.saturating_add(T::DbWeight::get().reads(2 as Weight))
+			.saturating_add(T::DbWeight::get().writes(1 as Weight))
+	}
 }
 
 // For backwards compatibility and tests
 impl WeightInfo for () {
 	fn create() -> Weight {
-		(58_077_000 as Weight)
+		(44_459_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
 	fn force_create() -> Weight {
-		(30_497_000 as Weight)
+		(21_480_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
 	fn destroy(z: u32, ) -> Weight {
 		(0 as Weight)
-			.saturating_add((1_153_000 as Weight).saturating_mul(z as Weight))
-			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			// Standard Error: 2_000
+			.saturating_add((1_149_000 as Weight).saturating_mul(z as Weight))
+			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 			.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(z as Weight)))
 	}
 	fn force_destroy(z: u32, ) -> Weight {
 		(0 as Weight)
-			.saturating_add((1_153_000 as Weight).saturating_mul(z as Weight))
-			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			// Standard Error: 2_000
+			.saturating_add((1_146_000 as Weight).saturating_mul(z as Weight))
+			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 			.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(z as Weight)))
 	}
 	fn mint() -> Weight {
-		(45_600_000 as Weight)
+		(32_995_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(2 as Weight))
 	}
 	fn burn() -> Weight {
-		(40_143_000 as Weight)
+		(29_245_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(2 as Weight))
 	}
 	fn transfer() -> Weight {
-		(58_903_000 as Weight)
+		(42_211_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(4 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(3 as Weight))
 	}
 	fn force_transfer() -> Weight {
-		(59_025_000 as Weight)
+		(42_218_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(4 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(3 as Weight))
 	}
 	fn freeze() -> Weight {
-		(43_308_000 as Weight)
+		(31_079_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
 	fn thaw() -> Weight {
-		(43_383_000 as Weight)
+		(30_853_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
+	fn freeze_asset() -> Weight {
+		(22_383_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
+	fn thaw_asset() -> Weight {
+		(22_341_000 as Weight)
+			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
 	fn transfer_ownership() -> Weight {
-		(31_380_000 as Weight)
+		(22_782_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
 	fn set_team() -> Weight {
-		(32_049_000 as Weight)
+		(23_293_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
 	fn set_max_zombies() -> Weight {
-		(57_745_000 as Weight)
+		(44_525_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
+	fn set_metadata(n: u32, s: u32, ) -> Weight {
+		(49_456_000 as Weight)
+			// Standard Error: 0
+			.saturating_add((1_000 as Weight).saturating_mul(n as Weight))
+			// Standard Error: 0
+			.saturating_add((6_000 as Weight).saturating_mul(s as Weight))
+			.saturating_add(RocksDbWeight::get().reads(2 as Weight))
+			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
+	}
 }