git.delta.rocks / unique-network / refs/commits / 2203d0f0ed69

difftreelog

Tests: refactor fractionalizer tests to playgrounds

Andrey2022-10-03parent: #239c99e.patch.diff
in: master

3 files changed

modifiedtests/package.jsondiffbeforeafterboth
before · tests/package.json
1{2  "name": "unique-tests",3  "version": "1.0.0",4  "description": "Unique Chain Tests",5  "main": "",6  "devDependencies": {7    "@polkadot/ts": "0.4.22",8    "@polkadot/typegen": "9.2.2",9    "@types/chai": "^4.3.1",10    "@types/chai-as-promised": "^7.1.5",11    "@types/chai-like": "^1.1.1",12    "@types/mocha": "^9.1.1",13    "@types/node": "^17.0.35",14    "@typescript-eslint/eslint-plugin": "^5.26.0",15    "@typescript-eslint/parser": "^5.26.0",16    "chai": "^4.3.6",17    "eslint": "^8.16.0",18    "mocha": "^10.0.0",19    "ts-node": "^10.8.0",20    "typescript": "^4.7.2"21  },22  "mocha": {23    "timeout": 9999999,24    "require": "ts-node/register"25  },26  "scripts": {27    "lint": "eslint --ext .ts,.js src/",28    "fix": "eslint --ext .ts,.js src/ --fix",29    "test": "mocha --timeout 9999999 -r ts-node/register './src/**/*.test.ts'",30    "testEth": "mocha --timeout 9999999 -r ts-node/register './**/eth/**/*.test.ts'",31    "testEthMarketplace": "mocha --timeout 9999999 -r ts-node/register './**/eth/marketplace/**/*.test.ts'",32    "testEthNesting": "mocha --timeout 9999999 -r ts-node/register './**/eth/nesting/**/*.test.ts'",33    "testEthPayable": "mocha --timeout 9999999 -r ts-node/register './**/eth/payable.test.ts'",34    "load": "mocha --timeout 9999999 -r ts-node/register './**/*.load.ts'",35    "loadTransfer": "ts-node src/transfer.nload.ts",36    "testCollision": "mocha --timeout 9999999 -r ts-node/register ./src/collision-tests/*.test.ts",37    "testEvent": "mocha --timeout 9999999 -r ts-node/register ./src/check-event/*.test.ts",38    "testNesting": "mocha --timeout 9999999 -r ts-node/register ./**/nest.test.ts",39    "testUnnesting": "mocha --timeout 9999999 -r ts-node/register ./**/unnest.test.ts",40    "testStructure": "mocha --timeout 9999999 -r ts-node/register ./**/nesting/**.test.ts",41    "testProperties": "mocha --timeout 9999999 -r ts-node/register ./**/properties.test.ts ./**/getPropertiesRpc.test.ts",42    "testMigration": "mocha --timeout 9999999 -r ts-node/register ./**/nesting/migration-check.test.ts",43    "testRmrk": "mocha --timeout 9999999 -r ts-node/register ./**/rmrk/**.test.ts",44    "testAddCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/addCollectionAdmin.test.ts",45    "testSetSchemaVersion": "mocha --timeout 9999999 -r ts-node/register ./**/setSchemaVersion.test.ts",46    "testSetCollectionLimits": "mocha --timeout 9999999 -r ts-node/register ./**/setCollectionLimits.test.ts",47    "testChangeCollectionOwner": "mocha --timeout 9999999 -r ts-node/register ./**/change-collection-owner.test.ts",48    "testSetCollectionSponsor": "mocha --timeout 9999999 -r ts-node/register ./**/setCollectionSponsor.test.ts",49    "testConfirmSponsorship": "mocha --timeout 9999999 -r ts-node/register ./**/confirmSponsorship.test.ts",50    "testRemoveCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/removeCollectionAdmin.test.ts",51    "testRemoveCollectionSponsor": "mocha --timeout 9999999 -r ts-node/register ./**/removeCollectionSponsor.test.ts",52    "testAllowLists": "mocha --timeout 9999999 -r ts-node/register ./**/allowLists.test.ts",53    "testConnection": "mocha --timeout 9999999 -r ts-node/register ./**/connection.test.ts",54    "testContracts": "mocha --timeout 9999999 -r ts-node/register ./**/contracts.test.ts",55    "testCreateItem": "mocha --timeout 9999999 -r ts-node/register ./**/createItem.test.ts",56    "testCreateMultipleItems": "mocha --timeout 9999999 -r ts-node/register ./**/createMultipleItems.test.ts",57    "testCreateMultipleItemsEx": "mocha --timeout 9999999 -r ts-node/register ./**/createMultipleItemsEx.test.ts",58    "testApprove": "mocha --timeout 9999999 -r ts-node/register ./**/approve.test.ts",59    "testTransferFrom": "mocha --timeout 9999999 -r ts-node/register ./**/transferFrom.test.ts",60    "testCreateCollection": "mocha --timeout 9999999 -r ts-node/register ./**/createCollection.test.ts",61    "testDestroyCollection": "mocha --timeout 9999999 -r ts-node/register ./**/destroyCollection.test.ts",62    "testToggleContractAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/toggleContractAllowList.test.ts",63    "testAddToContractAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/addToContractAllowList.test.ts",64    "testTransfer": "mocha --timeout 9999999 -r ts-node/register ./**/transfer.test.ts",65    "testBurnItem": "mocha --timeout 9999999 -r ts-node/register ./**/burnItem.test.ts",66    "testAdminTransferAndBurn": "mocha --timeout 9999999 -r ts-node/register ./**/adminTransferAndBurn.test.ts",67    "testSetPermissions": "mocha --timeout 9999999 -r ts-node/register ./**/setPermissions.test.ts",68    "testCreditFeesToTreasury": "mocha --timeout 9999999 -r ts-node/register ./**/creditFeesToTreasury.test.ts",69    "testContractSponsoring": "mocha --timeout 9999999 -r ts-node/register ./**/contractSponsoring.test.ts",70    "testEnableContractSponsoring": "mocha --timeout 9999999 -r ts-node/register ./**/enableContractSponsoring.test.ts",71    "testRemoveFromContractAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/removeFromContractAllowList.test.ts",72    "testSetContractSponsoringRateLimit": "mocha --timeout 9999999 -r ts-node/register ./**/setContractSponsoringRateLimit.test.ts",73    "testSetOffchainSchema": "mocha --timeout 9999999 -r ts-node/register ./**/setOffchainSchema.test.ts",74    "testNextSponsoring": "mocha --timeout 9999999 -r ts-node/register ./**/nextSponsoring.test.ts",75    "testOverflow": "mocha --timeout 9999999 -r ts-node/register ./**/overflow.test.ts",76    "testInflation": "mocha --timeout 9999999 -r ts-node/register ./**/inflation.test.ts",77    "testScheduler": "mocha --timeout 9999999 -r ts-node/register ./**/scheduler.test.ts",78    "testSchedulingEVM": "mocha --timeout 9999999 -r ts-node/register ./**/eth/scheduling.test.ts",79    "testXcmUnique": "RUN_XCM_TESTS=1 mocha --timeout 9999999 -r ts-node/register ./**/xcm/xcmUnique.test.ts",80    "testXcmQuartz": "RUN_XCM_TESTS=1 mocha --timeout 9999999 -r ts-node/register ./**/xcm/xcmQuartz.test.ts",81    "testXcmOpal": "RUN_XCM_TESTS=1 mocha --timeout 9999999 -r ts-node/register ./**/xcm/xcmOpal.test.ts",82    "testXcmTransferAcala": "mocha --timeout 9999999 -r ts-node/register ./**/xcm/xcmTransferAcala.test.ts acalaId=2000 uniqueId=5000",83    "testXcmTransferStatemine": "mocha --timeout 9999999 -r ts-node/register ./**/xcm/xcmTransferStatemine.test.ts statemineId=1000 uniqueId=5000",84    "testXcmTransferMoonbeam": "mocha --timeout 9999999 -r ts-node/register ./**/xcm/xcmTransferMoonbeam.test.ts",85    "testPalletPresence": "mocha --timeout 9999999 -r ts-node/register ./**/pallet-presence.test.ts",86    "testBlockProduction": "mocha --timeout 9999999 -r ts-node/register ./**/block-production.test.ts",87    "testEnableDisableTransfers": "mocha --timeout 9999999 -r ts-node/register ./**/enableDisableTransfer.test.ts",88    "testLimits": "mocha --timeout 9999999 -r ts-node/register ./**/limits.test.ts",89    "testEthCreateNFTCollection": "mocha --timeout 9999999 -r ts-node/register ./**/eth/createNFTCollection.test.ts",90    "testEthCreateRFTCollection": "mocha --timeout 9999999 -r ts-node/register ./**/eth/createRFTCollection.test.ts",91    "testEthNFT": "mocha --timeout 9999999 -r ts-node/register ./**/eth/nonFungible.test.ts",92    "testRFT": "mocha --timeout 9999999 -r ts-node/register ./**/refungible.test.ts",93    "testEthRFT": "mocha --timeout 9999999 -r ts-node/register ./**/eth/reFungible.test.ts ./**/eth/reFungibleToken.test.ts",94    "testFT": "mocha --timeout 9999999 -r ts-node/register ./**/fungible.test.ts",95    "testEthFT": "mocha --timeout 9999999 -r ts-node/register ./**/eth/fungible.test.ts",96    "testRPC": "mocha --timeout 9999999 -r ts-node/register ./**/rpc.test.ts",97    "testPromotion": "mocha --timeout 9999999 -r ts-node/register ./**/app-promotion.test.ts",98    "polkadot-types-fetch-metadata": "curl -H 'Content-Type: application/json' -d '{\"id\":\"1\", \"jsonrpc\":\"2.0\", \"method\": \"state_getMetadata\", \"params\":[]}' http://localhost:9933 > src/interfaces/metadata.json",99    "polkadot-types-from-defs": "ts-node ./node_modules/.bin/polkadot-types-from-defs --endpoint src/interfaces/metadata.json --input src/interfaces/ --package .",100    "polkadot-types-from-chain": "ts-node ./node_modules/.bin/polkadot-types-from-chain --endpoint src/interfaces/metadata.json --output src/interfaces/ --package .",101    "polkadot-types": "echo \"export default {}\" > src/interfaces/lookup.ts && yarn polkadot-types-fetch-metadata && yarn polkadot-types-from-defs && yarn polkadot-types-from-defs && yarn polkadot-types-from-chain"102  },103  "author": "",104  "license": "SEE LICENSE IN ../LICENSE",105  "homepage": "",106  "dependencies": {107    "@polkadot/api": "9.2.2",108    "@polkadot/api-contract": "9.2.2",109    "@polkadot/util-crypto": "10.1.7",110    "bignumber.js": "^9.0.2",111    "chai-as-promised": "^7.1.1",112    "chai-like": "^1.1.1",113    "find-process": "^1.4.7",114    "solc": "0.8.14-fixed",115    "web3": "^1.7.3"116  },117  "standard": {118    "globals": [119      "it",120      "assert",121      "beforeEach",122      "afterEach",123      "describe",124      "contract",125      "artifacts"126    ]127  },128  "resolutions": {129    "simple-get": "^4.0.1"130  }131}
modifiedtests/src/eth/fractionalizer/fractionalizer.test.tsdiffbeforeafterboth
--- a/tests/src/eth/fractionalizer/fractionalizer.test.ts
+++ b/tests/src/eth/fractionalizer/fractionalizer.test.ts
@@ -15,98 +15,61 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 
-import Web3 from 'web3';
-import {ApiPromise} from '@polkadot/api';
+import {readFile} from 'fs/promises';
+
+import {IKeyringPair} from '@polkadot/types/types';
 import {evmToAddress} from '@polkadot/util-crypto';
