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
--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -679,12 +679,29 @@
   },
   {
     "inputs": [
-      { "internalType": "string", "name": "key", "type": "string" },
-      { "internalType": "bool", "name": "isMutable", "type": "bool" },
-      { "internalType": "bool", "name": "collectionAdmin", "type": "bool" },
-      { "internalType": "bool", "name": "tokenOwner", "type": "bool" }
+      {
+        "components": [
+          { "internalType": "string", "name": "field_0", "type": "string" },
+          {
+            "components": [
+              {
+                "internalType": "enum EthTokenPermissions",
+                "name": "field_0",
+                "type": "uint8"
+              },
+              { "internalType": "bool", "name": "field_1", "type": "bool" }
+            ],
+            "internalType": "struct Tuple51[]",
+            "name": "field_1",
+            "type": "tuple[]"
+          }
+        ],
+        "internalType": "struct Tuple53[]",
+        "name": "permissions",
+        "type": "tuple[]"
+      }
     ],
-    "name": "setTokenPropertyPermission",
+    "name": "setTokenPropertyPermissions",
     "outputs": [],
     "stateMutability": "nonpayable",
     "type": "function"
@@ -734,6 +751,35 @@
     "type": "function"
   },
   {
+    "inputs": [],
+    "name": "tokenPropertyPermissions",
+    "outputs": [
+      {
+        "components": [
+          { "internalType": "string", "name": "field_0", "type": "string" },
+          {
+            "components": [
+              {
+                "internalType": "enum EthTokenPermissions",
+                "name": "field_0",
+                "type": "uint8"
+              },
+              { "internalType": "bool", "name": "field_1", "type": "bool" }
+            ],
+            "internalType": "struct Tuple51[]",
+            "name": "field_1",
+            "type": "tuple[]"
+          }
+        ],
+        "internalType": "struct Tuple53[]",
+        "name": "",
+        "type": "tuple[]"
+      }
+    ],
+    "stateMutability": "view",
+    "type": "function"
+  },
+  {
     "inputs": [
       { "internalType": "uint256", "name": "tokenId", "type": "uint256" }
     ],
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
before · tests/src/eth/events.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {expect} from 'chai';18import {IKeyringPair} from '@polkadot/types/types';19import {EthUniqueHelper, itEth, usingEthPlaygrounds} from './util';20import {IEvent, TCollectionMode} from '../util/playgrounds/types';21import {Pallets, requirePalletsOrSkip} from '../util';22import {NormalizedEvent} from './util/playgrounds/types';2324let donor: IKeyringPair;25  26before(async function () {27  await usingEthPlaygrounds(async (_helper, privateKey) => {28    donor = await privateKey({filename: __filename});29  });30});3132function clearEvents(ethEvents: NormalizedEvent[], subEvents: IEvent[]) {33  ethEvents.splice(0);34  subEvents.splice(0);35}3637async function testCollectionCreatedAndDestroy(helper: EthUniqueHelper, mode: TCollectionMode) {38  const owner = await helper.eth.createAccountWithBalance(donor);39  const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionCreated', 'CollectionDestroyed']}]);40  const {collectionAddress, events: ethEvents} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');41  await helper.wait.newBlocks(1);42  {43    expect(ethEvents).to.be.like([44      {45        event: 'CollectionCreated',46        args: {47          owner: owner,48          collectionId: collectionAddress,49        },50      },51    ]);52    expect(subEvents).to.be.like([{method: 'CollectionCreated'}]);53    clearEvents(ethEvents, subEvents);54  }55  {56    const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);57    const result = await collectionHelper.methods.destroyCollection(collectionAddress).send({from:owner});58    await helper.wait.newBlocks(1);59    expect(result.events).to.be.like({60      CollectionDestroyed: {61        returnValues: {62          collectionId: collectionAddress,63        },64      },65    });66    expect(subEvents).to.be.like([{method: 'CollectionDestroyed'}]);67  }68  unsubscribe();69}7071async function testCollectionPropertySetAndDeleted(helper: EthUniqueHelper, mode: TCollectionMode) {72  const owner = await helper.eth.createAccountWithBalance(donor);73  const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');74  const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);75  const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);76    77  const ethEvents: any = [];78  collectionHelper.events.allEvents((_: any, event: any) => {79    ethEvents.push(event);80  });81  const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionPropertySet', 'CollectionPropertyDeleted']}]);82  {83    await collection.methods.setCollectionProperties([{key: 'A', value: [0,1,2,3]}]).send({from:owner});84    await helper.wait.newBlocks(1);85    expect(ethEvents).to.be.like([86      {87        event: 'CollectionChanged',88        returnValues: {89          collectionId: collectionAddress,90        },91      },92    ]);93    expect(subEvents).to.be.like([{method: 'CollectionPropertySet'}]);94    clearEvents(ethEvents, subEvents);95  }96  {97    await collection.methods.deleteCollectionProperties(['A']).send({from:owner});98    await helper.wait.newBlocks(1);99    expect(ethEvents).to.be.like([100      {101        event: 'CollectionChanged',102        returnValues: {103          collectionId: collectionAddress,104        },105      },106    ]);107    expect(subEvents).to.be.like([{method: 'CollectionPropertyDeleted'}]);108  }109  unsubscribe();110}111112async function testPropertyPermissionSet(helper: EthUniqueHelper, mode: TCollectionMode) {113  const owner = await helper.eth.createAccountWithBalance(donor);114  const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');115  const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);116  const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);117  const ethEvents: any = [];118  collectionHelper.events.allEvents((_: any, event: any) => {119    ethEvents.push(event);120  });121  const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['PropertyPermissionSet']}]);122  await collection.methods.setTokenPropertyPermission('testKey', true, true, true).send({from: owner});123  await helper.wait.newBlocks(1);124  expect(ethEvents).to.be.like([125    {126      event: 'CollectionChanged',127      returnValues: {128        collectionId: collectionAddress,129      },130    },131  ]);132  expect(subEvents).to.be.like([{method: 'PropertyPermissionSet'}]);133  unsubscribe();134}135136async function testAllowListAddressAddedAndRemoved(helper: EthUniqueHelper, mode: TCollectionMode) {137  const owner = await helper.eth.createAccountWithBalance(donor);138  const user = helper.ethCrossAccount.createAccount();139  const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');140  const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);141  const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);142  const ethEvents: any[] = [];143  collectionHelper.events.allEvents((_: any, event: any) => {144    ethEvents.push(event);145  });146147  const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['AllowListAddressAdded', 'AllowListAddressRemoved']}]);148  {149    await collection.methods.addToCollectionAllowListCross(user).send({from: owner});150    await helper.wait.newBlocks(1);151    expect(ethEvents).to.be.like([152      {153        event: 'CollectionChanged',154        returnValues: {155          collectionId: collectionAddress,156        },157      },158    ]);159    expect(subEvents).to.be.like([{method: 'AllowListAddressAdded'}]);160    clearEvents(ethEvents, subEvents);161  }162  {163    await collection.methods.removeFromCollectionAllowListCross(user).send({from: owner});164    await helper.wait.newBlocks(1);165    expect(ethEvents.length).to.be.eq(1);166    expect(ethEvents).to.be.like([167      {168        event: 'CollectionChanged',169        returnValues: {170          collectionId: collectionAddress,171        },172      },173    ]);174    expect(subEvents).to.be.like([{method: 'AllowListAddressRemoved'}]);175  }176  unsubscribe();177}178179async function testCollectionAdminAddedAndRemoved(helper: EthUniqueHelper, mode: TCollectionMode) {180  const owner = await helper.eth.createAccountWithBalance(donor);181  const user = helper.ethCrossAccount.createAccount();182  const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');183  const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);184  const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);185  const ethEvents: any = [];186  collectionHelper.events.allEvents((_: any, event: any) => {187    ethEvents.push(event);188  });189  const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionAdminAdded', 'CollectionAdminRemoved']}]);190  {191    await collection.methods.addCollectionAdminCross(user).send({from: owner});192    await helper.wait.newBlocks(1);193    expect(ethEvents).to.be.like([194      {195        event: 'CollectionChanged',196        returnValues: {197          collectionId: collectionAddress,198        },199      },200    ]);201    expect(subEvents).to.be.like([{method: 'CollectionAdminAdded'}]);202    clearEvents(ethEvents, subEvents);203  }204  {205    await collection.methods.removeCollectionAdminCross(user).send({from: owner});206    await helper.wait.newBlocks(1);207    expect(ethEvents).to.be.like([208      {209        event: 'CollectionChanged',210        returnValues: {211          collectionId: collectionAddress,212        },213      },214    ]);215    expect(subEvents).to.be.like([{method: 'CollectionAdminRemoved'}]);216  }217  unsubscribe();218}219220async function testCollectionLimitSet(helper: EthUniqueHelper, mode: TCollectionMode) {221  const owner = await helper.eth.createAccountWithBalance(donor);222  const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');223  const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);224  const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);225  const ethEvents: any = [];226  collectionHelper.events.allEvents((_: any, event: any) => {227    ethEvents.push(event);228  });229  const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionLimitSet']}]);230  {231    await collection.methods.setCollectionLimit('ownerCanTransfer', 0n).send({from: owner});232    await helper.wait.newBlocks(1);233    expect(ethEvents).to.be.like([234      {235        event: 'CollectionChanged',236        returnValues: {237          collectionId: collectionAddress,238        },239      },240    ]);241    expect(subEvents).to.be.like([{method: 'CollectionLimitSet'}]);242  }243  unsubscribe();244}245246async function testCollectionOwnerChanged(helper: EthUniqueHelper, mode: TCollectionMode) {247  const owner = await helper.eth.createAccountWithBalance(donor);248  const newOwner = helper.ethCrossAccount.createAccount();249  const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');250  const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);251  const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);252  const ethEvents: any = [];253  collectionHelper.events.allEvents((_: any, event: any) => {254    ethEvents.push(event);255  });256  const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionOwnerChanged']}]);257  {258    await collection.methods.changeCollectionOwnerCross(newOwner).send({from: owner});259    await helper.wait.newBlocks(1);260    expect(ethEvents).to.be.like([261      {262        event: 'CollectionChanged',263        returnValues: {264          collectionId: collectionAddress,265        },266      },267    ]);268    expect(subEvents).to.be.like([{method: 'CollectionOwnerChanged'}]);269  }270  unsubscribe();271}272273async function testCollectionPermissionSet(helper: EthUniqueHelper, mode: TCollectionMode) {274  const owner = await helper.eth.createAccountWithBalance(donor);275  const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');276  const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);277  const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);278  const ethEvents: any = [];279  collectionHelper.events.allEvents((_: any, event: any) => {280    ethEvents.push(event);281  });282  const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['CollectionPermissionSet']}]);283  {284    await collection.methods.setCollectionMintMode(true).send({from: owner});285    await helper.wait.newBlocks(1);286    expect(ethEvents).to.be.like([287      {288        event: 'CollectionChanged',289        returnValues: {290          collectionId: collectionAddress,291        },292      },293    ]);294    expect(subEvents).to.be.like([{method: 'CollectionPermissionSet'}]);295    clearEvents(ethEvents, subEvents);296  }297  {298    await collection.methods.setCollectionAccess(1).send({from: owner});299    await helper.wait.newBlocks(1);300    expect(ethEvents).to.be.like([301      {302        event: 'CollectionChanged',303        returnValues: {304          collectionId: collectionAddress,305        },306      },307    ]);308    expect(subEvents).to.be.like([{method: 'CollectionPermissionSet'}]);309  }310  unsubscribe();311}312313async function testCollectionSponsorSetAndConfirmedAndThenRemoved(helper: EthUniqueHelper, mode: TCollectionMode) {314  const owner = await helper.eth.createAccountWithBalance(donor);315  const sponsor = await helper.ethCrossAccount.createAccountWithBalance(donor);316  const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');317  const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);318  const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);319  const ethEvents: any = [];320  collectionHelper.events.allEvents((_: any, event: any) => {321    ethEvents.push(event);322  });323  const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{324    section: 'common', names: ['CollectionSponsorSet', 'SponsorshipConfirmed', 'CollectionSponsorRemoved',325    ]}]);326  {327    await collection.methods.setCollectionSponsorCross(sponsor).send({from: owner});328    await helper.wait.newBlocks(1);329    expect(ethEvents).to.be.like([330      {331        event: 'CollectionChanged',332        returnValues: {333          collectionId: collectionAddress,334        },335      },336    ]);337    expect(subEvents).to.be.like([{method: 'CollectionSponsorSet'}]);338    clearEvents(ethEvents, subEvents);339  }340  {341    await collection.methods.confirmCollectionSponsorship().send({from: sponsor.eth});342    await helper.wait.newBlocks(1);343    expect(ethEvents).to.be.like([344      {345        event: 'CollectionChanged',346        returnValues: {347          collectionId: collectionAddress,348        },349      },350    ]);351    expect(subEvents).to.be.like([{method: 'SponsorshipConfirmed'}]);352    clearEvents(ethEvents, subEvents);353  }354  {355    await collection.methods.removeCollectionSponsor().send({from: owner});356    await helper.wait.newBlocks(1);357    expect(ethEvents).to.be.like([358      {359        event: 'CollectionChanged',360        returnValues: {361          collectionId: collectionAddress,362        },363      },364    ]);365    expect(subEvents).to.be.like([{method: 'CollectionSponsorRemoved'}]);366  }367  unsubscribe();368}369370async function testTokenPropertySetAndDeleted(helper: EthUniqueHelper, mode: TCollectionMode) {371  const owner = await helper.eth.createAccountWithBalance(donor);372  const {collectionAddress} = await helper.eth.createCollection(mode, owner, 'A', 'B', 'C');373  const collection = await helper.ethNativeContract.collection(collectionAddress, mode, owner);374  const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);375  const result = await collection.methods.mint(owner).send({from: owner});376  const tokenId = result.events.Transfer.returnValues.tokenId;377  await collection.methods.setTokenPropertyPermission('A', true, true, true).send({from: owner});378379380  const ethEvents: any = [];381  collectionHelper.events.allEvents((_: any, event: any) => {382    ethEvents.push(event);383  });384  const {unsubscribe, collectedEvents: subEvents} = await helper.subscribeEvents([{section: 'common', names: ['TokenPropertySet', 'TokenPropertyDeleted']}]);385  {386    await collection.methods.setProperties(tokenId, [{key: 'A', value: [1,2,3]}]).send({from: owner});387    await helper.wait.newBlocks(1);388    expect(ethEvents).to.be.like([389      {390        event: 'TokenChanged',391        returnValues: {392          collectionId: collectionAddress,393        },394      },395    ]);396    expect(subEvents).to.be.like([{method: 'TokenPropertySet'}]);397    clearEvents(ethEvents, subEvents);398  }399  {400    await collection.methods.deleteProperties(tokenId, ['A']).send({from: owner});401    await helper.wait.newBlocks(1);402    expect(ethEvents).to.be.like([403      {404        event: 'TokenChanged',405        returnValues: {406          collectionId: collectionAddress,407        },408      },409    ]);410    expect(subEvents).to.be.like([{method: 'TokenPropertyDeleted'}]);411  }412  unsubscribe();413}414415describe('[FT] Sync sub & eth events', () => {416  const mode: TCollectionMode = 'ft';417418  itEth('CollectionCreated and CollectionDestroyed events', async ({helper}) => {419    await testCollectionCreatedAndDestroy(helper, mode);420  });421422  itEth('CollectionChanged event for CollectionPropertySet and CollectionPropertyDeleted', async ({helper}) => {423    await testCollectionPropertySetAndDeleted(helper, mode);424  });425    426  itEth('CollectionChanged event for AllowListAddressAdded, AllowListAddressRemoved', async ({helper}) => {427    await testAllowListAddressAddedAndRemoved(helper, mode);428  });429    430  itEth('CollectionChanged event for CollectionAdminAdded, CollectionAdminRemoved', async ({helper}) => {431    await testCollectionAdminAddedAndRemoved(helper, mode);432  });433    434  itEth('CollectionChanged event for CollectionLimitSet', async ({helper}) => {435    await testCollectionLimitSet(helper, mode);436  });437    438  itEth('CollectionChanged event for CollectionOwnerChanged', async ({helper}) => {439    await testCollectionOwnerChanged(helper, mode);440  });441    442  itEth('CollectionChanged event for CollectionPermissionSet', async ({helper}) => {443    await testCollectionPermissionSet(helper, mode);444  });445446  itEth('CollectionChanged event for CollectionSponsorSet, SponsorshipConfirmed, CollectionSponsorRemoved', async ({helper}) => {447    await testCollectionSponsorSetAndConfirmedAndThenRemoved(helper, mode);448  });449});450451describe('[NFT] Sync sub & eth events', () => {452  const mode: TCollectionMode = 'nft';453454  itEth('CollectionCreated and CollectionDestroyed events', async ({helper}) => {455    await testCollectionCreatedAndDestroy(helper, mode);456  });457458  itEth('CollectionChanged event for CollectionPropertySet and CollectionPropertyDeleted', async ({helper}) => {459    await testCollectionPropertySetAndDeleted(helper, mode);460  });461    462  itEth('CollectionChanged event for PropertyPermissionSet', async ({helper}) => {463    await testPropertyPermissionSet(helper, mode);464  });465    466  itEth('CollectionChanged event for AllowListAddressAdded, AllowListAddressRemoved', async ({helper}) => {467    await testAllowListAddressAddedAndRemoved(helper, mode);468  });469    470  itEth('CollectionChanged event for CollectionAdminAdded, CollectionAdminRemoved', async ({helper}) => {471    await testCollectionAdminAddedAndRemoved(helper, mode);472  });473    474  itEth('CollectionChanged event for CollectionLimitSet', async ({helper}) => {475    await testCollectionLimitSet(helper, mode);476  });477    478  itEth('CollectionChanged event for CollectionOwnerChanged', async ({helper}) => {479    await testCollectionOwnerChanged(helper, mode);480  });481    482  itEth('CollectionChanged event for CollectionPermissionSet', async ({helper}) => {483    await testCollectionPermissionSet(helper, mode);484  });485486  itEth('CollectionChanged event for CollectionSponsorSet, SponsorshipConfirmed, CollectionSponsorRemoved', async ({helper}) => {487    await testCollectionSponsorSetAndConfirmedAndThenRemoved(helper, mode);488  });489     490  itEth('CollectionChanged event for TokenPropertySet, TokenPropertyDeleted', async ({helper}) => {491    await testTokenPropertySetAndDeleted(helper, mode);492  });493});494495describe('[RFT] Sync sub & eth events', () => {496  const mode: TCollectionMode = 'rft';497498  before(async function() {499    await usingEthPlaygrounds(async (helper, privateKey) => {500      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);501      const _donor = await privateKey({filename: __filename});502    });503  });504505  itEth('CollectionCreated and CollectionDestroyed events', async ({helper}) => {506    await testCollectionCreatedAndDestroy(helper, mode);507  });508509  itEth('CollectionChanged event for CollectionPropertySet and CollectionPropertyDeleted', async ({helper}) => {510    await testCollectionPropertySetAndDeleted(helper, mode);511  });512    513  itEth('CollectionChanged event for PropertyPermissionSet', async ({helper}) => {514    await testPropertyPermissionSet(helper, mode);515  });516    517  itEth('CollectionChanged event for AllowListAddressAdded, AllowListAddressRemoved', async ({helper}) => {518    await testAllowListAddressAddedAndRemoved(helper, mode);519  });520    521  itEth('CollectionChanged event for CollectionAdminAdded, CollectionAdminRemoved', async ({helper}) => {522    await testCollectionAdminAddedAndRemoved(helper, mode);523  });524    525  itEth('CollectionChanged event for CollectionLimitSet', async ({helper}) => {526    await testCollectionLimitSet(helper, mode);527  });528    529  itEth('CollectionChanged event for CollectionOwnerChanged', async ({helper}) => {530    await testCollectionOwnerChanged(helper, mode);531  });532    533  itEth('CollectionChanged event for CollectionPermissionSet', async ({helper}) => {534    await testCollectionPermissionSet(helper, mode);535  });536537  itEth('CollectionChanged event for CollectionSponsorSet, SponsorshipConfirmed, CollectionSponsorRemoved', async ({helper}) => {538    await testCollectionSponsorSetAndConfirmedAndThenRemoved(helper, mode);539  });540     541  itEth('CollectionChanged event for TokenPropertySet, TokenPropertyDeleted', async ({helper}) => {542    await testTokenPropertySetAndDeleted(helper, mode);543  });544});
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]]]
       ]);
     }
-  });
+  })
+  );
 
   [
     {