git.delta.rocks / unique-network / refs/commits / 5a3127a55154

difftreelog

source

pallets/balances-adapter/src/erc.rs6.0 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	erc::{CommonEvmHandler, CrossAccountId, PrecompileHandle, PrecompileResult},7	eth::CrossAddress,8};9use pallet_evm_coder_substrate::{10	call, dispatch_to_evm,11	execution::{PreDispatch, Result},12	frontier_contract, WithRecorder, SubstrateRecorder,13};14use sp_core::{U256, Get};15use sp_std::vec::Vec;1617frontier_contract! {18	macro_rules! NativeFungibleHandle_result {...}19	impl<T: Config> Contract for NativeFungibleHandle<T> {...}20}2122#[derive(ToLog)]23pub enum ERC20Events {24	Transfer {25		#[indexed]26		from: Address,27		#[indexed]28		to: Address,29		value: U256,30	},31	Approval {32		#[indexed]33		owner: Address,34		#[indexed]35		spender: Address,36		value: U256,37	},38}3940#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]41impl<T: Config> NativeFungibleHandle<T> {42	fn allowance(&self, _owner: Address, _spender: Address) -> Result<U256> {43		Ok(U256::zero())44	}4546	// #[weight(<SelfWeightOf<T>>::approve())]47	fn approve(&mut self, _caller: Caller, _spender: Address, _amount: U256) -> Result<bool> {48		// self.consume_store_reads(1)?;49		Err("Approve not supported".into())50	}5152	fn balance_of(&self, owner: Address) -> Result<U256> {53		// self.consume_store_reads(1)?;54		let owner = T::CrossAccountId::from_eth(owner);55		let balance = <T as Config>::Currency::free_balance(owner.as_sub());56		Ok(balance.into())57	}5859	fn decimals(&self) -> Result<u8> {60		Ok(T::Decimals::get())61	}6263	fn name(&self) -> Result<String> {64		Ok(T::Name::get())65	}6667	fn symbol(&self) -> Result<String> {68		Ok(T::Symbol::get())69	}7071	fn total_supply(&self) -> Result<U256> {72		// self.consume_store_reads(1)?;73		let total = <T as Config>::Currency::total_issuance();74		Ok(total.into())75	}7677	#[weight(<SelfWeightOf<T>>::transfer())]78	fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {79		let caller = T::CrossAccountId::from_eth(caller);80		let to = T::CrossAccountId::from_eth(to);81		let amount = amount.try_into().map_err(|_| "amount overflow")?;82		// let budget = self83		// 	.recorder84		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());8586		// <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;87		<T as Config>::Currency::transfer(88			caller.as_sub(),89			to.as_sub(),90			amount,91			ExistenceRequirement::KeepAlive,92		)93		.map_err(dispatch_to_evm::<T>)?;94		Ok(true)95	}9697	#[weight(<SelfWeightOf<T>>::transfer())]98	fn transfer_from(99		&mut self,100		caller: Caller,101		from: Address,102		to: Address,103		amount: U256,104	) -> Result<bool> {105		let caller = T::CrossAccountId::from_eth(caller);106		let from = T::CrossAccountId::from_eth(from);107		let to = T::CrossAccountId::from_eth(to);108		let amount = amount.try_into().map_err(|_| "amount overflow")?;109110		if from != caller {111			return Err("no permission".into());112		}113		// let budget = self114		// 	.recorder115		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());116117		// <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)118		// 	.map_err(dispatch_to_evm::<T>)?;119		<T as Config>::Currency::transfer(120			caller.as_sub(),121			to.as_sub(),122			amount,123			ExistenceRequirement::KeepAlive,124		)125		.map_err(dispatch_to_evm::<T>)?;126		Ok(true)127	}128}129130#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]131impl<T: Config> NativeFungibleHandle<T>132where133	T::AccountId: From<[u8; 32]>,134{135	fn balance_of_cross(&self, owner: CrossAddress) -> Result<U256> {136		// self.consume_store_reads(1)?;137		let owner = owner.into_sub_cross_account::<T>()?;138		let balance = <T as Config>::Currency::free_balance(owner.as_sub());139		Ok(balance.into())140	}141142	#[weight(<SelfWeightOf<T>>::transfer())]143	fn transfer_cross(&mut self, caller: Caller, to: CrossAddress, amount: U256) -> Result<bool> {144		let caller = T::CrossAccountId::from_eth(caller);145		let to = to.into_sub_cross_account::<T>()?;146		let amount = amount.try_into().map_err(|_| "amount overflow")?;147		// let budget = self148		// 	.recorder149		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());150151		// <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;152		<T as Config>::Currency::transfer(153			caller.as_sub(),154			to.as_sub(),155			amount,156			ExistenceRequirement::KeepAlive,157		)158		.map_err(dispatch_to_evm::<T>)?;159		Ok(true)160	}161162	#[weight(<SelfWeightOf<T>>::transfer())]163	fn transfer_from_cross(164		&mut self,165		caller: Caller,166		from: CrossAddress,167		to: CrossAddress,168		amount: U256,169	) -> Result<bool> {170		let caller = T::CrossAccountId::from_eth(caller);171		let from = from.into_sub_cross_account::<T>()?;172		let to = to.into_sub_cross_account::<T>()?;173		let amount = amount.try_into().map_err(|_| "amount overflow")?;174175		if from != caller {176			return Err("no permission".into());177		}178179		// let budget = self180		// 	.recorder181		// 	.weight_calls_budget(<StructureWeight<T>>::find_parent());182183		// <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)184		// 	.map_err(dispatch_to_evm::<T>)?;185		<T as Config>::Currency::transfer(186			caller.as_sub(),187			to.as_sub(),188			amount,189			ExistenceRequirement::KeepAlive,190		)191		.map_err(dispatch_to_evm::<T>)?;192		Ok(true)193	}194}195196#[solidity_interface(197	name = UniqueNativeFungible,198	is(ERC20, ERC20UniqueExtensions),199	enum(derive(PreDispatch))200)]201impl<T: Config> NativeFungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}202203generate_stubgen!(gen_impl, UniqueNativeFungibleCall<()>, true);204generate_stubgen!(gen_iface, UniqueNativeFungibleCall<()>, false);205206impl<T: Config> CommonEvmHandler for NativeFungibleHandle<T>207where208	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,209{210	const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNativeFungible.raw");211212	fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {213		call::<T, UniqueNativeFungibleCall<T>, _, _>(handle, self)214	}215}