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

difftreelog

source

pallets/fungible/src/erc.rs4.1 KiBsourcehistory
1use core::char::{REPLACEMENT_CHARACTER, decode_utf16};2use core::convert::TryInto;3use evm_coder::{ToLog, execution::*, generate_stubgen, solidity_interface, types::*, weight};4use up_data_structs::CollectionMode;5use pallet_common::erc::{CommonEvmHandler, PrecompileResult};6use sp_core::{H160, U256};7use sp_std::vec::Vec;8use pallet_common::account::CrossAccountId;9use pallet_evm_coder_substrate::{call, dispatch_to_evm};1011use crate::{12	Allowance, Balance, Config, FungibleHandle, Pallet, SelfWeightOf, TotalSupply,13	weights::WeightInfo,14};1516#[derive(ToLog)]17pub enum ERC20Events {18	Transfer {19		#[indexed]20		from: address,21		#[indexed]22		to: address,23		value: uint256,24	},25	Approval {26		#[indexed]27		owner: address,28		#[indexed]29		spender: address,30		value: uint256,31	},32}3334#[solidity_interface(name = "ERC20", events(ERC20Events))]35impl<T: Config> FungibleHandle<T> {36	fn name(&self) -> Result<string> {37		Ok(decode_utf16(self.name.iter().copied())38			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))39			.collect::<string>())40	}41	fn symbol(&self) -> Result<string> {42		Ok(string::from_utf8_lossy(&self.token_prefix).into())43	}44	fn total_supply(&self) -> Result<uint256> {45		self.consume_store_reads(1)?;46		Ok(<TotalSupply<T>>::get(self.id).into())47	}4849	fn decimals(&self) -> Result<uint8> {50		Ok(if let CollectionMode::Fungible(decimals) = &self.mode {51			*decimals52		} else {53			unreachable!()54		})55	}56	fn balance_of(&self, owner: address) -> Result<uint256> {57		self.consume_store_reads(1)?;58		let owner = T::CrossAccountId::from_eth(owner);59		let balance = <Balance<T>>::get((self.id, owner));60		Ok(balance.into())61	}62	#[weight(<SelfWeightOf<T>>::transfer())]63	fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result<bool> {64		let caller = T::CrossAccountId::from_eth(caller);65		let to = T::CrossAccountId::from_eth(to);66		let amount = amount.try_into().map_err(|_| "amount overflow")?;6768		<Pallet<T>>::transfer(self, &caller, &to, amount).map_err(|_| "transfer error")?;69		Ok(true)70	}71	#[weight(<SelfWeightOf<T>>::transfer_from())]72	fn transfer_from(73		&mut self,74		caller: caller,75		from: address,76		to: address,77		amount: uint256,78	) -> Result<bool> {79		let caller = T::CrossAccountId::from_eth(caller);80		let from = T::CrossAccountId::from_eth(from);81		let to = T::CrossAccountId::from_eth(to);82		let amount = amount.try_into().map_err(|_| "amount overflow")?;8384		<Pallet<T>>::transfer_from(self, &caller, &from, &to, amount)85			.map_err(dispatch_to_evm::<T>)?;86		Ok(true)87	}88	#[weight(<SelfWeightOf<T>>::approve())]89	fn approve(&mut self, caller: caller, spender: address, amount: uint256) -> Result<bool> {90		let caller = T::CrossAccountId::from_eth(caller);91		let spender = T::CrossAccountId::from_eth(spender);92		let amount = amount.try_into().map_err(|_| "amount overflow")?;9394		<Pallet<T>>::set_allowance(self, &caller, &spender, amount)95			.map_err(dispatch_to_evm::<T>)?;96		Ok(true)97	}98	fn allowance(&self, owner: address, spender: address) -> Result<uint256> {99		self.consume_store_reads(1)?;100		let owner = T::CrossAccountId::from_eth(owner);101		let spender = T::CrossAccountId::from_eth(spender);102103		Ok(<Allowance<T>>::get((self.id, owner, spender)).into())104	}105}106107#[solidity_interface(name = "ERC20UniqueExtensions")]108impl<T: Config> FungibleHandle<T> {109	#[weight(<SelfWeightOf<T>>::burn_from())]110	fn burn_from(&mut self, caller: caller, from: address, amount: uint256) -> Result<bool> {111		let caller = T::CrossAccountId::from_eth(caller);112		let from = T::CrossAccountId::from_eth(from);113		let amount = amount.try_into().map_err(|_| "amount overflow")?;114115		<Pallet<T>>::burn_from(self, &caller, &from, amount).map_err(dispatch_to_evm::<T>)?;116		Ok(true)117	}118}119120#[solidity_interface(name = "UniqueFungible", is(ERC20))]121impl<T: Config> FungibleHandle<T> {}122123generate_stubgen!(gen_impl, UniqueFungibleCall<()>, true);124generate_stubgen!(gen_iface, UniqueFungibleCall<()>, false);125126impl<T: Config> CommonEvmHandler for FungibleHandle<T> {127	const CODE: &'static [u8] = include_bytes!("./stubs/UniqueFungible.raw");128129	fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileResult> {130		call::<T, UniqueFungibleCall<T>, _>(*source, self, value, input)131	}132}