difftreelog
feat impl transfer, transer_from, transfer_cross, transfer_from_cross,
in: master
6 files changed
pallets/balances-adapter/src/erc.rsdiffbeforeafterboth--- a/pallets/balances-adapter/src/erc.rs
+++ b/pallets/balances-adapter/src/erc.rs
@@ -1,7 +1,10 @@
use crate::Config;
use evm_coder::{abi::AbiType, AbiCoder, ToLog, generate_stubgen, solidity_interface, types::*};
-use frame_support::traits::Currency;
-use pallet_common::erc::{CommonEvmHandler, CrossAccountId, PrecompileHandle, PrecompileResult};
+use frame_support::traits::{Currency, ExistenceRequirement};
+use pallet_common::{
+ erc::{CommonEvmHandler, CrossAccountId, PrecompileHandle, PrecompileResult},
+ eth::CrossAddress,
+};
use pallet_evm_coder_substrate::{
call, dispatch_to_evm,
execution::{PreDispatch, Result},
@@ -82,16 +85,22 @@
// #[weight(<SelfWeightOf<T>>::transfer())]
fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {
- // let caller = T::CrossAccountId::from_eth(caller);
- // let to = T::CrossAccountId::from_eth(to);
- // let amount = amount.try_into().map_err(|_| "amount overflow")?;
+ let caller = T::CrossAccountId::from_eth(caller);
+ let to = T::CrossAccountId::from_eth(to);
+ let amount = amount.try_into().map_err(|_| "amount overflow")?;
// let budget = self
// .recorder
// .weight_calls_budget(<StructureWeight<T>>::find_parent());
// <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;
- // Ok(true)
- todo!()
+ <T as Config>::Currency::transfer(
+ caller.as_sub(),
+ to.as_sub(),
+ amount,
+ ExistenceRequirement::KeepAlive,
+ )
+ .map_err(dispatch_to_evm::<T>);
+ Ok(true)
}
// #[weight(<SelfWeightOf<T>>::transfer_from())]
@@ -102,24 +111,93 @@
to: Address,
amount: U256,
) -> Result<bool> {
- // let caller = T::CrossAccountId::from_eth(caller);
- // let from = T::CrossAccountId::from_eth(from);
- // let to = T::CrossAccountId::from_eth(to);
- // let amount = amount.try_into().map_err(|_| "amount overflow")?;
+ let caller = T::CrossAccountId::from_eth(caller);
+ let from = T::CrossAccountId::from_eth(from);
+ let to = T::CrossAccountId::from_eth(to);
+ let amount = amount.try_into().map_err(|_| "amount overflow")?;
+
+ if (from != to) {
+ return Err("no permission".into());
+ }
+ // let budget = self
+ // .recorder
+ // .weight_calls_budget(<StructureWeight<T>>::find_parent());
+
+ // <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)
+ // .map_err(dispatch_to_evm::<T>)?;
+ <T as Config>::Currency::transfer(
+ caller.as_sub(),
+ to.as_sub(),
+ amount,
+ ExistenceRequirement::KeepAlive,
+ )
+ .map_err(dispatch_to_evm::<T>);
+ Ok(true)
+ }
+}
+
+#[solidity_interface(name = ERC20UniqueExtensions, enum(derive(PreDispatch)), enum_attr(weight))]
+impl<T: Config> NativeFungibleHandle<T>
+where
+ T::AccountId: From<[u8; 32]>,
+{
+ // #[weight(<SelfWeightOf<T>>::transfer())]
+ fn transfer_cross(&mut self, caller: Caller, to: CrossAddress, amount: U256) -> Result<bool> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ let to = to.into_sub_cross_account::<T>()?;
+ let amount = amount.try_into().map_err(|_| "amount overflow")?;
+ // let budget = self
+ // .recorder
+ // .weight_calls_budget(<StructureWeight<T>>::find_parent());
+
+ // <Pallet<T>>::transfer(self, &caller, &to, amount, &budget).map_err(|_| "transfer error")?;
+ <T as Config>::Currency::transfer(
+ caller.as_sub(),
+ to.as_sub(),
+ amount,
+ ExistenceRequirement::KeepAlive,
+ )
+ .map_err(dispatch_to_evm::<T>);
+ Ok(true)
+ }
+
+ // #[weight(<SelfWeightOf<T>>::transfer_from())]
+ fn transfer_from_cross(
+ &mut self,
+ caller: Caller,
+ from: CrossAddress,
+ to: CrossAddress,
+ amount: U256,
+ ) -> Result<bool> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ let from = from.into_sub_cross_account::<T>()?;
+ let to = to.into_sub_cross_account::<T>()?;
+ let amount = amount.try_into().map_err(|_| "amount overflow")?;
+
+ if (from != to) {
+ return Err("no permission".into());
+ }
+
// let budget = self
// .recorder
// .weight_calls_budget(<StructureWeight<T>>::find_parent());
// <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)
// .map_err(dispatch_to_evm::<T>)?;
- // Ok(true)
- todo!()
+ <T as Config>::Currency::transfer(
+ caller.as_sub(),
+ to.as_sub(),
+ amount,
+ ExistenceRequirement::KeepAlive,
+ )
+ .map_err(dispatch_to_evm::<T>);
+ Ok(true)
}
}
#[solidity_interface(
name = UniqueNativeFungible,
- is(ERC20),
+ is(ERC20, ERC20UniqueExtensions),
enum(derive(PreDispatch))
)]
impl<T: Config> NativeFungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}
pallets/balances-adapter/src/lib.rsdiffbeforeafterboth--- a/pallets/balances-adapter/src/lib.rs
+++ b/pallets/balances-adapter/src/lib.rs
@@ -17,7 +17,7 @@
Self::AccountId,
Balance = Self::CurrencyBalance,
>;
- type CurrencyBalance: Into<U256>;
+ type CurrencyBalance: Into<U256> + TryFrom<U256>;
type Decimals: Get<u8>;
type Name: Get<String>;
pallets/balances-adapter/src/stubs/UniqueNativeFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/balances-adapter/src/stubs/UniqueNativeFungible.soldiffbeforeafterboth1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7contract Dummy {8 uint8 dummy;9 string stub_error = "this contract is implemented in native";10}1112contract ERC165 is Dummy {13 function supportsInterface(bytes4 interfaceID) external view returns (bool) {14 require(false, stub_error);15 interfaceID;16 return true;17 }18}1920/// @dev inlined interface21contract ERC20Events {22 event Transfer(address indexed from, address indexed to, uint256 value);23 event Approval(address indexed owner, address indexed spender, uint256 value);24}2526/// @dev the ERC-165 identifier for this interface is 0x942e8b2227contract ERC20 is Dummy, ERC165, ERC20Events {28 /// @dev EVM selector for this function is: 0x06fdde03,29 /// or in textual repr: name()30 function name() public view returns (string memory) {31 require(false, stub_error);32 dummy;33 return "";34 }3536 /// @dev EVM selector for this function is: 0x95d89b41,37 /// or in textual repr: symbol()38 function symbol() public view returns (string memory) {39 require(false, stub_error);40 dummy;41 return "";42 }4344 /// @dev EVM selector for this function is: 0x18160ddd,45 /// or in textual repr: totalSupply()46 function totalSupply() public view returns (uint256) {47 require(false, stub_error);48 dummy;49 return 0;50 }5152 /// @dev EVM selector for this function is: 0x313ce567,53 /// or in textual repr: decimals()54 function decimals() public view returns (uint8) {55 require(false, stub_error);56 dummy;57 return 0;58 }5960 /// @dev EVM selector for this function is: 0x70a08231,61 /// or in textual repr: balanceOf(address)62 function balanceOf(address owner) public view returns (uint256) {63 require(false, stub_error);64 owner;65 dummy;66 return 0;67 }6869 /// @dev EVM selector for this function is: 0xa9059cbb,70 /// or in textual repr: transfer(address,uint256)71 function transfer(address to, uint256 amount) public returns (bool) {72 require(false, stub_error);73 to;74 amount;75 dummy = 0;76 return false;77 }7879 /// @dev EVM selector for this function is: 0x23b872dd,80 /// or in textual repr: transferFrom(address,address,uint256)81 function transferFrom(82 address from,83 address to,84 uint256 amount85 ) public returns (bool) {86 require(false, stub_error);87 from;88 to;89 amount;90 dummy = 0;91 return false;92 }9394 /// @dev EVM selector for this function is: 0x095ea7b3,95 /// or in textual repr: approve(address,uint256)96 function approve(address spender, uint256 amount) public returns (bool) {97 require(false, stub_error);98 spender;99 amount;100 dummy = 0;101 return false;102 }103104 /// @dev EVM selector for this function is: 0xdd62ed3e,105 /// or in textual repr: allowance(address,address)106 function allowance(address owner, address spender) public view returns (uint256) {107 require(false, stub_error);108 owner;109 spender;110 dummy;111 return 0;112 }113}114115contract UniqueNativeFungible is Dummy, ERC165, ERC20 {}1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7contract Dummy {8 uint8 dummy;9 string stub_error = "this contract is implemented in native";10}1112contract ERC165 is Dummy {13 function supportsInterface(bytes4 interfaceID) external view returns (bool) {14 require(false, stub_error);15 interfaceID;16 return true;17 }18}1920/// @dev the ERC-165 identifier for this interface is 0xff15c6f421contract ERC20UniqueExtensions is Dummy, ERC165 {22 /// @dev EVM selector for this function is: 0x2ada85ff,23 /// or in textual repr: transferCross((address,uint256),uint256)24 function transferCross(CrossAddress memory to, uint256 amount) public returns (bool) {25 require(false, stub_error);26 to;27 amount;28 dummy = 0;29 return false;30 }3132 /// @dev EVM selector for this function is: 0xd5cf430b,33 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)34 function transferFromCross(35 CrossAddress memory from,36 CrossAddress memory to,37 uint256 amount38 ) public returns (bool) {39 require(false, stub_error);40 from;41 to;42 amount;43 dummy = 0;44 return false;45 }46}4748/// Cross account struct49struct CrossAddress {50 address eth;51 uint256 sub;52}5354/// @dev inlined interface55contract ERC20Events {56 event Transfer(address indexed from, address indexed to, uint256 value);57 event Approval(address indexed owner, address indexed spender, uint256 value);58}5960/// @dev the ERC-165 identifier for this interface is 0x942e8b2261contract ERC20 is Dummy, ERC165, ERC20Events {62 /// @dev EVM selector for this function is: 0xdd62ed3e,63 /// or in textual repr: allowance(address,address)64 function allowance(address owner, address spender) public view returns (uint256) {65 require(false, stub_error);66 owner;67 spender;68 dummy;69 return 0;70 }7172 /// @dev EVM selector for this function is: 0x095ea7b3,73 /// or in textual repr: approve(address,uint256)74 function approve(address spender, uint256 amount) public returns (bool) {75 require(false, stub_error);76 spender;77 amount;78 dummy = 0;79 return false;80 }8182 /// @dev EVM selector for this function is: 0x70a08231,83 /// or in textual repr: balanceOf(address)84 function balanceOf(address owner) public view returns (uint256) {85 require(false, stub_error);86 owner;87 dummy;88 return 0;89 }9091 /// @dev EVM selector for this function is: 0x313ce567,92 /// or in textual repr: decimals()93 function decimals() public view returns (uint8) {94 require(false, stub_error);95 dummy;96 return 0;97 }9899 /// @dev EVM selector for this function is: 0x06fdde03,100 /// or in textual repr: name()101 function name() public view returns (string memory) {102 require(false, stub_error);103 dummy;104 return "";105 }106107 /// @dev EVM selector for this function is: 0x95d89b41,108 /// or in textual repr: symbol()109 function symbol() public view returns (string memory) {110 require(false, stub_error);111 dummy;112 return "";113 }114115 /// @dev EVM selector for this function is: 0x18160ddd,116 /// or in textual repr: totalSupply()117 function totalSupply() public view returns (uint256) {118 require(false, stub_error);119 dummy;120 return 0;121 }122123 /// @dev EVM selector for this function is: 0xa9059cbb,124 /// or in textual repr: transfer(address,uint256)125 function transfer(address to, uint256 amount) public returns (bool) {126 require(false, stub_error);127 to;128 amount;129 dummy = 0;130 return false;131 }132133 /// @dev EVM selector for this function is: 0x23b872dd,134 /// or in textual repr: transferFrom(address,address,uint256)135 function transferFrom(136 address from,137 address to,138 uint256 amount139 ) public returns (bool) {140 require(false, stub_error);141 from;142 to;143 amount;144 dummy = 0;145 return false;146 }147}148149contract UniqueNativeFungible is Dummy, ERC165, ERC20, ERC20UniqueExtensions {}tests/src/eth/abi/nativeFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/nativeFungible.json
+++ b/tests/src/eth/abi/nativeFungible.json
@@ -127,6 +127,24 @@
},
{
"inputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "eth", "type": "address" },
+ { "internalType": "uint256", "name": "sub", "type": "uint256" }
+ ],
+ "internalType": "struct CrossAddress",
+ "name": "to",
+ "type": "tuple"
+ },
+ { "internalType": "uint256", "name": "amount", "type": "uint256" }
+ ],
+ "name": "transferCross",
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
{ "internalType": "address", "name": "from", "type": "address" },
{ "internalType": "address", "name": "to", "type": "address" },
{ "internalType": "uint256", "name": "amount", "type": "uint256" }
@@ -135,5 +153,32 @@
"outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
"stateMutability": "nonpayable",
"type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ { "internalType": "address", "name": "eth", "type": "address" },
+ { "internalType": "uint256", "name": "sub", "type": "uint256" }
+ ],
+ "internalType": "struct CrossAddress",
+ "name": "from",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ { "internalType": "address", "name": "eth", "type": "address" },
+ { "internalType": "uint256", "name": "sub", "type": "uint256" }
+ ],
+ "internalType": "struct CrossAddress",
+ "name": "to",
+ "type": "tuple"
+ },
+ { "internalType": "uint256", "name": "amount", "type": "uint256" }
+ ],
+ "name": "transferFromCross",
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
+ "stateMutability": "nonpayable",
+ "type": "function"
}
]
tests/src/eth/api/UniqueNativeFungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNativeFungible.sol
+++ b/tests/src/eth/api/UniqueNativeFungible.sol
@@ -12,6 +12,27 @@
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
+/// @dev the ERC-165 identifier for this interface is 0xff15c6f4
+interface ERC20UniqueExtensions is Dummy, ERC165 {
+ /// @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);
+
+ /// @dev EVM selector for this function is: 0xd5cf430b,
+ /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
+ function transferFromCross(
+ CrossAddress memory from,
+ CrossAddress memory to,
+ uint256 amount
+ ) external returns (bool);
+}
+
+/// Cross account struct
+struct CrossAddress {
+ address eth;
+ uint256 sub;
+}
+
/// @dev inlined interface
interface ERC20Events {
event Transfer(address indexed from, address indexed to, uint256 value);
@@ -20,6 +41,22 @@
/// @dev the ERC-165 identifier for this interface is 0x942e8b22
interface ERC20 is Dummy, ERC165, ERC20Events {
+ /// @dev EVM selector for this function is: 0xdd62ed3e,
+ /// or in textual repr: allowance(address,address)
+ function allowance(address owner, address spender) external view returns (uint256);
+
+ /// @dev EVM selector for this function is: 0x095ea7b3,
+ /// or in textual repr: approve(address,uint256)
+ function approve(address spender, uint256 amount) external returns (bool);
+
+ /// @dev EVM selector for this function is: 0x70a08231,
+ /// or in textual repr: balanceOf(address)
+ function balanceOf(address owner) external view returns (uint256);
+
+ /// @dev EVM selector for this function is: 0x313ce567,
+ /// or in textual repr: decimals()
+ function decimals() external view returns (uint8);
+
/// @dev EVM selector for this function is: 0x06fdde03,
/// or in textual repr: name()
function name() external view returns (string memory);
@@ -32,14 +69,6 @@
/// or in textual repr: totalSupply()
function totalSupply() external view returns (uint256);
- /// @dev EVM selector for this function is: 0x313ce567,
- /// or in textual repr: decimals()
- function decimals() external view returns (uint8);
-
- /// @dev EVM selector for this function is: 0x70a08231,
- /// or in textual repr: balanceOf(address)
- function balanceOf(address owner) external view returns (uint256);
-
/// @dev EVM selector for this function is: 0xa9059cbb,
/// or in textual repr: transfer(address,uint256)
function transfer(address to, uint256 amount) external returns (bool);
@@ -51,14 +80,6 @@
address to,
uint256 amount
) external returns (bool);
-
- /// @dev EVM selector for this function is: 0x095ea7b3,
- /// or in textual repr: approve(address,uint256)
- function approve(address spender, uint256 amount) external returns (bool);
-
- /// @dev EVM selector for this function is: 0xdd62ed3e,
- /// or in textual repr: allowance(address,address)
- function allowance(address owner, address spender) external view returns (uint256);
}
-interface UniqueNativeFungible is Dummy, ERC165, ERC20 {}
+interface UniqueNativeFungible is Dummy, ERC165, ERC20, ERC20UniqueExtensions {}