-import {readFile} from 'fs/promises';
-import {executeTransaction, submitTransactionAsync} from '../../substrate/substrate-api';
-import {getCreateCollectionResult, getCreateItemResult, UNIQUE, requirePallets, Pallets} from '../../util/helpers';
-import {collectionIdToAddress, CompiledContract, createEthAccountWithBalance, createNonfungibleCollection, createRFTCollection, GAS_ARGS, itWeb3, tokenIdFromAddress, uniqueNFT, uniqueRefungible, uniqueRefungibleToken} from '../util/helpers';
+
 import {Contract} from 'web3-eth-contract';
-import * as solc from 'solc';
 
-import chai from 'chai';
-import chaiLike from 'chai-like';
-import {IKeyringPair} from '@polkadot/types/types';
-chai.use(chaiLike);
-const expect = chai.expect;
-let fractionalizer: CompiledContract;
+import {usingEthPlaygrounds, expect, itEth, EthUniqueHelper} from '../util/playgrounds';
+import {CompiledContract} from '../util/playgrounds/types';
+import {requirePalletsOrSkip, Pallets} from '../../util/playgrounds';
+
 
-async function compileFractionalizer() {
-  if (!fractionalizer) {
-    const input = {
-      language: 'Solidity',
-      sources: {
-        ['Fractionalizer.sol']: {
-          content: (await readFile(`${__dirname}/Fractionalizer.sol`)).toString(),
-        },
-      },
-      settings: {
-        outputSelection: {
-          '*': {
-            '*': ['*'],
-          },
-        },
-      },
-    };
-    const json = JSON.parse(solc.compile(JSON.stringify(input), {import: await findImports()}));
-    const out = json.contracts['Fractionalizer.sol']['Fractionalizer'];
+let compiledFractionalizer: CompiledContract;
 
-    fractionalizer = {
-      abi: out.abi,
-      object: '0x' + out.evm.bytecode.object,
-    };
+const compileContract = async (helper: EthUniqueHelper): Promise<CompiledContract> => {
+  if(!compiledFractionalizer) {
+    compiledFractionalizer = await helper.ethContract.compile('Fractionalizer', (await readFile(`${__dirname}/Fractionalizer.sol`)).toString(), [
+      {solPath: 'api/CollectionHelpers.sol', fsPath: `${__dirname}/../api/CollectionHelpers.sol`},
+      {solPath: 'api/ContractHelpers.sol', fsPath: `${__dirname}/../api/ContractHelpers.sol`},
+      {solPath: 'api/UniqueRefungibleToken.sol', fsPath: `${__dirname}/../api/UniqueRefungibleToken.sol`},
+      {solPath: 'api/UniqueRefungible.sol', fsPath: `${__dirname}/../api/UniqueRefungible.sol`},
+      {solPath: 'api/UniqueNFT.sol', fsPath: `${__dirname}/../api/UniqueNFT.sol`},
+    ]);
   }
-  return fractionalizer;
+  return compiledFractionalizer;
 }
 
-async function findImports() {
-  const collectionHelpers = (await readFile(`${__dirname}/../api/CollectionHelpers.sol`)).toString();
-  const contractHelpers = (await readFile(`${__dirname}/../api/ContractHelpers.sol`)).toString();
-  const uniqueRefungibleToken = (await readFile(`${__dirname}/../api/UniqueRefungibleToken.sol`)).toString();
-  const uniqueRefungible = (await readFile(`${__dirname}/../api/UniqueRefungible.sol`)).toString();
-  const uniqueNFT = (await readFile(`${__dirname}/../api/UniqueNFT.sol`)).toString();
 
-  return function(path: string) {
-    switch (path) {
-      case 'api/CollectionHelpers.sol': return {contents: `${collectionHelpers}`};
-      case 'api/ContractHelpers.sol': return {contents: `${contractHelpers}`};
-      case 'api/UniqueRefungibleToken.sol': return {contents: `${uniqueRefungibleToken}`};
-      case 'api/UniqueRefungible.sol': return {contents: `${uniqueRefungible}`};
-      case 'api/UniqueNFT.sol': return {contents: `${uniqueNFT}`};
-      default: return {error: 'File not found'};
-    }
-  };
+const deployContract = async (helper: EthUniqueHelper, owner: string): Promise<Contract> => {
+  const compiled = await compileContract(helper);
+  return await helper.ethContract.deployByAbi(owner, compiled.abi, compiled.object);
 }
 
-async function deployFractionalizer(web3: Web3, owner: string) {
-  const compiled = await compileFractionalizer();
-  const fractionalizerContract = new web3.eth.Contract(compiled.abi, undefined, {
-    data: compiled.object,
-    from: owner,
-    ...GAS_ARGS,
-  });
-  return await fractionalizerContract.deploy({data: compiled.object}).send({from: owner});
-}
 
-async function initFractionalizer(api: ApiPromise, web3: Web3, privateKeyWrapper: (account: string) => IKeyringPair, owner: string) {
-  const fractionalizer = await deployFractionalizer(web3, owner);
-  const amount = 10n * UNIQUE;
-  await web3.eth.sendTransaction({from: owner, to: fractionalizer.options.address, value: `${amount}`, ...GAS_ARGS});
-  const result = await fractionalizer.methods.createAndSetRFTCollection('A', 'B', 'C').send({value: Number(2n * UNIQUE)});
+const initContract = async (helper: EthUniqueHelper, owner: string): Promise<{contract: Contract, rftCollectionAddress: string}> => {
+  const fractionalizer = await deployContract(helper, owner);
+  const amount = 10n * helper.balance.getOneTokenNominal();
+  const web3 = helper.getWeb3();
+  await web3.eth.sendTransaction({from: owner, to: fractionalizer.options.address, value: `${amount}`, gas: helper.eth.DEFAULT_GAS});
+  const result = await fractionalizer.methods.createAndSetRFTCollection('A', 'B', 'C').send({value: Number(2n * helper.balance.getOneTokenNominal())});
   const rftCollectionAddress = result.events.RFTCollectionSet.returnValues._collection;
-  return {fractionalizer, rftCollectionAddress};
+  return {contract: fractionalizer, rftCollectionAddress};
 }
 
-async function createRFTToken(api: ApiPromise, web3: Web3, owner: string, fractionalizer: Contract, amount: bigint) {
-  const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
-  const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+const mintRFTToken = async (helper: EthUniqueHelper, owner: string, fractionalizer: Contract, amount: bigint): Promise<{
+  nftCollectionAddress: string, nftTokenId: number, rftTokenAddress: string
+}> => {
+  const nftCollection = await helper.eth.createNonfungibleCollection(owner, 'nft', 'NFT collection', 'NFT');
+  const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
   const nftTokenId = await nftContract.methods.nextTokenId().call();
-  await nftContract.methods.mint(owner, nftTokenId).send();
+  await nftContract.methods.mint(owner, nftTokenId).send({from: owner});
 
-  await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send();
-  await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send();
-  const result = await fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, amount).send();
+  await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});
+  await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});
+  const result = await fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, amount).send({from: owner});
   const {_collection, _tokenId, _rftToken} = result.events.Fractionalized.returnValues;
   return {
     nftCollectionAddress: _collection,
@@ -115,104 +78,111 @@
   };
 }
 
