git.delta.rocks / unique-network / refs/commits / 4dd148686c6b

difftreelog

source

pallets/balances-adapter/src/erc.rs4.9 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")?;61		let budget = self62			.recorder()63			.weight_calls_budget(<StructureWeight<T>>::find_parent());6465		<Pallet<T>>::transfer(self, &caller, &to, amount, &budget)66			.map_err(|e| dispatch_to_evm::<T>(e.error))?;67		Ok(true)68	}6970	#[weight(<SelfWeightOf<T>>::transfer_allow_death())]71	fn transfer_from(72		&mut self,73		caller: Caller,74		from: Address,75		to: Address,76		amount: U256,77	) -> Result<bool> {78		let caller = T::CrossAccountId::from_eth(caller);79		let from = T::CrossAccountId::from_eth(from);80		let to = T::CrossAccountId::from_eth(to);81		let amount = amount.try_into().map_err(|_| "amount overflow")?;82		let budget = self83			.recorder()84			.weight_calls_budget(<StructureWeight<T>>::find_parent());8586		<Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)87			.map_err(|e| dispatch_to_evm::<T>(e.error))?;88		Ok(true)89	}90}9192#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]93impl<T: Config> NativeFungibleHandle<T>94where95	T::AccountId: From<[u8; 32]>,96{97	fn balance_of_cross(&self, owner: CrossAddress) -> Result<U256> {98		self.consume_store_reads(1)?;99		let owner = owner.into_sub_cross_account::<T>()?;100		let balance = <Pallet<T>>::balance_of(&owner);101		Ok(balance.into())102	}103104	#[weight(<SelfWeightOf<T>>::transfer_allow_death())]105	fn transfer_cross(&mut self, caller: Caller, to: CrossAddress, amount: U256) -> Result<bool> {106		let caller = T::CrossAccountId::from_eth(caller);107		let to = to.into_sub_cross_account::<T>()?;108		let amount = amount.try_into().map_err(|_| "amount overflow")?;109		let budget = self110			.recorder()111			.weight_calls_budget(<StructureWeight<T>>::find_parent());112113		<Pallet<T>>::transfer(self, &caller, &to, amount, &budget)114			.map_err(|e| dispatch_to_evm::<T>(e.error))?;115116		Ok(true)117	}118119	#[weight(<SelfWeightOf<T>>::transfer_allow_death())]120	fn transfer_from_cross(121		&mut self,122		caller: Caller,123		from: CrossAddress,124		to: CrossAddress,125		amount: U256,126	) -> Result<bool> {127		let caller = T::CrossAccountId::from_eth(caller);128		let from = from.into_sub_cross_account::<T>()?;129		let to = to.into_sub_cross_account::<T>()?;130		let amount = amount.try_into().map_err(|_| "amount overflow")?;131132		if from != caller {133			return Err("no permission".into());134		}135136		let budget = self137			.recorder()138			.weight_calls_budget(<StructureWeight<T>>::find_parent());139140		<Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)141			.map_err(|e| dispatch_to_evm::<T>(e.error))?;142143		Ok(true)144	}145}146147#[solidity_interface(148	name = UniqueNativeFungible,149	is(ERC20, ERC20UniqueExtensions),150	enum(derive(PreDispatch))151)]152impl<T: Config> NativeFungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}153154generate_stubgen!(gen_impl, UniqueNativeFungibleCall<()>, true);155generate_stubgen!(gen_iface, UniqueNativeFungibleCall<()>, false);156157impl<T: Config> CommonEvmHandler for NativeFungibleHandle<T>158where159	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,160{161	const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNativeFungible.raw");162163	fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {164		call::<T, UniqueNativeFungibleCall<T>, _, _>(handle, self)165	}166}