git.delta.rocks / unique-network / refs/commits / 3293186a48b2

difftreelog

source

pallets/balances-adapter/src/erc.rs5.9 KiBsourcehistory
1use crate::{Config, NativeFungibleHandle, SelfWeightOf};2use evm_coder::{abi::AbiType, ToLog, generate_stubgen, solidity_interface, types::*};3use frame_support::traits::{Currency, ExistenceRequirement};4use pallet_balances::WeightInfo;5use pallet_common::{6	consume_store_reads,7	erc::{CommonEvmHandler, CrossAccountId, PrecompileHandle, PrecompileResult},8	eth::CrossAddress,9};10use pallet_evm_coder_substrate::{11	call, dispatch_to_evm,12	execution::{PreDispatch, Result},13	frontier_contract,14};15use sp_core::{U256, Get};16use sp_std::vec::Vec;1718frontier_contract! {19	macro_rules! NativeFungibleHandle_result {...}20	impl<T: Config> Contract for NativeFungibleHandle<T> {...}21}2223#[derive(ToLog)]24pub enum ERC20Events {25	Transfer {26		#[indexed]27		from: Address,28		#[indexed]29		to: Address,30		value: U256,31	},32}3334#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]35impl<T: Config> NativeFungibleHandle<T> {36	fn allowance(&self, _owner: Address, _spender: Address) -> Result<U256> {37		Ok(U256::zero())38	}3940	// #[weight(<SelfWeightOf<T>>::approve())]41	fn approve(&mut self, _caller: Caller, _spender: Address, _amount: U256) -> Result<bool> {42		// self.consume_store_reads(1)?;43		Err("Approve not supported".into())44	}4546	fn balance_of(&self, owner: Address) -> Result<U256> {47		consume_store_reads(self, 1)?;48		let owner = T::CrossAccountId::from_eth(owner);49		let balance = <T as Config>::Currency::free_balance(owner.as_sub());50		Ok(balance.into())51	}5253	fn decimals(&self) -> Result<u8> {54		Ok(T::Decimals::get())55	}5657	fn name(&self) -> Result<String> {58		Ok(T::Name::get())59	}6061	fn symbol(&self) -> Result<String> {62		Ok(T::Symbol::get())63	}6465	fn total_supply(&self) -> Result<U256> {66		consume_store_reads(self, 1)?;67		let total = <T as Config>::Currency::total_issuance();68		Ok(total.into())69	}7071	#[weight(<SelfWeightOf<T>>::transfer())]72	fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {73		let caller = T::CrossAccountId::from_eth(caller);74		let to = T::CrossAccountId::from_eth(to);75		let amount = amount.try_into().map_err(|_| "amount overflow")?;76		// let budget = self77		// 	.recorder78		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());7980		// <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;81		<T as Config>::Currency::transfer(82			caller.as_sub(),83			to.as_sub(),84			amount,85			ExistenceRequirement::KeepAlive,86		)87		.map_err(dispatch_to_evm::<T>)?;88		Ok(true)89	}9091	#[weight(<SelfWeightOf<T>>::transfer())]92	fn transfer_from(93		&mut self,94		caller: Caller,95		from: Address,96		to: Address,97		amount: U256,98	) -> Result<bool> {99		let caller = T::CrossAccountId::from_eth(caller);100		let from = T::CrossAccountId::from_eth(from);101		let to = T::CrossAccountId::from_eth(to);102		let amount = amount.try_into().map_err(|_| "amount overflow")?;103104		if from != caller {105			return Err("no permission".into());106		}107		// let budget = self108		// 	.recorder109		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());110111		// <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)112		// 	.map_err(dispatch_to_evm::<T>)?;113		<T as Config>::Currency::transfer(114			caller.as_sub(),115			to.as_sub(),116			amount,117			ExistenceRequirement::KeepAlive,118		)119		.map_err(dispatch_to_evm::<T>)?;120		Ok(true)121	}122}123124#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]125impl<T: Config> NativeFungibleHandle<T>126where127	T::AccountId: From<[u8; 32]>,128{129	fn balance_of_cross(&self, owner: CrossAddress) -> Result<U256> {130		consume_store_reads(self, 1)?;131		let owner = owner.into_sub_cross_account::<T>()?;132		let balance = <T as Config>::Currency::free_balance(owner.as_sub());133		Ok(balance.into())134	}135136	#[weight(<SelfWeightOf<T>>::transfer())]137	fn transfer_cross(&mut self, caller: Caller, to: CrossAddress, amount: U256) -> Result<bool> {138		let caller = T::CrossAccountId::from_eth(caller);139		let to = to.into_sub_cross_account::<T>()?;140		let amount = amount.try_into().map_err(|_| "amount overflow")?;141		// let budget = self142		// 	.recorder143		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());144145		// <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;146		<T as Config>::Currency::transfer(147			caller.as_sub(),148			to.as_sub(),149			amount,150			ExistenceRequirement::KeepAlive,151		)152		.map_err(dispatch_to_evm::<T>)?;153		Ok(true)154	}155156	#[weight(<SelfWeightOf<T>>::transfer())]157	fn transfer_from_cross(158		&mut self,159		caller: Caller,160		from: CrossAddress,161		to: CrossAddress,162		amount: U256,163	) -> Result<bool> {164		let caller = T::CrossAccountId::from_eth(caller);165		let from = from.into_sub_cross_account::<T>()?;166		let to = to.into_sub_cross_account::<T>()?;167		let amount = amount.try_into().map_err(|_| "amount overflow")?;168169		if from != caller {170			return Err("no permission".into());171		}172173		// let budget = self174		// 	.recorder175		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());176177		// <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)178		// 	.map_err(dispatch_to_evm::<T>)?;179		<T as Config>::Currency::transfer(180			caller.as_sub(),181			to.as_sub(),182			amount,183			ExistenceRequirement::KeepAlive,184		)185		.map_err(dispatch_to_evm::<T>)?;186		Ok(true)187	}188}189190#[solidity_interface(191	name = UniqueNativeFungible,192	is(ERC20, ERC20UniqueExtensions),193	enum(derive(PreDispatch))194)]195impl<T: Config> NativeFungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}196197generate_stubgen!(gen_impl, UniqueNativeFungibleCall<()>, true);198generate_stubgen!(gen_iface, UniqueNativeFungibleCall<()>, false);199200impl<T: Config> CommonEvmHandler for NativeFungibleHandle<T>201where202	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,203{204	const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNativeFungible.raw");205206	fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {207		call::<T, UniqueNativeFungibleCall<T>, _, _>(handle, self)208	}209}