+
 describe('Fractionalizer contract usage', () => {
+  let donor: IKeyringPair;
+
   before(async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+    await usingEthPlaygrounds(async (helper: EthUniqueHelper, privateKey) => {
+      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
+      donor = privateKey('//Alice');
+    });
   });
 
-  itWeb3('Set RFT collection', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    const fractionalizer = await deployFractionalizer(web3, owner);
-    const {collectionIdAddress} = await createRFTCollection(api, web3, owner);
-    const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
-    await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send();
-    const result = await fractionalizer.methods.setRFTCollection(collectionIdAddress).send();
+  itEth('Set RFT collection', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 10n);
+    const fractionalizer = await deployContract(helper, owner);
+    const rftCollection = await helper.eth.createRefungibleCollection(owner, 'rft', 'RFT collection', 'RFT');
+    const rftContract = helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);
+
+    await rftContract.methods.addCollectionAdmin(fractionalizer.options.address).send({from: owner});
+    const result = await fractionalizer.methods.setRFTCollection(rftCollection.collectionAddress).send({from: owner});
     expect(result.events).to.be.like({
       RFTCollectionSet: {
         returnValues: {
-          _collection: collectionIdAddress,
+          _collection: rftCollection.collectionAddress,
         },
       },
     });
   });
 
