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

difftreelog

feat impl balance_of_cross

Trubnikov Sergey2023-04-21parent: #ec349b0.patch.diff
in: master

5 files changed

modifiedpallets/balances-adapter/src/erc.rsdiffbeforeafterboth
before · pallets/balances-adapter/src/erc.rs
1use crate::Config;2use evm_coder::{abi::AbiType, AbiCoder, ToLog, generate_stubgen, solidity_interface, types::*};3use frame_support::traits::{Currency, ExistenceRequirement};4use pallet_common::{5	erc::{CommonEvmHandler, CrossAccountId, PrecompileHandle, PrecompileResult},6	eth::CrossAddress,7};8use pallet_evm_coder_substrate::{9	call, dispatch_to_evm,10	execution::{PreDispatch, Result},11	frontier_contract, WithRecorder, SubstrateRecorder,12};13use sp_core::{U256, Get};14use sp_std::vec::Vec;1516frontier_contract! {17	macro_rules! NativeFungibleHandle_result {...}18	impl<T: Config> Contract for NativeFungibleHandle<T> {...}19}2021#[derive(ToLog)]22pub enum ERC20Events {23	Transfer {24		#[indexed]25		from: Address,26		#[indexed]27		to: Address,28		value: U256,29	},30	Approval {31		#[indexed]32		owner: Address,33		#[indexed]34		spender: Address,35		value: U256,36	},37}3839pub struct NativeFungibleHandle<T: Config>(SubstrateRecorder<T>);4041impl<T: Config> WithRecorder<T> for NativeFungibleHandle<T> {42	fn recorder(&self) -> &pallet_evm_coder_substrate::SubstrateRecorder<T> {43		&self.044	}45	fn into_recorder(self) -> pallet_evm_coder_substrate::SubstrateRecorder<T> {46		self.047	}48}4950#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]51impl<T: Config> NativeFungibleHandle<T> {52	fn allowance(&self, owner: Address, spender: Address) -> Result<U256> {53		Ok(U256::zero())54	}5556	// #[weight(<SelfWeightOf<T>>::approve())]57	fn approve(&mut self, caller: Caller, spender: Address, amount: U256) -> Result<bool> {58		// self.consume_store_reads(1)?;59		Err("Approve not supported now".into())60	}61	fn balance_of(&self, owner: Address) -> Result<U256> {62		// self.consume_store_reads(1)?;63		let owner = T::CrossAccountId::from_eth(owner);64		let balance = <T as Config>::Currency::free_balance(owner.as_sub());65		Ok(balance.into())66	}6768	fn decimals(&self) -> Result<u8> {69		Ok(T::Decimals::get())70	}7172	fn name(&self) -> Result<String> {73		Ok(T::Name::get())74	}7576	fn symbol(&self) -> Result<String> {77		Ok(T::Symbol::get())78	}7980	fn total_supply(&self) -> Result<U256> {81		// self.consume_store_reads(1)?;82		let total = <T as Config>::Currency::total_issuance();83		Ok(total.into())84	}8586	// #[weight(<SelfWeightOf<T>>::transfer())]87	fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {88		let caller = T::CrossAccountId::from_eth(caller);89		let to = T::CrossAccountId::from_eth(to);90		let amount = amount.try_into().map_err(|_| "amount overflow")?;91		// let budget = self92		// 	.recorder93		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());9495		// <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;96		<T as Config>::Currency::transfer(97			caller.as_sub(),98			to.as_sub(),99			amount,100			ExistenceRequirement::KeepAlive,101		)102		.map_err(dispatch_to_evm::<T>);103		Ok(true)104	}105106	// #[weight(<SelfWeightOf<T>>::transfer_from())]107	fn transfer_from(108		&mut self,109		caller: Caller,110		from: Address,111		to: Address,112		amount: U256,113	) -> Result<bool> {114		let caller = T::CrossAccountId::from_eth(caller);115		let from = T::CrossAccountId::from_eth(from);116		let to = T::CrossAccountId::from_eth(to);117		let amount = amount.try_into().map_err(|_| "amount overflow")?;118119		if (from != to) {120			return Err("no permission".into());121		}122		// let budget = self123		// 	.recorder124		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());125126		// <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)127		// 	.map_err(dispatch_to_evm::<T>)?;128		<T as Config>::Currency::transfer(129			caller.as_sub(),130			to.as_sub(),131			amount,132			ExistenceRequirement::KeepAlive,133		)134		.map_err(dispatch_to_evm::<T>);135		Ok(true)136	}137}138139#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]140impl<T: Config> NativeFungibleHandle<T>141where142	T::AccountId: From<[u8; 32]>,143{144	// #[weight(<SelfWeightOf<T>>::transfer())]145	fn transfer_cross(&mut self, caller: Caller, to: CrossAddress, amount: U256) -> Result<bool> {146		let caller = T::CrossAccountId::from_eth(caller);147		let to = to.into_sub_cross_account::<T>()?;148		let amount = amount.try_into().map_err(|_| "amount overflow")?;149		// let budget = self150		// 	.recorder151		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());152153		// <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;154		<T as Config>::Currency::transfer(155			caller.as_sub(),156			to.as_sub(),157			amount,158			ExistenceRequirement::KeepAlive,159		)160		.map_err(dispatch_to_evm::<T>);161		Ok(true)162	}163164	// #[weight(<SelfWeightOf<T>>::transfer_from())]165	fn transfer_from_cross(166		&mut self,167		caller: Caller,168		from: CrossAddress,169		to: CrossAddress,170		amount: U256,171	) -> Result<bool> {172		let caller = T::CrossAccountId::from_eth(caller);173		let from = from.into_sub_cross_account::<T>()?;174		let to = to.into_sub_cross_account::<T>()?;175		let amount = amount.try_into().map_err(|_| "amount overflow")?;176177		if (from != to) {178			return Err("no permission".into());179		}180181		// let budget = self182		// 	.recorder183		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());184185		// <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)186		// 	.map_err(dispatch_to_evm::<T>)?;187		<T as Config>::Currency::transfer(188			caller.as_sub(),189			to.as_sub(),190			amount,191			ExistenceRequirement::KeepAlive,192		)193		.map_err(dispatch_to_evm::<T>);194		Ok(true)195	}196}197198#[solidity_interface(199	name = UniqueNativeFungible,200	is(ERC20, ERC20UniqueExtensions),201	enum(derive(PreDispatch))202)]203impl<T: Config> NativeFungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}204205generate_stubgen!(gen_impl, UniqueNativeFungibleCall<()>, true);206generate_stubgen!(gen_iface, UniqueNativeFungibleCall<()>, false);207208impl<T: Config> CommonEvmHandler for NativeFungibleHandle<T>209where210	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,211{212	const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNativeFungible.raw");213214	fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {215		call::<T, UniqueNativeFungibleCall<T>, _, _>(handle, self)216	}217}
after · pallets/balances-adapter/src/erc.rs
1use crate::Config;2use evm_coder::{abi::AbiType, AbiCoder, ToLog, generate_stubgen, solidity_interface, types::*};3use frame_support::traits::{Currency, ExistenceRequirement};4use pallet_common::{5	erc::{CommonEvmHandler, CrossAccountId, PrecompileHandle, PrecompileResult},6	eth::CrossAddress,7};8use pallet_evm_coder_substrate::{9	call, dispatch_to_evm,10	execution::{PreDispatch, Result},11	frontier_contract, WithRecorder, SubstrateRecorder,12};13use sp_core::{U256, Get};14use sp_std::vec::Vec;1516frontier_contract! {17	macro_rules! NativeFungibleHandle_result {...}18	impl<T: Config> Contract for NativeFungibleHandle<T> {...}19}2021#[derive(ToLog)]22pub enum ERC20Events {23	Transfer {24		#[indexed]25		from: Address,26		#[indexed]27		to: Address,28		value: U256,29	},30	Approval {31		#[indexed]32		owner: Address,33		#[indexed]34		spender: Address,35		value: U256,36	},37}3839pub struct NativeFungibleHandle<T: Config>(SubstrateRecorder<T>);4041impl<T: Config> WithRecorder<T> for NativeFungibleHandle<T> {42	fn recorder(&self) -> &pallet_evm_coder_substrate::SubstrateRecorder<T> {43		&self.044	}45	fn into_recorder(self) -> pallet_evm_coder_substrate::SubstrateRecorder<T> {46		self.047	}48}4950#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]51impl<T: Config> NativeFungibleHandle<T> {52	fn allowance(&self, owner: Address, spender: Address) -> Result<U256> {53		Ok(U256::zero())54	}5556	// #[weight(<SelfWeightOf<T>>::approve())]57	fn approve(&mut self, caller: Caller, spender: Address, amount: U256) -> Result<bool> {58		// self.consume_store_reads(1)?;59		Err("Approve not supported now".into())60	}6162	fn balance_of(&self, owner: Address) -> Result<U256> {63		// self.consume_store_reads(1)?;64		let owner = T::CrossAccountId::from_eth(owner);65		let balance = <T as Config>::Currency::free_balance(owner.as_sub());66		Ok(balance.into())67	}6869	fn decimals(&self) -> Result<u8> {70		Ok(T::Decimals::get())71	}7273	fn name(&self) -> Result<String> {74		Ok(T::Name::get())75	}7677	fn symbol(&self) -> Result<String> {78		Ok(T::Symbol::get())79	}8081	fn total_supply(&self) -> Result<U256> {82		// self.consume_store_reads(1)?;83		let total = <T as Config>::Currency::total_issuance();84		Ok(total.into())85	}8687	// #[weight(<SelfWeightOf<T>>::transfer())]88	fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {89		let caller = T::CrossAccountId::from_eth(caller);90		let to = T::CrossAccountId::from_eth(to);91		let amount = amount.try_into().map_err(|_| "amount overflow")?;92		// let budget = self93		// 	.recorder94		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());9596		// <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;97		<T as Config>::Currency::transfer(98			caller.as_sub(),99			to.as_sub(),100			amount,101			ExistenceRequirement::KeepAlive,102		)103		.map_err(dispatch_to_evm::<T>);104		Ok(true)105	}106107	// #[weight(<SelfWeightOf<T>>::transfer_from())]108	fn transfer_from(109		&mut self,110		caller: Caller,111		from: Address,112		to: Address,113		amount: U256,114	) -> Result<bool> {115		let caller = T::CrossAccountId::from_eth(caller);116		let from = T::CrossAccountId::from_eth(from);117		let to = T::CrossAccountId::from_eth(to);118		let amount = amount.try_into().map_err(|_| "amount overflow")?;119120		if (from != to) {121			return Err("no permission".into());122		}123		// let budget = self124		// 	.recorder125		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());126127		// <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)128		// 	.map_err(dispatch_to_evm::<T>)?;129		<T as Config>::Currency::transfer(130			caller.as_sub(),131			to.as_sub(),132			amount,133			ExistenceRequirement::KeepAlive,134		)135		.map_err(dispatch_to_evm::<T>);136		Ok(true)137	}138}139140#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]141impl<T: Config> NativeFungibleHandle<T>142where143	T::AccountId: From<[u8; 32]>,144{145	fn balance_of_cross(&self, owner: CrossAddress) -> Result<U256> {146		// self.consume_store_reads(1)?;147		let owner = owner.into_sub_cross_account::<T>()?;148		let balance = <T as Config>::Currency::free_balance(owner.as_sub());149		Ok(balance.into())150	}151152	// #[weight(<SelfWeightOf<T>>::transfer())]153	fn transfer_cross(&mut self, caller: Caller, to: CrossAddress, amount: U256) -> Result<bool> {154		let caller = T::CrossAccountId::from_eth(caller);155		let to = to.into_sub_cross_account::<T>()?;156		let amount = amount.try_into().map_err(|_| "amount overflow")?;157		// let budget = self158		// 	.recorder159		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());160161		// <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;162		<T as Config>::Currency::transfer(163			caller.as_sub(),164			to.as_sub(),165			amount,166			ExistenceRequirement::KeepAlive,167		)168		.map_err(dispatch_to_evm::<T>);169		Ok(true)170	}171172	// #[weight(<SelfWeightOf<T>>::transfer_from())]173	fn transfer_from_cross(174		&mut self,175		caller: Caller,176		from: CrossAddress,177		to: CrossAddress,178		amount: U256,179	) -> Result<bool> {180		let caller = T::CrossAccountId::from_eth(caller);181		let from = from.into_sub_cross_account::<T>()?;182		let to = to.into_sub_cross_account::<T>()?;183		let amount = amount.try_into().map_err(|_| "amount overflow")?;184185		if (from != to) {186			return Err("no permission".into());187		}188189		// let budget = self190		// 	.recorder191		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());192193		// <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)194		// 	.map_err(dispatch_to_evm::<T>)?;195		<T as Config>::Currency::transfer(196			caller.as_sub(),197			to.as_sub(),198			amount,199			ExistenceRequirement::KeepAlive,200		)201		.map_err(dispatch_to_evm::<T>);202		Ok(true)203	}204}205206#[solidity_interface(207	name = UniqueNativeFungible,208	is(ERC20, ERC20UniqueExtensions),209	enum(derive(PreDispatch))210)]211impl<T: Config> NativeFungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}212213generate_stubgen!(gen_impl, UniqueNativeFungibleCall<()>, true);214generate_stubgen!(gen_iface, UniqueNativeFungibleCall<()>, false);215216impl<T: Config> CommonEvmHandler for NativeFungibleHandle<T>217where218	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,219{220	const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNativeFungible.raw");221222	fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {223		call::<T, UniqueNativeFungibleCall<T>, _, _>(handle, self)224	}225}
modifiedpallets/balances-adapter/src/stubs/UniqueNativeFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/balances-adapter/src/stubs/UniqueNativeFungible.soldiffbeforeafterboth
--- a/pallets/balances-adapter/src/stubs/UniqueNativeFungible.sol
+++ b/pallets/balances-adapter/src/stubs/UniqueNativeFungible.sol
@@ -17,8 +17,17 @@
 	}
 }
 
