git.delta.rocks / unique-network / refs/commits / bea0737bb7ad

difftreelog

feat add nesting

Trubnikov Sergey2023-05-05parent: #3293186.patch.diff
in: master

5 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6264,9 +6264,11 @@
  "pallet-evm",
  "pallet-evm-coder-substrate",
  "pallet-evm-transaction-payment",
+ "pallet-structure",
  "parity-scale-codec",
  "scale-info",
  "sp-core",
+ "sp-runtime",
  "sp-std",
  "up-data-structs",
 ]
modifiedpallets/balances-adapter/Cargo.tomldiffbeforeafterboth
--- a/pallets/balances-adapter/Cargo.toml
+++ b/pallets/balances-adapter/Cargo.toml
@@ -9,7 +9,9 @@
 frame-support = { workspace = true }
 frame-system = { workspace = true }
 pallet-balances = { workspace = true }
+pallet-structure = { workspace = true }
 sp-core = { workspace = true }
+sp-runtime = { workspace = true }
 sp-std = { workspace = true }
 
 #Parity
modifiedpallets/balances-adapter/src/common.rsdiffbeforeafterboth
before · pallets/balances-adapter/src/common.rs
1use alloc::{vec, vec::Vec};2use core::marker::PhantomData;3use crate::{Config, NativeFungibleHandle};4use frame_support::{5	fail,6	traits::{Currency, ExistenceRequirement},7	weights::Weight,8};9use pallet_balances::{weights::SubstrateWeight as BalancesWeight, WeightInfo};10use pallet_common::{erc::CrossAccountId, CommonCollectionOperations, CommonWeightInfo, with_weight};11use up_data_structs::TokenId;1213pub struct CommonWeights<T: Config>(PhantomData<T>);14impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {15	fn create_multiple_items(_amount: &[up_data_structs::CreateItemData]) -> Weight {16		Weight::default()17	}1819	fn create_multiple_items_ex(20		_cost: &up_data_structs::CreateItemExData<T::CrossAccountId>,21	) -> Weight {22		Weight::default()23	}2425	fn burn_item() -> Weight {26		Weight::default()27	}2829	fn set_collection_properties(_amount: u32) -> Weight {30		Weight::default()31	}3233	fn delete_collection_properties(_amount: u32) -> Weight {34		Weight::default()35	}3637	fn set_token_properties(_amount: u32) -> Weight {38		Weight::default()39	}4041	fn delete_token_properties(_amount: u32) -> Weight {42		Weight::default()43	}4445	fn set_token_property_permissions(_amount: u32) -> Weight {46		Weight::default()47	}4849	fn transfer() -> Weight {50		<BalancesWeight<T> as WeightInfo>::transfer()51	}5253	fn approve() -> Weight {54		Weight::default()55	}5657	fn approve_from() -> Weight {58		Weight::default()59	}6061	fn transfer_from() -> Weight {62		<BalancesWeight<T> as WeightInfo>::transfer()63	}6465	fn burn_from() -> Weight {66		Weight::default()67	}6869	fn burn_recursively_self_raw() -> Weight {70		Weight::default()71	}7273	fn burn_recursively_breadth_raw(_amount: u32) -> Weight {74		Weight::default()75	}7677	fn token_owner() -> Weight {78		Weight::default()79	}8081	fn set_allowance_for_all() -> Weight {82		Weight::default()83	}8485	fn force_repair_item() -> Weight {86		Weight::default()87	}88}8990/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallete91/// methods and adds weight info.92impl<T: Config> CommonCollectionOperations<T> for NativeFungibleHandle<T> {93	fn create_item(94		&self,95		_sender: <T>::CrossAccountId,96		_to: <T>::CrossAccountId,97		_data: up_data_structs::CreateItemData,98		_nesting_budget: &dyn up_data_structs::budget::Budget,99	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {100		fail!(<pallet_common::Error<T>>::UnsupportedOperation);101	}102103	fn create_multiple_items(104		&self,105		_sender: <T>::CrossAccountId,106		_to: <T>::CrossAccountId,107		_data: Vec<up_data_structs::CreateItemData>,108		_nesting_budget: &dyn up_data_structs::budget::Budget,109	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {110		fail!(<pallet_common::Error<T>>::UnsupportedOperation);111	}112113	fn create_multiple_items_ex(114		&self,115		_sender: <T>::CrossAccountId,116		_data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,117		_nesting_budget: &dyn up_data_structs::budget::Budget,118	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {119		fail!(<pallet_common::Error<T>>::UnsupportedOperation);120	}121122	fn burn_item(123		&self,124		_sender: <T>::CrossAccountId,125		_token: TokenId,126		_amount: u128,127	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {128		fail!(<pallet_common::Error<T>>::UnsupportedOperation);129	}130131	fn burn_item_recursively(132		&self,133		_sender: <T>::CrossAccountId,134		_token: TokenId,135		_self_budget: &dyn up_data_structs::budget::Budget,136		_breadth_budget: &dyn up_data_structs::budget::Budget,137	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {138		fail!(<pallet_common::Error<T>>::UnsupportedOperation);139	}140141	fn set_collection_properties(142		&self,143		_sender: <T>::CrossAccountId,144		_properties: Vec<up_data_structs::Property>,145	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {146		fail!(<pallet_common::Error<T>>::UnsupportedOperation);147	}148149	fn delete_collection_properties(150		&self,151		_sender: &<T>::CrossAccountId,152		_property_keys: Vec<up_data_structs::PropertyKey>,153	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {154		fail!(<pallet_common::Error<T>>::UnsupportedOperation);155	}156157	fn set_token_properties(158		&self,159		_sender: <T>::CrossAccountId,160		_token_id: TokenId,161		_properties: Vec<up_data_structs::Property>,162		_budget: &dyn up_data_structs::budget::Budget,163	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {164		fail!(<pallet_common::Error<T>>::UnsupportedOperation);165	}166167	fn delete_token_properties(168		&self,169		_sender: <T>::CrossAccountId,170		_token_id: TokenId,171		_property_keys: Vec<up_data_structs::PropertyKey>,172		_budget: &dyn up_data_structs::budget::Budget,173	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {174		fail!(<pallet_common::Error<T>>::UnsupportedOperation);175	}176177	fn set_token_property_permissions(178		&self,179		_sender: &<T>::CrossAccountId,180		_property_permissions: Vec<up_data_structs::PropertyKeyPermission>,181	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {182		fail!(<pallet_common::Error<T>>::UnsupportedOperation);183	}184185	fn transfer(186		&self,187		sender: <T>::CrossAccountId,188		to: <T>::CrossAccountId,189		_token: TokenId,190		amount: u128,191		_budget: &dyn up_data_structs::budget::Budget,192	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {193		with_weight(194			<T as Config>::Currency::transfer(195				sender.as_sub(),196				to.as_sub(),197				amount.into(),198				ExistenceRequirement::KeepAlive,199			),200			Default::default(),201		)202	}203204	fn approve(205		&self,206		_sender: <T>::CrossAccountId,207		_spender: <T>::CrossAccountId,208		_token: TokenId,209		_amount: u128,210	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {211		fail!(<pallet_common::Error<T>>::UnsupportedOperation);212	}213214	fn approve_from(215		&self,216		_sender: <T>::CrossAccountId,217		_from: <T>::CrossAccountId,218		_to: <T>::CrossAccountId,219		_token: TokenId,220		_amount: u128,221	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {222		fail!(<pallet_common::Error<T>>::UnsupportedOperation);223	}224225	fn transfer_from(226		&self,227		sender: <T>::CrossAccountId,228		from: <T>::CrossAccountId,229		to: <T>::CrossAccountId,230		_token: TokenId,231		amount: u128,232		_budget: &dyn up_data_structs::budget::Budget,233	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {234		if sender != from {235			fail!(<pallet_common::Error<T>>::NoPermission);236		}237		with_weight(238			<T as Config>::Currency::transfer(239				from.as_sub(),240				to.as_sub(),241				amount.into(),242				ExistenceRequirement::KeepAlive,243			),244			Default::default(),245		)246	}247248	fn burn_from(249		&self,250		_sender: <T>::CrossAccountId,251		_from: <T>::CrossAccountId,252		_token: TokenId,253		_amount: u128,254		_budget: &dyn up_data_structs::budget::Budget,255	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {256		fail!(<pallet_common::Error<T>>::UnsupportedOperation);257	}258259	fn check_nesting(260		&self,261		_sender: <T>::CrossAccountId,262		_from: (up_data_structs::CollectionId, TokenId),263		_under: TokenId,264		_budget: &dyn up_data_structs::budget::Budget,265	) -> frame_support::sp_runtime::DispatchResult {266		fail!(<pallet_common::Error<T>>::UnsupportedOperation);267	}268269	fn nest(&self, _under: TokenId, _to_nest: (up_data_structs::CollectionId, TokenId)) {}270271	fn unnest(&self, _under: TokenId, _to_nest: (up_data_structs::CollectionId, TokenId)) {}272273	fn account_tokens(&self, account: <T>::CrossAccountId) -> Vec<TokenId> {274		let balance = <T as Config>::Currency::total_balance(account.as_sub());275		if balance != 0 {276			vec![TokenId::default()]277		} else {278			vec![]279		}280	}281282	fn collection_tokens(&self) -> Vec<TokenId> {283		vec![TokenId::default()]284	}285286	fn token_exists(&self, token: TokenId) -> bool {287		token == TokenId::default()288	}289290	fn last_token_id(&self) -> TokenId {291		TokenId::default()292	}293294	fn token_owner(295		&self,296		_token: TokenId,297	) -> Result<<T>::CrossAccountId, up_data_structs::TokenOwnerError> {298		Err(up_data_structs::TokenOwnerError::MultipleOwners)299	}300301	fn token_owners(&self, _token: TokenId) -> Vec<<T>::CrossAccountId> {302		vec![]303	}304305	fn token_property(306		&self,307		_token_id: TokenId,308		_key: &up_data_structs::PropertyKey,309	) -> Option<up_data_structs::PropertyValue> {310		None311	}312313	fn token_properties(314		&self,315		_token: TokenId,316		_keys: Option<Vec<up_data_structs::PropertyKey>>,317	) -> Vec<up_data_structs::Property> {318		vec![]319	}320321	fn total_supply(&self) -> u32 {322		1323	}324325	fn account_balance(&self, account: <T>::CrossAccountId) -> u32 {326		let balance: u128 = <T as Config>::Currency::free_balance(account.as_sub()).into();327		(balance != 0).into()328	}329330	fn balance(&self, account: <T>::CrossAccountId, token: TokenId) -> u128 {331		if token != TokenId::default() {332			return 0;333		}334		<T as Config>::Currency::free_balance(account.as_sub()).into()335	}336337	fn total_pieces(&self, token: TokenId) -> Option<u128> {338		if token != TokenId::default() {339			return None;340		}341		let total = <T as Config>::Currency::total_issuance();342		Some(total.into())343	}344345	fn allowance(346		&self,347		_sender: <T>::CrossAccountId,348		_spender: <T>::CrossAccountId,349		_token: TokenId,350	) -> u128 {351		0352	}353354	fn refungible_extensions(&self) -> Option<&dyn pallet_common::RefungibleExtensions<T>> {355		None356	}357358	fn set_allowance_for_all(359		&self,360		_owner: <T>::CrossAccountId,361		_operator: <T>::CrossAccountId,362		_approve: bool,363	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {364		fail!(<pallet_common::Error<T>>::UnsupportedOperation);365	}366367	fn allowance_for_all(368		&self,369		_owner: <T>::CrossAccountId,370		_operator: <T>::CrossAccountId,371	) -> bool {372		false373	}374375	fn repair_item(376		&self,377		_token: TokenId,378	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {379		fail!(<pallet_common::Error<T>>::UnsupportedOperation);380	}381}
after · pallets/balances-adapter/src/common.rs
1use alloc::{vec, vec::Vec};2use core::marker::PhantomData;3use crate::{Config, NativeFungibleHandle, Pallet};4use frame_support::{fail, traits::Currency, weights::Weight};5use pallet_balances::{weights::SubstrateWeight as BalancesWeight, WeightInfo};6use pallet_common::{erc::CrossAccountId, CommonCollectionOperations, CommonWeightInfo};7use up_data_structs::TokenId;89pub struct CommonWeights<T: Config>(PhantomData<T>);10impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {11	fn create_multiple_items(_amount: &[up_data_structs::CreateItemData]) -> Weight {12		Weight::default()13	}1415	fn create_multiple_items_ex(16		_cost: &up_data_structs::CreateItemExData<T::CrossAccountId>,17	) -> Weight {18		Weight::default()19	}2021	fn burn_item() -> Weight {22		Weight::default()23	}2425	fn set_collection_properties(_amount: u32) -> Weight {26		Weight::default()27	}2829	fn delete_collection_properties(_amount: u32) -> Weight {30		Weight::default()31	}3233	fn set_token_properties(_amount: u32) -> Weight {34		Weight::default()35	}3637	fn delete_token_properties(_amount: u32) -> Weight {38		Weight::default()39	}4041	fn set_token_property_permissions(_amount: u32) -> Weight {42		Weight::default()43	}4445	fn transfer() -> Weight {46		<BalancesWeight<T> as WeightInfo>::transfer()47	}4849	fn approve() -> Weight {50		Weight::default()51	}5253	fn approve_from() -> Weight {54		Weight::default()55	}5657	fn transfer_from() -> Weight {58		<BalancesWeight<T> as WeightInfo>::transfer()59	}6061	fn burn_from() -> Weight {62		Weight::default()63	}6465	fn burn_recursively_self_raw() -> Weight {66		Weight::default()67	}6869	fn burn_recursively_breadth_raw(_amount: u32) -> Weight {70		Weight::default()71	}7273	fn token_owner() -> Weight {74		Weight::default()75	}7677	fn set_allowance_for_all() -> Weight {78		Weight::default()79	}8081	fn force_repair_item() -> Weight {82		Weight::default()83	}84}8586/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallete87/// methods and adds weight info.88impl<T: Config> CommonCollectionOperations<T> for NativeFungibleHandle<T> {89	fn create_item(90		&self,91		_sender: <T>::CrossAccountId,92		_to: <T>::CrossAccountId,93		_data: up_data_structs::CreateItemData,94		_nesting_budget: &dyn up_data_structs::budget::Budget,95	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {96		fail!(<pallet_common::Error<T>>::UnsupportedOperation);97	}9899	fn create_multiple_items(100		&self,101		_sender: <T>::CrossAccountId,102		_to: <T>::CrossAccountId,103		_data: Vec<up_data_structs::CreateItemData>,104		_nesting_budget: &dyn up_data_structs::budget::Budget,105	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {106		fail!(<pallet_common::Error<T>>::UnsupportedOperation);107	}108109	fn create_multiple_items_ex(110		&self,111		_sender: <T>::CrossAccountId,112		_data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,113		_nesting_budget: &dyn up_data_structs::budget::Budget,114	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {115		fail!(<pallet_common::Error<T>>::UnsupportedOperation);116	}117118	fn burn_item(119		&self,120		_sender: <T>::CrossAccountId,121		_token: TokenId,122		_amount: u128,123	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {124		fail!(<pallet_common::Error<T>>::UnsupportedOperation);125	}126127	fn burn_item_recursively(128		&self,129		_sender: <T>::CrossAccountId,130		_token: TokenId,131		_self_budget: &dyn up_data_structs::budget::Budget,132		_breadth_budget: &dyn up_data_structs::budget::Budget,133	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {134		fail!(<pallet_common::Error<T>>::UnsupportedOperation);135	}136137	fn set_collection_properties(138		&self,139		_sender: <T>::CrossAccountId,140		_properties: Vec<up_data_structs::Property>,141	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {142		fail!(<pallet_common::Error<T>>::UnsupportedOperation);143	}144145	fn delete_collection_properties(146		&self,147		_sender: &<T>::CrossAccountId,148		_property_keys: Vec<up_data_structs::PropertyKey>,149	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {150		fail!(<pallet_common::Error<T>>::UnsupportedOperation);151	}152153	fn set_token_properties(154		&self,155		_sender: <T>::CrossAccountId,156		_token_id: TokenId,157		_properties: Vec<up_data_structs::Property>,158		_budget: &dyn up_data_structs::budget::Budget,159	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {160		fail!(<pallet_common::Error<T>>::UnsupportedOperation);161	}162163	fn delete_token_properties(164		&self,165		_sender: <T>::CrossAccountId,166		_token_id: TokenId,167		_property_keys: Vec<up_data_structs::PropertyKey>,168		_budget: &dyn up_data_structs::budget::Budget,169	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {170		fail!(<pallet_common::Error<T>>::UnsupportedOperation);171	}172173	fn set_token_property_permissions(174		&self,175		_sender: &<T>::CrossAccountId,176		_property_permissions: Vec<up_data_structs::PropertyKeyPermission>,177	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {178		fail!(<pallet_common::Error<T>>::UnsupportedOperation);179	}180181	fn transfer(182		&self,183		sender: <T>::CrossAccountId,184		to: <T>::CrossAccountId,185		_token: TokenId,186		amount: u128,187		budget: &dyn up_data_structs::budget::Budget,188	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {189		<Pallet<T>>::transfer(self, &sender, &to, amount, budget)190	}191192	fn approve(193		&self,194		_sender: <T>::CrossAccountId,195		_spender: <T>::CrossAccountId,196		_token: TokenId,197		_amount: u128,198	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {199		fail!(<pallet_common::Error<T>>::UnsupportedOperation);200	}201202	fn approve_from(203		&self,204		_sender: <T>::CrossAccountId,205		_from: <T>::CrossAccountId,206		_to: <T>::CrossAccountId,207		_token: TokenId,208		_amount: u128,209	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {210		fail!(<pallet_common::Error<T>>::UnsupportedOperation);211	}212213	fn transfer_from(214		&self,215		sender: <T>::CrossAccountId,216		from: <T>::CrossAccountId,217		to: <T>::CrossAccountId,218		_token: TokenId,219		amount: u128,220		budget: &dyn up_data_structs::budget::Budget,221	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {222		<Pallet<T>>::transfer_from(self, &sender, &from, &to, amount, budget)223	}224225	fn burn_from(226		&self,227		_sender: <T>::CrossAccountId,228		_from: <T>::CrossAccountId,229		_token: TokenId,230		_amount: u128,231		_budget: &dyn up_data_structs::budget::Budget,232	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {233		fail!(<pallet_common::Error<T>>::UnsupportedOperation);234	}235236	fn check_nesting(237		&self,238		_sender: <T>::CrossAccountId,239		_from: (up_data_structs::CollectionId, TokenId),240		_under: TokenId,241		_budget: &dyn up_data_structs::budget::Budget,242	) -> frame_support::sp_runtime::DispatchResult {243		fail!(<pallet_common::Error<T>>::UnsupportedOperation);244	}245246	fn nest(&self, _under: TokenId, _to_nest: (up_data_structs::CollectionId, TokenId)) {}247248	fn unnest(&self, _under: TokenId, _to_nest: (up_data_structs::CollectionId, TokenId)) {}249250	fn account_tokens(&self, account: <T>::CrossAccountId) -> Vec<TokenId> {251		let balance = <T as Config>::Currency::total_balance(account.as_sub());252		if balance != 0 {253			vec![TokenId::default()]254		} else {255			vec![]256		}257	}258259	fn collection_tokens(&self) -> Vec<TokenId> {260		vec![TokenId::default()]261	}262263	fn token_exists(&self, token: TokenId) -> bool {264		token == TokenId::default()265	}266267	fn last_token_id(&self) -> TokenId {268		TokenId::default()269	}270271	fn token_owner(272		&self,273		_token: TokenId,274	) -> Result<<T>::CrossAccountId, up_data_structs::TokenOwnerError> {275		Err(up_data_structs::TokenOwnerError::MultipleOwners)276	}277278	fn token_owners(&self, _token: TokenId) -> Vec<<T>::CrossAccountId> {279		vec![]280	}281282	fn token_property(283		&self,284		_token_id: TokenId,285		_key: &up_data_structs::PropertyKey,286	) -> Option<up_data_structs::PropertyValue> {287		None288	}289290	fn token_properties(291		&self,292		_token: TokenId,293		_keys: Option<Vec<up_data_structs::PropertyKey>>,294	) -> Vec<up_data_structs::Property> {295		vec![]296	}297298	fn total_supply(&self) -> u32 {299		1300	}301302	fn account_balance(&self, account: <T>::CrossAccountId) -> u32 {303		let balance: u128 = <T as Config>::Currency::free_balance(account.as_sub()).into();304		(balance != 0).into()305	}306307	fn balance(&self, account: <T>::CrossAccountId, token: TokenId) -> u128 {308		if token != TokenId::default() {309			return 0;310		}311		<T as Config>::Currency::free_balance(account.as_sub()).into()312	}313314	fn total_pieces(&self, token: TokenId) -> Option<u128> {315		if token != TokenId::default() {316			return None;317		}318		let total = <T as Config>::Currency::total_issuance();319		Some(total.into())320	}321322	fn allowance(323		&self,324		_sender: <T>::CrossAccountId,325		_spender: <T>::CrossAccountId,326		_token: TokenId,327	) -> u128 {328		0329	}330331	fn refungible_extensions(&self) -> Option<&dyn pallet_common::RefungibleExtensions<T>> {332		None333	}334335	fn set_allowance_for_all(336		&self,337		_owner: <T>::CrossAccountId,338		_operator: <T>::CrossAccountId,339		_approve: bool,340	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {341		fail!(<pallet_common::Error<T>>::UnsupportedOperation);342	}343344	fn allowance_for_all(345		&self,346		_owner: <T>::CrossAccountId,347		_operator: <T>::CrossAccountId,348	) -> bool {349		false350	}351352	fn repair_item(353		&self,354		_token: TokenId,355	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {356		fail!(<pallet_common::Error<T>>::UnsupportedOperation);357	}358}
modifiedpallets/balances-adapter/src/erc.rsdiffbeforeafterboth
--- a/pallets/balances-adapter/src/erc.rs
+++ b/pallets/balances-adapter/src/erc.rs
@@ -1,4 +1,4 @@
-use crate::{Config, NativeFungibleHandle, SelfWeightOf};
+use crate::{Config, NativeFungibleHandle, Pallet, SelfWeightOf};
 use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};
 use frame_support::traits::{Currency, ExistenceRequirement};
 use pallet_balances::WeightInfo;