-  itWeb3('Mint RFT collection', async ({api, web3, privateKeyWrapper}) => {
-    const alice = privateKeyWrapper('//Alice');
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    const fractionalizer = await deployFractionalizer(web3, owner);
-    const tx = api.tx.balances.transfer(evmToAddress(fractionalizer.options.address), 10n * UNIQUE);
-    await executeTransaction(api, alice, tx);
+  itEth('Mint RFT collection', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 10n);
+    const fractionalizer = await deployContract(helper, owner);
+    await helper.balance.transferToSubstrate(donor, evmToAddress(fractionalizer.options.address), 10n * helper.balance.getOneTokenNominal());
 
-    const result = await fractionalizer.methods.createAndSetRFTCollection('A', 'B', 'C').send({from: owner, value: Number(2n * UNIQUE)});
+    const result = await fractionalizer.methods.createAndSetRFTCollection('A', 'B', 'C').send({from: owner, value: Number(2n * helper.balance.getOneTokenNominal())});
     expect(result.events).to.be.like({
       RFTCollectionSet: {},
     });
     expect(result.events.RFTCollectionSet.returnValues._collection).to.be.ok;
   });
 
-  itWeb3('Set Allowlist', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
-    const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
-    const result1 = await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send({from: owner});
+  itEth('Set Allowlist', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
+    const {contract: fractionalizer} = await initContract(helper, owner);
+    const nftCollection = await helper.eth.createNonfungibleCollection(owner, 'nft', 'NFT collection', 'NFT');
+
+    const result1 = await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});
     expect(result1.events).to.be.like({
       AllowListSet: {
         returnValues: {
-          _collection: nftCollectionAddress,
+          _collection: nftCollection.collectionAddress,
           _status: true,
         },
       },
     });
-    const result2 = await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, false).send({from: owner});
+    const result2 = await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, false).send({from: owner});
     expect(result2.events).to.be.like({
       AllowListSet: {
         returnValues: {
-          _collection: nftCollectionAddress,
+          _collection: nftCollection.collectionAddress,
           _status: false,
         },
       },
     });
   });
 
