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

difftreelog

source

pallets/balances-adapter/src/erc.rs4.7 KiBsourcehistory
1use evm_coder::{abi::AbiType, generate_stubgen, solidity_interface, types::*};2use pallet_balances::WeightInfo;3use pallet_common::{4	erc::{CommonEvmHandler, CrossAccountId, PrecompileHandle, PrecompileResult},5	eth::CrossAddress,6};7use pallet_evm_coder_substrate::{8	call, dispatch_to_evm,9	execution::{PreDispatch, Result},10	frontier_contract, WithRecorder,11};12use pallet_structure::{weights::WeightInfo as _, SelfWeightOf as StructureWeight};13use sp_core::{Get, U256};1415use crate::{Config, NativeFungibleHandle, Pallet, SelfWeightOf};1617frontier_contract! {18	macro_rules! NativeFungibleHandle_result {...}19	impl<T: Config> Contract for NativeFungibleHandle<T> {...}20}2122#[solidity_interface(name = ERC20, enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]23impl<T: Config> NativeFungibleHandle<T> {24	fn allowance(&self, _owner: Address, _spender: Address) -> Result<U256> {25		Ok(U256::zero())26	}2728	fn approve(&mut self, _caller: Caller, _spender: Address, _amount: U256) -> Result<bool> {29		Err("approve not supported".into())30	}3132	fn balance_of(&self, owner: Address) -> Result<U256> {33		self.consume_store_reads(1)?;34		let owner = T::CrossAccountId::from_eth(owner);35		let balance = <Pallet<T>>::balance_of(&owner);36		Ok(balance.into())37	}3839	fn decimals(&self) -> Result<u8> {40		Ok(T::Decimals::get())41	}4243	fn name(&self) -> Result<String> {44		Ok(T::Name::get())45	}4647	fn symbol(&self) -> Result<String> {48		Ok(T::Symbol::get())49	}5051	fn total_supply(&self) -> Result<U256> {52		self.consume_store_reads(1)?;53		Ok(<Pallet<T>>::total_issuance().into())54	}5556	#[weight(<SelfWeightOf<T>>::transfer_allow_death())]57	fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {58		let caller = T::CrossAccountId::from_eth(caller);59		let to = T::CrossAccountId::from_eth(to);60		let amount = amount.try_into().map_err(|_| "amount overflow")?;6162		<Pallet<T>>::transfer(&caller, &to, amount).map_err(|e| dispatch_to_evm::<T>(e.error))?;63		Ok(true)64	}6566	#[weight(<SelfWeightOf<T>>::transfer_allow_death())]67	fn transfer_from(68		&mut self,69		caller: Caller,70		from: Address,71		to: Address,72		amount: U256,73	) -> Result<bool> {74		let caller = T::CrossAccountId::from_eth(caller);75		let from = T::CrossAccountId::from_eth(from);76		let to = T::CrossAccountId::from_eth(to);77		let amount = amount.try_into().map_err(|_| "amount overflow")?;78		let budget = self79			.recorder()80			.weight_calls_budget(<StructureWeight<T>>::find_parent());8182		<Pallet<T>>::transfer_from(&caller, &from, &to, amount, &budget)83			.map_err(|e| dispatch_to_evm::<T>(e.error))?;84		Ok(true)85	}86}8788#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]89impl<T: Config> NativeFungibleHandle<T>90where91	T::AccountId: From<[u8; 32]>,92{93	fn balance_of_cross(&self, owner: CrossAddress) -> Result<U256> {94		self.consume_store_reads(1)?;95		let owner = owner.into_sub_cross_account::<T>()?;96		let balance = <Pallet<T>>::balance_of(&owner);97		Ok(balance.into())98	}99100	#[weight(<SelfWeightOf<T>>::transfer_allow_death())]101	fn transfer_cross(&mut self, caller: Caller, to: CrossAddress, amount: U256) -> Result<bool> {102		let caller = T::CrossAccountId::from_eth(caller);103		let to = to.into_sub_cross_account::<T>()?;104		let amount = amount.try_into().map_err(|_| "amount overflow")?;105106		<Pallet<T>>::transfer(&caller, &to, amount).map_err(|e| dispatch_to_evm::<T>(e.error))?;107108		Ok(true)109	}110111	#[weight(<SelfWeightOf<T>>::transfer_allow_death())]112	fn transfer_from_cross(113		&mut self,114		caller: Caller,115		from: CrossAddress,116		to: CrossAddress,117		amount: U256,118	) -> Result<bool> {119		let caller = T::CrossAccountId::from_eth(caller);120		let from = from.into_sub_cross_account::<T>()?;121		let to = to.into_sub_cross_account::<T>()?;122		let amount = amount.try_into().map_err(|_| "amount overflow")?;123124		if from != caller {125			return Err("no permission".into());126		}127128		let budget = self129			.recorder()130			.weight_calls_budget(<StructureWeight<T>>::find_parent());131132		<Pallet<T>>::transfer_from(&caller, &from, &to, amount, &budget)133			.map_err(|e| dispatch_to_evm::<T>(e.error))?;134135		Ok(true)136	}137}138139#[solidity_interface(140	name = UniqueNativeFungible,141	is(ERC20, ERC20UniqueExtensions),142	enum(derive(PreDispatch))143)]144impl<T: Config> NativeFungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}145146generate_stubgen!(gen_impl, UniqueNativeFungibleCall<()>, true);147generate_stubgen!(gen_iface, UniqueNativeFungibleCall<()>, false);148149impl<T: Config> CommonEvmHandler for NativeFungibleHandle<T>150where151	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,152{153	const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNativeFungible.raw");154155	fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {156		call::<T, UniqueNativeFungibleCall<T>, _, _>(handle, self)157	}158}