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

difftreelog

fix rft test

Trubnikov Sergey2022-12-15parent: #a37fff1.patch.diff
in: master

6 files changed

modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -18,30 +18,45 @@
 }
 
 /// @title A contract that allows to set and delete token properties and change token property permissions.
-/// @dev the ERC-165 identifier for this interface is 0x91a97a68
+/// @dev the ERC-165 identifier for this interface is 0xde0695c2
 contract TokenProperties is Dummy, ERC165 {
+	// /// @notice Set permissions for token property.
+	// /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
+	// /// @param key Property key.
+	// /// @param isMutable Permission to mutate property.
+	// /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
+	// /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
+	// /// @dev EVM selector for this function is: 0x222d97fa,
+	// ///  or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)
+	// function setTokenPropertyPermission(string memory key, bool isMutable, bool collectionAdmin, bool tokenOwner) public {
+	// 	require(false, stub_error);
+	// 	key;
+	// 	isMutable;
+	// 	collectionAdmin;
+	// 	tokenOwner;
+	// 	dummy = 0;
+	// }
+
 	/// @notice Set permissions for token property.
 	/// @dev Throws error if `msg.sender` is not admin or owner of the collection.
-	/// @param key Property key.
-	/// @param isMutable Permission to mutate property.
-	/// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
-	/// @param tokenOwner Permission to mutate property by token owner if property is mutable.
-	/// @dev EVM selector for this function is: 0x222d97fa,
-	///  or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)
-	function setTokenPropertyPermission(
-		string memory key,
-		bool isMutable,
-		bool collectionAdmin,
-		bool tokenOwner
-	) public {
+	/// @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) public {
 		require(false, stub_error);
-		key;
-		isMutable;
-		collectionAdmin;
-		tokenOwner;
+		permissions;
 		dummy = 0;
 	}
 
+	/// @notice Get permissions for token properties.
+	/// @dev EVM selector for this function is: 0xf23d7790,
+	///  or in textual repr: tokenPropertyPermissions()
+	function tokenPropertyPermissions() public view returns (Tuple53[] memory) {
+		require(false, stub_error);
+		dummy;
+		return new Tuple53[](0);
+	}
+
 	// /// @notice Set token property value.
 	// /// @dev Throws error if `msg.sender` has no permission to edit the property.
 	// /// @param tokenId ID of the token.
@@ -118,6 +133,24 @@
 	bytes value;
 }
 