-  itWeb3('NFT to RFT', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  itEth('NFT to RFT', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
 
-    const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
-    const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+    const nftCollection = await helper.eth.createNonfungibleCollection(owner, 'nft', 'NFT collection', 'NFT');
+    const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
     const nftTokenId = await nftContract.methods.nextTokenId().call();
-    await nftContract.methods.mint(owner, nftTokenId).send();
+    await nftContract.methods.mint(owner, nftTokenId).send({from: owner});
 
-    const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
+    const {contract: fractionalizer} = await initContract(helper, owner);
 
-    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send();
-    await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send();
-    const result = await fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100).send();
+    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});
+    await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});
+    const result = await fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, 100).send({from: owner});
     expect(result.events).to.be.like({
       Fractionalized: {
         returnValues: {
-          _collection: nftCollectionAddress,
+          _collection: nftCollection.collectionAddress,
           _tokenId: nftTokenId,
           _amount: '100',
         },
       },
     });
     const rftTokenAddress = result.events.Fractionalized.returnValues._rftToken;
-    const rftTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);
+
+    const rftTokenContract = helper.ethNativeContract.rftToken(rftTokenAddress);
     expect(await rftTokenContract.methods.balanceOf(owner).call()).to.equal('100');
   });
 
-  itWeb3('RFT to NFT', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  itEth('RFT to NFT', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
 
-    const {fractionalizer, rftCollectionAddress} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
-    const {rftTokenAddress, nftCollectionAddress, nftTokenId} = await createRFTToken(api, web3, owner, fractionalizer, 100n);
+    const {contract: fractionalizer, rftCollectionAddress} = await initContract(helper, owner);
+    const {rftTokenAddress, nftCollectionAddress, nftTokenId} = await mintRFTToken(helper, owner, fractionalizer, 100n);
 
-    const {collectionId, tokenId} = tokenIdFromAddress(rftTokenAddress);
-    const refungibleAddress = collectionIdToAddress(collectionId);
+    const {collectionId, tokenId} = helper.ethAddress.extractTokenId(rftTokenAddress);
+    const refungibleAddress = helper.ethAddress.fromCollectionId(collectionId);
     expect(rftCollectionAddress).to.be.equal(refungibleAddress);
-    const refungibleTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);
-    await refungibleTokenContract.methods.approve(fractionalizer.options.address, 100).send();
-    const result = await fractionalizer.methods.rft2nft(refungibleAddress, tokenId).send();
+    const refungibleTokenContract = helper.ethNativeContract.rftToken(rftTokenAddress, owner);
+    await refungibleTokenContract.methods.approve(fractionalizer.options.address, 100).send({from: owner});
+    const result = await fractionalizer.methods.rft2nft(refungibleAddress, tokenId).send({from: owner});
     expect(result.events).to.be.like({
       Defractionalized: {
         returnValues: {
@@ -224,17 +194,17 @@
     });
   });
 
-  itWeb3('Test fractionalizer NFT <-> RFT mapping ', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  itEth('Test fractionalizer NFT <-> RFT mapping ', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
 
-    const {fractionalizer, rftCollectionAddress} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
-    const {rftTokenAddress, nftCollectionAddress, nftTokenId} = await createRFTToken(api, web3, owner, fractionalizer, 100n);
+    const {contract: fractionalizer, rftCollectionAddress} = await initContract(helper, owner);
+    const {rftTokenAddress, nftCollectionAddress, nftTokenId} = await mintRFTToken(helper, owner, fractionalizer, 100n);
 
-    const {collectionId, tokenId} = tokenIdFromAddress(rftTokenAddress);
-    const refungibleAddress = collectionIdToAddress(collectionId);
+    const {collectionId, tokenId} = helper.ethAddress.extractTokenId(rftTokenAddress);
+    const refungibleAddress = helper.ethAddress.fromCollectionId(collectionId);
     expect(rftCollectionAddress).to.be.equal(refungibleAddress);
-    const refungibleTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);
-    await refungibleTokenContract.methods.approve(fractionalizer.options.address, 100).send();
+    const refungibleTokenContract = helper.ethNativeContract.rftToken(rftTokenAddress, owner);
+    await refungibleTokenContract.methods.approve(fractionalizer.options.address, 100).send({from: owner});
 
     const rft2nft = await fractionalizer.methods.rft2nftMapping(rftTokenAddress).call();
     expect(rft2nft).to.be.like({
@@ -250,251 +220,227 @@
 
 
 describe('Negative Integration Tests for fractionalizer', () => {
+  let donor: IKeyringPair;
+
   before(async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+    await usingEthPlaygrounds(async (helper: EthUniqueHelper, privateKey) => {
+      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
+      donor = privateKey('//Alice');
+    });
   });
 
-  itWeb3('call setRFTCollection twice', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    const {collectionIdAddress} = await createRFTCollection(api, web3, owner);
-    const refungibleContract = uniqueRefungible(web3, collectionIdAddress, owner);
+  itEth('call setRFTCollection twice', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
+    const rftCollection = await helper.eth.createRefungibleCollection(owner, 'rft', 'RFT collection', 'RFT');
+    const refungibleContract = helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);
 
-    const fractionalizer = await deployFractionalizer(web3, owner);
-    await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send();
-    await fractionalizer.methods.setRFTCollection(collectionIdAddress).send();
+    const fractionalizer = await deployContract(helper, owner);
+    await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send({from: owner});
+    await fractionalizer.methods.setRFTCollection(rftCollection.collectionAddress).send({from: owner});
 
-    await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())
+    await expect(fractionalizer.methods.setRFTCollection(rftCollection.collectionAddress).call())
       .to.be.rejectedWith(/RFT collection is already set$/g);
   });
 
-  itWeb3('call setRFTCollection with NFT collection', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    const {collectionIdAddress} = await createNonfungibleCollection(api, web3, owner);
-    const nftContract = uniqueNFT(web3, collectionIdAddress, owner);
+  itEth('call setRFTCollection with NFT collection', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
+    const nftCollection = await helper.eth.createNonfungibleCollection(owner, 'nft', 'NFT collection', 'NFT');
+    const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
 
-    const fractionalizer = await deployFractionalizer(web3, owner);
-    await nftContract.methods.addCollectionAdmin(fractionalizer.options.address).send();
+    const fractionalizer = await deployContract(helper, owner);
+    await nftContract.methods.addCollectionAdmin(fractionalizer.options.address).send({from: owner});
 
-    await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())
+    await expect(fractionalizer.methods.setRFTCollection(nftCollection.collectionAddress).call())
       .to.be.rejectedWith(/Wrong collection type. Collection is not refungible.$/g);
   });
 
-  itWeb3('call setRFTCollection while not collection admin', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    const fractionalizer = await deployFractionalizer(web3, owner);
-    const {collectionIdAddress} = await createRFTCollection(api, web3, owner);
+  itEth('call setRFTCollection while not collection admin', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
+    const fractionalizer = await deployContract(helper, owner);
+    const rftCollection = await helper.eth.createRefungibleCollection(owner, 'rft', 'RFT collection', 'RFT');
 
-    await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())
+    await expect(fractionalizer.methods.setRFTCollection(rftCollection.collectionAddress).call())
       .to.be.rejectedWith(/Fractionalizer contract should be an admin of the collection$/g);
   });
 
-  itWeb3('call setRFTCollection after createAndSetRFTCollection', async ({api, web3, privateKeyWrapper}) => {
-    const alice = privateKeyWrapper('//Alice');
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    const fractionalizer = await deployFractionalizer(web3, owner);
-    const tx = api.tx.balances.transfer(evmToAddress(fractionalizer.options.address), 10n * UNIQUE);
-    await submitTransactionAsync(alice, tx);
+  itEth('call setRFTCollection after createAndSetRFTCollection', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
+    const fractionalizer = await deployContract(helper, owner);
+    await helper.balance.transferToSubstrate(donor, evmToAddress(fractionalizer.options.address), 10n * helper.balance.getOneTokenNominal());
 
-    const result = await fractionalizer.methods.createAndSetRFTCollection('A', 'B', 'C').send({from: owner, value: Number(2n * UNIQUE)});
+    const result = await fractionalizer.methods.createAndSetRFTCollection('A', 'B', 'C').send({from: owner, value: Number(2n * helper.balance.getOneTokenNominal())});
     const collectionIdAddress = result.events.RFTCollectionSet.returnValues._collection;
 
     await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())
       .to.be.rejectedWith(/RFT collection is already set$/g);
   });
 
-  itWeb3('call nft2rft without setting RFT collection for contract', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  itEth('call nft2rft without setting RFT collection for contract', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
 
-    const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
-    const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+    const nftCollection = await helper.eth.createNonfungibleCollection(owner, 'nft', 'NFT collection', 'NFT');
+    const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
     const nftTokenId = await nftContract.methods.nextTokenId().call();
-    await nftContract.methods.mint(owner, nftTokenId).send();
+    await nftContract.methods.mint(owner, nftTokenId).send({from: owner});
 
-    const fractionalizer = await deployFractionalizer(web3, owner);
+    const fractionalizer = await deployContract(helper, owner);
 
-    await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100).call())
+    await expect(fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, 100).call())
       .to.be.rejectedWith(/RFT collection is not set$/g);
   });
 
