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

difftreelog

added `collectionNestingPermissions` funtion in `Collection` interface

PraetorP2022-12-06parent: #5223dbe.patch.diff
in: master

13 files changed

modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -26,7 +26,7 @@
 	weight,
 };
 use pallet_evm_coder_substrate::dispatch_to_evm;
-use sp_std::vec::Vec;
+use sp_std::{vec, vec::Vec};
 use up_data_structs::{
 	AccessMode, CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property,
 	SponsoringRateLimit, SponsorshipState,
@@ -35,7 +35,9 @@
 
 use crate::{
 	Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf,
-	eth::{EthCrossAccount, convert_cross_account_to_uint256},
+	eth::{
+		EthCrossAccount, convert_cross_account_to_uint256, CollectionPermissions as EvmPermissions,
+	},
 	weights::WeightInfo,
 };
 
@@ -508,6 +510,14 @@
 		))
 	}
 
+	/// Returns permissions for a collection
+	fn collection_nesting_permissions(&self) -> Result<Vec<(EvmPermissions, bool)>> {
+		let nesting = self.collection.permissions.nesting();
+		Ok(vec![
+			(EvmPermissions::CollectionAdmin, nesting.collection_admin),
+			(EvmPermissions::TokenOwner, nesting.token_owner),
+		])
+	}
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -155,3 +155,10 @@
 		}
 	}
 }
+#[derive(Default, Debug, Clone, Copy, AbiCoder)]
+#[repr(u8)]
+pub enum CollectionPermissions {
+	#[default]
+	CollectionAdmin,
+	TokenOwner,
+}
modifiedpallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
--- a/pallets/fungible/src/stubs/UniqueFungible.sol
+++ b/pallets/fungible/src/stubs/UniqueFungible.sol
@@ -18,7 +18,7 @@
 }
 
 /// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xeecfdb34
+/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
 contract Collection is Dummy, ERC165 {
 	// /// Set collection property.
 	// ///
@@ -263,6 +263,15 @@
 		return Tuple21(false, new uint256[](0));
 	}
 
+	/// Returns permissions for a collection
+	/// @dev EVM selector for this function is: 0x5b2eaf4b,
+	///  or in textual repr: collectionNestingPermissions()
+	function collectionNestingPermissions() public view returns (Tuple24[] memory) {
+		require(false, stub_error);
+		dummy;
+		return new Tuple24[](0);
+	}
+
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
@@ -434,6 +443,17 @@
 	uint256 sub;
 }
 
+enum CollectionPermissions {
+	CollectionAdmin,
+	TokenOwner
+}
+
+/// @dev anonymous struct
+struct Tuple24 {
+	CollectionPermissions field_0;
+	bool field_1;
+}
+
 /// @dev anonymous struct
 struct Tuple21 {
 	bool field_0;
modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -119,7 +119,7 @@
 }
 
 /// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xeecfdb34
+/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
 contract Collection is Dummy, ERC165 {
 	// /// Set collection property.
 	// ///
@@ -364,6 +364,15 @@
 		return Tuple34(false, new uint256[](0));
 	}
 
+	/// Returns permissions for a collection
+	/// @dev EVM selector for this function is: 0x5b2eaf4b,
+	///  or in textual repr: collectionNestingPermissions()
+	function collectionNestingPermissions() public view returns (Tuple37[] memory) {
+		require(false, stub_error);
+		dummy;
+		return new Tuple37[](0);
+	}
+
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
@@ -535,6 +544,17 @@
 	uint256 sub;
 }
 
+enum CollectionPermissions {
+	CollectionAdmin,
+	TokenOwner
+}
+
+/// @dev anonymous struct
+struct Tuple37 {
+	CollectionPermissions field_0;
+	bool field_1;
+}
+
 /// @dev anonymous struct
 struct Tuple34 {
 	bool field_0;
modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -119,7 +119,7 @@
 }
 
 /// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xeecfdb34
+/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
 contract Collection is Dummy, ERC165 {
 	// /// Set collection property.
 	// ///
@@ -364,6 +364,15 @@
 		return Tuple33(false, new uint256[](0));
 	}
 
+	/// Returns permissions for a collection
+	/// @dev EVM selector for this function is: 0x5b2eaf4b,
+	///  or in textual repr: collectionNestingPermissions()
+	function collectionNestingPermissions() public view returns (Tuple36[] memory) {
+		require(false, stub_error);
+		dummy;
+		return new Tuple36[](0);
+	}
+
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
@@ -535,6 +544,17 @@
 	uint256 sub;
 }
 
