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

difftreelog

source

pallets/balances-adapter/src/erc.rs6.2 KiBsourcehistory
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}