From 8298cf82947926e8175ddaf52824c5730f563ec9 Mon Sep 17 00:00:00 2001 From: Trubnikov Sergey Date: Mon, 19 Dec 2022 17:14:34 +0000 Subject: [PATCH] feat: Rewrite tuple to named structures for TokenPropertyPermission. fix: AbiCoder derive macro --- --- a/crates/evm-coder/procedural/src/abi_derive/derive_enum.rs +++ b/crates/evm-coder/procedural/src/abi_derive/derive_enum.rs @@ -86,6 +86,21 @@ ) } +pub fn impl_enum_solidity_type<'a>(name: &syn::Ident) -> proc_macro2::TokenStream { + quote! { + #[cfg(feature = "stubgen")] + impl ::evm_coder::solidity::SolidityType for #name { + fn names(tc: &::evm_coder::solidity::TypeCollector) -> Vec { + Vec::new() + } + + fn len() -> usize { + 1 + } + } + } +} + pub fn impl_enum_solidity_type_name(name: &syn::Ident) -> proc_macro2::TokenStream { quote!( #[cfg(feature = "stubgen")] --- a/crates/evm-coder/procedural/src/abi_derive/mod.rs +++ b/crates/evm-coder/procedural/src/abi_derive/mod.rs @@ -86,6 +86,7 @@ let abi_type = impl_enum_abi_type(name, option_count); let abi_read = impl_enum_abi_read(name); let abi_write = impl_enum_abi_write(name); + let solidity_type = impl_enum_solidity_type(name); let solidity_type_name = impl_enum_solidity_type_name(name); let solidity_struct_collect = impl_enum_solidity_struct_collect( name, @@ -102,6 +103,7 @@ #abi_type #abi_read #abi_write + #solidity_type #solidity_type_name #solidity_struct_collect }) --- a/crates/evm-coder/src/abi/impls.rs +++ b/crates/evm-coder/src/abi/impls.rs @@ -184,6 +184,11 @@ } } +macro_rules! count { + () => (0usize); + ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*)); +} + macro_rules! impl_tuples { ($($ident:ident)+) => { impl<$($ident: AbiType,)+> AbiType for ($($ident,)+) @@ -198,7 +203,7 @@ shift_left(1) fixed(")") ); - const FIELDS_COUNT: usize = 0 $(+ {let _ = <$ident as AbiType>::FIELDS_COUNT; 1})+; + const FIELDS_COUNT: usize = count!($($ident)*); fn is_dynamic() -> bool { false --- a/crates/evm-coder/src/solidity/impls.rs +++ b/crates/evm-coder/src/solidity/impls.rs @@ -74,6 +74,16 @@ } } +impl StructCollect for Vec { + fn name() -> String { + ::name() + "[]" + } + + fn declaration() -> String { + unimplemented!("Vectors have not declarations.") + } +} + macro_rules! count { () => (0usize); ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*)); @@ -131,60 +141,3 @@ impl_tuples! {A B C D E F G H} impl_tuples! {A B C D E F G H I} impl_tuples! {A B C D E F G H I J} - -impl StructCollect for Property { - fn name() -> String { - "Property".into() - } - - fn declaration() -> String { - use std::fmt::Write; - - let mut str = String::new(); - writeln!(str, "/// @dev Property struct").unwrap(); - writeln!(str, "struct {} {{", Self::name()).unwrap(); - writeln!(str, "\tstring key;").unwrap(); - writeln!(str, "\tbytes value;").unwrap(); - writeln!(str, "}}").unwrap(); - str - } -} - -impl SolidityTypeName for Property { - fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result { - write!(writer, "{}", tc.collect_struct::()) - } - - fn is_simple() -> bool { - false - } - - fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result { - write!(writer, "{}(", tc.collect_struct::())?; - address::solidity_default(writer, tc)?; - write!(writer, ",")?; - uint256::solidity_default(writer, tc)?; - write!(writer, ")") - } -} - -impl SolidityType for Property { - fn names(tc: &TypeCollector) -> Vec { - let mut collected = Vec::with_capacity(Self::len()); - { - let mut out = string::new(); - string::solidity_name(&mut out, tc).expect("no fmt error"); - collected.push(out); - } - { - let mut out = string::new(); - bytes::solidity_name(&mut out, tc).expect("no fmt error"); - collected.push(out); - } - collected - } - - fn len() -> usize { - 2 - } -} --- a/crates/evm-coder/src/solidity/mod.rs +++ b/crates/evm-coder/src/solidity/mod.rs @@ -76,7 +76,8 @@ self.anonymous.borrow_mut().insert(names, id); format!("Tuple{}", id) } - pub fn collect_struct(&self) -> String { + pub fn collect_struct(&self) -> String { + let _names = T::names(self); self.collect(::declaration()); ::name() } --- a/crates/evm-coder/tests/abi_derive_generation.rs +++ b/crates/evm-coder/tests/abi_derive_generation.rs @@ -100,6 +100,15 @@ } #[test] + #[cfg(feature = "stubgen")] + fn struct_collect_vec() { + assert_eq!( + as ::evm_coder::solidity::StructCollect>::name(), + "uint8[]" + ); + } + + #[test] fn impl_abi_type_signature() { assert_eq!( ::SIGNATURE --- a/pallets/common/src/eth.rs +++ b/pallets/common/src/eth.rs @@ -16,6 +16,7 @@ //! The module contains a number of functions for converting and checking ethereum identifiers. +use sp_std::{vec, vec::Vec}; use evm_coder::{ AbiCoder, types::{uint256, address}, @@ -183,3 +184,102 @@ /// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`] CollectionAdmin, } + +/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value. +#[derive(Debug, Default, AbiCoder)] +pub struct PropertyPermission { + /// TokenPermission field. + code: EthTokenPermissions, + /// TokenPermission value. + value: bool, +} + +impl PropertyPermission { + pub fn into_vec(pp: up_data_structs::PropertyPermission) -> Vec { + vec![ + PropertyPermission { + code: EthTokenPermissions::Mutable, + value: pp.mutable, + }, + PropertyPermission { + code: EthTokenPermissions::TokenOwner, + value: pp.token_owner, + }, + PropertyPermission { + code: EthTokenPermissions::CollectionAdmin, + value: pp.collection_admin, + }, + ] + } + + pub fn from_vec(permission: Vec) -> up_data_structs::PropertyPermission { + let mut token_permission = up_data_structs::PropertyPermission::default(); + + for PropertyPermission { code, value } in permission { + match code { + EthTokenPermissions::Mutable => token_permission.mutable = value, + EthTokenPermissions::TokenOwner => token_permission.token_owner = value, + EthTokenPermissions::CollectionAdmin => token_permission.collection_admin = value, + } + } + token_permission + } +} + +/// Ethereum representation of Token Property Permissions. +#[derive(Debug, Default, AbiCoder)] +pub struct TokenPropertyPermission { + /// Token property key. + key: evm_coder::types::string, + /// Token property permissions. + permissions: Vec, +} + +impl + From<( + up_data_structs::PropertyKey, + up_data_structs::PropertyPermission, + )> for TokenPropertyPermission +{ + fn from( + value: ( + up_data_structs::PropertyKey, + up_data_structs::PropertyPermission, + ), + ) -> Self { + let (key, permission) = value; + let key = evm_coder::types::string::from_utf8(key.into_inner()) + .expect("Stored key must be valid"); + let permissions = PropertyPermission::into_vec(permission); + Self { key, permissions } + } +} + +impl TokenPropertyPermission { + pub fn into_property_key_permissions( + permissions: Vec, + ) -> evm_coder::execution::Result> { + let mut perms = Vec::new(); + + for TokenPropertyPermission { key, permissions } in permissions { + if permissions.len() > ::FIELDS_COUNT { + return Err(alloc::format!( + "Actual number of fields {} for {}, which exceeds the maximum value of {}", + permissions.len(), + stringify!(EthTokenPermissions), + ::FIELDS_COUNT + ) + .as_str() + .into()); + } + + let token_permission = PropertyPermission::from_vec(permissions); + + perms.push(up_data_structs::PropertyKeyPermission { + key: key.into_bytes().try_into().map_err(|_| "too long key")?, + permission: token_permission, + }); + } + Ok(perms) + } +} --- a/pallets/fungible/src/stubs/UniqueFungible.sol +++ b/pallets/fungible/src/stubs/UniqueFungible.sol @@ -470,9 +470,12 @@ uint256 sub; } +/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration. enum CollectionPermissions { - CollectionAdmin, - TokenOwner + /// @dev Owner of token can nest tokens under it. + TokenOwner, + /// @dev Admin of token collection can nest tokens under token. + CollectionAdmin } /// @dev anonymous struct @@ -516,9 +519,11 @@ uint256 field_2; } -/// @dev Property struct +/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue). struct Property { + /// @dev Property key. string key; + /// @dev Property value. bytes value; } --- a/pallets/nonfungible/src/erc.rs +++ b/pallets/nonfungible/src/erc.rs @@ -38,7 +38,7 @@ use pallet_common::{ CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations, erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key}, - eth::{Property as PropertyStruct, EthCrossAccount, EthTokenPermissions}, + eth::{Property as PropertyStruct, EthCrossAccount}, }; use pallet_evm::{account::CrossAccountId, PrecompileHandle}; use pallet_evm_coder_substrate::call; @@ -94,40 +94,12 @@ fn set_token_property_permissions( &mut self, caller: caller, - permissions: Vec<(string, Vec<(EthTokenPermissions, bool)>)>, + permissions: Vec, ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); - let mut perms = Vec::new(); - - for (key, pp) in permissions { - if pp.len() > EthTokenPermissions::FIELDS_COUNT { - return Err(alloc::format!( - "Actual number of fields {} for {}, which exceeds the maximum value of {}", - pp.len(), - stringify!(EthTokenPermissions), - EthTokenPermissions::FIELDS_COUNT - ) - .as_str() - .into()); - } - - let mut token_permission = PropertyPermission::default(); - - for (perm, value) in pp { - match perm { - EthTokenPermissions::Mutable => token_permission.mutable = value, - EthTokenPermissions::TokenOwner => token_permission.token_owner = value, - EthTokenPermissions::CollectionAdmin => { - token_permission.collection_admin = value - } - } - } - - perms.push(PropertyKeyPermission { - key: key.into_bytes().try_into().map_err(|_| "too long key")?, - permission: token_permission, - }); - } + let perms = pallet_common::eth::TokenPropertyPermission::into_property_key_permissions( + permissions, + )?; >::set_token_property_permissions(self, &caller, perms) .map_err(dispatch_to_evm::) @@ -136,19 +108,11 @@ /// @notice Get permissions for token properties. fn token_property_permissions( &self, - ) -> Result)>> { + ) -> Result> { let perms = >::token_property_permission(self.id); Ok(perms .into_iter() - .map(|(key, pp)| { - let key = string::from_utf8(key.into_inner()).expect("Stored key must be valid"); - let pp = vec![ - (EthTokenPermissions::Mutable, pp.mutable), - (EthTokenPermissions::TokenOwner, pp.token_owner), - (EthTokenPermissions::CollectionAdmin, pp.collection_admin), - ]; - (key, pp) - }) + .map(pallet_common::eth::TokenPropertyPermission::from) .collect()) } --- a/pallets/nonfungible/src/stubs/UniqueNFT.sol +++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol @@ -42,7 +42,7 @@ /// @param permissions Permissions for keys. /// @dev EVM selector for this function is: 0xbd92983a, /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[]) - function setTokenPropertyPermissions(Tuple61[] memory permissions) public { + function setTokenPropertyPermissions(TokenPropertyPermission[] memory permissions) public { require(false, stub_error); permissions; dummy = 0; @@ -51,10 +51,10 @@ /// @notice Get permissions for token properties. /// @dev EVM selector for this function is: 0xf23d7790, /// or in textual repr: tokenPropertyPermissions() - function tokenPropertyPermissions() public view returns (Tuple61[] memory) { + function tokenPropertyPermissions() public view returns (TokenPropertyPermission[] memory) { require(false, stub_error); dummy; - return new Tuple61[](0); + return new TokenPropertyPermission[](0); } // /// @notice Set token property value. @@ -127,12 +127,30 @@ } } -/// @dev Property struct +/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue). struct Property { + /// @dev Property key. string key; + /// @dev Property value. bytes value; } +/// @dev Ethereum representation of Token Property Permissions. +struct TokenPropertyPermission { + /// @dev Token property key. + string key; + /// @dev Token property permissions. + PropertyPermission[] permissions; +} + +/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value. +struct PropertyPermission { + /// @dev TokenPermission field. + EthTokenPermissions code; + /// @dev TokenPermission value. + bool value; +} + /// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration. enum EthTokenPermissions { /// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`] @@ -141,18 +159,6 @@ TokenOwner, /// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`] CollectionAdmin -} - -/// @dev anonymous struct -struct Tuple61 { - string field_0; - Tuple59[] field_1; -} - -/// @dev anonymous struct -struct Tuple59 { - EthTokenPermissions field_0; - bool field_1; } /// @title A contract that allows you to work with collections. @@ -608,9 +614,12 @@ uint256 sub; } +/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration. enum CollectionPermissions { - CollectionAdmin, - TokenOwner + /// @dev Owner of token can nest tokens under it. + TokenOwner, + /// @dev Admin of token collection can nest tokens under token. + CollectionAdmin } /// @dev anonymous struct --- a/pallets/refungible/src/erc.rs +++ b/pallets/refungible/src/erc.rs @@ -33,7 +33,7 @@ use pallet_common::{ CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations, erc::{CommonEvmHandler, CollectionCall, static_property::key}, - eth::{Property as PropertyStruct, EthCrossAccount, EthTokenPermissions}, + eth::{Property as PropertyStruct, EthCrossAccount}, Error as CommonError, }; use pallet_evm::{account::CrossAccountId, PrecompileHandle}; @@ -97,47 +97,13 @@ fn set_token_property_permissions( &mut self, caller: caller, - permissions: Vec<(string, Vec<(EthTokenPermissions, bool)>)>, + permissions: Vec, ) -> Result<()> { let caller = T::CrossAccountId::from_eth(caller); - const PERMISSIONS_FIELDS_COUNT: usize = 3; - - let mut perms = Vec::new(); - - for (key, pp) in permissions { - if pp.len() > PERMISSIONS_FIELDS_COUNT { - return Err(alloc::format!( - "Actual number of fields {} for {}, which exceeds the maximum value of {}", - pp.len(), - stringify!(EthTokenPermissions), - PERMISSIONS_FIELDS_COUNT - ) - .as_str() - .into()); - } - - let mut token_permission = PropertyPermission { - mutable: false, - collection_admin: false, - token_owner: false, - }; + let perms = pallet_common::eth::TokenPropertyPermission::into_property_key_permissions( + permissions, + )?; - for (perm, value) in pp { - match perm { - EthTokenPermissions::Mutable => token_permission.mutable = value, - EthTokenPermissions::TokenOwner => token_permission.token_owner = value, - EthTokenPermissions::CollectionAdmin => { - token_permission.collection_admin = value - } - } - } - - perms.push(PropertyKeyPermission { - key: key.into_bytes().try_into().map_err(|_| "too long key")?, - permission: token_permission, - }); - } - >::set_token_property_permissions(self, &caller, perms) .map_err(dispatch_to_evm::) } @@ -145,19 +111,11 @@ /// @notice Get permissions for token properties. fn token_property_permissions( &self, - ) -> Result)>> { + ) -> Result> { let perms = >::token_property_permission(self.id); Ok(perms .into_iter() - .map(|(key, pp)| { - let key = string::from_utf8(key.into_inner()).expect("Stored key must be valid"); - let pp = vec![ - (EthTokenPermissions::Mutable, pp.mutable), - (EthTokenPermissions::TokenOwner, pp.token_owner), - (EthTokenPermissions::CollectionAdmin, pp.collection_admin), - ]; - (key, pp) - }) + .map(pallet_common::eth::TokenPropertyPermission::from) .collect()) } --- a/pallets/refungible/src/stubs/UniqueRefungible.sol +++ b/pallets/refungible/src/stubs/UniqueRefungible.sol @@ -42,7 +42,7 @@ /// @param permissions Permissions for keys. /// @dev EVM selector for this function is: 0xbd92983a, /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[]) - function setTokenPropertyPermissions(Tuple60[] memory permissions) public { + function setTokenPropertyPermissions(TokenPropertyPermission[] memory permissions) public { require(false, stub_error); permissions; dummy = 0; @@ -51,10 +51,10 @@ /// @notice Get permissions for token properties. /// @dev EVM selector for this function is: 0xf23d7790, /// or in textual repr: tokenPropertyPermissions() - function tokenPropertyPermissions() public view returns (Tuple60[] memory) { + function tokenPropertyPermissions() public view returns (TokenPropertyPermission[] memory) { require(false, stub_error); dummy; - return new Tuple60[](0); + return new TokenPropertyPermission[](0); } // /// @notice Set token property value. @@ -127,12 +127,30 @@ } } -/// @dev Property struct +/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue). struct Property { + /// @dev Property key. string key; + /// @dev Property value. bytes value; } +/// @dev Ethereum representation of Token Property Permissions. +struct TokenPropertyPermission { + /// @dev Token property key. + string key; + /// @dev Token property permissions. + PropertyPermission[] permissions; +} + +/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value. +struct PropertyPermission { + /// @dev TokenPermission field. + EthTokenPermissions code; + /// @dev TokenPermission value. + bool value; +} + /// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration. enum EthTokenPermissions { /// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`] @@ -141,18 +159,6 @@ TokenOwner, /// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`] CollectionAdmin -} - -/// @dev anonymous struct -struct Tuple60 { - string field_0; - Tuple58[] field_1; -} - -/// @dev anonymous struct -struct Tuple58 { - EthTokenPermissions field_0; - bool field_1; } /// @title A contract that allows you to work with collections. @@ -608,9 +614,12 @@ uint256 sub; } +/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration. enum CollectionPermissions { - CollectionAdmin, - TokenOwner + /// @dev Owner of token can nest tokens under it. + TokenOwner, + /// @dev Admin of token collection can nest tokens under token. + CollectionAdmin } /// @dev anonymous struct --- a/tests/src/eth/abi/nonFungible.json +++ b/tests/src/eth/abi/nonFungible.json @@ -752,22 +752,22 @@ "inputs": [ { "components": [ - { "internalType": "string", "name": "field_0", "type": "string" }, + { "internalType": "string", "name": "key", "type": "string" }, { "components": [ { "internalType": "enum EthTokenPermissions", - "name": "field_0", + "name": "code", "type": "uint8" }, - { "internalType": "bool", "name": "field_1", "type": "bool" } + { "internalType": "bool", "name": "value", "type": "bool" } ], - "internalType": "struct Tuple59[]", - "name": "field_1", + "internalType": "struct PropertyPermission[]", + "name": "permissions", "type": "tuple[]" } ], - "internalType": "struct Tuple61[]", + "internalType": "struct TokenPropertyPermission[]", "name": "permissions", "type": "tuple[]" } @@ -818,22 +818,22 @@ "outputs": [ { "components": [ - { "internalType": "string", "name": "field_0", "type": "string" }, + { "internalType": "string", "name": "key", "type": "string" }, { "components": [ { "internalType": "enum EthTokenPermissions", - "name": "field_0", + "name": "code", "type": "uint8" }, - { "internalType": "bool", "name": "field_1", "type": "bool" } + { "internalType": "bool", "name": "value", "type": "bool" } ], - "internalType": "struct Tuple59[]", - "name": "field_1", + "internalType": "struct PropertyPermission[]", + "name": "permissions", "type": "tuple[]" } ], - "internalType": "struct Tuple61[]", + "internalType": "struct TokenPropertyPermission[]", "name": "", "type": "tuple[]" } --- a/tests/src/eth/abi/reFungible.json +++ b/tests/src/eth/abi/reFungible.json @@ -734,22 +734,22 @@ "inputs": [ { "components": [ - { "internalType": "string", "name": "field_0", "type": "string" }, + { "internalType": "string", "name": "key", "type": "string" }, { "components": [ { "internalType": "enum EthTokenPermissions", - "name": "field_0", + "name": "code", "type": "uint8" }, - { "internalType": "bool", "name": "field_1", "type": "bool" } + { "internalType": "bool", "name": "value", "type": "bool" } ], - "internalType": "struct Tuple58[]", - "name": "field_1", + "internalType": "struct PropertyPermission[]", + "name": "permissions", "type": "tuple[]" } ], - "internalType": "struct Tuple60[]", + "internalType": "struct TokenPropertyPermission[]", "name": "permissions", "type": "tuple[]" } @@ -809,22 +809,22 @@ "outputs": [ { "components": [ - { "internalType": "string", "name": "field_0", "type": "string" }, + { "internalType": "string", "name": "key", "type": "string" }, { "components": [ { "internalType": "enum EthTokenPermissions", - "name": "field_0", + "name": "code", "type": "uint8" }, - { "internalType": "bool", "name": "field_1", "type": "bool" } + { "internalType": "bool", "name": "value", "type": "bool" } ], - "internalType": "struct Tuple58[]", - "name": "field_1", + "internalType": "struct PropertyPermission[]", + "name": "permissions", "type": "tuple[]" } ], - "internalType": "struct Tuple60[]", + "internalType": "struct TokenPropertyPermission[]", "name": "", "type": "tuple[]" } --- a/tests/src/eth/api/UniqueFungible.sol +++ b/tests/src/eth/api/UniqueFungible.sol @@ -316,9 +316,12 @@ bool field_1; } +/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration. enum CollectionPermissions { - CollectionAdmin, - TokenOwner + /// @dev Owner of token can nest tokens under it. + TokenOwner, + /// @dev Admin of token collection can nest tokens under token. + CollectionAdmin } /// @dev anonymous struct @@ -356,9 +359,11 @@ uint256 field_2; } -/// @dev Property struct +/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue). struct Property { + /// @dev Property key. string key; + /// @dev Property value. bytes value; } --- a/tests/src/eth/api/UniqueNFT.sol +++ b/tests/src/eth/api/UniqueNFT.sol @@ -30,12 +30,12 @@ /// @param permissions Permissions for keys. /// @dev EVM selector for this function is: 0xbd92983a, /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[]) - function setTokenPropertyPermissions(Tuple53[] memory permissions) external; + function setTokenPropertyPermissions(TokenPropertyPermission[] memory permissions) external; /// @notice Get permissions for token properties. /// @dev EVM selector for this function is: 0xf23d7790, /// or in textual repr: tokenPropertyPermissions() - function tokenPropertyPermissions() external view returns (Tuple53[] memory); + function tokenPropertyPermissions() external view returns (TokenPropertyPermission[] memory); // /// @notice Set token property value. // /// @dev Throws error if `msg.sender` has no permission to edit the property. @@ -80,12 +80,30 @@ function property(uint256 tokenId, string memory key) external view returns (bytes memory); } -/// @dev Property struct +/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue). struct Property { + /// @dev Property key. string key; + /// @dev Property value. bytes value; } +/// @dev Ethereum representation of Token Property Permissions. +struct TokenPropertyPermission { + /// @dev Token property key. + string key; + /// @dev Token property permissions. + PropertyPermission[] permissions; +} + +/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value. +struct PropertyPermission { + /// @dev TokenPermission field. + EthTokenPermissions code; + /// @dev TokenPermission value. + bool value; +} + /// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration. enum EthTokenPermissions { /// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`] @@ -96,18 +114,6 @@ CollectionAdmin } -/// @dev anonymous struct -struct Tuple53 { - string field_0; - Tuple51[] field_1; -} - -/// @dev anonymous struct -struct Tuple51 { - EthTokenPermissions field_0; - bool field_1; -} - /// @title A contract that allows you to work with collections. /// @dev the ERC-165 identifier for this interface is 0x81172a75 interface Collection is Dummy, ERC165 { @@ -412,9 +418,12 @@ bool field_1; } +/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration. enum CollectionPermissions { - CollectionAdmin, - TokenOwner + /// @dev Owner of token can nest tokens under it. + TokenOwner, + /// @dev Admin of token collection can nest tokens under token. + CollectionAdmin } /// @dev anonymous struct --- a/tests/src/eth/api/UniqueRefungible.sol +++ b/tests/src/eth/api/UniqueRefungible.sol @@ -30,12 +30,12 @@ /// @param permissions Permissions for keys. /// @dev EVM selector for this function is: 0xbd92983a, /// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[]) - function setTokenPropertyPermissions(Tuple52[] memory permissions) external; + function setTokenPropertyPermissions(TokenPropertyPermission[] memory permissions) external; /// @notice Get permissions for token properties. /// @dev EVM selector for this function is: 0xf23d7790, /// or in textual repr: tokenPropertyPermissions() - function tokenPropertyPermissions() external view returns (Tuple52[] memory); + function tokenPropertyPermissions() external view returns (TokenPropertyPermission[] memory); // /// @notice Set token property value. // /// @dev Throws error if `msg.sender` has no permission to edit the property. @@ -80,12 +80,30 @@ function property(uint256 tokenId, string memory key) external view returns (bytes memory); } -/// @dev Property struct +/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue). struct Property { + /// @dev Property key. string key; + /// @dev Property value. bytes value; } +/// @dev Ethereum representation of Token Property Permissions. +struct TokenPropertyPermission { + /// @dev Token property key. + string key; + /// @dev Token property permissions. + PropertyPermission[] permissions; +} + +/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value. +struct PropertyPermission { + /// @dev TokenPermission field. + EthTokenPermissions code; + /// @dev TokenPermission value. + bool value; +} + /// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration. enum EthTokenPermissions { /// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`] @@ -96,18 +114,6 @@ CollectionAdmin } -/// @dev anonymous struct -struct Tuple52 { - string field_0; - Tuple50[] field_1; -} - -/// @dev anonymous struct -struct Tuple50 { - EthTokenPermissions field_0; - bool field_1; -} - /// @title A contract that allows you to work with collections. /// @dev the ERC-165 identifier for this interface is 0x81172a75 interface Collection is Dummy, ERC165 { @@ -412,9 +418,12 @@ bool field_1; } +/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration. enum CollectionPermissions { - CollectionAdmin, - TokenOwner + /// @dev Owner of token can nest tokens under it. + TokenOwner, + /// @dev Admin of token collection can nest tokens under token. + CollectionAdmin } /// @dev anonymous struct -- gitstuff