-/// @dev the ERC-165 identifier for this interface is 0xff15c6f4
+/// @dev the ERC-165 identifier for this interface is 0x1313556c
 contract ERC20UniqueExtensions is Dummy, ERC165 {
+	/// @dev EVM selector for this function is: 0xec069398,
+	///  or in textual repr: balanceOfCross((address,uint256))
+	function balanceOfCross(CrossAddress memory owner) public view returns (uint256) {
+		require(false, stub_error);
+		owner;
+		dummy;
+		return 0;
+	}
+
 	/// @dev EVM selector for this function is: 0x2ada85ff,
 	///  or in textual repr: transferCross((address,uint256),uint256)
 	function transferCross(CrossAddress memory to, uint256 amount) public returns (bool) {
modifiedtests/src/eth/abi/nativeFungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/nativeFungible.json
+++ b/tests/src/eth/abi/nativeFungible.json
@@ -79,6 +79,23 @@
     "type": "function"
   },
   {
+    "inputs": [
+      {
+        "components": [
+          { "internalType": "address", "name": "eth", "type": "address" },
+          { "internalType": "uint256", "name": "sub", "type": "uint256" }
+        ],
+        "internalType": "struct CrossAddress",
+        "name": "owner",
+        "type": "tuple"
+      }
+    ],
+    "name": "balanceOfCross",
+    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
     "inputs": [],
     "name": "decimals",
     "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],
modifiedtests/src/eth/api/UniqueNativeFungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNativeFungible.sol
+++ b/tests/src/eth/api/UniqueNativeFungible.sol
@@ -12,8 +12,12 @@
 	function supportsInterface(bytes4 interfaceID) external view returns (bool);
 }
 
-/// @dev the ERC-165 identifier for this interface is 0xff15c6f4
+/// @dev the ERC-165 identifier for this interface is 0x1313556c
 interface ERC20UniqueExtensions is Dummy, ERC165 {
+	/// @dev EVM selector for this function is: 0xec069398,
+	///  or in textual repr: balanceOfCross((address,uint256))
+	function balanceOfCross(CrossAddress memory owner) external view returns (uint256);
+
 	/// @dev EVM selector for this function is: 0x2ada85ff,
 	///  or in textual repr: transferCross((address,uint256),uint256)
 	function transferCross(CrossAddress memory to, uint256 amount) external returns (bool);