+enum EthTokenPermissions {
+	Mutable,
+	TokenOwner,
+	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 0xb5e1747f
 contract Collection is Dummy, ERC165 {
modifiedtests/src/eth/abi/reFungible.jsondiffbeforeafterboth
before · tests/src/eth/abi/reFungible.json
1[2  {3    "anonymous": false,4    "inputs": [5      {6        "indexed": true,7        "internalType": "address",8        "name": "owner",9        "type": "address"10      },11      {12        "indexed": true,13        "internalType": "address",14        "name": "approved",15        "type": "address"16      },17      {18        "indexed": true,19        "internalType": "uint256",20        "name": "tokenId",21        "type": "uint256"22      }23    ],24    "name": "Approval",25    "type": "event"26  },27  {28    "anonymous": false,29    "inputs": [30      {31        "indexed": true,32        "internalType": "address",33        "name": "owner",34        "type": "address"35      },36      {37        "indexed": true,38        "internalType": "address",39        "name": "operator",40        "type": "address"41      },42      {43        "indexed": false,44        "internalType": "bool",45        "name": "approved",46        "type": "bool"47      }48    ],49    "name": "ApprovalForAll",50    "type": "event"51  },52  {53    "anonymous": false,54    "inputs": [],55    "name": "MintingFinished",56    "type": "event"57  },58  {59    "anonymous": false,60    "inputs": [61      {62        "indexed": true,63        "internalType": "address",64        "name": "from",65        "type": "address"66      },67      {68        "indexed": true,69        "internalType": "address",70        "name": "to",71        "type": "address"72      },73      {74        "indexed": true,75        "internalType": "uint256",76        "name": "tokenId",77        "type": "uint256"78      }79    ],80    "name": "Transfer",81    "type": "event"82  },83  {84    "inputs": [85      {86        "components": [87          { "internalType": "address", "name": "eth", "type": "address" },88          { "internalType": "uint256", "name": "sub", "type": "uint256" }89        ],90        "internalType": "struct EthCrossAccount",91        "name": "newAdmin",92        "type": "tuple"93      }94    ],95    "name": "addCollectionAdminCross",96    "outputs": [],97    "stateMutability": "nonpayable",98    "type": "function"99  },100  {101    "inputs": [102      {103        "components": [104          { "internalType": "address", "name": "eth", "type": "address" },105          { "internalType": "uint256", "name": "sub", "type": "uint256" }106        ],107        "internalType": "struct EthCrossAccount",108        "name": "user",109        "type": "tuple"110      }111    ],112    "name": "addToCollectionAllowListCross",113    "outputs": [],114    "stateMutability": "nonpayable",115    "type": "function"116  },117  {118    "inputs": [119      {120        "components": [121          { "internalType": "address", "name": "eth", "type": "address" },122          { "internalType": "uint256", "name": "sub", "type": "uint256" }123        ],124        "internalType": "struct EthCrossAccount",125        "name": "user",126        "type": "tuple"127      }128    ],129    "name": "allowlistedCross",130    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],131    "stateMutability": "view",132    "type": "function"133  },134  {135    "inputs": [136      { "internalType": "address", "name": "approved", "type": "address" },137      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }138    ],139    "name": "approve",140    "outputs": [],141    "stateMutability": "nonpayable",142    "type": "function"143  },144  {145    "inputs": [146      { "internalType": "address", "name": "owner", "type": "address" }147    ],148    "name": "balanceOf",149    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],150    "stateMutability": "view",151    "type": "function"152  },153  {154    "inputs": [155      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }156    ],157    "name": "burn",158    "outputs": [],159    "stateMutability": "nonpayable",160    "type": "function"161  },162  {163    "inputs": [164      {165        "components": [166          { "internalType": "address", "name": "eth", "type": "address" },167          { "internalType": "uint256", "name": "sub", "type": "uint256" }168        ],169        "internalType": "struct EthCrossAccount",170        "name": "from",171        "type": "tuple"172      },173      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }174    ],175    "name": "burnFromCross",176    "outputs": [],177    "stateMutability": "nonpayable",178    "type": "function"179  },180  {181    "inputs": [182      {183        "components": [184          { "internalType": "address", "name": "eth", "type": "address" },185          { "internalType": "uint256", "name": "sub", "type": "uint256" }186        ],187        "internalType": "struct EthCrossAccount",188        "name": "newOwner",189        "type": "tuple"190      }191    ],192    "name": "changeCollectionOwnerCross",193    "outputs": [],194    "stateMutability": "nonpayable",195    "type": "function"196  },197  {198    "inputs": [],199    "name": "collectionAdmins",200    "outputs": [201      {202        "components": [203          { "internalType": "address", "name": "eth", "type": "address" },204          { "internalType": "uint256", "name": "sub", "type": "uint256" }205        ],206        "internalType": "struct EthCrossAccount[]",207        "name": "",208        "type": "tuple[]"209      }210    ],211    "stateMutability": "view",212    "type": "function"213  },214  {215    "inputs": [],216    "name": "collectionHelperAddress",217    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],218    "stateMutability": "view",219    "type": "function"220  },221  {222    "inputs": [],223    "name": "collectionNestingPermissions",224    "outputs": [225      {226        "components": [227          {228            "internalType": "enum CollectionPermissions",229            "name": "field_0",230            "type": "uint8"231          },232          { "internalType": "bool", "name": "field_1", "type": "bool" }233        ],234        "internalType": "struct Tuple36[]",235        "name": "",236        "type": "tuple[]"237      }238    ],239    "stateMutability": "view",240    "type": "function"241  },242  {243    "inputs": [],244    "name": "collectionNestingRestrictedCollectionIds",245    "outputs": [246      {247        "components": [248          { "internalType": "bool", "name": "field_0", "type": "bool" },249          {250            "internalType": "uint256[]",251            "name": "field_1",252            "type": "uint256[]"253          }254        ],255        "internalType": "struct Tuple33",256        "name": "",257        "type": "tuple"258      }259    ],260    "stateMutability": "view",261    "type": "function"262  },263  {264    "inputs": [],265    "name": "collectionOwner",266    "outputs": [267      {268        "components": [269          { "internalType": "address", "name": "eth", "type": "address" },270          { "internalType": "uint256", "name": "sub", "type": "uint256" }271        ],272        "internalType": "struct EthCrossAccount",273        "name": "",274        "type": "tuple"275      }276    ],277    "stateMutability": "view",278    "type": "function"279  },280  {281    "inputs": [282      { "internalType": "string[]", "name": "keys", "type": "string[]" }283    ],284    "name": "collectionProperties",285    "outputs": [286      {287        "components": [288          { "internalType": "string", "name": "key", "type": "string" },289          { "internalType": "bytes", "name": "value", "type": "bytes" }290        ],291        "internalType": "struct Property[]",292        "name": "",293        "type": "tuple[]"294      }295    ],296    "stateMutability": "view",297    "type": "function"298  },299  {300    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],301    "name": "collectionProperty",302    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],303    "stateMutability": "view",304    "type": "function"305  },306  {307    "inputs": [],308    "name": "collectionSponsor",309    "outputs": [310      {311        "components": [312          { "internalType": "address", "name": "field_0", "type": "address" },313          { "internalType": "uint256", "name": "field_1", "type": "uint256" }314        ],315        "internalType": "struct Tuple29",316        "name": "",317        "type": "tuple"318      }319    ],320    "stateMutability": "view",321    "type": "function"322  },323  {324    "inputs": [],325    "name": "confirmCollectionSponsorship",326    "outputs": [],327    "stateMutability": "nonpayable",328    "type": "function"329  },330  {331    "inputs": [],332    "name": "contractAddress",333    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],334    "stateMutability": "view",335    "type": "function"336  },337  {338    "inputs": [339      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }340    ],341    "name": "crossOwnerOf",342    "outputs": [343      {344        "components": [345          { "internalType": "address", "name": "eth", "type": "address" },346          { "internalType": "uint256", "name": "sub", "type": "uint256" }347        ],348        "internalType": "struct EthCrossAccount",349        "name": "",350        "type": "tuple"351      }352    ],353    "stateMutability": "view",354    "type": "function"355  },356  {357    "inputs": [358      { "internalType": "string[]", "name": "keys", "type": "string[]" }359    ],360    "name": "deleteCollectionProperties",361    "outputs": [],362    "stateMutability": "nonpayable",363    "type": "function"364  },365  {366    "inputs": [367      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },368      { "internalType": "string[]", "name": "keys", "type": "string[]" }369    ],370    "name": "deleteProperties",371    "outputs": [],372    "stateMutability": "nonpayable",373    "type": "function"374  },375  {376    "inputs": [],377    "name": "description",378    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],379    "stateMutability": "view",380    "type": "function"381  },382  {383    "inputs": [],384    "name": "finishMinting",385    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],386    "stateMutability": "nonpayable",387    "type": "function"388  },389  {390    "inputs": [391      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }392    ],393    "name": "getApproved",394    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],395    "stateMutability": "view",396    "type": "function"397  },398  {399    "inputs": [],400    "name": "hasCollectionPendingSponsor",401    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],402    "stateMutability": "view",403    "type": "function"404  },405  {406    "inputs": [407      { "internalType": "address", "name": "owner", "type": "address" },408      { "internalType": "address", "name": "operator", "type": "address" }409    ],410    "name": "isApprovedForAll",411    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],412    "stateMutability": "view",413    "type": "function"414  },415  {416    "inputs": [417      {418        "components": [419          { "internalType": "address", "name": "eth", "type": "address" },420          { "internalType": "uint256", "name": "sub", "type": "uint256" }421        ],422        "internalType": "struct EthCrossAccount",423        "name": "user",424        "type": "tuple"425      }426    ],427    "name": "isOwnerOrAdminCross",428    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],429    "stateMutability": "view",430    "type": "function"431  },432  {433    "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],434    "name": "mint",435    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],436    "stateMutability": "nonpayable",437    "type": "function"438  },439  {440    "inputs": [441      { "internalType": "address", "name": "to", "type": "address" },442      { "internalType": "string", "name": "tokenUri", "type": "string" }443    ],444    "name": "mintWithTokenURI",445    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],446    "stateMutability": "nonpayable",447    "type": "function"448  },449  {450    "inputs": [],451    "name": "mintingFinished",452    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],453    "stateMutability": "view",454    "type": "function"455  },456  {457    "inputs": [],458    "name": "name",459    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],460    "stateMutability": "view",461    "type": "function"462  },463  {464    "inputs": [],465    "name": "nextTokenId",466    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],467    "stateMutability": "view",468    "type": "function"469  },470  {471    "inputs": [472      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }473    ],474    "name": "ownerOf",475    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],476    "stateMutability": "view",477    "type": "function"478  },479  {480    "inputs": [481      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },482      { "internalType": "string[]", "name": "keys", "type": "string[]" }483    ],484    "name": "properties",485    "outputs": [486      {487        "components": [488          { "internalType": "string", "name": "key", "type": "string" },489          { "internalType": "bytes", "name": "value", "type": "bytes" }490        ],491        "internalType": "struct Property[]",492        "name": "",493        "type": "tuple[]"494      }495    ],496    "stateMutability": "view",497    "type": "function"498  },499  {500    "inputs": [501      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },502      { "internalType": "string", "name": "key", "type": "string" }503    ],504    "name": "property",505    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],506    "stateMutability": "view",507    "type": "function"508  },509  {510    "inputs": [511      {512        "components": [513          { "internalType": "address", "name": "eth", "type": "address" },514          { "internalType": "uint256", "name": "sub", "type": "uint256" }515        ],516        "internalType": "struct EthCrossAccount",517        "name": "admin",518        "type": "tuple"519      }520    ],521    "name": "removeCollectionAdminCross",522    "outputs": [],523    "stateMutability": "nonpayable",524    "type": "function"525  },526  {527    "inputs": [],528    "name": "removeCollectionSponsor",529    "outputs": [],530    "stateMutability": "nonpayable",531    "type": "function"532  },533  {534    "inputs": [535      {536        "components": [537          { "internalType": "address", "name": "eth", "type": "address" },538          { "internalType": "uint256", "name": "sub", "type": "uint256" }539        ],540        "internalType": "struct EthCrossAccount",541        "name": "user",542        "type": "tuple"543      }544    ],545    "name": "removeFromCollectionAllowListCross",546    "outputs": [],547    "stateMutability": "nonpayable",548    "type": "function"549  },550  {551    "inputs": [552      { "internalType": "address", "name": "from", "type": "address" },553      { "internalType": "address", "name": "to", "type": "address" },554      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }555    ],556    "name": "safeTransferFrom",557    "outputs": [],558    "stateMutability": "nonpayable",559    "type": "function"560  },561  {562    "inputs": [563      { "internalType": "address", "name": "from", "type": "address" },564      { "internalType": "address", "name": "to", "type": "address" },565      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },566      { "internalType": "bytes", "name": "data", "type": "bytes" }567    ],568    "name": "safeTransferFromWithData",569    "outputs": [],570    "stateMutability": "nonpayable",571    "type": "function"572  },573  {574    "inputs": [575      { "internalType": "address", "name": "operator", "type": "address" },576      { "internalType": "bool", "name": "approved", "type": "bool" }577    ],578    "name": "setApprovalForAll",579    "outputs": [],580    "stateMutability": "nonpayable",581    "type": "function"582  },583  {584    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],585    "name": "setCollectionAccess",586    "outputs": [],587    "stateMutability": "nonpayable",588    "type": "function"589  },590  {591    "inputs": [592      { "internalType": "string", "name": "limit", "type": "string" },593      { "internalType": "uint256", "name": "value", "type": "uint256" }594    ],595    "name": "setCollectionLimit",596    "outputs": [],597    "stateMutability": "nonpayable",598    "type": "function"599  },600  {601    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],602    "name": "setCollectionMintMode",603    "outputs": [],604    "stateMutability": "nonpayable",605    "type": "function"606  },607  {608    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],609    "name": "setCollectionNesting",610    "outputs": [],611    "stateMutability": "nonpayable",612    "type": "function"613  },614  {615    "inputs": [616      { "internalType": "bool", "name": "enable", "type": "bool" },617      {618        "internalType": "address[]",619        "name": "collections",620        "type": "address[]"621      }622    ],623    "name": "setCollectionNesting",624    "outputs": [],625    "stateMutability": "nonpayable",626    "type": "function"627  },628  {629    "inputs": [630      {631        "components": [632          { "internalType": "string", "name": "key", "type": "string" },633          { "internalType": "bytes", "name": "value", "type": "bytes" }634        ],635        "internalType": "struct Property[]",636        "name": "properties",637        "type": "tuple[]"638      }639    ],640    "name": "setCollectionProperties",641    "outputs": [],642    "stateMutability": "nonpayable",643    "type": "function"644  },645  {646    "inputs": [647      {648        "components": [649          { "internalType": "address", "name": "eth", "type": "address" },650          { "internalType": "uint256", "name": "sub", "type": "uint256" }651        ],652        "internalType": "struct EthCrossAccount",653        "name": "sponsor",654        "type": "tuple"655      }656    ],657    "name": "setCollectionSponsorCross",658    "outputs": [],659    "stateMutability": "nonpayable",660    "type": "function"661  },662  {663    "inputs": [664      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },665      {666        "components": [667          { "internalType": "string", "name": "key", "type": "string" },668          { "internalType": "bytes", "name": "value", "type": "bytes" }669        ],670        "internalType": "struct Property[]",671        "name": "properties",672        "type": "tuple[]"673      }674    ],675    "name": "setProperties",676    "outputs": [],677    "stateMutability": "nonpayable",678    "type": "function"679  },680  {681    "inputs": [682      { "internalType": "string", "name": "key", "type": "string" },683      { "internalType": "bool", "name": "isMutable", "type": "bool" },684      { "internalType": "bool", "name": "collectionAdmin", "type": "bool" },685      { "internalType": "bool", "name": "tokenOwner", "type": "bool" }686    ],687    "name": "setTokenPropertyPermission",688    "outputs": [],689    "stateMutability": "nonpayable",690    "type": "function"691  },692  {693    "inputs": [694      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }695    ],696    "name": "supportsInterface",697    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],698    "stateMutability": "view",699    "type": "function"700  },701  {702    "inputs": [],703    "name": "symbol",704    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],705    "stateMutability": "view",706    "type": "function"707  },708  {709    "inputs": [710      { "internalType": "uint256", "name": "index", "type": "uint256" }711    ],712    "name": "tokenByIndex",713    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],714    "stateMutability": "view",715    "type": "function"716  },717  {718    "inputs": [719      { "internalType": "uint256", "name": "token", "type": "uint256" }720    ],721    "name": "tokenContractAddress",722    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],723    "stateMutability": "view",724    "type": "function"725  },726  {727    "inputs": [728      { "internalType": "address", "name": "owner", "type": "address" },729      { "internalType": "uint256", "name": "index", "type": "uint256" }730    ],731    "name": "tokenOfOwnerByIndex",732    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],733    "stateMutability": "view",734    "type": "function"735  },736  {737    "inputs": [738      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }739    ],740    "name": "tokenURI",741    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],742    "stateMutability": "view",743    "type": "function"744  },745  {746    "inputs": [],747    "name": "totalSupply",748    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],749    "stateMutability": "view",750    "type": "function"751  },752  {753    "inputs": [754      { "internalType": "address", "name": "to", "type": "address" },755      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }756    ],757    "name": "transfer",758    "outputs": [],759    "stateMutability": "nonpayable",760    "type": "function"761  },762  {763    "inputs": [764      {765        "components": [766          { "internalType": "address", "name": "eth", "type": "address" },767          { "internalType": "uint256", "name": "sub", "type": "uint256" }768        ],769        "internalType": "struct EthCrossAccount",770        "name": "to",771        "type": "tuple"772      },773      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }774    ],775    "name": "transferCross",776    "outputs": [],777    "stateMutability": "nonpayable",778    "type": "function"779  },780  {781    "inputs": [782      { "internalType": "address", "name": "from", "type": "address" },783      { "internalType": "address", "name": "to", "type": "address" },784      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }785    ],786    "name": "transferFrom",787    "outputs": [],788    "stateMutability": "nonpayable",789    "type": "function"790  },791  {792    "inputs": [793      {794        "components": [795          { "internalType": "address", "name": "eth", "type": "address" },796          { "internalType": "uint256", "name": "sub", "type": "uint256" }797        ],798        "internalType": "struct EthCrossAccount",799        "name": "from",800        "type": "tuple"801      },802      {803        "components": [804          { "internalType": "address", "name": "eth", "type": "address" },805          { "internalType": "uint256", "name": "sub", "type": "uint256" }806        ],807        "internalType": "struct EthCrossAccount",808        "name": "to",809        "type": "tuple"810      },811      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }812    ],813    "name": "transferFromCross",814    "outputs": [],815    "stateMutability": "nonpayable",816    "type": "function"817  },818  {819    "inputs": [],820    "name": "uniqueCollectionType",821    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],822    "stateMutability": "view",823    "type": "function"824  }825]
after · tests/src/eth/abi/reFungible.json
1[2  {3    "anonymous": false,4    "inputs": [5      {6        "indexed": true,7        "internalType": "address",8        "name": "owner",9        "type": "address"10      },11      {12        "indexed": true,13        "internalType": "address",14        "name": "approved",15        "type": "address"16      },17      {18        "indexed": true,19        "internalType": "uint256",20        "name": "tokenId",21        "type": "uint256"22      }23    ],24    "name": "Approval",25    "type": "event"26  },27  {28    "anonymous": false,29    "inputs": [30      {31        "indexed": true,32        "internalType": "address",33        "name": "owner",34        "type": "address"35      },36      {37        "indexed": true,38        "internalType": "address",39        "name": "operator",40        "type": "address"41      },42      {43        "indexed": false,44        "internalType": "bool",45        "name": "approved",46        "type": "bool"47      }48    ],49    "name": "ApprovalForAll",50    "type": "event"51  },52  {53    "anonymous": false,54    "inputs": [],55    "name": "MintingFinished",56    "type": "event"57  },58  {59    "anonymous": false,60    "inputs": [61      {62        "indexed": true,63        "internalType": "address",64        "name": "from",65        "type": "address"66      },67      {68        "indexed": true,69        "internalType": "address",70        "name": "to",71        "type": "address"72      },73      {74        "indexed": true,75        "internalType": "uint256",76        "name": "tokenId",77        "type": "uint256"78      }79    ],80    "name": "Transfer",81    "type": "event"82  },83  {84    "inputs": [85      {86        "components": [87          { "internalType": "address", "name": "eth", "type": "address" },88          { "internalType": "uint256", "name": "sub", "type": "uint256" }89        ],90        "internalType": "struct EthCrossAccount",91        "name": "newAdmin",92        "type": "tuple"93      }94    ],95    "name": "addCollectionAdminCross",96    "outputs": [],97    "stateMutability": "nonpayable",98    "type": "function"99  },100  {101    "inputs": [102      {103        "components": [104          { "internalType": "address", "name": "eth", "type": "address" },105          { "internalType": "uint256", "name": "sub", "type": "uint256" }106        ],107        "internalType": "struct EthCrossAccount",108        "name": "user",109        "type": "tuple"110      }111    ],112    "name": "addToCollectionAllowListCross",113    "outputs": [],114    "stateMutability": "nonpayable",115    "type": "function"116  },117  {118    "inputs": [119      {120        "components": [121          { "internalType": "address", "name": "eth", "type": "address" },122          { "internalType": "uint256", "name": "sub", "type": "uint256" }123        ],124        "internalType": "struct EthCrossAccount",125        "name": "user",126        "type": "tuple"127      }128    ],129    "name": "allowlistedCross",130    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],131    "stateMutability": "view",132    "type": "function"133  },134  {135    "inputs": [136      { "internalType": "address", "name": "approved", "type": "address" },137      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }138    ],139    "name": "approve",140    "outputs": [],141    "stateMutability": "nonpayable",142    "type": "function"143  },144  {145    "inputs": [146      { "internalType": "address", "name": "owner", "type": "address" }147    ],148    "name": "balanceOf",149    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],150    "stateMutability": "view",151    "type": "function"152  },153  {154    "inputs": [155      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }156    ],157    "name": "burn",158    "outputs": [],159    "stateMutability": "nonpayable",160    "type": "function"161  },162  {163    "inputs": [164      {165        "components": [166          { "internalType": "address", "name": "eth", "type": "address" },167          { "internalType": "uint256", "name": "sub", "type": "uint256" }168        ],169        "internalType": "struct EthCrossAccount",170        "name": "from",171        "type": "tuple"172      },173      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }174    ],175    "name": "burnFromCross",176    "outputs": [],177    "stateMutability": "nonpayable",178    "type": "function"179  },180  {181    "inputs": [182      {183        "components": [184          { "internalType": "address", "name": "eth", "type": "address" },185          { "internalType": "uint256", "name": "sub", "type": "uint256" }186        ],187        "internalType": "struct EthCrossAccount",188        "name": "newOwner",189        "type": "tuple"190      }191    ],192    "name": "changeCollectionOwnerCross",193    "outputs": [],194    "stateMutability": "nonpayable",195    "type": "function"196  },197  {198    "inputs": [],199    "name": "collectionAdmins",200    "outputs": [201      {202        "components": [203          { "internalType": "address", "name": "eth", "type": "address" },204          { "internalType": "uint256", "name": "sub", "type": "uint256" }205        ],206        "internalType": "struct EthCrossAccount[]",207        "name": "",208        "type": "tuple[]"209      }210    ],211    "stateMutability": "view",212    "type": "function"213  },214  {215    "inputs": [],216    "name": "collectionHelperAddress",217    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],218    "stateMutability": "view",219    "type": "function"220  },221  {222    "inputs": [],223    "name": "collectionNestingPermissions",224    "outputs": [225      {226        "components": [227          {228            "internalType": "enum CollectionPermissions",229            "name": "field_0",230            "type": "uint8"231          },232          { "internalType": "bool", "name": "field_1", "type": "bool" }233        ],234        "internalType": "struct Tuple36[]",235        "name": "",236        "type": "tuple[]"237      }238    ],239    "stateMutability": "view",240    "type": "function"241  },242  {243    "inputs": [],244    "name": "collectionNestingRestrictedCollectionIds",245    "outputs": [246      {247        "components": [248          { "internalType": "bool", "name": "field_0", "type": "bool" },249          {250            "internalType": "uint256[]",251            "name": "field_1",252            "type": "uint256[]"253          }254        ],255        "internalType": "struct Tuple33",256        "name": "",257        "type": "tuple"258      }259    ],260    "stateMutability": "view",261    "type": "function"262  },263  {264    "inputs": [],265    "name": "collectionOwner",266    "outputs": [267      {268        "components": [269          { "internalType": "address", "name": "eth", "type": "address" },270          { "internalType": "uint256", "name": "sub", "type": "uint256" }271        ],272        "internalType": "struct EthCrossAccount",273        "name": "",274        "type": "tuple"275      }276    ],277    "stateMutability": "view",278    "type": "function"279  },280  {281    "inputs": [282      { "internalType": "string[]", "name": "keys", "type": "string[]" }283    ],284    "name": "collectionProperties",285    "outputs": [286      {287        "components": [288          { "internalType": "string", "name": "key", "type": "string" },289          { "internalType": "bytes", "name": "value", "type": "bytes" }290        ],291        "internalType": "struct Property[]",292        "name": "",293        "type": "tuple[]"294      }295    ],296    "stateMutability": "view",297    "type": "function"298  },299  {300    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],301    "name": "collectionProperty",302    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],303    "stateMutability": "view",304    "type": "function"305  },306  {307    "inputs": [],308    "name": "collectionSponsor",309    "outputs": [310      {311        "components": [312          { "internalType": "address", "name": "field_0", "type": "address" },313          { "internalType": "uint256", "name": "field_1", "type": "uint256" }314        ],315        "internalType": "struct Tuple29",316        "name": "",317        "type": "tuple"318      }319    ],320    "stateMutability": "view",321    "type": "function"322  },323  {324    "inputs": [],325    "name": "confirmCollectionSponsorship",326    "outputs": [],327    "stateMutability": "nonpayable",328    "type": "function"329  },330  {331    "inputs": [],332    "name": "contractAddress",333    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],334    "stateMutability": "view",335    "type": "function"336  },337  {338    "inputs": [339      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }340    ],341    "name": "crossOwnerOf",342    "outputs": [343      {344        "components": [345          { "internalType": "address", "name": "eth", "type": "address" },346          { "internalType": "uint256", "name": "sub", "type": "uint256" }347        ],348        "internalType": "struct EthCrossAccount",349        "name": "",350        "type": "tuple"351      }352    ],353    "stateMutability": "view",354    "type": "function"355  },356  {357    "inputs": [358      { "internalType": "string[]", "name": "keys", "type": "string[]" }359    ],360    "name": "deleteCollectionProperties",361    "outputs": [],362    "stateMutability": "nonpayable",363    "type": "function"364  },365  {366    "inputs": [367      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },368      { "internalType": "string[]", "name": "keys", "type": "string[]" }369    ],370    "name": "deleteProperties",371    "outputs": [],372    "stateMutability": "nonpayable",373    "type": "function"374  },375  {376    "inputs": [],377    "name": "description",378    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],379    "stateMutability": "view",380    "type": "function"381  },382  {383    "inputs": [],384    "name": "finishMinting",385    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],386    "stateMutability": "nonpayable",387    "type": "function"388  },389  {390    "inputs": [391      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }392    ],393    "name": "getApproved",394    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],395    "stateMutability": "view",396    "type": "function"397  },398  {399    "inputs": [],400    "name": "hasCollectionPendingSponsor",401    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],402    "stateMutability": "view",403    "type": "function"404  },405  {406    "inputs": [407      { "internalType": "address", "name": "owner", "type": "address" },408      { "internalType": "address", "name": "operator", "type": "address" }409    ],410    "name": "isApprovedForAll",411    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],412    "stateMutability": "view",413    "type": "function"414  },415  {416    "inputs": [417      {418        "components": [419          { "internalType": "address", "name": "eth", "type": "address" },420          { "internalType": "uint256", "name": "sub", "type": "uint256" }421        ],422        "internalType": "struct EthCrossAccount",423        "name": "user",424        "type": "tuple"425      }426    ],427    "name": "isOwnerOrAdminCross",428    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],429    "stateMutability": "view",430    "type": "function"431  },432  {433    "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],434    "name": "mint",435    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],436    "stateMutability": "nonpayable",437    "type": "function"438  },439  {440    "inputs": [441      { "internalType": "address", "name": "to", "type": "address" },442      { "internalType": "string", "name": "tokenUri", "type": "string" }443    ],444    "name": "mintWithTokenURI",445    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],446    "stateMutability": "nonpayable",447    "type": "function"448  },449  {450    "inputs": [],451    "name": "mintingFinished",452    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],453    "stateMutability": "view",454    "type": "function"455  },456  {457    "inputs": [],458    "name": "name",459    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],460    "stateMutability": "view",461    "type": "function"462  },463  {464    "inputs": [],465    "name": "nextTokenId",466    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],467    "stateMutability": "view",468    "type": "function"469  },470  {471    "inputs": [472      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }473    ],474    "name": "ownerOf",475    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],476    "stateMutability": "view",477    "type": "function"478  },479  {480    "inputs": [481      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },482      { "internalType": "string[]", "name": "keys", "type": "string[]" }483    ],484    "name": "properties",485    "outputs": [486      {487        "components": [488          { "internalType": "string", "name": "key", "type": "string" },489          { "internalType": "bytes", "name": "value", "type": "bytes" }490        ],491        "internalType": "struct Property[]",492        "name": "",493        "type": "tuple[]"494      }495    ],496    "stateMutability": "view",497    "type": "function"498  },499  {500    "inputs": [501      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },502      { "internalType": "string", "name": "key", "type": "string" }503    ],504    "name": "property",505    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],506    "stateMutability": "view",507    "type": "function"508  },509  {510    "inputs": [511      {512        "components": [513          { "internalType": "address", "name": "eth", "type": "address" },514          { "internalType": "uint256", "name": "sub", "type": "uint256" }515        ],516        "internalType": "struct EthCrossAccount",517        "name": "admin",518        "type": "tuple"519      }520    ],521    "name": "removeCollectionAdminCross",522    "outputs": [],523    "stateMutability": "nonpayable",524    "type": "function"525  },526  {527    "inputs": [],528    "name": "removeCollectionSponsor",529    "outputs": [],530    "stateMutability": "nonpayable",531    "type": "function"532  },533  {534    "inputs": [535      {536        "components": [537          { "internalType": "address", "name": "eth", "type": "address" },538          { "internalType": "uint256", "name": "sub", "type": "uint256" }539        ],540        "internalType": "struct EthCrossAccount",541        "name": "user",542        "type": "tuple"543      }544    ],545    "name": "removeFromCollectionAllowListCross",546    "outputs": [],547    "stateMutability": "nonpayable",548    "type": "function"549  },550  {551    "inputs": [552      { "internalType": "address", "name": "from", "type": "address" },553      { "internalType": "address", "name": "to", "type": "address" },554      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }555    ],556    "name": "safeTransferFrom",557    "outputs": [],558    "stateMutability": "nonpayable",559    "type": "function"560  },561  {562    "inputs": [563      { "internalType": "address", "name": "from", "type": "address" },564      { "internalType": "address", "name": "to", "type": "address" },565      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },566      { "internalType": "bytes", "name": "data", "type": "bytes" }567    ],568    "name": "safeTransferFromWithData",569    "outputs": [],570    "stateMutability": "nonpayable",571    "type": "function"572  },573  {574    "inputs": [575      { "internalType": "address", "name": "operator", "type": "address" },576      { "internalType": "bool", "name": "approved", "type": "bool" }577    ],578    "name": "setApprovalForAll",579    "outputs": [],580    "stateMutability": "nonpayable",581    "type": "function"582  },583  {584    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],585    "name": "setCollectionAccess",586    "outputs": [],587    "stateMutability": "nonpayable",588    "type": "function"589  },590  {591    "inputs": [592      { "internalType": "string", "name": "limit", "type": "string" },593      { "internalType": "uint256", "name": "value", "type": "uint256" }594    ],595    "name": "setCollectionLimit",596    "outputs": [],597    "stateMutability": "nonpayable",598    "type": "function"599  },600  {601    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],602    "name": "setCollectionMintMode",603    "outputs": [],604    "stateMutability": "nonpayable",605    "type": "function"606  },607  {608    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],609    "name": "setCollectionNesting",610    "outputs": [],611    "stateMutability": "nonpayable",612    "type": "function"613  },614  {615    "inputs": [616      { "internalType": "bool", "name": "enable", "type": "bool" },617      {618        "internalType": "address[]",619        "name": "collections",620        "type": "address[]"621      }622    ],623    "name": "setCollectionNesting",624    "outputs": [],625    "stateMutability": "nonpayable",626    "type": "function"627  },628  {629    "inputs": [630      {631        "components": [632          { "internalType": "string", "name": "key", "type": "string" },633          { "internalType": "bytes", "name": "value", "type": "bytes" }634        ],635        "internalType": "struct Property[]",636        "name": "properties",637        "type": "tuple[]"638      }639    ],640    "name": "setCollectionProperties",641    "outputs": [],642    "stateMutability": "nonpayable",643    "type": "function"644  },645  {646    "inputs": [647      {648        "components": [649          { "internalType": "address", "name": "eth", "type": "address" },650          { "internalType": "uint256", "name": "sub", "type": "uint256" }651        ],652        "internalType": "struct EthCrossAccount",653        "name": "sponsor",654        "type": "tuple"655      }656    ],657    "name": "setCollectionSponsorCross",658    "outputs": [],659    "stateMutability": "nonpayable",660    "type": "function"661  },662  {663    "inputs": [664      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },665      {666        "components": [667          { "internalType": "string", "name": "key", "type": "string" },668          { "internalType": "bytes", "name": "value", "type": "bytes" }669        ],670        "internalType": "struct Property[]",671        "name": "properties",672        "type": "tuple[]"673      }674    ],675    "name": "setProperties",676    "outputs": [],677    "stateMutability": "nonpayable",678    "type": "function"679  },680  {681    "inputs": [682      {683        "components": [684          { "internalType": "string", "name": "field_0", "type": "string" },685          {686            "components": [687              {688                "internalType": "enum EthTokenPermissions",689                "name": "field_0",690                "type": "uint8"691              },692              { "internalType": "bool", "name": "field_1", "type": "bool" }693            ],694            "internalType": "struct Tuple51[]",695            "name": "field_1",696            "type": "tuple[]"697          }698        ],699        "internalType": "struct Tuple53[]",700        "name": "permissions",701        "type": "tuple[]"702      }703    ],704    "name": "setTokenPropertyPermissions",705    "outputs": [],706    "stateMutability": "nonpayable",707    "type": "function"708  },709  {710    "inputs": [711      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }712    ],713    "name": "supportsInterface",714    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],715    "stateMutability": "view",716    "type": "function"717  },718  {719    "inputs": [],720    "name": "symbol",721    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],722    "stateMutability": "view",723    "type": "function"724  },725  {726    "inputs": [727      { "internalType": "uint256", "name": "index", "type": "uint256" }728    ],729    "name": "tokenByIndex",730    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],731    "stateMutability": "view",732    "type": "function"733  },734  {735    "inputs": [736      { "internalType": "uint256", "name": "token", "type": "uint256" }737    ],738    "name": "tokenContractAddress",739    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],740    "stateMutability": "view",741    "type": "function"742  },743  {744    "inputs": [745      { "internalType": "address", "name": "owner", "type": "address" },746      { "internalType": "uint256", "name": "index", "type": "uint256" }747    ],748    "name": "tokenOfOwnerByIndex",749    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],750    "stateMutability": "view",751    "type": "function"752  },753  {754    "inputs": [],755    "name": "tokenPropertyPermissions",756    "outputs": [757      {758        "components": [759          { "internalType": "string", "name": "field_0", "type": "string" },760          {761            "components": [762              {763                "internalType": "enum EthTokenPermissions",764                "name": "field_0",765                "type": "uint8"766              },767              { "internalType": "bool", "name": "field_1", "type": "bool" }768            ],769            "internalType": "struct Tuple51[]",770            "name": "field_1",771            "type": "tuple[]"772          }773        ],774        "internalType": "struct Tuple53[]",775        "name": "",776        "type": "tuple[]"777      }778    ],779    "stateMutability": "view",780    "type": "function"781  },782  {783    "inputs": [784      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }785    ],786    "name": "tokenURI",787    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],788    "stateMutability": "view",789    "type": "function"790  },791  {792    "inputs": [],793    "name": "totalSupply",794    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],795    "stateMutability": "view",796    "type": "function"797  },798  {799    "inputs": [800      { "internalType": "address", "name": "to", "type": "address" },801      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }802    ],803    "name": "transfer",804    "outputs": [],805    "stateMutability": "nonpayable",806    "type": "function"807  },808  {809    "inputs": [810      {811        "components": [812          { "internalType": "address", "name": "eth", "type": "address" },813          { "internalType": "uint256", "name": "sub", "type": "uint256" }814        ],815        "internalType": "struct EthCrossAccount",816        "name": "to",817        "type": "tuple"818      },819      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }820    ],821    "name": "transferCross",822    "outputs": [],823    "stateMutability": "nonpayable",824    "type": "function"825  },826  {827    "inputs": [828      { "internalType": "address", "name": "from", "type": "address" },829      { "internalType": "address", "name": "to", "type": "address" },830      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }831    ],832    "name": "transferFrom",833    "outputs": [],834    "stateMutability": "nonpayable",835    "type": "function"836  },837  {838    "inputs": [839      {840        "components": [841          { "internalType": "address", "name": "eth", "type": "address" },842          { "internalType": "uint256", "name": "sub", "type": "uint256" }843        ],844        "internalType": "struct EthCrossAccount",845        "name": "from",846        "type": "tuple"847      },848      {849        "components": [850          { "internalType": "address", "name": "eth", "type": "address" },851          { "internalType": "uint256", "name": "sub", "type": "uint256" }852        ],853        "internalType": "struct EthCrossAccount",854        "name": "to",855        "type": "tuple"856      },857      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }858    ],859    "name": "transferFromCross",860    "outputs": [],861    "stateMutability": "nonpayable",862    "type": "function"863  },864  {865    "inputs": [],866    "name": "uniqueCollectionType",867    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],868    "stateMutability": "view",869    "type": "function"870  }871]
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -13,22 +13,29 @@
 }
 
 /// @title A contract that allows to set and delete token properties and change token property permissions.
