From d161923f05d5bd279150df2957fc8803a749c4cb Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Wed, 18 Jan 2023 09:41:25 +0000 Subject: [PATCH] Merge pull request #825 from UniqueNetwork/feature/evm_coder_types_refactor Feature/evm_coder_types_refactor --- --- a/Cargo.lock +++ b/Cargo.lock @@ -2330,7 +2330,6 @@ "hex", "hex-literal", "impl-trait-for-tuples", - "pallet-evm", "primitive-types 0.12.1", "sha3-const", "similar-asserts", --- a/crates/evm-coder/Cargo.toml +++ b/crates/evm-coder/Cargo.toml @@ -19,8 +19,6 @@ # We have tuple-heavy code in solidity.rs impl-trait-for-tuples = "0.2.2" -pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.36" } - [dev-dependencies] # We want to assert some large binary blobs equality in tests hex = "0.4.3" --- a/crates/evm-coder/procedural/src/solidity_interface.rs +++ b/crates/evm-coder/procedural/src/solidity_interface.rs @@ -347,14 +347,14 @@ fn is_value(&self) -> bool { if let Ok(ident) = self.plain() { - return ident == "value"; + return ident == "Value"; } false } fn is_caller(&self) -> bool { if let Ok(ident) = self.plain() { - return ident == "caller"; + return ident == "Caller"; } false } @@ -610,7 +610,7 @@ let custom_signature = self.expand_custom_signature(); quote! { const #screaming_name_signature: ::evm_coder::custom_signature::SignatureUnit = #custom_signature; - const #screaming_name: ::evm_coder::types::bytes4 = { + const #screaming_name: ::evm_coder::types::Bytes4 = { let mut sum = ::evm_coder::sha3_const::Keccak256::new(); let mut pos = 0; while pos < Self::#screaming_name_signature.len { @@ -974,7 +974,7 @@ #consts )* /// Return this call ERC165 selector - pub const fn interface_id() -> ::evm_coder::types::bytes4 { + pub const fn interface_id() -> ::evm_coder::types::Bytes4 { let mut interface_id = 0; #(#interface_id)* #(#inline_interface_id)* @@ -999,7 +999,7 @@ )*), }; - let mut out = ::evm_coder::types::string::new(); + let mut out = ::evm_coder::types::String::new(); if #solidity_name.starts_with("Inline") { out.push_str("/// @dev inlined interface\n"); } @@ -1019,7 +1019,7 @@ } } impl #gen_ref ::evm_coder::Call for #call_name #gen_ref { - fn parse(method_id: ::evm_coder::types::bytes4, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result> { + fn parse(method_id: ::evm_coder::types::Bytes4, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result> { use ::evm_coder::abi::AbiRead; match method_id { ::evm_coder::ERC165Call::INTERFACE_ID => return Ok( @@ -1041,7 +1041,7 @@ #gen_where { /// Is this contract implements specified ERC165 selector - pub fn supports_interface(this: &#name, interface_id: ::evm_coder::types::bytes4) -> bool { + pub fn supports_interface(this: &#name, interface_id: ::evm_coder::types::Bytes4) -> bool { interface_id != u32::to_be_bytes(0xffffff) && ( interface_id == ::evm_coder::ERC165Call::INTERFACE_ID || interface_id == Self::interface_id() --- a/crates/evm-coder/procedural/src/to_log.rs +++ b/crates/evm-coder/procedural/src/to_log.rs @@ -137,7 +137,7 @@ Self::#name {#( #fields, )*} => { - topics.push(topic::from(Self::#name_screaming)); + topics.push(::evm_coder::types::Topic::from(Self::#name_screaming)); #( topics.push(#indexed.to_topic()); )* @@ -222,7 +222,7 @@ #solidity_functions, )*), }; - let mut out = string::new(); + let mut out = ::evm_coder::types::String::new(); out.push_str("/// @dev inlined interface\n"); let _ = interface.format(is_impl, &mut out, tc); tc.collect(out); @@ -231,7 +231,7 @@ #[automatically_derived] impl ::evm_coder::events::ToLog for #name { - fn to_log(&self, contract: address) -> ::ethereum::Log { + fn to_log(&self, contract: Address) -> ::ethereum::Log { use ::evm_coder::events::ToTopic; use ::evm_coder::abi::AbiWrite; let mut writer = ::evm_coder::abi::AbiWriter::new(); --- a/crates/evm-coder/src/abi/impls.rs +++ b/crates/evm-coder/src/abi/impls.rs @@ -63,27 +63,27 @@ impl_abi!(u128, uint128, false); impl_abi!(U256, uint256, false); impl_abi!(H160, address, false); -impl_abi!(string, string, true); +impl_abi!(String, string, true); impl_abi_writeable!(&str, string); -impl_abi_type!(bytes, bytes, true); +impl_abi_type!(Bytes, bytes, true); -impl AbiRead for bytes { - fn abi_read(reader: &mut AbiReader) -> Result { - Ok(bytes(reader.bytes()?)) +impl AbiRead for Bytes { + fn abi_read(reader: &mut AbiReader) -> Result { + Ok(Bytes(reader.bytes()?)) } } -impl AbiWrite for bytes { +impl AbiWrite for Bytes { fn abi_write(&self, writer: &mut AbiWriter) { writer.bytes(self.0.as_slice()) } } -impl_abi_type!(bytes4, bytes4, false); -impl AbiRead for bytes4 { - fn abi_read(reader: &mut AbiReader) -> Result { +impl_abi_type!(Bytes4, bytes4, false); +impl AbiRead for Bytes4 { + fn abi_read(reader: &mut AbiReader) -> Result { reader.bytes4() } } --- a/crates/evm-coder/src/abi/mod.rs +++ b/crates/evm-coder/src/abi/mod.rs @@ -54,7 +54,7 @@ } } /// Start reading RLP buffer, parsing first 4 bytes as selector - pub fn new_call(buf: &'i [u8]) -> Result<(bytes4, Self)> { + pub fn new_call(buf: &'i [u8]) -> Result<(Bytes4, Self)> { if buf.len() < 4 { return Err(Error::Error(ExitError::OutOfOffset)); } @@ -148,8 +148,8 @@ } /// Read [`string`] at current position, then advance - pub fn string(&mut self) -> Result { - string::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange)) + pub fn string(&mut self) -> Result { + String::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange)) } /// Read [`u8`] at current position, then advance --- a/crates/evm-coder/src/abi/test.rs +++ b/crates/evm-coder/src/abi/test.rs @@ -39,22 +39,22 @@ #[test] fn encode_decode_uint8() { - test_impl_uint!(uint8); + test_impl_uint!(u8); } #[test] fn encode_decode_uint32() { - test_impl_uint!(uint32); + test_impl_uint!(u32); } #[test] fn encode_decode_uint128() { - test_impl_uint!(uint128); + test_impl_uint!(u128); } #[test] fn encode_decode_uint256() { - test_impl::( + test_impl::( 0xdeadbeef, U256([255, 0, 0, 0]), &hex!( @@ -101,7 +101,7 @@ #[test] fn encode_decode_vec_tuple_address_uint256() { - test_impl::>( + test_impl::>( 0x1ACF2D55, vec![ ( @@ -138,7 +138,7 @@ #[test] fn encode_decode_vec_tuple_uint256_string() { - test_impl::>( + test_impl::>( 0xdeadbeef, vec![ (1.into(), "Test URI 0".to_string()), @@ -261,7 +261,7 @@ let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap(); assert_eq!(call, u32::to_be_bytes(decoded_data.0)); let address = decoder.address().unwrap(); - let data = >::abi_read(&mut decoder).unwrap(); + let data = >::abi_read(&mut decoder).unwrap(); assert_eq!(data, decoded_data.1); let mut writer = AbiWriter::new_call(decoded_data.0); @@ -273,12 +273,12 @@ #[test] fn encode_decode_vec_tuple_string_bytes() { - test_impl::>( + test_impl::>( 0xdeadbeef, vec![ ( "Test URI 0".to_string(), - bytes(vec![ + Bytes(vec![ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, @@ -287,14 +287,14 @@ ), ( "Test URI 1".to_string(), - bytes(vec![ + Bytes(vec![ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, ]), ), - ("Test URI 2".to_string(), bytes(vec![0x33, 0x33])), + ("Test URI 2".to_string(), Bytes(vec![0x33, 0x33])), ], &hex!( " @@ -337,10 +337,10 @@ // #[ignore = "reason"] fn encode_decode_tuple0_tuple1_uint8_tuple1_string_bytes_tuple1_uint8_bytes() { let int = 0xff; - let by = bytes(vec![0x11, 0x22, 0x33]); + let by = Bytes(vec![0x11, 0x22, 0x33]); let string = "some string".to_string(); - test_impl::<((u8,), (String, bytes), (u8, bytes))>( + test_impl::<((u8,), (String, Bytes), (u8, Bytes))>( 0xdeadbeef, ((int,), (string.clone(), by.clone()), (int, by)), &hex!( @@ -485,9 +485,9 @@ #[test] fn encode_decode_tuple0_tuple1_string_bytes() { - test_impl::<((String, bytes),)>( + test_impl::<((String, Bytes),)>( 0xdeadbeef, - (("some string".to_string(), bytes(vec![1, 2, 3])),), + (("some string".to_string(), Bytes(vec![1, 2, 3])),), &hex!( " deadbeef --- a/crates/evm-coder/src/events.rs +++ b/crates/evm-coder/src/events.rs @@ -15,7 +15,7 @@ // along with Unique Network. If not, see . use ethereum::Log; -use primitive_types::{H160, H256}; +use primitive_types::{H160, H256, U256}; use crate::types::*; @@ -45,7 +45,7 @@ } } -impl ToTopic for uint256 { +impl ToTopic for U256 { fn to_topic(&self) -> H256 { let mut out = [0u8; 32]; self.to_big_endian(&mut out); @@ -53,7 +53,7 @@ } } -impl ToTopic for address { +impl ToTopic for Address { fn to_topic(&self) -> H256 { let mut out = [0u8; 32]; out[12..32].copy_from_slice(&self.0); @@ -61,7 +61,7 @@ } } -impl ToTopic for uint32 { +impl ToTopic for u32 { fn to_topic(&self) -> H256 { let mut out = [0u8; 32]; out[28..32].copy_from_slice(&self.to_be_bytes()); --- a/crates/evm-coder/src/lib.rs +++ b/crates/evm-coder/src/lib.rs @@ -131,33 +131,23 @@ use alloc::{vec::Vec}; use primitive_types::{U256, H160, H256}; - pub type address = H160; - pub type uint8 = u8; - pub type uint16 = u16; - pub type uint32 = u32; - pub type uint64 = u64; - pub type uint128 = u128; - pub type uint256 = U256; - pub type bytes4 = [u8; 4]; - pub type topic = H256; + pub type Address = H160; + pub type Bytes4 = [u8; 4]; + pub type Topic = H256; #[cfg(not(feature = "std"))] - pub type string = ::alloc::string::String; + pub type String = ::alloc::string::String; #[cfg(feature = "std")] - pub type string = ::std::string::String; + pub type String = ::std::string::String; #[derive(Default, Debug, PartialEq, Eq, Clone)] - pub struct bytes(pub Vec); - - /// Solidity doesn't have `void` type, however we have special implementation - /// for empty tuple return type - pub type void = (); + pub struct Bytes(pub Vec); //#region Special types /// Makes function payable - pub type value = U256; + pub type Value = U256; /// Makes function caller-sensitive - pub type caller = address; + pub type Caller = Address; //#endregion /// Ethereum typed call message, similar to solidity @@ -172,20 +162,20 @@ pub value: U256, } - impl From> for bytes { + impl From> for Bytes { fn from(src: Vec) -> Self { Self(src) } } #[allow(clippy::from_over_into)] - impl Into> for bytes { + impl Into> for Bytes { fn into(self) -> Vec { self.0 } } - impl bytes { + impl Bytes { #[must_use] pub fn len(&self) -> usize { self.0.len() @@ -201,7 +191,7 @@ /// Parseable EVM call, this trait should be implemented with [`solidity_interface`] macro pub trait Call: Sized { /// Parse call buffer into typed call enum - fn parse(selector: types::bytes4, input: &mut AbiReader) -> execution::Result>; + fn parse(selector: types::Bytes4, input: &mut AbiReader) -> execution::Result>; } /// Intended to be used as `#[weight]` output type @@ -237,22 +227,22 @@ /// implements specified interface SupportsInterface { /// Requested interface - interface_id: types::bytes4, + interface_id: types::Bytes4, }, } impl ERC165Call { /// ERC165 selector is provided by standard - pub const INTERFACE_ID: types::bytes4 = u32::to_be_bytes(0x01ffc9a7); + pub const INTERFACE_ID: types::Bytes4 = u32::to_be_bytes(0x01ffc9a7); } impl Call for ERC165Call { - fn parse(selector: types::bytes4, input: &mut AbiReader) -> execution::Result> { + fn parse(selector: types::Bytes4, input: &mut AbiReader) -> execution::Result> { if selector != Self::INTERFACE_ID { return Ok(None); } Ok(Some(Self::SupportsInterface { - interface_id: types::bytes4::abi_read(input)?, + interface_id: types::Bytes4::abi_read(input)?, })) } } --- a/crates/evm-coder/src/solidity/impls.rs +++ b/crates/evm-coder/src/solidity/impls.rs @@ -27,14 +27,14 @@ u64 => "uint64" true = "0", u128 => "uint128" true = "0", U256 => "uint256" true = "0", - bytes4 => "bytes4" true = "bytes4(0)", + Bytes4 => "bytes4" true = "bytes4(0)", H160 => "address" true = "0x0000000000000000000000000000000000000000", - string => "string" false = "\"\"", - bytes => "bytes" false = "hex\"\"", + String => "string" false = "\"\"", + Bytes => "bytes" false = "hex\"\"", bool => "bool" true = "false", } -impl SolidityTypeName for void { +impl SolidityTypeName for () { fn solidity_name(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result { Ok(()) } @@ -72,10 +72,10 @@ macro_rules! impl_tuples { ($($ident:ident)+) => { impl<$($ident: SolidityTypeName + 'static),+> SolidityTupleTy for ($($ident,)+) { - fn fields(tc: &TypeCollector) -> Vec { + fn fields(tc: &TypeCollector) -> Vec { let mut collected = Vec::with_capacity(Self::len()); $({ - let mut out = string::new(); + let mut out = String::new(); $ident::solidity_name(&mut out, tc).expect("no fmt error"); collected.push(out); })*; --- a/crates/evm-coder/src/solidity/mod.rs +++ b/crates/evm-coder/src/solidity/mod.rs @@ -26,7 +26,7 @@ mod impls; #[cfg(not(feature = "std"))] -use alloc::{string::String, vec::Vec, collections::BTreeMap, format}; +use alloc::{vec::Vec, collections::BTreeMap, format}; #[cfg(feature = "std")] use std::collections::BTreeMap; use core::{ @@ -42,16 +42,16 @@ pub struct TypeCollector { /// Code => id /// id ordering is required to perform topo-sort on the resulting data - structs: RefCell>, - anonymous: RefCell, usize>>, - // generic: RefCell>, + structs: RefCell>, + anonymous: RefCell, usize>>, + // generic: RefCell>, id: Cell, } impl TypeCollector { pub fn new() -> Self { Self::default() } - pub fn collect(&self, item: string) { + pub fn collect(&self, item: String) { let id = self.next_id(); self.structs.borrow_mut().insert(item, id); } @@ -84,7 +84,7 @@ pub fn collect_enum(&self) -> String { T::generate_solidity_interface(self) } - pub fn finish(self) -> Vec { + pub fn finish(self) -> Vec { let mut data = self.structs.into_inner().into_iter().collect::>(); data.sort_by_key(|(_, id)| Reverse(*id)); data.into_iter().map(|(code, _)| code).collect() @@ -360,7 +360,7 @@ pub struct SolidityInterface { pub docs: &'static [&'static str], - pub selector: bytes4, + pub selector: Bytes4, pub name: &'static str, pub is: &'static [&'static str], pub functions: F, --- a/crates/evm-coder/tests/abi_derive_generation.rs +++ b/crates/evm-coder/tests/abi_derive_generation.rs @@ -1,6 +1,6 @@ mod test_struct { use evm_coder_procedural::AbiCoder; - use evm_coder::types::bytes; + use evm_coder::types::Bytes; #[test] fn empty_struct() { @@ -27,13 +27,13 @@ #[derive(AbiCoder, PartialEq, Debug)] struct TypeStruct2DynamicParam { _a: String, - _b: bytes, + _b: Bytes, } #[derive(AbiCoder, PartialEq, Debug)] struct TypeStruct2MixedParam { _a: u8, - _b: bytes, + _b: Bytes, } #[derive(AbiCoder, PartialEq, Debug)] @@ -236,10 +236,10 @@ struct TupleStruct2SimpleParam(u8, u32); #[derive(AbiCoder, PartialEq, Debug)] - struct TupleStruct2DynamicParam(String, bytes); + struct TupleStruct2DynamicParam(String, Bytes); #[derive(AbiCoder, PartialEq, Debug)] - struct TupleStruct2MixedParam(u8, bytes); + struct TupleStruct2MixedParam(u8, Bytes); #[derive(AbiCoder, PartialEq, Debug)] struct TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam); @@ -562,8 +562,8 @@ #[test] fn codec_struct_2_dynamic() { let _a: String = "some string".into(); - let _b: bytes = bytes(vec![0x11, 0x22, 0x33]); - test_impl::<(String, bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>( + let _b: Bytes = Bytes(vec![0x11, 0x22, 0x33]); + test_impl::<(String, Bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>( (_a.clone(), _b.clone()), TupleStruct2DynamicParam(_a.clone(), _b.clone()), TypeStruct2DynamicParam { _a, _b }, @@ -573,8 +573,8 @@ #[test] fn codec_struct_2_mixed() { let _a: u8 = 0xff; - let _b: bytes = bytes(vec![0x11, 0x22, 0x33]); - test_impl::<(u8, bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>( + let _b: Bytes = Bytes(vec![0x11, 0x22, 0x33]); + test_impl::<(u8, Bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>( (_a.clone(), _b.clone()), TupleStruct2MixedParam(_a.clone(), _b.clone()), TypeStruct2MixedParam { _a, _b }, @@ -605,9 +605,9 @@ #[test] fn codec_struct_2_derived_dynamic() { let _a = "some string".to_string(); - let _b = bytes(vec![0x11, 0x22, 0x33]); + let _b = Bytes(vec![0x11, 0x22, 0x33]); test_impl::< - ((String,), (String, bytes)), + ((String,), (String, Bytes)), TupleStruct2DerivedDynamicParam, TypeStruct2DerivedDynamicParam, >( @@ -626,10 +626,10 @@ #[test] fn codec_struct_3_derived_mixed() { let int = 0xff; - let by = bytes(vec![0x11, 0x22, 0x33]); + let by = Bytes(vec![0x11, 0x22, 0x33]); let string = "some string".to_string(); test_impl::< - ((u8,), (String, bytes), (u8, bytes)), + ((u8,), (String, Bytes), (u8, Bytes)), TupleStruct3DerivedMixedParam, TypeStruct3DerivedMixedParam, >( --- a/crates/evm-coder/tests/conditional_is.rs +++ b/crates/evm-coder/tests/conditional_is.rs @@ -4,14 +4,14 @@ #[solidity_interface(name = A)] impl Contract { - fn method_a() -> Result { + fn method_a() -> Result<()> { Ok(()) } } #[solidity_interface(name = B)] impl Contract { - fn method_b() -> Result { + fn method_b() -> Result<()> { Ok(()) } } --- a/crates/evm-coder/tests/generics.rs +++ b/crates/evm-coder/tests/generics.rs @@ -16,19 +16,20 @@ use std::marker::PhantomData; use evm_coder::{execution::Result, generate_stubgen, solidity_interface, types::*}; +use primitive_types::U256; pub struct Generic(PhantomData); #[solidity_interface(name = GenericIs)] impl Generic { - fn test_1(&self) -> Result { + fn test_1(&self) -> Result { unreachable!() } } #[solidity_interface(name = Generic, is(GenericIs))] impl> Generic { - fn test_2(&self) -> Result { + fn test_2(&self) -> Result { unreachable!() } } @@ -40,7 +41,7 @@ where T: core::fmt::Debug, { - fn test_3(&self) -> Result { + fn test_3(&self) -> Result { unreachable!() } } --- a/crates/evm-coder/tests/log.rs +++ b/crates/evm-coder/tests/log.rs @@ -17,19 +17,20 @@ #![allow(dead_code)] use evm_coder::{ToLog, types::*}; +use primitive_types::U256; #[derive(ToLog)] enum ERC721Log { Transfer { #[indexed] - from: address, + from: Address, #[indexed] - to: address, - value: uint256, + to: Address, + value: U256, }, Eee { #[indexed] - aaa: address, - bbb: uint256, + aaa: Address, + bbb: U256, }, } --- a/crates/evm-coder/tests/random.rs +++ b/crates/evm-coder/tests/random.rs @@ -19,19 +19,20 @@ use evm_coder::{ abi::AbiType, ToLog, execution::Result, solidity_interface, types::*, solidity, weight, }; +use primitive_types::U256; pub struct Impls; #[solidity_interface(name = OurInterface)] impl Impls { - fn fn_a(&self, _input: uint256) -> Result { + fn fn_a(&self, _input: U256) -> Result { unreachable!() } } #[solidity_interface(name = OurInterface1)] impl Impls { - fn fn_b(&self, _input: uint128) -> Result { + fn fn_b(&self, _input: u128) -> Result { unreachable!() } } @@ -39,12 +40,12 @@ #[derive(ToLog)] enum OurEvents { Event1 { - field1: uint32, + field1: u32, }, Event2 { - field1: uint32, + field1: u32, #[indexed] - field2: uint32, + field2: u32, }, } @@ -56,27 +57,27 @@ )] impl Impls { #[solidity(rename_selector = "fnK")] - fn fn_c(&self, _input: uint32) -> Result { + fn fn_c(&self, _input: u32) -> Result { unreachable!() } - fn fn_d(&self, _value: uint32) -> Result { + fn fn_d(&self, _value: u32) -> Result { unreachable!() } - fn caller_sensitive(&self, _caller: caller) -> Result { + fn caller_sensitive(&self, _caller: Caller) -> Result { unreachable!() } - fn payable(&mut self, _value: value) -> Result { + fn payable(&mut self, _value: Value) -> Result { unreachable!() } #[weight(*_weight)] - fn with_weight(&self, _weight: uint64) -> Result { + fn with_weight(&self, _weight: u64) -> Result<()> { unreachable!() } /// Doccoment example - fn with_doc(&self) -> Result { + fn with_doc(&self) -> Result<()> { unreachable!() } } --- a/crates/evm-coder/tests/solidity_generation.rs +++ b/crates/evm-coder/tests/solidity_generation.rs @@ -15,34 +15,35 @@ // along with Unique Network. If not, see . use evm_coder::{abi::AbiType, execution::Result, generate_stubgen, solidity_interface, types::*}; +use primitive_types::U256; pub struct ERC20; #[solidity_interface(name = ERC20)] impl ERC20 { - fn decimals(&self) -> Result { + fn decimals(&self) -> Result { unreachable!() } /// Get balance of specified owner - fn balance_of(&self, _owner: address) -> Result { + fn balance_of(&self, _owner: Address) -> Result { unreachable!() } - fn transfer(&mut self, _caller: caller, _to: address, _value: uint256) -> Result { + fn transfer(&mut self, _caller: Caller, _to: Address, _value: U256) -> Result { unreachable!() } fn transfer_from( &mut self, - _caller: caller, - _from: address, - _to: address, - _value: uint256, + _caller: Caller, + _from: Address, + _to: Address, + _value: U256, ) -> Result { unreachable!() } - fn approve(&mut self, _caller: caller, _spender: address, _value: uint256) -> Result { + fn approve(&mut self, _caller: Caller, _spender: Address, _value: U256) -> Result { unreachable!() } - fn allowance(&self, _owner: address, _spender: address) -> Result { + fn allowance(&self, _owner: Address, _spender: Address) -> Result { unreachable!() } } --- a/pallets/common/src/erc.rs +++ b/pallets/common/src/erc.rs @@ -26,6 +26,7 @@ }; use pallet_evm_coder_substrate::dispatch_to_evm; use sp_std::{vec, vec::Vec}; +use sp_core::U256; use up_data_structs::{ AccessMode, CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property, SponsoringRateLimit, SponsorshipState, @@ -42,32 +43,32 @@ CollectionCreated { /// Collection owner. #[indexed] - owner: address, + owner: Address, /// Collection ID. #[indexed] - collection_id: address, + collection_id: Address, }, /// The collection has been destroyed. CollectionDestroyed { /// Collection ID. #[indexed] - collection_id: address, + collection_id: Address, }, /// The collection has been changed. CollectionChanged { /// Collection ID. #[indexed] - collection_id: address, + collection_id: Address, }, /// The token has been changed. TokenChanged { /// Collection ID. #[indexed] - collection_id: address, + collection_id: Address, /// Token ID. - token_id: uint256, + token_id: U256, }, } @@ -93,12 +94,7 @@ /// @param value Propery value. #[solidity(hide)] #[weight(>::set_collection_properties(1))] - fn set_collection_property( - &mut self, - caller: caller, - key: string, - value: bytes, - ) -> Result { + fn set_collection_property(&mut self, caller: Caller, key: String, value: Bytes) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let key = >::from(key) .try_into() @@ -115,9 +111,9 @@ #[weight(>::set_collection_properties(properties.len() as u32))] fn set_collection_properties( &mut self, - caller: caller, + caller: Caller, properties: Vec, - ) -> Result { + ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let properties = properties @@ -134,7 +130,7 @@ /// @param key Property key. #[solidity(hide)] #[weight(>::delete_collection_properties(1))] - fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> { + fn delete_collection_property(&mut self, caller: Caller, key: String) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let key = >::from(key) .try_into() @@ -147,7 +143,7 @@ /// /// @param keys Properties keys. #[weight(>::delete_collection_properties(keys.len() as u32))] - fn delete_collection_properties(&mut self, caller: caller, keys: Vec) -> Result<()> { + fn delete_collection_properties(&mut self, caller: Caller, keys: Vec) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let keys = keys .into_iter() @@ -168,7 +164,7 @@ /// /// @param key Property key. /// @return bytes The property corresponding to the key. - fn collection_property(&self, key: string) -> Result { + fn collection_property(&self, key: String) -> Result { let key = >::from(key) .try_into() .map_err(|_| "key too large")?; @@ -176,14 +172,14 @@ let props = CollectionProperties::::get(self.id); let prop = props.get(&key).ok_or("key not found")?; - Ok(bytes(prop.to_vec())) + Ok(Bytes(prop.to_vec())) } /// Get collection properties. /// /// @param keys Properties keys. Empty keys for all propertyes. /// @return Vector of properties key/value pairs. - fn collection_properties(&self, keys: Vec) -> Result> { + fn collection_properties(&self, keys: Vec) -> Result> { let keys = keys .into_iter() .map(|key| { @@ -212,7 +208,7 @@ /// /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract. #[solidity(hide)] - fn set_collection_sponsor(&mut self, caller: caller, sponsor: address) -> Result { + fn set_collection_sponsor(&mut self, caller: Caller, sponsor: Address) -> Result<()> { self.consume_store_reads_and_writes(1, 1)?; let caller = T::CrossAccountId::from_eth(caller); @@ -229,9 +225,9 @@ /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract. fn set_collection_sponsor_cross( &mut self, - caller: caller, + caller: Caller, sponsor: eth::CrossAddress, - ) -> Result { + ) -> Result<()> { self.consume_store_reads_and_writes(1, 1)?; let caller = T::CrossAccountId::from_eth(caller); @@ -252,7 +248,7 @@ /// Collection sponsorship confirmation. /// /// @dev After setting the sponsor for the collection, it must be confirmed with this function. - fn confirm_collection_sponsorship(&mut self, caller: caller) -> Result { + fn confirm_collection_sponsorship(&mut self, caller: Caller) -> Result<()> { self.consume_store_writes(1)?; let caller = T::CrossAccountId::from_eth(caller); @@ -261,7 +257,7 @@ } /// Remove collection sponsor. - fn remove_collection_sponsor(&mut self, caller: caller) -> Result { + fn remove_collection_sponsor(&mut self, caller: Caller) -> Result<()> { self.consume_store_reads_and_writes(1, 1)?; let caller = T::CrossAccountId::from_eth(caller); self.remove_sponsor(&caller).map_err(dispatch_to_evm::) @@ -343,11 +339,7 @@ /// @dev Throws error if limit not found. /// @param limit Some limit. #[solidity(rename_selector = "setCollectionLimit")] - fn set_collection_limit( - &mut self, - caller: caller, - limit: eth::CollectionLimit, - ) -> Result { + fn set_collection_limit(&mut self, caller: Caller, limit: eth::CollectionLimit) -> Result<()> { self.consume_store_reads_and_writes(1, 1)?; if !limit.has_value() { @@ -359,7 +351,7 @@ } /// Get contract address. - fn contract_address(&self) -> Result
{ + fn contract_address(&self) -> Result
{ Ok(crate::eth::collection_id_to_address(self.id)) } @@ -367,9 +359,9 @@ /// @param newAdmin Cross account administrator address. fn add_collection_admin_cross( &mut self, - caller: caller, + caller: Caller, new_admin: eth::CrossAddress, - ) -> Result { + ) -> Result<()> { self.consume_store_reads_and_writes(2, 2)?; let caller = T::CrossAccountId::from_eth(caller); @@ -382,9 +374,9 @@ /// @param admin Cross account administrator address. fn remove_collection_admin_cross( &mut self, - caller: caller, + caller: Caller, admin: eth::CrossAddress, - ) -> Result { + ) -> Result<()> { self.consume_store_reads_and_writes(2, 2)?; let caller = T::CrossAccountId::from_eth(caller); @@ -396,7 +388,7 @@ /// Add collection admin. /// @param newAdmin Address of the added administrator. #[solidity(hide)] - fn add_collection_admin(&mut self, caller: caller, new_admin: address) -> Result { + fn add_collection_admin(&mut self, caller: Caller, new_admin: Address) -> Result<()> { self.consume_store_reads_and_writes(2, 2)?; let caller = T::CrossAccountId::from_eth(caller); @@ -409,7 +401,7 @@ /// /// @param admin Address of the removed administrator. #[solidity(hide)] - fn remove_collection_admin(&mut self, caller: caller, admin: address) -> Result { + fn remove_collection_admin(&mut self, caller: Caller, admin: Address) -> Result<()> { self.consume_store_reads_and_writes(2, 2)?; let caller = T::CrossAccountId::from_eth(caller); @@ -422,7 +414,7 @@ /// /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled' #[solidity(rename_selector = "setCollectionNesting")] - fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result { + fn set_nesting_bool(&mut self, caller: Caller, enable: bool) -> Result<()> { self.consume_store_reads_and_writes(1, 1)?; let caller = T::CrossAccountId::from_eth(caller); @@ -443,10 +435,10 @@ #[solidity(rename_selector = "setCollectionNesting")] fn set_nesting( &mut self, - caller: caller, + caller: Caller, enable: bool, - collections: Vec
, - ) -> Result { + collections: Vec
, + ) -> Result<()> { self.consume_store_reads_and_writes(1, 1)?; if collections.is_empty() { @@ -511,18 +503,12 @@ } /// Set the collection access method. /// @param mode Access mode - /// 0 for Normal - /// 1 for AllowList - fn set_collection_access(&mut self, caller: caller, mode: uint8) -> Result { + fn set_collection_access(&mut self, caller: Caller, mode: eth::AccessMode) -> Result<()> { self.consume_store_reads_and_writes(1, 1)?; let caller = T::CrossAccountId::from_eth(caller); let permissions = CollectionPermissions { - access: Some(match mode { - 0 => AccessMode::Normal, - 1 => AccessMode::AllowList, - _ => return Err("not supported access mode".into()), - }), + access: Some(mode.into()), ..Default::default() }; >::update_permissions(&caller, self, permissions).map_err(dispatch_to_evm::) @@ -540,7 +526,7 @@ /// /// @param user Address of a trusted user. #[solidity(hide)] - fn add_to_collection_allow_list(&mut self, caller: caller, user: address) -> Result { + fn add_to_collection_allow_list(&mut self, caller: Caller, user: Address) -> Result<()> { self.consume_store_writes(1)?; let caller = T::CrossAccountId::from_eth(caller); @@ -554,9 +540,9 @@ /// @param user User cross account address. fn add_to_collection_allow_list_cross( &mut self, - caller: caller, + caller: Caller, user: eth::CrossAddress, - ) -> Result { + ) -> Result<()> { self.consume_store_writes(1)?; let caller = T::CrossAccountId::from_eth(caller); @@ -569,7 +555,7 @@ /// /// @param user Address of a removed user. #[solidity(hide)] - fn remove_from_collection_allow_list(&mut self, caller: caller, user: address) -> Result { + fn remove_from_collection_allow_list(&mut self, caller: Caller, user: Address) -> Result<()> { self.consume_store_writes(1)?; let caller = T::CrossAccountId::from_eth(caller); @@ -583,9 +569,9 @@ /// @param user User cross account address. fn remove_from_collection_allow_list_cross( &mut self, - caller: caller, + caller: Caller, user: eth::CrossAddress, - ) -> Result { + ) -> Result<()> { self.consume_store_writes(1)?; let caller = T::CrossAccountId::from_eth(caller); @@ -597,7 +583,7 @@ /// Switch permission for minting. /// /// @param mode Enable if "true". - fn set_collection_mint_mode(&mut self, caller: caller, mode: bool) -> Result { + fn set_collection_mint_mode(&mut self, caller: Caller, mode: bool) -> Result<()> { self.consume_store_reads_and_writes(1, 1)?; let caller = T::CrossAccountId::from_eth(caller); @@ -613,7 +599,7 @@ /// @param user account to verify /// @return "true" if account is the owner or admin #[solidity(hide, rename_selector = "isOwnerOrAdmin")] - fn is_owner_or_admin_eth(&self, user: address) -> Result { + fn is_owner_or_admin_eth(&self, user: Address) -> Result { let user = T::CrossAccountId::from_eth(user); Ok(self.is_owner_or_admin(&user)) } @@ -630,7 +616,7 @@ /// Returns collection type /// /// @return `Fungible` or `NFT` or `ReFungible` - fn unique_collection_type(&self) -> Result { + fn unique_collection_type(&self) -> Result { let mode = match self.collection.mode { CollectionMode::Fungible(_) => "Fungible", CollectionMode::NFT => "NFT", @@ -654,7 +640,7 @@ /// @dev Owner can be changed only by current owner /// @param newOwner new owner account #[solidity(hide, rename_selector = "changeCollectionOwner")] - fn set_owner(&mut self, caller: caller, new_owner: address) -> Result { + fn set_owner(&mut self, caller: Caller, new_owner: Address) -> Result<()> { self.consume_store_writes(1)?; let caller = T::CrossAccountId::from_eth(caller); @@ -680,9 +666,9 @@ /// @param newOwner new owner cross account fn change_collection_owner_cross( &mut self, - caller: caller, + caller: Caller, new_owner: eth::CrossAddress, - ) -> Result { + ) -> Result<()> { self.consume_store_writes(1)?; let caller = T::CrossAccountId::from_eth(caller); --- a/pallets/common/src/eth.rs +++ b/pallets/common/src/eth.rs @@ -18,12 +18,9 @@ use alloc::format; use sp_std::{vec, vec::Vec}; -use evm_coder::{ - AbiCoder, - types::{uint256, address}, -}; +use evm_coder::{AbiCoder, types::Address}; pub use pallet_evm::{Config, account::CrossAccountId}; -use sp_core::H160; +use sp_core::{H160, U256}; use up_data_structs::CollectionId; // 0x17c4e6453Cc49AAAaEACA894e6D9683e00000001 - collection 1 @@ -33,7 +30,7 @@ ]; /// Maps the ethereum address of the collection in substrate. -pub fn map_eth_to_id(eth: &H160) -> Option { +pub fn map_eth_to_id(eth: &Address) -> Option { if eth[0..16] != ETH_COLLECTION_PREFIX { return None; } @@ -43,7 +40,7 @@ } /// Maps the substrate collection id in ethereum. -pub fn collection_id_to_address(id: CollectionId) -> H160 { +pub fn collection_id_to_address(id: CollectionId) -> Address { let mut out = [0; 20]; out[0..16].copy_from_slice(Ð_COLLECTION_PREFIX); out[16..20].copy_from_slice(&u32::to_be_bytes(id.0)); @@ -51,12 +48,12 @@ } /// Check if the ethereum address is a collection. -pub fn is_collection(address: &H160) -> bool { +pub fn is_collection(address: &Address) -> bool { address[0..16] == ETH_COLLECTION_PREFIX } -/// Convert `uint256` to `CrossAccountId`. -pub fn convert_uint256_to_cross_account(from: uint256) -> T::CrossAccountId +/// Convert `U256` to `CrossAccountId`. +pub fn convert_uint256_to_cross_account(from: U256) -> T::CrossAccountId where T::AccountId: From<[u8; 32]>, { @@ -69,8 +66,8 @@ /// Cross account struct #[derive(Debug, Default, AbiCoder)] pub struct CrossAddress { - pub(crate) eth: address, - pub(crate) sub: uint256, + pub(crate) eth: Address, + pub(crate) sub: U256, } impl CrossAddress { @@ -97,7 +94,7 @@ { Self { eth: Default::default(), - sub: uint256::from_big_endian(account_id.as_ref()), + sub: U256::from_big_endian(account_id.as_ref()), } } /// Converts [`CrossAddress`] to `CrossAccountId`. @@ -121,17 +118,17 @@ /// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue). #[derive(Debug, Default, AbiCoder)] pub struct Property { - key: evm_coder::types::string, - value: evm_coder::types::bytes, + key: evm_coder::types::String, + value: evm_coder::types::Bytes, } impl TryFrom for Property { type Error = evm_coder::execution::Error; fn try_from(from: up_data_structs::Property) -> Result { - let key = evm_coder::types::string::from_utf8(from.key.into()) + let key = evm_coder::types::String::from_utf8(from.key.into()) .map_err(|e| Self::Error::Revert(format!("utf8 conversion error: {}", e)))?; - let value = evm_coder::types::bytes(from.value.to_vec()); + let value = evm_coder::types::Bytes(from.value.to_vec()); Ok(Property { key, value }) } } @@ -187,7 +184,7 @@ #[derive(Debug, Default, AbiCoder)] pub struct CollectionLimit { field: CollectionLimitField, - value: Option, + value: Option, } impl CollectionLimit { @@ -345,7 +342,7 @@ #[derive(Debug, Default, AbiCoder)] pub struct TokenPropertyPermission { /// Token property key. - key: evm_coder::types::string, + key: evm_coder::types::String, /// Token property permissions. permissions: Vec, } @@ -363,7 +360,7 @@ ), ) -> Self { let (key, permission) = value; - let key = evm_coder::types::string::from_utf8(key.into_inner()) + let key = evm_coder::types::String::from_utf8(key.into_inner()) .expect("Stored key must be valid"); let permissions = PropertyPermission::into_vec(permission); Self { key, permissions } @@ -393,12 +390,12 @@ #[derive(Debug, Default, AbiCoder)] pub struct CollectionNesting { token_owner: bool, - ids: Vec, + ids: Vec, } impl CollectionNesting { /// Create [`CollectionNesting`]. - pub fn new(token_owner: bool, ids: Vec) -> Self { + pub fn new(token_owner: bool, ids: Vec) -> Self { Self { token_owner, ids } } } @@ -416,3 +413,32 @@ Self { field, value } } } + +/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]). +#[derive(AbiCoder, Copy, Clone, Default, Debug)] +#[repr(u8)] +pub enum AccessMode { + /// Access grant for owner and admins. Used as default. + #[default] + Normal, + /// Like a [`Normal`](AccessMode::Normal) but also users in allow list. + AllowList, +} + +impl From for AccessMode { + fn from(value: up_data_structs::AccessMode) -> Self { + match value { + up_data_structs::AccessMode::Normal => AccessMode::Normal, + up_data_structs::AccessMode::AllowList => AccessMode::AllowList, + } + } +} + +impl Into for AccessMode { + fn into(self) -> up_data_structs::AccessMode { + match self { + AccessMode::Normal => up_data_structs::AccessMode::Normal, + AccessMode::AllowList => up_data_structs::AccessMode::AllowList, + } + } +} --- a/pallets/evm-coder-substrate/src/lib.rs +++ b/pallets/evm-coder-substrate/src/lib.rs @@ -41,7 +41,7 @@ use evm_coder::{ abi::{AbiReader, AbiWrite, AbiWriter}, execution, - types::{Msg, value}, + types::{Msg, Value}, }; pub use pallet::*; @@ -256,7 +256,7 @@ >( caller: H160, e: &mut E, - value: value, + value: Value, input: &[u8], ) -> execution::Result> { let (selector, mut reader) = AbiReader::new_call(input)?; --- a/pallets/evm-contract-helpers/src/eth.rs +++ b/pallets/evm-contract-helpers/src/eth.rs @@ -49,25 +49,25 @@ ContractSponsorSet { /// Contract address of the affected collection. #[indexed] - contract_address: address, + contract_address: Address, /// New sponsor address. - sponsor: address, + sponsor: Address, }, /// New sponsor was confirm. ContractSponsorshipConfirmed { /// Contract address of the affected collection. #[indexed] - contract_address: address, + contract_address: Address, /// New sponsor address. - sponsor: address, + sponsor: Address, }, /// Collection sponsor was removed. ContractSponsorRemoved { /// Contract address of the affected collection. #[indexed] - contract_address: address, + contract_address: Address, }, } @@ -96,7 +96,7 @@ /// @dev Returns zero address if contract does not exists /// @param contractAddress Contract to get owner of /// @return address Owner of contract - fn contract_owner(&self, contract_address: address) -> Result
{ + fn contract_owner(&self, contract_address: Address) -> Result
{ Ok(>::get(contract_address)) } @@ -105,10 +105,10 @@ /// @param sponsor User address who set as pending sponsor. fn set_sponsor( &mut self, - caller: caller, - contract_address: address, - sponsor: address, - ) -> Result { + caller: Caller, + contract_address: Address, + sponsor: Address, + ) -> Result<()> { self.recorder().consume_sload()?; self.recorder().consume_sstore()?; @@ -125,7 +125,7 @@ /// Set contract as self sponsored. /// /// @param contractAddress Contract for which a self sponsoring is being enabled. - fn self_sponsored_enable(&mut self, caller: caller, contract_address: address) -> Result { + fn self_sponsored_enable(&mut self, caller: Caller, contract_address: Address) -> Result<()> { self.recorder().consume_sload()?; self.recorder().consume_sstore()?; @@ -146,7 +146,7 @@ /// Remove sponsor. /// /// @param contractAddress Contract for which a sponsorship is being removed. - fn remove_sponsor(&mut self, caller: caller, contract_address: address) -> Result { + fn remove_sponsor(&mut self, caller: Caller, contract_address: Address) -> Result<()> { self.recorder().consume_sload()?; self.recorder().consume_sstore()?; @@ -161,7 +161,7 @@ /// @dev Caller must be same that set via [`setSponsor`]. /// /// @param contractAddress Сontract for which need to confirm sponsorship. - fn confirm_sponsorship(&mut self, caller: caller, contract_address: address) -> Result { + fn confirm_sponsorship(&mut self, caller: Caller, contract_address: Address) -> Result<()> { self.recorder().consume_sload()?; self.recorder().consume_sstore()?; @@ -175,7 +175,7 @@ /// /// @param contractAddress The contract for which a sponsor is requested. /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw. - fn sponsor(&self, contract_address: address) -> Result> { + fn sponsor(&self, contract_address: Address) -> Result> { Ok(match Pallet::::get_sponsor(contract_address) { Some(ref value) => Some(eth::CrossAddress::from_sub_cross_account::(value)), None => None, @@ -186,7 +186,7 @@ /// /// @param contractAddress The contract for which the presence of a confirmed sponsor is checked. /// @return **true** if contract has confirmed sponsor. - fn has_sponsor(&self, contract_address: address) -> Result { + fn has_sponsor(&self, contract_address: Address) -> Result { Ok(Pallet::::get_sponsor(contract_address).is_some()) } @@ -194,23 +194,23 @@ /// /// @param contractAddress The contract for which the presence of a pending sponsor is checked. /// @return **true** if contract has pending sponsor. - fn has_pending_sponsor(&self, contract_address: address) -> Result { + fn has_pending_sponsor(&self, contract_address: Address) -> Result { Ok(match Sponsoring::::get(contract_address) { SponsorshipState::Disabled | SponsorshipState::Confirmed(_) => false, SponsorshipState::Unconfirmed(_) => true, }) } - fn sponsoring_enabled(&self, contract_address: address) -> Result { + fn sponsoring_enabled(&self, contract_address: Address) -> Result { Ok(>::sponsoring_mode(contract_address) != SponsoringModeT::Disabled) } fn set_sponsoring_mode( &mut self, - caller: caller, - contract_address: address, + caller: Caller, + contract_address: Address, mode: SponsoringModeT, - ) -> Result { + ) -> Result<()> { self.recorder().consume_sload()?; self.recorder().consume_sstore()?; @@ -223,7 +223,7 @@ /// Get current contract sponsoring rate limit /// @param contractAddress Contract to get sponsoring rate limit of /// @return uint32 Amount of blocks between two sponsored transactions - fn sponsoring_rate_limit(&self, contract_address: address) -> Result { + fn sponsoring_rate_limit(&self, contract_address: Address) -> Result { self.recorder().consume_sload()?; Ok(>::get(contract_address) @@ -239,10 +239,10 @@ /// @dev Only contract owner can change this setting fn set_sponsoring_rate_limit( &mut self, - caller: caller, - contract_address: address, - rate_limit: uint32, - ) -> Result { + caller: Caller, + contract_address: Address, + rate_limit: u32, + ) -> Result<()> { self.recorder().consume_sload()?; self.recorder().consume_sstore()?; @@ -259,10 +259,10 @@ /// @dev Only contract owner can change this setting fn set_sponsoring_fee_limit( &mut self, - caller: caller, - contract_address: address, - fee_limit: uint256, - ) -> Result { + caller: Caller, + contract_address: Address, + fee_limit: U256, + ) -> Result<()> { self.recorder().consume_sload()?; self.recorder().consume_sstore()?; @@ -276,7 +276,7 @@ /// @param contractAddress Contract to get sponsoring fee limit of /// @return uint256 Maximum amount of fee that could be spent by single /// transaction - fn sponsoring_fee_limit(&self, contract_address: address) -> Result { + fn sponsoring_fee_limit(&self, contract_address: Address) -> Result { self.recorder().consume_sload()?; Ok(get_sponsoring_fee_limit::(contract_address)) @@ -287,7 +287,7 @@ /// @param contractAddress Contract to check allowlist of /// @param user User to check /// @return bool Is specified users exists in contract allowlist - fn allowed(&self, contract_address: address, user: address) -> Result { + fn allowed(&self, contract_address: Address, user: Address) -> Result { self.0.consume_sload()?; Ok(>::allowed(contract_address, user)) } @@ -300,11 +300,11 @@ /// @dev Only contract owner can change this setting fn toggle_allowed( &mut self, - caller: caller, - contract_address: address, - user: address, + caller: Caller, + contract_address: Address, + user: Address, is_allowed: bool, - ) -> Result { + ) -> Result<()> { self.recorder().consume_sload()?; self.recorder().consume_sstore()?; @@ -320,7 +320,7 @@ /// in case of allowlist access enabled, only users from allowlist may call this contract /// @param contractAddress Contract to get allowlist access of /// @return bool Is specified contract has allowlist access enabled - fn allowlist_enabled(&self, contract_address: address) -> Result { + fn allowlist_enabled(&self, contract_address: Address) -> Result { Ok(>::get(contract_address)) } @@ -329,10 +329,10 @@ /// @param enabled Should allowlist access to be enabled? fn toggle_allowlist( &mut self, - caller: caller, - contract_address: address, + caller: Caller, + contract_address: Address, enabled: bool, - ) -> Result { + ) -> Result<()> { self.recorder().consume_sload()?; self.recorder().consume_sstore()?; @@ -441,7 +441,7 @@ } } -fn get_sponsoring_fee_limit(contract_address: address) -> uint256 { +fn get_sponsoring_fee_limit(contract_address: Address) -> U256 { >::get(contract_address) .get(&0xffffffff) .cloned() --- a/pallets/fungible/src/erc.rs +++ b/pallets/fungible/src/erc.rs @@ -32,7 +32,7 @@ use pallet_evm::{account::CrossAccountId, PrecompileHandle}; use pallet_evm_coder_substrate::{call, dispatch_to_evm}; use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _}; -use sp_core::Get; +use sp_core::{U256, Get}; use crate::{ Allowance, Balance, Config, FungibleHandle, Pallet, SelfWeightOf, TotalSupply, @@ -43,50 +43,50 @@ pub enum ERC20Events { Transfer { #[indexed] - from: address, + from: Address, #[indexed] - to: address, - value: uint256, + to: Address, + value: U256, }, Approval { #[indexed] - owner: address, + owner: Address, #[indexed] - spender: address, - value: uint256, + spender: Address, + value: U256, }, } #[solidity_interface(name = ERC20, events(ERC20Events))] impl FungibleHandle { - fn name(&self) -> Result { + fn name(&self) -> Result { Ok(decode_utf16(self.name.iter().copied()) .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)) - .collect::()) + .collect::()) } - fn symbol(&self) -> Result { - Ok(string::from_utf8_lossy(&self.token_prefix).into()) + fn symbol(&self) -> Result { + Ok(String::from_utf8_lossy(&self.token_prefix).into()) } - fn total_supply(&self) -> Result { + fn total_supply(&self) -> Result { self.consume_store_reads(1)?; Ok(>::get(self.id).into()) } - fn decimals(&self) -> Result { + fn decimals(&self) -> Result { Ok(if let CollectionMode::Fungible(decimals) = &self.mode { *decimals } else { unreachable!() }) } - fn balance_of(&self, owner: address) -> Result { + fn balance_of(&self, owner: Address) -> Result { self.consume_store_reads(1)?; let owner = T::CrossAccountId::from_eth(owner); let balance = >::get((self.id, owner)); Ok(balance.into()) } #[weight(>::transfer())] - fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result { + fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); let amount = amount.try_into().map_err(|_| "amount overflow")?; @@ -101,10 +101,10 @@ #[weight(>::transfer_from())] fn transfer_from( &mut self, - caller: caller, - from: address, - to: address, - amount: uint256, + caller: Caller, + from: Address, + to: Address, + amount: U256, ) -> Result { let caller = T::CrossAccountId::from_eth(caller); let from = T::CrossAccountId::from_eth(from); @@ -119,7 +119,7 @@ Ok(true) } #[weight(>::approve())] - fn approve(&mut self, caller: caller, spender: address, amount: uint256) -> Result { + fn approve(&mut self, caller: Caller, spender: Address, amount: U256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let spender = T::CrossAccountId::from_eth(spender); let amount = amount.try_into().map_err(|_| "amount overflow")?; @@ -128,7 +128,7 @@ .map_err(dispatch_to_evm::)?; Ok(true) } - fn allowance(&self, owner: address, spender: address) -> Result { + fn allowance(&self, owner: Address, spender: Address) -> Result { self.consume_store_reads(1)?; let owner = T::CrossAccountId::from_eth(owner); let spender = T::CrossAccountId::from_eth(spender); @@ -137,7 +137,7 @@ } /// @notice Returns collection helper contract address - fn collection_helper_address(&self) -> Result
{ + fn collection_helper_address(&self) -> Result
{ Ok(T::ContractAddress::get()) } } @@ -148,7 +148,7 @@ /// @param to account that will receive minted tokens /// @param amount amount of tokens to mint #[weight(>::create_item())] - fn mint(&mut self, caller: caller, to: address, amount: uint256) -> Result { + fn mint(&mut self, caller: Caller, to: Address, amount: U256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); let amount = amount.try_into().map_err(|_| "amount overflow")?; @@ -167,18 +167,18 @@ T::AccountId: From<[u8; 32]>, { /// @notice A description for the collection. - fn description(&self) -> Result { + fn description(&self) -> Result { Ok(decode_utf16(self.description.iter().copied()) .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)) - .collect::()) + .collect::()) } #[weight(>::create_item())] fn mint_cross( &mut self, - caller: caller, + caller: Caller, to: pallet_common::eth::CrossAddress, - amount: uint256, + amount: U256, ) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = to.into_sub_cross_account::()?; @@ -194,9 +194,9 @@ #[weight(>::approve())] fn approve_cross( &mut self, - caller: caller, + caller: Caller, spender: pallet_common::eth::CrossAddress, - amount: uint256, + amount: U256, ) -> Result { let caller = T::CrossAccountId::from_eth(caller); let spender = spender.into_sub_cross_account::()?; @@ -214,7 +214,7 @@ /// @param amount The amount that will be burnt. #[solidity(hide)] #[weight(>::burn_from())] - fn burn_from(&mut self, caller: caller, from: address, amount: uint256) -> Result { + fn burn_from(&mut self, caller: Caller, from: Address, amount: U256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let from = T::CrossAccountId::from_eth(from); let amount = amount.try_into().map_err(|_| "amount overflow")?; @@ -235,9 +235,9 @@ #[weight(>::burn_from())] fn burn_from_cross( &mut self, - caller: caller, + caller: Caller, from: pallet_common::eth::CrossAddress, - amount: uint256, + amount: U256, ) -> Result { let caller = T::CrossAccountId::from_eth(caller); let from = from.into_sub_cross_account::()?; @@ -254,7 +254,7 @@ /// Mint tokens for multiple accounts. /// @param amounts array of pairs of account address and amount #[weight(>::create_multiple_items_ex(amounts.len() as u32))] - fn mint_bulk(&mut self, caller: caller, amounts: Vec<(address, uint256)>) -> Result { + fn mint_bulk(&mut self, caller: Caller, amounts: Vec<(Address, U256)>) -> Result { let caller = T::CrossAccountId::from_eth(caller); let budget = self .recorder @@ -277,9 +277,9 @@ #[weight(>::transfer())] fn transfer_cross( &mut self, - caller: caller, + caller: Caller, to: pallet_common::eth::CrossAddress, - amount: uint256, + amount: U256, ) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = to.into_sub_cross_account::()?; @@ -295,10 +295,10 @@ #[weight(>::transfer_from())] fn transfer_from_cross( &mut self, - caller: caller, + caller: Caller, from: pallet_common::eth::CrossAddress, to: pallet_common::eth::CrossAddress, - amount: uint256, + amount: U256, ) -> Result { let caller = T::CrossAccountId::from_eth(caller); let from = from.into_sub_cross_account::()?; --- a/pallets/fungible/src/stubs/UniqueFungible.sol +++ b/pallets/fungible/src/stubs/UniqueFungible.sol @@ -274,11 +274,9 @@ /// Set the collection access method. /// @param mode Access mode - /// 0 for Normal - /// 1 for AllowList /// @dev EVM selector for this function is: 0x41835d4c, /// or in textual repr: setCollectionAccess(uint8) - function setCollectionAccess(uint8 mode) public { + function setCollectionAccess(AccessMode mode) public { require(false, stub_error); mode; dummy = 0; @@ -443,6 +441,14 @@ uint256 sub; } +/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]). +enum AccessMode { + /// Access grant for owner and admins. Used as default. + Normal, + /// Like a [`Normal`](AccessMode::Normal) but also users in allow list. + AllowList +} + /// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field. struct CollectionNestingPermission { CollectionPermissionField field; --- a/pallets/nonfungible/src/erc.rs +++ b/pallets/nonfungible/src/erc.rs @@ -43,7 +43,7 @@ use pallet_evm::{account::CrossAccountId, PrecompileHandle}; use pallet_evm_coder_substrate::call; use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _}; -use sp_core::Get; +use sp_core::{U256, Get}; use crate::{ AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData, TokensMinted, @@ -63,8 +63,8 @@ #[solidity(hide)] fn set_token_property_permission( &mut self, - caller: caller, - key: string, + caller: Caller, + key: String, is_mutable: bool, collection_admin: bool, token_owner: bool, @@ -93,7 +93,7 @@ #[weight(>::set_token_property_permissions(permissions.len() as u32))] fn set_token_property_permissions( &mut self, - caller: caller, + caller: Caller, permissions: Vec, ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); @@ -121,10 +121,10 @@ #[weight(>::set_token_properties(1))] fn set_property( &mut self, - caller: caller, - token_id: uint256, - key: string, - value: bytes, + caller: Caller, + token_id: U256, + key: String, + value: Bytes, ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?; @@ -154,8 +154,8 @@ #[weight(>::set_token_properties(properties.len() as u32))] fn set_properties( &mut self, - caller: caller, - token_id: uint256, + caller: Caller, + token_id: U256, properties: Vec, ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); @@ -187,7 +187,7 @@ /// @param key Property key. #[solidity(hide)] #[weight(>::delete_token_properties(1))] - fn delete_property(&mut self, token_id: uint256, caller: caller, key: string) -> Result<()> { + fn delete_property(&mut self, token_id: U256, caller: Caller, key: String) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?; let key = >::from(key) @@ -209,9 +209,9 @@ #[weight(>::delete_token_properties(keys.len() as u32))] fn delete_properties( &mut self, - token_id: uint256, - caller: caller, - keys: Vec, + token_id: U256, + caller: Caller, + keys: Vec, ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?; @@ -239,7 +239,7 @@ /// @param tokenId ID of the token. /// @param key Property key. /// @return Property value bytes - fn property(&self, token_id: uint256, key: string) -> Result { + fn property(&self, token_id: U256, key: String) -> Result { let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?; let key = >::from(key) .try_into() @@ -261,11 +261,11 @@ /// any transfer, the approved address for that NFT (if any) is reset to none. Transfer { #[indexed] - from: address, + from: Address, #[indexed] - to: address, + to: Address, #[indexed] - token_id: uint256, + token_id: U256, }, /// @dev This emits when the approved address for an NFT is changed or /// reaffirmed. The zero address indicates there is no approved address. @@ -273,20 +273,20 @@ /// address for that NFT (if any) is reset to none. Approval { #[indexed] - owner: address, + owner: Address, #[indexed] - approved: address, + approved: Address, #[indexed] - token_id: uint256, + token_id: U256, }, /// @dev This emits when an operator is enabled or disabled for an owner. /// The operator can manage all NFTs of the owner. #[allow(dead_code)] ApprovalForAll { #[indexed] - owner: address, + owner: Address, #[indexed] - operator: address, + operator: Address, approved: bool, }, } @@ -301,14 +301,14 @@ /// @notice A descriptive name for a collection of NFTs in this contract /// @dev real implementation of this function lies in `ERC721UniqueExtensions` #[solidity(hide, rename_selector = "name")] - fn name_proxy(&self) -> Result { + fn name_proxy(&self) -> Result { self.name() } /// @notice An abbreviated name for NFTs in this contract /// @dev real implementation of this function lies in `ERC721UniqueExtensions` #[solidity(hide, rename_selector = "symbol")] - fn symbol_proxy(&self) -> Result { + fn symbol_proxy(&self) -> Result { self.symbol() } @@ -322,7 +322,7 @@ /// /// @return token's const_metadata #[solidity(rename_selector = "tokenURI")] - fn token_uri(&self, token_id: uint256) -> Result { + fn token_uri(&self, token_id: U256) -> Result { let token_id_u32: u32 = token_id.try_into().map_err(|_| "token id overflow")?; match get_token_property(self, token_id_u32, &key::url()).as_deref() { @@ -335,7 +335,7 @@ let base_uri = pallet_common::Pallet::::get_collection_property(self.id, &key::base_uri()) .map(BoundedVec::into_inner) - .map(string::from_utf8) + .map(String::from_utf8) .transpose() .map_err(|e| { Error::Revert(alloc::format!( @@ -368,12 +368,12 @@ /// @param index A counter less than `totalSupply()` /// @return The token identifier for the `index`th NFT, /// (sort order not specified) - fn token_by_index(&self, index: uint256) -> Result { + fn token_by_index(&self, index: U256) -> Result { Ok(index) } /// @dev Not implemented - fn token_of_owner_by_index(&self, _owner: address, _index: uint256) -> Result { + fn token_of_owner_by_index(&self, _owner: Address, _index: U256) -> Result { // TODO: Not implemetable Err("not implemented".into()) } @@ -381,7 +381,7 @@ /// @notice Count NFTs tracked by this contract /// @return A count of valid NFTs tracked by this contract, where each one of /// them has an assigned and queryable owner not equal to the zero address - fn total_supply(&self) -> Result { + fn total_supply(&self) -> Result { self.consume_store_reads(1)?; Ok(>::total_supply(self).into()) } @@ -396,7 +396,7 @@ /// function throws for queries about the zero address. /// @param owner An address for whom to query the balance /// @return The number of NFTs owned by `owner`, possibly zero - fn balance_of(&self, owner: address) -> Result { + fn balance_of(&self, owner: Address) -> Result { self.consume_store_reads(1)?; let owner = T::CrossAccountId::from_eth(owner); let balance = >::get((self.id, owner)); @@ -407,7 +407,7 @@ /// about them do throw. /// @param tokenId The identifier for an NFT /// @return The address of the owner of the NFT - fn owner_of(&self, token_id: uint256) -> Result
{ + fn owner_of(&self, token_id: U256) -> Result
{ self.consume_store_reads(1)?; let token: TokenId = token_id.try_into()?; Ok(*>::get((self.id, token)) @@ -419,21 +419,16 @@ #[solidity(rename_selector = "safeTransferFrom")] fn safe_transfer_from_with_data( &mut self, - _from: address, - _to: address, - _token_id: uint256, - _data: bytes, - ) -> Result { + _from: Address, + _to: Address, + _token_id: U256, + _data: Bytes, + ) -> Result<()> { // TODO: Not implemetable Err("not implemented".into()) } /// @dev Not implemented - fn safe_transfer_from( - &mut self, - _from: address, - _to: address, - _token_id: uint256, - ) -> Result { + fn safe_transfer_from(&mut self, _from: Address, _to: Address, _token_id: U256) -> Result<()> { // TODO: Not implemetable Err("not implemented".into()) } @@ -450,11 +445,11 @@ #[weight(>::transfer_from())] fn transfer_from( &mut self, - caller: caller, - from: address, - to: address, - token_id: uint256, - ) -> Result { + caller: Caller, + from: Address, + to: Address, + token_id: U256, + ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let from = T::CrossAccountId::from_eth(from); let to = T::CrossAccountId::from_eth(to); @@ -475,7 +470,7 @@ /// @param approved The new approved NFT controller /// @param tokenId The NFT to approve #[weight(>::approve())] - fn approve(&mut self, caller: caller, approved: address, token_id: uint256) -> Result { + fn approve(&mut self, caller: Caller, approved: Address, token_id: U256) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let approved = T::CrossAccountId::from_eth(approved); let token = token_id.try_into()?; @@ -492,10 +487,10 @@ #[weight(>::set_allowance_for_all())] fn set_approval_for_all( &mut self, - caller: caller, - operator: address, + caller: Caller, + operator: Address, approved: bool, - ) -> Result { + ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let operator = T::CrossAccountId::from_eth(operator); @@ -505,14 +500,14 @@ } /// @dev Not implemented - fn get_approved(&self, _token_id: uint256) -> Result
{ + fn get_approved(&self, _token_id: U256) -> Result
{ // TODO: Not implemetable Err("not implemented".into()) } /// @notice Tells whether the given `owner` approves the `operator`. #[weight(>::allowance_for_all())] - fn is_approved_for_all(&self, owner: address, operator: address) -> Result { + fn is_approved_for_all(&self, owner: Address, operator: Address) -> Result { let owner = T::CrossAccountId::from_eth(owner); let operator = T::CrossAccountId::from_eth(operator); @@ -528,7 +523,7 @@ /// operator of the current owner. /// @param tokenId The NFT to approve #[weight(>::burn_item())] - fn burn(&mut self, caller: caller, token_id: uint256) -> Result { + fn burn(&mut self, caller: Caller, token_id: U256) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let token = token_id.try_into()?; @@ -544,8 +539,8 @@ /// @param to The new owner /// @return uint256 The id of the newly minted token #[weight(>::create_item())] - fn mint(&mut self, caller: caller, to: address) -> Result { - let token_id: uint256 = >::get(self.id) + fn mint(&mut self, caller: Caller, to: Address) -> Result { + let token_id: U256 = >::get(self.id) .checked_add(1) .ok_or("item id overflow")? .into(); @@ -560,7 +555,7 @@ /// @param tokenId ID of the minted NFT #[solidity(hide, rename_selector = "mint")] #[weight(>::create_item())] - fn mint_check_id(&mut self, caller: caller, to: address, token_id: uint256) -> Result { + fn mint_check_id(&mut self, caller: Caller, to: Address, token_id: U256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); let token_id: u32 = token_id.try_into()?; @@ -598,11 +593,11 @@ #[weight(>::create_item())] fn mint_with_token_uri( &mut self, - caller: caller, - to: address, - token_uri: string, - ) -> Result { - let token_id: uint256 = >::get(self.id) + caller: Caller, + to: Address, + token_uri: String, + ) -> Result { + let token_id: U256 = >::get(self.id) .checked_add(1) .ok_or("item id overflow")? .into(); @@ -620,10 +615,10 @@ #[weight(>::create_item())] fn mint_with_token_uri_check_id( &mut self, - caller: caller, - to: address, - token_id: uint256, - token_uri: string, + caller: Caller, + to: Address, + token_id: U256, + token_uri: String, ) -> Result { let key = key::url(); let permission = get_token_permission::(self.id, &key)?; @@ -675,12 +670,12 @@ collection: &CollectionHandle, token_id: u32, key: &up_data_structs::PropertyKey, -) -> Result { +) -> Result { collection.consume_store_reads(1)?; let properties = >::try_get((collection.id, token_id)) .map_err(|_| Error::Revert("Token properties not found".into()))?; if let Some(property) = properties.get(key) { - return Ok(string::from_utf8_lossy(property).into()); + return Ok(String::from_utf8_lossy(property).into()); } Err("Property tokenURI not found".into()) @@ -696,7 +691,7 @@ .get(key) .map(Clone::clone) .ok_or_else(|| { - let key = string::from_utf8(key.clone().into_inner()).unwrap_or_default(); + let key = String::from_utf8(key.clone().into_inner()).unwrap_or_default(); Error::Revert(alloc::format!("No permission for key {}", key)) })?; Ok(a) @@ -709,28 +704,28 @@ T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>, { /// @notice A descriptive name for a collection of NFTs in this contract - fn name(&self) -> Result { + fn name(&self) -> Result { Ok(decode_utf16(self.name.iter().copied()) .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)) - .collect::()) + .collect::()) } /// @notice An abbreviated name for NFTs in this contract - fn symbol(&self) -> Result { - Ok(string::from_utf8_lossy(&self.token_prefix).into()) + fn symbol(&self) -> Result { + Ok(String::from_utf8_lossy(&self.token_prefix).into()) } /// @notice A description for the collection. - fn description(&self) -> Result { + fn description(&self) -> Result { Ok(decode_utf16(self.description.iter().copied()) .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)) - .collect::()) + .collect::()) } /// Returns the owner (in cross format) of the token. /// /// @param tokenId Id for the token. - fn cross_owner_of(&self, token_id: uint256) -> Result { + fn cross_owner_of(&self, token_id: U256) -> Result { Self::token_owner(&self, token_id.try_into()?) .map(|o| eth::CrossAddress::from_sub_cross_account::(&o)) .ok_or(Error::Revert("key too large".into())) @@ -741,7 +736,7 @@ /// @param tokenId Id for the token. /// @param keys Properties keys. Empty keys for all propertyes. /// @return Vector of properties key/value pairs. - fn properties(&self, token_id: uint256, keys: Vec) -> Result> { + fn properties(&self, token_id: U256, keys: Vec) -> Result> { let keys = keys .into_iter() .map(|key| { @@ -770,10 +765,10 @@ #[weight(>::approve())] fn approve_cross( &mut self, - caller: caller, + caller: Caller, approved: eth::CrossAddress, - token_id: uint256, - ) -> Result { + token_id: U256, + ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let approved = approved.into_sub_cross_account::()?; let token = token_id.try_into()?; @@ -789,7 +784,7 @@ /// @param to The new owner /// @param tokenId The NFT to transfer #[weight(>::transfer())] - fn transfer(&mut self, caller: caller, to: address, token_id: uint256) -> Result { + fn transfer(&mut self, caller: Caller, to: Address, token_id: U256) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); let token = token_id.try_into()?; @@ -809,10 +804,10 @@ #[weight(>::transfer())] fn transfer_cross( &mut self, - caller: caller, + caller: Caller, to: eth::CrossAddress, - token_id: uint256, - ) -> Result { + token_id: U256, + ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let to = to.into_sub_cross_account::()?; let token = token_id.try_into()?; @@ -833,11 +828,11 @@ #[weight(>::transfer())] fn transfer_from_cross( &mut self, - caller: caller, + caller: Caller, from: eth::CrossAddress, to: eth::CrossAddress, - token_id: uint256, - ) -> Result { + token_id: U256, + ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let from = from.into_sub_cross_account::()?; let to = to.into_sub_cross_account::()?; @@ -858,7 +853,7 @@ /// @param tokenId The NFT to transfer #[solidity(hide)] #[weight(>::burn_from())] - fn burn_from(&mut self, caller: caller, from: address, token_id: uint256) -> Result { + fn burn_from(&mut self, caller: Caller, from: Address, token_id: U256) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let from = T::CrossAccountId::from_eth(from); let token = token_id.try_into()?; @@ -880,10 +875,10 @@ #[weight(>::burn_from())] fn burn_from_cross( &mut self, - caller: caller, + caller: Caller, from: eth::CrossAddress, - token_id: uint256, - ) -> Result { + token_id: U256, + ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let from = from.into_sub_cross_account::()?; let token = token_id.try_into()?; @@ -897,7 +892,7 @@ } /// @notice Returns next free NFT ID. - fn next_token_id(&self) -> Result { + fn next_token_id(&self) -> Result { self.consume_store_reads(1)?; Ok(>::get(self.id) .checked_add(1) @@ -912,7 +907,7 @@ /// @param tokenIds IDs of the minted NFTs #[solidity(hide)] #[weight(>::create_multiple_items(token_ids.len() as u32))] - fn mint_bulk(&mut self, caller: caller, to: address, token_ids: Vec) -> Result { + fn mint_bulk(&mut self, caller: Caller, to: Address, token_ids: Vec) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); let mut expected_index = >::get(self.id) @@ -951,9 +946,9 @@ #[weight(>::create_multiple_items(tokens.len() as u32))] fn mint_bulk_with_token_uri( &mut self, - caller: caller, - to: address, - tokens: Vec<(uint256, string)>, + caller: Caller, + to: Address, + tokens: Vec<(U256, String)>, ) -> Result { let key = key::url(); let caller = T::CrossAccountId::from_eth(caller); @@ -1002,10 +997,10 @@ #[weight(>::create_item())] fn mint_cross( &mut self, - caller: caller, + caller: Caller, to: eth::CrossAddress, properties: Vec, - ) -> Result { + ) -> Result { let token_id = >::get(self.id) .checked_add(1) .ok_or("item id overflow")?; @@ -1040,7 +1035,7 @@ } /// @notice Returns collection helper contract address - fn collection_helper_address(&self) -> Result
{ + fn collection_helper_address(&self) -> Result
{ Ok(T::ContractAddress::get()) } } --- a/pallets/nonfungible/src/stubs/UniqueNFT.sol +++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol @@ -416,11 +416,9 @@ /// Set the collection access method. /// @param mode Access mode - /// 0 for Normal - /// 1 for AllowList /// @dev EVM selector for this function is: 0x41835d4c, /// or in textual repr: setCollectionAccess(uint8) - function setCollectionAccess(uint8 mode) public { + function setCollectionAccess(AccessMode mode) public { require(false, stub_error); mode; dummy = 0; @@ -585,6 +583,14 @@ uint256 sub; } +/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]). +enum AccessMode { + /// Access grant for owner and admins. Used as default. + Normal, + /// Like a [`Normal`](AccessMode::Normal) but also users in allow list. + AllowList +} + /// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field. struct CollectionNestingPermission { CollectionPermissionField field; --- a/pallets/refungible/src/erc.rs +++ b/pallets/refungible/src/erc.rs @@ -39,7 +39,7 @@ use pallet_evm::{account::CrossAccountId, PrecompileHandle}; use pallet_evm_coder_substrate::{call, dispatch_to_evm}; use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _}; -use sp_core::{H160, Get}; +use sp_core::{H160, U256, Get}; use sp_std::{collections::btree_map::BTreeMap, vec::Vec, vec}; use up_data_structs::{ CollectionId, CollectionPropertiesVec, mapping::TokenAddressMapping, Property, PropertyKey, @@ -66,8 +66,8 @@ #[solidity(hide)] fn set_token_property_permission( &mut self, - caller: caller, - key: string, + caller: Caller, + key: String, is_mutable: bool, collection_admin: bool, token_owner: bool, @@ -96,7 +96,7 @@ #[weight(>::set_token_property_permissions(permissions.len() as u32))] fn set_token_property_permissions( &mut self, - caller: caller, + caller: Caller, permissions: Vec, ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); @@ -124,10 +124,10 @@ #[weight(>::set_token_properties(1))] fn set_property( &mut self, - caller: caller, - token_id: uint256, - key: string, - value: bytes, + caller: Caller, + token_id: U256, + key: String, + value: Bytes, ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?; @@ -157,8 +157,8 @@ #[weight(>::set_token_properties(properties.len() as u32))] fn set_properties( &mut self, - caller: caller, - token_id: uint256, + caller: Caller, + token_id: U256, properties: Vec, ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); @@ -190,7 +190,7 @@ /// @param key Property key. #[solidity(hide)] #[weight(>::delete_token_properties(1))] - fn delete_property(&mut self, token_id: uint256, caller: caller, key: string) -> Result<()> { + fn delete_property(&mut self, token_id: U256, caller: Caller, key: String) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?; let key = >::from(key) @@ -212,9 +212,9 @@ #[weight(>::delete_token_properties(keys.len() as u32))] fn delete_properties( &mut self, - token_id: uint256, - caller: caller, - keys: Vec, + token_id: U256, + caller: Caller, + keys: Vec, ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?; @@ -242,7 +242,7 @@ /// @param tokenId ID of the token. /// @param key Property key. /// @return Property value bytes - fn property(&self, token_id: uint256, key: string) -> Result { + fn property(&self, token_id: U256, key: String) -> Result { let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?; let key = >::from(key) .try_into() @@ -262,28 +262,28 @@ /// may be created and assigned without emitting Transfer. Transfer { #[indexed] - from: address, + from: Address, #[indexed] - to: address, + to: Address, #[indexed] - token_id: uint256, + token_id: U256, }, /// @dev Not supported Approval { #[indexed] - owner: address, + owner: Address, #[indexed] - approved: address, + approved: Address, #[indexed] - token_id: uint256, + token_id: U256, }, /// @dev Not supported #[allow(dead_code)] ApprovalForAll { #[indexed] - owner: address, + owner: Address, #[indexed] - operator: address, + operator: Address, approved: bool, }, } @@ -298,14 +298,14 @@ /// @notice A descriptive name for a collection of NFTs in this contract /// @dev real implementation of this function lies in `ERC721UniqueExtensions` #[solidity(hide, rename_selector = "name")] - fn name_proxy(&self) -> Result { + fn name_proxy(&self) -> Result { self.name() } /// @notice An abbreviated name for NFTs in this contract /// @dev real implementation of this function lies in `ERC721UniqueExtensions` #[solidity(hide, rename_selector = "symbol")] - fn symbol_proxy(&self) -> Result { + fn symbol_proxy(&self) -> Result { self.symbol() } @@ -319,7 +319,7 @@ /// /// @return token's const_metadata #[solidity(rename_selector = "tokenURI")] - fn token_uri(&self, token_id: uint256) -> Result { + fn token_uri(&self, token_id: U256) -> Result { let token_id_u32: u32 = token_id.try_into().map_err(|_| "token id overflow")?; match get_token_property(self, token_id_u32, &key::url()).as_deref() { @@ -332,7 +332,7 @@ let base_uri = pallet_common::Pallet::::get_collection_property(self.id, &key::base_uri()) .map(BoundedVec::into_inner) - .map(string::from_utf8) + .map(String::from_utf8) .transpose() .map_err(|e| { Error::Revert(alloc::format!( @@ -365,12 +365,12 @@ /// @param index A counter less than `totalSupply()` /// @return The token identifier for the `index`th NFT, /// (sort order not specified) - fn token_by_index(&self, index: uint256) -> Result { + fn token_by_index(&self, index: U256) -> Result { Ok(index) } /// Not implemented - fn token_of_owner_by_index(&self, _owner: address, _index: uint256) -> Result { + fn token_of_owner_by_index(&self, _owner: Address, _index: U256) -> Result { // TODO: Not implemetable Err("not implemented".into()) } @@ -378,7 +378,7 @@ /// @notice Count RFTs tracked by this contract /// @return A count of valid RFTs tracked by this contract, where each one of /// them has an assigned and queryable owner not equal to the zero address - fn total_supply(&self) -> Result { + fn total_supply(&self) -> Result { self.consume_store_reads(1)?; Ok(>::total_supply(self).into()) } @@ -393,7 +393,7 @@ /// function throws for queries about the zero address. /// @param owner An address for whom to query the balance /// @return The number of RFTs owned by `owner`, possibly zero - fn balance_of(&self, owner: address) -> Result { + fn balance_of(&self, owner: Address) -> Result { self.consume_store_reads(1)?; let owner = T::CrossAccountId::from_eth(owner); let balance = >::get((self.id, owner)); @@ -407,7 +407,7 @@ /// the tokens that are partially owned. /// @param tokenId The identifier for an RFT /// @return The address of the owner of the RFT - fn owner_of(&self, token_id: uint256) -> Result
{ + fn owner_of(&self, token_id: U256) -> Result
{ self.consume_store_reads(2)?; let token = token_id.try_into()?; let owner = >::token_owner(self.id, token); @@ -420,23 +420,18 @@ #[solidity(rename_selector = "safeTransferFrom")] fn safe_transfer_from_with_data( &mut self, - _from: address, - _to: address, - _token_id: uint256, - _data: bytes, - ) -> Result { + _from: Address, + _to: Address, + _token_id: U256, + _data: Bytes, + ) -> Result<()> { // TODO: Not implemetable Err("not implemented".into()) } /// @dev Not implemented #[solidity(rename_selector = "safeTransferFrom")] - fn safe_transfer_from( - &mut self, - _from: address, - _to: address, - _token_id: uint256, - ) -> Result { + fn safe_transfer_from(&mut self, _from: Address, _to: Address, _token_id: U256) -> Result<()> { // TODO: Not implemetable Err("not implemented".into()) } @@ -454,11 +449,11 @@ #[weight(>::transfer_from_creating_removing())] fn transfer_from( &mut self, - caller: caller, - from: address, - to: address, - token_id: uint256, - ) -> Result { + caller: Caller, + from: Address, + to: Address, + token_id: U256, + ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let from = T::CrossAccountId::from_eth(from); let to = T::CrossAccountId::from_eth(to); @@ -477,7 +472,7 @@ } /// @dev Not implemented - fn approve(&mut self, _caller: caller, _approved: address, _token_id: uint256) -> Result { + fn approve(&mut self, _caller: Caller, _approved: Address, _token_id: U256) -> Result<()> { Err("not implemented".into()) } @@ -488,10 +483,10 @@ #[weight(>::set_allowance_for_all())] fn set_approval_for_all( &mut self, - caller: caller, - operator: address, + caller: Caller, + operator: Address, approved: bool, - ) -> Result { + ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let operator = T::CrossAccountId::from_eth(operator); @@ -501,14 +496,14 @@ } /// @dev Not implemented - fn get_approved(&self, _token_id: uint256) -> Result
{ + fn get_approved(&self, _token_id: U256) -> Result
{ // TODO: Not implemetable Err("not implemented".into()) } /// @notice Tells whether the given `owner` approves the `operator`. #[weight(>::allowance_for_all())] - fn is_approved_for_all(&self, owner: address, operator: address) -> Result { + fn is_approved_for_all(&self, owner: Address, operator: Address) -> Result { let owner = T::CrossAccountId::from_eth(owner); let operator = T::CrossAccountId::from_eth(operator); @@ -556,7 +551,7 @@ /// operator of the current owner. /// @param tokenId The RFT to approve #[weight(>::burn_item_fully())] - fn burn(&mut self, caller: caller, token_id: uint256) -> Result { + fn burn(&mut self, caller: Caller, token_id: U256) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let token = token_id.try_into()?; @@ -575,8 +570,8 @@ /// @param to The new owner /// @return uint256 The id of the newly minted token #[weight(>::create_item())] - fn mint(&mut self, caller: caller, to: address) -> Result { - let token_id: uint256 = >::get(self.id) + fn mint(&mut self, caller: Caller, to: Address) -> Result { + let token_id: U256 = >::get(self.id) .checked_add(1) .ok_or("item id overflow")? .into(); @@ -591,7 +586,7 @@ /// @param tokenId ID of the minted RFT #[solidity(hide, rename_selector = "mint")] #[weight(>::create_item())] - fn mint_check_id(&mut self, caller: caller, to: address, token_id: uint256) -> Result { + fn mint_check_id(&mut self, caller: Caller, to: Address, token_id: U256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); let token_id: u32 = token_id.try_into()?; @@ -634,11 +629,11 @@ #[weight(>::create_item())] fn mint_with_token_uri( &mut self, - caller: caller, - to: address, - token_uri: string, - ) -> Result { - let token_id: uint256 = >::get(self.id) + caller: Caller, + to: Address, + token_uri: String, + ) -> Result { + let token_id: U256 = >::get(self.id) .checked_add(1) .ok_or("item id overflow")? .into(); @@ -656,10 +651,10 @@ #[weight(>::create_item())] fn mint_with_token_uri_check_id( &mut self, - caller: caller, - to: address, - token_id: uint256, - token_uri: string, + caller: Caller, + to: Address, + token_id: U256, + token_uri: String, ) -> Result { let key = key::url(); let permission = get_token_permission::(self.id, &key)?; @@ -713,12 +708,12 @@ collection: &CollectionHandle, token_id: u32, key: &up_data_structs::PropertyKey, -) -> Result { +) -> Result { collection.consume_store_reads(1)?; let properties = >::try_get((collection.id, token_id)) .map_err(|_| Error::Revert("Token properties not found".into()))?; if let Some(property) = properties.get(key) { - return Ok(string::from_utf8_lossy(property).into()); + return Ok(String::from_utf8_lossy(property).into()); } Err("Property tokenURI not found".into()) @@ -734,7 +729,7 @@ .get(key) .map(Clone::clone) .ok_or_else(|| { - let key = string::from_utf8(key.clone().into_inner()).unwrap_or_default(); + let key = String::from_utf8(key.clone().into_inner()).unwrap_or_default(); Error::Revert(alloc::format!("No permission for key {}", key)) })?; Ok(a) @@ -747,28 +742,28 @@ T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>, { /// @notice A descriptive name for a collection of NFTs in this contract - fn name(&self) -> Result { + fn name(&self) -> Result { Ok(decode_utf16(self.name.iter().copied()) .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)) - .collect::()) + .collect::()) } /// @notice An abbreviated name for NFTs in this contract - fn symbol(&self) -> Result { - Ok(string::from_utf8_lossy(&self.token_prefix).into()) + fn symbol(&self) -> Result { + Ok(String::from_utf8_lossy(&self.token_prefix).into()) } /// @notice A description for the collection. - fn description(&self) -> Result { + fn description(&self) -> Result { Ok(decode_utf16(self.description.iter().copied()) .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)) - .collect::()) + .collect::()) } /// Returns the owner (in cross format) of the token. /// /// @param tokenId Id for the token. - fn cross_owner_of(&self, token_id: uint256) -> Result { + fn cross_owner_of(&self, token_id: U256) -> Result { Self::token_owner(&self, token_id.try_into()?) .map(|o| eth::CrossAddress::from_sub_cross_account::(&o)) .ok_or(Error::Revert("key too large".into())) @@ -779,7 +774,7 @@ /// @param tokenId Id for the token. /// @param keys Properties keys. Empty keys for all propertyes. /// @return Vector of properties key/value pairs. - fn properties(&self, token_id: uint256, keys: Vec) -> Result> { + fn properties(&self, token_id: U256, keys: Vec) -> Result> { let keys = keys .into_iter() .map(|key| { @@ -805,7 +800,7 @@ /// @param to The new owner /// @param tokenId The RFT to transfer #[weight(>::transfer_creating_removing())] - fn transfer(&mut self, caller: caller, to: address, token_id: uint256) -> Result { + fn transfer(&mut self, caller: Caller, to: Address, token_id: U256) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); let token = token_id.try_into()?; @@ -830,10 +825,10 @@ #[weight(>::transfer_creating_removing())] fn transfer_cross( &mut self, - caller: caller, + caller: Caller, to: eth::CrossAddress, - token_id: uint256, - ) -> Result { + token_id: U256, + ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let to = to.into_sub_cross_account::()?; let token = token_id.try_into()?; @@ -858,11 +853,11 @@ #[weight(>::transfer_creating_removing())] fn transfer_from_cross( &mut self, - caller: caller, + caller: Caller, from: eth::CrossAddress, to: eth::CrossAddress, - token_id: uint256, - ) -> Result { + token_id: U256, + ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let from = from.into_sub_cross_account::()?; let to = to.into_sub_cross_account::()?; @@ -888,7 +883,7 @@ /// @param tokenId The RFT to transfer #[solidity(hide)] #[weight(>::burn_from())] - fn burn_from(&mut self, caller: caller, from: address, token_id: uint256) -> Result { + fn burn_from(&mut self, caller: Caller, from: Address, token_id: U256) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let from = T::CrossAccountId::from_eth(from); let token = token_id.try_into()?; @@ -914,10 +909,10 @@ #[weight(>::burn_from())] fn burn_from_cross( &mut self, - caller: caller, + caller: Caller, from: eth::CrossAddress, - token_id: uint256, - ) -> Result { + token_id: U256, + ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let from = from.into_sub_cross_account::()?; let token = token_id.try_into()?; @@ -934,7 +929,7 @@ } /// @notice Returns next free RFT ID. - fn next_token_id(&self) -> Result { + fn next_token_id(&self) -> Result { self.consume_store_reads(1)?; Ok(>::get(self.id) .checked_add(1) @@ -949,7 +944,7 @@ /// @param tokenIds IDs of the minted RFTs #[solidity(hide)] #[weight(>::create_multiple_items(token_ids.len() as u32))] - fn mint_bulk(&mut self, caller: caller, to: address, token_ids: Vec) -> Result { + fn mint_bulk(&mut self, caller: Caller, to: Address, token_ids: Vec) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); let mut expected_index = >::get(self.id) @@ -994,9 +989,9 @@ #[weight(>::create_multiple_items(tokens.len() as u32))] fn mint_bulk_with_token_uri( &mut self, - caller: caller, - to: address, - tokens: Vec<(uint256, string)>, + caller: Caller, + to: Address, + tokens: Vec<(U256, String)>, ) -> Result { let key = key::url(); let caller = T::CrossAccountId::from_eth(caller); @@ -1051,10 +1046,10 @@ #[weight(>::create_item())] fn mint_cross( &mut self, - caller: caller, + caller: Caller, to: eth::CrossAddress, properties: Vec, - ) -> Result { + ) -> Result { let token_id = >::get(self.id) .checked_add(1) .ok_or("item id overflow")?; @@ -1093,7 +1088,7 @@ /// Returns EVM address for refungible token /// /// @param token ID of the token - fn token_contract_address(&self, token: uint256) -> Result
{ + fn token_contract_address(&self, token: U256) -> Result
{ Ok(T::EvmTokenAddressMapping::token_to_address( self.id, token.try_into().map_err(|_| "token id overflow")?, @@ -1101,7 +1096,7 @@ } /// @notice Returns collection helper contract address - fn collection_helper_address(&self) -> Result
{ + fn collection_helper_address(&self) -> Result
{ Ok(T::ContractAddress::get()) } } --- a/pallets/refungible/src/erc_token.rs +++ b/pallets/refungible/src/erc_token.rs @@ -37,6 +37,7 @@ use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder}; use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _}; use sp_std::vec::Vec; +use sp_core::U256; use up_data_structs::TokenId; use crate::{ @@ -51,11 +52,11 @@ #[solidity_interface(name = ERC1633)] impl RefungibleTokenHandle { - fn parent_token(&self) -> Result
{ + fn parent_token(&self) -> Result
{ Ok(collection_id_to_address(self.id)) } - fn parent_token_id(&self) -> Result { + fn parent_token_id(&self) -> Result { Ok(self.1.into()) } } @@ -68,19 +69,19 @@ /// of burning tokens the transfer is to 0. Transfer { #[indexed] - from: address, + from: Address, #[indexed] - to: address, - value: uint256, + to: Address, + value: U256, }, /// @dev This event is emitted when the amount of tokens (value) is approved /// by the owner to be used by the spender. Approval { #[indexed] - owner: address, + owner: Address, #[indexed] - spender: address, - value: uint256, + spender: Address, + value: U256, }, } @@ -91,25 +92,25 @@ #[solidity_interface(name = ERC20, events(ERC20Events))] impl RefungibleTokenHandle { /// @return the name of the token. - fn name(&self) -> Result { + fn name(&self) -> Result { Ok(decode_utf16(self.name.iter().copied()) .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)) - .collect::()) + .collect::()) } /// @return the symbol of the token. - fn symbol(&self) -> Result { - Ok(string::from_utf8_lossy(&self.token_prefix).into()) + fn symbol(&self) -> Result { + Ok(String::from_utf8_lossy(&self.token_prefix).into()) } /// @dev Total number of tokens in existence - fn total_supply(&self) -> Result { + fn total_supply(&self) -> Result { self.consume_store_reads(1)?; Ok(>::get((self.id, self.1)).into()) } /// @dev Not supported - fn decimals(&self) -> Result { + fn decimals(&self) -> Result { // Decimals aren't supported for refungible tokens Ok(0) } @@ -117,7 +118,7 @@ /// @dev Gets the balance of the specified address. /// @param owner The address to query the balance of. /// @return An uint256 representing the amount owned by the passed address. - fn balance_of(&self, owner: address) -> Result { + fn balance_of(&self, owner: Address) -> Result { self.consume_store_reads(1)?; let owner = T::CrossAccountId::from_eth(owner); let balance = >::get((self.id, self.1, owner)); @@ -128,7 +129,7 @@ /// @param to The address to transfer to. /// @param amount The amount to be transferred. #[weight(>::transfer())] - fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result { + fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); let amount = amount.try_into().map_err(|_| "amount overflow")?; @@ -148,10 +149,10 @@ #[weight(>::transfer_from())] fn transfer_from( &mut self, - caller: caller, - from: address, - to: address, - amount: uint256, + caller: Caller, + from: Address, + to: Address, + amount: U256, ) -> Result { let caller = T::CrossAccountId::from_eth(caller); let from = T::CrossAccountId::from_eth(from); @@ -174,7 +175,7 @@ /// @param spender The address which will spend the funds. /// @param amount The amount of tokens to be spent. #[weight(>::approve())] - fn approve(&mut self, caller: caller, spender: address, amount: uint256) -> Result { + fn approve(&mut self, caller: Caller, spender: Address, amount: U256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let spender = T::CrossAccountId::from_eth(spender); let amount = amount.try_into().map_err(|_| "amount overflow")?; @@ -188,7 +189,7 @@ /// @param owner address The address which owns the funds. /// @param spender address The address which will spend the funds. /// @return A uint256 specifying the amount of tokens still available for the spender. - fn allowance(&self, owner: address, spender: address) -> Result { + fn allowance(&self, owner: Address, spender: Address) -> Result { self.consume_store_reads(1)?; let owner = T::CrossAccountId::from_eth(owner); let spender = T::CrossAccountId::from_eth(spender); @@ -208,7 +209,7 @@ /// @param amount The amount that will be burnt. #[weight(>::burn_from())] #[solidity(hide)] - fn burn_from(&mut self, caller: caller, from: address, amount: uint256) -> Result { + fn burn_from(&mut self, caller: Caller, from: Address, amount: U256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let from = T::CrossAccountId::from_eth(from); let amount = amount.try_into().map_err(|_| "amount overflow")?; @@ -228,9 +229,9 @@ #[weight(>::burn_from())] fn burn_from_cross( &mut self, - caller: caller, + caller: Caller, from: pallet_common::eth::CrossAddress, - amount: uint256, + amount: U256, ) -> Result { let caller = T::CrossAccountId::from_eth(caller); let from = from.into_sub_cross_account::()?; @@ -254,9 +255,9 @@ #[weight(>::approve())] fn approve_cross( &mut self, - caller: caller, + caller: Caller, spender: pallet_common::eth::CrossAddress, - amount: uint256, + amount: U256, ) -> Result { let caller = T::CrossAccountId::from_eth(caller); let spender = spender.into_sub_cross_account::()?; @@ -270,7 +271,7 @@ /// Throws if `msg.sender` doesn't owns all of the tokens. /// @param amount New total amount of the tokens. #[weight(>::repartition_item())] - fn repartition(&mut self, caller: caller, amount: uint256) -> Result { + fn repartition(&mut self, caller: Caller, amount: U256) -> Result { let caller = T::CrossAccountId::from_eth(caller); let amount = amount.try_into().map_err(|_| "amount overflow")?; @@ -284,9 +285,9 @@ #[weight(>::transfer())] fn transfer_cross( &mut self, - caller: caller, + caller: Caller, to: pallet_common::eth::CrossAddress, - amount: uint256, + amount: U256, ) -> Result { let caller = T::CrossAccountId::from_eth(caller); let to = to.into_sub_cross_account::()?; @@ -307,10 +308,10 @@ #[weight(>::transfer_from())] fn transfer_from_cross( &mut self, - caller: caller, + caller: Caller, from: pallet_common::eth::CrossAddress, to: pallet_common::eth::CrossAddress, - amount: uint256, + amount: U256, ) -> Result { let caller = T::CrossAccountId::from_eth(caller); let from = from.into_sub_cross_account::()?; --- a/pallets/refungible/src/stubs/UniqueRefungible.sol +++ b/pallets/refungible/src/stubs/UniqueRefungible.sol @@ -416,11 +416,9 @@ /// Set the collection access method. /// @param mode Access mode - /// 0 for Normal - /// 1 for AllowList /// @dev EVM selector for this function is: 0x41835d4c, /// or in textual repr: setCollectionAccess(uint8) - function setCollectionAccess(uint8 mode) public { + function setCollectionAccess(AccessMode mode) public { require(false, stub_error); mode; dummy = 0; @@ -585,6 +583,14 @@ uint256 sub; } +/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]). +enum AccessMode { + /// Access grant for owner and admins. Used as default. + Normal, + /// Like a [`Normal`](AccessMode::Normal) but also users in allow list. + AllowList +} + /// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field. struct CollectionNestingPermission { CollectionPermissionField field; --- a/pallets/unique/src/eth/mod.rs +++ b/pallets/unique/src/eth/mod.rs @@ -56,10 +56,10 @@ } fn convert_data( - caller: caller, - name: string, - description: string, - token_prefix: string, + caller: Caller, + name: String, + description: String, + token_prefix: String, ) -> Result<( T::CrossAccountId, CollectionName, @@ -87,13 +87,13 @@ #[inline(always)] fn create_collection_internal( - caller: caller, - value: value, - name: string, + caller: Caller, + value: Value, + name: String, collection_mode: CollectionMode, - description: string, - token_prefix: string, -) -> Result
{ + description: String, + token_prefix: String, +) -> Result
{ let (caller, name, description, token_prefix) = convert_data::(caller, name, description, token_prefix)?; let data = CreateCollectionData { @@ -118,7 +118,7 @@ Ok(address) } -fn check_sent_amount_equals_collection_creation_price(value: value) -> Result<()> { +fn check_sent_amount_equals_collection_creation_price(value: Value) -> Result<()> { let value = value.as_u128(); let creation_price: u128 = T::CollectionCreationPrice::get() .try_into() @@ -149,12 +149,12 @@ #[solidity(rename_selector = "createNFTCollection")] fn create_nft_collection( &mut self, - caller: caller, - value: value, - name: string, - description: string, - token_prefix: string, - ) -> Result
{ + caller: Caller, + value: Value, + name: String, + description: String, + token_prefix: String, + ) -> Result
{ let (caller, name, description, token_prefix) = convert_data::(caller, name, description, token_prefix)?; let data = CreateCollectionData { @@ -188,12 +188,12 @@ #[solidity(hide)] fn create_nonfungible_collection( &mut self, - caller: caller, - value: value, - name: string, - description: string, - token_prefix: string, - ) -> Result
{ + caller: Caller, + value: Value, + name: String, + description: String, + token_prefix: String, + ) -> Result
{ create_collection_internal::( caller, value, @@ -208,12 +208,12 @@ #[solidity(rename_selector = "createRFTCollection")] fn create_rft_collection( &mut self, - caller: caller, - value: value, - name: string, - description: string, - token_prefix: string, - ) -> Result
{ + caller: Caller, + value: Value, + name: String, + description: String, + token_prefix: String, + ) -> Result
{ create_collection_internal::( caller, value, @@ -228,13 +228,13 @@ #[solidity(rename_selector = "createFTCollection")] fn create_fungible_collection( &mut self, - caller: caller, - value: value, - name: string, - decimals: uint8, - description: string, - token_prefix: string, - ) -> Result
{ + caller: Caller, + value: Value, + name: String, + decimals: u8, + description: String, + token_prefix: String, + ) -> Result
{ create_collection_internal::( caller, value, @@ -248,9 +248,9 @@ #[solidity(rename_selector = "makeCollectionERC721MetadataCompatible")] fn make_collection_metadata_compatible( &mut self, - caller: caller, - collection: address, - base_uri: string, + caller: Caller, + collection: Address, + base_uri: String, ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let collection = @@ -334,7 +334,7 @@ } #[weight(>::destroy_collection())] - fn destroy_collection(&mut self, caller: caller, collection_address: address) -> Result { + fn destroy_collection(&mut self, caller: Caller, collection_address: Address) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); let collection_id = pallet_common::eth::map_eth_to_id(&collection_address) @@ -346,7 +346,7 @@ /// Check if a collection exists /// @param collectionAddress Address of the collection in question /// @return bool Does the collection exist? - fn is_collection_exist(&self, _caller: caller, collection_address: address) -> Result { + fn is_collection_exist(&self, _caller: Caller, collection_address: Address) -> Result { if let Some(id) = pallet_common::eth::map_eth_to_id(&collection_address) { let collection_id = id; return Ok(>::contains_key(collection_id)); @@ -355,7 +355,7 @@ Ok(false) } - fn collection_creation_fee(&self) -> Result { + fn collection_creation_fee(&self) -> Result { let price: u128 = T::CollectionCreationPrice::get() .try_into() .map_err(|_| ()) // workaround for `expect` requiring `Debug` trait @@ -366,14 +366,14 @@ /// Returns address of a collection. /// @param collectionId - CollectionId of the collection /// @return eth mirror address of the collection - fn collection_address(&self, collection_id: uint32) -> Result
{ + fn collection_address(&self, collection_id: u32) -> Result
{ Ok(collection_id_to_address(collection_id.into())) } /// Returns collectionId of a collection. /// @param collectionAddress - Eth address of the collection /// @return collectionId of the collection - fn collection_id(&self, collection_address: address) -> Result { + fn collection_id(&self, collection_address: Address) -> Result { map_eth_to_id(&collection_address) .map(|id| id.0) .ok_or(Error::Revert(format!( --- a/runtime/tests/src/tests.rs +++ b/runtime/tests/src/tests.rs @@ -323,7 +323,7 @@ .map(|d| { d.into() }) .collect() )); - for (index, data) in items_data.into_iter().enumerate() { + for (index, _data) in items_data.into_iter().enumerate() { let balance = >::get(( CollectionId(1), TokenId((index + 1) as u32), --- a/tests/src/eth/abi/fungible.json +++ b/tests/src/eth/abi/fungible.json @@ -488,7 +488,9 @@ "type": "function" }, { - "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }], + "inputs": [ + { "internalType": "enum AccessMode", "name": "mode", "type": "uint8" } + ], "name": "setCollectionAccess", "outputs": [], "stateMutability": "nonpayable", --- a/tests/src/eth/abi/nonFungible.json +++ b/tests/src/eth/abi/nonFungible.json @@ -630,7 +630,9 @@ "type": "function" }, { - "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }], + "inputs": [ + { "internalType": "enum AccessMode", "name": "mode", "type": "uint8" } + ], "name": "setCollectionAccess", "outputs": [], "stateMutability": "nonpayable", --- a/tests/src/eth/abi/reFungible.json +++ b/tests/src/eth/abi/reFungible.json @@ -612,7 +612,9 @@ "type": "function" }, { - "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }], + "inputs": [ + { "internalType": "enum AccessMode", "name": "mode", "type": "uint8" } + ], "name": "setCollectionAccess", "outputs": [], "stateMutability": "nonpayable", --- a/tests/src/eth/api/UniqueFungible.sol +++ b/tests/src/eth/api/UniqueFungible.sol @@ -175,11 +175,9 @@ /// Set the collection access method. /// @param mode Access mode - /// 0 for Normal - /// 1 for AllowList /// @dev EVM selector for this function is: 0x41835d4c, /// or in textual repr: setCollectionAccess(uint8) - function setCollectionAccess(uint8 mode) external; + function setCollectionAccess(AccessMode mode) external; /// Checks that user allowed to operate with collection. /// @@ -285,6 +283,14 @@ uint256 sub; } +/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]). +enum AccessMode { + /// Access grant for owner and admins. Used as default. + Normal, + /// Like a [`Normal`](AccessMode::Normal) but also users in allow list. + AllowList +} + /// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field. struct CollectionNestingPermission { CollectionPermissionField field; --- a/tests/src/eth/api/UniqueNFT.sol +++ b/tests/src/eth/api/UniqueNFT.sol @@ -275,11 +275,9 @@ /// Set the collection access method. /// @param mode Access mode - /// 0 for Normal - /// 1 for AllowList /// @dev EVM selector for this function is: 0x41835d4c, /// or in textual repr: setCollectionAccess(uint8) - function setCollectionAccess(uint8 mode) external; + function setCollectionAccess(AccessMode mode) external; /// Checks that user allowed to operate with collection. /// @@ -385,6 +383,14 @@ uint256 sub; } +/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]). +enum AccessMode { + /// Access grant for owner and admins. Used as default. + Normal, + /// Like a [`Normal`](AccessMode::Normal) but also users in allow list. + AllowList +} + /// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field. struct CollectionNestingPermission { CollectionPermissionField field; --- a/tests/src/eth/api/UniqueRefungible.sol +++ b/tests/src/eth/api/UniqueRefungible.sol @@ -275,11 +275,9 @@ /// Set the collection access method. /// @param mode Access mode - /// 0 for Normal - /// 1 for AllowList /// @dev EVM selector for this function is: 0x41835d4c, /// or in textual repr: setCollectionAccess(uint8) - function setCollectionAccess(uint8 mode) external; + function setCollectionAccess(AccessMode mode) external; /// Checks that user allowed to operate with collection. /// @@ -385,6 +383,14 @@ uint256 sub; } +/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]). +enum AccessMode { + /// Access grant for owner and admins. Used as default. + Normal, + /// Like a [`Normal`](AccessMode::Normal) but also users in allow list. + AllowList +} + /// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field. struct CollectionNestingPermission { CollectionPermissionField field; -- gitstuff