-  itWeb3('call nft2rft while not owner of NFT token', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    const nftOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  itEth('call nft2rft while not owner of NFT token', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
+    const nftOwner = await helper.eth.createAccountWithBalance(donor, 10n);
 
-    const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
-    const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+    const nftCollection = await helper.eth.createNonfungibleCollection(owner, 'nft', 'NFT collection', 'NFT');
+    const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
     const nftTokenId = await nftContract.methods.nextTokenId().call();
-    await nftContract.methods.mint(owner, nftTokenId).send();
-    await nftContract.methods.transfer(nftOwner, 1).send();
+    await nftContract.methods.mint(owner, nftTokenId).send({from: owner});
+    await nftContract.methods.transfer(nftOwner, 1).send({from: owner});
 
 
-    const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
-    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send();
+    const {contract: fractionalizer} = await initContract(helper, owner);
+    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});
 
-    await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100).call())
+    await expect(fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, 100).call({from: owner}))
       .to.be.rejectedWith(/Only token owner could fractionalize it$/g);
   });
 
-  itWeb3('call nft2rft while not in list of allowed accounts', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  itEth('call nft2rft while not in list of allowed accounts', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
 
-    const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
-    const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+    const nftCollection = await helper.eth.createNonfungibleCollection(owner, 'nft', 'NFT collection', 'NFT');
+    const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
     const nftTokenId = await nftContract.methods.nextTokenId().call();
-    await nftContract.methods.mint(owner, nftTokenId).send();
+    await nftContract.methods.mint(owner, nftTokenId).send({from: owner});
 
-    const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
+    const {contract: fractionalizer} = await initContract(helper, owner);
 
-    await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send();
-    await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100).call())
+    await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});
+    await expect(fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, 100).call())
       .to.be.rejectedWith(/Fractionalization of this collection is not allowed by admin$/g);
   });
 
-  itWeb3('call nft2rft while fractionalizer doesnt have approval for nft token', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  itEth('call nft2rft while fractionalizer doesnt have approval for nft token', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
 
-    const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
-    const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+    const nftCollection = await helper.eth.createNonfungibleCollection(owner, 'nft', 'NFT collection', 'NFT');
+    const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
     const nftTokenId = await nftContract.methods.nextTokenId().call();
-    await nftContract.methods.mint(owner, nftTokenId).send();
+    await nftContract.methods.mint(owner, nftTokenId).send({from: owner});
 
-    const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
+    const {contract: fractionalizer} = await initContract(helper, owner);
 
-    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send();
-    await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100).call())
+    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});
+    await expect(fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, 100).call())
       .to.be.rejectedWith(/ApprovedValueTooLow$/g);
   });
 
