difftreelog
feat impl balance_of_cross
in: master
5 files changed
pallets/balances-adapter/src/erc.rsdiffbeforeafterboth1use 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 }61 fn balance_of(&self, owner: Address) -> Result<U256> {62 // self.consume_store_reads(1)?;63 let owner = T::CrossAccountId::from_eth(owner);64 let balance = <T as Config>::Currency::free_balance(owner.as_sub());65 Ok(balance.into())66 }6768 fn decimals(&self) -> Result<u8> {69 Ok(T::Decimals::get())70 }7172 fn name(&self) -> Result<String> {73 Ok(T::Name::get())74 }7576 fn symbol(&self) -> Result<String> {77 Ok(T::Symbol::get())78 }7980 fn total_supply(&self) -> Result<U256> {81 // self.consume_store_reads(1)?;82 let total = <T as Config>::Currency::total_issuance();83 Ok(total.into())84 }8586 // #[weight(<SelfWeightOf<T>>::transfer())]87 fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {88 let caller = T::CrossAccountId::from_eth(caller);89 let to = T::CrossAccountId::from_eth(to);90 let amount = amount.try_into().map_err(|_| "amount overflow")?;91 // let budget = self92 // .recorder93 // .weight_calls_budget(<StructureWeight<T>>::find_parent());9495 // <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;96 <T as Config>::Currency::transfer(97 caller.as_sub(),98 to.as_sub(),99 amount,100 ExistenceRequirement::KeepAlive,101 )102 .map_err(dispatch_to_evm::<T>);103 Ok(true)104 }105106 // #[weight(<SelfWeightOf<T>>::transfer_from())]107 fn transfer_from(108 &mut self,109 caller: Caller,110 from: Address,111 to: Address,112 amount: U256,113 ) -> Result<bool> {114 let caller = T::CrossAccountId::from_eth(caller);115 let from = T::CrossAccountId::from_eth(from);116 let to = T::CrossAccountId::from_eth(to);117 let amount = amount.try_into().map_err(|_| "amount overflow")?;118119 if (from != to) {120 return Err("no permission".into());121 }122 // let budget = self123 // .recorder124 // .weight_calls_budget(<StructureWeight<T>>::find_parent());125126 // <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)127 // .map_err(dispatch_to_evm::<T>)?;128 <T as Config>::Currency::transfer(129 caller.as_sub(),130 to.as_sub(),131 amount,132 ExistenceRequirement::KeepAlive,133 )134 .map_err(dispatch_to_evm::<T>);135 Ok(true)136 }137}138139#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]140impl<T: Config> NativeFungibleHandle<T>141where142 T::AccountId: From<[u8; 32]>,143{144 // #[weight(<SelfWeightOf<T>>::transfer())]145 fn transfer_cross(&mut self, caller: Caller, to: CrossAddress, amount: U256) -> Result<bool> {146 let caller = T::CrossAccountId::from_eth(caller);147 let to = to.into_sub_cross_account::<T>()?;148 let amount = amount.try_into().map_err(|_| "amount overflow")?;149 // let budget = self150 // .recorder151 // .weight_calls_budget(<StructureWeight<T>>::find_parent());152153 // <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;154 <T as Config>::Currency::transfer(155 caller.as_sub(),156 to.as_sub(),157 amount,158 ExistenceRequirement::KeepAlive,159 )160 .map_err(dispatch_to_evm::<T>);161 Ok(true)162 }163164 // #[weight(<SelfWeightOf<T>>::transfer_from())]165 fn transfer_from_cross(166 &mut self,167 caller: Caller,168 from: CrossAddress,169 to: CrossAddress,170 amount: U256,171 ) -> Result<bool> {172 let caller = T::CrossAccountId::from_eth(caller);173 let from = from.into_sub_cross_account::<T>()?;174 let to = to.into_sub_cross_account::<T>()?;175 let amount = amount.try_into().map_err(|_| "amount overflow")?;176177 if (from != to) {178 return Err("no permission".into());179 }180181 // let budget = self182 // .recorder183 // .weight_calls_budget(<StructureWeight<T>>::find_parent());184185 // <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)186 // .map_err(dispatch_to_evm::<T>)?;187 <T as Config>::Currency::transfer(188 caller.as_sub(),189 to.as_sub(),190 amount,191 ExistenceRequirement::KeepAlive,192 )193 .map_err(dispatch_to_evm::<T>);194 Ok(true)195 }196}197198#[solidity_interface(199 name = UniqueNativeFungible,200 is(ERC20, ERC20UniqueExtensions),201 enum(derive(PreDispatch))202)]203impl<T: Config> NativeFungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}204205generate_stubgen!(gen_impl, UniqueNativeFungibleCall<()>, true);206generate_stubgen!(gen_iface, UniqueNativeFungibleCall<()>, false);207208impl<T: Config> CommonEvmHandler for NativeFungibleHandle<T>209where210 T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,211{212 const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNativeFungible.raw");213214 fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {215 call::<T, UniqueNativeFungibleCall<T>, _, _>(handle, self)216 }217}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}pallets/balances-adapter/src/stubs/UniqueNativeFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/balances-adapter/src/stubs/UniqueNativeFungible.soldiffbeforeafterboth--- a/pallets/balances-adapter/src/stubs/UniqueNativeFungible.sol
+++ b/pallets/balances-adapter/src/stubs/UniqueNativeFungible.sol
@@ -17,8 +17,17 @@
}
}
-/// @dev the ERC-165 identifier for this interface is 0xff15c6f4
+/// @dev the ERC-165 identifier for this interface is 0x1313556c
contract ERC20UniqueExtensions is Dummy, ERC165 {
+ /// @dev EVM selector for this function is: 0xec069398,
+ /// or in textual repr: balanceOfCross((address,uint256))
+ function balanceOfCross(CrossAddress memory owner) public view returns (uint256) {
+ require(false, stub_error);
+ owner;
+ dummy;
+ return 0;
+ }
+
/// @dev EVM selector for this function is: 0x2ada85ff,
/// or in textual repr: transferCross((address,uint256),uint256)
function transferCross(CrossAddress memory to, uint256 amount) public returns (bool) {
tests/src/eth/abi/nativeFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/nativeFungible.json
+++ b/tests/src/eth/abi/nativeFungible.json
@@ -79,6 +79,23 @@
"type": "function"
},
{
+ "inputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "eth", "type": "address" },
+ { "internalType": "uint256", "name": "sub", "type": "uint256" }
+ ],
+ "internalType": "struct CrossAddress",
+ "name": "owner",
+ "type": "tuple"
+ }
+ ],
+ "name": "balanceOfCross",
+ "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
"inputs": [],
"name": "decimals",
"outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],
tests/src/eth/api/UniqueNativeFungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNativeFungible.sol
+++ b/tests/src/eth/api/UniqueNativeFungible.sol
@@ -12,8 +12,12 @@
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
-/// @dev the ERC-165 identifier for this interface is 0xff15c6f4
+/// @dev the ERC-165 identifier for this interface is 0x1313556c
interface ERC20UniqueExtensions is Dummy, ERC165 {
+ /// @dev EVM selector for this function is: 0xec069398,
+ /// or in textual repr: balanceOfCross((address,uint256))
+ function balanceOfCross(CrossAddress memory owner) external view returns (uint256);
+
/// @dev EVM selector for this function is: 0x2ada85ff,
/// or in textual repr: transferCross((address,uint256),uint256)
function transferCross(CrossAddress memory to, uint256 amount) external returns (bool);