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

difftreelog

Merge branch 'feature/refinement_on_named_structures' into develop

Yaroslav Bolyukin2022-12-22parents: #2abdf7d #be088e7.patch.diff
in: master

50 files changed

modifiedcrates/evm-coder/procedural/src/abi_derive/derive_enum.rsdiffbeforeafterboth
1use quote::quote;1use quote::quote;
2
3use super::extract_docs;
24
3pub fn impl_solidity_option<'a>(5pub fn impl_solidity_option<'a>(
6 docs: Vec<String>,
4 name: &proc_macro2::Ident,7 name: &proc_macro2::Ident,
5 enum_options: impl Iterator<Item = &'a syn::Ident>,8 enum_options: impl Iterator<Item = &'a syn::Variant> + Clone,
6) -> proc_macro2::TokenStream {9) -> proc_macro2::TokenStream {
7 let enum_options = enum_options.map(|opt| {10 let variant_names = enum_options.clone().map(|opt| {
11 let opt = &opt.ident;
8 let s = name.to_string() + "." + opt.to_string().as_str();12 let s = name.to_string() + "." + opt.to_string().as_str();
9 let as_string = proc_macro2::Literal::string(s.as_str());13 let as_string = proc_macro2::Literal::string(s.as_str());
10 quote!(#name::#opt => #as_string,)14 quote!(#name::#opt => #as_string,)
11 });15 });
16 let solidity_name = name.to_string();
17
18 let solidity_fields = enum_options.map(|v| {
19 let docs = extract_docs(&v.attrs).expect("TODO: handle bad docs");
20 let name = v.ident.to_string();
21 quote! {
22 SolidityEnumVariant {
23 docs: &[#(#docs),*],
24 name: #name,
25 }
26 }
27 });
28
12 quote!(29 quote!(
13 #[cfg(feature = "stubgen")]30 #[cfg(feature = "stubgen")]
14 impl ::evm_coder::solidity::SolidityEnum for #name {31 impl ::evm_coder::solidity::SolidityEnumTy for #name {
32 fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector) -> String {
33 use evm_coder::solidity::*;
34 use core::fmt::Write;
35 let interface = SolidityEnum {
36 docs: &[#(#docs),*],
37 name: #solidity_name,
38 fields: &[#(
39 #solidity_fields,
40 )*],
41 };
42 let mut out = String::new();
43 let _ = interface.format(&mut out, tc);
44 tc.collect(out);
45 #solidity_name.to_string()
46 }
15 fn solidity_option(&self) -> &str {47 fn solidity_option(&self) -> &str {
16 match self {48 match self {
17 #(#enum_options)*49 #(#variant_names)*
18 }50 }
19 }51 }
20 }52 }
2355
24pub fn impl_enum_from_u8<'a>(56pub fn impl_enum_from_u8<'a>(
25 name: &proc_macro2::Ident,57 name: &proc_macro2::Ident,
26 enum_options: impl Iterator<Item = &'a syn::Ident>,58 enum_options: impl Iterator<Item = &'a syn::Variant>,
27) -> proc_macro2::TokenStream {59) -> proc_macro2::TokenStream {
28 let error_str = format!("Value not convertible into enum \"{name}\"");60 let error_str = format!("Value not convertible into enum \"{name}\"");
29 let error_str = proc_macro2::Literal::string(&error_str);61 let error_str = proc_macro2::Literal::string(&error_str);
30 let enum_options = enum_options.enumerate().map(|(i, opt)| {62 let enum_options = enum_options.enumerate().map(|(i, opt)| {
63 let opt = &opt.ident;
31 let n = proc_macro2::Literal::u8_suffixed(i as u8);64 let n = proc_macro2::Literal::u8_suffixed(i as u8);
32 quote! {#n => Ok(#name::#opt),}65 quote! {#n => Ok(#name::#opt),}
33 });66 });
93 writer: &mut impl ::core::fmt::Write,126 writer: &mut impl ::core::fmt::Write,
94 tc: &::evm_coder::solidity::TypeCollector,127 tc: &::evm_coder::solidity::TypeCollector,
95 ) -> ::core::fmt::Result {128 ) -> ::core::fmt::Result {
96 write!(writer, "{}", tc.collect_struct::<Self>())129 write!(writer, "{}", tc.collect_enum::<Self>())
97 }130 }
98131
99 fn is_simple() -> bool {132 fn is_simple() -> bool {
104 writer: &mut impl ::core::fmt::Write,137 writer: &mut impl ::core::fmt::Write,
105 tc: &::evm_coder::solidity::TypeCollector,138 tc: &::evm_coder::solidity::TypeCollector,
106 ) -> ::core::fmt::Result {139 ) -> ::core::fmt::Result {
107 write!(writer, "{}", <#name as ::evm_coder::solidity::SolidityEnum>::solidity_option(&<#name>::default()))140 write!(writer, "{}", <#name as ::evm_coder::solidity::SolidityEnumTy>::solidity_option(&<#name>::default()))
108 }141 }
109 }142 }
110 )143 )
111}144}
112
113pub fn impl_enum_solidity_struct_collect<'a>(
114 name: &syn::Ident,
115 enum_options: impl Iterator<Item = &'a syn::Ident>,
116 option_count: usize,
117 enum_options_docs: impl Iterator<Item = syn::Result<Vec<proc_macro2::TokenStream>>>,
118 docs: &[proc_macro2::TokenStream],
119) -> proc_macro2::TokenStream {
120 let string_name = name.to_string();
121 let enum_options = enum_options
122 .zip(enum_options_docs)
123 .enumerate()
124 .map(|(i, (opt, doc))| {
125 let opt = proc_macro2::Literal::string(opt.to_string().as_str());
126 let doc = doc.expect("Doc parsing error");
127 let comma = if i != option_count - 1 { "," } else { "" };
128 quote! {
129 #(#doc)*
130 writeln!(str, "\t{}{}", #opt, #comma).expect("Enum format option");
131 }
132 });
133
134 quote!(
135 #[cfg(feature = "stubgen")]
136 impl ::evm_coder::solidity::StructCollect for #name {
137 fn name() -> String {
138 #string_name.into()
139 }
140
141 fn declaration() -> String {
142 use std::fmt::Write;
143
144 let mut str = String::new();
145 #(#docs)*
146 writeln!(str, "enum {} {{", <Self as ::evm_coder::solidity::StructCollect>::name()).unwrap();
147 #(#enum_options)*
148 writeln!(str, "}}").unwrap();
149 str
150 }
151 }
152 )
153}
154145
155pub fn check_and_count_options(de: &syn::DataEnum) -> syn::Result<usize> {146pub fn check_and_count_options(de: &syn::DataEnum) -> syn::Result<usize> {
156 let mut count = 0;147 let mut count = 0;
modifiedcrates/evm-coder/procedural/src/abi_derive/derive_struct.rsdiffbeforeafterboth
1use super::extract_docs;1use super::extract_docs;
2use quote::quote;2use quote::quote;
3use syn::Field;
34
4pub fn tuple_type<'a>(5pub fn tuple_type<'a>(
5 field_types: impl Iterator<Item = &'a syn::Type> + Clone,6 field_types: impl Iterator<Item = &'a syn::Type> + Clone,
87 &field.ty88 &field.ty
88}89}
89
90pub fn map_field_to_doc(field: &syn::Field) -> syn::Result<Vec<proc_macro2::TokenStream>> {
91 extract_docs(&field.attrs, true)
92}
9390
94pub fn impl_can_be_placed_in_vec(ident: &syn::Ident) -> proc_macro2::TokenStream {91pub fn impl_can_be_placed_in_vec(ident: &syn::Ident) -> proc_macro2::TokenStream {
95 quote! {92 quote! {
147144
148pub fn impl_struct_solidity_type<'a>(145pub fn impl_struct_solidity_type<'a>(
149 name: &syn::Ident,146 name: &syn::Ident,
147 docs: Vec<String>,
150 field_types: impl Iterator<Item = &'a syn::Type> + Clone,148 fields: impl Iterator<Item = &'a Field> + Clone,
151 params_count: usize,
152) -> proc_macro2::TokenStream {149) -> proc_macro2::TokenStream {
150 let solidity_name = name.to_string();
153 let len = proc_macro2::Literal::usize_suffixed(params_count);151 let solidity_fields = fields.enumerate().map(|(i, f)| {
152 let name = f
153 .ident
154 .as_ref()
155 .map(|i| i.to_string())
156 .unwrap_or_else(|| format!("field_{i}"));
157 let ty = &f.ty;
158 let docs = extract_docs(&f.attrs).expect("TODO: handle bad docs");
159 quote! {
160 SolidityStructField::<#ty> {
161 docs: &[#(#docs),*],
162 name: #name,
163 ty: ::core::marker::PhantomData,
164 }
165 }
166 });
154 quote! {167 quote! {
155 #[cfg(feature = "stubgen")]168 #[cfg(feature = "stubgen")]
156 impl ::evm_coder::solidity::SolidityType for #name {169 impl ::evm_coder::solidity::SolidityStructTy for #name {
170 /// Generate solidity definitions for methods described in this struct
157 fn names(tc: &::evm_coder::solidity::TypeCollector) -> Vec<String> {171 fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector) -> String {
158 let mut collected =
159 Vec::with_capacity(<Self as ::evm_coder::solidity::SolidityType>::len());172 use evm_coder::solidity::*;
173 use core::fmt::Write;
174 let interface = SolidityStruct {
175 docs: &[#(#docs),*],
160 #({176 name: #solidity_name,
177 fields: (#(
178 #solidity_fields,
179 )*),
180 };
161 let mut out = String::new();181 let mut out = String::new();
162 <#field_types as ::evm_coder::solidity::SolidityTypeName>::solidity_name(&mut out, tc)182 let _ = interface.format(&mut out, tc);
163 .expect("no fmt error");
164 collected.push(out);183 tc.collect(out);
165 })*
166 collected
167 }
168
169 fn len() -> usize {
170 #len184 #solidity_name.to_string()
171 }185 }
172 }186 }
173 }187 }
174}188}
216 }230 }
217}231}
218
219pub fn impl_struct_solidity_struct_collect<'a>(
220 name: &syn::Ident,
221 field_names: impl Iterator<Item = proc_macro2::Ident> + Clone,
222 field_types: impl Iterator<Item = &'a syn::Type> + Clone,
223 field_docs: impl Iterator<Item = syn::Result<Vec<proc_macro2::TokenStream>>> + Clone,
224 docs: &[proc_macro2::TokenStream],
225) -> syn::Result<proc_macro2::TokenStream> {
226 let string_name = name.to_string();
227 let name_type = field_names
228 .into_iter()
229 .zip(field_types)
230 .zip(field_docs)
231 .map(|((name, ty), doc)| {
232 let field_docs = doc.expect("Doc parse error");
233 let name = format!("{}", name);
234 quote!(
235 #(#field_docs)*
236 write!(str, "\t{} ", <#ty as ::evm_coder::solidity::StructCollect>::name()).unwrap();
237 writeln!(str, "{};", #name).unwrap();
238 )
239 });
240
241 Ok(quote! {
242 #[cfg(feature = "stubgen")]
243 impl ::evm_coder::solidity::StructCollect for #name {
244 fn name() -> String {
245 #string_name.into()
246 }
247
248 fn declaration() -> String {
249 use std::fmt::Write;
250
251 let mut str = String::new();
252 #(#docs)*
253 writeln!(str, "struct {} {{", Self::name()).unwrap();
254 #(#name_type)*
255 writeln!(str, "}}").unwrap();
256 str
257 }
258 }
259 })
260}
261232
modifiedcrates/evm-coder/procedural/src/abi_derive/mod.rsdiffbeforeafterboth
19 ast: &syn::DeriveInput,19 ast: &syn::DeriveInput,
20) -> syn::Result<proc_macro2::TokenStream> {20) -> syn::Result<proc_macro2::TokenStream> {
21 let name = &ast.ident;21 let name = &ast.ident;
22 let docs = extract_docs(&ast.attrs, false)?;22 let docs = extract_docs(&ast.attrs)?;
23 let (is_named_fields, field_names, field_types, field_docs, params_count) = match ds.fields {23 let (is_named_fields, field_names, field_types, params_count) = match ds.fields {
24 syn::Fields::Named(ref fields) => Ok((24 syn::Fields::Named(ref fields) => Ok((
25 true,25 true,
26 fields.named.iter().enumerate().map(map_field_to_name),26 fields.named.iter().enumerate().map(map_field_to_name),
27 fields.named.iter().map(map_field_to_type),27 fields.named.iter().map(map_field_to_type),
28 fields.named.iter().map(map_field_to_doc),
29 fields.named.len(),28 fields.named.len(),
30 )),29 )),
31 syn::Fields::Unnamed(ref fields) => Ok((30 syn::Fields::Unnamed(ref fields) => Ok((
32 false,31 false,
33 fields.unnamed.iter().enumerate().map(map_field_to_name),32 fields.unnamed.iter().enumerate().map(map_field_to_name),
34 fields.unnamed.iter().map(map_field_to_type),33 fields.unnamed.iter().map(map_field_to_type),
35 fields.unnamed.iter().map(map_field_to_doc),
36 fields.unnamed.len(),34 fields.unnamed.len(),
37 )),35 )),
38 syn::Fields::Unit => Err(syn::Error::new(name.span(), "Unit structs not supported")),36 syn::Fields::Unit => Err(syn::Error::new(name.span(), "Unit structs not supported")),
52 let abi_type = impl_struct_abi_type(name, tuple_type.clone());50 let abi_type = impl_struct_abi_type(name, tuple_type.clone());
53 let abi_read = impl_struct_abi_read(name, tuple_type, tuple_names, struct_from_tuple);51 let abi_read = impl_struct_abi_read(name, tuple_type, tuple_names, struct_from_tuple);
54 let abi_write = impl_struct_abi_write(name, is_named_fields, tuple_ref_type, tuple_data);52 let abi_write = impl_struct_abi_write(name, is_named_fields, tuple_ref_type, tuple_data);
55 let solidity_type = impl_struct_solidity_type(name, field_types.clone(), params_count);53 let solidity_type = impl_struct_solidity_type(name, docs, ds.fields.iter());
56 let solidity_type_name =54 let solidity_type_name =
57 impl_struct_solidity_type_name(name, field_types.clone(), params_count);55 impl_struct_solidity_type_name(name, field_types.clone(), params_count);
58 let solidity_struct_collect =
59 impl_struct_solidity_struct_collect(name, field_names, field_types, field_docs, &docs)?;
6056
61 Ok(quote! {57 Ok(quote! {
62 #can_be_plcaed_in_vec58 #can_be_plcaed_in_vec
65 #abi_write61 #abi_write
66 #solidity_type62 #solidity_type
67 #solidity_type_name63 #solidity_type_name
68 #solidity_struct_collect
69 })64 })
70}65}
7166
75) -> syn::Result<proc_macro2::TokenStream> {70) -> syn::Result<proc_macro2::TokenStream> {
76 let name = &ast.ident;71 let name = &ast.ident;
77 check_repr_u8(name, &ast.attrs)?;72 check_repr_u8(name, &ast.attrs)?;
78 let docs = extract_docs(&ast.attrs, false)?;73 let docs = extract_docs(&ast.attrs)?;
79 let option_count = check_and_count_options(de)?;
80 let enum_options = de.variants.iter().map(|v| &v.ident);74 let enum_options = de.variants.iter();
81 let enum_options_docs = de.variants.iter().map(|v| extract_docs(&v.attrs, true));
8275
83 let from = impl_enum_from_u8(name, enum_options.clone());76 let from = impl_enum_from_u8(name, enum_options.clone());
84 let solidity_option = impl_solidity_option(name, enum_options.clone());77 let solidity_option = impl_solidity_option(docs, name, enum_options.clone());
85 let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);78 let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);
86 let abi_type = impl_enum_abi_type(name);79 let abi_type = impl_enum_abi_type(name);
87 let abi_read = impl_enum_abi_read(name);80 let abi_read = impl_enum_abi_read(name);
88 let abi_write = impl_enum_abi_write(name);81 let abi_write = impl_enum_abi_write(name);
89 let solidity_type_name = impl_enum_solidity_type_name(name);82 let solidity_type_name = impl_enum_solidity_type_name(name);
90 let solidity_struct_collect = impl_enum_solidity_struct_collect(
91 name,
92 enum_options,
93 option_count,
94 enum_options_docs,
95 &docs,
96 );
9783
98 Ok(quote! {84 Ok(quote! {
99 #from85 #from
103 #abi_read89 #abi_read
104 #abi_write90 #abi_write
105 #solidity_type_name91 #solidity_type_name
106 #solidity_struct_collect
107 })92 })
108}93}
10994
110fn extract_docs(95fn extract_docs(attrs: &[syn::Attribute]) -> syn::Result<Vec<String>> {
111 attrs: &[syn::Attribute],
112 is_field_doc: bool,
113) -> syn::Result<Vec<proc_macro2::TokenStream>> {
114 attrs96 attrs
115 .iter()97 .iter()
116 .filter_map(|attr| {98 .filter_map(|attr| {
131 }113 }
132 None114 None
133 })115 })
134 .enumerate()
135 .map(|(i, doc)| {
136 let doc = doc?;
137 let doc = doc.trim();
138 let dev = if i == 0 { " @dev" } else { "" };
139 let tab = if is_field_doc { "\t" } else { "" };
140 Ok(quote! {
141 writeln!(str, "{}///{} {}", #tab, #dev, #doc).unwrap();
142 })
143 })
144 .collect()116 .collect()
145}117}
146118
modifiedcrates/evm-coder/src/abi/impls.rsdiffbeforeafterboth
135 }135 }
136}136}
137
138impl sealed::CanBePlacedInVec for Property {}
139
140impl AbiType for Property {
141 const SIGNATURE: SignatureUnit = make_signature!(new fixed("(string,bytes)"));
142
143 fn is_dynamic() -> bool {
144 string::is_dynamic() || bytes::is_dynamic()
145 }
146
147 fn size() -> usize {
148 <string as AbiType>::size() + <bytes as AbiType>::size()
149 }
150}
151
152impl AbiRead for Property {
153 fn abi_read(reader: &mut AbiReader) -> Result<Property> {
154 let size = if !Property::is_dynamic() {
155 Some(<Property as AbiType>::size())
156 } else {
157 None
158 };
159 let mut subresult = reader.subresult(size)?;
160 let key = <string>::abi_read(&mut subresult)?;
161 let value = <bytes>::abi_read(&mut subresult)?;
162
163 Ok(Property { key, value })
164 }
165}
166
167impl AbiWrite for Property {
168 fn abi_write(&self, writer: &mut AbiWriter) {
169 (&self.key, &self.value).abi_write(writer);
170 }
171}
172137
173impl<T: AbiWrite + AbiType> AbiWrite for Vec<T> {138impl<T: AbiWrite + AbiType> AbiWrite for Vec<T> {
174 fn abi_write(&self, writer: &mut AbiWriter) {139 fn abi_write(&self, writer: &mut AbiWriter) {
modifiedcrates/evm-coder/src/lib.rsdiffbeforeafterboth
197 }197 }
198 }198 }
199
200 #[derive(Debug, Default)]
201 pub struct Property {
202 pub key: string,
203 pub value: bytes,
204 }
205}199}
206200
207/// Parseable EVM call, this trait should be implemented with [`solidity_interface`] macro201/// Parseable EVM call, this trait should be implemented with [`solidity_interface`] macro
modifiedcrates/evm-coder/src/solidity/impls.rsdiffbeforeafterboth
1use super::{TypeCollector, SolidityTypeName, SolidityType, StructCollect};1use super::{TypeCollector, SolidityTypeName, SolidityTupleTy};
2use crate::{sealed, types::*};2use crate::{sealed, types::*};
3use core::fmt;3use core::fmt;
4use primitive_types::{U256, H160};4use primitive_types::{U256, H160};
18 }18 }
19 }19 }
20
21 impl StructCollect for $ty {
22 fn name() -> String {
23 $name.to_string()
24 }
25
26 fn declaration() -> String {
27 String::default()
28 }
29 }
30 )*20 )*
31 };21 };
32}22}
8171
82macro_rules! impl_tuples {72macro_rules! impl_tuples {
83 ($($ident:ident)+) => {73 ($($ident:ident)+) => {
84 impl<$($ident: SolidityTypeName + 'static),+> SolidityType for ($($ident,)+) {74 impl<$($ident: SolidityTypeName + 'static),+> SolidityTupleTy for ($($ident,)+) {
85 fn names(tc: &TypeCollector) -> Vec<string> {75 fn fields(tc: &TypeCollector) -> Vec<string> {
86 let mut collected = Vec::with_capacity(Self::len());76 let mut collected = Vec::with_capacity(Self::len());
87 $({77 $({
88 let mut out = string::new();78 let mut out = string::new();
132impl_tuples! {A B C D E F G H I}122impl_tuples! {A B C D E F G H I}
133impl_tuples! {A B C D E F G H I J}123impl_tuples! {A B C D E F G H I J}
134
135impl StructCollect for Property {
136 fn name() -> String {
137 "Property".into()
138 }
139
140 fn declaration() -> String {
141 use std::fmt::Write;
142
143 let mut str = String::new();
144 writeln!(str, "/// @dev Property struct").unwrap();
145 writeln!(str, "struct {} {{", Self::name()).unwrap();
146 writeln!(str, "\tstring key;").unwrap();
147 writeln!(str, "\tbytes value;").unwrap();
148 writeln!(str, "}}").unwrap();
149 str
150 }
151}
152
153impl SolidityTypeName for Property {
154 fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
155 write!(writer, "{}", tc.collect_struct::<Self>())
156 }
157
158 fn is_simple() -> bool {
159 false
160 }
161
162 fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
163 write!(writer, "{}(", tc.collect_struct::<Self>())?;
164 address::solidity_default(writer, tc)?;
165 write!(writer, ",")?;
166 uint256::solidity_default(writer, tc)?;
167 write!(writer, ")")
168 }
169}
170
171impl SolidityType for Property {
172 fn names(tc: &TypeCollector) -> Vec<string> {
173 let mut collected = Vec::with_capacity(Self::len());
174 {
175 let mut out = string::new();
176 string::solidity_name(&mut out, tc).expect("no fmt error");
177 collected.push(out);
178 }
179 {
180 let mut out = string::new();
181 bytes::solidity_name(&mut out, tc).expect("no fmt error");
182 collected.push(out);
183 }
184 collected
185 }
186
187 fn len() -> usize {
188 2
189 }
190}
191124
modifiedcrates/evm-coder/src/solidity/mod.rsdiffbeforeafterboth
44 /// id ordering is required to perform topo-sort on the resulting data44 /// id ordering is required to perform topo-sort on the resulting data
45 structs: RefCell<BTreeMap<string, usize>>,45 structs: RefCell<BTreeMap<string, usize>>,
46 anonymous: RefCell<BTreeMap<Vec<string>, usize>>,46 anonymous: RefCell<BTreeMap<Vec<string>, usize>>,
47 // generic: RefCell<BTreeMap<string, usize>>,
47 id: Cell<usize>,48 id: Cell<usize>,
48}49}
49impl TypeCollector {50impl TypeCollector {
59 self.id.set(v + 1);60 self.id.set(v + 1);
60 v61 v
61 }62 }
63 /// Collect typle, deduplicating it by type, and returning generated name
62 pub fn collect_tuple<T: SolidityType>(&self) -> String {64 pub fn collect_tuple<T: SolidityTupleTy>(&self) -> String {
63 let names = T::names(self);65 let names = T::fields(self);
64 if let Some(id) = self.anonymous.borrow().get(&names).cloned() {66 if let Some(id) = self.anonymous.borrow().get(&names).cloned() {
65 return format!("Tuple{}", id);67 return format!("Tuple{}", id);
66 }68 }
76 self.anonymous.borrow_mut().insert(names, id);78 self.anonymous.borrow_mut().insert(names, id);
77 format!("Tuple{}", id)79 format!("Tuple{}", id)
78 }80 }
79 pub fn collect_struct<T: StructCollect>(&self) -> String {81 pub fn collect_struct<T: SolidityStructTy>(&self) -> String {
80 self.collect(<T as StructCollect>::declaration());
81 <T as StructCollect>::name()82 T::generate_solidity_interface(self)
82 }83 }
84 pub fn collect_enum<T: SolidityEnumTy>(&self) -> String {
85 T::generate_solidity_interface(self)
86 }
83 pub fn finish(self) -> Vec<string> {87 pub fn finish(self) -> Vec<string> {
84 let mut data = self.structs.into_inner().into_iter().collect::<Vec<_>>();88 let mut data = self.structs.into_inner().into_iter().collect::<Vec<_>>();
85 data.sort_by_key(|(_, id)| Reverse(*id));89 data.sort_by_key(|(_, id)| Reverse(*id));
420 }424 }
421}425}
426
427#[impl_for_tuples(0, 48)]
428impl SolidityItems for Tuple {
429 for_tuples!( where #( Tuple: SolidityItems ),* );
430
431 fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
432 for_tuples!( #(
433 Tuple.solidity_name(writer, tc)?;
434 )* );
435 Ok(())
436 }
437}
438
439pub struct SolidityStructField<T> {
440 pub docs: &'static [&'static str],
441 pub name: &'static str,
442 pub ty: PhantomData<*const T>,
443}
444
445impl<T> SolidityItems for SolidityStructField<T>
446where
447 T: SolidityTypeName,
448{
449 fn solidity_name(&self, out: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
450 for doc in self.docs {
451 writeln!(out, "///{}", doc)?;
452 }
453 write!(out, "\t")?;
454 T::solidity_name(out, tc)?;
455 writeln!(out, " {};", self.name)?;
456 Ok(())
457 }
458}
459pub struct SolidityStruct<F> {
460 pub docs: &'static [&'static str],
461 // pub generics:
462 pub name: &'static str,
463 pub fields: F,
464}
465impl<F> SolidityStruct<F>
466where
467 F: SolidityItems,
468{
469 pub fn format(&self, out: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
470 for doc in self.docs {
471 writeln!(out, "///{}", doc)?;
472 }
473 writeln!(out, "struct {} {{", self.name)?;
474 self.fields.solidity_name(out, tc)?;
475 writeln!(out, "}}")?;
476 Ok(())
477 }
478}
479
480pub struct SolidityEnumVariant {
481 pub docs: &'static [&'static str],
482 pub name: &'static str,
483}
484impl SolidityItems for SolidityEnumVariant {
485 fn solidity_name(&self, out: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
486 for doc in self.docs {
487 writeln!(out, "///{}", doc)?;
488 }
489 write!(out, "\t{}", self.name)?;
490 Ok(())
491 }
492}
493pub struct SolidityEnum {
494 pub docs: &'static [&'static str],
495 pub name: &'static str,
496 pub fields: &'static [SolidityEnumVariant],
497}
498impl SolidityEnum {
499 pub fn format(&self, out: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
500 for doc in self.docs {
501 writeln!(out, "///{}", doc)?;
502 }
503 write!(out, "enum {} {{", self.name)?;
504 for (i, field) in self.fields.iter().enumerate() {
505 if i != 0 {
506 write!(out, ",")?;
507 }
508 writeln!(out)?;
509 field.solidity_name(out, tc)?;
510 }
511 writeln!(out)?;
512 writeln!(out, "}}")?;
513 Ok(())
514 }
515}
422516
modifiedcrates/evm-coder/src/solidity/traits.rsdiffbeforeafterboth
1use super::TypeCollector;1use super::TypeCollector;
2use core::fmt;2use core::fmt;
3
4pub trait StructCollect: 'static {
5 /// Structure name.
6 fn name() -> String;
7 /// Structure declaration.
8 fn declaration() -> String;
9}
10
11pub trait SolidityEnum: 'static {
12 fn solidity_option(&self) -> &str;
13}
143
15pub trait SolidityTypeName: 'static {4pub trait SolidityTypeName: 'static {
16 fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;5 fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
23 }12 }
24}13}
2514
26pub trait SolidityType {15pub trait SolidityTupleTy: 'static {
27 fn names(tc: &TypeCollector) -> Vec<String>;16 fn fields(tc: &TypeCollector) -> Vec<String>;
28 fn len() -> usize;17 fn len() -> usize;
29}18}
19pub trait SolidityStructTy: 'static {
20 fn generate_solidity_interface(tc: &TypeCollector) -> String;
21}
22pub trait SolidityEnumTy: 'static {
23 fn generate_solidity_interface(tc: &TypeCollector) -> String;
24 fn solidity_option(&self) -> &str;
25}
3026
31pub trait SolidityArguments {27pub trait SolidityArguments {
32 fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;28 fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
47 ) -> fmt::Result;43 ) -> fmt::Result;
48}44}
45
46pub trait SolidityItems {
47 fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
48 // For PhantomData fields
49 // fn is_void()
50}
4951
modifiedcrates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth
73 _c: TypeStruct2MixedParam,73 _c: TypeStruct2MixedParam,
74 }74 }
75
76 #[test]
77 #[cfg(feature = "stubgen")]
78 fn struct_collect_type_struct3_derived_mixed_param() {
79 assert_eq!(
80 <TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),
81 "TypeStruct3DerivedMixedParam"
82 );
83 similar_asserts::assert_eq!(
84 <TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),
85 r#"/// @dev Some docs
86/// At multi
87/// line
88struct TypeStruct3DerivedMixedParam {
89 /// @dev Docs for A
90 /// multi
91 /// line
92 TypeStruct1SimpleParam _a;
93 /// @dev Docs for B
94 TypeStruct2DynamicParam _b;
95 /// @dev Docs for C
96 TypeStruct2MixedParam _c;
97}
98"#
99 );
100 }
10175
102 #[test]76 #[test]
103 fn impl_abi_type_signature() {77 fn impl_abi_type_signature() {
293 TupleStruct2MixedParam,267 TupleStruct2MixedParam,
294 );268 );
295
296 #[test]
297 #[cfg(feature = "stubgen")]
298 fn struct_collect_tuple_struct3_derived_mixed_param() {
299 assert_eq!(
300 <TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),
301 "TupleStruct3DerivedMixedParam"
302 );
303 similar_asserts::assert_eq!(
304 <TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),
305 r#"/// @dev Some docs
306/// At multi
307/// line
308struct TupleStruct3DerivedMixedParam {
309 /// @dev Docs for A
310 /// multi
311 /// line
312 TupleStruct1SimpleParam field0;
313 TupleStruct2DynamicParam field1;
314 /// @dev Docs for C
315 TupleStruct2MixedParam field2;
316}
317"#
318 );
319 }
320269
321 #[test]270 #[test]
322 fn impl_abi_type_signature_same_for_structs() {271 fn impl_abi_type_signature_same_for_structs() {
814 }763 }
815 }764 }
816
817 #[test]
818 #[cfg(feature = "stubgen")]
819 fn struct_collect_enum() {
820 assert_eq!(
821 <Color as ::evm_coder::solidity::StructCollect>::name(),
822 "Color"
823 );
824 similar_asserts::assert_eq!(
825 <Color as ::evm_coder::solidity::StructCollect>::declaration(),
826 r#"/// @dev Some docs
827/// At multi
828/// line
829enum Color {
830 /// @dev Docs for Red
831 /// multi
832 /// line
833 Red,
834 Green,
835 /// @dev Docs for Blue
836 Blue
837}
838"#
839 );
840 }
841}765}
842766
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
21 abi::AbiType,21 abi::AbiType,
22 solidity_interface, solidity, ToLog,22 solidity_interface, solidity, ToLog,
23 types::*,23 types::*,
24 types::Property as PropertyStruct,
25 execution::{Result, Error},24 execution::{Result, Error},
26 weight,25 weight,
27};26};
31 AccessMode, CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property,30 AccessMode, CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property,
32 SponsoringRateLimit, SponsorshipState,31 SponsoringRateLimit, SponsorshipState,
33};32};
34use alloc::format;
3533
36use crate::{34use crate::{
37 Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf,35 Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf, eth, weights::WeightInfo,
38 eth::{
39 EthCrossAccount, CollectionPermissions as EvmPermissions,
40 CollectionLimits as EvmCollectionLimits,
41 },
42 weights::WeightInfo,
43};36};
4437
45/// Events for ethereum collection helper.38/// Events for ethereum collection helper.
123 fn set_collection_properties(116 fn set_collection_properties(
124 &mut self,117 &mut self,
125 caller: caller,118 caller: caller,
126 properties: Vec<PropertyStruct>,119 properties: Vec<eth::Property>,
127 ) -> Result<void> {120 ) -> Result<void> {
128 let caller = T::CrossAccountId::from_eth(caller);121 let caller = T::CrossAccountId::from_eth(caller);
129122
130 let properties = properties123 let properties = properties
131 .into_iter()124 .into_iter()
132 .map(|PropertyStruct { key, value }| {125 .map(eth::Property::try_into)
133 let key = <Vec<u8>>::from(key)
134 .try_into()
135 .map_err(|_| "key too large")?;
136
137 let value = value.0.try_into().map_err(|_| "value too large")?;
138
139 Ok(Property { key, value })
140 })
141 .collect::<Result<Vec<_>>>()?;126 .collect::<Result<Vec<_>>>()?;
142127
143 <Pallet<T>>::set_collection_properties(self, &caller, properties)128 <Pallet<T>>::set_collection_properties(self, &caller, properties)
197 ///182 ///
198 /// @param keys Properties keys. Empty keys for all propertyes.183 /// @param keys Properties keys. Empty keys for all propertyes.
199 /// @return Vector of properties key/value pairs.184 /// @return Vector of properties key/value pairs.
200 fn collection_properties(&self, keys: Vec<string>) -> Result<Vec<PropertyStruct>> {185 fn collection_properties(&self, keys: Vec<string>) -> Result<Vec<eth::Property>> {
201 let keys = keys186 let keys = keys
202 .into_iter()187 .into_iter()
203 .map(|key| {188 .map(|key| {
215200
216 let properties = properties201 let properties = properties
217 .into_iter()202 .into_iter()
218 .map(|p| {203 .map(Property::try_into)
219 let key =
220 string::from_utf8(p.key.into()).map_err(|e| Error::Revert(format!("{}", e)))?;
221 let value = bytes(p.value.to_vec());
222 Ok(PropertyStruct { key, value })
223 })
224 .collect::<Result<Vec<_>>>()?;204 .collect::<Result<Vec<_>>>()?;
225 Ok(properties)205 Ok(properties)
226 }206 }
249 fn set_collection_sponsor_cross(229 fn set_collection_sponsor_cross(
250 &mut self,230 &mut self,
251 caller: caller,231 caller: caller,
252 sponsor: EthCrossAccount,232 sponsor: eth::CrossAddress,
253 ) -> Result<void> {233 ) -> Result<void> {
254 self.consume_store_reads_and_writes(1, 1)?;234 self.consume_store_reads_and_writes(1, 1)?;
255235
289 /// Get current sponsor.269 /// Get current sponsor.
290 ///270 ///
291 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.271 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
292 fn collection_sponsor(&self) -> Result<EthCrossAccount> {272 fn collection_sponsor(&self) -> Result<eth::CrossAddress> {
293 let sponsor = match self.collection.sponsorship.sponsor() {273 let sponsor = match self.collection.sponsorship.sponsor() {
294 Some(sponsor) => sponsor,274 Some(sponsor) => sponsor,
295 None => return Ok(Default::default()),275 None => return Ok(Default::default()),
296 };276 };
297277
298 Ok(EthCrossAccount::from_sub::<T>(&sponsor))278 Ok(eth::CrossAddress::from_sub::<T>(&sponsor))
299 }279 }
300280
301 /// Get current collection limits.281 /// Get current collection limits.
302 ///282 ///
303 /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:283 /// @return Array of collection limits
304 /// "accountTokenOwnershipLimit",284 fn collection_limits(&self) -> Result<Vec<eth::CollectionLimit>> {
305 /// "sponsoredDataSize",
306 /// "sponsoredDataRateLimit",
307 /// "tokenLimit",
308 /// "sponsorTransferTimeout",
309 /// "sponsorApproveTimeout"
310 /// "ownerCanTransfer",
311 /// "ownerCanDestroy",
312 /// "transfersEnabled"
313 /// Return `false` if a limit not set.
314 fn collection_limits(&self) -> Result<Vec<(EvmCollectionLimits, bool, uint256)>> {
315 let convert_value_limit = |limit: EvmCollectionLimits,
316 value: Option<u32>|
317 -> (EvmCollectionLimits, bool, uint256) {
318 value
319 .map(|v| (limit, true, v.into()))
320 .unwrap_or((limit, false, Default::default()))
321 };
322
323 let convert_bool_limit = |limit: EvmCollectionLimits,
324 value: Option<bool>|
325 -> (EvmCollectionLimits, bool, uint256) {
326 value
327 .map(|v| {
328 (
329 limit,
330 true,
331 if v {
332 uint256::from(1)
333 } else {
334 Default::default()
335 },
336 )
337 })
338 .unwrap_or((limit, false, Default::default()))
339 };
340
341 let limits = &self.collection.limits;285 let limits = &self.collection.limits;
342286
343 Ok(vec![287 Ok(vec![
344 convert_value_limit(288 eth::CollectionLimit::new(
345 EvmCollectionLimits::AccountTokenOwnership,289 eth::CollectionLimitField::AccountTokenOwnership,
346 limits.account_token_ownership_limit,290 limits.account_token_ownership_limit,
347 ),291 ),
348 convert_value_limit(292 eth::CollectionLimit::new(
349 EvmCollectionLimits::SponsoredDataSize,293 eth::CollectionLimitField::SponsoredDataSize,
350 limits.sponsored_data_size,294 limits.sponsored_data_size,
351 ),295 ),
352 limits296 limits
353 .sponsored_data_rate_limit297 .sponsored_data_rate_limit
354 .and_then(|limit| {298 .and_then(|limit| {
355 if let SponsoringRateLimit::Blocks(blocks) = limit {299 if let SponsoringRateLimit::Blocks(blocks) = limit {
356 Some((300 Some(eth::CollectionLimit::new::<u32>(
357 EvmCollectionLimits::SponsoredDataRateLimit,301 eth::CollectionLimitField::SponsoredDataRateLimit,
358 true,302 blocks,
359 blocks.into(),
360 ))303 ))
361 } else {304 } else {
362 None305 None
363 }306 }
364 })307 })
365 .unwrap_or((308 .unwrap_or(eth::CollectionLimit::new::<u32>(
366 EvmCollectionLimits::SponsoredDataRateLimit,309 eth::CollectionLimitField::SponsoredDataRateLimit,
367 false,
368 Default::default(),310 Default::default(),
369 )),311 )),
370 convert_value_limit(EvmCollectionLimits::TokenLimit, limits.token_limit),312 eth::CollectionLimit::new(eth::CollectionLimitField::TokenLimit, limits.token_limit),
371 convert_value_limit(313 eth::CollectionLimit::new(
372 EvmCollectionLimits::SponsorTransferTimeout,314 eth::CollectionLimitField::SponsorTransferTimeout,
373 limits.sponsor_transfer_timeout,315 limits.sponsor_transfer_timeout,
374 ),316 ),
375 convert_value_limit(317 eth::CollectionLimit::new(
376 EvmCollectionLimits::SponsorApproveTimeout,318 eth::CollectionLimitField::SponsorApproveTimeout,
377 limits.sponsor_approve_timeout,319 limits.sponsor_approve_timeout,
378 ),320 ),
379 convert_bool_limit(321 eth::CollectionLimit::new(
380 EvmCollectionLimits::OwnerCanTransfer,322 eth::CollectionLimitField::OwnerCanTransfer,
381 limits.owner_can_transfer,323 limits.owner_can_transfer,
382 ),324 ),
383 convert_bool_limit(325 eth::CollectionLimit::new(
384 EvmCollectionLimits::OwnerCanDestroy,326 eth::CollectionLimitField::OwnerCanDestroy,
385 limits.owner_can_destroy,327 limits.owner_can_destroy,
386 ),328 ),
387 convert_bool_limit(329 eth::CollectionLimit::new(
388 EvmCollectionLimits::TransferEnabled,330 eth::CollectionLimitField::TransferEnabled,
389 limits.transfers_enabled,331 limits.transfers_enabled,
390 ),332 ),
391 ])333 ])
392 }334 }
393335
394 /// Set limits for the collection.336 /// Set limits for the collection.
395 /// @dev Throws error if limit not found.337 /// @dev Throws error if limit not found.
396 /// @param limit Name of the limit. Valid names:338 /// @param limit Some limit.
397 /// "accountTokenOwnershipLimit",
398 /// "sponsoredDataSize",
399 /// "sponsoredDataRateLimit",
400 /// "tokenLimit",
401 /// "sponsorTransferTimeout",
402 /// "sponsorApproveTimeout"
403 /// "ownerCanTransfer",
404 /// "ownerCanDestroy",
405 /// "transfersEnabled"
406 /// @param status enable\disable limit. Works only with `true`.
407 /// @param value Value of the limit.
408 #[solidity(rename_selector = "setCollectionLimit")]339 #[solidity(rename_selector = "setCollectionLimit")]
409 fn set_collection_limit(340 fn set_collection_limit(
410 &mut self,341 &mut self,
411 caller: caller,342 caller: caller,
412 limit: EvmCollectionLimits,343 limit: eth::CollectionLimit,
413 status: bool,
414 value: uint256,
415 ) -> Result<void> {344 ) -> Result<void> {
416 self.consume_store_reads_and_writes(1, 1)?;345 self.consume_store_reads_and_writes(1, 1)?;
417346
418 if !status {347 if !limit.has_value() {
419 return Err(Error::Revert("user can't disable limits".into()));348 return Err(Error::Revert("user can't disable limits".into()));
420 }349 }
421350
422 let value = value
423 .try_into()
424 .map_err(|_| Error::Revert(format!("can't convert value to u32 \"{}\"", value)))?;
425
426 let convert_value_to_bool = || match value {
427 0 => Ok(false),
428 1 => Ok(true),
429 _ => {
430 return Err(Error::Revert(format!(
431 "can't convert value to boolean \"{}\"",
432 value
433 )))
434 }
435 };
436
437 let mut limits = self.limits.clone();
438
439 match limit {
440 EvmCollectionLimits::AccountTokenOwnership => {
441 limits.account_token_ownership_limit = Some(value);
442 }
443 EvmCollectionLimits::SponsoredDataSize => {
444 limits.sponsored_data_size = Some(value);
445 }
446 EvmCollectionLimits::SponsoredDataRateLimit => {
447 limits.sponsored_data_rate_limit = Some(SponsoringRateLimit::Blocks(value));
448 }
449 EvmCollectionLimits::TokenLimit => {
450 limits.token_limit = Some(value);
451 }
452 EvmCollectionLimits::SponsorTransferTimeout => {
453 limits.sponsor_transfer_timeout = Some(value);
454 }
455 EvmCollectionLimits::SponsorApproveTimeout => {
456 limits.sponsor_approve_timeout = Some(value);
457 }
458 EvmCollectionLimits::OwnerCanTransfer => {
459 limits.owner_can_transfer = Some(convert_value_to_bool()?);
460 }
461 EvmCollectionLimits::OwnerCanDestroy => {
462 limits.owner_can_destroy = Some(convert_value_to_bool()?);
463 }
464 EvmCollectionLimits::TransferEnabled => {
465 limits.transfers_enabled = Some(convert_value_to_bool()?);
466 }
467 _ => return Err(Error::Revert(format!("unknown limit \"{:?}\"", limit))),
468 }
469
470 let caller = T::CrossAccountId::from_eth(caller);351 let caller = T::CrossAccountId::from_eth(caller);
471 <Pallet<T>>::update_limits(&caller, self, limits).map_err(dispatch_to_evm::<T>)352 <Pallet<T>>::update_limits(&caller, self, limit.try_into()?).map_err(dispatch_to_evm::<T>)
472 }353 }
473354
474 /// Get contract address.355 /// Get contract address.
481 fn add_collection_admin_cross(362 fn add_collection_admin_cross(
482 &mut self,363 &mut self,
483 caller: caller,364 caller: caller,
484 new_admin: EthCrossAccount,365 new_admin: eth::CrossAddress,
485 ) -> Result<void> {366 ) -> Result<void> {
486 self.consume_store_reads_and_writes(2, 2)?;367 self.consume_store_reads_and_writes(2, 2)?;
487368
496 fn remove_collection_admin_cross(377 fn remove_collection_admin_cross(
497 &mut self,378 &mut self,
498 caller: caller,379 caller: caller,
499 admin: EthCrossAccount,380 admin: eth::CrossAddress,
500 ) -> Result<void> {381 ) -> Result<void> {
501 self.consume_store_reads_and_writes(2, 2)?;382 self.consume_store_reads_and_writes(2, 2)?;
502383
595476
596 /// Returns nesting for a collection477 /// Returns nesting for a collection
597 #[solidity(rename_selector = "collectionNestingRestrictedCollectionIds")]478 #[solidity(rename_selector = "collectionNestingRestrictedCollectionIds")]
598 fn collection_nesting_restricted_ids(&self) -> Result<(bool, Vec<uint256>)> {479 fn collection_nesting_restricted_ids(&self) -> Result<eth::CollectionNesting> {
599 let nesting = self.collection.permissions.nesting();480 let nesting = self.collection.permissions.nesting();
600481
601 Ok((482 Ok(eth::CollectionNesting::new(
602 nesting.token_owner,483 nesting.token_owner,
603 nesting484 nesting
604 .restricted485 .restricted
609 }490 }
610491
611 /// Returns permissions for a collection492 /// Returns permissions for a collection
612 fn collection_nesting_permissions(&self) -> Result<Vec<(EvmPermissions, bool)>> {493 fn collection_nesting_permissions(&self) -> Result<Vec<eth::CollectionNestingPermission>> {
613 let nesting = self.collection.permissions.nesting();494 let nesting = self.collection.permissions.nesting();
614 Ok(vec![495 Ok(vec![
615 (EvmPermissions::CollectionAdmin, nesting.collection_admin),496 eth::CollectionNestingPermission::new(
497 eth::CollectionPermissionField::CollectionAdmin,
498 nesting.collection_admin,
499 ),
616 (EvmPermissions::TokenOwner, nesting.token_owner),500 eth::CollectionNestingPermission::new(
501 eth::CollectionPermissionField::TokenOwner,
502 nesting.token_owner,
503 ),
617 ])504 ])
618 }505 }
619 /// Set the collection access method.506 /// Set the collection access method.
638 /// Checks that user allowed to operate with collection.525 /// Checks that user allowed to operate with collection.
639 ///526 ///
640 /// @param user User address to check.527 /// @param user User address to check.
641 fn allowlisted_cross(&self, user: EthCrossAccount) -> Result<bool> {528 fn allowlisted_cross(&self, user: eth::CrossAddress) -> Result<bool> {
642 let user = user.into_sub_cross_account::<T>()?;529 let user = user.into_sub_cross_account::<T>()?;
643 Ok(Pallet::<T>::allowed(self.id, user))530 Ok(Pallet::<T>::allowed(self.id, user))
644 }531 }
662 fn add_to_collection_allow_list_cross(549 fn add_to_collection_allow_list_cross(
663 &mut self,550 &mut self,
664 caller: caller,551 caller: caller,
665 user: EthCrossAccount,552 user: eth::CrossAddress,
666 ) -> Result<void> {553 ) -> Result<void> {
667 self.consume_store_writes(1)?;554 self.consume_store_writes(1)?;
668555
691 fn remove_from_collection_allow_list_cross(578 fn remove_from_collection_allow_list_cross(
692 &mut self,579 &mut self,
693 caller: caller,580 caller: caller,
694 user: EthCrossAccount,581 user: eth::CrossAddress,
695 ) -> Result<void> {582 ) -> Result<void> {
696 self.consume_store_writes(1)?;583 self.consume_store_writes(1)?;
697584
729 ///616 ///
730 /// @param user User cross account to verify617 /// @param user User cross account to verify
731 /// @return "true" if account is the owner or admin618 /// @return "true" if account is the owner or admin
732 fn is_owner_or_admin_cross(&self, user: EthCrossAccount) -> Result<bool> {619 fn is_owner_or_admin_cross(&self, user: eth::CrossAddress) -> Result<bool> {
733 let user = user.into_sub_cross_account::<T>()?;620 let user = user.into_sub_cross_account::<T>()?;
734 Ok(self.is_owner_or_admin(&user))621 Ok(self.is_owner_or_admin(&user))
735 }622 }
750 ///637 ///
751 /// @return Tuble with sponsor address and his substrate mirror.638 /// @return Tuble with sponsor address and his substrate mirror.
752 /// If address is canonical then substrate mirror is zero and vice versa.639 /// If address is canonical then substrate mirror is zero and vice versa.
753 fn collection_owner(&self) -> Result<EthCrossAccount> {640 fn collection_owner(&self) -> Result<eth::CrossAddress> {
754 Ok(EthCrossAccount::from_sub_cross_account::<T>(641 Ok(eth::CrossAddress::from_sub_cross_account::<T>(
755 &T::CrossAccountId::from_sub(self.owner.clone()),642 &T::CrossAccountId::from_sub(self.owner.clone()),
756 ))643 ))
757 }644 }
774 ///661 ///
775 /// @return Vector of tuples with admins address and his substrate mirror.662 /// @return Vector of tuples with admins address and his substrate mirror.
776 /// If address is canonical then substrate mirror is zero and vice versa.663 /// If address is canonical then substrate mirror is zero and vice versa.
777 fn collection_admins(&self) -> Result<Vec<EthCrossAccount>> {664 fn collection_admins(&self) -> Result<Vec<eth::CrossAddress>> {
778 let result = crate::IsAdmin::<T>::iter_prefix((self.id,))665 let result = crate::IsAdmin::<T>::iter_prefix((self.id,))
779 .map(|(admin, _)| EthCrossAccount::from_sub_cross_account::<T>(&admin))666 .map(|(admin, _)| eth::CrossAddress::from_sub_cross_account::<T>(&admin))
780 .collect();667 .collect();
781 Ok(result)668 Ok(result)
782 }669 }
788 fn change_collection_owner_cross(675 fn change_collection_owner_cross(
789 &mut self,676 &mut self,
790 caller: caller,677 caller: caller,
791 new_owner: EthCrossAccount,678 new_owner: eth::CrossAddress,
792 ) -> Result<void> {679 ) -> Result<void> {
793 self.consume_store_writes(1)?;680 self.consume_store_writes(1)?;
794681
797 self.change_owner(caller, new_owner)684 self.change_owner(caller, new_owner)
798 .map_err(dispatch_to_evm::<T>)685 .map_err(dispatch_to_evm::<T>)
799 }686 }
800}
801
802/// ### Note
803/// Do not forget to add: `self.consume_store_reads(1)?;`
804fn check_is_owner_or_admin<T: Config>(
805 caller: caller,
806 collection: &CollectionHandle<T>,
807) -> Result<T::CrossAccountId> {
808 let caller = T::CrossAccountId::from_eth(caller);
809 collection
810 .check_is_owner_or_admin(&caller)
811 .map_err(dispatch_to_evm::<T>)?;
812 Ok(caller)
813}
814
815/// ### Note
816/// Do not forget to add: `self.consume_store_writes(1)?;`
817fn save<T: Config>(collection: &CollectionHandle<T>) -> Result<void> {
818 collection
819 .check_is_internal()
820 .map_err(dispatch_to_evm::<T>)?;
821 collection.save().map_err(dispatch_to_evm::<T>)?;
822 Ok(())
823}687}
824688
825/// Contains static property keys and values.689/// Contains static property keys and values.
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
1616
17//! The module contains a number of functions for converting and checking ethereum identifiers.17//! The module contains a number of functions for converting and checking ethereum identifiers.
1818
19use alloc::format;
20use sp_std::{vec, vec::Vec};
19use evm_coder::{21use evm_coder::{
20 AbiCoder,22 AbiCoder,
21 types::{uint256, address},23 types::{uint256, address},
64 T::CrossAccountId::from_sub(account_id)66 T::CrossAccountId::from_sub(account_id)
65}67}
68
69/// Ethereum representation of Optional value with uint256.
70#[derive(Debug, Default, AbiCoder)]
71pub struct OptionUint {
72 status: bool,
73 value: uint256,
74}
75
76impl From<u32> for OptionUint {
77 fn from(value: u32) -> Self {
78 Self {
79 status: true,
80 value: uint256::from(value),
81 }
82 }
83}
84
85impl From<Option<u32>> for OptionUint {
86 fn from(value: Option<u32>) -> Self {
87 match value {
88 Some(value) => Self {
89 status: true,
90 value: value.into(),
91 },
92 None => Self {
93 status: false,
94 value: Default::default(),
95 },
96 }
97 }
98}
99
100impl From<bool> for OptionUint {
101 fn from(value: bool) -> Self {
102 Self {
103 status: true,
104 value: if value {
105 uint256::from(1)
106 } else {
107 Default::default()
108 },
109 }
110 }
111}
112
113impl From<Option<bool>> for OptionUint {
114 fn from(value: Option<bool>) -> Self {
115 match value {
116 Some(value) => Self::from(value),
117 None => Self {
118 status: false,
119 value: Default::default(),
120 },
121 }
122 }
123}
124
125/// Ethereum representation of Optional value with CrossAddress.
126#[derive(Debug, Default, AbiCoder)]
127pub struct OptionCrossAddress {
128 pub status: bool,
129 pub value: CrossAddress,
130}
66131
67/// Cross account struct132/// Cross account struct
68#[derive(Debug, Default, AbiCoder)]133#[derive(Debug, Default, AbiCoder)]
69pub struct EthCrossAccount {134pub struct CrossAddress {
70 pub(crate) eth: address,135 pub(crate) eth: address,
71 pub(crate) sub: uint256,136 pub(crate) sub: uint256,
72}137}
73138
74impl EthCrossAccount {139impl CrossAddress {
75 /// Converts `CrossAccountId` to `EthCrossAccountId`140 /// Converts `CrossAccountId` to [`CrossAddress`]
76 pub fn from_sub_cross_account<T>(cross_account_id: &T::CrossAccountId) -> Self141 pub fn from_sub_cross_account<T>(cross_account_id: &T::CrossAccountId) -> Self
77 where142 where
78 T: pallet_evm::Config,143 T: pallet_evm::Config,
87 }152 }
88 }153 }
89 }154 }
90 /// Creates `EthCrossAccount` from substrate account155 /// Creates [`CrossAddress`] from substrate account
91 pub fn from_sub<T>(account_id: &T::AccountId) -> Self156 pub fn from_sub<T>(account_id: &T::AccountId) -> Self
92 where157 where
93 T: pallet_evm::Config,158 T: pallet_evm::Config,
98 sub: uint256::from_big_endian(account_id.as_ref()),163 sub: uint256::from_big_endian(account_id.as_ref()),
99 }164 }
100 }165 }
101 /// Converts `EthCrossAccount` to `CrossAccountId`166 /// Converts [`CrossAddress`] to `CrossAccountId`
102 pub fn into_sub_cross_account<T>(&self) -> evm_coder::execution::Result<T::CrossAccountId>167 pub fn into_sub_cross_account<T>(&self) -> evm_coder::execution::Result<T::CrossAccountId>
103 where168 where
104 T: pallet_evm::Config,169 T: pallet_evm::Config,
116 }181 }
117}182}
183
184/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
185#[derive(Debug, Default, AbiCoder)]
186pub struct Property {
187 key: evm_coder::types::string,
188 value: evm_coder::types::bytes,
189}
190
191impl TryFrom<up_data_structs::Property> for Property {
192 type Error = evm_coder::execution::Error;
193
194 fn try_from(from: up_data_structs::Property) -> Result<Self, Self::Error> {
195 let key = evm_coder::types::string::from_utf8(from.key.into())
196 .map_err(|e| Self::Error::Revert(format!("utf8 conversion error: {}", e)))?;
197 let value = evm_coder::types::bytes(from.value.to_vec());
198 Ok(Property { key, value })
199 }
200}
201
202impl TryInto<up_data_structs::Property> for Property {
203 type Error = evm_coder::execution::Error;
204
205 fn try_into(self) -> Result<up_data_structs::Property, Self::Error> {
206 let key = <Vec<u8>>::from(self.key)
207 .try_into()
208 .map_err(|_| "key too large")?;
209
210 let value = self.value.0.try_into().map_err(|_| "value too large")?;
211
212 Ok(up_data_structs::Property { key, value })
213 }
214}
118215
119/// [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.216/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
120#[derive(Debug, Default, Clone, Copy, AbiCoder)]217#[derive(Debug, Default, Clone, Copy, AbiCoder)]
121#[repr(u8)]218#[repr(u8)]
122pub enum CollectionLimits {219pub enum CollectionLimitField {
123 /// How many tokens can a user have on one account.220 /// How many tokens can a user have on one account.
124 #[default]221 #[default]
125 AccountTokenOwnership,222 AccountTokenOwnership,
149 TransferEnabled,246 TransferEnabled,
150}247}
248
249/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
250#[derive(Debug, Default, AbiCoder)]
251pub struct CollectionLimit {
252 field: CollectionLimitField,
253 value: OptionUint,
254}
255
256impl CollectionLimit {
257 /// Create [`CollectionLimit`] from field and value.
258 pub fn new<T>(field: CollectionLimitField, value: T) -> Self
259 where
260 OptionUint: From<T>,
261 {
262 Self {
263 field,
264 value: value.into(),
265 }
266 }
267 /// Whether the field contains a value.
268 pub fn has_value(&self) -> bool {
269 self.value.status
270 }
271}
272
273impl TryInto<up_data_structs::CollectionLimits> for CollectionLimit {
274 type Error = evm_coder::execution::Error;
275
276 fn try_into(self) -> Result<up_data_structs::CollectionLimits, Self::Error> {
277 let value = self.value.value.try_into().map_err(|error| {
278 Self::Error::Revert(format!(
279 "can't convert value to u32 \"{}\" because: \"{error}\"",
280 self.value.value
281 ))
282 })?;
283
284 let convert_value_to_bool = || match value {
285 0 => Ok(false),
286 1 => Ok(true),
287 _ => {
288 return Err(Self::Error::Revert(format!(
289 "can't convert value to boolean \"{value}\""
290 )))
291 }
292 };
293
294 let mut limits = up_data_structs::CollectionLimits::default();
295 match self.field {
296 CollectionLimitField::AccountTokenOwnership => {
297 limits.account_token_ownership_limit = Some(value);
298 }
299 CollectionLimitField::SponsoredDataSize => {
300 limits.sponsored_data_size = Some(value);
301 }
302 CollectionLimitField::SponsoredDataRateLimit => {
303 limits.sponsored_data_rate_limit =
304 Some(up_data_structs::SponsoringRateLimit::Blocks(value));
305 }
306 CollectionLimitField::TokenLimit => {
307 limits.token_limit = Some(value);
308 }
309 CollectionLimitField::SponsorTransferTimeout => {
310 limits.sponsor_transfer_timeout = Some(value);
311 }
312 CollectionLimitField::SponsorApproveTimeout => {
313 limits.sponsor_approve_timeout = Some(value);
314 }
315 CollectionLimitField::OwnerCanTransfer => {
316 limits.owner_can_transfer = Some(convert_value_to_bool()?);
317 }
318 CollectionLimitField::OwnerCanDestroy => {
319 limits.owner_can_destroy = Some(convert_value_to_bool()?);
320 }
321 CollectionLimitField::TransferEnabled => {
322 limits.transfers_enabled = Some(convert_value_to_bool()?);
323 }
324 };
325 Ok(limits)
326 }
327}
328
151/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.329/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
152#[derive(Default, Debug, Clone, Copy, AbiCoder)]330#[derive(Default, Debug, Clone, Copy, AbiCoder)]
153#[repr(u8)]331#[repr(u8)]
154pub enum CollectionPermissions {332pub enum CollectionPermissionField {
155 /// Owner of token can nest tokens under it.333 /// Owner of token can nest tokens under it.
156 #[default]334 #[default]
157 TokenOwner,335 TokenOwner,
163/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.341/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
164#[derive(AbiCoder, Copy, Clone, Default, Debug)]342#[derive(AbiCoder, Copy, Clone, Default, Debug)]
165#[repr(u8)]343#[repr(u8)]
166pub enum EthTokenPermissions {344pub enum TokenPermissionField {
167 /// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]345 /// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
168 #[default]346 #[default]
169 Mutable,347 Mutable,
175 CollectionAdmin,353 CollectionAdmin,
176}354}
355
356/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
357#[derive(Debug, Default, AbiCoder)]
358pub struct PropertyPermission {
359 /// TokenPermission field.
360 code: TokenPermissionField,
361 /// TokenPermission value.
362 value: bool,
363}
364
365impl PropertyPermission {
366 /// Make vector of [`PropertyPermission`] from [`up_data_structs::PropertyPermission`].
367 pub fn into_vec(pp: up_data_structs::PropertyPermission) -> Vec<Self> {
368 vec![
369 PropertyPermission {
370 code: TokenPermissionField::Mutable,
371 value: pp.mutable,
372 },
373 PropertyPermission {
374 code: TokenPermissionField::TokenOwner,
375 value: pp.token_owner,
376 },
377 PropertyPermission {
378 code: TokenPermissionField::CollectionAdmin,
379 value: pp.collection_admin,
380 },
381 ]
382 }
383
384 /// Make [`up_data_structs::PropertyPermission`] from vector of [`PropertyPermission`].
385 pub fn from_vec(permission: Vec<Self>) -> up_data_structs::PropertyPermission {
386 let mut token_permission = up_data_structs::PropertyPermission::default();
387
388 for PropertyPermission { code, value } in permission {
389 match code {
390 TokenPermissionField::Mutable => token_permission.mutable = value,
391 TokenPermissionField::TokenOwner => token_permission.token_owner = value,
392 TokenPermissionField::CollectionAdmin => token_permission.collection_admin = value,
393 }
394 }
395 token_permission
396 }
397}
398
399/// Ethereum representation of Token Property Permissions.
400#[derive(Debug, Default, AbiCoder)]
401pub struct TokenPropertyPermission {
402 /// Token property key.
403 key: evm_coder::types::string,
404 /// Token property permissions.
405 permissions: Vec<PropertyPermission>,
406}
407
408impl
409 From<(
410 up_data_structs::PropertyKey,
411 up_data_structs::PropertyPermission,
412 )> for TokenPropertyPermission
413{
414 fn from(
415 value: (
416 up_data_structs::PropertyKey,
417 up_data_structs::PropertyPermission,
418 ),
419 ) -> Self {
420 let (key, permission) = value;
421 let key = evm_coder::types::string::from_utf8(key.into_inner())
422 .expect("Stored key must be valid");
423 let permissions = PropertyPermission::into_vec(permission);
424 Self { key, permissions }
425 }
426}
427
428impl TokenPropertyPermission {
429 /// Convert vector of [`TokenPropertyPermission`] into vector of [`up_data_structs::PropertyKeyPermission`].
430 pub fn into_property_key_permissions(
431 permissions: Vec<TokenPropertyPermission>,
432 ) -> evm_coder::execution::Result<Vec<up_data_structs::PropertyKeyPermission>> {
433 let mut perms = Vec::new();
434
435 for TokenPropertyPermission { key, permissions } in permissions {
436 let token_permission = PropertyPermission::from_vec(permissions);
437
438 perms.push(up_data_structs::PropertyKeyPermission {
439 key: key.into_bytes().try_into().map_err(|_| "too long key")?,
440 permission: token_permission,
441 });
442 }
443 Ok(perms)
444 }
445}
446
447/// Nested collections.
448#[derive(Debug, Default, AbiCoder)]
449pub struct CollectionNesting {
450 token_owner: bool,
451 ids: Vec<uint256>,
452}
453
454impl CollectionNesting {
455 /// Create [`CollectionNesting`].
456 pub fn new(token_owner: bool, ids: Vec<uint256>) -> Self {
457 Self { token_owner, ids }
458 }
459}
460
461/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
462#[derive(Debug, Default, AbiCoder)]
463pub struct CollectionNestingPermission {
464 field: CollectionPermissionField,
465 value: bool,
466}
467
468impl CollectionNestingPermission {
469 /// Create [`CollectionNestingPermission`].
470 pub fn new(field: CollectionPermissionField, value: bool) -> Self {
471 Self { field, value }
472 }
473}
177474
modifiedpallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth
23 execution::Result,23 execution::Result,
24 generate_stubgen, solidity_interface,24 generate_stubgen, solidity_interface,
25 types::*,25 types::*,
26 ToLog,26 ToLog, AbiCoder,
27};27};
28use pallet_common::eth::EthCrossAccount;28use pallet_common::eth;
29use pallet_evm::{29use pallet_evm::{
30 ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, PrecompileHandle,30 ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, PrecompileHandle,
31 account::CrossAccountId,31 account::CrossAccountId,
175 ///175 ///
176 /// @param contractAddress The contract for which a sponsor is requested.176 /// @param contractAddress The contract for which a sponsor is requested.
177 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.177 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
178 fn sponsor(&self, contract_address: address) -> Result<EthCrossAccount> {178 fn sponsor(&self, contract_address: address) -> Result<eth::OptionCrossAddress> {
179 Ok(EthCrossAccount::from_sub_cross_account::<T>(179 Ok(match Pallet::<T>::get_sponsor(contract_address) {
180 &Pallet::<T>::get_sponsor(contract_address).ok_or("Contract has no sponsor")?,180 Some(ref value) => eth::OptionCrossAddress {
181 status: true,
182 value: eth::CrossAddress::from_sub_cross_account::<T>(value),
183 },
184 None => eth::OptionCrossAddress {
185 status: false,
186 value: Default::default(),
187 },
181 ))188 })
182 }189 }
183190
184 /// Check tat contract has confirmed sponsor.191 /// Check tat contract has confirmed sponsor.
208 &mut self,215 &mut self,
209 caller: caller,216 caller: caller,
210 contract_address: address,217 contract_address: address,
211 // TODO: implement support for enums in evm-coder
212 mode: uint8,218 mode: SponsoringModeT,
213 ) -> Result<void> {219 ) -> Result<void> {
214 self.recorder().consume_sload()?;220 self.recorder().consume_sload()?;
215 self.recorder().consume_sstore()?;221 self.recorder().consume_sstore()?;
216222
217 <Pallet<T>>::ensure_owner(contract_address, caller).map_err(dispatch_to_evm::<T>)?;223 <Pallet<T>>::ensure_owner(contract_address, caller).map_err(dispatch_to_evm::<T>)?;
218 let mode = SponsoringModeT::from_eth(mode).ok_or("unknown mode")?;
219 <Pallet<T>>::set_sponsoring_mode(contract_address, mode);224 <Pallet<T>>::set_sponsoring_mode(contract_address, mode);
220225
221 Ok(())226 Ok(())
modifiedpallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth
19#![warn(missing_docs)]19#![warn(missing_docs)]
2020
21use codec::{Decode, Encode, MaxEncodedLen};21use codec::{Decode, Encode, MaxEncodedLen};
22use evm_coder::AbiCoder;
22pub use pallet::*;23pub use pallet::*;
23pub use eth::*;24pub use eth::*;
24use scale_info::TypeInfo;25use scale_info::TypeInfo;
408409
409/// Available contract sponsoring modes410/// Available contract sponsoring modes
410#[derive(Encode, Decode, PartialEq, TypeInfo, MaxEncodedLen, Default)]411#[derive(
412 Encode, Decode, Debug, PartialEq, TypeInfo, MaxEncodedLen, Default, AbiCoder, Clone, Copy,
413)]
414#[repr(u8)]
411pub enum SponsoringModeT {415pub enum SponsoringModeT {
412 /// Sponsoring is disabled416 /// Sponsoring is disabled
413 #[default]417 #[default]
418 Generous,422 Generous,
419}423}
420
421impl SponsoringModeT {
422 fn from_eth(v: u8) -> Option<Self> {
423 Some(match v {
424 0 => Self::Disabled,
425 1 => Self::Allowlisted,
426 2 => Self::Generous,
427 _ => return None,
428 })
429 }
430 #[allow(dead_code)]
431 fn to_eth(self) -> u8 {
432 match self {
433 SponsoringModeT::Disabled => 0,
434 SponsoringModeT::Allowlisted => 1,
435 SponsoringModeT::Generous => 2,
436 }
437 }
438}
439424
modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth
96 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.96 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
97 /// @dev EVM selector for this function is: 0x766c4f37,97 /// @dev EVM selector for this function is: 0x766c4f37,
98 /// or in textual repr: sponsor(address)98 /// or in textual repr: sponsor(address)
99 function sponsor(address contractAddress) public view returns (EthCrossAccount memory) {99 function sponsor(address contractAddress) public view returns (OptionCrossAddress memory) {
100 require(false, stub_error);100 require(false, stub_error);
101 contractAddress;101 contractAddress;
102 dummy;102 dummy;
103 return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);103 return OptionCrossAddress(false, CrossAddress(0x0000000000000000000000000000000000000000, 0));
104 }104 }
105105
106 /// Check tat contract has confirmed sponsor.106 /// Check tat contract has confirmed sponsor.
140140
141 /// @dev EVM selector for this function is: 0xfde8a560,141 /// @dev EVM selector for this function is: 0xfde8a560,
142 /// or in textual repr: setSponsoringMode(address,uint8)142 /// or in textual repr: setSponsoringMode(address,uint8)
143 function setSponsoringMode(address contractAddress, uint8 mode) public {143 function setSponsoringMode(address contractAddress, SponsoringModeT mode) public {
144 require(false, stub_error);144 require(false, stub_error);
145 contractAddress;145 contractAddress;
146 mode;146 mode;
265 }265 }
266}266}
267
268/// Available contract sponsoring modes
269enum SponsoringModeT {
270 /// Sponsoring is disabled
271 Disabled,
272 /// Only users from allowlist will be sponsored
273 Allowlisted,
274 /// All users will be sponsored
275 Generous
276}
267277
268/// @dev Cross account struct278/// Cross account struct
269struct EthCrossAccount {279struct CrossAddress {
270 address eth;280 address eth;
271 uint256 sub;281 uint256 sub;
272}282}
283
284/// Ethereum representation of Optional value with CrossAddress.
285struct OptionCrossAddress {
286 bool status;
287 CrossAddress value;
288}
273289
modifiedpallets/fungible/src/erc.rsdiffbeforeafterboth
27use pallet_common::{27use pallet_common::{
28 CollectionHandle,28 CollectionHandle,
29 erc::{CommonEvmHandler, PrecompileResult, CollectionCall},29 erc::{CommonEvmHandler, PrecompileResult, CollectionCall},
30 eth::EthCrossAccount,
31};30};
32use sp_std::vec::Vec;31use sp_std::vec::Vec;
33use pallet_evm::{account::CrossAccountId, PrecompileHandle};32use pallet_evm::{account::CrossAccountId, PrecompileHandle};
175 }174 }
176175
177 #[weight(<SelfWeightOf<T>>::create_item())]176 #[weight(<SelfWeightOf<T>>::create_item())]
178 fn mint_cross(&mut self, caller: caller, to: EthCrossAccount, amount: uint256) -> Result<bool> {177 fn mint_cross(
178 &mut self,
179 caller: caller,
180 to: pallet_common::eth::CrossAddress,
181 amount: uint256,
182 ) -> Result<bool> {
179 let caller = T::CrossAccountId::from_eth(caller);183 let caller = T::CrossAccountId::from_eth(caller);
180 let to = to.into_sub_cross_account::<T>()?;184 let to = to.into_sub_cross_account::<T>()?;
191 fn approve_cross(195 fn approve_cross(
192 &mut self,196 &mut self,
193 caller: caller,197 caller: caller,
194 spender: EthCrossAccount,198 spender: pallet_common::eth::CrossAddress,
195 amount: uint256,199 amount: uint256,
196 ) -> Result<bool> {200 ) -> Result<bool> {
197 let caller = T::CrossAccountId::from_eth(caller);201 let caller = T::CrossAccountId::from_eth(caller);
232 fn burn_from_cross(236 fn burn_from_cross(
233 &mut self,237 &mut self,
234 caller: caller,238 caller: caller,
235 from: EthCrossAccount,239 from: pallet_common::eth::CrossAddress,
236 amount: uint256,240 amount: uint256,
237 ) -> Result<bool> {241 ) -> Result<bool> {
238 let caller = T::CrossAccountId::from_eth(caller);242 let caller = T::CrossAccountId::from_eth(caller);
274 fn transfer_cross(278 fn transfer_cross(
275 &mut self,279 &mut self,
276 caller: caller,280 caller: caller,
277 to: EthCrossAccount,281 to: pallet_common::eth::CrossAddress,
278 amount: uint256,282 amount: uint256,
279 ) -> Result<bool> {283 ) -> Result<bool> {
280 let caller = T::CrossAccountId::from_eth(caller);284 let caller = T::CrossAccountId::from_eth(caller);
292 fn transfer_from_cross(296 fn transfer_from_cross(
293 &mut self,297 &mut self,
294 caller: caller,298 caller: caller,
295 from: EthCrossAccount,299 from: pallet_common::eth::CrossAddress,
296 to: EthCrossAccount,300 to: pallet_common::eth::CrossAddress,
297 amount: uint256,301 amount: uint256,
298 ) -> Result<bool> {302 ) -> Result<bool> {
299 let caller = T::CrossAccountId::from_eth(caller);303 let caller = T::CrossAccountId::from_eth(caller);
modifiedpallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
18}18}
1919
20/// @title A contract that allows you to work with collections.20/// @title A contract that allows you to work with collections.
21/// @dev the ERC-165 identifier for this interface is 0x81172a7521/// @dev the ERC-165 identifier for this interface is 0x2a14cfd1
22contract Collection is Dummy, ERC165 {22contract Collection is Dummy, ERC165 {
23 // /// Set collection property.23 // /// Set collection property.
24 // ///24 // ///
114 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.114 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
115 /// @dev EVM selector for this function is: 0x84a1d5a8,115 /// @dev EVM selector for this function is: 0x84a1d5a8,
116 /// or in textual repr: setCollectionSponsorCross((address,uint256))116 /// or in textual repr: setCollectionSponsorCross((address,uint256))
117 function setCollectionSponsorCross(EthCrossAccount memory sponsor) public {117 function setCollectionSponsorCross(CrossAddress memory sponsor) public {
118 require(false, stub_error);118 require(false, stub_error);
119 sponsor;119 sponsor;
120 dummy = 0;120 dummy = 0;
152 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.152 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
153 /// @dev EVM selector for this function is: 0x6ec0a9f1,153 /// @dev EVM selector for this function is: 0x6ec0a9f1,
154 /// or in textual repr: collectionSponsor()154 /// or in textual repr: collectionSponsor()
155 function collectionSponsor() public view returns (EthCrossAccount memory) {155 function collectionSponsor() public view returns (CrossAddress memory) {
156 require(false, stub_error);156 require(false, stub_error);
157 dummy;157 dummy;
158 return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);158 return CrossAddress(0x0000000000000000000000000000000000000000, 0);
159 }159 }
160160
161 /// Get current collection limits.161 /// Get current collection limits.
162 ///162 ///
163 /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:163 /// @return Array of collection limits
164 /// "accountTokenOwnershipLimit",
165 /// "sponsoredDataSize",
166 /// "sponsoredDataRateLimit",
167 /// "tokenLimit",
168 /// "sponsorTransferTimeout",
169 /// "sponsorApproveTimeout"
170 /// "ownerCanTransfer",
171 /// "ownerCanDestroy",
172 /// "transfersEnabled"
173 /// Return `false` if a limit not set.
174 /// @dev EVM selector for this function is: 0xf63bc572,164 /// @dev EVM selector for this function is: 0xf63bc572,
175 /// or in textual repr: collectionLimits()165 /// or in textual repr: collectionLimits()
176 function collectionLimits() public view returns (Tuple23[] memory) {166 function collectionLimits() public view returns (CollectionLimit[] memory) {
177 require(false, stub_error);167 require(false, stub_error);
178 dummy;168 dummy;
179 return new Tuple23[](0);169 return new CollectionLimit[](0);
180 }170 }
181171
182 /// Set limits for the collection.172 /// Set limits for the collection.
183 /// @dev Throws error if limit not found.173 /// @dev Throws error if limit not found.
184 /// @param limit Name of the limit. Valid names:
185 /// "accountTokenOwnershipLimit",
186 /// "sponsoredDataSize",
187 /// "sponsoredDataRateLimit",
188 /// "tokenLimit",
189 /// "sponsorTransferTimeout",
190 /// "sponsorApproveTimeout"
191 /// "ownerCanTransfer",
192 /// "ownerCanDestroy",
193 /// "transfersEnabled"
194 /// @param status enable\disable limit. Works only with `true`.
195 /// @param value Value of the limit.174 /// @param limit Some limit.
196 /// @dev EVM selector for this function is: 0x88150bd0,175 /// @dev EVM selector for this function is: 0x2316ee74,
197 /// or in textual repr: setCollectionLimit(uint8,bool,uint256)176 /// or in textual repr: setCollectionLimit((uint8,(bool,uint256)))
198 function setCollectionLimit(177 function setCollectionLimit(CollectionLimit memory limit) public {
199 CollectionLimits limit,
200 bool status,
201 uint256 value
202 ) public {
203 require(false, stub_error);178 require(false, stub_error);
204 limit;179 limit;
205 status;
206 value;
207 dummy = 0;180 dummy = 0;
208 }181 }
209182
220 /// @param newAdmin Cross account administrator address.193 /// @param newAdmin Cross account administrator address.
221 /// @dev EVM selector for this function is: 0x859aa7d6,194 /// @dev EVM selector for this function is: 0x859aa7d6,
222 /// or in textual repr: addCollectionAdminCross((address,uint256))195 /// or in textual repr: addCollectionAdminCross((address,uint256))
223 function addCollectionAdminCross(EthCrossAccount memory newAdmin) public {196 function addCollectionAdminCross(CrossAddress memory newAdmin) public {
224 require(false, stub_error);197 require(false, stub_error);
225 newAdmin;198 newAdmin;
226 dummy = 0;199 dummy = 0;
230 /// @param admin Cross account administrator address.203 /// @param admin Cross account administrator address.
231 /// @dev EVM selector for this function is: 0x6c0cd173,204 /// @dev EVM selector for this function is: 0x6c0cd173,
232 /// or in textual repr: removeCollectionAdminCross((address,uint256))205 /// or in textual repr: removeCollectionAdminCross((address,uint256))
233 function removeCollectionAdminCross(EthCrossAccount memory admin) public {206 function removeCollectionAdminCross(CrossAddress memory admin) public {
234 require(false, stub_error);207 require(false, stub_error);
235 admin;208 admin;
236 dummy = 0;209 dummy = 0;
284 /// Returns nesting for a collection257 /// Returns nesting for a collection
285 /// @dev EVM selector for this function is: 0x22d25bfe,258 /// @dev EVM selector for this function is: 0x22d25bfe,
286 /// or in textual repr: collectionNestingRestrictedCollectionIds()259 /// or in textual repr: collectionNestingRestrictedCollectionIds()
287 function collectionNestingRestrictedCollectionIds() public view returns (Tuple29 memory) {260 function collectionNestingRestrictedCollectionIds() public view returns (CollectionNesting memory) {
288 require(false, stub_error);261 require(false, stub_error);
289 dummy;262 dummy;
290 return Tuple29(false, new uint256[](0));263 return CollectionNesting(false, new uint256[](0));
291 }264 }
292265
293 /// Returns permissions for a collection266 /// Returns permissions for a collection
294 /// @dev EVM selector for this function is: 0x5b2eaf4b,267 /// @dev EVM selector for this function is: 0x5b2eaf4b,
295 /// or in textual repr: collectionNestingPermissions()268 /// or in textual repr: collectionNestingPermissions()
296 function collectionNestingPermissions() public view returns (Tuple32[] memory) {269 function collectionNestingPermissions() public view returns (CollectionNestingPermission[] memory) {
297 require(false, stub_error);270 require(false, stub_error);
298 dummy;271 dummy;
299 return new Tuple32[](0);272 return new CollectionNestingPermission[](0);
300 }273 }
301274
302 /// Set the collection access method.275 /// Set the collection access method.
316 /// @param user User address to check.289 /// @param user User address to check.
317 /// @dev EVM selector for this function is: 0x91b6df49,290 /// @dev EVM selector for this function is: 0x91b6df49,
318 /// or in textual repr: allowlistedCross((address,uint256))291 /// or in textual repr: allowlistedCross((address,uint256))
319 function allowlistedCross(EthCrossAccount memory user) public view returns (bool) {292 function allowlistedCross(CrossAddress memory user) public view returns (bool) {
320 require(false, stub_error);293 require(false, stub_error);
321 user;294 user;
322 dummy;295 dummy;
339 /// @param user User cross account address.312 /// @param user User cross account address.
340 /// @dev EVM selector for this function is: 0xa0184a3a,313 /// @dev EVM selector for this function is: 0xa0184a3a,
341 /// or in textual repr: addToCollectionAllowListCross((address,uint256))314 /// or in textual repr: addToCollectionAllowListCross((address,uint256))
342 function addToCollectionAllowListCross(EthCrossAccount memory user) public {315 function addToCollectionAllowListCross(CrossAddress memory user) public {
343 require(false, stub_error);316 require(false, stub_error);
344 user;317 user;
345 dummy = 0;318 dummy = 0;
361 /// @param user User cross account address.334 /// @param user User cross account address.
362 /// @dev EVM selector for this function is: 0x09ba452a,335 /// @dev EVM selector for this function is: 0x09ba452a,
363 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))336 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))
364 function removeFromCollectionAllowListCross(EthCrossAccount memory user) public {337 function removeFromCollectionAllowListCross(CrossAddress memory user) public {
365 require(false, stub_error);338 require(false, stub_error);
366 user;339 user;
367 dummy = 0;340 dummy = 0;
397 /// @return "true" if account is the owner or admin370 /// @return "true" if account is the owner or admin
398 /// @dev EVM selector for this function is: 0x3e75a905,371 /// @dev EVM selector for this function is: 0x3e75a905,
399 /// or in textual repr: isOwnerOrAdminCross((address,uint256))372 /// or in textual repr: isOwnerOrAdminCross((address,uint256))
400 function isOwnerOrAdminCross(EthCrossAccount memory user) public view returns (bool) {373 function isOwnerOrAdminCross(CrossAddress memory user) public view returns (bool) {
401 require(false, stub_error);374 require(false, stub_error);
402 user;375 user;
403 dummy;376 dummy;
421 /// If address is canonical then substrate mirror is zero and vice versa.394 /// If address is canonical then substrate mirror is zero and vice versa.
422 /// @dev EVM selector for this function is: 0xdf727d3b,395 /// @dev EVM selector for this function is: 0xdf727d3b,
423 /// or in textual repr: collectionOwner()396 /// or in textual repr: collectionOwner()
424 function collectionOwner() public view returns (EthCrossAccount memory) {397 function collectionOwner() public view returns (CrossAddress memory) {
425 require(false, stub_error);398 require(false, stub_error);
426 dummy;399 dummy;
427 return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);400 return CrossAddress(0x0000000000000000000000000000000000000000, 0);
428 }401 }
429402
430 // /// Changes collection owner to another account403 // /// Changes collection owner to another account
445 /// If address is canonical then substrate mirror is zero and vice versa.418 /// If address is canonical then substrate mirror is zero and vice versa.
446 /// @dev EVM selector for this function is: 0x5813216b,419 /// @dev EVM selector for this function is: 0x5813216b,
447 /// or in textual repr: collectionAdmins()420 /// or in textual repr: collectionAdmins()
448 function collectionAdmins() public view returns (EthCrossAccount[] memory) {421 function collectionAdmins() public view returns (CrossAddress[] memory) {
449 require(false, stub_error);422 require(false, stub_error);
450 dummy;423 dummy;
451 return new EthCrossAccount[](0);424 return new CrossAddress[](0);
452 }425 }
453426
454 /// Changes collection owner to another account427 /// Changes collection owner to another account
457 /// @param newOwner new owner cross account430 /// @param newOwner new owner cross account
458 /// @dev EVM selector for this function is: 0x6496c497,431 /// @dev EVM selector for this function is: 0x6496c497,
459 /// or in textual repr: changeCollectionOwnerCross((address,uint256))432 /// or in textual repr: changeCollectionOwnerCross((address,uint256))
460 function changeCollectionOwnerCross(EthCrossAccount memory newOwner) public {433 function changeCollectionOwnerCross(CrossAddress memory newOwner) public {
461 require(false, stub_error);434 require(false, stub_error);
462 newOwner;435 newOwner;
463 dummy = 0;436 dummy = 0;
464 }437 }
465}438}
466439
467/// @dev Cross account struct440/// Cross account struct
468struct EthCrossAccount {441struct CrossAddress {
469 address eth;442 address eth;
470 uint256 sub;443 uint256 sub;
471}444}
472445
446/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
447struct CollectionNestingPermission {
448 CollectionPermissionField field;
449 bool value;
450}
451
452/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
473enum CollectionPermissions {453enum CollectionPermissionField {
474 CollectionAdmin,454 /// Owner of token can nest tokens under it.
475 TokenOwner455 TokenOwner,
456 /// Admin of token collection can nest tokens under token.
457 CollectionAdmin
476}458}
477459
478/// @dev anonymous struct460/// Nested collections.
479struct Tuple32 {461struct CollectionNesting {
480 CollectionPermissions field_0;462 bool token_owner;
481 bool field_1;463 uint256[] ids;
482}464}
483465
484/// @dev anonymous struct466/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
467struct CollectionLimit {
468 CollectionLimitField field;
469 OptionUint value;
470}
471
472/// Ethereum representation of Optional value with uint256.
485struct Tuple29 {473struct OptionUint {
486 bool field_0;474 bool status;
487 uint256[] field_1;475 uint256 value;
488}476}
489477
490/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.478/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
491enum CollectionLimits {479enum CollectionLimitField {
492 /// @dev How many tokens can a user have on one account.480 /// How many tokens can a user have on one account.
493 AccountTokenOwnership,481 AccountTokenOwnership,
494 /// @dev How many bytes of data are available for sponsorship.482 /// How many bytes of data are available for sponsorship.
495 SponsoredDataSize,483 SponsoredDataSize,
496 /// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]484 /// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
497 SponsoredDataRateLimit,485 SponsoredDataRateLimit,
498 /// @dev How many tokens can be mined into this collection.486 /// How many tokens can be mined into this collection.
499 TokenLimit,487 TokenLimit,
500 /// @dev Timeouts for transfer sponsoring.488 /// Timeouts for transfer sponsoring.
501 SponsorTransferTimeout,489 SponsorTransferTimeout,
502 /// @dev Timeout for sponsoring an approval in passed blocks.490 /// Timeout for sponsoring an approval in passed blocks.
503 SponsorApproveTimeout,491 SponsorApproveTimeout,
504 /// @dev Whether the collection owner of the collection can send tokens (which belong to other users).492 /// Whether the collection owner of the collection can send tokens (which belong to other users).
505 OwnerCanTransfer,493 OwnerCanTransfer,
506 /// @dev Can the collection owner burn other people's tokens.494 /// Can the collection owner burn other people's tokens.
507 OwnerCanDestroy,495 OwnerCanDestroy,
508 /// @dev Is it possible to send tokens from this collection between users.496 /// Is it possible to send tokens from this collection between users.
509 TransferEnabled497 TransferEnabled
510}498}
511499
512/// @dev anonymous struct500/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
513struct Tuple23 {
514 CollectionLimits field_0;
515 bool field_1;
516 uint256 field_2;
517}
518
519/// @dev Property struct
520struct Property {501struct Property {
521 string key;502 string key;
522 bytes value;503 bytes value;
535516
536 /// @dev EVM selector for this function is: 0x269e6158,517 /// @dev EVM selector for this function is: 0x269e6158,
537 /// or in textual repr: mintCross((address,uint256),uint256)518 /// or in textual repr: mintCross((address,uint256),uint256)
538 function mintCross(EthCrossAccount memory to, uint256 amount) public returns (bool) {519 function mintCross(CrossAddress memory to, uint256 amount) public returns (bool) {
539 require(false, stub_error);520 require(false, stub_error);
540 to;521 to;
541 amount;522 amount;
545526
546 /// @dev EVM selector for this function is: 0x0ecd0ab0,527 /// @dev EVM selector for this function is: 0x0ecd0ab0,
547 /// or in textual repr: approveCross((address,uint256),uint256)528 /// or in textual repr: approveCross((address,uint256),uint256)
548 function approveCross(EthCrossAccount memory spender, uint256 amount) public returns (bool) {529 function approveCross(CrossAddress memory spender, uint256 amount) public returns (bool) {
549 require(false, stub_error);530 require(false, stub_error);
550 spender;531 spender;
551 amount;532 amount;
575 /// @param amount The amount that will be burnt.556 /// @param amount The amount that will be burnt.
576 /// @dev EVM selector for this function is: 0xbb2f5a58,557 /// @dev EVM selector for this function is: 0xbb2f5a58,
577 /// or in textual repr: burnFromCross((address,uint256),uint256)558 /// or in textual repr: burnFromCross((address,uint256),uint256)
578 function burnFromCross(EthCrossAccount memory from, uint256 amount) public returns (bool) {559 function burnFromCross(CrossAddress memory from, uint256 amount) public returns (bool) {
579 require(false, stub_error);560 require(false, stub_error);
580 from;561 from;
581 amount;562 amount;
596577
597 /// @dev EVM selector for this function is: 0x2ada85ff,578 /// @dev EVM selector for this function is: 0x2ada85ff,
598 /// or in textual repr: transferCross((address,uint256),uint256)579 /// or in textual repr: transferCross((address,uint256),uint256)
599 function transferCross(EthCrossAccount memory to, uint256 amount) public returns (bool) {580 function transferCross(CrossAddress memory to, uint256 amount) public returns (bool) {
600 require(false, stub_error);581 require(false, stub_error);
601 to;582 to;
602 amount;583 amount;
607 /// @dev EVM selector for this function is: 0xd5cf430b,588 /// @dev EVM selector for this function is: 0xd5cf430b,
608 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)589 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
609 function transferFromCross(590 function transferFromCross(
610 EthCrossAccount memory from,591 CrossAddress memory from,
611 EthCrossAccount memory to,592 CrossAddress memory to,
612 uint256 amount593 uint256 amount
613 ) public returns (bool) {594 ) public returns (bool) {
614 require(false, stub_error);595 require(false, stub_error);
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
26};26};
27use evm_coder::{27use evm_coder::{
28 abi::AbiType, ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*,28 abi::AbiType, ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*,
29 types::Property as PropertyStruct, weight,29 weight,
30};30};
31use frame_support::BoundedVec;31use frame_support::BoundedVec;
32use up_data_structs::{32use up_data_structs::{
38use pallet_common::{38use pallet_common::{
39 CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,39 CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
40 erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key},40 erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key},
41 eth::{EthCrossAccount, EthTokenPermissions},41 eth,
42};42};
43use pallet_evm::{account::CrossAccountId, PrecompileHandle};43use pallet_evm::{account::CrossAccountId, PrecompileHandle};
44use pallet_evm_coder_substrate::call;44use pallet_evm_coder_substrate::call;
94 fn set_token_property_permissions(94 fn set_token_property_permissions(
95 &mut self,95 &mut self,
96 caller: caller,96 caller: caller,
97 permissions: Vec<(string, Vec<(EthTokenPermissions, bool)>)>,97 permissions: Vec<eth::TokenPropertyPermission>,
98 ) -> Result<()> {98 ) -> Result<()> {
99 let caller = T::CrossAccountId::from_eth(caller);99 let caller = T::CrossAccountId::from_eth(caller);
100 const PERMISSIONS_FIELDS_COUNT: usize = 3;
101
102 let mut perms = Vec::new();
103
104 for (key, pp) in permissions {
105 if pp.len() > PERMISSIONS_FIELDS_COUNT {
106 return Err(alloc::format!(
107 "Actual number of fields {} for {}, which exceeds the maximum value of {}",
108 pp.len(),
109 stringify!(EthTokenPermissions),
110 PERMISSIONS_FIELDS_COUNT
111 )
112 .as_str()
113 .into());
114 }
115
116 let mut token_permission = PropertyPermission::default();100 let perms = eth::TokenPropertyPermission::into_property_key_permissions(permissions)?;
117
118 for (perm, value) in pp {
119 match perm {
120 EthTokenPermissions::Mutable => token_permission.mutable = value,
121 EthTokenPermissions::TokenOwner => token_permission.token_owner = value,
122 EthTokenPermissions::CollectionAdmin => {
123 token_permission.collection_admin = value
124 }
125 }
126 }
127
128 perms.push(PropertyKeyPermission {
129 key: key.into_bytes().try_into().map_err(|_| "too long key")?,
130 permission: token_permission,
131 });
132 }
133101
134 <Pallet<T>>::set_token_property_permissions(self, &caller, perms)102 <Pallet<T>>::set_token_property_permissions(self, &caller, perms)
135 .map_err(dispatch_to_evm::<T>)103 .map_err(dispatch_to_evm::<T>)
136 }104 }
137105
138 /// @notice Get permissions for token properties.106 /// @notice Get permissions for token properties.
139 fn token_property_permissions(107 fn token_property_permissions(&self) -> Result<Vec<eth::TokenPropertyPermission>> {
140 &self,
141 ) -> Result<Vec<(string, Vec<(EthTokenPermissions, bool)>)>> {
142 let perms = <Pallet<T>>::token_property_permission(self.id);108 let perms = <Pallet<T>>::token_property_permission(self.id);
143 Ok(perms109 Ok(perms
144 .into_iter()110 .into_iter()
145 .map(|(key, pp)| {111 .map(eth::TokenPropertyPermission::from)
146 let key = string::from_utf8(key.into_inner()).expect("Stored key must be valid");
147 let pp = vec![
148 (EthTokenPermissions::Mutable, pp.mutable),
149 (EthTokenPermissions::TokenOwner, pp.token_owner),
150 (EthTokenPermissions::CollectionAdmin, pp.collection_admin),
151 ];
152 (key, pp)
153 })
154 .collect())112 .collect())
155 }113 }
156114
198 &mut self,156 &mut self,
199 caller: caller,157 caller: caller,
200 token_id: uint256,158 token_id: uint256,
201 properties: Vec<PropertyStruct>,159 properties: Vec<eth::Property>,
202 ) -> Result<()> {160 ) -> Result<()> {
203 let caller = T::CrossAccountId::from_eth(caller);161 let caller = T::CrossAccountId::from_eth(caller);
204 let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;162 let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
209167
210 let properties = properties168 let properties = properties
211 .into_iter()169 .into_iter()
212 .map(|PropertyStruct { key, value }| {170 .map(eth::Property::try_into)
213 let key = <Vec<u8>>::from(key)
214 .try_into()
215 .map_err(|_| "key too large")?;
216
217 let value = value.0.try_into().map_err(|_| "value too large")?;
218
219 Ok(Property { key, value })
220 })
221 .collect::<Result<Vec<_>>>()?;171 .collect::<Result<Vec<_>>>()?;
222172
223 <Pallet<T>>::set_token_properties(173 <Pallet<T>>::set_token_properties(
800 /// Returns the owner (in cross format) of the token.750 /// Returns the owner (in cross format) of the token.
801 ///751 ///
802 /// @param tokenId Id for the token.752 /// @param tokenId Id for the token.
803 fn cross_owner_of(&self, token_id: uint256) -> Result<EthCrossAccount> {753 fn cross_owner_of(&self, token_id: uint256) -> Result<eth::CrossAddress> {
804 Self::token_owner(&self, token_id.try_into()?)754 Self::token_owner(&self, token_id.try_into()?)
805 .map(|o| EthCrossAccount::from_sub_cross_account::<T>(&o))755 .map(|o| eth::CrossAddress::from_sub_cross_account::<T>(&o))
806 .ok_or(Error::Revert("key too large".into()))756 .ok_or(Error::Revert("key too large".into()))
807 }757 }
808758
811 /// @param tokenId Id for the token.761 /// @param tokenId Id for the token.
812 /// @param keys Properties keys. Empty keys for all propertyes.762 /// @param keys Properties keys. Empty keys for all propertyes.
813 /// @return Vector of properties key/value pairs.763 /// @return Vector of properties key/value pairs.
814 fn properties(&self, token_id: uint256, keys: Vec<string>) -> Result<Vec<PropertyStruct>> {764 fn properties(&self, token_id: uint256, keys: Vec<string>) -> Result<Vec<eth::Property>> {
815 let keys = keys765 let keys = keys
816 .into_iter()766 .into_iter()
817 .map(|key| {767 .map(|key| {
827 if keys.is_empty() { None } else { Some(keys) },777 if keys.is_empty() { None } else { Some(keys) },
828 )778 )
829 .into_iter()779 .into_iter()
830 .map(|p| {780 .map(eth::Property::try_from)
831 let key = string::from_utf8(p.key.to_vec())
832 .map_err(|e| Error::Revert(alloc::format!("{}", e)))?;
833 let value = bytes(p.value.to_vec());
834 Ok(PropertyStruct { key, value })
835 })
836 .collect::<Result<Vec<_>>>()781 .collect::<Result<Vec<_>>>()
837 }782 }
838783
846 fn approve_cross(791 fn approve_cross(
847 &mut self,792 &mut self,
848 caller: caller,793 caller: caller,
849 approved: EthCrossAccount,794 approved: eth::CrossAddress,
850 token_id: uint256,795 token_id: uint256,
851 ) -> Result<void> {796 ) -> Result<void> {
852 let caller = T::CrossAccountId::from_eth(caller);797 let caller = T::CrossAccountId::from_eth(caller);
885 fn transfer_cross(830 fn transfer_cross(
886 &mut self,831 &mut self,
887 caller: caller,832 caller: caller,
888 to: EthCrossAccount,833 to: eth::CrossAddress,
889 token_id: uint256,834 token_id: uint256,
890 ) -> Result<void> {835 ) -> Result<void> {
891 let caller = T::CrossAccountId::from_eth(caller);836 let caller = T::CrossAccountId::from_eth(caller);
909 fn transfer_from_cross(854 fn transfer_from_cross(
910 &mut self,855 &mut self,
911 caller: caller,856 caller: caller,
912 from: EthCrossAccount,857 from: eth::CrossAddress,
913 to: EthCrossAccount,858 to: eth::CrossAddress,
914 token_id: uint256,859 token_id: uint256,
915 ) -> Result<void> {860 ) -> Result<void> {
916 let caller = T::CrossAccountId::from_eth(caller);861 let caller = T::CrossAccountId::from_eth(caller);
956 fn burn_from_cross(901 fn burn_from_cross(
957 &mut self,902 &mut self,
958 caller: caller,903 caller: caller,
959 from: EthCrossAccount,904 from: eth::CrossAddress,
960 token_id: uint256,905 token_id: uint256,
961 ) -> Result<void> {906 ) -> Result<void> {
962 let caller = T::CrossAccountId::from_eth(caller);907 let caller = T::CrossAccountId::from_eth(caller);
1078 fn mint_cross(1023 fn mint_cross(
1079 &mut self,1024 &mut self,
1080 caller: caller,1025 caller: caller,
1081 to: EthCrossAccount,1026 to: eth::CrossAddress,
1082 properties: Vec<PropertyStruct>,1027 properties: Vec<eth::Property>,
1083 ) -> Result<uint256> {1028 ) -> Result<uint256> {
1084 let token_id = <TokensMinted<T>>::get(self.id)1029 let token_id = <TokensMinted<T>>::get(self.id)
1085 .checked_add(1)1030 .checked_add(1)
10891034
1090 let properties = properties1035 let properties = properties
1091 .into_iter()1036 .into_iter()
1092 .map(|PropertyStruct { key, value }| {1037 .map(eth::Property::try_into)
1093 let key = <Vec<u8>>::from(key)
1094 .try_into()
1095 .map_err(|_| "key too large")?;
1096
1097 let value = value.0.try_into().map_err(|_| "value too large")?;
1098
1099 Ok(Property { key, value })
1100 })
1101 .collect::<Result<Vec<_>>>()?1038 .collect::<Result<Vec<_>>>()?
1102 .try_into()1039 .try_into()
1103 .map_err(|_| Error::Revert(alloc::format!("too many properties")))?;1040 .map_err(|_| Error::Revert(alloc::format!("too many properties")))?;
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
42 /// @param permissions Permissions for keys.42 /// @param permissions Permissions for keys.
43 /// @dev EVM selector for this function is: 0xbd92983a,43 /// @dev EVM selector for this function is: 0xbd92983a,
44 /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])44 /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
45 function setTokenPropertyPermissions(Tuple61[] memory permissions) public {45 function setTokenPropertyPermissions(TokenPropertyPermission[] memory permissions) public {
46 require(false, stub_error);46 require(false, stub_error);
47 permissions;47 permissions;
48 dummy = 0;48 dummy = 0;
51 /// @notice Get permissions for token properties.51 /// @notice Get permissions for token properties.
52 /// @dev EVM selector for this function is: 0xf23d7790,52 /// @dev EVM selector for this function is: 0xf23d7790,
53 /// or in textual repr: tokenPropertyPermissions()53 /// or in textual repr: tokenPropertyPermissions()
54 function tokenPropertyPermissions() public view returns (Tuple61[] memory) {54 function tokenPropertyPermissions() public view returns (TokenPropertyPermission[] memory) {
55 require(false, stub_error);55 require(false, stub_error);
56 dummy;56 dummy;
57 return new Tuple61[](0);57 return new TokenPropertyPermission[](0);
58 }58 }
5959
60 // /// @notice Set token property value.60 // /// @notice Set token property value.
127 }127 }
128}128}
129129
130/// @dev Property struct130/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
131struct Property {131struct Property {
132 string key;132 string key;
133 bytes value;133 bytes value;
134}134}
135135
136/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.136/// Ethereum representation of Token Property Permissions.
137enum EthTokenPermissions {
138 /// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
139 Mutable,
140 /// @dev Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
141 TokenOwner,
142 /// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
143 CollectionAdmin
144}
145
146/// @dev anonymous struct
147struct Tuple61 {137struct TokenPropertyPermission {
138 /// Token property key.
148 string field_0;139 string key;
140 /// Token property permissions.
149 Tuple59[] field_1;141 PropertyPermission[] permissions;
150}142}
151143
152/// @dev anonymous struct144/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
153struct Tuple59 {145struct PropertyPermission {
146 /// TokenPermission field.
154 EthTokenPermissions field_0;147 TokenPermissionField code;
148 /// TokenPermission value.
155 bool field_1;149 bool value;
156}150}
151
152/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
153enum TokenPermissionField {
154 /// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
155 Mutable,
156 /// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
157 TokenOwner,
158 /// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
159 CollectionAdmin
160}
157161
158/// @title A contract that allows you to work with collections.162/// @title A contract that allows you to work with collections.
159/// @dev the ERC-165 identifier for this interface is 0x81172a75163/// @dev the ERC-165 identifier for this interface is 0x2a14cfd1
160contract Collection is Dummy, ERC165 {164contract Collection is Dummy, ERC165 {
161 // /// Set collection property.165 // /// Set collection property.
162 // ///166 // ///
252 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.256 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
253 /// @dev EVM selector for this function is: 0x84a1d5a8,257 /// @dev EVM selector for this function is: 0x84a1d5a8,
254 /// or in textual repr: setCollectionSponsorCross((address,uint256))258 /// or in textual repr: setCollectionSponsorCross((address,uint256))
255 function setCollectionSponsorCross(EthCrossAccount memory sponsor) public {259 function setCollectionSponsorCross(CrossAddress memory sponsor) public {
256 require(false, stub_error);260 require(false, stub_error);
257 sponsor;261 sponsor;
258 dummy = 0;262 dummy = 0;
290 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.294 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
291 /// @dev EVM selector for this function is: 0x6ec0a9f1,295 /// @dev EVM selector for this function is: 0x6ec0a9f1,
292 /// or in textual repr: collectionSponsor()296 /// or in textual repr: collectionSponsor()
293 function collectionSponsor() public view returns (EthCrossAccount memory) {297 function collectionSponsor() public view returns (CrossAddress memory) {
294 require(false, stub_error);298 require(false, stub_error);
295 dummy;299 dummy;
296 return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);300 return CrossAddress(0x0000000000000000000000000000000000000000, 0);
297 }301 }
298302
299 /// Get current collection limits.303 /// Get current collection limits.
300 ///304 ///
301 /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:305 /// @return Array of collection limits
302 /// "accountTokenOwnershipLimit",
303 /// "sponsoredDataSize",
304 /// "sponsoredDataRateLimit",
305 /// "tokenLimit",
306 /// "sponsorTransferTimeout",
307 /// "sponsorApproveTimeout"
308 /// "ownerCanTransfer",
309 /// "ownerCanDestroy",
310 /// "transfersEnabled"
311 /// Return `false` if a limit not set.
312 /// @dev EVM selector for this function is: 0xf63bc572,306 /// @dev EVM selector for this function is: 0xf63bc572,
313 /// or in textual repr: collectionLimits()307 /// or in textual repr: collectionLimits()
314 function collectionLimits() public view returns (Tuple35[] memory) {308 function collectionLimits() public view returns (CollectionLimit[] memory) {
315 require(false, stub_error);309 require(false, stub_error);
316 dummy;310 dummy;
317 return new Tuple35[](0);311 return new CollectionLimit[](0);
318 }312 }
319313
320 /// Set limits for the collection.314 /// Set limits for the collection.
321 /// @dev Throws error if limit not found.315 /// @dev Throws error if limit not found.
322 /// @param limit Name of the limit. Valid names:
323 /// "accountTokenOwnershipLimit",
324 /// "sponsoredDataSize",
325 /// "sponsoredDataRateLimit",
326 /// "tokenLimit",
327 /// "sponsorTransferTimeout",
328 /// "sponsorApproveTimeout"
329 /// "ownerCanTransfer",
330 /// "ownerCanDestroy",
331 /// "transfersEnabled"
332 /// @param status enable\disable limit. Works only with `true`.
333 /// @param value Value of the limit.316 /// @param limit Some limit.
334 /// @dev EVM selector for this function is: 0x88150bd0,317 /// @dev EVM selector for this function is: 0x2316ee74,
335 /// or in textual repr: setCollectionLimit(uint8,bool,uint256)318 /// or in textual repr: setCollectionLimit((uint8,(bool,uint256)))
336 function setCollectionLimit(319 function setCollectionLimit(CollectionLimit memory limit) public {
337 CollectionLimits limit,
338 bool status,
339 uint256 value
340 ) public {
341 require(false, stub_error);320 require(false, stub_error);
342 limit;321 limit;
343 status;
344 value;
345 dummy = 0;322 dummy = 0;
346 }323 }
347324
358 /// @param newAdmin Cross account administrator address.335 /// @param newAdmin Cross account administrator address.
359 /// @dev EVM selector for this function is: 0x859aa7d6,336 /// @dev EVM selector for this function is: 0x859aa7d6,
360 /// or in textual repr: addCollectionAdminCross((address,uint256))337 /// or in textual repr: addCollectionAdminCross((address,uint256))
361 function addCollectionAdminCross(EthCrossAccount memory newAdmin) public {338 function addCollectionAdminCross(CrossAddress memory newAdmin) public {
362 require(false, stub_error);339 require(false, stub_error);
363 newAdmin;340 newAdmin;
364 dummy = 0;341 dummy = 0;
368 /// @param admin Cross account administrator address.345 /// @param admin Cross account administrator address.
369 /// @dev EVM selector for this function is: 0x6c0cd173,346 /// @dev EVM selector for this function is: 0x6c0cd173,
370 /// or in textual repr: removeCollectionAdminCross((address,uint256))347 /// or in textual repr: removeCollectionAdminCross((address,uint256))
371 function removeCollectionAdminCross(EthCrossAccount memory admin) public {348 function removeCollectionAdminCross(CrossAddress memory admin) public {
372 require(false, stub_error);349 require(false, stub_error);
373 admin;350 admin;
374 dummy = 0;351 dummy = 0;
422 /// Returns nesting for a collection399 /// Returns nesting for a collection
423 /// @dev EVM selector for this function is: 0x22d25bfe,400 /// @dev EVM selector for this function is: 0x22d25bfe,
424 /// or in textual repr: collectionNestingRestrictedCollectionIds()401 /// or in textual repr: collectionNestingRestrictedCollectionIds()
425 function collectionNestingRestrictedCollectionIds() public view returns (Tuple41 memory) {402 function collectionNestingRestrictedCollectionIds() public view returns (CollectionNesting memory) {
426 require(false, stub_error);403 require(false, stub_error);
427 dummy;404 dummy;
428 return Tuple41(false, new uint256[](0));405 return CollectionNesting(false, new uint256[](0));
429 }406 }
430407
431 /// Returns permissions for a collection408 /// Returns permissions for a collection
432 /// @dev EVM selector for this function is: 0x5b2eaf4b,409 /// @dev EVM selector for this function is: 0x5b2eaf4b,
433 /// or in textual repr: collectionNestingPermissions()410 /// or in textual repr: collectionNestingPermissions()
434 function collectionNestingPermissions() public view returns (Tuple44[] memory) {411 function collectionNestingPermissions() public view returns (CollectionNestingPermission[] memory) {
435 require(false, stub_error);412 require(false, stub_error);
436 dummy;413 dummy;
437 return new Tuple44[](0);414 return new CollectionNestingPermission[](0);
438 }415 }
439416
440 /// Set the collection access method.417 /// Set the collection access method.
454 /// @param user User address to check.431 /// @param user User address to check.
455 /// @dev EVM selector for this function is: 0x91b6df49,432 /// @dev EVM selector for this function is: 0x91b6df49,
456 /// or in textual repr: allowlistedCross((address,uint256))433 /// or in textual repr: allowlistedCross((address,uint256))
457 function allowlistedCross(EthCrossAccount memory user) public view returns (bool) {434 function allowlistedCross(CrossAddress memory user) public view returns (bool) {
458 require(false, stub_error);435 require(false, stub_error);
459 user;436 user;
460 dummy;437 dummy;
477 /// @param user User cross account address.454 /// @param user User cross account address.
478 /// @dev EVM selector for this function is: 0xa0184a3a,455 /// @dev EVM selector for this function is: 0xa0184a3a,
479 /// or in textual repr: addToCollectionAllowListCross((address,uint256))456 /// or in textual repr: addToCollectionAllowListCross((address,uint256))
480 function addToCollectionAllowListCross(EthCrossAccount memory user) public {457 function addToCollectionAllowListCross(CrossAddress memory user) public {
481 require(false, stub_error);458 require(false, stub_error);
482 user;459 user;
483 dummy = 0;460 dummy = 0;
499 /// @param user User cross account address.476 /// @param user User cross account address.
500 /// @dev EVM selector for this function is: 0x09ba452a,477 /// @dev EVM selector for this function is: 0x09ba452a,
501 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))478 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))
502 function removeFromCollectionAllowListCross(EthCrossAccount memory user) public {479 function removeFromCollectionAllowListCross(CrossAddress memory user) public {
503 require(false, stub_error);480 require(false, stub_error);
504 user;481 user;
505 dummy = 0;482 dummy = 0;
535 /// @return "true" if account is the owner or admin512 /// @return "true" if account is the owner or admin
536 /// @dev EVM selector for this function is: 0x3e75a905,513 /// @dev EVM selector for this function is: 0x3e75a905,
537 /// or in textual repr: isOwnerOrAdminCross((address,uint256))514 /// or in textual repr: isOwnerOrAdminCross((address,uint256))
538 function isOwnerOrAdminCross(EthCrossAccount memory user) public view returns (bool) {515 function isOwnerOrAdminCross(CrossAddress memory user) public view returns (bool) {
539 require(false, stub_error);516 require(false, stub_error);
540 user;517 user;
541 dummy;518 dummy;
559 /// If address is canonical then substrate mirror is zero and vice versa.536 /// If address is canonical then substrate mirror is zero and vice versa.
560 /// @dev EVM selector for this function is: 0xdf727d3b,537 /// @dev EVM selector for this function is: 0xdf727d3b,
561 /// or in textual repr: collectionOwner()538 /// or in textual repr: collectionOwner()
562 function collectionOwner() public view returns (EthCrossAccount memory) {539 function collectionOwner() public view returns (CrossAddress memory) {
563 require(false, stub_error);540 require(false, stub_error);
564 dummy;541 dummy;
565 return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);542 return CrossAddress(0x0000000000000000000000000000000000000000, 0);
566 }543 }
567544
568 // /// Changes collection owner to another account545 // /// Changes collection owner to another account
583 /// If address is canonical then substrate mirror is zero and vice versa.560 /// If address is canonical then substrate mirror is zero and vice versa.
584 /// @dev EVM selector for this function is: 0x5813216b,561 /// @dev EVM selector for this function is: 0x5813216b,
585 /// or in textual repr: collectionAdmins()562 /// or in textual repr: collectionAdmins()
586 function collectionAdmins() public view returns (EthCrossAccount[] memory) {563 function collectionAdmins() public view returns (CrossAddress[] memory) {
587 require(false, stub_error);564 require(false, stub_error);
588 dummy;565 dummy;
589 return new EthCrossAccount[](0);566 return new CrossAddress[](0);
590 }567 }
591568
592 /// Changes collection owner to another account569 /// Changes collection owner to another account
595 /// @param newOwner new owner cross account572 /// @param newOwner new owner cross account
596 /// @dev EVM selector for this function is: 0x6496c497,573 /// @dev EVM selector for this function is: 0x6496c497,
597 /// or in textual repr: changeCollectionOwnerCross((address,uint256))574 /// or in textual repr: changeCollectionOwnerCross((address,uint256))
598 function changeCollectionOwnerCross(EthCrossAccount memory newOwner) public {575 function changeCollectionOwnerCross(CrossAddress memory newOwner) public {
599 require(false, stub_error);576 require(false, stub_error);
600 newOwner;577 newOwner;
601 dummy = 0;578 dummy = 0;
602 }579 }
603}580}
604581
605/// @dev Cross account struct582/// Cross account struct
606struct EthCrossAccount {583struct CrossAddress {
607 address eth;584 address eth;
608 uint256 sub;585 uint256 sub;
609}586}
610587
588/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
589struct CollectionNestingPermission {
590 CollectionPermissionField field;
591 bool value;
592}
593
594/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
611enum CollectionPermissions {595enum CollectionPermissionField {
612 CollectionAdmin,596 /// Owner of token can nest tokens under it.
613 TokenOwner597 TokenOwner,
598 /// Admin of token collection can nest tokens under token.
599 CollectionAdmin
614}600}
615601
616/// @dev anonymous struct602/// Nested collections.
617struct Tuple44 {603struct CollectionNesting {
618 CollectionPermissions field_0;604 bool token_owner;
619 bool field_1;605 uint256[] ids;
620}606}
621607
622/// @dev anonymous struct608/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
609struct CollectionLimit {
610 CollectionLimitField field;
611 OptionUint value;
612}
613
614/// Ethereum representation of Optional value with uint256.
623struct Tuple41 {615struct OptionUint {
624 bool field_0;616 bool status;
625 uint256[] field_1;617 uint256 value;
626}618}
627619
628/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.620/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
629enum CollectionLimits {621enum CollectionLimitField {
630 /// @dev How many tokens can a user have on one account.622 /// How many tokens can a user have on one account.
631 AccountTokenOwnership,623 AccountTokenOwnership,
632 /// @dev How many bytes of data are available for sponsorship.624 /// How many bytes of data are available for sponsorship.
633 SponsoredDataSize,625 SponsoredDataSize,
634 /// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]626 /// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
635 SponsoredDataRateLimit,627 SponsoredDataRateLimit,
636 /// @dev How many tokens can be mined into this collection.628 /// How many tokens can be mined into this collection.
637 TokenLimit,629 TokenLimit,
638 /// @dev Timeouts for transfer sponsoring.630 /// Timeouts for transfer sponsoring.
639 SponsorTransferTimeout,631 SponsorTransferTimeout,
640 /// @dev Timeout for sponsoring an approval in passed blocks.632 /// Timeout for sponsoring an approval in passed blocks.
641 SponsorApproveTimeout,633 SponsorApproveTimeout,
642 /// @dev Whether the collection owner of the collection can send tokens (which belong to other users).634 /// Whether the collection owner of the collection can send tokens (which belong to other users).
643 OwnerCanTransfer,635 OwnerCanTransfer,
644 /// @dev Can the collection owner burn other people's tokens.636 /// Can the collection owner burn other people's tokens.
645 OwnerCanDestroy,637 OwnerCanDestroy,
646 /// @dev Is it possible to send tokens from this collection between users.638 /// Is it possible to send tokens from this collection between users.
647 TransferEnabled639 TransferEnabled
648}640}
649
650/// @dev anonymous struct
651struct Tuple35 {
652 CollectionLimits field_0;
653 bool field_1;
654 uint256 field_2;
655}
656641
657/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension642/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
658/// @dev See https://eips.ethereum.org/EIPS/eip-721643/// @dev See https://eips.ethereum.org/EIPS/eip-721
832 /// @param tokenId Id for the token.817 /// @param tokenId Id for the token.
833 /// @dev EVM selector for this function is: 0x2b29dace,818 /// @dev EVM selector for this function is: 0x2b29dace,
834 /// or in textual repr: crossOwnerOf(uint256)819 /// or in textual repr: crossOwnerOf(uint256)
835 function crossOwnerOf(uint256 tokenId) public view returns (EthCrossAccount memory) {820 function crossOwnerOf(uint256 tokenId) public view returns (CrossAddress memory) {
836 require(false, stub_error);821 require(false, stub_error);
837 tokenId;822 tokenId;
838 dummy;823 dummy;
839 return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);824 return CrossAddress(0x0000000000000000000000000000000000000000, 0);
840 }825 }
841826
842 /// Returns the token properties.827 /// Returns the token properties.
862 /// @param tokenId The NFT to approve847 /// @param tokenId The NFT to approve
863 /// @dev EVM selector for this function is: 0x0ecd0ab0,848 /// @dev EVM selector for this function is: 0x0ecd0ab0,
864 /// or in textual repr: approveCross((address,uint256),uint256)849 /// or in textual repr: approveCross((address,uint256),uint256)
865 function approveCross(EthCrossAccount memory approved, uint256 tokenId) public {850 function approveCross(CrossAddress memory approved, uint256 tokenId) public {
866 require(false, stub_error);851 require(false, stub_error);
867 approved;852 approved;
868 tokenId;853 tokenId;
890 /// @param tokenId The NFT to transfer875 /// @param tokenId The NFT to transfer
891 /// @dev EVM selector for this function is: 0x2ada85ff,876 /// @dev EVM selector for this function is: 0x2ada85ff,
892 /// or in textual repr: transferCross((address,uint256),uint256)877 /// or in textual repr: transferCross((address,uint256),uint256)
893 function transferCross(EthCrossAccount memory to, uint256 tokenId) public {878 function transferCross(CrossAddress memory to, uint256 tokenId) public {
894 require(false, stub_error);879 require(false, stub_error);
895 to;880 to;
896 tokenId;881 tokenId;
906 /// @dev EVM selector for this function is: 0xd5cf430b,891 /// @dev EVM selector for this function is: 0xd5cf430b,
907 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)892 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
908 function transferFromCross(893 function transferFromCross(
909 EthCrossAccount memory from,894 CrossAddress memory from,
910 EthCrossAccount memory to,895 CrossAddress memory to,
911 uint256 tokenId896 uint256 tokenId
912 ) public {897 ) public {
913 require(false, stub_error);898 require(false, stub_error);
940 /// @param tokenId The NFT to transfer925 /// @param tokenId The NFT to transfer
941 /// @dev EVM selector for this function is: 0xbb2f5a58,926 /// @dev EVM selector for this function is: 0xbb2f5a58,
942 /// or in textual repr: burnFromCross((address,uint256),uint256)927 /// or in textual repr: burnFromCross((address,uint256),uint256)
943 function burnFromCross(EthCrossAccount memory from, uint256 tokenId) public {928 function burnFromCross(CrossAddress memory from, uint256 tokenId) public {
944 require(false, stub_error);929 require(false, stub_error);
945 from;930 from;
946 tokenId;931 tokenId;
992 /// @return uint256 The id of the newly minted token977 /// @return uint256 The id of the newly minted token
993 /// @dev EVM selector for this function is: 0xb904db03,978 /// @dev EVM selector for this function is: 0xb904db03,
994 /// or in textual repr: mintCross((address,uint256),(string,bytes)[])979 /// or in textual repr: mintCross((address,uint256),(string,bytes)[])
995 function mintCross(EthCrossAccount memory to, Property[] memory properties) public returns (uint256) {980 function mintCross(CrossAddress memory to, Property[] memory properties) public returns (uint256) {
996 require(false, stub_error);981 require(false, stub_error);
997 to;982 to;
998 properties;983 properties;
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
27};27};
28use evm_coder::{28use evm_coder::{
29 abi::AbiType, ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*,29 abi::AbiType, ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*,
30 types::Property as PropertyStruct, weight,30 weight,
31};31};
32use frame_support::{BoundedBTreeMap, BoundedVec};32use frame_support::{BoundedBTreeMap, BoundedVec};
33use pallet_common::{33use pallet_common::{
34 CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,34 CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
35 Error as CommonError,
35 erc::{CommonEvmHandler, CollectionCall, static_property::key},36 erc::{CommonEvmHandler, CollectionCall, static_property::key},
36 eth::{EthCrossAccount, EthTokenPermissions},37 eth,
37 Error as CommonError,
38};38};
39use pallet_evm::{account::CrossAccountId, PrecompileHandle};39use pallet_evm::{account::CrossAccountId, PrecompileHandle};
40use pallet_evm_coder_substrate::{call, dispatch_to_evm};40use pallet_evm_coder_substrate::{call, dispatch_to_evm};
97 fn set_token_property_permissions(97 fn set_token_property_permissions(
98 &mut self,98 &mut self,
99 caller: caller,99 caller: caller,
100 permissions: Vec<(string, Vec<(EthTokenPermissions, bool)>)>,100 permissions: Vec<eth::TokenPropertyPermission>,
101 ) -> Result<()> {101 ) -> Result<()> {
102 let caller = T::CrossAccountId::from_eth(caller);102 let caller = T::CrossAccountId::from_eth(caller);
103 const PERMISSIONS_FIELDS_COUNT: usize = 3;
104
105 let mut perms = Vec::new();
106
107 for (key, pp) in permissions {
108 if pp.len() > PERMISSIONS_FIELDS_COUNT {
109 return Err(alloc::format!(
110 "Actual number of fields {} for {}, which exceeds the maximum value of {}",
111 pp.len(),
112 stringify!(EthTokenPermissions),
113 PERMISSIONS_FIELDS_COUNT
114 )
115 .as_str()
116 .into());
117 }
118
119 let mut token_permission = PropertyPermission {103 let perms = eth::TokenPropertyPermission::into_property_key_permissions(permissions)?;
120 mutable: false,
121 collection_admin: false,
122 token_owner: false,
123 };
124
125 for (perm, value) in pp {
126 match perm {
127 EthTokenPermissions::Mutable => token_permission.mutable = value,
128 EthTokenPermissions::TokenOwner => token_permission.token_owner = value,
129 EthTokenPermissions::CollectionAdmin => {
130 token_permission.collection_admin = value
131 }
132 }
133 }
134
135 perms.push(PropertyKeyPermission {
136 key: key.into_bytes().try_into().map_err(|_| "too long key")?,
137 permission: token_permission,
138 });
139 }
140104
141 <Pallet<T>>::set_token_property_permissions(self, &caller, perms)105 <Pallet<T>>::set_token_property_permissions(self, &caller, perms)
142 .map_err(dispatch_to_evm::<T>)106 .map_err(dispatch_to_evm::<T>)
143 }107 }
144108
145 /// @notice Get permissions for token properties.109 /// @notice Get permissions for token properties.
146 fn token_property_permissions(110 fn token_property_permissions(&self) -> Result<Vec<eth::TokenPropertyPermission>> {
147 &self,
148 ) -> Result<Vec<(string, Vec<(EthTokenPermissions, bool)>)>> {
149 let perms = <Pallet<T>>::token_property_permission(self.id);111 let perms = <Pallet<T>>::token_property_permission(self.id);
150 Ok(perms112 Ok(perms
151 .into_iter()113 .into_iter()
152 .map(|(key, pp)| {114 .map(eth::TokenPropertyPermission::from)
153 let key = string::from_utf8(key.into_inner()).expect("Stored key must be valid");
154 let pp = vec![
155 (EthTokenPermissions::Mutable, pp.mutable),
156 (EthTokenPermissions::TokenOwner, pp.token_owner),
157 (EthTokenPermissions::CollectionAdmin, pp.collection_admin),
158 ];
159 (key, pp)
160 })
161 .collect())115 .collect())
162 }116 }
163117
205 &mut self,159 &mut self,
206 caller: caller,160 caller: caller,
207 token_id: uint256,161 token_id: uint256,
208 properties: Vec<PropertyStruct>,162 properties: Vec<eth::Property>,
209 ) -> Result<()> {163 ) -> Result<()> {
210 let caller = T::CrossAccountId::from_eth(caller);164 let caller = T::CrossAccountId::from_eth(caller);
211 let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;165 let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
216170
217 let properties = properties171 let properties = properties
218 .into_iter()172 .into_iter()
219 .map(|PropertyStruct { key, value }| {173 .map(eth::Property::try_into)
220 let key = <Vec<u8>>::from(key)
221 .try_into()
222 .map_err(|_| "key too large")?;
223
224 let value = value.0.try_into().map_err(|_| "value too large")?;
225
226 Ok(Property { key, value })
227 })
228 .collect::<Result<Vec<_>>>()?;174 .collect::<Result<Vec<_>>>()?;
229175
230 <Pallet<T>>::set_token_properties(176 <Pallet<T>>::set_token_properties(
839 /// Returns the owner (in cross format) of the token.785 /// Returns the owner (in cross format) of the token.
840 ///786 ///
841 /// @param tokenId Id for the token.787 /// @param tokenId Id for the token.
842 fn cross_owner_of(&self, token_id: uint256) -> Result<EthCrossAccount> {788 fn cross_owner_of(&self, token_id: uint256) -> Result<eth::CrossAddress> {
843 Self::token_owner(&self, token_id.try_into()?)789 Self::token_owner(&self, token_id.try_into()?)
844 .map(|o| EthCrossAccount::from_sub_cross_account::<T>(&o))790 .map(|o| eth::CrossAddress::from_sub_cross_account::<T>(&o))
845 .ok_or(Error::Revert("key too large".into()))791 .ok_or(Error::Revert("key too large".into()))
846 }792 }
847793
850 /// @param tokenId Id for the token.796 /// @param tokenId Id for the token.
851 /// @param keys Properties keys. Empty keys for all propertyes.797 /// @param keys Properties keys. Empty keys for all propertyes.
852 /// @return Vector of properties key/value pairs.798 /// @return Vector of properties key/value pairs.
853 fn properties(&self, token_id: uint256, keys: Vec<string>) -> Result<Vec<PropertyStruct>> {799 fn properties(&self, token_id: uint256, keys: Vec<string>) -> Result<Vec<eth::Property>> {
854 let keys = keys800 let keys = keys
855 .into_iter()801 .into_iter()
856 .map(|key| {802 .map(|key| {
866 if keys.is_empty() { None } else { Some(keys) },812 if keys.is_empty() { None } else { Some(keys) },
867 )813 )
868 .into_iter()814 .into_iter()
869 .map(|p| {815 .map(eth::Property::try_from)
870 let key = string::from_utf8(p.key.to_vec())
871 .map_err(|e| Error::Revert(alloc::format!("{}", e)))?;
872 let value = bytes(p.value.to_vec());
873 Ok(PropertyStruct { key, value })
874 })
875 .collect::<Result<Vec<_>>>()816 .collect::<Result<Vec<_>>>()
876 }817 }
877 /// @notice Transfer ownership of an RFT818 /// @notice Transfer ownership of an RFT
907 fn transfer_cross(848 fn transfer_cross(
908 &mut self,849 &mut self,
909 caller: caller,850 caller: caller,
910 to: EthCrossAccount,851 to: eth::CrossAddress,
911 token_id: uint256,852 token_id: uint256,
912 ) -> Result<void> {853 ) -> Result<void> {
913 let caller = T::CrossAccountId::from_eth(caller);854 let caller = T::CrossAccountId::from_eth(caller);
935 fn transfer_from_cross(876 fn transfer_from_cross(
936 &mut self,877 &mut self,
937 caller: caller,878 caller: caller,
938 from: EthCrossAccount,879 from: eth::CrossAddress,
939 to: EthCrossAccount,880 to: eth::CrossAddress,
940 token_id: uint256,881 token_id: uint256,
941 ) -> Result<void> {882 ) -> Result<void> {
942 let caller = T::CrossAccountId::from_eth(caller);883 let caller = T::CrossAccountId::from_eth(caller);
991 fn burn_from_cross(932 fn burn_from_cross(
992 &mut self,933 &mut self,
993 caller: caller,934 caller: caller,
994 from: EthCrossAccount,935 from: eth::CrossAddress,
995 token_id: uint256,936 token_id: uint256,
996 ) -> Result<void> {937 ) -> Result<void> {
997 let caller = T::CrossAccountId::from_eth(caller);938 let caller = T::CrossAccountId::from_eth(caller);
1128 fn mint_cross(1069 fn mint_cross(
1129 &mut self,1070 &mut self,
1130 caller: caller,1071 caller: caller,
1131 to: EthCrossAccount,1072 to: eth::CrossAddress,
1132 properties: Vec<PropertyStruct>,1073 properties: Vec<eth::Property>,
1133 ) -> Result<uint256> {1074 ) -> Result<uint256> {
1134 let token_id = <TokensMinted<T>>::get(self.id)1075 let token_id = <TokensMinted<T>>::get(self.id)
1135 .checked_add(1)1076 .checked_add(1)
11391080
1140 let properties = properties1081 let properties = properties
1141 .into_iter()1082 .into_iter()
1142 .map(|PropertyStruct { key, value }| {1083 .map(eth::Property::try_into)
1143 let key = <Vec<u8>>::from(key)
1144 .try_into()
1145 .map_err(|_| "key too large")?;
1146
1147 let value = value.0.try_into().map_err(|_| "value too large")?;
1148
1149 Ok(Property { key, value })
1150 })
1151 .collect::<Result<Vec<_>>>()?1084 .collect::<Result<Vec<_>>>()?
1152 .try_into()1085 .try_into()
1153 .map_err(|_| Error::Revert(alloc::format!("too many properties")))?;1086 .map_err(|_| Error::Revert(alloc::format!("too many properties")))?;
modifiedpallets/refungible/src/erc_token.rsdiffbeforeafterboth
30use pallet_common::{30use pallet_common::{
31 CommonWeightInfo,31 CommonWeightInfo,
32 erc::{CommonEvmHandler, PrecompileResult},32 erc::{CommonEvmHandler, PrecompileResult},
33 eth::{collection_id_to_address, EthCrossAccount},33 eth::collection_id_to_address,
34};34};
35use pallet_evm::{account::CrossAccountId, PrecompileHandle};35use pallet_evm::{account::CrossAccountId, PrecompileHandle};
36use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};36use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};
224 fn burn_from_cross(224 fn burn_from_cross(
225 &mut self,225 &mut self,
226 caller: caller,226 caller: caller,
227 from: EthCrossAccount,227 from: pallet_common::eth::CrossAddress,
228 amount: uint256,228 amount: uint256,
229 ) -> Result<bool> {229 ) -> Result<bool> {
230 let caller = T::CrossAccountId::from_eth(caller);230 let caller = T::CrossAccountId::from_eth(caller);
250 fn approve_cross(250 fn approve_cross(
251 &mut self,251 &mut self,
252 caller: caller,252 caller: caller,
253 spender: EthCrossAccount,253 spender: pallet_common::eth::CrossAddress,
254 amount: uint256,254 amount: uint256,
255 ) -> Result<bool> {255 ) -> Result<bool> {
256 let caller = T::CrossAccountId::from_eth(caller);256 let caller = T::CrossAccountId::from_eth(caller);
280 fn transfer_cross(280 fn transfer_cross(
281 &mut self,281 &mut self,
282 caller: caller,282 caller: caller,
283 to: EthCrossAccount,283 to: pallet_common::eth::CrossAddress,
284 amount: uint256,284 amount: uint256,
285 ) -> Result<bool> {285 ) -> Result<bool> {
286 let caller = T::CrossAccountId::from_eth(caller);286 let caller = T::CrossAccountId::from_eth(caller);
303 fn transfer_from_cross(303 fn transfer_from_cross(
304 &mut self,304 &mut self,
305 caller: caller,305 caller: caller,
306 from: EthCrossAccount,306 from: pallet_common::eth::CrossAddress,
307 to: EthCrossAccount,307 to: pallet_common::eth::CrossAddress,
308 amount: uint256,308 amount: uint256,
309 ) -> Result<bool> {309 ) -> Result<bool> {
310 let caller = T::CrossAccountId::from_eth(caller);310 let caller = T::CrossAccountId::from_eth(caller);
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
9292
93use codec::{Encode, Decode, MaxEncodedLen};93use codec::{Encode, Decode, MaxEncodedLen};
94use core::ops::Deref;94use core::ops::Deref;
95use derivative::Derivative;
96use evm_coder::ToLog;95use evm_coder::ToLog;
97use frame_support::{96use frame_support::{BoundedVec, ensure, fail, storage::with_transaction, transactional};
98 BoundedBTreeMap, BoundedVec, ensure, fail, storage::with_transaction, transactional,
99 pallet_prelude::ConstU32,
100};
101use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};97use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};
102use pallet_evm_coder_substrate::WithRecorder;98use pallet_evm_coder_substrate::WithRecorder;
110use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};106use sp_runtime::{ArithmeticError, DispatchError, DispatchResult, TransactionOutcome};
111use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};107use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};
112use up_data_structs::{108use up_data_structs::{
113 AccessMode, budget::Budget, CollectionId, CollectionFlags, CollectionPropertiesVec,109 AccessMode, budget::Budget, CollectionId, CollectionFlags, CreateCollectionData,
114 CreateCollectionData, CustomDataLimit, mapping::TokenAddressMapping, MAX_ITEMS_PER_BATCH,110 CustomDataLimit, mapping::TokenAddressMapping, MAX_REFUNGIBLE_PIECES, Property, PropertyKey,
115 MAX_REFUNGIBLE_PIECES, Property, PropertyKey, PropertyKeyPermission, PropertyPermission,111 PropertyKeyPermission, PropertyPermission, PropertyScope, PropertyValue, TokenId,
116 PropertyScope, PropertyValue, TokenId, TrySetProperty, PropertiesPermissionMap,112 TrySetProperty, PropertiesPermissionMap, CreateRefungibleExMultipleOwners,
117 CreateRefungibleExMultipleOwners,
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
42 /// @param permissions Permissions for keys.42 /// @param permissions Permissions for keys.
43 /// @dev EVM selector for this function is: 0xbd92983a,43 /// @dev EVM selector for this function is: 0xbd92983a,
44 /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])44 /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
45 function setTokenPropertyPermissions(Tuple60[] memory permissions) public {45 function setTokenPropertyPermissions(TokenPropertyPermission[] memory permissions) public {
46 require(false, stub_error);46 require(false, stub_error);
47 permissions;47 permissions;
48 dummy = 0;48 dummy = 0;
51 /// @notice Get permissions for token properties.51 /// @notice Get permissions for token properties.
52 /// @dev EVM selector for this function is: 0xf23d7790,52 /// @dev EVM selector for this function is: 0xf23d7790,
53 /// or in textual repr: tokenPropertyPermissions()53 /// or in textual repr: tokenPropertyPermissions()
54 function tokenPropertyPermissions() public view returns (Tuple60[] memory) {54 function tokenPropertyPermissions() public view returns (TokenPropertyPermission[] memory) {
55 require(false, stub_error);55 require(false, stub_error);
56 dummy;56 dummy;
57 return new Tuple60[](0);57 return new TokenPropertyPermission[](0);
58 }58 }
5959
60 // /// @notice Set token property value.60 // /// @notice Set token property value.
127 }127 }
128}128}
129129
130/// @dev Property struct130/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
131struct Property {131struct Property {
132 string key;132 string key;
133 bytes value;133 bytes value;
134}134}
135135
136/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.136/// Ethereum representation of Token Property Permissions.
137enum EthTokenPermissions {
138 /// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
139 Mutable,
140 /// @dev Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
141 TokenOwner,
142 /// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
143 CollectionAdmin
144}
145
146/// @dev anonymous struct
147struct Tuple60 {137struct TokenPropertyPermission {
138 /// Token property key.
148 string field_0;139 string key;
140 /// Token property permissions.
149 Tuple58[] field_1;141 PropertyPermission[] permissions;
150}142}
151143
152/// @dev anonymous struct144/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
153struct Tuple58 {145struct PropertyPermission {
146 /// TokenPermission field.
154 EthTokenPermissions field_0;147 TokenPermissionField code;
148 /// TokenPermission value.
155 bool field_1;149 bool value;
156}150}
151
152/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
153enum TokenPermissionField {
154 /// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
155 Mutable,
156 /// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
157 TokenOwner,
158 /// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
159 CollectionAdmin
160}
157161
158/// @title A contract that allows you to work with collections.162/// @title A contract that allows you to work with collections.
159/// @dev the ERC-165 identifier for this interface is 0x81172a75163/// @dev the ERC-165 identifier for this interface is 0x2a14cfd1
160contract Collection is Dummy, ERC165 {164contract Collection is Dummy, ERC165 {
161 // /// Set collection property.165 // /// Set collection property.
162 // ///166 // ///
252 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.256 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
253 /// @dev EVM selector for this function is: 0x84a1d5a8,257 /// @dev EVM selector for this function is: 0x84a1d5a8,
254 /// or in textual repr: setCollectionSponsorCross((address,uint256))258 /// or in textual repr: setCollectionSponsorCross((address,uint256))
255 function setCollectionSponsorCross(EthCrossAccount memory sponsor) public {259 function setCollectionSponsorCross(CrossAddress memory sponsor) public {
256 require(false, stub_error);260 require(false, stub_error);
257 sponsor;261 sponsor;
258 dummy = 0;262 dummy = 0;
290 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.294 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
291 /// @dev EVM selector for this function is: 0x6ec0a9f1,295 /// @dev EVM selector for this function is: 0x6ec0a9f1,
292 /// or in textual repr: collectionSponsor()296 /// or in textual repr: collectionSponsor()
293 function collectionSponsor() public view returns (EthCrossAccount memory) {297 function collectionSponsor() public view returns (CrossAddress memory) {
294 require(false, stub_error);298 require(false, stub_error);
295 dummy;299 dummy;
296 return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);300 return CrossAddress(0x0000000000000000000000000000000000000000, 0);
297 }301 }
298302
299 /// Get current collection limits.303 /// Get current collection limits.
300 ///304 ///
301 /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:305 /// @return Array of collection limits
302 /// "accountTokenOwnershipLimit",
303 /// "sponsoredDataSize",
304 /// "sponsoredDataRateLimit",
305 /// "tokenLimit",
306 /// "sponsorTransferTimeout",
307 /// "sponsorApproveTimeout"
308 /// "ownerCanTransfer",
309 /// "ownerCanDestroy",
310 /// "transfersEnabled"
311 /// Return `false` if a limit not set.
312 /// @dev EVM selector for this function is: 0xf63bc572,306 /// @dev EVM selector for this function is: 0xf63bc572,
313 /// or in textual repr: collectionLimits()307 /// or in textual repr: collectionLimits()
314 function collectionLimits() public view returns (Tuple34[] memory) {308 function collectionLimits() public view returns (CollectionLimit[] memory) {
315 require(false, stub_error);309 require(false, stub_error);
316 dummy;310 dummy;
317 return new Tuple34[](0);311 return new CollectionLimit[](0);
318 }312 }
319313
320 /// Set limits for the collection.314 /// Set limits for the collection.
321 /// @dev Throws error if limit not found.315 /// @dev Throws error if limit not found.
322 /// @param limit Name of the limit. Valid names:
323 /// "accountTokenOwnershipLimit",
324 /// "sponsoredDataSize",
325 /// "sponsoredDataRateLimit",
326 /// "tokenLimit",
327 /// "sponsorTransferTimeout",
328 /// "sponsorApproveTimeout"
329 /// "ownerCanTransfer",
330 /// "ownerCanDestroy",
331 /// "transfersEnabled"
332 /// @param status enable\disable limit. Works only with `true`.
333 /// @param value Value of the limit.316 /// @param limit Some limit.
334 /// @dev EVM selector for this function is: 0x88150bd0,317 /// @dev EVM selector for this function is: 0x2316ee74,
335 /// or in textual repr: setCollectionLimit(uint8,bool,uint256)318 /// or in textual repr: setCollectionLimit((uint8,(bool,uint256)))
336 function setCollectionLimit(319 function setCollectionLimit(CollectionLimit memory limit) public {
337 CollectionLimits limit,
338 bool status,
339 uint256 value
340 ) public {
341 require(false, stub_error);320 require(false, stub_error);
342 limit;321 limit;
343 status;
344 value;
345 dummy = 0;322 dummy = 0;
346 }323 }
347324
358 /// @param newAdmin Cross account administrator address.335 /// @param newAdmin Cross account administrator address.
359 /// @dev EVM selector for this function is: 0x859aa7d6,336 /// @dev EVM selector for this function is: 0x859aa7d6,
360 /// or in textual repr: addCollectionAdminCross((address,uint256))337 /// or in textual repr: addCollectionAdminCross((address,uint256))
361 function addCollectionAdminCross(EthCrossAccount memory newAdmin) public {338 function addCollectionAdminCross(CrossAddress memory newAdmin) public {
362 require(false, stub_error);339 require(false, stub_error);
363 newAdmin;340 newAdmin;
364 dummy = 0;341 dummy = 0;
368 /// @param admin Cross account administrator address.345 /// @param admin Cross account administrator address.
369 /// @dev EVM selector for this function is: 0x6c0cd173,346 /// @dev EVM selector for this function is: 0x6c0cd173,
370 /// or in textual repr: removeCollectionAdminCross((address,uint256))347 /// or in textual repr: removeCollectionAdminCross((address,uint256))
371 function removeCollectionAdminCross(EthCrossAccount memory admin) public {348 function removeCollectionAdminCross(CrossAddress memory admin) public {
372 require(false, stub_error);349 require(false, stub_error);
373 admin;350 admin;
374 dummy = 0;351 dummy = 0;
422 /// Returns nesting for a collection399 /// Returns nesting for a collection
423 /// @dev EVM selector for this function is: 0x22d25bfe,400 /// @dev EVM selector for this function is: 0x22d25bfe,
424 /// or in textual repr: collectionNestingRestrictedCollectionIds()401 /// or in textual repr: collectionNestingRestrictedCollectionIds()
425 function collectionNestingRestrictedCollectionIds() public view returns (Tuple40 memory) {402 function collectionNestingRestrictedCollectionIds() public view returns (CollectionNesting memory) {
426 require(false, stub_error);403 require(false, stub_error);
427 dummy;404 dummy;
428 return Tuple40(false, new uint256[](0));405 return CollectionNesting(false, new uint256[](0));
429 }406 }
430407
431 /// Returns permissions for a collection408 /// Returns permissions for a collection
432 /// @dev EVM selector for this function is: 0x5b2eaf4b,409 /// @dev EVM selector for this function is: 0x5b2eaf4b,
433 /// or in textual repr: collectionNestingPermissions()410 /// or in textual repr: collectionNestingPermissions()
434 function collectionNestingPermissions() public view returns (Tuple43[] memory) {411 function collectionNestingPermissions() public view returns (CollectionNestingPermission[] memory) {
435 require(false, stub_error);412 require(false, stub_error);
436 dummy;413 dummy;
437 return new Tuple43[](0);414 return new CollectionNestingPermission[](0);
438 }415 }
439416
440 /// Set the collection access method.417 /// Set the collection access method.
454 /// @param user User address to check.431 /// @param user User address to check.
455 /// @dev EVM selector for this function is: 0x91b6df49,432 /// @dev EVM selector for this function is: 0x91b6df49,
456 /// or in textual repr: allowlistedCross((address,uint256))433 /// or in textual repr: allowlistedCross((address,uint256))
457 function allowlistedCross(EthCrossAccount memory user) public view returns (bool) {434 function allowlistedCross(CrossAddress memory user) public view returns (bool) {
458 require(false, stub_error);435 require(false, stub_error);
459 user;436 user;
460 dummy;437 dummy;
477 /// @param user User cross account address.454 /// @param user User cross account address.
478 /// @dev EVM selector for this function is: 0xa0184a3a,455 /// @dev EVM selector for this function is: 0xa0184a3a,
479 /// or in textual repr: addToCollectionAllowListCross((address,uint256))456 /// or in textual repr: addToCollectionAllowListCross((address,uint256))
480 function addToCollectionAllowListCross(EthCrossAccount memory user) public {457 function addToCollectionAllowListCross(CrossAddress memory user) public {
481 require(false, stub_error);458 require(false, stub_error);
482 user;459 user;
483 dummy = 0;460 dummy = 0;
499 /// @param user User cross account address.476 /// @param user User cross account address.
500 /// @dev EVM selector for this function is: 0x09ba452a,477 /// @dev EVM selector for this function is: 0x09ba452a,
501 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))478 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))
502 function removeFromCollectionAllowListCross(EthCrossAccount memory user) public {479 function removeFromCollectionAllowListCross(CrossAddress memory user) public {
503 require(false, stub_error);480 require(false, stub_error);
504 user;481 user;
505 dummy = 0;482 dummy = 0;
535 /// @return "true" if account is the owner or admin512 /// @return "true" if account is the owner or admin
536 /// @dev EVM selector for this function is: 0x3e75a905,513 /// @dev EVM selector for this function is: 0x3e75a905,
537 /// or in textual repr: isOwnerOrAdminCross((address,uint256))514 /// or in textual repr: isOwnerOrAdminCross((address,uint256))
538 function isOwnerOrAdminCross(EthCrossAccount memory user) public view returns (bool) {515 function isOwnerOrAdminCross(CrossAddress memory user) public view returns (bool) {
539 require(false, stub_error);516 require(false, stub_error);
540 user;517 user;
541 dummy;518 dummy;
559 /// If address is canonical then substrate mirror is zero and vice versa.536 /// If address is canonical then substrate mirror is zero and vice versa.
560 /// @dev EVM selector for this function is: 0xdf727d3b,537 /// @dev EVM selector for this function is: 0xdf727d3b,
561 /// or in textual repr: collectionOwner()538 /// or in textual repr: collectionOwner()
562 function collectionOwner() public view returns (EthCrossAccount memory) {539 function collectionOwner() public view returns (CrossAddress memory) {
563 require(false, stub_error);540 require(false, stub_error);
564 dummy;541 dummy;
565 return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);542 return CrossAddress(0x0000000000000000000000000000000000000000, 0);
566 }543 }
567544
568 // /// Changes collection owner to another account545 // /// Changes collection owner to another account
583 /// If address is canonical then substrate mirror is zero and vice versa.560 /// If address is canonical then substrate mirror is zero and vice versa.
584 /// @dev EVM selector for this function is: 0x5813216b,561 /// @dev EVM selector for this function is: 0x5813216b,
585 /// or in textual repr: collectionAdmins()562 /// or in textual repr: collectionAdmins()
586 function collectionAdmins() public view returns (EthCrossAccount[] memory) {563 function collectionAdmins() public view returns (CrossAddress[] memory) {
587 require(false, stub_error);564 require(false, stub_error);
588 dummy;565 dummy;
589 return new EthCrossAccount[](0);566 return new CrossAddress[](0);
590 }567 }
591568
592 /// Changes collection owner to another account569 /// Changes collection owner to another account
595 /// @param newOwner new owner cross account572 /// @param newOwner new owner cross account
596 /// @dev EVM selector for this function is: 0x6496c497,573 /// @dev EVM selector for this function is: 0x6496c497,
597 /// or in textual repr: changeCollectionOwnerCross((address,uint256))574 /// or in textual repr: changeCollectionOwnerCross((address,uint256))
598 function changeCollectionOwnerCross(EthCrossAccount memory newOwner) public {575 function changeCollectionOwnerCross(CrossAddress memory newOwner) public {
599 require(false, stub_error);576 require(false, stub_error);
600 newOwner;577 newOwner;
601 dummy = 0;578 dummy = 0;
602 }579 }
603}580}
604581
605/// @dev Cross account struct582/// Cross account struct
606struct EthCrossAccount {583struct CrossAddress {
607 address eth;584 address eth;
608 uint256 sub;585 uint256 sub;
609}586}
610587
588/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
589struct CollectionNestingPermission {
590 CollectionPermissionField field;
591 bool value;
592}
593
594/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
611enum CollectionPermissions {595enum CollectionPermissionField {
612 CollectionAdmin,596 /// Owner of token can nest tokens under it.
613 TokenOwner597 TokenOwner,
598 /// Admin of token collection can nest tokens under token.
599 CollectionAdmin
614}600}
615601
616/// @dev anonymous struct602/// Nested collections.
617struct Tuple43 {603struct CollectionNesting {
618 CollectionPermissions field_0;604 bool token_owner;
619 bool field_1;605 uint256[] ids;
620}606}
621607
622/// @dev anonymous struct608/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
609struct CollectionLimit {
610 CollectionLimitField field;
611 OptionUint value;
612}
613
614/// Ethereum representation of Optional value with uint256.
623struct Tuple40 {615struct OptionUint {
624 bool field_0;616 bool status;
625 uint256[] field_1;617 uint256 value;
626}618}
627619
628/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.620/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
629enum CollectionLimits {621enum CollectionLimitField {
630 /// @dev How many tokens can a user have on one account.622 /// How many tokens can a user have on one account.
631 AccountTokenOwnership,623 AccountTokenOwnership,
632 /// @dev How many bytes of data are available for sponsorship.624 /// How many bytes of data are available for sponsorship.
633 SponsoredDataSize,625 SponsoredDataSize,
634 /// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]626 /// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
635 SponsoredDataRateLimit,627 SponsoredDataRateLimit,
636 /// @dev How many tokens can be mined into this collection.628 /// How many tokens can be mined into this collection.
637 TokenLimit,629 TokenLimit,
638 /// @dev Timeouts for transfer sponsoring.630 /// Timeouts for transfer sponsoring.
639 SponsorTransferTimeout,631 SponsorTransferTimeout,
640 /// @dev Timeout for sponsoring an approval in passed blocks.632 /// Timeout for sponsoring an approval in passed blocks.
641 SponsorApproveTimeout,633 SponsorApproveTimeout,
642 /// @dev Whether the collection owner of the collection can send tokens (which belong to other users).634 /// Whether the collection owner of the collection can send tokens (which belong to other users).
643 OwnerCanTransfer,635 OwnerCanTransfer,
644 /// @dev Can the collection owner burn other people's tokens.636 /// Can the collection owner burn other people's tokens.
645 OwnerCanDestroy,637 OwnerCanDestroy,
646 /// @dev Is it possible to send tokens from this collection between users.638 /// Is it possible to send tokens from this collection between users.
647 TransferEnabled639 TransferEnabled
648}640}
649
650/// @dev anonymous struct
651struct Tuple34 {
652 CollectionLimits field_0;
653 bool field_1;
654 uint256 field_2;
655}
656641
657/// @dev the ERC-165 identifier for this interface is 0x5b5e139f642/// @dev the ERC-165 identifier for this interface is 0x5b5e139f
658contract ERC721Metadata is Dummy, ERC165 {643contract ERC721Metadata is Dummy, ERC165 {
830 /// @param tokenId Id for the token.815 /// @param tokenId Id for the token.
831 /// @dev EVM selector for this function is: 0x2b29dace,816 /// @dev EVM selector for this function is: 0x2b29dace,
832 /// or in textual repr: crossOwnerOf(uint256)817 /// or in textual repr: crossOwnerOf(uint256)
833 function crossOwnerOf(uint256 tokenId) public view returns (EthCrossAccount memory) {818 function crossOwnerOf(uint256 tokenId) public view returns (CrossAddress memory) {
834 require(false, stub_error);819 require(false, stub_error);
835 tokenId;820 tokenId;
836 dummy;821 dummy;
837 return EthCrossAccount(0x0000000000000000000000000000000000000000, 0);822 return CrossAddress(0x0000000000000000000000000000000000000000, 0);
838 }823 }
839824
840 /// Returns the token properties.825 /// Returns the token properties.
875 /// @param tokenId The RFT to transfer860 /// @param tokenId The RFT to transfer
876 /// @dev EVM selector for this function is: 0x2ada85ff,861 /// @dev EVM selector for this function is: 0x2ada85ff,
877 /// or in textual repr: transferCross((address,uint256),uint256)862 /// or in textual repr: transferCross((address,uint256),uint256)
878 function transferCross(EthCrossAccount memory to, uint256 tokenId) public {863 function transferCross(CrossAddress memory to, uint256 tokenId) public {
879 require(false, stub_error);864 require(false, stub_error);
880 to;865 to;
881 tokenId;866 tokenId;
891 /// @dev EVM selector for this function is: 0xd5cf430b,876 /// @dev EVM selector for this function is: 0xd5cf430b,
892 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)877 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
893 function transferFromCross(878 function transferFromCross(
894 EthCrossAccount memory from,879 CrossAddress memory from,
895 EthCrossAccount memory to,880 CrossAddress memory to,
896 uint256 tokenId881 uint256 tokenId
897 ) public {882 ) public {
898 require(false, stub_error);883 require(false, stub_error);
927 /// @param tokenId The RFT to transfer912 /// @param tokenId The RFT to transfer
928 /// @dev EVM selector for this function is: 0xbb2f5a58,913 /// @dev EVM selector for this function is: 0xbb2f5a58,
929 /// or in textual repr: burnFromCross((address,uint256),uint256)914 /// or in textual repr: burnFromCross((address,uint256),uint256)
930 function burnFromCross(EthCrossAccount memory from, uint256 tokenId) public {915 function burnFromCross(CrossAddress memory from, uint256 tokenId) public {
931 require(false, stub_error);916 require(false, stub_error);
932 from;917 from;
933 tokenId;918 tokenId;
979 /// @return uint256 The id of the newly minted token964 /// @return uint256 The id of the newly minted token
980 /// @dev EVM selector for this function is: 0xb904db03,965 /// @dev EVM selector for this function is: 0xb904db03,
981 /// or in textual repr: mintCross((address,uint256),(string,bytes)[])966 /// or in textual repr: mintCross((address,uint256),(string,bytes)[])
982 function mintCross(EthCrossAccount memory to, Property[] memory properties) public returns (uint256) {967 function mintCross(CrossAddress memory to, Property[] memory properties) public returns (uint256) {
983 require(false, stub_error);968 require(false, stub_error);
984 to;969 to;
985 properties;970 properties;
modifiedpallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungibleToken.soldiffbeforeafterboth
58 /// @param amount The amount that will be burnt.58 /// @param amount The amount that will be burnt.
59 /// @dev EVM selector for this function is: 0xbb2f5a58,59 /// @dev EVM selector for this function is: 0xbb2f5a58,
60 /// or in textual repr: burnFromCross((address,uint256),uint256)60 /// or in textual repr: burnFromCross((address,uint256),uint256)
61 function burnFromCross(EthCrossAccount memory from, uint256 amount) public returns (bool) {61 function burnFromCross(CrossAddress memory from, uint256 amount) public returns (bool) {
62 require(false, stub_error);62 require(false, stub_error);
63 from;63 from;
64 amount;64 amount;
75 /// @param amount The amount of tokens to be spent.75 /// @param amount The amount of tokens to be spent.
76 /// @dev EVM selector for this function is: 0x0ecd0ab0,76 /// @dev EVM selector for this function is: 0x0ecd0ab0,
77 /// or in textual repr: approveCross((address,uint256),uint256)77 /// or in textual repr: approveCross((address,uint256),uint256)
78 function approveCross(EthCrossAccount memory spender, uint256 amount) public returns (bool) {78 function approveCross(CrossAddress memory spender, uint256 amount) public returns (bool) {
79 require(false, stub_error);79 require(false, stub_error);
80 spender;80 spender;
81 amount;81 amount;
100 /// @param amount The amount to be transferred.100 /// @param amount The amount to be transferred.
101 /// @dev EVM selector for this function is: 0x2ada85ff,101 /// @dev EVM selector for this function is: 0x2ada85ff,
102 /// or in textual repr: transferCross((address,uint256),uint256)102 /// or in textual repr: transferCross((address,uint256),uint256)
103 function transferCross(EthCrossAccount memory to, uint256 amount) public returns (bool) {103 function transferCross(CrossAddress memory to, uint256 amount) public returns (bool) {
104 require(false, stub_error);104 require(false, stub_error);
105 to;105 to;
106 amount;106 amount;
115 /// @dev EVM selector for this function is: 0xd5cf430b,115 /// @dev EVM selector for this function is: 0xd5cf430b,
116 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)116 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
117 function transferFromCross(117 function transferFromCross(
118 EthCrossAccount memory from,118 CrossAddress memory from,
119 EthCrossAccount memory to,119 CrossAddress memory to,
120 uint256 amount120 uint256 amount
121 ) public returns (bool) {121 ) public returns (bool) {
122 require(false, stub_error);122 require(false, stub_error);
128 }128 }
129}129}
130130
131/// @dev Cross account struct131/// Cross account struct
132struct EthCrossAccount {132struct CrossAddress {
133 address eth;133 address eth;
134 uint256 sub;134 uint256 sub;
135}135}
modifiedpallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
74extern crate alloc;74extern crate alloc;
7575
76use frame_support::{76use frame_support::{
77 decl_module, decl_storage, decl_error, decl_event,77 decl_module, decl_storage, decl_error,
78 dispatch::DispatchResult,78 dispatch::DispatchResult,
79 ensure, fail,79 ensure, fail,
80 weights::{Weight},80 weights::{Weight},
modifiedtests/src/eth/abi/contractHelpers.jsondiffbeforeafterboth
190 "name": "contractAddress",190 "name": "contractAddress",
191 "type": "address"191 "type": "address"
192 },192 },
193 { "internalType": "uint8", "name": "mode", "type": "uint8" }193 {
194 "internalType": "enum SponsoringModeT",
195 "name": "mode",
196 "type": "uint8"
197 }
222 "name": "sponsor",226 "name": "sponsor",
223 "outputs": [227 "outputs": [
224 {228 {
229 "components": [
230 { "internalType": "bool", "name": "status", "type": "bool" },
231 {
225 "components": [232 "components": [
226 { "internalType": "address", "name": "eth", "type": "address" },233 { "internalType": "address", "name": "eth", "type": "address" },
227 { "internalType": "uint256", "name": "sub", "type": "uint256" }234 { "internalType": "uint256", "name": "sub", "type": "uint256" }
228 ],235 ],
236 "internalType": "struct CrossAddress",
237 "name": "value",
238 "type": "tuple"
239 }
240 ],
229 "internalType": "struct EthCrossAccount",241 "internalType": "struct OptionCrossAddress",
230 "name": "",242 "name": "",
231 "type": "tuple"243 "type": "tuple"
232 }244 }
modifiedtests/src/eth/abi/fungible.jsondiffbeforeafterboth
56 { "internalType": "address", "name": "eth", "type": "address" },56 { "internalType": "address", "name": "eth", "type": "address" },
57 { "internalType": "uint256", "name": "sub", "type": "uint256" }57 { "internalType": "uint256", "name": "sub", "type": "uint256" }
58 ],58 ],
59 "internalType": "struct EthCrossAccount",59 "internalType": "struct CrossAddress",
60 "name": "newAdmin",60 "name": "newAdmin",
61 "type": "tuple"61 "type": "tuple"
62 }62 }
73 { "internalType": "address", "name": "eth", "type": "address" },73 { "internalType": "address", "name": "eth", "type": "address" },
74 { "internalType": "uint256", "name": "sub", "type": "uint256" }74 { "internalType": "uint256", "name": "sub", "type": "uint256" }
75 ],75 ],
76 "internalType": "struct EthCrossAccount",76 "internalType": "struct CrossAddress",
77 "name": "user",77 "name": "user",
78 "type": "tuple"78 "type": "tuple"
79 }79 }
100 { "internalType": "address", "name": "eth", "type": "address" },100 { "internalType": "address", "name": "eth", "type": "address" },
101 { "internalType": "uint256", "name": "sub", "type": "uint256" }101 { "internalType": "uint256", "name": "sub", "type": "uint256" }
102 ],102 ],
103 "internalType": "struct EthCrossAccount",103 "internalType": "struct CrossAddress",
104 "name": "user",104 "name": "user",
105 "type": "tuple"105 "type": "tuple"
106 }106 }
127 { "internalType": "address", "name": "eth", "type": "address" },127 { "internalType": "address", "name": "eth", "type": "address" },
128 { "internalType": "uint256", "name": "sub", "type": "uint256" }128 { "internalType": "uint256", "name": "sub", "type": "uint256" }
129 ],129 ],
130 "internalType": "struct EthCrossAccount",130 "internalType": "struct CrossAddress",
131 "name": "spender",131 "name": "spender",
132 "type": "tuple"132 "type": "tuple"
133 },133 },
154 { "internalType": "address", "name": "eth", "type": "address" },154 { "internalType": "address", "name": "eth", "type": "address" },
155 { "internalType": "uint256", "name": "sub", "type": "uint256" }155 { "internalType": "uint256", "name": "sub", "type": "uint256" }
156 ],156 ],
157 "internalType": "struct EthCrossAccount",157 "internalType": "struct CrossAddress",
158 "name": "from",158 "name": "from",
159 "type": "tuple"159 "type": "tuple"
160 },160 },
172 { "internalType": "address", "name": "eth", "type": "address" },172 { "internalType": "address", "name": "eth", "type": "address" },
173 { "internalType": "uint256", "name": "sub", "type": "uint256" }173 { "internalType": "uint256", "name": "sub", "type": "uint256" }
174 ],174 ],
175 "internalType": "struct EthCrossAccount",175 "internalType": "struct CrossAddress",
176 "name": "newOwner",176 "name": "newOwner",
177 "type": "tuple"177 "type": "tuple"
178 }178 }
191 { "internalType": "address", "name": "eth", "type": "address" },191 { "internalType": "address", "name": "eth", "type": "address" },
192 { "internalType": "uint256", "name": "sub", "type": "uint256" }192 { "internalType": "uint256", "name": "sub", "type": "uint256" }
193 ],193 ],
194 "internalType": "struct EthCrossAccount[]",194 "internalType": "struct CrossAddress[]",
195 "name": "",195 "name": "",
196 "type": "tuple[]"196 "type": "tuple[]"
197 }197 }
213 {213 {
214 "components": [214 "components": [
215 {215 {
216 "internalType": "enum CollectionLimits",216 "internalType": "enum CollectionLimitField",
217 "name": "field_0",217 "name": "field",
218 "type": "uint8"218 "type": "uint8"
219 },219 },
220 {
221 "components": [
220 { "internalType": "bool", "name": "field_1", "type": "bool" },222 { "internalType": "bool", "name": "status", "type": "bool" },
221 { "internalType": "uint256", "name": "field_2", "type": "uint256" }223 { "internalType": "uint256", "name": "value", "type": "uint256" }
224 ],
225 "internalType": "struct OptionUint",
226 "name": "value",
227 "type": "tuple"
228 }
222 ],229 ],
223 "internalType": "struct Tuple23[]",230 "internalType": "struct CollectionLimit[]",
224 "name": "",231 "name": "",
225 "type": "tuple[]"232 "type": "tuple[]"
226 }233 }
235 {242 {
236 "components": [243 "components": [
237 {244 {
238 "internalType": "enum CollectionPermissions",245 "internalType": "enum CollectionPermissionField",
239 "name": "field_0",246 "name": "field",
240 "type": "uint8"247 "type": "uint8"
241 },248 },
242 { "internalType": "bool", "name": "field_1", "type": "bool" }249 { "internalType": "bool", "name": "value", "type": "bool" }
243 ],250 ],
244 "internalType": "struct Tuple32[]",251 "internalType": "struct CollectionNestingPermission[]",
245 "name": "",252 "name": "",
246 "type": "tuple[]"253 "type": "tuple[]"
247 }254 }
255 "outputs": [262 "outputs": [
256 {263 {
257 "components": [264 "components": [
258 { "internalType": "bool", "name": "field_0", "type": "bool" },265 { "internalType": "bool", "name": "token_owner", "type": "bool" },
259 {266 { "internalType": "uint256[]", "name": "ids", "type": "uint256[]" }
260 "internalType": "uint256[]",
261 "name": "field_1",
262 "type": "uint256[]"
263 }
264 ],267 ],
265 "internalType": "struct Tuple29",268 "internalType": "struct CollectionNesting",
266 "name": "",269 "name": "",
267 "type": "tuple"270 "type": "tuple"
268 }271 }
279 { "internalType": "address", "name": "eth", "type": "address" },282 { "internalType": "address", "name": "eth", "type": "address" },
280 { "internalType": "uint256", "name": "sub", "type": "uint256" }283 { "internalType": "uint256", "name": "sub", "type": "uint256" }
281 ],284 ],
282 "internalType": "struct EthCrossAccount",285 "internalType": "struct CrossAddress",
283 "name": "",286 "name": "",
284 "type": "tuple"287 "type": "tuple"
285 }288 }
322 { "internalType": "address", "name": "eth", "type": "address" },325 { "internalType": "address", "name": "eth", "type": "address" },
323 { "internalType": "uint256", "name": "sub", "type": "uint256" }326 { "internalType": "uint256", "name": "sub", "type": "uint256" }
324 ],327 ],
325 "internalType": "struct EthCrossAccount",328 "internalType": "struct CrossAddress",
326 "name": "",329 "name": "",
327 "type": "tuple"330 "type": "tuple"
328 }331 }
381 { "internalType": "address", "name": "eth", "type": "address" },384 { "internalType": "address", "name": "eth", "type": "address" },
382 { "internalType": "uint256", "name": "sub", "type": "uint256" }385 { "internalType": "uint256", "name": "sub", "type": "uint256" }
383 ],386 ],
384 "internalType": "struct EthCrossAccount",387 "internalType": "struct CrossAddress",
385 "name": "user",388 "name": "user",
386 "type": "tuple"389 "type": "tuple"
387 }390 }
425 { "internalType": "address", "name": "eth", "type": "address" },428 { "internalType": "address", "name": "eth", "type": "address" },
426 { "internalType": "uint256", "name": "sub", "type": "uint256" }429 { "internalType": "uint256", "name": "sub", "type": "uint256" }
427 ],430 ],
428 "internalType": "struct EthCrossAccount",431 "internalType": "struct CrossAddress",
429 "name": "to",432 "name": "to",
430 "type": "tuple"433 "type": "tuple"
431 },434 },
450 { "internalType": "address", "name": "eth", "type": "address" },453 { "internalType": "address", "name": "eth", "type": "address" },
451 { "internalType": "uint256", "name": "sub", "type": "uint256" }454 { "internalType": "uint256", "name": "sub", "type": "uint256" }
452 ],455 ],
453 "internalType": "struct EthCrossAccount",456 "internalType": "struct CrossAddress",
454 "name": "admin",457 "name": "admin",
455 "type": "tuple"458 "type": "tuple"
456 }459 }
474 { "internalType": "address", "name": "eth", "type": "address" },477 { "internalType": "address", "name": "eth", "type": "address" },
475 { "internalType": "uint256", "name": "sub", "type": "uint256" }478 { "internalType": "uint256", "name": "sub", "type": "uint256" }
476 ],479 ],
477 "internalType": "struct EthCrossAccount",480 "internalType": "struct CrossAddress",
478 "name": "user",481 "name": "user",
479 "type": "tuple"482 "type": "tuple"
480 }483 }
492 "type": "function"495 "type": "function"
493 },496 },
494 {497 {
495 "inputs": [498 "inputs": [
499 {
500 "components": [
496 {501 {
497 "internalType": "enum CollectionLimits",502 "internalType": "enum CollectionLimitField",
498 "name": "limit",503 "name": "field",
499 "type": "uint8"504 "type": "uint8"
500 },505 },
506 {
507 "components": [
501 { "internalType": "bool", "name": "status", "type": "bool" },508 { "internalType": "bool", "name": "status", "type": "bool" },
502 { "internalType": "uint256", "name": "value", "type": "uint256" }509 { "internalType": "uint256", "name": "value", "type": "uint256" }
510 ],
511 "internalType": "struct OptionUint",
512 "name": "value",
513 "type": "tuple"
514 }
515 ],
516 "internalType": "struct CollectionLimit",
517 "name": "limit",
518 "type": "tuple"
519 }
503 ],520 ],
504 "name": "setCollectionLimit",521 "name": "setCollectionLimit",
505 "outputs": [],522 "outputs": [],
506 "stateMutability": "nonpayable",523 "stateMutability": "nonpayable",
558 { "internalType": "address", "name": "eth", "type": "address" },575 { "internalType": "address", "name": "eth", "type": "address" },
559 { "internalType": "uint256", "name": "sub", "type": "uint256" }576 { "internalType": "uint256", "name": "sub", "type": "uint256" }
560 ],577 ],
561 "internalType": "struct EthCrossAccount",578 "internalType": "struct CrossAddress",
562 "name": "sponsor",579 "name": "sponsor",
563 "type": "tuple"580 "type": "tuple"
564 }581 }
608 { "internalType": "address", "name": "eth", "type": "address" },625 { "internalType": "address", "name": "eth", "type": "address" },
609 { "internalType": "uint256", "name": "sub", "type": "uint256" }626 { "internalType": "uint256", "name": "sub", "type": "uint256" }
610 ],627 ],
611 "internalType": "struct EthCrossAccount",628 "internalType": "struct CrossAddress",
612 "name": "to",629 "name": "to",
613 "type": "tuple"630 "type": "tuple"
614 },631 },
637 { "internalType": "address", "name": "eth", "type": "address" },654 { "internalType": "address", "name": "eth", "type": "address" },
638 { "internalType": "uint256", "name": "sub", "type": "uint256" }655 { "internalType": "uint256", "name": "sub", "type": "uint256" }
639 ],656 ],
640 "internalType": "struct EthCrossAccount",657 "internalType": "struct CrossAddress",
641 "name": "from",658 "name": "from",
642 "type": "tuple"659 "type": "tuple"
643 },660 },
646 { "internalType": "address", "name": "eth", "type": "address" },663 { "internalType": "address", "name": "eth", "type": "address" },
647 { "internalType": "uint256", "name": "sub", "type": "uint256" }664 { "internalType": "uint256", "name": "sub", "type": "uint256" }
648 ],665 ],
649 "internalType": "struct EthCrossAccount",666 "internalType": "struct CrossAddress",
650 "name": "to",667 "name": "to",
651 "type": "tuple"668 "type": "tuple"
652 },669 },
modifiedtests/src/eth/abi/nonFungible.jsondiffbeforeafterboth
87 { "internalType": "address", "name": "eth", "type": "address" },87 { "internalType": "address", "name": "eth", "type": "address" },
88 { "internalType": "uint256", "name": "sub", "type": "uint256" }88 { "internalType": "uint256", "name": "sub", "type": "uint256" }
89 ],89 ],
90 "internalType": "struct EthCrossAccount",90 "internalType": "struct CrossAddress",
91 "name": "newAdmin",91 "name": "newAdmin",
92 "type": "tuple"92 "type": "tuple"
93 }93 }
104 { "internalType": "address", "name": "eth", "type": "address" },104 { "internalType": "address", "name": "eth", "type": "address" },
105 { "internalType": "uint256", "name": "sub", "type": "uint256" }105 { "internalType": "uint256", "name": "sub", "type": "uint256" }
106 ],106 ],
107 "internalType": "struct EthCrossAccount",107 "internalType": "struct CrossAddress",
108 "name": "user",108 "name": "user",
109 "type": "tuple"109 "type": "tuple"
110 }110 }
121 { "internalType": "address", "name": "eth", "type": "address" },121 { "internalType": "address", "name": "eth", "type": "address" },
122 { "internalType": "uint256", "name": "sub", "type": "uint256" }122 { "internalType": "uint256", "name": "sub", "type": "uint256" }
123 ],123 ],
124 "internalType": "struct EthCrossAccount",124 "internalType": "struct CrossAddress",
125 "name": "user",125 "name": "user",
126 "type": "tuple"126 "type": "tuple"
127 }127 }
148 { "internalType": "address", "name": "eth", "type": "address" },148 { "internalType": "address", "name": "eth", "type": "address" },
149 { "internalType": "uint256", "name": "sub", "type": "uint256" }149 { "internalType": "uint256", "name": "sub", "type": "uint256" }
150 ],150 ],
151 "internalType": "struct EthCrossAccount",151 "internalType": "struct CrossAddress",
152 "name": "approved",152 "name": "approved",
153 "type": "tuple"153 "type": "tuple"
154 },154 },
184 { "internalType": "address", "name": "eth", "type": "address" },184 { "internalType": "address", "name": "eth", "type": "address" },
185 { "internalType": "uint256", "name": "sub", "type": "uint256" }185 { "internalType": "uint256", "name": "sub", "type": "uint256" }
186 ],186 ],
187 "internalType": "struct EthCrossAccount",187 "internalType": "struct CrossAddress",
188 "name": "from",188 "name": "from",
189 "type": "tuple"189 "type": "tuple"
190 },190 },
202 { "internalType": "address", "name": "eth", "type": "address" },202 { "internalType": "address", "name": "eth", "type": "address" },
203 { "internalType": "uint256", "name": "sub", "type": "uint256" }203 { "internalType": "uint256", "name": "sub", "type": "uint256" }
204 ],204 ],
205 "internalType": "struct EthCrossAccount",205 "internalType": "struct CrossAddress",
206 "name": "newOwner",206 "name": "newOwner",
207 "type": "tuple"207 "type": "tuple"
208 }208 }
221 { "internalType": "address", "name": "eth", "type": "address" },221 { "internalType": "address", "name": "eth", "type": "address" },
222 { "internalType": "uint256", "name": "sub", "type": "uint256" }222 { "internalType": "uint256", "name": "sub", "type": "uint256" }
223 ],223 ],
224 "internalType": "struct EthCrossAccount[]",224 "internalType": "struct CrossAddress[]",
225 "name": "",225 "name": "",
226 "type": "tuple[]"226 "type": "tuple[]"
227 }227 }
243 {243 {
244 "components": [244 "components": [
245 {245 {
246 "internalType": "enum CollectionLimits",246 "internalType": "enum CollectionLimitField",
247 "name": "field_0",247 "name": "field",
248 "type": "uint8"248 "type": "uint8"
249 },249 },
250 {
251 "components": [
250 { "internalType": "bool", "name": "field_1", "type": "bool" },252 { "internalType": "bool", "name": "status", "type": "bool" },
251 { "internalType": "uint256", "name": "field_2", "type": "uint256" }253 { "internalType": "uint256", "name": "value", "type": "uint256" }
254 ],
255 "internalType": "struct OptionUint",
256 "name": "value",
257 "type": "tuple"
258 }
252 ],259 ],
253 "internalType": "struct Tuple35[]",260 "internalType": "struct CollectionLimit[]",
254 "name": "",261 "name": "",
255 "type": "tuple[]"262 "type": "tuple[]"
256 }263 }
265 {272 {
266 "components": [273 "components": [
267 {274 {
268 "internalType": "enum CollectionPermissions",275 "internalType": "enum CollectionPermissionField",
269 "name": "field_0",276 "name": "field",
270 "type": "uint8"277 "type": "uint8"
271 },278 },
272 { "internalType": "bool", "name": "field_1", "type": "bool" }279 { "internalType": "bool", "name": "value", "type": "bool" }
273 ],280 ],
274 "internalType": "struct Tuple44[]",281 "internalType": "struct CollectionNestingPermission[]",
275 "name": "",282 "name": "",
276 "type": "tuple[]"283 "type": "tuple[]"
277 }284 }
285 "outputs": [292 "outputs": [
286 {293 {
287 "components": [294 "components": [
288 { "internalType": "bool", "name": "field_0", "type": "bool" },295 { "internalType": "bool", "name": "token_owner", "type": "bool" },
289 {296 { "internalType": "uint256[]", "name": "ids", "type": "uint256[]" }
290 "internalType": "uint256[]",
291 "name": "field_1",
292 "type": "uint256[]"
293 }
294 ],297 ],
295 "internalType": "struct Tuple41",298 "internalType": "struct CollectionNesting",
296 "name": "",299 "name": "",
297 "type": "tuple"300 "type": "tuple"
298 }301 }
309 { "internalType": "address", "name": "eth", "type": "address" },312 { "internalType": "address", "name": "eth", "type": "address" },
310 { "internalType": "uint256", "name": "sub", "type": "uint256" }313 { "internalType": "uint256", "name": "sub", "type": "uint256" }
311 ],314 ],
312 "internalType": "struct EthCrossAccount",315 "internalType": "struct CrossAddress",
313 "name": "",316 "name": "",
314 "type": "tuple"317 "type": "tuple"
315 }318 }
352 { "internalType": "address", "name": "eth", "type": "address" },355 { "internalType": "address", "name": "eth", "type": "address" },
353 { "internalType": "uint256", "name": "sub", "type": "uint256" }356 { "internalType": "uint256", "name": "sub", "type": "uint256" }
354 ],357 ],
355 "internalType": "struct EthCrossAccount",358 "internalType": "struct CrossAddress",
356 "name": "",359 "name": "",
357 "type": "tuple"360 "type": "tuple"
358 }361 }
385 { "internalType": "address", "name": "eth", "type": "address" },388 { "internalType": "address", "name": "eth", "type": "address" },
386 { "internalType": "uint256", "name": "sub", "type": "uint256" }389 { "internalType": "uint256", "name": "sub", "type": "uint256" }
387 ],390 ],
388 "internalType": "struct EthCrossAccount",391 "internalType": "struct CrossAddress",
389 "name": "",392 "name": "",
390 "type": "tuple"393 "type": "tuple"
391 }394 }
459 { "internalType": "address", "name": "eth", "type": "address" },462 { "internalType": "address", "name": "eth", "type": "address" },
460 { "internalType": "uint256", "name": "sub", "type": "uint256" }463 { "internalType": "uint256", "name": "sub", "type": "uint256" }
461 ],464 ],
462 "internalType": "struct EthCrossAccount",465 "internalType": "struct CrossAddress",
463 "name": "user",466 "name": "user",
464 "type": "tuple"467 "type": "tuple"
465 }468 }
483 { "internalType": "address", "name": "eth", "type": "address" },486 { "internalType": "address", "name": "eth", "type": "address" },
484 { "internalType": "uint256", "name": "sub", "type": "uint256" }487 { "internalType": "uint256", "name": "sub", "type": "uint256" }
485 ],488 ],
486 "internalType": "struct EthCrossAccount",489 "internalType": "struct CrossAddress",
487 "name": "to",490 "name": "to",
488 "type": "tuple"491 "type": "tuple"
489 },492 },
579 { "internalType": "address", "name": "eth", "type": "address" },582 { "internalType": "address", "name": "eth", "type": "address" },
580 { "internalType": "uint256", "name": "sub", "type": "uint256" }583 { "internalType": "uint256", "name": "sub", "type": "uint256" }
581 ],584 ],
582 "internalType": "struct EthCrossAccount",585 "internalType": "struct CrossAddress",
583 "name": "admin",586 "name": "admin",
584 "type": "tuple"587 "type": "tuple"
585 }588 }
603 { "internalType": "address", "name": "eth", "type": "address" },606 { "internalType": "address", "name": "eth", "type": "address" },
604 { "internalType": "uint256", "name": "sub", "type": "uint256" }607 { "internalType": "uint256", "name": "sub", "type": "uint256" }
605 ],608 ],
606 "internalType": "struct EthCrossAccount",609 "internalType": "struct CrossAddress",
607 "name": "user",610 "name": "user",
608 "type": "tuple"611 "type": "tuple"
609 }612 }
654 "type": "function"657 "type": "function"
655 },658 },
656 {659 {
657 "inputs": [660 "inputs": [
661 {
662 "components": [
658 {663 {
659 "internalType": "enum CollectionLimits",664 "internalType": "enum CollectionLimitField",
660 "name": "limit",665 "name": "field",
661 "type": "uint8"666 "type": "uint8"
662 },667 },
668 {
669 "components": [
663 { "internalType": "bool", "name": "status", "type": "bool" },670 { "internalType": "bool", "name": "status", "type": "bool" },
664 { "internalType": "uint256", "name": "value", "type": "uint256" }671 { "internalType": "uint256", "name": "value", "type": "uint256" }
672 ],
673 "internalType": "struct OptionUint",
674 "name": "value",
675 "type": "tuple"
676 }
677 ],
678 "internalType": "struct CollectionLimit",
679 "name": "limit",
680 "type": "tuple"
681 }
665 ],682 ],
666 "name": "setCollectionLimit",683 "name": "setCollectionLimit",
667 "outputs": [],684 "outputs": [],
668 "stateMutability": "nonpayable",685 "stateMutability": "nonpayable",
720 { "internalType": "address", "name": "eth", "type": "address" },737 { "internalType": "address", "name": "eth", "type": "address" },
721 { "internalType": "uint256", "name": "sub", "type": "uint256" }738 { "internalType": "uint256", "name": "sub", "type": "uint256" }
722 ],739 ],
723 "internalType": "struct EthCrossAccount",740 "internalType": "struct CrossAddress",
724 "name": "sponsor",741 "name": "sponsor",
725 "type": "tuple"742 "type": "tuple"
726 }743 }
752 "inputs": [769 "inputs": [
753 {770 {
754 "components": [771 "components": [
755 { "internalType": "string", "name": "field_0", "type": "string" },772 { "internalType": "string", "name": "key", "type": "string" },
756 {773 {
757 "components": [774 "components": [
758 {775 {
759 "internalType": "enum EthTokenPermissions",776 "internalType": "enum TokenPermissionField",
760 "name": "field_0",777 "name": "code",
761 "type": "uint8"778 "type": "uint8"
762 },779 },
763 { "internalType": "bool", "name": "field_1", "type": "bool" }780 { "internalType": "bool", "name": "value", "type": "bool" }
764 ],781 ],
765 "internalType": "struct Tuple59[]",782 "internalType": "struct PropertyPermission[]",
766 "name": "field_1",783 "name": "permissions",
767 "type": "tuple[]"784 "type": "tuple[]"
768 }785 }
769 ],786 ],
770 "internalType": "struct Tuple61[]",787 "internalType": "struct TokenPropertyPermission[]",
771 "name": "permissions",788 "name": "permissions",
772 "type": "tuple[]"789 "type": "tuple[]"
773 }790 }
818 "outputs": [835 "outputs": [
819 {836 {
820 "components": [837 "components": [
821 { "internalType": "string", "name": "field_0", "type": "string" },838 { "internalType": "string", "name": "key", "type": "string" },
822 {839 {
823 "components": [840 "components": [
824 {841 {
825 "internalType": "enum EthTokenPermissions",842 "internalType": "enum TokenPermissionField",
826 "name": "field_0",843 "name": "code",
827 "type": "uint8"844 "type": "uint8"
828 },845 },
829 { "internalType": "bool", "name": "field_1", "type": "bool" }846 { "internalType": "bool", "name": "value", "type": "bool" }
830 ],847 ],
831 "internalType": "struct Tuple59[]",848 "internalType": "struct PropertyPermission[]",
832 "name": "field_1",849 "name": "permissions",
833 "type": "tuple[]"850 "type": "tuple[]"
834 }851 }
835 ],852 ],
836 "internalType": "struct Tuple61[]",853 "internalType": "struct TokenPropertyPermission[]",
837 "name": "",854 "name": "",
838 "type": "tuple[]"855 "type": "tuple[]"
839 }856 }
874 { "internalType": "address", "name": "eth", "type": "address" },891 { "internalType": "address", "name": "eth", "type": "address" },
875 { "internalType": "uint256", "name": "sub", "type": "uint256" }892 { "internalType": "uint256", "name": "sub", "type": "uint256" }
876 ],893 ],
877 "internalType": "struct EthCrossAccount",894 "internalType": "struct CrossAddress",
878 "name": "to",895 "name": "to",
879 "type": "tuple"896 "type": "tuple"
880 },897 },
903 { "internalType": "address", "name": "eth", "type": "address" },920 { "internalType": "address", "name": "eth", "type": "address" },
904 { "internalType": "uint256", "name": "sub", "type": "uint256" }921 { "internalType": "uint256", "name": "sub", "type": "uint256" }
905 ],922 ],
906 "internalType": "struct EthCrossAccount",923 "internalType": "struct CrossAddress",
907 "name": "from",924 "name": "from",
908 "type": "tuple"925 "type": "tuple"
909 },926 },
912 { "internalType": "address", "name": "eth", "type": "address" },929 { "internalType": "address", "name": "eth", "type": "address" },
913 { "internalType": "uint256", "name": "sub", "type": "uint256" }930 { "internalType": "uint256", "name": "sub", "type": "uint256" }
914 ],931 ],
915 "internalType": "struct EthCrossAccount",932 "internalType": "struct CrossAddress",
916 "name": "to",933 "name": "to",
917 "type": "tuple"934 "type": "tuple"
918 },935 },
modifiedtests/src/eth/abi/reFungible.jsondiffbeforeafterboth
87 { "internalType": "address", "name": "eth", "type": "address" },87 { "internalType": "address", "name": "eth", "type": "address" },
88 { "internalType": "uint256", "name": "sub", "type": "uint256" }88 { "internalType": "uint256", "name": "sub", "type": "uint256" }
89 ],89 ],
90 "internalType": "struct EthCrossAccount",90 "internalType": "struct CrossAddress",
91 "name": "newAdmin",91 "name": "newAdmin",
92 "type": "tuple"92 "type": "tuple"
93 }93 }
104 { "internalType": "address", "name": "eth", "type": "address" },104 { "internalType": "address", "name": "eth", "type": "address" },
105 { "internalType": "uint256", "name": "sub", "type": "uint256" }105 { "internalType": "uint256", "name": "sub", "type": "uint256" }
106 ],106 ],
107 "internalType": "struct EthCrossAccount",107 "internalType": "struct CrossAddress",
108 "name": "user",108 "name": "user",
109 "type": "tuple"109 "type": "tuple"
110 }110 }
121 { "internalType": "address", "name": "eth", "type": "address" },121 { "internalType": "address", "name": "eth", "type": "address" },
122 { "internalType": "uint256", "name": "sub", "type": "uint256" }122 { "internalType": "uint256", "name": "sub", "type": "uint256" }
123 ],123 ],
124 "internalType": "struct EthCrossAccount",124 "internalType": "struct CrossAddress",
125 "name": "user",125 "name": "user",
126 "type": "tuple"126 "type": "tuple"
127 }127 }
166 { "internalType": "address", "name": "eth", "type": "address" },166 { "internalType": "address", "name": "eth", "type": "address" },
167 { "internalType": "uint256", "name": "sub", "type": "uint256" }167 { "internalType": "uint256", "name": "sub", "type": "uint256" }
168 ],168 ],
169 "internalType": "struct EthCrossAccount",169 "internalType": "struct CrossAddress",
170 "name": "from",170 "name": "from",
171 "type": "tuple"171 "type": "tuple"
172 },172 },
184 { "internalType": "address", "name": "eth", "type": "address" },184 { "internalType": "address", "name": "eth", "type": "address" },
185 { "internalType": "uint256", "name": "sub", "type": "uint256" }185 { "internalType": "uint256", "name": "sub", "type": "uint256" }
186 ],186 ],
187 "internalType": "struct EthCrossAccount",187 "internalType": "struct CrossAddress",
188 "name": "newOwner",188 "name": "newOwner",
189 "type": "tuple"189 "type": "tuple"
190 }190 }
203 { "internalType": "address", "name": "eth", "type": "address" },203 { "internalType": "address", "name": "eth", "type": "address" },
204 { "internalType": "uint256", "name": "sub", "type": "uint256" }204 { "internalType": "uint256", "name": "sub", "type": "uint256" }
205 ],205 ],
206 "internalType": "struct EthCrossAccount[]",206 "internalType": "struct CrossAddress[]",
207 "name": "",207 "name": "",
208 "type": "tuple[]"208 "type": "tuple[]"
209 }209 }
225 {225 {
226 "components": [226 "components": [
227 {227 {
228 "internalType": "enum CollectionLimits",228 "internalType": "enum CollectionLimitField",
229 "name": "field_0",229 "name": "field",
230 "type": "uint8"230 "type": "uint8"
231 },231 },
232 {
233 "components": [
232 { "internalType": "bool", "name": "field_1", "type": "bool" },234 { "internalType": "bool", "name": "status", "type": "bool" },
233 { "internalType": "uint256", "name": "field_2", "type": "uint256" }235 { "internalType": "uint256", "name": "value", "type": "uint256" }
236 ],
237 "internalType": "struct OptionUint",
238 "name": "value",
239 "type": "tuple"
240 }
234 ],241 ],
235 "internalType": "struct Tuple34[]",242 "internalType": "struct CollectionLimit[]",
236 "name": "",243 "name": "",
237 "type": "tuple[]"244 "type": "tuple[]"
238 }245 }
247 {254 {
248 "components": [255 "components": [
249 {256 {
250 "internalType": "enum CollectionPermissions",257 "internalType": "enum CollectionPermissionField",
251 "name": "field_0",258 "name": "field",
252 "type": "uint8"259 "type": "uint8"
253 },260 },
254 { "internalType": "bool", "name": "field_1", "type": "bool" }261 { "internalType": "bool", "name": "value", "type": "bool" }
255 ],262 ],
256 "internalType": "struct Tuple43[]",263 "internalType": "struct CollectionNestingPermission[]",
257 "name": "",264 "name": "",
258 "type": "tuple[]"265 "type": "tuple[]"
259 }266 }
267 "outputs": [274 "outputs": [
268 {275 {
269 "components": [276 "components": [
270 { "internalType": "bool", "name": "field_0", "type": "bool" },277 { "internalType": "bool", "name": "token_owner", "type": "bool" },
271 {278 { "internalType": "uint256[]", "name": "ids", "type": "uint256[]" }
272 "internalType": "uint256[]",
273 "name": "field_1",
274 "type": "uint256[]"
275 }
276 ],279 ],
277 "internalType": "struct Tuple40",280 "internalType": "struct CollectionNesting",
278 "name": "",281 "name": "",
279 "type": "tuple"282 "type": "tuple"
280 }283 }
291 { "internalType": "address", "name": "eth", "type": "address" },294 { "internalType": "address", "name": "eth", "type": "address" },
292 { "internalType": "uint256", "name": "sub", "type": "uint256" }295 { "internalType": "uint256", "name": "sub", "type": "uint256" }
293 ],296 ],
294 "internalType": "struct EthCrossAccount",297 "internalType": "struct CrossAddress",
295 "name": "",298 "name": "",
296 "type": "tuple"299 "type": "tuple"
297 }300 }
334 { "internalType": "address", "name": "eth", "type": "address" },337 { "internalType": "address", "name": "eth", "type": "address" },
335 { "internalType": "uint256", "name": "sub", "type": "uint256" }338 { "internalType": "uint256", "name": "sub", "type": "uint256" }
336 ],339 ],
337 "internalType": "struct EthCrossAccount",340 "internalType": "struct CrossAddress",
338 "name": "",341 "name": "",
339 "type": "tuple"342 "type": "tuple"
340 }343 }
367 { "internalType": "address", "name": "eth", "type": "address" },370 { "internalType": "address", "name": "eth", "type": "address" },
368 { "internalType": "uint256", "name": "sub", "type": "uint256" }371 { "internalType": "uint256", "name": "sub", "type": "uint256" }
369 ],372 ],
370 "internalType": "struct EthCrossAccount",373 "internalType": "struct CrossAddress",
371 "name": "",374 "name": "",
372 "type": "tuple"375 "type": "tuple"
373 }376 }
441 { "internalType": "address", "name": "eth", "type": "address" },444 { "internalType": "address", "name": "eth", "type": "address" },
442 { "internalType": "uint256", "name": "sub", "type": "uint256" }445 { "internalType": "uint256", "name": "sub", "type": "uint256" }
443 ],446 ],
444 "internalType": "struct EthCrossAccount",447 "internalType": "struct CrossAddress",
445 "name": "user",448 "name": "user",
446 "type": "tuple"449 "type": "tuple"
447 }450 }
465 { "internalType": "address", "name": "eth", "type": "address" },468 { "internalType": "address", "name": "eth", "type": "address" },
466 { "internalType": "uint256", "name": "sub", "type": "uint256" }469 { "internalType": "uint256", "name": "sub", "type": "uint256" }
467 ],470 ],
468 "internalType": "struct EthCrossAccount",471 "internalType": "struct CrossAddress",
469 "name": "to",472 "name": "to",
470 "type": "tuple"473 "type": "tuple"
471 },474 },
561 { "internalType": "address", "name": "eth", "type": "address" },564 { "internalType": "address", "name": "eth", "type": "address" },
562 { "internalType": "uint256", "name": "sub", "type": "uint256" }565 { "internalType": "uint256", "name": "sub", "type": "uint256" }
563 ],566 ],
564 "internalType": "struct EthCrossAccount",567 "internalType": "struct CrossAddress",
565 "name": "admin",568 "name": "admin",
566 "type": "tuple"569 "type": "tuple"
567 }570 }
585 { "internalType": "address", "name": "eth", "type": "address" },588 { "internalType": "address", "name": "eth", "type": "address" },
586 { "internalType": "uint256", "name": "sub", "type": "uint256" }589 { "internalType": "uint256", "name": "sub", "type": "uint256" }
587 ],590 ],
588 "internalType": "struct EthCrossAccount",591 "internalType": "struct CrossAddress",
589 "name": "user",592 "name": "user",
590 "type": "tuple"593 "type": "tuple"
591 }594 }
636 "type": "function"639 "type": "function"
637 },640 },
638 {641 {
639 "inputs": [642 "inputs": [
643 {
644 "components": [
640 {645 {
641 "internalType": "enum CollectionLimits",646 "internalType": "enum CollectionLimitField",
642 "name": "limit",647 "name": "field",
643 "type": "uint8"648 "type": "uint8"
644 },649 },
650 {
651 "components": [
645 { "internalType": "bool", "name": "status", "type": "bool" },652 { "internalType": "bool", "name": "status", "type": "bool" },
646 { "internalType": "uint256", "name": "value", "type": "uint256" }653 { "internalType": "uint256", "name": "value", "type": "uint256" }
654 ],
655 "internalType": "struct OptionUint",
656 "name": "value",
657 "type": "tuple"
658 }
659 ],
660 "internalType": "struct CollectionLimit",
661 "name": "limit",
662 "type": "tuple"
663 }
647 ],664 ],
648 "name": "setCollectionLimit",665 "name": "setCollectionLimit",
649 "outputs": [],666 "outputs": [],
650 "stateMutability": "nonpayable",667 "stateMutability": "nonpayable",
702 { "internalType": "address", "name": "eth", "type": "address" },719 { "internalType": "address", "name": "eth", "type": "address" },
703 { "internalType": "uint256", "name": "sub", "type": "uint256" }720 { "internalType": "uint256", "name": "sub", "type": "uint256" }
704 ],721 ],
705 "internalType": "struct EthCrossAccount",722 "internalType": "struct CrossAddress",
706 "name": "sponsor",723 "name": "sponsor",
707 "type": "tuple"724 "type": "tuple"
708 }725 }
734 "inputs": [751 "inputs": [
735 {752 {
736 "components": [753 "components": [
737 { "internalType": "string", "name": "field_0", "type": "string" },754 { "internalType": "string", "name": "key", "type": "string" },
738 {755 {
739 "components": [756 "components": [
740 {757 {
741 "internalType": "enum EthTokenPermissions",758 "internalType": "enum TokenPermissionField",
742 "name": "field_0",759 "name": "code",
743 "type": "uint8"760 "type": "uint8"
744 },761 },
745 { "internalType": "bool", "name": "field_1", "type": "bool" }762 { "internalType": "bool", "name": "value", "type": "bool" }
746 ],763 ],
747 "internalType": "struct Tuple58[]",764 "internalType": "struct PropertyPermission[]",
748 "name": "field_1",765 "name": "permissions",
749 "type": "tuple[]"766 "type": "tuple[]"
750 }767 }
751 ],768 ],
752 "internalType": "struct Tuple60[]",769 "internalType": "struct TokenPropertyPermission[]",
753 "name": "permissions",770 "name": "permissions",
754 "type": "tuple[]"771 "type": "tuple[]"
755 }772 }
809 "outputs": [826 "outputs": [
810 {827 {
811 "components": [828 "components": [
812 { "internalType": "string", "name": "field_0", "type": "string" },829 { "internalType": "string", "name": "key", "type": "string" },
813 {830 {
814 "components": [831 "components": [
815 {832 {
816 "internalType": "enum EthTokenPermissions",833 "internalType": "enum TokenPermissionField",
817 "name": "field_0",834 "name": "code",
818 "type": "uint8"835 "type": "uint8"
819 },836 },
820 { "internalType": "bool", "name": "field_1", "type": "bool" }837 { "internalType": "bool", "name": "value", "type": "bool" }
821 ],838 ],
822 "internalType": "struct Tuple58[]",839 "internalType": "struct PropertyPermission[]",
823 "name": "field_1",840 "name": "permissions",
824 "type": "tuple[]"841 "type": "tuple[]"
825 }842 }
826 ],843 ],
827 "internalType": "struct Tuple60[]",844 "internalType": "struct TokenPropertyPermission[]",
828 "name": "",845 "name": "",
829 "type": "tuple[]"846 "type": "tuple[]"
830 }847 }
865 { "internalType": "address", "name": "eth", "type": "address" },882 { "internalType": "address", "name": "eth", "type": "address" },
866 { "internalType": "uint256", "name": "sub", "type": "uint256" }883 { "internalType": "uint256", "name": "sub", "type": "uint256" }
867 ],884 ],
868 "internalType": "struct EthCrossAccount",885 "internalType": "struct CrossAddress",
869 "name": "to",886 "name": "to",
870 "type": "tuple"887 "type": "tuple"
871 },888 },
894 { "internalType": "address", "name": "eth", "type": "address" },911 { "internalType": "address", "name": "eth", "type": "address" },
895 { "internalType": "uint256", "name": "sub", "type": "uint256" }912 { "internalType": "uint256", "name": "sub", "type": "uint256" }
896 ],913 ],
897 "internalType": "struct EthCrossAccount",914 "internalType": "struct CrossAddress",
898 "name": "from",915 "name": "from",
899 "type": "tuple"916 "type": "tuple"
900 },917 },
903 { "internalType": "address", "name": "eth", "type": "address" },920 { "internalType": "address", "name": "eth", "type": "address" },
904 { "internalType": "uint256", "name": "sub", "type": "uint256" }921 { "internalType": "uint256", "name": "sub", "type": "uint256" }
905 ],922 ],
906 "internalType": "struct EthCrossAccount",923 "internalType": "struct CrossAddress",
907 "name": "to",924 "name": "to",
908 "type": "tuple"925 "type": "tuple"
909 },926 },
modifiedtests/src/eth/abi/reFungibleToken.jsondiffbeforeafterboth
76 { "internalType": "address", "name": "eth", "type": "address" },76 { "internalType": "address", "name": "eth", "type": "address" },
77 { "internalType": "uint256", "name": "sub", "type": "uint256" }77 { "internalType": "uint256", "name": "sub", "type": "uint256" }
78 ],78 ],
79 "internalType": "struct EthCrossAccount",79 "internalType": "struct CrossAddress",
80 "name": "spender",80 "name": "spender",
81 "type": "tuple"81 "type": "tuple"
82 },82 },
113 { "internalType": "address", "name": "eth", "type": "address" },113 { "internalType": "address", "name": "eth", "type": "address" },
114 { "internalType": "uint256", "name": "sub", "type": "uint256" }114 { "internalType": "uint256", "name": "sub", "type": "uint256" }
115 ],115 ],
116 "internalType": "struct EthCrossAccount",116 "internalType": "struct CrossAddress",
117 "name": "from",117 "name": "from",
118 "type": "tuple"118 "type": "tuple"
119 },119 },
201 { "internalType": "address", "name": "eth", "type": "address" },201 { "internalType": "address", "name": "eth", "type": "address" },
202 { "internalType": "uint256", "name": "sub", "type": "uint256" }202 { "internalType": "uint256", "name": "sub", "type": "uint256" }
203 ],203 ],
204 "internalType": "struct EthCrossAccount",204 "internalType": "struct CrossAddress",
205 "name": "to",205 "name": "to",
206 "type": "tuple"206 "type": "tuple"
207 },207 },
230 { "internalType": "address", "name": "eth", "type": "address" },230 { "internalType": "address", "name": "eth", "type": "address" },
231 { "internalType": "uint256", "name": "sub", "type": "uint256" }231 { "internalType": "uint256", "name": "sub", "type": "uint256" }
232 ],232 ],
233 "internalType": "struct EthCrossAccount",233 "internalType": "struct CrossAddress",
234 "name": "from",234 "name": "from",
235 "type": "tuple"235 "type": "tuple"
236 },236 },
239 { "internalType": "address", "name": "eth", "type": "address" },239 { "internalType": "address", "name": "eth", "type": "address" },
240 { "internalType": "uint256", "name": "sub", "type": "uint256" }240 { "internalType": "uint256", "name": "sub", "type": "uint256" }
241 ],241 ],
242 "internalType": "struct EthCrossAccount",242 "internalType": "struct CrossAddress",
243 "name": "to",243 "name": "to",
244 "type": "tuple"244 "type": "tuple"
245 },245 },
modifiedtests/src/eth/api/ContractHelpers.soldiffbeforeafterboth
69 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.69 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
70 /// @dev EVM selector for this function is: 0x766c4f37,70 /// @dev EVM selector for this function is: 0x766c4f37,
71 /// or in textual repr: sponsor(address)71 /// or in textual repr: sponsor(address)
72 function sponsor(address contractAddress) external view returns (EthCrossAccount memory);72 function sponsor(address contractAddress) external view returns (OptionCrossAddress memory);
7373
74 /// Check tat contract has confirmed sponsor.74 /// Check tat contract has confirmed sponsor.
75 ///75 ///
9393
94 /// @dev EVM selector for this function is: 0xfde8a560,94 /// @dev EVM selector for this function is: 0xfde8a560,
95 /// or in textual repr: setSponsoringMode(address,uint8)95 /// or in textual repr: setSponsoringMode(address,uint8)
96 function setSponsoringMode(address contractAddress, uint8 mode) external;96 function setSponsoringMode(address contractAddress, SponsoringModeT mode) external;
9797
98 /// Get current contract sponsoring rate limit98 /// Get current contract sponsoring rate limit
99 /// @param contractAddress Contract to get sponsoring rate limit of99 /// @param contractAddress Contract to get sponsoring rate limit of
171 function toggleAllowlist(address contractAddress, bool enabled) external;171 function toggleAllowlist(address contractAddress, bool enabled) external;
172}172}
173
174/// Available contract sponsoring modes
175enum SponsoringModeT {
176 /// Sponsoring is disabled
177 Disabled,
178 /// Only users from allowlist will be sponsored
179 Allowlisted,
180 /// All users will be sponsored
181 Generous
182}
183
184/// Ethereum representation of Optional value with CrossAddress.
185struct OptionCrossAddress {
186 bool status;
187 CrossAddress value;
188}
173189
174/// @dev Cross account struct190/// Cross account struct
175struct EthCrossAccount {191struct CrossAddress {
176 address eth;192 address eth;
177 uint256 sub;193 uint256 sub;
178}194}
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
13}13}
1414
15/// @title A contract that allows you to work with collections.15/// @title A contract that allows you to work with collections.
16/// @dev the ERC-165 identifier for this interface is 0x81172a7516/// @dev the ERC-165 identifier for this interface is 0x2a14cfd1
17interface Collection is Dummy, ERC165 {17interface Collection is Dummy, ERC165 {
18 // /// Set collection property.18 // /// Set collection property.
19 // ///19 // ///
78 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.78 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
79 /// @dev EVM selector for this function is: 0x84a1d5a8,79 /// @dev EVM selector for this function is: 0x84a1d5a8,
80 /// or in textual repr: setCollectionSponsorCross((address,uint256))80 /// or in textual repr: setCollectionSponsorCross((address,uint256))
81 function setCollectionSponsorCross(EthCrossAccount memory sponsor) external;81 function setCollectionSponsorCross(CrossAddress memory sponsor) external;
8282
83 /// Whether there is a pending sponsor.83 /// Whether there is a pending sponsor.
84 /// @dev EVM selector for this function is: 0x058ac185,84 /// @dev EVM selector for this function is: 0x058ac185,
102 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.102 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
103 /// @dev EVM selector for this function is: 0x6ec0a9f1,103 /// @dev EVM selector for this function is: 0x6ec0a9f1,
104 /// or in textual repr: collectionSponsor()104 /// or in textual repr: collectionSponsor()
105 function collectionSponsor() external view returns (EthCrossAccount memory);105 function collectionSponsor() external view returns (CrossAddress memory);
106106
107 /// Get current collection limits.107 /// Get current collection limits.
108 ///108 ///
109 /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:109 /// @return Array of collection limits
110 /// "accountTokenOwnershipLimit",
111 /// "sponsoredDataSize",
112 /// "sponsoredDataRateLimit",
113 /// "tokenLimit",
114 /// "sponsorTransferTimeout",
115 /// "sponsorApproveTimeout"
116 /// "ownerCanTransfer",
117 /// "ownerCanDestroy",
118 /// "transfersEnabled"
119 /// Return `false` if a limit not set.
120 /// @dev EVM selector for this function is: 0xf63bc572,110 /// @dev EVM selector for this function is: 0xf63bc572,
121 /// or in textual repr: collectionLimits()111 /// or in textual repr: collectionLimits()
122 function collectionLimits() external view returns (Tuple21[] memory);112 function collectionLimits() external view returns (CollectionLimit[] memory);
123113
124 /// Set limits for the collection.114 /// Set limits for the collection.
125 /// @dev Throws error if limit not found.115 /// @dev Throws error if limit not found.
126 /// @param limit Name of the limit. Valid names:
127 /// "accountTokenOwnershipLimit",
128 /// "sponsoredDataSize",
129 /// "sponsoredDataRateLimit",
130 /// "tokenLimit",
131 /// "sponsorTransferTimeout",
132 /// "sponsorApproveTimeout"
133 /// "ownerCanTransfer",
134 /// "ownerCanDestroy",
135 /// "transfersEnabled"
136 /// @param status enable\disable limit. Works only with `true`.
137 /// @param value Value of the limit.116 /// @param limit Some limit.
138 /// @dev EVM selector for this function is: 0x88150bd0,117 /// @dev EVM selector for this function is: 0x2316ee74,
139 /// or in textual repr: setCollectionLimit(uint8,bool,uint256)118 /// or in textual repr: setCollectionLimit((uint8,(bool,uint256)))
140 function setCollectionLimit(119 function setCollectionLimit(CollectionLimit memory limit) external;
141 CollectionLimits limit,
142 bool status,
143 uint256 value
144 ) external;
145120
146 /// Get contract address.121 /// Get contract address.
152 /// @param newAdmin Cross account administrator address.127 /// @param newAdmin Cross account administrator address.
153 /// @dev EVM selector for this function is: 0x859aa7d6,128 /// @dev EVM selector for this function is: 0x859aa7d6,
154 /// or in textual repr: addCollectionAdminCross((address,uint256))129 /// or in textual repr: addCollectionAdminCross((address,uint256))
155 function addCollectionAdminCross(EthCrossAccount memory newAdmin) external;130 function addCollectionAdminCross(CrossAddress memory newAdmin) external;
156131
157 /// Remove collection admin.132 /// Remove collection admin.
158 /// @param admin Cross account administrator address.133 /// @param admin Cross account administrator address.
159 /// @dev EVM selector for this function is: 0x6c0cd173,134 /// @dev EVM selector for this function is: 0x6c0cd173,
160 /// or in textual repr: removeCollectionAdminCross((address,uint256))135 /// or in textual repr: removeCollectionAdminCross((address,uint256))
161 function removeCollectionAdminCross(EthCrossAccount memory admin) external;136 function removeCollectionAdminCross(CrossAddress memory admin) external;
162137
163 // /// Add collection admin.138 // /// Add collection admin.
164 // /// @param newAdmin Address of the added administrator.139 // /// @param newAdmin Address of the added administrator.
191 /// Returns nesting for a collection166 /// Returns nesting for a collection
192 /// @dev EVM selector for this function is: 0x22d25bfe,167 /// @dev EVM selector for this function is: 0x22d25bfe,
193 /// or in textual repr: collectionNestingRestrictedCollectionIds()168 /// or in textual repr: collectionNestingRestrictedCollectionIds()
194 function collectionNestingRestrictedCollectionIds() external view returns (Tuple26 memory);169 function collectionNestingRestrictedCollectionIds() external view returns (CollectionNesting memory);
195170
196 /// Returns permissions for a collection171 /// Returns permissions for a collection
197 /// @dev EVM selector for this function is: 0x5b2eaf4b,172 /// @dev EVM selector for this function is: 0x5b2eaf4b,
198 /// or in textual repr: collectionNestingPermissions()173 /// or in textual repr: collectionNestingPermissions()
199 function collectionNestingPermissions() external view returns (Tuple29[] memory);174 function collectionNestingPermissions() external view returns (CollectionNestingPermission[] memory);
200175
201 /// Set the collection access method.176 /// Set the collection access method.
202 /// @param mode Access mode177 /// @param mode Access mode
211 /// @param user User address to check.186 /// @param user User address to check.
212 /// @dev EVM selector for this function is: 0x91b6df49,187 /// @dev EVM selector for this function is: 0x91b6df49,
213 /// or in textual repr: allowlistedCross((address,uint256))188 /// or in textual repr: allowlistedCross((address,uint256))
214 function allowlistedCross(EthCrossAccount memory user) external view returns (bool);189 function allowlistedCross(CrossAddress memory user) external view returns (bool);
215190
216 // /// Add the user to the allowed list.191 // /// Add the user to the allowed list.
217 // ///192 // ///
225 /// @param user User cross account address.200 /// @param user User cross account address.
226 /// @dev EVM selector for this function is: 0xa0184a3a,201 /// @dev EVM selector for this function is: 0xa0184a3a,
227 /// or in textual repr: addToCollectionAllowListCross((address,uint256))202 /// or in textual repr: addToCollectionAllowListCross((address,uint256))
228 function addToCollectionAllowListCross(EthCrossAccount memory user) external;203 function addToCollectionAllowListCross(CrossAddress memory user) external;
229204
230 // /// Remove the user from the allowed list.205 // /// Remove the user from the allowed list.
231 // ///206 // ///
239 /// @param user User cross account address.214 /// @param user User cross account address.
240 /// @dev EVM selector for this function is: 0x09ba452a,215 /// @dev EVM selector for this function is: 0x09ba452a,
241 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))216 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))
242 function removeFromCollectionAllowListCross(EthCrossAccount memory user) external;217 function removeFromCollectionAllowListCross(CrossAddress memory user) external;
243218
244 /// Switch permission for minting.219 /// Switch permission for minting.
245 ///220 ///
262 /// @return "true" if account is the owner or admin237 /// @return "true" if account is the owner or admin
263 /// @dev EVM selector for this function is: 0x3e75a905,238 /// @dev EVM selector for this function is: 0x3e75a905,
264 /// or in textual repr: isOwnerOrAdminCross((address,uint256))239 /// or in textual repr: isOwnerOrAdminCross((address,uint256))
265 function isOwnerOrAdminCross(EthCrossAccount memory user) external view returns (bool);240 function isOwnerOrAdminCross(CrossAddress memory user) external view returns (bool);
266241
267 /// Returns collection type242 /// Returns collection type
268 ///243 ///
277 /// If address is canonical then substrate mirror is zero and vice versa.252 /// If address is canonical then substrate mirror is zero and vice versa.
278 /// @dev EVM selector for this function is: 0xdf727d3b,253 /// @dev EVM selector for this function is: 0xdf727d3b,
279 /// or in textual repr: collectionOwner()254 /// or in textual repr: collectionOwner()
280 function collectionOwner() external view returns (EthCrossAccount memory);255 function collectionOwner() external view returns (CrossAddress memory);
281256
282 // /// Changes collection owner to another account257 // /// Changes collection owner to another account
283 // ///258 // ///
293 /// If address is canonical then substrate mirror is zero and vice versa.268 /// If address is canonical then substrate mirror is zero and vice versa.
294 /// @dev EVM selector for this function is: 0x5813216b,269 /// @dev EVM selector for this function is: 0x5813216b,
295 /// or in textual repr: collectionAdmins()270 /// or in textual repr: collectionAdmins()
296 function collectionAdmins() external view returns (EthCrossAccount[] memory);271 function collectionAdmins() external view returns (CrossAddress[] memory);
297272
298 /// Changes collection owner to another account273 /// Changes collection owner to another account
299 ///274 ///
300 /// @dev Owner can be changed only by current owner275 /// @dev Owner can be changed only by current owner
301 /// @param newOwner new owner cross account276 /// @param newOwner new owner cross account
302 /// @dev EVM selector for this function is: 0x6496c497,277 /// @dev EVM selector for this function is: 0x6496c497,
303 /// or in textual repr: changeCollectionOwnerCross((address,uint256))278 /// or in textual repr: changeCollectionOwnerCross((address,uint256))
304 function changeCollectionOwnerCross(EthCrossAccount memory newOwner) external;279 function changeCollectionOwnerCross(CrossAddress memory newOwner) external;
305}280}
306281
307/// @dev Cross account struct282/// Cross account struct
308struct EthCrossAccount {283struct CrossAddress {
309 address eth;284 address eth;
310 uint256 sub;285 uint256 sub;
311}286}
312287
313/// @dev anonymous struct288/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
314struct Tuple29 {289struct CollectionNestingPermission {
315 CollectionPermissions field_0;290 CollectionPermissionField field;
316 bool field_1;291 bool value;
317}292}
318293
294/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
319enum CollectionPermissions {295enum CollectionPermissionField {
320 CollectionAdmin,296 /// Owner of token can nest tokens under it.
321 TokenOwner297 TokenOwner,
298 /// Admin of token collection can nest tokens under token.
299 CollectionAdmin
322}300}
323301
324/// @dev anonymous struct302/// Nested collections.
325struct Tuple26 {303struct CollectionNesting {
326 bool field_0;304 bool token_owner;
327 uint256[] field_1;305 uint256[] ids;
328}306}
329307
330/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.308/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
309struct CollectionLimit {
310 CollectionLimitField field;
311 OptionUint value;
312}
313
314/// Ethereum representation of Optional value with uint256.
315struct OptionUint {
316 bool status;
317 uint256 value;
318}
319
320/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
331enum CollectionLimits {321enum CollectionLimitField {
332 /// @dev How many tokens can a user have on one account.322 /// How many tokens can a user have on one account.
333 AccountTokenOwnership,323 AccountTokenOwnership,
334 /// @dev How many bytes of data are available for sponsorship.324 /// How many bytes of data are available for sponsorship.
335 SponsoredDataSize,325 SponsoredDataSize,
336 /// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]326 /// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
337 SponsoredDataRateLimit,327 SponsoredDataRateLimit,
338 /// @dev How many tokens can be mined into this collection.328 /// How many tokens can be mined into this collection.
339 TokenLimit,329 TokenLimit,
340 /// @dev Timeouts for transfer sponsoring.330 /// Timeouts for transfer sponsoring.
341 SponsorTransferTimeout,331 SponsorTransferTimeout,
342 /// @dev Timeout for sponsoring an approval in passed blocks.332 /// Timeout for sponsoring an approval in passed blocks.
343 SponsorApproveTimeout,333 SponsorApproveTimeout,
344 /// @dev Whether the collection owner of the collection can send tokens (which belong to other users).334 /// Whether the collection owner of the collection can send tokens (which belong to other users).
345 OwnerCanTransfer,335 OwnerCanTransfer,
346 /// @dev Can the collection owner burn other people's tokens.336 /// Can the collection owner burn other people's tokens.
347 OwnerCanDestroy,337 OwnerCanDestroy,
348 /// @dev Is it possible to send tokens from this collection between users.338 /// Is it possible to send tokens from this collection between users.
349 TransferEnabled339 TransferEnabled
350}340}
351341
352/// @dev anonymous struct342/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
353struct Tuple21 {
354 CollectionLimits field_0;
355 bool field_1;
356 uint256 field_2;
357}
358
359/// @dev Property struct
360struct Property {343struct Property {
361 string key;344 string key;
362 bytes value;345 bytes value;
371354
372 /// @dev EVM selector for this function is: 0x269e6158,355 /// @dev EVM selector for this function is: 0x269e6158,
373 /// or in textual repr: mintCross((address,uint256),uint256)356 /// or in textual repr: mintCross((address,uint256),uint256)
374 function mintCross(EthCrossAccount memory to, uint256 amount) external returns (bool);357 function mintCross(CrossAddress memory to, uint256 amount) external returns (bool);
375358
376 /// @dev EVM selector for this function is: 0x0ecd0ab0,359 /// @dev EVM selector for this function is: 0x0ecd0ab0,
377 /// or in textual repr: approveCross((address,uint256),uint256)360 /// or in textual repr: approveCross((address,uint256),uint256)
378 function approveCross(EthCrossAccount memory spender, uint256 amount) external returns (bool);361 function approveCross(CrossAddress memory spender, uint256 amount) external returns (bool);
379362
380 // /// Burn tokens from account363 // /// Burn tokens from account
381 // /// @dev Function that burns an `amount` of the tokens of a given account,364 // /// @dev Function that burns an `amount` of the tokens of a given account,
393 /// @param amount The amount that will be burnt.376 /// @param amount The amount that will be burnt.
394 /// @dev EVM selector for this function is: 0xbb2f5a58,377 /// @dev EVM selector for this function is: 0xbb2f5a58,
395 /// or in textual repr: burnFromCross((address,uint256),uint256)378 /// or in textual repr: burnFromCross((address,uint256),uint256)
396 function burnFromCross(EthCrossAccount memory from, uint256 amount) external returns (bool);379 function burnFromCross(CrossAddress memory from, uint256 amount) external returns (bool);
397380
398 /// Mint tokens for multiple accounts.381 /// Mint tokens for multiple accounts.
399 /// @param amounts array of pairs of account address and amount382 /// @param amounts array of pairs of account address and amount
403386
404 /// @dev EVM selector for this function is: 0x2ada85ff,387 /// @dev EVM selector for this function is: 0x2ada85ff,
405 /// or in textual repr: transferCross((address,uint256),uint256)388 /// or in textual repr: transferCross((address,uint256),uint256)
406 function transferCross(EthCrossAccount memory to, uint256 amount) external returns (bool);389 function transferCross(CrossAddress memory to, uint256 amount) external returns (bool);
407390
408 /// @dev EVM selector for this function is: 0xd5cf430b,391 /// @dev EVM selector for this function is: 0xd5cf430b,
409 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)392 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
410 function transferFromCross(393 function transferFromCross(
411 EthCrossAccount memory from,394 CrossAddress memory from,
412 EthCrossAccount memory to,395 CrossAddress memory to,
413 uint256 amount396 uint256 amount
414 ) external returns (bool);397 ) external returns (bool);
415}398}
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
30 /// @param permissions Permissions for keys.30 /// @param permissions Permissions for keys.
31 /// @dev EVM selector for this function is: 0xbd92983a,31 /// @dev EVM selector for this function is: 0xbd92983a,
32 /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])32 /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
33 function setTokenPropertyPermissions(Tuple53[] memory permissions) external;33 function setTokenPropertyPermissions(TokenPropertyPermission[] memory permissions) external;
3434
35 /// @notice Get permissions for token properties.35 /// @notice Get permissions for token properties.
36 /// @dev EVM selector for this function is: 0xf23d7790,36 /// @dev EVM selector for this function is: 0xf23d7790,
37 /// or in textual repr: tokenPropertyPermissions()37 /// or in textual repr: tokenPropertyPermissions()
38 function tokenPropertyPermissions() external view returns (Tuple53[] memory);38 function tokenPropertyPermissions() external view returns (TokenPropertyPermission[] memory);
3939
40 // /// @notice Set token property value.40 // /// @notice Set token property value.
41 // /// @dev Throws error if `msg.sender` has no permission to edit the property.41 // /// @dev Throws error if `msg.sender` has no permission to edit the property.
80 function property(uint256 tokenId, string memory key) external view returns (bytes memory);80 function property(uint256 tokenId, string memory key) external view returns (bytes memory);
81}81}
8282
83/// @dev Property struct83/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
84struct Property {84struct Property {
85 string key;85 string key;
86 bytes value;86 bytes value;
87}87}
8888
89/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.89/// Ethereum representation of Token Property Permissions.
90enum EthTokenPermissions {
91 /// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
92 Mutable,
93 /// @dev Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
94 TokenOwner,
95 /// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
96 CollectionAdmin
97}
98
99/// @dev anonymous struct
100struct Tuple53 {90struct TokenPropertyPermission {
91 /// Token property key.
101 string field_0;92 string key;
93 /// Token property permissions.
102 Tuple51[] field_1;94 PropertyPermission[] permissions;
103}95}
10496
105/// @dev anonymous struct97/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
106struct Tuple51 {98struct PropertyPermission {
99 /// TokenPermission field.
107 EthTokenPermissions field_0;100 TokenPermissionField code;
101 /// TokenPermission value.
108 bool field_1;102 bool value;
109}103}
104
105/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
106enum TokenPermissionField {
107 /// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
108 Mutable,
109 /// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
110 TokenOwner,
111 /// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
112 CollectionAdmin
113}
110114
111/// @title A contract that allows you to work with collections.115/// @title A contract that allows you to work with collections.
112/// @dev the ERC-165 identifier for this interface is 0x81172a75116/// @dev the ERC-165 identifier for this interface is 0x2a14cfd1
113interface Collection is Dummy, ERC165 {117interface Collection is Dummy, ERC165 {
114 // /// Set collection property.118 // /// Set collection property.
115 // ///119 // ///
174 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.178 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
175 /// @dev EVM selector for this function is: 0x84a1d5a8,179 /// @dev EVM selector for this function is: 0x84a1d5a8,
176 /// or in textual repr: setCollectionSponsorCross((address,uint256))180 /// or in textual repr: setCollectionSponsorCross((address,uint256))
177 function setCollectionSponsorCross(EthCrossAccount memory sponsor) external;181 function setCollectionSponsorCross(CrossAddress memory sponsor) external;
178182
179 /// Whether there is a pending sponsor.183 /// Whether there is a pending sponsor.
180 /// @dev EVM selector for this function is: 0x058ac185,184 /// @dev EVM selector for this function is: 0x058ac185,
198 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.202 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
199 /// @dev EVM selector for this function is: 0x6ec0a9f1,203 /// @dev EVM selector for this function is: 0x6ec0a9f1,
200 /// or in textual repr: collectionSponsor()204 /// or in textual repr: collectionSponsor()
201 function collectionSponsor() external view returns (EthCrossAccount memory);205 function collectionSponsor() external view returns (CrossAddress memory);
202206
203 /// Get current collection limits.207 /// Get current collection limits.
204 ///208 ///
205 /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:209 /// @return Array of collection limits
206 /// "accountTokenOwnershipLimit",
207 /// "sponsoredDataSize",
208 /// "sponsoredDataRateLimit",
209 /// "tokenLimit",
210 /// "sponsorTransferTimeout",
211 /// "sponsorApproveTimeout"
212 /// "ownerCanTransfer",
213 /// "ownerCanDestroy",
214 /// "transfersEnabled"
215 /// Return `false` if a limit not set.
216 /// @dev EVM selector for this function is: 0xf63bc572,210 /// @dev EVM selector for this function is: 0xf63bc572,
217 /// or in textual repr: collectionLimits()211 /// or in textual repr: collectionLimits()
218 function collectionLimits() external view returns (Tuple31[] memory);212 function collectionLimits() external view returns (CollectionLimit[] memory);
219213
220 /// Set limits for the collection.214 /// Set limits for the collection.
221 /// @dev Throws error if limit not found.215 /// @dev Throws error if limit not found.
222 /// @param limit Name of the limit. Valid names:
223 /// "accountTokenOwnershipLimit",
224 /// "sponsoredDataSize",
225 /// "sponsoredDataRateLimit",
226 /// "tokenLimit",
227 /// "sponsorTransferTimeout",
228 /// "sponsorApproveTimeout"
229 /// "ownerCanTransfer",
230 /// "ownerCanDestroy",
231 /// "transfersEnabled"
232 /// @param status enable\disable limit. Works only with `true`.
233 /// @param value Value of the limit.216 /// @param limit Some limit.
234 /// @dev EVM selector for this function is: 0x88150bd0,217 /// @dev EVM selector for this function is: 0x2316ee74,
235 /// or in textual repr: setCollectionLimit(uint8,bool,uint256)218 /// or in textual repr: setCollectionLimit((uint8,(bool,uint256)))
236 function setCollectionLimit(219 function setCollectionLimit(CollectionLimit memory limit) external;
237 CollectionLimits limit,
238 bool status,
239 uint256 value
240 ) external;
241220
242 /// Get contract address.221 /// Get contract address.
248 /// @param newAdmin Cross account administrator address.227 /// @param newAdmin Cross account administrator address.
249 /// @dev EVM selector for this function is: 0x859aa7d6,228 /// @dev EVM selector for this function is: 0x859aa7d6,
250 /// or in textual repr: addCollectionAdminCross((address,uint256))229 /// or in textual repr: addCollectionAdminCross((address,uint256))
251 function addCollectionAdminCross(EthCrossAccount memory newAdmin) external;230 function addCollectionAdminCross(CrossAddress memory newAdmin) external;
252231
253 /// Remove collection admin.232 /// Remove collection admin.
254 /// @param admin Cross account administrator address.233 /// @param admin Cross account administrator address.
255 /// @dev EVM selector for this function is: 0x6c0cd173,234 /// @dev EVM selector for this function is: 0x6c0cd173,
256 /// or in textual repr: removeCollectionAdminCross((address,uint256))235 /// or in textual repr: removeCollectionAdminCross((address,uint256))
257 function removeCollectionAdminCross(EthCrossAccount memory admin) external;236 function removeCollectionAdminCross(CrossAddress memory admin) external;
258237
259 // /// Add collection admin.238 // /// Add collection admin.
260 // /// @param newAdmin Address of the added administrator.239 // /// @param newAdmin Address of the added administrator.
287 /// Returns nesting for a collection266 /// Returns nesting for a collection
288 /// @dev EVM selector for this function is: 0x22d25bfe,267 /// @dev EVM selector for this function is: 0x22d25bfe,
289 /// or in textual repr: collectionNestingRestrictedCollectionIds()268 /// or in textual repr: collectionNestingRestrictedCollectionIds()
290 function collectionNestingRestrictedCollectionIds() external view returns (Tuple36 memory);269 function collectionNestingRestrictedCollectionIds() external view returns (CollectionNesting memory);
291270
292 /// Returns permissions for a collection271 /// Returns permissions for a collection
293 /// @dev EVM selector for this function is: 0x5b2eaf4b,272 /// @dev EVM selector for this function is: 0x5b2eaf4b,
294 /// or in textual repr: collectionNestingPermissions()273 /// or in textual repr: collectionNestingPermissions()
295 function collectionNestingPermissions() external view returns (Tuple39[] memory);274 function collectionNestingPermissions() external view returns (CollectionNestingPermission[] memory);
296275
297 /// Set the collection access method.276 /// Set the collection access method.
298 /// @param mode Access mode277 /// @param mode Access mode
307 /// @param user User address to check.286 /// @param user User address to check.
308 /// @dev EVM selector for this function is: 0x91b6df49,287 /// @dev EVM selector for this function is: 0x91b6df49,
309 /// or in textual repr: allowlistedCross((address,uint256))288 /// or in textual repr: allowlistedCross((address,uint256))
310 function allowlistedCross(EthCrossAccount memory user) external view returns (bool);289 function allowlistedCross(CrossAddress memory user) external view returns (bool);
311290
312 // /// Add the user to the allowed list.291 // /// Add the user to the allowed list.
313 // ///292 // ///
321 /// @param user User cross account address.300 /// @param user User cross account address.
322 /// @dev EVM selector for this function is: 0xa0184a3a,301 /// @dev EVM selector for this function is: 0xa0184a3a,
323 /// or in textual repr: addToCollectionAllowListCross((address,uint256))302 /// or in textual repr: addToCollectionAllowListCross((address,uint256))
324 function addToCollectionAllowListCross(EthCrossAccount memory user) external;303 function addToCollectionAllowListCross(CrossAddress memory user) external;
325304
326 // /// Remove the user from the allowed list.305 // /// Remove the user from the allowed list.
327 // ///306 // ///
335 /// @param user User cross account address.314 /// @param user User cross account address.
336 /// @dev EVM selector for this function is: 0x09ba452a,315 /// @dev EVM selector for this function is: 0x09ba452a,
337 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))316 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))
338 function removeFromCollectionAllowListCross(EthCrossAccount memory user) external;317 function removeFromCollectionAllowListCross(CrossAddress memory user) external;
339318
340 /// Switch permission for minting.319 /// Switch permission for minting.
341 ///320 ///
358 /// @return "true" if account is the owner or admin337 /// @return "true" if account is the owner or admin
359 /// @dev EVM selector for this function is: 0x3e75a905,338 /// @dev EVM selector for this function is: 0x3e75a905,
360 /// or in textual repr: isOwnerOrAdminCross((address,uint256))339 /// or in textual repr: isOwnerOrAdminCross((address,uint256))
361 function isOwnerOrAdminCross(EthCrossAccount memory user) external view returns (bool);340 function isOwnerOrAdminCross(CrossAddress memory user) external view returns (bool);
362341
363 /// Returns collection type342 /// Returns collection type
364 ///343 ///
373 /// If address is canonical then substrate mirror is zero and vice versa.352 /// If address is canonical then substrate mirror is zero and vice versa.
374 /// @dev EVM selector for this function is: 0xdf727d3b,353 /// @dev EVM selector for this function is: 0xdf727d3b,
375 /// or in textual repr: collectionOwner()354 /// or in textual repr: collectionOwner()
376 function collectionOwner() external view returns (EthCrossAccount memory);355 function collectionOwner() external view returns (CrossAddress memory);
377356
378 // /// Changes collection owner to another account357 // /// Changes collection owner to another account
379 // ///358 // ///
389 /// If address is canonical then substrate mirror is zero and vice versa.368 /// If address is canonical then substrate mirror is zero and vice versa.
390 /// @dev EVM selector for this function is: 0x5813216b,369 /// @dev EVM selector for this function is: 0x5813216b,
391 /// or in textual repr: collectionAdmins()370 /// or in textual repr: collectionAdmins()
392 function collectionAdmins() external view returns (EthCrossAccount[] memory);371 function collectionAdmins() external view returns (CrossAddress[] memory);
393372
394 /// Changes collection owner to another account373 /// Changes collection owner to another account
395 ///374 ///
396 /// @dev Owner can be changed only by current owner375 /// @dev Owner can be changed only by current owner
397 /// @param newOwner new owner cross account376 /// @param newOwner new owner cross account
398 /// @dev EVM selector for this function is: 0x6496c497,377 /// @dev EVM selector for this function is: 0x6496c497,
399 /// or in textual repr: changeCollectionOwnerCross((address,uint256))378 /// or in textual repr: changeCollectionOwnerCross((address,uint256))
400 function changeCollectionOwnerCross(EthCrossAccount memory newOwner) external;379 function changeCollectionOwnerCross(CrossAddress memory newOwner) external;
401}380}
402381
403/// @dev Cross account struct382/// Cross account struct
404struct EthCrossAccount {383struct CrossAddress {
405 address eth;384 address eth;
406 uint256 sub;385 uint256 sub;
407}386}
408387
409/// @dev anonymous struct388/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
410struct Tuple39 {389struct CollectionNestingPermission {
411 CollectionPermissions field_0;390 CollectionPermissionField field;
412 bool field_1;391 bool value;
413}392}
414393
394/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
415enum CollectionPermissions {395enum CollectionPermissionField {
416 CollectionAdmin,396 /// Owner of token can nest tokens under it.
417 TokenOwner397 TokenOwner,
398 /// Admin of token collection can nest tokens under token.
399 CollectionAdmin
418}400}
419401
420/// @dev anonymous struct402/// Nested collections.
421struct Tuple36 {403struct CollectionNesting {
422 bool field_0;404 bool token_owner;
423 uint256[] field_1;405 uint256[] ids;
424}406}
425407
426/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.408/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
409struct CollectionLimit {
410 CollectionLimitField field;
411 OptionUint value;
412}
413
414/// Ethereum representation of Optional value with uint256.
415struct OptionUint {
416 bool status;
417 uint256 value;
418}
419
420/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
427enum CollectionLimits {421enum CollectionLimitField {
428 /// @dev How many tokens can a user have on one account.422 /// How many tokens can a user have on one account.
429 AccountTokenOwnership,423 AccountTokenOwnership,
430 /// @dev How many bytes of data are available for sponsorship.424 /// How many bytes of data are available for sponsorship.
431 SponsoredDataSize,425 SponsoredDataSize,
432 /// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]426 /// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
433 SponsoredDataRateLimit,427 SponsoredDataRateLimit,
434 /// @dev How many tokens can be mined into this collection.428 /// How many tokens can be mined into this collection.
435 TokenLimit,429 TokenLimit,
436 /// @dev Timeouts for transfer sponsoring.430 /// Timeouts for transfer sponsoring.
437 SponsorTransferTimeout,431 SponsorTransferTimeout,
438 /// @dev Timeout for sponsoring an approval in passed blocks.432 /// Timeout for sponsoring an approval in passed blocks.
439 SponsorApproveTimeout,433 SponsorApproveTimeout,
440 /// @dev Whether the collection owner of the collection can send tokens (which belong to other users).434 /// Whether the collection owner of the collection can send tokens (which belong to other users).
441 OwnerCanTransfer,435 OwnerCanTransfer,
442 /// @dev Can the collection owner burn other people's tokens.436 /// Can the collection owner burn other people's tokens.
443 OwnerCanDestroy,437 OwnerCanDestroy,
444 /// @dev Is it possible to send tokens from this collection between users.438 /// Is it possible to send tokens from this collection between users.
445 TransferEnabled439 TransferEnabled
446}440}
447
448/// @dev anonymous struct
449struct Tuple31 {
450 CollectionLimits field_0;
451 bool field_1;
452 uint256 field_2;
453}
454441
455/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension442/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
456/// @dev See https://eips.ethereum.org/EIPS/eip-721443/// @dev See https://eips.ethereum.org/EIPS/eip-721
569 /// @param tokenId Id for the token.556 /// @param tokenId Id for the token.
570 /// @dev EVM selector for this function is: 0x2b29dace,557 /// @dev EVM selector for this function is: 0x2b29dace,
571 /// or in textual repr: crossOwnerOf(uint256)558 /// or in textual repr: crossOwnerOf(uint256)
572 function crossOwnerOf(uint256 tokenId) external view returns (EthCrossAccount memory);559 function crossOwnerOf(uint256 tokenId) external view returns (CrossAddress memory);
573560
574 /// Returns the token properties.561 /// Returns the token properties.
575 ///562 ///
588 /// @param tokenId The NFT to approve575 /// @param tokenId The NFT to approve
589 /// @dev EVM selector for this function is: 0x0ecd0ab0,576 /// @dev EVM selector for this function is: 0x0ecd0ab0,
590 /// or in textual repr: approveCross((address,uint256),uint256)577 /// or in textual repr: approveCross((address,uint256),uint256)
591 function approveCross(EthCrossAccount memory approved, uint256 tokenId) external;578 function approveCross(CrossAddress memory approved, uint256 tokenId) external;
592579
593 /// @notice Transfer ownership of an NFT580 /// @notice Transfer ownership of an NFT
594 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`581 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
606 /// @param tokenId The NFT to transfer593 /// @param tokenId The NFT to transfer
607 /// @dev EVM selector for this function is: 0x2ada85ff,594 /// @dev EVM selector for this function is: 0x2ada85ff,
608 /// or in textual repr: transferCross((address,uint256),uint256)595 /// or in textual repr: transferCross((address,uint256),uint256)
609 function transferCross(EthCrossAccount memory to, uint256 tokenId) external;596 function transferCross(CrossAddress memory to, uint256 tokenId) external;
610597
611 /// @notice Transfer ownership of an NFT from cross account address to cross account address598 /// @notice Transfer ownership of an NFT from cross account address to cross account address
612 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`599 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
617 /// @dev EVM selector for this function is: 0xd5cf430b,604 /// @dev EVM selector for this function is: 0xd5cf430b,
618 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)605 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
619 function transferFromCross(606 function transferFromCross(
620 EthCrossAccount memory from,607 CrossAddress memory from,
621 EthCrossAccount memory to,608 CrossAddress memory to,
622 uint256 tokenId609 uint256 tokenId
623 ) external;610 ) external;
624611
640 /// @param tokenId The NFT to transfer627 /// @param tokenId The NFT to transfer
641 /// @dev EVM selector for this function is: 0xbb2f5a58,628 /// @dev EVM selector for this function is: 0xbb2f5a58,
642 /// or in textual repr: burnFromCross((address,uint256),uint256)629 /// or in textual repr: burnFromCross((address,uint256),uint256)
643 function burnFromCross(EthCrossAccount memory from, uint256 tokenId) external;630 function burnFromCross(CrossAddress memory from, uint256 tokenId) external;
644631
645 /// @notice Returns next free NFT ID.632 /// @notice Returns next free NFT ID.
646 /// @dev EVM selector for this function is: 0x75794a3c,633 /// @dev EVM selector for this function is: 0x75794a3c,
671 /// @return uint256 The id of the newly minted token658 /// @return uint256 The id of the newly minted token
672 /// @dev EVM selector for this function is: 0xb904db03,659 /// @dev EVM selector for this function is: 0xb904db03,
673 /// or in textual repr: mintCross((address,uint256),(string,bytes)[])660 /// or in textual repr: mintCross((address,uint256),(string,bytes)[])
674 function mintCross(EthCrossAccount memory to, Property[] memory properties) external returns (uint256);661 function mintCross(CrossAddress memory to, Property[] memory properties) external returns (uint256);
675}662}
676663
677/// @dev anonymous struct664/// @dev anonymous struct
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
30 /// @param permissions Permissions for keys.30 /// @param permissions Permissions for keys.
31 /// @dev EVM selector for this function is: 0xbd92983a,31 /// @dev EVM selector for this function is: 0xbd92983a,
32 /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])32 /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
33 function setTokenPropertyPermissions(Tuple52[] memory permissions) external;33 function setTokenPropertyPermissions(TokenPropertyPermission[] memory permissions) external;
3434
35 /// @notice Get permissions for token properties.35 /// @notice Get permissions for token properties.
36 /// @dev EVM selector for this function is: 0xf23d7790,36 /// @dev EVM selector for this function is: 0xf23d7790,
37 /// or in textual repr: tokenPropertyPermissions()37 /// or in textual repr: tokenPropertyPermissions()
38 function tokenPropertyPermissions() external view returns (Tuple52[] memory);38 function tokenPropertyPermissions() external view returns (TokenPropertyPermission[] memory);
3939
40 // /// @notice Set token property value.40 // /// @notice Set token property value.
41 // /// @dev Throws error if `msg.sender` has no permission to edit the property.41 // /// @dev Throws error if `msg.sender` has no permission to edit the property.
80 function property(uint256 tokenId, string memory key) external view returns (bytes memory);80 function property(uint256 tokenId, string memory key) external view returns (bytes memory);
81}81}
8282
83/// @dev Property struct83/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
84struct Property {84struct Property {
85 string key;85 string key;
86 bytes value;86 bytes value;
87}87}
8888
89/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.89/// Ethereum representation of Token Property Permissions.
90enum EthTokenPermissions {
91 /// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
92 Mutable,
93 /// @dev Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
94 TokenOwner,
95 /// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
96 CollectionAdmin
97}
98
99/// @dev anonymous struct
100struct Tuple52 {90struct TokenPropertyPermission {
91 /// Token property key.
101 string field_0;92 string key;
93 /// Token property permissions.
102 Tuple50[] field_1;94 PropertyPermission[] permissions;
103}95}
10496
105/// @dev anonymous struct97/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
106struct Tuple50 {98struct PropertyPermission {
99 /// TokenPermission field.
107 EthTokenPermissions field_0;100 TokenPermissionField code;
101 /// TokenPermission value.
108 bool field_1;102 bool value;
109}103}
104
105/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
106enum TokenPermissionField {
107 /// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
108 Mutable,
109 /// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
110 TokenOwner,
111 /// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
112 CollectionAdmin
113}
110114
111/// @title A contract that allows you to work with collections.115/// @title A contract that allows you to work with collections.
112/// @dev the ERC-165 identifier for this interface is 0x81172a75116/// @dev the ERC-165 identifier for this interface is 0x2a14cfd1
113interface Collection is Dummy, ERC165 {117interface Collection is Dummy, ERC165 {
114 // /// Set collection property.118 // /// Set collection property.
115 // ///119 // ///
174 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.178 /// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
175 /// @dev EVM selector for this function is: 0x84a1d5a8,179 /// @dev EVM selector for this function is: 0x84a1d5a8,
176 /// or in textual repr: setCollectionSponsorCross((address,uint256))180 /// or in textual repr: setCollectionSponsorCross((address,uint256))
177 function setCollectionSponsorCross(EthCrossAccount memory sponsor) external;181 function setCollectionSponsorCross(CrossAddress memory sponsor) external;
178182
179 /// Whether there is a pending sponsor.183 /// Whether there is a pending sponsor.
180 /// @dev EVM selector for this function is: 0x058ac185,184 /// @dev EVM selector for this function is: 0x058ac185,
198 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.202 /// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
199 /// @dev EVM selector for this function is: 0x6ec0a9f1,203 /// @dev EVM selector for this function is: 0x6ec0a9f1,
200 /// or in textual repr: collectionSponsor()204 /// or in textual repr: collectionSponsor()
201 function collectionSponsor() external view returns (EthCrossAccount memory);205 function collectionSponsor() external view returns (CrossAddress memory);
202206
203 /// Get current collection limits.207 /// Get current collection limits.
204 ///208 ///
205 /// @return Array of tuples (byte, bool, uint256) with limits and their values. Order of limits:209 /// @return Array of collection limits
206 /// "accountTokenOwnershipLimit",
207 /// "sponsoredDataSize",
208 /// "sponsoredDataRateLimit",
209 /// "tokenLimit",
210 /// "sponsorTransferTimeout",
211 /// "sponsorApproveTimeout"
212 /// "ownerCanTransfer",
213 /// "ownerCanDestroy",
214 /// "transfersEnabled"
215 /// Return `false` if a limit not set.
216 /// @dev EVM selector for this function is: 0xf63bc572,210 /// @dev EVM selector for this function is: 0xf63bc572,
217 /// or in textual repr: collectionLimits()211 /// or in textual repr: collectionLimits()
218 function collectionLimits() external view returns (Tuple30[] memory);212 function collectionLimits() external view returns (CollectionLimit[] memory);
219213
220 /// Set limits for the collection.214 /// Set limits for the collection.
221 /// @dev Throws error if limit not found.215 /// @dev Throws error if limit not found.
222 /// @param limit Name of the limit. Valid names:
223 /// "accountTokenOwnershipLimit",
224 /// "sponsoredDataSize",
225 /// "sponsoredDataRateLimit",
226 /// "tokenLimit",
227 /// "sponsorTransferTimeout",
228 /// "sponsorApproveTimeout"
229 /// "ownerCanTransfer",
230 /// "ownerCanDestroy",
231 /// "transfersEnabled"
232 /// @param status enable\disable limit. Works only with `true`.
233 /// @param value Value of the limit.216 /// @param limit Some limit.
234 /// @dev EVM selector for this function is: 0x88150bd0,217 /// @dev EVM selector for this function is: 0x2316ee74,
235 /// or in textual repr: setCollectionLimit(uint8,bool,uint256)218 /// or in textual repr: setCollectionLimit((uint8,(bool,uint256)))
236 function setCollectionLimit(219 function setCollectionLimit(CollectionLimit memory limit) external;
237 CollectionLimits limit,
238 bool status,
239 uint256 value
240 ) external;
241220
242 /// Get contract address.221 /// Get contract address.
248 /// @param newAdmin Cross account administrator address.227 /// @param newAdmin Cross account administrator address.
249 /// @dev EVM selector for this function is: 0x859aa7d6,228 /// @dev EVM selector for this function is: 0x859aa7d6,
250 /// or in textual repr: addCollectionAdminCross((address,uint256))229 /// or in textual repr: addCollectionAdminCross((address,uint256))
251 function addCollectionAdminCross(EthCrossAccount memory newAdmin) external;230 function addCollectionAdminCross(CrossAddress memory newAdmin) external;
252231
253 /// Remove collection admin.232 /// Remove collection admin.
254 /// @param admin Cross account administrator address.233 /// @param admin Cross account administrator address.
255 /// @dev EVM selector for this function is: 0x6c0cd173,234 /// @dev EVM selector for this function is: 0x6c0cd173,
256 /// or in textual repr: removeCollectionAdminCross((address,uint256))235 /// or in textual repr: removeCollectionAdminCross((address,uint256))
257 function removeCollectionAdminCross(EthCrossAccount memory admin) external;236 function removeCollectionAdminCross(CrossAddress memory admin) external;
258237
259 // /// Add collection admin.238 // /// Add collection admin.
260 // /// @param newAdmin Address of the added administrator.239 // /// @param newAdmin Address of the added administrator.
287 /// Returns nesting for a collection266 /// Returns nesting for a collection
288 /// @dev EVM selector for this function is: 0x22d25bfe,267 /// @dev EVM selector for this function is: 0x22d25bfe,
289 /// or in textual repr: collectionNestingRestrictedCollectionIds()268 /// or in textual repr: collectionNestingRestrictedCollectionIds()
290 function collectionNestingRestrictedCollectionIds() external view returns (Tuple35 memory);269 function collectionNestingRestrictedCollectionIds() external view returns (CollectionNesting memory);
291270
292 /// Returns permissions for a collection271 /// Returns permissions for a collection
293 /// @dev EVM selector for this function is: 0x5b2eaf4b,272 /// @dev EVM selector for this function is: 0x5b2eaf4b,
294 /// or in textual repr: collectionNestingPermissions()273 /// or in textual repr: collectionNestingPermissions()
295 function collectionNestingPermissions() external view returns (Tuple38[] memory);274 function collectionNestingPermissions() external view returns (CollectionNestingPermission[] memory);
296275
297 /// Set the collection access method.276 /// Set the collection access method.
298 /// @param mode Access mode277 /// @param mode Access mode
307 /// @param user User address to check.286 /// @param user User address to check.
308 /// @dev EVM selector for this function is: 0x91b6df49,287 /// @dev EVM selector for this function is: 0x91b6df49,
309 /// or in textual repr: allowlistedCross((address,uint256))288 /// or in textual repr: allowlistedCross((address,uint256))
310 function allowlistedCross(EthCrossAccount memory user) external view returns (bool);289 function allowlistedCross(CrossAddress memory user) external view returns (bool);
311290
312 // /// Add the user to the allowed list.291 // /// Add the user to the allowed list.
313 // ///292 // ///
321 /// @param user User cross account address.300 /// @param user User cross account address.
322 /// @dev EVM selector for this function is: 0xa0184a3a,301 /// @dev EVM selector for this function is: 0xa0184a3a,
323 /// or in textual repr: addToCollectionAllowListCross((address,uint256))302 /// or in textual repr: addToCollectionAllowListCross((address,uint256))
324 function addToCollectionAllowListCross(EthCrossAccount memory user) external;303 function addToCollectionAllowListCross(CrossAddress memory user) external;
325304
326 // /// Remove the user from the allowed list.305 // /// Remove the user from the allowed list.
327 // ///306 // ///
335 /// @param user User cross account address.314 /// @param user User cross account address.
336 /// @dev EVM selector for this function is: 0x09ba452a,315 /// @dev EVM selector for this function is: 0x09ba452a,
337 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))316 /// or in textual repr: removeFromCollectionAllowListCross((address,uint256))
338 function removeFromCollectionAllowListCross(EthCrossAccount memory user) external;317 function removeFromCollectionAllowListCross(CrossAddress memory user) external;
339318
340 /// Switch permission for minting.319 /// Switch permission for minting.
341 ///320 ///
358 /// @return "true" if account is the owner or admin337 /// @return "true" if account is the owner or admin
359 /// @dev EVM selector for this function is: 0x3e75a905,338 /// @dev EVM selector for this function is: 0x3e75a905,
360 /// or in textual repr: isOwnerOrAdminCross((address,uint256))339 /// or in textual repr: isOwnerOrAdminCross((address,uint256))
361 function isOwnerOrAdminCross(EthCrossAccount memory user) external view returns (bool);340 function isOwnerOrAdminCross(CrossAddress memory user) external view returns (bool);
362341
363 /// Returns collection type342 /// Returns collection type
364 ///343 ///
373 /// If address is canonical then substrate mirror is zero and vice versa.352 /// If address is canonical then substrate mirror is zero and vice versa.
374 /// @dev EVM selector for this function is: 0xdf727d3b,353 /// @dev EVM selector for this function is: 0xdf727d3b,
375 /// or in textual repr: collectionOwner()354 /// or in textual repr: collectionOwner()
376 function collectionOwner() external view returns (EthCrossAccount memory);355 function collectionOwner() external view returns (CrossAddress memory);
377356
378 // /// Changes collection owner to another account357 // /// Changes collection owner to another account
379 // ///358 // ///
389 /// If address is canonical then substrate mirror is zero and vice versa.368 /// If address is canonical then substrate mirror is zero and vice versa.
390 /// @dev EVM selector for this function is: 0x5813216b,369 /// @dev EVM selector for this function is: 0x5813216b,
391 /// or in textual repr: collectionAdmins()370 /// or in textual repr: collectionAdmins()
392 function collectionAdmins() external view returns (EthCrossAccount[] memory);371 function collectionAdmins() external view returns (CrossAddress[] memory);
393372
394 /// Changes collection owner to another account373 /// Changes collection owner to another account
395 ///374 ///
396 /// @dev Owner can be changed only by current owner375 /// @dev Owner can be changed only by current owner
397 /// @param newOwner new owner cross account376 /// @param newOwner new owner cross account
398 /// @dev EVM selector for this function is: 0x6496c497,377 /// @dev EVM selector for this function is: 0x6496c497,
399 /// or in textual repr: changeCollectionOwnerCross((address,uint256))378 /// or in textual repr: changeCollectionOwnerCross((address,uint256))
400 function changeCollectionOwnerCross(EthCrossAccount memory newOwner) external;379 function changeCollectionOwnerCross(CrossAddress memory newOwner) external;
401}380}
402381
403/// @dev Cross account struct382/// Cross account struct
404struct EthCrossAccount {383struct CrossAddress {
405 address eth;384 address eth;
406 uint256 sub;385 uint256 sub;
407}386}
408387
409/// @dev anonymous struct388/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
410struct Tuple38 {389struct CollectionNestingPermission {
411 CollectionPermissions field_0;390 CollectionPermissionField field;
412 bool field_1;391 bool value;
413}392}
414393
394/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
415enum CollectionPermissions {395enum CollectionPermissionField {
416 CollectionAdmin,396 /// Owner of token can nest tokens under it.
417 TokenOwner397 TokenOwner,
398 /// Admin of token collection can nest tokens under token.
399 CollectionAdmin
418}400}
419401
420/// @dev anonymous struct402/// Nested collections.
421struct Tuple35 {403struct CollectionNesting {
422 bool field_0;404 bool token_owner;
423 uint256[] field_1;405 uint256[] ids;
424}406}
425407
426/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) representation for EVM.408/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
409struct CollectionLimit {
410 CollectionLimitField field;
411 OptionUint value;
412}
413
414/// Ethereum representation of Optional value with uint256.
415struct OptionUint {
416 bool status;
417 uint256 value;
418}
419
420/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
427enum CollectionLimits {421enum CollectionLimitField {
428 /// @dev How many tokens can a user have on one account.422 /// How many tokens can a user have on one account.
429 AccountTokenOwnership,423 AccountTokenOwnership,
430 /// @dev How many bytes of data are available for sponsorship.424 /// How many bytes of data are available for sponsorship.
431 SponsoredDataSize,425 SponsoredDataSize,
432 /// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]426 /// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
433 SponsoredDataRateLimit,427 SponsoredDataRateLimit,
434 /// @dev How many tokens can be mined into this collection.428 /// How many tokens can be mined into this collection.
435 TokenLimit,429 TokenLimit,
436 /// @dev Timeouts for transfer sponsoring.430 /// Timeouts for transfer sponsoring.
437 SponsorTransferTimeout,431 SponsorTransferTimeout,
438 /// @dev Timeout for sponsoring an approval in passed blocks.432 /// Timeout for sponsoring an approval in passed blocks.
439 SponsorApproveTimeout,433 SponsorApproveTimeout,
440 /// @dev Whether the collection owner of the collection can send tokens (which belong to other users).434 /// Whether the collection owner of the collection can send tokens (which belong to other users).
441 OwnerCanTransfer,435 OwnerCanTransfer,
442 /// @dev Can the collection owner burn other people's tokens.436 /// Can the collection owner burn other people's tokens.
443 OwnerCanDestroy,437 OwnerCanDestroy,
444 /// @dev Is it possible to send tokens from this collection between users.438 /// Is it possible to send tokens from this collection between users.
445 TransferEnabled439 TransferEnabled
446}440}
447
448/// @dev anonymous struct
449struct Tuple30 {
450 CollectionLimits field_0;
451 bool field_1;
452 uint256 field_2;
453}
454441
455/// @dev the ERC-165 identifier for this interface is 0x5b5e139f442/// @dev the ERC-165 identifier for this interface is 0x5b5e139f
456interface ERC721Metadata is Dummy, ERC165 {443interface ERC721Metadata is Dummy, ERC165 {
567 /// @param tokenId Id for the token.554 /// @param tokenId Id for the token.
568 /// @dev EVM selector for this function is: 0x2b29dace,555 /// @dev EVM selector for this function is: 0x2b29dace,
569 /// or in textual repr: crossOwnerOf(uint256)556 /// or in textual repr: crossOwnerOf(uint256)
570 function crossOwnerOf(uint256 tokenId) external view returns (EthCrossAccount memory);557 function crossOwnerOf(uint256 tokenId) external view returns (CrossAddress memory);
571558
572 /// Returns the token properties.559 /// Returns the token properties.
573 ///560 ///
596 /// @param tokenId The RFT to transfer583 /// @param tokenId The RFT to transfer
597 /// @dev EVM selector for this function is: 0x2ada85ff,584 /// @dev EVM selector for this function is: 0x2ada85ff,
598 /// or in textual repr: transferCross((address,uint256),uint256)585 /// or in textual repr: transferCross((address,uint256),uint256)
599 function transferCross(EthCrossAccount memory to, uint256 tokenId) external;586 function transferCross(CrossAddress memory to, uint256 tokenId) external;
600587
601 /// @notice Transfer ownership of an RFT588 /// @notice Transfer ownership of an RFT
602 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`589 /// @dev Throws unless `msg.sender` is the current owner. Throws if `to`
607 /// @dev EVM selector for this function is: 0xd5cf430b,594 /// @dev EVM selector for this function is: 0xd5cf430b,
608 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)595 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
609 function transferFromCross(596 function transferFromCross(
610 EthCrossAccount memory from,597 CrossAddress memory from,
611 EthCrossAccount memory to,598 CrossAddress memory to,
612 uint256 tokenId599 uint256 tokenId
613 ) external;600 ) external;
614601
632 /// @param tokenId The RFT to transfer619 /// @param tokenId The RFT to transfer
633 /// @dev EVM selector for this function is: 0xbb2f5a58,620 /// @dev EVM selector for this function is: 0xbb2f5a58,
634 /// or in textual repr: burnFromCross((address,uint256),uint256)621 /// or in textual repr: burnFromCross((address,uint256),uint256)
635 function burnFromCross(EthCrossAccount memory from, uint256 tokenId) external;622 function burnFromCross(CrossAddress memory from, uint256 tokenId) external;
636623
637 /// @notice Returns next free RFT ID.624 /// @notice Returns next free RFT ID.
638 /// @dev EVM selector for this function is: 0x75794a3c,625 /// @dev EVM selector for this function is: 0x75794a3c,
663 /// @return uint256 The id of the newly minted token650 /// @return uint256 The id of the newly minted token
664 /// @dev EVM selector for this function is: 0xb904db03,651 /// @dev EVM selector for this function is: 0xb904db03,
665 /// or in textual repr: mintCross((address,uint256),(string,bytes)[])652 /// or in textual repr: mintCross((address,uint256),(string,bytes)[])
666 function mintCross(EthCrossAccount memory to, Property[] memory properties) external returns (uint256);653 function mintCross(CrossAddress memory to, Property[] memory properties) external returns (uint256);
667654
668 /// Returns EVM address for refungible token655 /// Returns EVM address for refungible token
669 ///656 ///
modifiedtests/src/eth/api/UniqueRefungibleToken.soldiffbeforeafterboth
39 /// @param amount The amount that will be burnt.39 /// @param amount The amount that will be burnt.
40 /// @dev EVM selector for this function is: 0xbb2f5a58,40 /// @dev EVM selector for this function is: 0xbb2f5a58,
41 /// or in textual repr: burnFromCross((address,uint256),uint256)41 /// or in textual repr: burnFromCross((address,uint256),uint256)
42 function burnFromCross(EthCrossAccount memory from, uint256 amount) external returns (bool);42 function burnFromCross(CrossAddress memory from, uint256 amount) external returns (bool);
4343
44 /// @dev Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`.44 /// @dev Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`.
45 /// Beware that changing an allowance with this method brings the risk that someone may use both the old45 /// Beware that changing an allowance with this method brings the risk that someone may use both the old
50 /// @param amount The amount of tokens to be spent.50 /// @param amount The amount of tokens to be spent.
51 /// @dev EVM selector for this function is: 0x0ecd0ab0,51 /// @dev EVM selector for this function is: 0x0ecd0ab0,
52 /// or in textual repr: approveCross((address,uint256),uint256)52 /// or in textual repr: approveCross((address,uint256),uint256)
53 function approveCross(EthCrossAccount memory spender, uint256 amount) external returns (bool);53 function approveCross(CrossAddress memory spender, uint256 amount) external returns (bool);
5454
55 /// @dev Function that changes total amount of the tokens.55 /// @dev Function that changes total amount of the tokens.
56 /// Throws if `msg.sender` doesn't owns all of the tokens.56 /// Throws if `msg.sender` doesn't owns all of the tokens.
64 /// @param amount The amount to be transferred.64 /// @param amount The amount to be transferred.
65 /// @dev EVM selector for this function is: 0x2ada85ff,65 /// @dev EVM selector for this function is: 0x2ada85ff,
66 /// or in textual repr: transferCross((address,uint256),uint256)66 /// or in textual repr: transferCross((address,uint256),uint256)
67 function transferCross(EthCrossAccount memory to, uint256 amount) external returns (bool);67 function transferCross(CrossAddress memory to, uint256 amount) external returns (bool);
6868
69 /// @dev Transfer tokens from one address to another69 /// @dev Transfer tokens from one address to another
70 /// @param from The address which you want to send tokens from70 /// @param from The address which you want to send tokens from
73 /// @dev EVM selector for this function is: 0xd5cf430b,73 /// @dev EVM selector for this function is: 0xd5cf430b,
74 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)74 /// or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)
75 function transferFromCross(75 function transferFromCross(
76 EthCrossAccount memory from,76 CrossAddress memory from,
77 EthCrossAccount memory to,77 CrossAddress memory to,
78 uint256 amount78 uint256 amount
79 ) external returns (bool);79 ) external returns (bool);
80}80}
8181
82/// @dev Cross account struct82/// Cross account struct
83struct EthCrossAccount {83struct CrossAddress {
84 address eth;84 address eth;
85 uint256 sub;85 uint256 sub;
86}86}
modifiedtests/src/eth/collectionLimits.test.tsdiffbeforeafterboth
1import {IKeyringPair} from '@polkadot/types/types';1import {IKeyringPair} from '@polkadot/types/types';
2import {Pallets} from '../util';2import {Pallets} from '../util';
3import {expect, itEth, usingEthPlaygrounds} from './util';3import {expect, itEth, usingEthPlaygrounds} from './util';
4import {CollectionLimits} from './util/playgrounds/types';4import {CollectionLimitField} from './util/playgrounds/types';
55
66
7describe('Can set collection limits', () => {7describe('Can set collection limits', () => {
46 };46 };
4747
48 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, testCase.case, owner);48 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, testCase.case, owner);
49 await collectionEvm.methods.setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, limits.accountTokenOwnershipLimit).send();49 await collectionEvm.methods.setCollectionLimit({field: CollectionLimitField.AccountTokenOwnership, value: {status: true, value: limits.accountTokenOwnershipLimit}}).send();
50 await collectionEvm.methods.setCollectionLimit(CollectionLimits.SponsoredDataSize, true, limits.sponsoredDataSize).send();50 await collectionEvm.methods.setCollectionLimit({field: CollectionLimitField.SponsoredDataSize, value: {status: true, value: limits.sponsoredDataSize}}).send();
51 await collectionEvm.methods.setCollectionLimit(CollectionLimits.SponsoredDataRateLimit, true, limits.sponsoredDataRateLimit).send();51 await collectionEvm.methods.setCollectionLimit({field: CollectionLimitField.SponsoredDataRateLimit, value: {status: true, value: limits.sponsoredDataRateLimit}}).send();
52 await collectionEvm.methods.setCollectionLimit(CollectionLimits.TokenLimit, true, limits.tokenLimit).send();52 await collectionEvm.methods.setCollectionLimit({field: CollectionLimitField.TokenLimit, value: {status: true, value: limits.tokenLimit}}).send();
53 await collectionEvm.methods.setCollectionLimit(CollectionLimits.SponsorTransferTimeout, true, limits.sponsorTransferTimeout).send();53 await collectionEvm.methods.setCollectionLimit({field: CollectionLimitField.SponsorTransferTimeout, value: {status: true, value: limits.sponsorTransferTimeout}}).send();
54 await collectionEvm.methods.setCollectionLimit(CollectionLimits.SponsorApproveTimeout, true, limits.sponsorApproveTimeout).send();54 await collectionEvm.methods.setCollectionLimit({field: CollectionLimitField.SponsorApproveTimeout, value: {status: true, value: limits.sponsorApproveTimeout}}).send();
55 await collectionEvm.methods.setCollectionLimit(CollectionLimits.OwnerCanTransfer, true, limits.ownerCanTransfer).send();55 await collectionEvm.methods.setCollectionLimit({field: CollectionLimitField.OwnerCanTransfer, value: {status: true, value: limits.ownerCanTransfer}}).send();
56 await collectionEvm.methods.setCollectionLimit(CollectionLimits.OwnerCanDestroy, true, limits.ownerCanDestroy).send();56 await collectionEvm.methods.setCollectionLimit({field: CollectionLimitField.OwnerCanDestroy, value: {status: true, value: limits.ownerCanDestroy}}).send();
57 await collectionEvm.methods.setCollectionLimit(CollectionLimits.TransferEnabled, true, limits.transfersEnabled).send();57 await collectionEvm.methods.setCollectionLimit({field: CollectionLimitField.TransferEnabled, value: {status: true, value: limits.transfersEnabled}}).send();
5858
59 // Check limits from sub:59 // Check limits from sub:
60 const data = (await helper.rft.getData(collectionId))!;60 const data = (await helper.rft.getData(collectionId))!;
63 // Check limits from eth:63 // Check limits from eth:
64 const limitsEvm = await collectionEvm.methods.collectionLimits().call({from: owner});64 const limitsEvm = await collectionEvm.methods.collectionLimits().call({from: owner});
65 expect(limitsEvm).to.have.length(9);65 expect(limitsEvm).to.have.length(9);
66 expect(limitsEvm[0]).to.deep.eq([CollectionLimits.AccountTokenOwnership.toString(), true, limits.accountTokenOwnershipLimit.toString()]);66 expect(limitsEvm[0]).to.deep.eq([CollectionLimitField.AccountTokenOwnership.toString(), [true, limits.accountTokenOwnershipLimit.toString()]]);
67 expect(limitsEvm[1]).to.deep.eq([CollectionLimits.SponsoredDataSize.toString(), true, limits.sponsoredDataSize.toString()]);67 expect(limitsEvm[1]).to.deep.eq([CollectionLimitField.SponsoredDataSize.toString(), [true, limits.sponsoredDataSize.toString()]]);
68 expect(limitsEvm[2]).to.deep.eq([CollectionLimits.SponsoredDataRateLimit.toString(), true, limits.sponsoredDataRateLimit.toString()]);68 expect(limitsEvm[2]).to.deep.eq([CollectionLimitField.SponsoredDataRateLimit.toString(), [true, limits.sponsoredDataRateLimit.toString()]]);
69 expect(limitsEvm[3]).to.deep.eq([CollectionLimits.TokenLimit.toString(), true, limits.tokenLimit.toString()]);69 expect(limitsEvm[3]).to.deep.eq([CollectionLimitField.TokenLimit.toString(), [true, limits.tokenLimit.toString()]]);
70 expect(limitsEvm[4]).to.deep.eq([CollectionLimits.SponsorTransferTimeout.toString(), true, limits.sponsorTransferTimeout.toString()]);70 expect(limitsEvm[4]).to.deep.eq([CollectionLimitField.SponsorTransferTimeout.toString(), [true, limits.sponsorTransferTimeout.toString()]]);
71 expect(limitsEvm[5]).to.deep.eq([CollectionLimits.SponsorApproveTimeout.toString(), true, limits.sponsorApproveTimeout.toString()]);71 expect(limitsEvm[5]).to.deep.eq([CollectionLimitField.SponsorApproveTimeout.toString(), [true, limits.sponsorApproveTimeout.toString()]]);
72 expect(limitsEvm[6]).to.deep.eq([CollectionLimits.OwnerCanTransfer.toString(), true, limits.ownerCanTransfer.toString()]);72 expect(limitsEvm[6]).to.deep.eq([CollectionLimitField.OwnerCanTransfer.toString(), [true, limits.ownerCanTransfer.toString()]]);
73 expect(limitsEvm[7]).to.deep.eq([CollectionLimits.OwnerCanDestroy.toString(), true, limits.ownerCanDestroy.toString()]);73 expect(limitsEvm[7]).to.deep.eq([CollectionLimitField.OwnerCanDestroy.toString(), [true, limits.ownerCanDestroy.toString()]]);
74 expect(limitsEvm[8]).to.deep.eq([CollectionLimits.TransferEnabled.toString(), true, limits.transfersEnabled.toString()]);74 expect(limitsEvm[8]).to.deep.eq([CollectionLimitField.TransferEnabled.toString(), [true, limits.transfersEnabled.toString()]]);
75 }));75 }));
76});76});
7777
101101
102 // Cannot set non-existing limit102 // Cannot set non-existing limit
103 await expect(collectionEvm.methods103 await expect(collectionEvm.methods
104 .setCollectionLimit(9, true, 1)104 .setCollectionLimit({field: 9, value: {status: true, value: 1}})
105 .call()).to.be.rejectedWith('Returned error: VM Exception while processing transaction: revert Value not convertible into enum "CollectionLimits"');105 .call()).to.be.rejectedWith('Returned error: VM Exception while processing transaction: revert Value not convertible into enum "CollectionLimits"');
106106
107 // Cannot disable limits107 // Cannot disable limits
108 await expect(collectionEvm.methods108 await expect(collectionEvm.methods
109 .setCollectionLimit(CollectionLimits.AccountTokenOwnership, false, 200)109 .setCollectionLimit({field: CollectionLimitField.AccountTokenOwnership, value: {status: false, value: 200}})
110 .call()).to.be.rejectedWith('Returned error: VM Exception while processing transaction: revert user can\'t disable limits');110 .call()).to.be.rejectedWith('user can\'t disable limits');
111111
112 await expect(collectionEvm.methods112 await expect(collectionEvm.methods
113 .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, invalidLimits.accountTokenOwnershipLimit)113 .setCollectionLimit({field: CollectionLimitField.AccountTokenOwnership, value: {status: true, value: invalidLimits.accountTokenOwnershipLimit}})
114 .call()).to.be.rejectedWith(`can't convert value to u32 "${invalidLimits.accountTokenOwnershipLimit}"`);114 .call()).to.be.rejectedWith(`can't convert value to u32 "${invalidLimits.accountTokenOwnershipLimit}"`);
115115
116 await expect(collectionEvm.methods116 await expect(collectionEvm.methods
117 .setCollectionLimit(CollectionLimits.TransferEnabled, true, 3)117 .setCollectionLimit({field: CollectionLimitField.TransferEnabled, value: {status: true, value: 3}})
118 .call()).to.be.rejectedWith(`can't convert value to boolean "${invalidLimits.transfersEnabled}"`);118 .call()).to.be.rejectedWith(`can't convert value to boolean "${invalidLimits.transfersEnabled}"`);
119119
120 expect(() => collectionEvm.methods120 expect(() => collectionEvm.methods
121 .setCollectionLimit(CollectionLimits.SponsoredDataSize, true, -1).send()).to.throw('value out-of-bounds');121 .setCollectionLimit({field: CollectionLimitField.SponsoredDataSize, value: {status: true, value: -1}}).send()).to.throw('value out-of-bounds');
122 }));122 }));
123123
124 [124 [
133133
134 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, testCase.case, owner);134 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, testCase.case, owner);
135 await expect(collectionEvm.methods135 await expect(collectionEvm.methods
136 .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)136 .setCollectionLimit({field: CollectionLimitField.AccountTokenOwnership, value: {status: true, value: 1000}})
137 .call({from: nonOwner}))137 .call({from: nonOwner}))
138 .to.be.rejectedWith('NoPermission');138 .to.be.rejectedWith('NoPermission');
139139
140 await expect(collectionEvm.methods140 await expect(collectionEvm.methods
141 .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)141 .setCollectionLimit({field: CollectionLimitField.AccountTokenOwnership, value: {status: true, value: 1000}})
142 .send({from: nonOwner}))142 .send({from: nonOwner}))
143 .to.be.rejected;143 .to.be.rejected;
144 }));144 }));
modifiedtests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth
42 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;42 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;
4343
44 // 1.1 Can get sponsor using methods.sponsor:44 // 1.1 Can get sponsor using methods.sponsor:
45 const actualSponsor = await helpers.methods.sponsor(flipper.options.address).call();45 const actualSponsorOpt = await helpers.methods.sponsor(flipper.options.address).call();
46 expect(actualSponsorOpt.status).to.be.true;
47 const actualSponsor = actualSponsorOpt.value;
46 expect(actualSponsor.eth).to.eq(flipper.options.address);48 expect(actualSponsor.eth).to.eq(flipper.options.address);
47 expect(actualSponsor.sub).to.eq('0');49 expect(actualSponsor.sub).to.eq('0');
4850
151 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;153 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;
152154
153 // 1.1 Can get sponsor using methods.sponsor:155 // 1.1 Can get sponsor using methods.sponsor:
154 const actualSponsor = await helpers.methods.sponsor(flipper.options.address).call();156 const actualSponsorOpt = await helpers.methods.sponsor(flipper.options.address).call();
157 expect(actualSponsorOpt.status).to.be.true;
158 const actualSponsor = actualSponsorOpt.value;
155 expect(actualSponsor.eth).to.eq(sponsor);159 expect(actualSponsor.eth).to.eq(sponsor);
156 expect(actualSponsor.sub).to.eq('0');160 expect(actualSponsor.sub).to.eq('0');
157161
modifiedtests/src/eth/createFTCollection.test.tsdiffbeforeafterboth
18import {evmToAddress} from '@polkadot/util-crypto';18import {evmToAddress} from '@polkadot/util-crypto';
19import {Pallets, requirePalletsOrSkip} from '../util';19import {Pallets, requirePalletsOrSkip} from '../util';
20import {expect, itEth, usingEthPlaygrounds} from './util';20import {expect, itEth, usingEthPlaygrounds} from './util';
21import {CollectionLimits} from './util/playgrounds/types';21import {CollectionLimitField} from './util/playgrounds/types';
2222
23const DECIMALS = 18;23const DECIMALS = 18;
2424
199 }199 }
200 {200 {
201 await expect(peasantCollection.methods201 await expect(peasantCollection.methods
202 .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)202 .setCollectionLimit({field: CollectionLimitField.AccountTokenOwnership, value: {status: true, value: 1000}})
203 .call()).to.be.rejectedWith(EXPECTED_ERROR);203 .call()).to.be.rejectedWith(EXPECTED_ERROR);
204 }204 }
205 });205 });
224 }224 }
225 {225 {
226 await expect(peasantCollection.methods226 await expect(peasantCollection.methods
227 .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)227 .setCollectionLimit({field: CollectionLimitField.AccountTokenOwnership, value: {status: true, value: 1000}})
228 .call()).to.be.rejectedWith(EXPECTED_ERROR);228 .call()).to.be.rejectedWith(EXPECTED_ERROR);
229 }229 }
230 });230 });
modifiedtests/src/eth/createNFTCollection.test.tsdiffbeforeafterboth
17import {evmToAddress} from '@polkadot/util-crypto';17import {evmToAddress} from '@polkadot/util-crypto';
18import {IKeyringPair} from '@polkadot/types/types';18import {IKeyringPair} from '@polkadot/types/types';
19import {expect, itEth, usingEthPlaygrounds} from './util';19import {expect, itEth, usingEthPlaygrounds} from './util';
20import {CollectionLimits} from './util/playgrounds/types';20import {CollectionLimitField} from './util/playgrounds/types';
2121
2222
23describe('Create NFT collection from EVM', () => {23describe('Create NFT collection from EVM', () => {
210 }210 }
211 {211 {
212 await expect(malfeasantCollection.methods212 await expect(malfeasantCollection.methods
213 .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)213 .setCollectionLimit({field: CollectionLimitField.AccountTokenOwnership, value: {status: true, value: 1000}})
214 .call()).to.be.rejectedWith(EXPECTED_ERROR);214 .call()).to.be.rejectedWith(EXPECTED_ERROR);
215 }215 }
216 });216 });
235 }235 }
236 {236 {
237 await expect(malfeasantCollection.methods237 await expect(malfeasantCollection.methods
238 .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)238 .setCollectionLimit({field: CollectionLimitField.AccountTokenOwnership, value: {status: true, value: 1000}})
239 .call()).to.be.rejectedWith(EXPECTED_ERROR);239 .call()).to.be.rejectedWith(EXPECTED_ERROR);
240 }240 }
241 });241 });
modifiedtests/src/eth/createRFTCollection.test.tsdiffbeforeafterboth
18import {IKeyringPair} from '@polkadot/types/types';18import {IKeyringPair} from '@polkadot/types/types';
19import {Pallets, requirePalletsOrSkip} from '../util';19import {Pallets, requirePalletsOrSkip} from '../util';
20import {expect, itEth, usingEthPlaygrounds} from './util';20import {expect, itEth, usingEthPlaygrounds} from './util';
21import {CollectionLimits} from './util/playgrounds/types';21import {CollectionLimitField} from './util/playgrounds/types';
2222
2323
24describe('Create RFT collection from EVM', () => {24describe('Create RFT collection from EVM', () => {
242 }242 }
243 {243 {
244 await expect(peasantCollection.methods244 await expect(peasantCollection.methods
245 .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)245 .setCollectionLimit({field: CollectionLimitField.AccountTokenOwnership, value: {status: true, value: 1000}})
246 .call()).to.be.rejectedWith(EXPECTED_ERROR);246 .call()).to.be.rejectedWith(EXPECTED_ERROR);
247 }247 }
248 });248 });
267 }267 }
268 {268 {
269 await expect(peasantCollection.methods269 await expect(peasantCollection.methods
270 .setCollectionLimit(CollectionLimits.AccountTokenOwnership, true, 1000)270 .setCollectionLimit({field: CollectionLimitField.AccountTokenOwnership, value: {status: true, value: 1000}})
271 .call()).to.be.rejectedWith(EXPECTED_ERROR);271 .call()).to.be.rejectedWith(EXPECTED_ERROR);
272 }272 }
273 });273 });
modifiedtests/src/eth/events.test.tsdiffbeforeafterboth
19import {EthUniqueHelper, itEth, usingEthPlaygrounds} from './util';19import {EthUniqueHelper, itEth, usingEthPlaygrounds} from './util';
20import {IEvent, TCollectionMode} from '../util/playgrounds/types';20import {IEvent, TCollectionMode} from '../util/playgrounds/types';
21import {Pallets, requirePalletsOrSkip} from '../util';21import {Pallets, requirePalletsOrSkip} from '../util';
22import {CollectionLimits, EthTokenPermissions, NormalizedEvent} from './util/playgrounds/types';22import {CollectionLimitField, TokenPermissionField, NormalizedEvent} from './util/playgrounds/types';
2323
24let donor: IKeyringPair;24let donor: IKeyringPair;
2525
121 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['PropertyPermissionSet']}]);121 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['PropertyPermissionSet']}]);
122 await collection.methods.setTokenPropertyPermissions([122 await collection.methods.setTokenPropertyPermissions([
123 ['A', [123 ['A', [
124 [EthTokenPermissions.Mutable, true],124 [TokenPermissionField.Mutable, true],
125 [EthTokenPermissions.TokenOwner, true],125 [TokenPermissionField.TokenOwner, true],
126 [EthTokenPermissions.CollectionAdmin, true]],126 [TokenPermissionField.CollectionAdmin, true]],
127 ],127 ],
128 ]).send({from: owner});128 ]).send({from: owner});
129 await helper.wait.newBlocks(1);129 await helper.wait.newBlocks(1);
233 });233 });
234 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionLimitSet']}]);234 const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionLimitSet']}]);
235 {235 {
236 await collection.methods.setCollectionLimit(CollectionLimits.OwnerCanTransfer, true, 0).send({from: owner});236 await collection.methods.setCollectionLimit({field: CollectionLimitField.OwnerCanTransfer, value: {status: true, value: 0}}).send({from: owner});
237 await helper.wait.newBlocks(1);237 await helper.wait.newBlocks(1);
238 expect(ethEvents).to.containSubset([238 expect(ethEvents).to.containSubset([
239 {239 {
379 const tokenId = result.events.Transfer.returnValues.tokenId;379 const tokenId = result.events.Transfer.returnValues.tokenId;
380 await collection.methods.setTokenPropertyPermissions([380 await collection.methods.setTokenPropertyPermissions([
381 ['A', [381 ['A', [
382 [EthTokenPermissions.Mutable, true],382 [TokenPermissionField.Mutable, true],
383 [EthTokenPermissions.TokenOwner, true],383 [TokenPermissionField.TokenOwner, true],
384 [EthTokenPermissions.CollectionAdmin, true]],384 [TokenPermissionField.CollectionAdmin, true]],
385 ],385 ],
386 ]).send({from: owner});386 ]).send({from: owner});
387387
modifiedtests/src/eth/fractionalizer/Fractionalizer.soldiffbeforeafterboth
3import {CollectionHelpers} from "../api/CollectionHelpers.sol";3import {CollectionHelpers} from "../api/CollectionHelpers.sol";
4import {ContractHelpers} from "../api/ContractHelpers.sol";4import {ContractHelpers} from "../api/ContractHelpers.sol";
5import {UniqueRefungibleToken} from "../api/UniqueRefungibleToken.sol";5import {UniqueRefungibleToken} from "../api/UniqueRefungibleToken.sol";
6import {UniqueRefungible, EthCrossAccount} from "../api/UniqueRefungible.sol";6import {UniqueRefungible, CrossAddress} from "../api/UniqueRefungible.sol";
7import {UniqueNFT} from "../api/UniqueNFT.sol";7import {UniqueNFT} from "../api/UniqueNFT.sol";
88
9/// @dev Fractionalization contract. It stores mappings between NFT and RFT tokens,9/// @dev Fractionalization contract. It stores mappings between NFT and RFT tokens,
63 "Wrong collection type. Collection is not refungible."63 "Wrong collection type. Collection is not refungible."
64 );64 );
65 require(65 require(
66 refungibleContract.isOwnerOrAdminCross(EthCrossAccount({eth: address(this), sub: uint256(0)})),66 refungibleContract.isOwnerOrAdminCross(CrossAddress({eth: address(this), sub: uint256(0)})),
67 "Fractionalizer contract should be an admin of the collection"67 "Fractionalizer contract should be an admin of the collection"
68 );68 );
69 rftCollection = _collection;69 rftCollection = _collection;
modifiedtests/src/eth/tokenProperties.test.tsdiffbeforeafterboth
20import {ITokenPropertyPermission} from '../util/playgrounds/types';20import {ITokenPropertyPermission} from '../util/playgrounds/types';
21import {Pallets} from '../util';21import {Pallets} from '../util';
22import {UniqueNFTCollection, UniqueNFToken, UniqueRFTCollection} from '../util/playgrounds/unique';22import {UniqueNFTCollection, UniqueNFToken, UniqueRFTCollection} from '../util/playgrounds/unique';
23import {EthTokenPermissions} from './util/playgrounds/types';23import {TokenPermissionField} from './util/playgrounds/types';
2424
25describe('EVM token properties', () => {25describe('EVM token properties', () => {
26 let donor: IKeyringPair;26 let donor: IKeyringPair;
4747
48 await collection.methods.setTokenPropertyPermissions([48 await collection.methods.setTokenPropertyPermissions([
49 ['testKey', [49 ['testKey', [
50 [EthTokenPermissions.Mutable, mutable],50 [TokenPermissionField.Mutable, mutable],
51 [EthTokenPermissions.TokenOwner, tokenOwner],51 [TokenPermissionField.TokenOwner, tokenOwner],
52 [EthTokenPermissions.CollectionAdmin, collectionAdmin]],52 [TokenPermissionField.CollectionAdmin, collectionAdmin]],
53 ],53 ],
54 ]).send({from: caller.eth});54 ]).send({from: caller.eth});
5555
6060
61 expect(await collection.methods.tokenPropertyPermissions().call({from: caller.eth})).to.be.like([61 expect(await collection.methods.tokenPropertyPermissions().call({from: caller.eth})).to.be.like([
62 ['testKey', [62 ['testKey', [
63 [EthTokenPermissions.Mutable.toString(), mutable],63 [TokenPermissionField.Mutable.toString(), mutable],
64 [EthTokenPermissions.TokenOwner.toString(), tokenOwner],64 [TokenPermissionField.TokenOwner.toString(), tokenOwner],
65 [EthTokenPermissions.CollectionAdmin.toString(), collectionAdmin]],65 [TokenPermissionField.CollectionAdmin.toString(), collectionAdmin]],
66 ],66 ],
67 ]);67 ]);
68 }68 }
8080
81 await collection.methods.setTokenPropertyPermissions([81 await collection.methods.setTokenPropertyPermissions([
82 ['testKey_0', [82 ['testKey_0', [
83 [EthTokenPermissions.Mutable, true],83 [TokenPermissionField.Mutable, true],
84 [EthTokenPermissions.TokenOwner, true],84 [TokenPermissionField.TokenOwner, true],
85 [EthTokenPermissions.CollectionAdmin, true]],85 [TokenPermissionField.CollectionAdmin, true]],
86 ],86 ],
87 ['testKey_1', [87 ['testKey_1', [
88 [EthTokenPermissions.Mutable, true],88 [TokenPermissionField.Mutable, true],
89 [EthTokenPermissions.TokenOwner, false],89 [TokenPermissionField.TokenOwner, false],
90 [EthTokenPermissions.CollectionAdmin, true]],90 [TokenPermissionField.CollectionAdmin, true]],
91 ],91 ],
92 ['testKey_2', [92 ['testKey_2', [
93 [EthTokenPermissions.Mutable, false],93 [TokenPermissionField.Mutable, false],
94 [EthTokenPermissions.TokenOwner, true],94 [TokenPermissionField.TokenOwner, true],
95 [EthTokenPermissions.CollectionAdmin, false]],95 [TokenPermissionField.CollectionAdmin, false]],
96 ],96 ],
97 ]).send({from: owner});97 ]).send({from: owner});
9898
113113
114 expect(await collection.methods.tokenPropertyPermissions().call({from: owner})).to.be.like([114 expect(await collection.methods.tokenPropertyPermissions().call({from: owner})).to.be.like([
115 ['testKey_0', [115 ['testKey_0', [
116 [EthTokenPermissions.Mutable.toString(), true],116 [TokenPermissionField.Mutable.toString(), true],
117 [EthTokenPermissions.TokenOwner.toString(), true],117 [TokenPermissionField.TokenOwner.toString(), true],
118 [EthTokenPermissions.CollectionAdmin.toString(), true]],118 [TokenPermissionField.CollectionAdmin.toString(), true]],
119 ],119 ],
120 ['testKey_1', [120 ['testKey_1', [
121 [EthTokenPermissions.Mutable.toString(), true],121 [TokenPermissionField.Mutable.toString(), true],
122 [EthTokenPermissions.TokenOwner.toString(), false],122 [TokenPermissionField.TokenOwner.toString(), false],
123 [EthTokenPermissions.CollectionAdmin.toString(), true]],123 [TokenPermissionField.CollectionAdmin.toString(), true]],
124 ],124 ],
125 ['testKey_2', [125 ['testKey_2', [
126 [EthTokenPermissions.Mutable.toString(), false],126 [TokenPermissionField.Mutable.toString(), false],
127 [EthTokenPermissions.TokenOwner.toString(), true],127 [TokenPermissionField.TokenOwner.toString(), true],
128 [EthTokenPermissions.CollectionAdmin.toString(), false]],128 [TokenPermissionField.CollectionAdmin.toString(), false]],
129 ],129 ],
130 ]);130 ]);
131 }));131 }));
144144
145 await collection.methods.setTokenPropertyPermissions([145 await collection.methods.setTokenPropertyPermissions([
146 ['testKey_0', [146 ['testKey_0', [
147 [EthTokenPermissions.Mutable, true],147 [TokenPermissionField.Mutable, true],
148 [EthTokenPermissions.TokenOwner, true],148 [TokenPermissionField.TokenOwner, true],
149 [EthTokenPermissions.CollectionAdmin, true]],149 [TokenPermissionField.CollectionAdmin, true]],
150 ],150 ],
151 ['testKey_1', [151 ['testKey_1', [
152 [EthTokenPermissions.Mutable, true],152 [TokenPermissionField.Mutable, true],
153 [EthTokenPermissions.TokenOwner, false],153 [TokenPermissionField.TokenOwner, false],
154 [EthTokenPermissions.CollectionAdmin, true]],154 [TokenPermissionField.CollectionAdmin, true]],
155 ],155 ],
156 ['testKey_2', [156 ['testKey_2', [
157 [EthTokenPermissions.Mutable, false],157 [TokenPermissionField.Mutable, false],
158 [EthTokenPermissions.TokenOwner, true],158 [TokenPermissionField.TokenOwner, true],
159 [EthTokenPermissions.CollectionAdmin, false]],159 [TokenPermissionField.CollectionAdmin, false]],
160 ],160 ],
161 ]).send({from: caller.eth});161 ]).send({from: caller.eth});
162162
177177
178 expect(await collection.methods.tokenPropertyPermissions().call({from: caller.eth})).to.be.like([178 expect(await collection.methods.tokenPropertyPermissions().call({from: caller.eth})).to.be.like([
179 ['testKey_0', [179 ['testKey_0', [
180 [EthTokenPermissions.Mutable.toString(), true],180 [TokenPermissionField.Mutable.toString(), true],
181 [EthTokenPermissions.TokenOwner.toString(), true],181 [TokenPermissionField.TokenOwner.toString(), true],
182 [EthTokenPermissions.CollectionAdmin.toString(), true]],182 [TokenPermissionField.CollectionAdmin.toString(), true]],
183 ],183 ],
184 ['testKey_1', [184 ['testKey_1', [
185 [EthTokenPermissions.Mutable.toString(), true],185 [TokenPermissionField.Mutable.toString(), true],
186 [EthTokenPermissions.TokenOwner.toString(), false],186 [TokenPermissionField.TokenOwner.toString(), false],
187 [EthTokenPermissions.CollectionAdmin.toString(), true]],187 [TokenPermissionField.CollectionAdmin.toString(), true]],
188 ],188 ],
189 ['testKey_2', [189 ['testKey_2', [
190 [EthTokenPermissions.Mutable.toString(), false],190 [TokenPermissionField.Mutable.toString(), false],
191 [EthTokenPermissions.TokenOwner.toString(), true],191 [TokenPermissionField.TokenOwner.toString(), true],
192 [EthTokenPermissions.CollectionAdmin.toString(), false]],192 [TokenPermissionField.CollectionAdmin.toString(), false]],
193 ],193 ],
194 ]);194 ]);
195195
460460
461 await expect(collection.methods.setTokenPropertyPermissions([461 await expect(collection.methods.setTokenPropertyPermissions([
462 ['testKey_0', [462 ['testKey_0', [
463 [EthTokenPermissions.Mutable, true],463 [TokenPermissionField.Mutable, true],
464 [EthTokenPermissions.TokenOwner, true],464 [TokenPermissionField.TokenOwner, true],
465 [EthTokenPermissions.CollectionAdmin, true]],465 [TokenPermissionField.CollectionAdmin, true]],
466 ],466 ],
467 ]).call({from: caller})).to.be.rejectedWith('NoPermission');467 ]).call({from: caller})).to.be.rejectedWith('NoPermission');
468 }));468 }));
480 await expect(collection.methods.setTokenPropertyPermissions([480 await expect(collection.methods.setTokenPropertyPermissions([
481 // "Space" is invalid character481 // "Space" is invalid character
482 ['testKey 0', [482 ['testKey 0', [
483 [EthTokenPermissions.Mutable, true],483 [TokenPermissionField.Mutable, true],
484 [EthTokenPermissions.TokenOwner, true],484 [TokenPermissionField.TokenOwner, true],
485 [EthTokenPermissions.CollectionAdmin, true]],485 [TokenPermissionField.CollectionAdmin, true]],
486 ],486 ],
487 ]).call({from: owner})).to.be.rejectedWith('InvalidCharacterInPropertyKey');487 ]).call({from: owner})).to.be.rejectedWith('InvalidCharacterInPropertyKey');
488 }));488 }));
500 // 1. Owner sets strict property-permissions:500 // 1. Owner sets strict property-permissions:
501 await collection.methods.setTokenPropertyPermissions([501 await collection.methods.setTokenPropertyPermissions([
502 ['testKey', [502 ['testKey', [
503 [EthTokenPermissions.Mutable, true],503 [TokenPermissionField.Mutable, true],
504 [EthTokenPermissions.TokenOwner, true],504 [TokenPermissionField.TokenOwner, true],
505 [EthTokenPermissions.CollectionAdmin, true]],505 [TokenPermissionField.CollectionAdmin, true]],
506 ],506 ],
507 ]).send({from: owner});507 ]).send({from: owner});
508508
509 // 2. Owner can set stricter property-permissions:509 // 2. Owner can set stricter property-permissions:
510 for(const values of [[true, true, false], [true, false, false], [false, false, false]]) {510 for(const values of [[true, true, false], [true, false, false], [false, false, false]]) {
511 await collection.methods.setTokenPropertyPermissions([511 await collection.methods.setTokenPropertyPermissions([
512 ['testKey', [512 ['testKey', [
513 [EthTokenPermissions.Mutable, values[0]],513 [TokenPermissionField.Mutable, values[0]],
514 [EthTokenPermissions.TokenOwner, values[1]],514 [TokenPermissionField.TokenOwner, values[1]],
515 [EthTokenPermissions.CollectionAdmin, values[2]]],515 [TokenPermissionField.CollectionAdmin, values[2]]],
516 ],516 ],
517 ]).send({from: owner});517 ]).send({from: owner});
518 }518 }
536 // 1. Owner sets strict property-permissions:536 // 1. Owner sets strict property-permissions:
537 await collection.methods.setTokenPropertyPermissions([537 await collection.methods.setTokenPropertyPermissions([
538 ['testKey', [538 ['testKey', [
539 [EthTokenPermissions.Mutable, false],539 [TokenPermissionField.Mutable, false],
540 [EthTokenPermissions.TokenOwner, false],540 [TokenPermissionField.TokenOwner, false],
541 [EthTokenPermissions.CollectionAdmin, false]],541 [TokenPermissionField.CollectionAdmin, false]],
542 ],542 ],
543 ]).send({from: owner});543 ]).send({from: owner});
544544
545 // 2. Owner cannot set less strict property-permissions:545 // 2. Owner cannot set less strict property-permissions:
546 for(const values of [[true, false, false], [false, true, false], [false, false, true]]) {546 for(const values of [[true, false, false], [false, true, false], [false, false, true]]) {
547 await expect(collection.methods.setTokenPropertyPermissions([547 await expect(collection.methods.setTokenPropertyPermissions([
548 ['testKey', [548 ['testKey', [
549 [EthTokenPermissions.Mutable, values[0]],549 [TokenPermissionField.Mutable, values[0]],
550 [EthTokenPermissions.TokenOwner, values[1]],550 [TokenPermissionField.TokenOwner, values[1]],
551 [EthTokenPermissions.CollectionAdmin, values[2]]],551 [TokenPermissionField.CollectionAdmin, values[2]]],
552 ],552 ],
553 ]).call({from: owner})).to.be.rejectedWith('NoPermission');553 ]).call({from: owner})).to.be.rejectedWith('NoPermission');
554 }554 }
modifiedtests/src/eth/util/playgrounds/types.tsdiffbeforeafterboth
14 args: { [key: string]: string }14 args: { [key: string]: string }
15};15};
16
17export interface OptionUint {
18 status: boolean,
19 value: bigint,
20}
21
16export interface TEthCrossAccount {22export interface CrossAddress {
17 readonly eth: string,23 readonly eth: string,
18 readonly sub: string | Uint8Array,24 readonly sub: string | Uint8Array,
19}25}
2026
21export type EthProperty = string[];27export type EthProperty = string[];
2228
23export enum EthTokenPermissions {29export enum TokenPermissionField {
24 Mutable,30 Mutable,
25 TokenOwner,31 TokenOwner,
26 CollectionAdmin32 CollectionAdmin
27}33}
34
28export enum CollectionLimits {35export enum CollectionLimitField {
29 AccountTokenOwnership,36 AccountTokenOwnership,
30 SponsoredDataSize,37 SponsoredDataSize,
31 SponsoredDataRateLimit,38 SponsoredDataRateLimit,
37 TransferEnabled44 TransferEnabled
38}45}
46
47export interface CollectionLimit {
48 field: CollectionLimitField,
49 value: OptionUint,
50}
3951
modifiedtests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth
1818
19import {DevUniqueHelper} from '../../../util/playgrounds/unique.dev';19import {DevUniqueHelper} from '../../../util/playgrounds/unique.dev';
2020
21import {ContractImports, CompiledContract, TEthCrossAccount, NormalizedEvent, EthProperty} from './types';21import {ContractImports, CompiledContract, CrossAddress, NormalizedEvent, EthProperty} from './types';
2222
23// Native contracts ABI23// Native contracts ABI
24import collectionHelpersAbi from '../../abi/collectionHelpers.json';24import collectionHelpersAbi from '../../abi/collectionHelpers.json';
435export type EthUniqueHelperConstructor = new (...args: any[]) => EthUniqueHelper;435export type EthUniqueHelperConstructor = new (...args: any[]) => EthUniqueHelper;
436436
437export class EthCrossAccountGroup extends EthGroupBase {437export class EthCrossAccountGroup extends EthGroupBase {
438 createAccount(): TEthCrossAccount {438 createAccount(): CrossAddress {
439 return this.fromAddress(this.helper.eth.createAccount());439 return this.fromAddress(this.helper.eth.createAccount());
440 }440 }
441441
442 async createAccountWithBalance(donor: IKeyringPair, amount=100n) {442 async createAccountWithBalance(donor: IKeyringPair, amount=100n) {
443 return this.fromAddress(await this.helper.eth.createAccountWithBalance(donor, amount));443 return this.fromAddress(await this.helper.eth.createAccountWithBalance(donor, amount));
444 }444 }
445445
446 fromAddress(address: TEthereumAccount): TEthCrossAccount {446 fromAddress(address: TEthereumAccount): CrossAddress {
447 return {447 return {
448 eth: address,448 eth: address,
449 sub: '0',449 sub: '0',
450 };450 };
451 }451 }
452452
453 fromKeyringPair(keyring: IKeyringPair): TEthCrossAccount {453 fromKeyringPair(keyring: IKeyringPair): CrossAddress {
454 return {454 return {
455 eth: '0x0000000000000000000000000000000000000000',455 eth: '0x0000000000000000000000000000000000000000',
456 sub: keyring.addressRaw,456 sub: keyring.addressRaw,