-/// @dev the ERC-165 identifier for this interface is 0x91a97a68
+/// @dev the ERC-165 identifier for this interface is 0xde0695c2
 interface TokenProperties is Dummy, ERC165 {
+	// /// @notice Set permissions for token property.
+	// /// @dev Throws error if `msg.sender` is not admin or owner of the collection.
+	// /// @param key Property key.
+	// /// @param isMutable Permission to mutate property.
+	// /// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
+	// /// @param tokenOwner Permission to mutate property by token owner if property is mutable.
+	// /// @dev EVM selector for this function is: 0x222d97fa,
+	// ///  or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)
+	// function setTokenPropertyPermission(string memory key, bool isMutable, bool collectionAdmin, bool tokenOwner) external;
+
 	/// @notice Set permissions for token property.
 	/// @dev Throws error if `msg.sender` is not admin or owner of the collection.
-	/// @param key Property key.
-	/// @param isMutable Permission to mutate property.
-	/// @param collectionAdmin Permission to mutate property by collection admin if property is mutable.
-	/// @param tokenOwner Permission to mutate property by token owner if property is mutable.
-	/// @dev EVM selector for this function is: 0x222d97fa,
-	///  or in textual repr: setTokenPropertyPermission(string,bool,bool,bool)
-	function setTokenPropertyPermission(
-		string memory key,
-		bool isMutable,
-		bool collectionAdmin,
-		bool tokenOwner
-	) external;
+	/// @param permissions Permissions for keys.
+	/// @dev EVM selector for this function is: 0xbd92983a,
+	///  or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
+	function setTokenPropertyPermissions(Tuple47[] 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 (Tuple47[] memory);
 
 	// /// @notice Set token property value.
 	// /// @dev Throws error if `msg.sender` has no permission to edit the property.
@@ -79,6 +86,24 @@
 	bytes value;
 }
 
+enum EthTokenPermissions {
+	Mutable,
+	TokenOwner,
+	CollectionAdmin
+}
+
+/// @dev anonymous struct
+struct Tuple47 {
+	string field_0;
+	Tuple45[] field_1;
+}
+
+/// @dev anonymous struct
+struct Tuple45 {
+	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 0xb5e1747f
 interface Collection is Dummy, ERC165 {
modifiedtests/src/eth/events.test.tsdiffbeforeafterboth
--- a/tests/src/eth/events.test.ts
+++ b/tests/src/eth/events.test.ts
@@ -119,7 +119,7 @@
     ethEvents.push(event);
   });
   const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['PropertyPermissionSet']}]);