-  itWeb3('call rft2nft without setting RFT collection for contract', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  itEth('call rft2nft without setting RFT collection for contract', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
 
-    const fractionalizer = await deployFractionalizer(web3, owner);
-    const {collectionIdAddress: rftCollectionAddress} = await createRFTCollection(api, web3, owner);
-    const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);
+    const fractionalizer = await deployContract(helper, owner);
+    const rftCollection = await helper.eth.createRefungibleCollection(owner, 'rft', 'RFT collection', 'RFT');
+    const refungibleContract = helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);
     const rftTokenId = await refungibleContract.methods.nextTokenId().call();
-    await refungibleContract.methods.mint(owner, rftTokenId).send();
+    await refungibleContract.methods.mint(owner, rftTokenId).send({from: owner});
     
-    await expect(fractionalizer.methods.rft2nft(rftCollectionAddress, rftTokenId).call())
+    await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call({from: owner}))
       .to.be.rejectedWith(/RFT collection is not set$/g);
   });
 
-  itWeb3('call rft2nft for RFT token that is not from configured RFT collection', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  itEth('call rft2nft for RFT token that is not from configured RFT collection', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
 
-    const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
-    const {collectionIdAddress: rftCollectionAddress} = await createRFTCollection(api, web3, owner);
-    const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);
+    const {contract: fractionalizer} = await initContract(helper, owner);
+    const rftCollection = await helper.eth.createRefungibleCollection(owner, 'rft', 'RFT collection', 'RFT');
+    const refungibleContract = helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);
     const rftTokenId = await refungibleContract.methods.nextTokenId().call();
-    await refungibleContract.methods.mint(owner, rftTokenId).send();
+    await refungibleContract.methods.mint(owner, rftTokenId).send({from: owner});
     
-    await expect(fractionalizer.methods.rft2nft(rftCollectionAddress, rftTokenId).call())
+    await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call())
       .to.be.rejectedWith(/Wrong RFT collection$/g);
   });
 
-  itWeb3('call rft2nft for RFT token that was not minted by fractionalizer contract', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    const {collectionIdAddress: rftCollectionAddress} = await createRFTCollection(api, web3, owner);
+  itEth('call rft2nft for RFT token that was not minted by fractionalizer contract', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
+    const rftCollection = await helper.eth.createRefungibleCollection(owner, 'rft', 'RFT collection', 'RFT');
+    const refungibleContract = helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);
 
-    const fractionalizer = await deployFractionalizer(web3, owner);
-    const refungibleContract = uniqueRefungible(web3, rftCollectionAddress, owner);
+    const fractionalizer = await deployContract(helper, owner);
 
-    await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send();
-    await fractionalizer.methods.setRFTCollection(rftCollectionAddress).send();
+    await refungibleContract.methods.addCollectionAdmin(fractionalizer.options.address).send({from: owner});
+    await fractionalizer.methods.setRFTCollection(rftCollection.collectionAddress).send({from: owner});
 
     const rftTokenId = await refungibleContract.methods.nextTokenId().call();
-    await refungibleContract.methods.mint(owner, rftTokenId).send();
+    await refungibleContract.methods.mint(owner, rftTokenId).send({from: owner});
     
-    await expect(fractionalizer.methods.rft2nft(rftCollectionAddress, rftTokenId).call())
+    await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call())
       .to.be.rejectedWith(/No corresponding NFT token found$/g);
   });
 
-  itWeb3('call rft2nft without owning all RFT pieces', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  itEth('call rft2nft without owning all RFT pieces', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
+    const receiver = await helper.eth.createAccountWithBalance(donor, 10n);
 
-    const {fractionalizer, rftCollectionAddress} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
-    const {rftTokenAddress} = await createRFTToken(api, web3, owner, fractionalizer, 100n);
+    const {contract: fractionalizer, rftCollectionAddress} = await initContract(helper, owner);
+    const {rftTokenAddress} = await mintRFTToken(helper, owner, fractionalizer, 100n);
     
-    const {tokenId} = tokenIdFromAddress(rftTokenAddress);
-    const refungibleTokenContract = uniqueRefungibleToken(web3, rftTokenAddress, owner);
-    await refungibleTokenContract.methods.transfer(receiver, 50).send();
-    await refungibleTokenContract.methods.approve(fractionalizer.options.address, 50).send();
-    await expect(fractionalizer.methods.rft2nft(rftCollectionAddress, tokenId).call())
+    const {tokenId} = helper.ethAddress.extractTokenId(rftTokenAddress);
+    const refungibleTokenContract = helper.ethNativeContract.rftToken(rftTokenAddress, owner);
+    await refungibleTokenContract.methods.transfer(receiver, 50).send({from: owner});
+    await refungibleTokenContract.methods.approve(fractionalizer.options.address, 50).send({from: receiver});
+    await expect(fractionalizer.methods.rft2nft(rftCollectionAddress, tokenId).call({from: receiver}))
       .to.be.rejectedWith(/Not all pieces are owned by the caller$/g);
   });
 
-  itWeb3('send QTZ/UNQ to contract from non owner', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    const payer = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
+  itEth('send QTZ/UNQ to contract from non owner', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
+    const payer = await helper.eth.createAccountWithBalance(donor, 10n);
 
-    const fractionalizer = await deployFractionalizer(web3, owner);
-    const amount = 10n * UNIQUE;
-    await expect(web3.eth.sendTransaction({from: payer, to: fractionalizer.options.address, value: `${amount}`, ...GAS_ARGS})).to.be.rejected;
+    const fractionalizer = await deployContract(helper, owner);
+    const amount = 10n * helper.balance.getOneTokenNominal();
+    const web3 = helper.getWeb3();
+    await expect(web3.eth.sendTransaction({from: payer, to: fractionalizer.options.address, value: `${amount}`, gas: helper.eth.DEFAULT_GAS})).to.be.rejected;
   });
 
