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

difftreelog

source

pallets/balances-adapter/src/erc.rs4.9 KiBsourcehistory
1use crate::{Config, NativeFungibleHandle, Pallet, SelfWeightOf};2use evm_coder::{abi::AbiType, generate_stubgen, solidity_interface, types::*};3use pallet_balances::WeightInfo;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,12};13use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};14use sp_core::{U256, Get};1516frontier_contract! {17	macro_rules! NativeFungibleHandle_result {...}18	impl<T: Config> Contract for NativeFungibleHandle<T> {...}19}2021#[solidity_interface(name = ERC20, enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]22impl<T: Config> NativeFungibleHandle<T> {23	fn allowance(&self, _owner: Address, _spender: Address) -> Result<U256> {24		Ok(U256::zero())25	}2627	fn approve(&mut self, _caller: Caller, _spender: Address, _amount: U256) -> Result<bool> {28		Err("approve not supported".into())29	}3031	fn balance_of(&self, owner: Address) -> Result<U256> {32		self.consume_store_reads(1)?;33		let owner = T::CrossAccountId::from_eth(owner);34		let balance = <Pallet<T>>::balance_of(&owner);35		Ok(balance.into())36	}3738	fn decimals(&self) -> Result<u8> {39		Ok(T::Decimals::get())40	}4142	fn name(&self) -> Result<String> {43		Ok(T::Name::get())44	}4546	fn symbol(&self) -> Result<String> {47		Ok(T::Symbol::get())48	}4950	fn total_supply(&self) -> Result<U256> {51		self.consume_store_reads(1)?;52		Ok(<Pallet<T>>::total_issuance().into())53	}5455	#[weight(<SelfWeightOf<T>>::transfer_allow_death())]56	fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {57		let caller = T::CrossAccountId::from_eth(caller);58		let to = T::CrossAccountId::from_eth(to);59		let amount = amount.try_into().map_err(|_| "amount overflow")?;60		let budget = self61			.recorder()62			.weight_calls_budget(<StructureWeight<T>>::find_parent());6364		<Pallet<T>>::transfer(self, &caller, &to, amount, &budget)65			.map_err(|e| dispatch_to_evm::<T>(e.error))?;66		Ok(true)67	}6869	#[weight(<SelfWeightOf<T>>::transfer_allow_death())]70	fn transfer_from(71		&mut self,72		caller: Caller,73		from: Address,74		to: Address,75		amount: U256,76	) -> Result<bool> {77		let caller = T::CrossAccountId::from_eth(caller);78		let from = T::CrossAccountId::from_eth(from);79		let to = T::CrossAccountId::from_eth(to);80		let amount = amount.try_into().map_err(|_| "amount overflow")?;81		let budget = self82			.recorder()83			.weight_calls_budget(<StructureWeight<T>>::find_parent());8485		<Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)86			.map_err(|e| dispatch_to_evm::<T>(e.error))?;87		Ok(true)88	}89}9091#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]92impl<T: Config> NativeFungibleHandle<T>93where94	T::AccountId: From<[u8; 32]>,95{96	fn balance_of_cross(&self, owner: CrossAddress) -> Result<U256> {97		self.consume_store_reads(1)?;98		let owner = owner.into_sub_cross_account::<T>()?;99		let balance = <Pallet<T>>::balance_of(&owner);100		Ok(balance.into())101	}102103	#[weight(<SelfWeightOf<T>>::transfer_allow_death())]104	fn transfer_cross(&mut self, caller: Caller, to: CrossAddress, amount: U256) -> Result<bool> {105		let caller = T::CrossAccountId::from_eth(caller);106		let to = to.into_sub_cross_account::<T>()?;107		let amount = amount.try_into().map_err(|_| "amount overflow")?;108		let budget = self109			.recorder()110			.weight_calls_budget(<StructureWeight<T>>::find_parent());111112		<Pallet<T>>::transfer(self, &caller, &to, amount, &budget)113			.map_err(|e| dispatch_to_evm::<T>(e.error))?;114115		Ok(true)116	}117118	#[weight(<SelfWeightOf<T>>::transfer_allow_death())]119	fn transfer_from_cross(120		&mut self,121		caller: Caller,122		from: CrossAddress,123		to: CrossAddress,124		amount: U256,125	) -> Result<bool> {126		let caller = T::CrossAccountId::from_eth(caller);127		let from = from.into_sub_cross_account::<T>()?;128		let to = to.into_sub_cross_account::<T>()?;129		let amount = amount.try_into().map_err(|_| "amount overflow")?;130131		if from != caller {132			return Err("no permission".into());133		}134135		let budget = self136			.recorder()137			.weight_calls_budget(<StructureWeight<T>>::find_parent());138139		<Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)140			.map_err(|e| dispatch_to_evm::<T>(e.error))?;141142		Ok(true)143	}144}145146#[solidity_interface(147	name = UniqueNativeFungible,148	is(ERC20, ERC20UniqueExtensions),149	enum(derive(PreDispatch))150)]151impl<T: Config> NativeFungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}152153generate_stubgen!(gen_impl, UniqueNativeFungibleCall<()>, true);154generate_stubgen!(gen_iface, UniqueNativeFungibleCall<()>, false);155156impl<T: Config> CommonEvmHandler for NativeFungibleHandle<T>157where158	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,159{160	const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNativeFungible.raw");161162	fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {163		call::<T, UniqueNativeFungibleCall<T>, _, _>(handle, self)164	}165}