-  await collection.methods.setTokenPropertyPermission('testKey', true, true, true).send({from: owner});
+  await collection.methods.setTokenPropertyPermissions([['testKey', [[0, true], [1, true], [2, true]]]]).send({from: owner});
   await helper.wait.newBlocks(1);
   expect(ethEvents).to.be.like([
     {
@@ -374,7 +374,7 @@
   const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
   const result = await collection.methods.mint(owner).send({from: owner});
   const tokenId = result.events.Transfer.returnValues.tokenId;
-  await collection.methods.setTokenPropertyPermission('A', true, true, true).send({from: owner});
+  await collection.methods.setTokenPropertyPermissions([['A', [[0, true], [1, true], [2, true]]]]).send({from: owner});
 
 
   const ethEvents: any = [];
modifiedtests/src/eth/tokenProperties.test.tsdiffbeforeafterboth
--- a/tests/src/eth/tokenProperties.test.ts
+++ b/tests/src/eth/tokenProperties.test.ts
@@ -17,7 +17,7 @@
 import {IKeyringPair} from '@polkadot/types/types';
 import {Contract} from 'web3-eth-contract';
 import {itEth, usingEthPlaygrounds, expect} from './util';
-import {ITokenPropertyPermission} from '../util/playgrounds/types';
+import {ITokenPropertyPermission, TCollectionMode} from '../util/playgrounds/types';
 import {Pallets} from '../util';
 import {UniqueNFTCollection, UniqueNFToken, UniqueRFTCollection} from '../util/playgrounds/unique';
 
@@ -32,28 +32,32 @@
     });
   });
 