@@ -10,8 +10,9 @@
 use pallet_evm_coder_substrate::{
 	call, dispatch_to_evm,
 	execution::{PreDispatch, Result},
-	frontier_contract,
+	frontier_contract, WithRecorder,
 };
+use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
 use sp_core::{U256, Get};
 use sp_std::vec::Vec;
 
@@ -73,18 +74,12 @@
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = T::CrossAccountId::from_eth(to);
 		let amount = amount.try_into().map_err(|_| "amount overflow")?;
-		// let budget = self
-		// 	.recorder
-		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());
+		let budget = self
+			.recorder()
+			.weight_calls_budget(<StructureWeight<T>>::find_parent());
 
-		// <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;
-		<T as Config>::Currency::transfer(
-			caller.as_sub(),
-			to.as_sub(),
-			amount,
-			ExistenceRequirement::KeepAlive,
-		)
-		.map_err(dispatch_to_evm::<T>)?;
+		<Pallet<T>>::transfer(self, &caller, &to, amount, &budget)
+			.map_err(|e| dispatch_to_evm::<T>(e.error))?;
 		Ok(true)
 	}
 
@@ -100,23 +95,12 @@
 		let from = T::CrossAccountId::from_eth(from);
 		let to = T::CrossAccountId::from_eth(to);
 		let amount = amount.try_into().map_err(|_| "amount overflow")?;