+enum CollectionPermissions {
+	CollectionAdmin,
+	TokenOwner
+}
+
+/// @dev anonymous struct
+struct Tuple36 {
+	CollectionPermissions field_0;
+	bool field_1;
+}
+
 /// @dev anonymous struct
 struct Tuple33 {
 	bool field_0;
modifiedtests/src/eth/abi/fungible.jsondiffbeforeafterboth
before · tests/src/eth/abi/fungible.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": "spender",15        "type": "address"16      },17      {18        "indexed": false,19        "internalType": "uint256",20        "name": "value",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": "from",34        "type": "address"35      },36      {37        "indexed": true,38        "internalType": "address",39        "name": "to",40        "type": "address"41      },42      {43        "indexed": false,44        "internalType": "uint256",45        "name": "value",46        "type": "uint256"47      }48    ],49    "name": "Transfer",50    "type": "event"51  },52  {53    "inputs": [54      {55        "components": [56          { "internalType": "address", "name": "eth", "type": "address" },57          { "internalType": "uint256", "name": "sub", "type": "uint256" }58        ],59        "internalType": "struct EthCrossAccount",60        "name": "newAdmin",61        "type": "tuple"62      }63    ],64    "name": "addCollectionAdminCross",65    "outputs": [],66    "stateMutability": "nonpayable",67    "type": "function"68  },69  {70    "inputs": [71      {72        "components": [73          { "internalType": "address", "name": "eth", "type": "address" },74          { "internalType": "uint256", "name": "sub", "type": "uint256" }75        ],76        "internalType": "struct EthCrossAccount",77        "name": "user",78        "type": "tuple"79      }80    ],81    "name": "addToCollectionAllowListCross",82    "outputs": [],83    "stateMutability": "nonpayable",84    "type": "function"85  },86  {87    "inputs": [88      { "internalType": "address", "name": "owner", "type": "address" },89      { "internalType": "address", "name": "spender", "type": "address" }90    ],91    "name": "allowance",92    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],93    "stateMutability": "view",94    "type": "function"95  },96  {97    "inputs": [98      {99        "components": [100          { "internalType": "address", "name": "eth", "type": "address" },101          { "internalType": "uint256", "name": "sub", "type": "uint256" }102        ],103        "internalType": "struct EthCrossAccount",104        "name": "user",105        "type": "tuple"106      }107    ],108    "name": "allowlistedCross",109    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],110    "stateMutability": "view",111    "type": "function"112  },113  {114    "inputs": [115      { "internalType": "address", "name": "spender", "type": "address" },116      { "internalType": "uint256", "name": "amount", "type": "uint256" }117    ],118    "name": "approve",119    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],120    "stateMutability": "nonpayable",121    "type": "function"122  },123  {124    "inputs": [125      {126        "components": [127          { "internalType": "address", "name": "eth", "type": "address" },128          { "internalType": "uint256", "name": "sub", "type": "uint256" }129        ],130        "internalType": "struct EthCrossAccount",131        "name": "spender",132        "type": "tuple"133      },134      { "internalType": "uint256", "name": "amount", "type": "uint256" }135    ],136    "name": "approveCross",137    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],138    "stateMutability": "nonpayable",139    "type": "function"140  },141  {142    "inputs": [143      { "internalType": "address", "name": "owner", "type": "address" }144    ],145    "name": "balanceOf",146    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],147    "stateMutability": "view",148    "type": "function"149  },150  {151    "inputs": [152      {153        "components": [154          { "internalType": "address", "name": "eth", "type": "address" },155          { "internalType": "uint256", "name": "sub", "type": "uint256" }156        ],157        "internalType": "struct EthCrossAccount",158        "name": "from",159        "type": "tuple"160      },161      { "internalType": "uint256", "name": "amount", "type": "uint256" }162    ],163    "name": "burnFromCross",164    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],165    "stateMutability": "nonpayable",166    "type": "function"167  },168  {169    "inputs": [170      {171        "components": [172          { "internalType": "address", "name": "eth", "type": "address" },173          { "internalType": "uint256", "name": "sub", "type": "uint256" }174        ],175        "internalType": "struct EthCrossAccount",176        "name": "newOwner",177        "type": "tuple"178      }179    ],180    "name": "changeCollectionOwnerCross",181    "outputs": [],182    "stateMutability": "nonpayable",183    "type": "function"184  },185  {186    "inputs": [],187    "name": "collectionAdmins",188    "outputs": [189      {190        "components": [191          { "internalType": "address", "name": "eth", "type": "address" },192          { "internalType": "uint256", "name": "sub", "type": "uint256" }193        ],194        "internalType": "struct EthCrossAccount[]",195        "name": "",196        "type": "tuple[]"197      }198    ],199    "stateMutability": "view",200    "type": "function"201  },202  {203    "inputs": [],204    "name": "collectionHelperAddress",205    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],206    "stateMutability": "view",207    "type": "function"208  },209  {210    "inputs": [],211    "name": "collectionNestingRestrictedCollectionIds",212    "outputs": [213      {214        "components": [215          { "internalType": "bool", "name": "field_0", "type": "bool" },216          {217            "internalType": "uint256[]",218            "name": "field_1",219            "type": "uint256[]"220          }221        ],222        "internalType": "struct Tuple21",223        "name": "",224        "type": "tuple"225      }226    ],227    "stateMutability": "view",228    "type": "function"229  },230  {231    "inputs": [],232    "name": "collectionOwner",233    "outputs": [234      {235        "components": [236          { "internalType": "address", "name": "eth", "type": "address" },237          { "internalType": "uint256", "name": "sub", "type": "uint256" }238        ],239        "internalType": "struct EthCrossAccount",240        "name": "",241        "type": "tuple"242      }243    ],244    "stateMutability": "view",245    "type": "function"246  },247  {248    "inputs": [249      { "internalType": "string[]", "name": "keys", "type": "string[]" }250    ],251    "name": "collectionProperties",252    "outputs": [253      {254        "components": [255          { "internalType": "string", "name": "key", "type": "string" },256          { "internalType": "bytes", "name": "value", "type": "bytes" }257        ],258        "internalType": "struct Property[]",259        "name": "",260        "type": "tuple[]"261      }262    ],263    "stateMutability": "view",264    "type": "function"265  },266  {267    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],268    "name": "collectionProperty",269    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],270    "stateMutability": "view",271    "type": "function"272  },273  {274    "inputs": [],275    "name": "collectionSponsor",276    "outputs": [277      {278        "components": [279          { "internalType": "address", "name": "field_0", "type": "address" },280          { "internalType": "uint256", "name": "field_1", "type": "uint256" }281        ],282        "internalType": "struct Tuple8",283        "name": "",284        "type": "tuple"285      }286    ],287    "stateMutability": "view",288    "type": "function"289  },290  {291    "inputs": [],292    "name": "confirmCollectionSponsorship",293    "outputs": [],294    "stateMutability": "nonpayable",295    "type": "function"296  },297  {298    "inputs": [],299    "name": "contractAddress",300    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],301    "stateMutability": "view",302    "type": "function"303  },304  {305    "inputs": [],306    "name": "decimals",307    "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],308    "stateMutability": "view",309    "type": "function"310  },311  {312    "inputs": [313      { "internalType": "string[]", "name": "keys", "type": "string[]" }314    ],315    "name": "deleteCollectionProperties",316    "outputs": [],317    "stateMutability": "nonpayable",318    "type": "function"319  },320  {321    "inputs": [],322    "name": "description",323    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],324    "stateMutability": "view",325    "type": "function"326  },327  {328    "inputs": [],329    "name": "hasCollectionPendingSponsor",330    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],331    "stateMutability": "view",332    "type": "function"333  },334  {335    "inputs": [336      {337        "components": [338          { "internalType": "address", "name": "eth", "type": "address" },339          { "internalType": "uint256", "name": "sub", "type": "uint256" }340        ],341        "internalType": "struct EthCrossAccount",342        "name": "user",343        "type": "tuple"344      }345    ],346    "name": "isOwnerOrAdminCross",347    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],348    "stateMutability": "view",349    "type": "function"350  },351  {352    "inputs": [353      { "internalType": "address", "name": "to", "type": "address" },354      { "internalType": "uint256", "name": "amount", "type": "uint256" }355    ],356    "name": "mint",357    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],358    "stateMutability": "nonpayable",359    "type": "function"360  },361  {362    "inputs": [363      {364        "components": [365          { "internalType": "address", "name": "field_0", "type": "address" },366          { "internalType": "uint256", "name": "field_1", "type": "uint256" }367        ],368        "internalType": "struct Tuple8[]",369        "name": "amounts",370        "type": "tuple[]"371      }372    ],373    "name": "mintBulk",374    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],375    "stateMutability": "nonpayable",376    "type": "function"377  },378  {379    "inputs": [],380    "name": "name",381    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],382    "stateMutability": "view",383    "type": "function"384  },385  {386    "inputs": [387      {388        "components": [389          { "internalType": "address", "name": "eth", "type": "address" },390          { "internalType": "uint256", "name": "sub", "type": "uint256" }391        ],392        "internalType": "struct EthCrossAccount",393        "name": "admin",394        "type": "tuple"395      }396    ],397    "name": "removeCollectionAdminCross",398    "outputs": [],399    "stateMutability": "nonpayable",400    "type": "function"401  },402  {403    "inputs": [],404    "name": "removeCollectionSponsor",405    "outputs": [],406    "stateMutability": "nonpayable",407    "type": "function"408  },409  {410    "inputs": [411      {412        "components": [413          { "internalType": "address", "name": "eth", "type": "address" },414          { "internalType": "uint256", "name": "sub", "type": "uint256" }415        ],416        "internalType": "struct EthCrossAccount",417        "name": "user",418        "type": "tuple"419      }420    ],421    "name": "removeFromCollectionAllowListCross",422    "outputs": [],423    "stateMutability": "nonpayable",424    "type": "function"425  },426  {427    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],428    "name": "setCollectionAccess",429    "outputs": [],430    "stateMutability": "nonpayable",431    "type": "function"432  },433  {434    "inputs": [435      { "internalType": "string", "name": "limit", "type": "string" },436      { "internalType": "uint256", "name": "value", "type": "uint256" }437    ],438    "name": "setCollectionLimit",439    "outputs": [],440    "stateMutability": "nonpayable",441    "type": "function"442  },443  {444    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],445    "name": "setCollectionMintMode",446    "outputs": [],447    "stateMutability": "nonpayable",448    "type": "function"449  },450  {451    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],452    "name": "setCollectionNesting",453    "outputs": [],454    "stateMutability": "nonpayable",455    "type": "function"456  },457  {458    "inputs": [459      { "internalType": "bool", "name": "enable", "type": "bool" },460      {461        "internalType": "address[]",462        "name": "collections",463        "type": "address[]"464      }465    ],466    "name": "setCollectionNesting",467    "outputs": [],468    "stateMutability": "nonpayable",469    "type": "function"470  },471  {472    "inputs": [473      {474        "components": [475          { "internalType": "string", "name": "key", "type": "string" },476          { "internalType": "bytes", "name": "value", "type": "bytes" }477        ],478        "internalType": "struct Property[]",479        "name": "properties",480        "type": "tuple[]"481      }482    ],483    "name": "setCollectionProperties",484    "outputs": [],485    "stateMutability": "nonpayable",486    "type": "function"487  },488  {489    "inputs": [490      {491        "components": [492          { "internalType": "address", "name": "eth", "type": "address" },493          { "internalType": "uint256", "name": "sub", "type": "uint256" }494        ],495        "internalType": "struct EthCrossAccount",496        "name": "sponsor",497        "type": "tuple"498      }499    ],500    "name": "setCollectionSponsorCross",501    "outputs": [],502    "stateMutability": "nonpayable",503    "type": "function"504  },505  {506    "inputs": [507      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }508    ],509    "name": "supportsInterface",510    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],511    "stateMutability": "view",512    "type": "function"513  },514  {515    "inputs": [],516    "name": "symbol",517    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],518    "stateMutability": "view",519    "type": "function"520  },521  {522    "inputs": [],523    "name": "totalSupply",524    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],525    "stateMutability": "view",526    "type": "function"527  },528  {529    "inputs": [530      { "internalType": "address", "name": "to", "type": "address" },531      { "internalType": "uint256", "name": "amount", "type": "uint256" }532    ],533    "name": "transfer",534    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],535    "stateMutability": "nonpayable",536    "type": "function"537  },538  {539    "inputs": [540      {541        "components": [542          { "internalType": "address", "name": "eth", "type": "address" },543          { "internalType": "uint256", "name": "sub", "type": "uint256" }544        ],545        "internalType": "struct EthCrossAccount",546        "name": "to",547        "type": "tuple"548      },549      { "internalType": "uint256", "name": "amount", "type": "uint256" }550    ],551    "name": "transferCross",552    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],553    "stateMutability": "nonpayable",554    "type": "function"555  },556  {557    "inputs": [558      { "internalType": "address", "name": "from", "type": "address" },559      { "internalType": "address", "name": "to", "type": "address" },560      { "internalType": "uint256", "name": "amount", "type": "uint256" }561    ],562    "name": "transferFrom",563    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],564    "stateMutability": "nonpayable",565    "type": "function"566  },567  {568    "inputs": [569      {570        "components": [571          { "internalType": "address", "name": "eth", "type": "address" },572          { "internalType": "uint256", "name": "sub", "type": "uint256" }573        ],574        "internalType": "struct EthCrossAccount",575        "name": "from",576        "type": "tuple"577      },578      {579        "components": [580          { "internalType": "address", "name": "eth", "type": "address" },581          { "internalType": "uint256", "name": "sub", "type": "uint256" }582        ],583        "internalType": "struct EthCrossAccount",584        "name": "to",585        "type": "tuple"586      },587      { "internalType": "uint256", "name": "amount", "type": "uint256" }588    ],589    "name": "transferFromCross",590    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],591    "stateMutability": "nonpayable",592    "type": "function"593  },594  {595    "inputs": [],596    "name": "uniqueCollectionType",597    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],598    "stateMutability": "view",599    "type": "function"600  }601]
after · tests/src/eth/abi/fungible.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": "spender",15        "type": "address"16      },17      {18        "indexed": false,19        "internalType": "uint256",20        "name": "value",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": "from",34        "type": "address"35      },36      {37        "indexed": true,38        "internalType": "address",39        "name": "to",40        "type": "address"41      },42      {43        "indexed": false,44        "internalType": "uint256",45        "name": "value",46        "type": "uint256"47      }48    ],49    "name": "Transfer",50    "type": "event"51  },52  {53    "inputs": [54      {55        "components": [56          { "internalType": "address", "name": "eth", "type": "address" },57          { "internalType": "uint256", "name": "sub", "type": "uint256" }58        ],59        "internalType": "struct EthCrossAccount",60        "name": "newAdmin",61        "type": "tuple"62      }63    ],64    "name": "addCollectionAdminCross",65    "outputs": [],66    "stateMutability": "nonpayable",67    "type": "function"68  },69  {70    "inputs": [71      {72        "components": [73          { "internalType": "address", "name": "eth", "type": "address" },74          { "internalType": "uint256", "name": "sub", "type": "uint256" }75        ],76        "internalType": "struct EthCrossAccount",77        "name": "user",78        "type": "tuple"79      }80    ],81    "name": "addToCollectionAllowListCross",82    "outputs": [],83    "stateMutability": "nonpayable",84    "type": "function"85  },86  {87    "inputs": [88      { "internalType": "address", "name": "owner", "type": "address" },89      { "internalType": "address", "name": "spender", "type": "address" }90    ],91    "name": "allowance",92    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],93    "stateMutability": "view",94    "type": "function"95  },96  {97    "inputs": [98      {99        "components": [100          { "internalType": "address", "name": "eth", "type": "address" },101          { "internalType": "uint256", "name": "sub", "type": "uint256" }102        ],103        "internalType": "struct EthCrossAccount",104        "name": "user",105        "type": "tuple"106      }107    ],108    "name": "allowlistedCross",109    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],110    "stateMutability": "view",111    "type": "function"112  },113  {114    "inputs": [115      { "internalType": "address", "name": "spender", "type": "address" },116      { "internalType": "uint256", "name": "amount", "type": "uint256" }117    ],118    "name": "approve",119    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],120    "stateMutability": "nonpayable",121    "type": "function"122  },123  {124    "inputs": [125      {126        "components": [127          { "internalType": "address", "name": "eth", "type": "address" },128          { "internalType": "uint256", "name": "sub", "type": "uint256" }129        ],130        "internalType": "struct EthCrossAccount",131        "name": "spender",132        "type": "tuple"133      },134      { "internalType": "uint256", "name": "amount", "type": "uint256" }135    ],136    "name": "approveCross",137    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],138    "stateMutability": "nonpayable",139    "type": "function"140  },141  {142    "inputs": [143      { "internalType": "address", "name": "owner", "type": "address" }144    ],145    "name": "balanceOf",146    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],147    "stateMutability": "view",148    "type": "function"149  },150  {151    "inputs": [152      {153        "components": [154          { "internalType": "address", "name": "eth", "type": "address" },155          { "internalType": "uint256", "name": "sub", "type": "uint256" }156        ],157        "internalType": "struct EthCrossAccount",158        "name": "from",159        "type": "tuple"160      },161      { "internalType": "uint256", "name": "amount", "type": "uint256" }162    ],163    "name": "burnFromCross",164    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],165    "stateMutability": "nonpayable",166    "type": "function"167  },168  {169    "inputs": [170      {171        "components": [172          { "internalType": "address", "name": "eth", "type": "address" },173          { "internalType": "uint256", "name": "sub", "type": "uint256" }174        ],175        "internalType": "struct EthCrossAccount",176        "name": "newOwner",177        "type": "tuple"178      }179    ],180    "name": "changeCollectionOwnerCross",181    "outputs": [],182    "stateMutability": "nonpayable",183    "type": "function"184  },185  {186    "inputs": [],187    "name": "collectionAdmins",188    "outputs": [189      {190        "components": [191          { "internalType": "address", "name": "eth", "type": "address" },192          { "internalType": "uint256", "name": "sub", "type": "uint256" }193        ],194        "internalType": "struct EthCrossAccount[]",195        "name": "",196        "type": "tuple[]"197      }198    ],199    "stateMutability": "view",200    "type": "function"201  },202  {203    "inputs": [],204    "name": "collectionHelperAddress",205    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],206    "stateMutability": "view",207    "type": "function"208  },209  {210    "inputs": [],211    "name": "collectionNestingPermissions",212    "outputs": [213      {214        "components": [215          {216            "internalType": "enum CollectionPermissions",217            "name": "field_0",218            "type": "uint8"219          },220          { "internalType": "bool", "name": "field_1", "type": "bool" }221        ],222        "internalType": "struct Tuple24[]",223        "name": "",224        "type": "tuple[]"225      }226    ],227    "stateMutability": "view",228    "type": "function"229  },230  {231    "inputs": [],232    "name": "collectionNestingRestrictedCollectionIds",233    "outputs": [234      {235        "components": [236          { "internalType": "bool", "name": "field_0", "type": "bool" },237          {238            "internalType": "uint256[]",239            "name": "field_1",240            "type": "uint256[]"241          }242        ],243        "internalType": "struct Tuple21",244        "name": "",245        "type": "tuple"246      }247    ],248    "stateMutability": "view",249    "type": "function"250  },251  {252    "inputs": [],253    "name": "collectionOwner",254    "outputs": [255      {256        "components": [257          { "internalType": "address", "name": "eth", "type": "address" },258          { "internalType": "uint256", "name": "sub", "type": "uint256" }259        ],260        "internalType": "struct EthCrossAccount",261        "name": "",262        "type": "tuple"263      }264    ],265    "stateMutability": "view",266    "type": "function"267  },268  {269    "inputs": [270      { "internalType": "string[]", "name": "keys", "type": "string[]" }271    ],272    "name": "collectionProperties",273    "outputs": [274      {275        "components": [276          { "internalType": "string", "name": "key", "type": "string" },277          { "internalType": "bytes", "name": "value", "type": "bytes" }278        ],279        "internalType": "struct Property[]",280        "name": "",281        "type": "tuple[]"282      }283    ],284    "stateMutability": "view",285    "type": "function"286  },287  {288    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],289    "name": "collectionProperty",290    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],291    "stateMutability": "view",292    "type": "function"293  },294  {295    "inputs": [],296    "name": "collectionSponsor",297    "outputs": [298      {299        "components": [300          { "internalType": "address", "name": "field_0", "type": "address" },301          { "internalType": "uint256", "name": "field_1", "type": "uint256" }302        ],303        "internalType": "struct Tuple8",304        "name": "",305        "type": "tuple"306      }307    ],308    "stateMutability": "view",309    "type": "function"310  },311  {312    "inputs": [],313    "name": "confirmCollectionSponsorship",314    "outputs": [],315    "stateMutability": "nonpayable",316    "type": "function"317  },318  {319    "inputs": [],320    "name": "contractAddress",321    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],322    "stateMutability": "view",323    "type": "function"324  },325  {326    "inputs": [],327    "name": "decimals",328    "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }],329    "stateMutability": "view",330    "type": "function"331  },332  {333    "inputs": [334      { "internalType": "string[]", "name": "keys", "type": "string[]" }335    ],336    "name": "deleteCollectionProperties",337    "outputs": [],338    "stateMutability": "nonpayable",339    "type": "function"340  },341  {342    "inputs": [],343    "name": "description",344    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],345    "stateMutability": "view",346    "type": "function"347  },348  {349    "inputs": [],350    "name": "hasCollectionPendingSponsor",351    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],352    "stateMutability": "view",353    "type": "function"354  },355  {356    "inputs": [357      {358        "components": [359          { "internalType": "address", "name": "eth", "type": "address" },360          { "internalType": "uint256", "name": "sub", "type": "uint256" }361        ],362        "internalType": "struct EthCrossAccount",363        "name": "user",364        "type": "tuple"365      }366    ],367    "name": "isOwnerOrAdminCross",368    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],369    "stateMutability": "view",370    "type": "function"371  },372  {373    "inputs": [374      { "internalType": "address", "name": "to", "type": "address" },375      { "internalType": "uint256", "name": "amount", "type": "uint256" }376    ],377    "name": "mint",378    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],379    "stateMutability": "nonpayable",380    "type": "function"381  },382  {383    "inputs": [384      {385        "components": [386          { "internalType": "address", "name": "field_0", "type": "address" },387          { "internalType": "uint256", "name": "field_1", "type": "uint256" }388        ],389        "internalType": "struct Tuple8[]",390        "name": "amounts",391        "type": "tuple[]"392      }393    ],394    "name": "mintBulk",395    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],396    "stateMutability": "nonpayable",397    "type": "function"398  },399  {400    "inputs": [],401    "name": "name",402    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],403    "stateMutability": "view",404    "type": "function"405  },406  {407    "inputs": [408      {409        "components": [410          { "internalType": "address", "name": "eth", "type": "address" },411          { "internalType": "uint256", "name": "sub", "type": "uint256" }412        ],413        "internalType": "struct EthCrossAccount",414        "name": "admin",415        "type": "tuple"416      }417    ],418    "name": "removeCollectionAdminCross",419    "outputs": [],420    "stateMutability": "nonpayable",421    "type": "function"422  },423  {424    "inputs": [],425    "name": "removeCollectionSponsor",426    "outputs": [],427    "stateMutability": "nonpayable",428    "type": "function"429  },430  {431    "inputs": [432      {433        "components": [434          { "internalType": "address", "name": "eth", "type": "address" },435          { "internalType": "uint256", "name": "sub", "type": "uint256" }436        ],437        "internalType": "struct EthCrossAccount",438        "name": "user",439        "type": "tuple"440      }441    ],442    "name": "removeFromCollectionAllowListCross",443    "outputs": [],444    "stateMutability": "nonpayable",445    "type": "function"446  },447  {448    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],449    "name": "setCollectionAccess",450    "outputs": [],451    "stateMutability": "nonpayable",452    "type": "function"453  },454  {455    "inputs": [456      { "internalType": "string", "name": "limit", "type": "string" },457      { "internalType": "uint256", "name": "value", "type": "uint256" }458    ],459    "name": "setCollectionLimit",460    "outputs": [],461    "stateMutability": "nonpayable",462    "type": "function"463  },464  {465    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],466    "name": "setCollectionMintMode",467    "outputs": [],468    "stateMutability": "nonpayable",469    "type": "function"470  },471  {472    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],473    "name": "setCollectionNesting",474    "outputs": [],475    "stateMutability": "nonpayable",476    "type": "function"477  },478  {479    "inputs": [480      { "internalType": "bool", "name": "enable", "type": "bool" },481      {482        "internalType": "address[]",483        "name": "collections",484        "type": "address[]"485      }486    ],487    "name": "setCollectionNesting",488    "outputs": [],489    "stateMutability": "nonpayable",490    "type": "function"491  },492  {493    "inputs": [494      {495        "components": [496          { "internalType": "string", "name": "key", "type": "string" },497          { "internalType": "bytes", "name": "value", "type": "bytes" }498        ],499        "internalType": "struct Property[]",500        "name": "properties",501        "type": "tuple[]"502      }503    ],504    "name": "setCollectionProperties",505    "outputs": [],506    "stateMutability": "nonpayable",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": "sponsor",518        "type": "tuple"519      }520    ],521    "name": "setCollectionSponsorCross",522    "outputs": [],523    "stateMutability": "nonpayable",524    "type": "function"525  },526  {527    "inputs": [528      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }529    ],530    "name": "supportsInterface",531    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],532    "stateMutability": "view",533    "type": "function"534  },535  {536    "inputs": [],537    "name": "symbol",538    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],539    "stateMutability": "view",540    "type": "function"541  },542  {543    "inputs": [],544    "name": "totalSupply",545    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],546    "stateMutability": "view",547    "type": "function"548  },549  {550    "inputs": [551      { "internalType": "address", "name": "to", "type": "address" },552      { "internalType": "uint256", "name": "amount", "type": "uint256" }553    ],554    "name": "transfer",555    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],556    "stateMutability": "nonpayable",557    "type": "function"558  },559  {560    "inputs": [561      {562        "components": [563          { "internalType": "address", "name": "eth", "type": "address" },564          { "internalType": "uint256", "name": "sub", "type": "uint256" }565        ],566        "internalType": "struct EthCrossAccount",567        "name": "to",568        "type": "tuple"569      },570      { "internalType": "uint256", "name": "amount", "type": "uint256" }571    ],572    "name": "transferCross",573    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],574    "stateMutability": "nonpayable",575    "type": "function"576  },577  {578    "inputs": [579      { "internalType": "address", "name": "from", "type": "address" },580      { "internalType": "address", "name": "to", "type": "address" },581      { "internalType": "uint256", "name": "amount", "type": "uint256" }582    ],583    "name": "transferFrom",584    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],585    "stateMutability": "nonpayable",586    "type": "function"587  },588  {589    "inputs": [590      {591        "components": [592          { "internalType": "address", "name": "eth", "type": "address" },593          { "internalType": "uint256", "name": "sub", "type": "uint256" }594        ],595        "internalType": "struct EthCrossAccount",596        "name": "from",597        "type": "tuple"598      },599      {600        "components": [601          { "internalType": "address", "name": "eth", "type": "address" },602          { "internalType": "uint256", "name": "sub", "type": "uint256" }603        ],604        "internalType": "struct EthCrossAccount",605        "name": "to",606        "type": "tuple"607      },608      { "internalType": "uint256", "name": "amount", "type": "uint256" }609    ],610    "name": "transferFromCross",611    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],612    "stateMutability": "nonpayable",613    "type": "function"614  },615  {616    "inputs": [],617    "name": "uniqueCollectionType",618    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],619    "stateMutability": "view",620    "type": "function"621  }622]
modifiedtests/src/eth/abi/nonFungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/nonFungible.json
+++ b/tests/src/eth/abi/nonFungible.json
@@ -238,6 +238,27 @@
   },
   {
     "inputs": [],
+    "name": "collectionNestingPermissions",
+    "outputs": [
+      {
+        "components": [
+          {
+            "internalType": "enum CollectionPermissions",
+            "name": "field_0",
+            "type": "uint8"
+          },
+          { "internalType": "bool", "name": "field_1", "type": "bool" }
+        ],
+        "internalType": "struct Tuple37[]",
+        "name": "",
+        "type": "tuple[]"
+      }
+    ],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [],
     "name": "collectionNestingRestrictedCollectionIds",
     "outputs": [
       {
modifiedtests/src/eth/abi/reFungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -220,6 +220,27 @@
   },
   {
     "inputs": [],
+    "name": "collectionNestingPermissions",
+    "outputs": [
+      {
+        "components": [
+          {
+            "internalType": "enum CollectionPermissions",
+            "name": "field_0",
+            "type": "uint8"
+          },
+          { "internalType": "bool", "name": "field_1", "type": "bool" }
+        ],
+        "internalType": "struct Tuple36[]",
+        "name": "",
+        "type": "tuple[]"
+      }
+    ],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
+    "inputs": [],
     "name": "collectionNestingRestrictedCollectionIds",
     "outputs": [
       {
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -13,7 +13,7 @@
 }
 
 /// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xeecfdb34
+/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
 interface Collection is Dummy, ERC165 {
 	// /// Set collection property.
 	// ///
@@ -171,6 +171,11 @@
 	///  or in textual repr: collectionNestingRestrictedCollectionIds()
 	function collectionNestingRestrictedCollectionIds() external view returns (Tuple20 memory);
 
+	/// Returns permissions for a collection
+	/// @dev EVM selector for this function is: 0x5b2eaf4b,
+	///  or in textual repr: collectionNestingPermissions()
+	function collectionNestingPermissions() external view returns (Tuple23[] memory);
+
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
@@ -284,6 +289,17 @@
 }
 
 /// @dev anonymous struct
+struct Tuple23 {
+	CollectionPermissions field_0;
+	bool field_1;
+}
+
+enum CollectionPermissions {
+	CollectionAdmin,
+	TokenOwner
+}
+
+/// @dev anonymous struct
 struct Tuple20 {
 	bool field_0;
 	uint256[] field_1;
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -80,7 +80,7 @@
 }
 
 /// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xeecfdb34
+/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
 interface Collection is Dummy, ERC165 {
 	// /// Set collection property.
 	// ///
@@ -238,6 +238,11 @@
 	///  or in textual repr: collectionNestingRestrictedCollectionIds()
 	function collectionNestingRestrictedCollectionIds() external view returns (Tuple31 memory);
 
+	/// Returns permissions for a collection
+	/// @dev EVM selector for this function is: 0x5b2eaf4b,
+	///  or in textual repr: collectionNestingPermissions()
+	function collectionNestingPermissions() external view returns (Tuple34[] memory);
+
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
@@ -351,6 +356,17 @@
 }
 
 /// @dev anonymous struct
+struct Tuple34 {
+	CollectionPermissions field_0;
+	bool field_1;
+}
+
+enum CollectionPermissions {
+	CollectionAdmin,
+	TokenOwner
+}
+
+/// @dev anonymous struct
 struct Tuple31 {
 	bool field_0;
 	uint256[] field_1;
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -80,7 +80,7 @@
 }
 
 /// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0xeecfdb34
+/// @dev the ERC-165 identifier for this interface is 0xb5e1747f
 interface Collection is Dummy, ERC165 {
 	// /// Set collection property.
 	// ///
@@ -238,6 +238,11 @@
 	///  or in textual repr: collectionNestingRestrictedCollectionIds()
 	function collectionNestingRestrictedCollectionIds() external view returns (Tuple30 memory);
 
+	/// Returns permissions for a collection
+	/// @dev EVM selector for this function is: 0x5b2eaf4b,
+	///  or in textual repr: collectionNestingPermissions()
+	function collectionNestingPermissions() external view returns (Tuple33[] memory);
+
 	/// Set the collection access method.
 	/// @param mode Access mode
 	/// 	0 for Normal
@@ -351,6 +356,17 @@
 }
 
 /// @dev anonymous struct
+struct Tuple33 {
+	CollectionPermissions field_0;
+	bool field_1;
+}
+
+enum CollectionPermissions {
+	CollectionAdmin,
+	TokenOwner
+}
+
+/// @dev anonymous struct
 struct Tuple30 {
 	bool field_0;
 	uint256[] field_1;
modifiedtests/src/eth/nesting/nest.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nesting/nest.test.ts
+++ b/tests/src/eth/nesting/nest.test.ts
@@ -52,7 +52,7 @@
       expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(owner);
     });
     
-    itEth('NFT: collectionNestingRestrictedCollectionIds()', async ({helper}) => {
+    itEth('NFT: collectionNestingRestrictedCollectionIds() & collectionNestingPermissions', async ({helper}) => {
       const owner = await helper.eth.createAccountWithBalance(donor);
       const {collectionId: unnestedCollsectionId, collectionAddress: unnsetedCollectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
       const unnestedContract = helper.ethNativeContract.collection(unnsetedCollectionAddress, 'nft', owner);
@@ -62,7 +62,9 @@
       expect(await contract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([true, []]);
       await contract.methods.setCollectionNesting(true, [unnsetedCollectionAddress]).send({from: owner});
       expect(await contract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([true, [unnestedCollsectionId.toString()]]);
-      
+      expect(await contract.methods.collectionNestingPermissions().call({from: owner})).to.be.like([['0', false], ['1', true]]);
+      await contract.methods.setCollectionNesting(false).send({from: owner});
+      expect(await contract.methods.collectionNestingPermissions().call({from: owner})).to.be.like([['0', false], ['1', false]]);
     });
     
     itEth('NFT: allows an Owner to nest/unnest their token (Restricted nesting)', async ({helper}) => {