-  itEth('Can be reconfigured', async({helper}) => {
+  [
+    {mode: 'nft'},
+    {mode: 'rft'}
+  ].map(testCase =>
+  itEth(`[${testCase.mode}] Set and get token property permissions`, async({helper}) => {
     const owner = await helper.eth.createAccountWithBalance(donor);
-    const caller = await helper.eth.createAccountWithBalance(donor);
+    const caller = await helper.ethCrossAccount.createAccountWithBalance(donor);
+    const mode: any = testCase.mode;
     for(const [mutable,collectionAdmin, tokenOwner] of cartesian([], [false, true], [false, true], [false, true])) {
-      const collection = await helper.nft.mintCollection(alice);
-      await collection.addAdmin(alice, {Ethereum: caller});
+      const {collectionId, collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');
+      const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);
+      await collection.methods.addCollectionAdminCross(caller).send({from: owner});
+
+      await collection.methods.setTokenPropertyPermissions([['testKey', [[0, mutable], [1, tokenOwner], [2, collectionAdmin]]]]).send({from: caller.eth});
       
-      const address = helper.ethAddress.fromCollectionId(collection.collectionId);
-      const contract = helper.ethNativeContract.collection(address, 'nft', caller);
-  
-      await contract.methods.setTokenPropertyPermissions([['testKey', [[0, mutable], [1, tokenOwner], [2, collectionAdmin]]]]).send({from: caller});
-  
-      expect(await collection.getPropertyPermissions()).to.be.deep.equal([{
+      expect(await helper.nft.getPropertyPermissions(collectionId)).to.be.deep.equal([{
         key: 'testKey',
         permission: {mutable, collectionAdmin, tokenOwner},
       }]);
 
-      expect(await contract.methods.tokenPropertyPermissions().call({from: caller})).to.be.like([
+      expect(await collection.methods.tokenPropertyPermissions().call({from: caller.eth})).to.be.like([
         ['testKey', [['0', mutable], ['1', tokenOwner], ['2', collectionAdmin]]]
       ]);
     }
-  });
+  })
+  );
 
   [
     {