-
-		if from != caller {
-			return Err("no permission".into());
-		}
-		// let budget = self
-		// 	.recorder
-		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());
+		let budget = self
+			.recorder()
+			.weight_calls_budget(<StructureWeight<T>>::find_parent());
 
-		// <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)
-		// 	.map_err(dispatch_to_evm::<T>)?;
-		<T as Config>::Currency::transfer(
-			caller.as_sub(),
-			to.as_sub(),
-			amount,
-			ExistenceRequirement::KeepAlive,
-		)
-		.map_err(dispatch_to_evm::<T>)?;
+		<Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)
+			.map_err(|e| dispatch_to_evm::<T>(e.error))?;
 		Ok(true)
 	}
 }
modifiedpallets/balances-adapter/src/lib.rsdiffbeforeafterboth
--- a/pallets/balances-adapter/src/lib.rs
+++ b/pallets/balances-adapter/src/lib.rs
@@ -5,14 +5,17 @@
 use core::ops::Deref;
 
 use frame_support::sp_runtime::DispatchResult;
+use pallet_evm_coder_substrate::{WithRecorder, SubstrateRecorder};
 pub use pallet::*;
-use pallet_evm_coder_substrate::{WithRecorder, SubstrateRecorder};
 
 pub mod common;
 pub mod erc;
 
 pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
 