-  itWeb3('fractionalize NFT with NFT transfers disallowed', async ({api, web3, privateKeyWrapper}) => {
-    const alice = privateKeyWrapper('//Alice');
-    let collectionId;
-    {
-      const tx = api.tx.unique.createCollectionEx({name: 'A', description: 'B', tokenPrefix: 'C', mode: 'NFT'});
-      const events = await submitTransactionAsync(alice, tx);
-      const result = getCreateCollectionResult(events);
-      collectionId = result.collectionId;
-    }
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    let nftTokenId;
-    {
-      const createData = {nft: {}};
-      const tx = api.tx.unique.createItem(collectionId, {Ethereum: owner}, createData as any);
-      const events = await executeTransaction(api, alice, tx);
-      const result = getCreateItemResult(events);
-      nftTokenId = result.itemId;
-    }
-    {
-      const tx = api.tx.unique.setTransfersEnabledFlag(collectionId, false);
-      await executeTransaction(api, alice, tx);
-    }
-    const nftCollectionAddress = collectionIdToAddress(collectionId);
-    const {fractionalizer} = await initFractionalizer(api, web3, privateKeyWrapper, owner);
-    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send();
+  itEth('fractionalize NFT with NFT transfers disallowed', async ({helper}) => {
+    const nftCollection = await helper.nft.mintCollection(donor, {name: 'A', description: 'B', tokenPrefix: 'C'});
+
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
+    const nftToken = await nftCollection.mintToken(donor, {Ethereum: owner});
+    await helper.executeExtrinsic(donor, 'api.tx.unique.setTransfersEnabledFlag', [nftCollection.collectionId, false], true);
+    const nftCollectionAddress = helper.ethAddress.fromCollectionId(nftCollection.collectionId);
+    const {contract: fractionalizer} = await initContract(helper, owner);
+    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send({from: owner});
 
-    const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
-    await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send();
-    await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100).call())
+    const nftContract = helper.ethNativeContract.collection(nftCollectionAddress, 'nft', owner);
+    await nftContract.methods.approve(fractionalizer.options.address, nftToken.tokenId).send({from: owner});
+    await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftToken.tokenId, 100).call())
       .to.be.rejectedWith(/TransferNotAllowed$/g);
   });
   
-  itWeb3('fractionalize NFT with RFT transfers disallowed', async ({api, web3, privateKeyWrapper}) => {
-    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);
-    const alice = privateKeyWrapper('//Alice');
+  itEth('fractionalize NFT with RFT transfers disallowed', async ({helper}) => {
+    const owner = await helper.eth.createAccountWithBalance(donor, 20n);
 
-    let collectionId;
-    {
-      const tx = api.tx.unique.createCollectionEx({name: 'A', description: 'B', tokenPrefix: 'C', mode: 'ReFungible'});
-      const events = await submitTransactionAsync(alice, tx);
-      const result = getCreateCollectionResult(events);
-      collectionId = result.collectionId;
-    }
-    const rftCollectionAddress = collectionIdToAddress(collectionId);
-    const fractionalizer = await deployFractionalizer(web3, owner);
-    {
-      const changeAdminTx = api.tx.unique.addCollectionAdmin(collectionId, {Ethereum: fractionalizer.options.address});
-      await submitTransactionAsync(alice, changeAdminTx);
-    }
-    await fractionalizer.methods.setRFTCollection(rftCollectionAddress).send();
-    {
-      const tx = api.tx.unique.setTransfersEnabledFlag(collectionId, false);
-      await executeTransaction(api, alice, tx);
-    }
+    const rftCollection = await helper.rft.mintCollection(donor, {name: 'A', description: 'B', tokenPrefix: 'C'});
+    const rftCollectionAddress = helper.ethAddress.fromCollectionId(rftCollection.collectionId);
+    const fractionalizer = await deployContract(helper, owner);
+    await rftCollection.addAdmin(donor, {Ethereum: fractionalizer.options.address});
 
-    const {collectionIdAddress: nftCollectionAddress} = await createNonfungibleCollection(api, web3, owner);
-    const nftContract = uniqueNFT(web3, nftCollectionAddress, owner);
+    await fractionalizer.methods.setRFTCollection(rftCollectionAddress).send({from: owner});
+    await helper.executeExtrinsic(donor, 'api.tx.unique.setTransfersEnabledFlag', [rftCollection.collectionId, false], true);
+
+    const nftCollection = await helper.eth.createNonfungibleCollection(owner, 'nft', 'NFT collection', 'NFT');
+    const nftContract = helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);
     const nftTokenId = await nftContract.methods.nextTokenId().call();
-    await nftContract.methods.mint(owner, nftTokenId).send();
+    await nftContract.methods.mint(owner, nftTokenId).send({from: owner});
 
-    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send();
-    await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send();
+    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});
+    await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});
 
-    await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftTokenId, 100n).call())
+    await expect(fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, 100n).call())
       .to.be.rejectedWith(/TransferNotAllowed$/g);
   });
 });
modifiedtests/src/eth/util/playgrounds/index.tsdiffbeforeafterboth
--- a/tests/src/eth/util/playgrounds/index.ts
+++ b/tests/src/eth/util/playgrounds/index.ts
@@ -12,8 +12,10 @@
 
 import chai from 'chai';
 import chaiAsPromised from 'chai-as-promised';
+import chaiLike from 'chai-like';
 import {requirePalletsOrSkip} from '../../../util/playgrounds';
 chai.use(chaiAsPromised);
+chai.use(chaiLike);
 export const expect = chai.expect;
 
 export const usingEthPlaygrounds = async (code: (helper: EthUniqueHelper, privateKey: (seed: string) => IKeyringPair) => Promise<void>) => {