+const NATIVE_FUNGIBLE_COLLECTION_ID: up_data_structs::CollectionId =
+	up_data_structs::CollectionId(0);
+
 /// Handle for native fungible collection
 pub struct NativeFungibleHandle<T: Config>(SubstrateRecorder<T>);
 impl<T: Config> NativeFungibleHandle<T> {
@@ -45,14 +48,27 @@
 }
 #[frame_support::pallet]
 pub mod pallet {
+	use super::*;
 	use alloc::string::String;
-	use frame_support::{traits::Get};
+	use frame_support::{
+		dispatch::PostDispatchInfo,
+		ensure,
+		pallet_prelude::{DispatchResultWithPostInfo, Pays},
+		traits::{Currency, ExistenceRequirement, Get},
+	};
 	use pallet_balances::WeightInfo;
+	use pallet_common::{erc::CrossAccountId, Error as CommonError, Pallet as PalletCommon};
+	use pallet_structure::Pallet as PalletStructure;
 	use sp_core::U256;
+	use sp_runtime::DispatchError;
+	use up_data_structs::{budget::Budget, mapping::TokenAddressMapping, TokenId};
 
 	#[pallet::config]
 	pub trait Config:
-		frame_system::Config + pallet_evm_coder_substrate::Config + pallet_common::Config
+		frame_system::Config
+		+ pallet_evm_coder_substrate::Config
+		+ pallet_common::Config
+		+ pallet_structure::Config
 	{
 		/// Currency from `pallet_balances`
 		type Currency: frame_support::traits::Currency<
@@ -74,4 +90,104 @@
 	}
 	#[pallet::pallet]
 	pub struct Pallet<T>(_);
+
+	impl<T: Config> Pallet<T> {
+		/// Checks if a non-owner has (enough) allowance from the owner to perform operations on the tokens.
+		/// Returns the expected remaining allowance - it should be set manually if the transaction proceeds.
+		///
+		/// - `collection`: Collection that contains the token.
+		/// - `spender`: CrossAccountId who has the allowance rights.
+		/// - `from`: The owner of the tokens who sets the allowance.
+		/// - `amount`: Amount of tokens by which the allowance sholud be reduced.
+		fn check_allowed(
+			spender: &T::CrossAccountId,
+			from: &T::CrossAccountId,
+			nesting_budget: &dyn Budget,
+		) -> Result<u128, DispatchError> {
+			if spender.conv_eq(from) {
+				return Ok(0);
+			}
+
+			if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {
+				ensure!(
+					<PalletStructure<T>>::check_indirectly_owned(
+						spender.clone(),
+						source.0,
+						source.1,
+						None,
+						nesting_budget
+					)?,
+					<CommonError<T>>::ApprovedValueTooLow,
+				);
+			} else if spender != from {
+				return Ok(0);
+			}
+
+			Ok(<T as Config>::Currency::free_balance(from.as_sub()).into())
+		}
+
+		/// Transfers the specified amount of tokens. Will check that
+		/// the transfer is allowed for the token.
+		///
+		/// - `from`: Owner of tokens to transfer.
+		/// - `to`: Recepient of transfered tokens.
+		/// - `amount`: Amount of tokens to transfer.
+		/// - `collection`: Collection that contains the token
+		pub fn transfer(
+			_collection: &NativeFungibleHandle<T>,
+			from: &T::CrossAccountId,
+			to: &T::CrossAccountId,
+			amount: u128,
+			nesting_budget: &dyn Budget,
+		) -> DispatchResultWithPostInfo {
+			<PalletCommon<T>>::ensure_correct_receiver(to)?;
+
+			if from != to && amount != 0 {
+				<T as Config>::Currency::transfer(
+					from.as_sub(),
+					to.as_sub(),
+					amount.into(),
+					ExistenceRequirement::KeepAlive,
+				)?;
+
+				<PalletStructure<T>>::nest_if_sent_to_token(
+					from.clone(),
+					to,
+					NATIVE_FUNGIBLE_COLLECTION_ID,
+					TokenId::default(),
+					nesting_budget,
+				)?;
+
+				let balance_from: u128 =
+					<T as Config>::Currency::free_balance(from.as_sub()).into();
+				if balance_from == 0 {
+					<PalletStructure<T>>::unnest_if_nested(
+						from,
+						NATIVE_FUNGIBLE_COLLECTION_ID,
+						TokenId::default(),
+					);
+				}
+			};
+
+			Ok(PostDispatchInfo {
+				actual_weight: Some(<SelfWeightOf<T>>::transfer()),
+				pays_fee: Pays::Yes,
+			})
+		}
+
+		pub fn transfer_from(
+			collection: &NativeFungibleHandle<T>,
+			spender: &T::CrossAccountId,
+			from: &T::CrossAccountId,
+			to: &T::CrossAccountId,
+			amount: u128,
+			nesting_budget: &dyn Budget,
+		) -> DispatchResultWithPostInfo {
+			let allowance = Self::check_allowed(collection, spender, from, amount, nesting_budget)?;
+			if allowance < amount {
+				return Err(<CommonError<T>>::ApprovedValueTooLow.into());
+			}
+			Self::transfer(collection, from, to, amount, nesting_budget)
+		}
+	}
 }