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

difftreelog

fix yarn fix

Daniel Shiposha2022-08-30parent: #183fa35.patch.diff
in: master

2 files changed

modifiedtests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth
before · tests/src/eth/collectionAdmin.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.3// Unique Network is free software: you can redistribute it and/or modify4// it under the terms of the GNU General Public License as published by5// the Free Software Foundation, either version 3 of the License, or6// (at your option) any later version.7//8// Unique Network is distributed in the hope that it will be useful,9// but WITHOUT ANY WARRANTY; without even the implied warranty of10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the11// GNU General Public License for more details.1213// You should have received a copy of the GNU General Public License14// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1516import {expect} from 'chai';17import privateKey from '../substrate/privateKey';18import { UNIQUE } from '../util/helpers';19import {20  createEthAccount,21  createEthAccountWithBalance, 22  evmCollection, 23  evmCollectionHelpers, 24  getCollectionAddressFromResult, 25  itWeb3,26  recordEthFee,27  subToEth,28} from './util/helpers';2930describe('Add collection admins', () => {31  itWeb3('Add admin by owner', async ({api, web3, privateKeyWrapper}) => {32    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);33    const collectionHelper = evmCollectionHelpers(web3, owner);34        35    const result = await collectionHelper.methods36      .createNonfungibleCollection('A', 'B', 'C')37      .send();38    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);3940    const newAdmin = await createEthAccount(web3);41    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);42    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();43    const adminList = await api.rpc.unique.adminlist(collectionId);44    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())45      .to.be.eq(newAdmin.toLocaleLowerCase());46  });4748  itWeb3('Add substrate admin by owner', async ({api, web3, privateKeyWrapper}) => {49    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);50    const collectionHelper = evmCollectionHelpers(web3, owner);51        52    const result = await collectionHelper.methods53      .createNonfungibleCollection('A', 'B', 'C')54      .send();55    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);5657    const newAdmin = privateKeyWrapper('//Alice');58    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);59    await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();6061    const adminList = await api.rpc.unique.adminlist(collectionId);62    expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())63      .to.be.eq(newAdmin.address.toLocaleLowerCase());64  });65  66  itWeb3('Verify owner or admin', async ({api, web3, privateKeyWrapper}) => {67    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);68    const collectionHelper = evmCollectionHelpers(web3, owner);69        70    const result = await collectionHelper.methods71      .createNonfungibleCollection('A', 'B', 'C')72      .send();73    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);7475    const newAdmin = createEthAccount(web3);76    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);77    expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false;78    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();79    expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true;80  });8182  itWeb3('(!negative tests!) Add admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {83    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);84    const collectionHelper = evmCollectionHelpers(web3, owner);85        86    const result = await collectionHelper.methods87      .createNonfungibleCollection('A', 'B', 'C')88      .send();89    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);9091    const admin = await createEthAccountWithBalance(api, web3, privateKeyWrapper);92    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);93    await collectionEvm.methods.addCollectionAdmin(admin).send();94    95    const user = await createEthAccount(web3);96    await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: admin}))97      .to.be.rejectedWith('NoPermission');9899    const adminList = await api.rpc.unique.adminlist(collectionId);100    expect(adminList.length).to.be.eq(1);101    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())102      .to.be.eq(admin.toLocaleLowerCase());103  });104105  itWeb3('(!negative tests!) Add admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => {106    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);107    const collectionHelper = evmCollectionHelpers(web3, owner);108        109    const result = await collectionHelper.methods110      .createNonfungibleCollection('A', 'B', 'C')111      .send();112    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);113114    const notAdmin = await createEthAccountWithBalance(api, web3, privateKeyWrapper);115    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);116    117    const user = await createEthAccount(web3);118    await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: notAdmin}))119      .to.be.rejectedWith('NoPermission');120121    const adminList = await api.rpc.unique.adminlist(collectionId);122    expect(adminList.length).to.be.eq(0);123  });124125  itWeb3('(!negative tests!) Add substrate admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {126    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);127    const collectionHelper = evmCollectionHelpers(web3, owner);128        129    const result = await collectionHelper.methods130      .createNonfungibleCollection('A', 'B', 'C')131      .send();132    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);133134    const admin = await createEthAccountWithBalance(api, web3, privateKeyWrapper);135    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);136    await collectionEvm.methods.addCollectionAdmin(admin).send();137138    const notAdmin = privateKey('//Alice');139    await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin.addressRaw).call({from: admin}))140      .to.be.rejectedWith('NoPermission');141142    const adminList = await api.rpc.unique.adminlist(collectionId);143    expect(adminList.length).to.be.eq(1);144    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())145      .to.be.eq(admin.toLocaleLowerCase());146  });147  148  itWeb3('(!negative tests!) Add substrate admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => {149    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);150    const collectionHelper = evmCollectionHelpers(web3, owner);151        152    const result = await collectionHelper.methods153      .createNonfungibleCollection('A', 'B', 'C')154      .send();155    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);156157    const notAdmin0 = await createEthAccountWithBalance(api, web3, privateKeyWrapper);158    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);159    const notAdmin1 = privateKey('//Alice');160    await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin1.addressRaw).call({from: notAdmin0}))161      .to.be.rejectedWith('NoPermission');162163    const adminList = await api.rpc.unique.adminlist(collectionId);164    expect(adminList.length).to.be.eq(0);165  });166});167168describe('Remove collection admins', () => {169  itWeb3('Remove admin by owner', async ({api, web3, privateKeyWrapper}) => {170    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);171    const collectionHelper = evmCollectionHelpers(web3, owner);172        173    const result = await collectionHelper.methods174      .createNonfungibleCollection('A', 'B', 'C')175      .send();176    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);177178    const newAdmin = await createEthAccount(web3);179    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);180    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();181    {182      const adminList = await api.rpc.unique.adminlist(collectionId);183      expect(adminList.length).to.be.eq(1);184      expect(adminList[0].asEthereum.toString().toLocaleLowerCase())185        .to.be.eq(newAdmin.toLocaleLowerCase());186    }187188    await collectionEvm.methods.removeCollectionAdmin(newAdmin).send();189    const adminList = await api.rpc.unique.adminlist(collectionId);190    expect(adminList.length).to.be.eq(0);191  });192193  itWeb3('Remove substrate admin by owner', async ({api, web3, privateKeyWrapper}) => {194    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);195    const collectionHelper = evmCollectionHelpers(web3, owner);196        197    const result = await collectionHelper.methods198      .createNonfungibleCollection('A', 'B', 'C')199      .send();200    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);201202    const newAdmin = privateKeyWrapper('//Alice');203    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);204    await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();205    {206      const adminList = await api.rpc.unique.adminlist(collectionId);207      expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())208        .to.be.eq(newAdmin.address.toLocaleLowerCase());209    }210    211    await collectionEvm.methods.removeCollectionAdminSubstrate(newAdmin.addressRaw).send();212    const adminList = await api.rpc.unique.adminlist(collectionId);213    expect(adminList.length).to.be.eq(0);214  });215216  itWeb3('(!negative tests!) Remove admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {217    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);218    const collectionHelper = evmCollectionHelpers(web3, owner);219        220    const result = await collectionHelper.methods221      .createNonfungibleCollection('A', 'B', 'C')222      .send();223    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);224225    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);226227    const admin0 = await createEthAccountWithBalance(api, web3, privateKeyWrapper);228    await collectionEvm.methods.addCollectionAdmin(admin0).send();229    const admin1 = await createEthAccount(web3);230    await collectionEvm.methods.addCollectionAdmin(admin1).send();231232    await expect(collectionEvm.methods.removeCollectionAdmin(admin1).call({from: admin0}))233      .to.be.rejectedWith('NoPermission');234    {235      const adminList = await api.rpc.unique.adminlist(collectionId);236      expect(adminList.length).to.be.eq(2);237      expect(adminList.toString().toLocaleLowerCase())238        .to.be.deep.contains(admin0.toLocaleLowerCase())239        .to.be.deep.contains(admin1.toLocaleLowerCase());240    }241  });242243  itWeb3('(!negative tests!) Remove admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => {244    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);245    const collectionHelper = evmCollectionHelpers(web3, owner);246        247    const result = await collectionHelper.methods248      .createNonfungibleCollection('A', 'B', 'C')249      .send();250    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);251252    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);253254    const admin = await createEthAccountWithBalance(api, web3, privateKeyWrapper);255    await collectionEvm.methods.addCollectionAdmin(admin).send();256    const notAdmin = await createEthAccount(web3);257258    await expect(collectionEvm.methods.removeCollectionAdmin(admin).call({from: notAdmin}))259      .to.be.rejectedWith('NoPermission');260    {261      const adminList = await api.rpc.unique.adminlist(collectionId);262      expect(adminList[0].asEthereum.toString().toLocaleLowerCase())263        .to.be.eq(admin.toLocaleLowerCase());264      expect(adminList.length).to.be.eq(1);265    }266  });267268  itWeb3('(!negative tests!) Remove substrate admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {269    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);270    const collectionHelper = evmCollectionHelpers(web3, owner);271        272    const result = await collectionHelper.methods273      .createNonfungibleCollection('A', 'B', 'C')274      .send();275    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);276277    const adminSub = privateKeyWrapper('//Alice');278    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);279    await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();280    const adminEth = await createEthAccountWithBalance(api, web3, privateKeyWrapper);281    await collectionEvm.methods.addCollectionAdmin(adminEth).send();282283    await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: adminEth}))284      .to.be.rejectedWith('NoPermission');285286    const adminList = await api.rpc.unique.adminlist(collectionId);287    expect(adminList.length).to.be.eq(2);288    expect(adminList.toString().toLocaleLowerCase())289      .to.be.deep.contains(adminSub.address.toLocaleLowerCase())290      .to.be.deep.contains(adminEth.toLocaleLowerCase());291  });292293  itWeb3('(!negative tests!) Remove substrate admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => {294    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);295    const collectionHelper = evmCollectionHelpers(web3, owner);296        297    const result = await collectionHelper.methods298      .createNonfungibleCollection('A', 'B', 'C')299      .send();300    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);301302    const adminSub = privateKeyWrapper('//Alice');303    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);304    await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();305    const notAdminEth = await createEthAccountWithBalance(api, web3, privateKeyWrapper);306307    await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: notAdminEth}))308      .to.be.rejectedWith('NoPermission');309310    const adminList = await api.rpc.unique.adminlist(collectionId);311    expect(adminList.length).to.be.eq(1);312    expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())313      .to.be.eq(adminSub.address.toLocaleLowerCase());314  });315});316317describe('Change owner tests', () => {318  itWeb3('Change owner', async ({api, web3, privateKeyWrapper}) => {319    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);320    const newOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);321    const collectionHelper = evmCollectionHelpers(web3, owner);322    const result = await collectionHelper.methods323      .createNonfungibleCollection('A', 'B', 'C')324      .send();325    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);326    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);327  328    await collectionEvm.methods.setOwner(newOwner).send();329  330    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;331    expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.true;332  });333334  itWeb3('change owner call fee', async ({web3, api, privateKeyWrapper}) => {335    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);336    const newOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);337    const collectionHelper = evmCollectionHelpers(web3, owner);338    const result = await collectionHelper.methods339      .createNonfungibleCollection('A', 'B', 'C')340      .send();341    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);342    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);343344    const cost = await recordEthFee(api, owner, () => collectionEvm.methods.setOwner(newOwner).send());345    expect(cost < BigInt(0.2 * Number(UNIQUE)));346    expect(cost > 0);347  });348349  itWeb3('(!negative tests!) call setOwner by non owner', async ({api, web3, privateKeyWrapper}) => {350    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);351    const newOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);352    const collectionHelper = evmCollectionHelpers(web3, owner);353    const result = await collectionHelper.methods354      .createNonfungibleCollection('A', 'B', 'C')355      .send();356    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);357    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);358  359    await expect(collectionEvm.methods.setOwner(newOwner).send({from: newOwner})).to.be.rejected;360    expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.false;361  });362});363364describe('Change substrate owner tests', () => {365  itWeb3('Change owner', async ({api, web3, privateKeyWrapper}) => {366    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);367    const newOwner = privateKeyWrapper('//Alice');368    const collectionHelper = evmCollectionHelpers(web3, owner);369    const result = await collectionHelper.methods370      .createNonfungibleCollection('A', 'B', 'C')371      .send();372    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);373    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);374  375    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.true;376    expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;377    378    await collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send();379  380    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;381    expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.true;382  });383384  itWeb3('change owner call fee', async ({web3, api, privateKeyWrapper}) => {385    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);386    const newOwner = privateKeyWrapper('//Alice');387    const collectionHelper = evmCollectionHelpers(web3, owner);388    const result = await collectionHelper.methods389      .createNonfungibleCollection('A', 'B', 'C')390      .send();391    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);392    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);393394    const cost = await recordEthFee(api, owner, () => collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send());395    expect(cost < BigInt(0.2 * Number(UNIQUE)));396    expect(cost > 0);397  });398399  itWeb3('(!negative tests!) call setOwner by non owner', async ({api, web3, privateKeyWrapper}) => {400    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);401    const otherReceiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);402    const newOwner = privateKeyWrapper('//Alice');403    const collectionHelper = evmCollectionHelpers(web3, owner);404    const result = await collectionHelper.methods405      .createNonfungibleCollection('A', 'B', 'C')406      .send();407    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);408    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);409  410    await expect(collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send({from: otherReceiver})).to.be.rejected;411    expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;412  });413});
after · tests/src/eth/collectionAdmin.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.3// Unique Network is free software: you can redistribute it and/or modify4// it under the terms of the GNU General Public License as published by5// the Free Software Foundation, either version 3 of the License, or6// (at your option) any later version.7//8// Unique Network is distributed in the hope that it will be useful,9// but WITHOUT ANY WARRANTY; without even the implied warranty of10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the11// GNU General Public License for more details.1213// You should have received a copy of the GNU General Public License14// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1516import {expect} from 'chai';17import privateKey from '../substrate/privateKey';18import {UNIQUE} from '../util/helpers';19import {20  createEthAccount,21  createEthAccountWithBalance, 22  evmCollection, 23  evmCollectionHelpers, 24  getCollectionAddressFromResult, 25  itWeb3,26  recordEthFee,27  subToEth,28} from './util/helpers';2930describe('Add collection admins', () => {31  itWeb3('Add admin by owner', async ({api, web3, privateKeyWrapper}) => {32    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);33    const collectionHelper = evmCollectionHelpers(web3, owner);34        35    const result = await collectionHelper.methods36      .createNonfungibleCollection('A', 'B', 'C')37      .send();38    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);3940    const newAdmin = await createEthAccount(web3);41    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);42    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();43    const adminList = await api.rpc.unique.adminlist(collectionId);44    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())45      .to.be.eq(newAdmin.toLocaleLowerCase());46  });4748  itWeb3('Add substrate admin by owner', async ({api, web3, privateKeyWrapper}) => {49    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);50    const collectionHelper = evmCollectionHelpers(web3, owner);51        52    const result = await collectionHelper.methods53      .createNonfungibleCollection('A', 'B', 'C')54      .send();55    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);5657    const newAdmin = privateKeyWrapper('//Alice');58    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);59    await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();6061    const adminList = await api.rpc.unique.adminlist(collectionId);62    expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())63      .to.be.eq(newAdmin.address.toLocaleLowerCase());64  });65  66  itWeb3('Verify owner or admin', async ({api, web3, privateKeyWrapper}) => {67    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);68    const collectionHelper = evmCollectionHelpers(web3, owner);69        70    const result = await collectionHelper.methods71      .createNonfungibleCollection('A', 'B', 'C')72      .send();73    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);7475    const newAdmin = createEthAccount(web3);76    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);77    expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false;78    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();79    expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true;80  });8182  itWeb3('(!negative tests!) Add admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {83    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);84    const collectionHelper = evmCollectionHelpers(web3, owner);85        86    const result = await collectionHelper.methods87      .createNonfungibleCollection('A', 'B', 'C')88      .send();89    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);9091    const admin = await createEthAccountWithBalance(api, web3, privateKeyWrapper);92    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);93    await collectionEvm.methods.addCollectionAdmin(admin).send();94    95    const user = await createEthAccount(web3);96    await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: admin}))97      .to.be.rejectedWith('NoPermission');9899    const adminList = await api.rpc.unique.adminlist(collectionId);100    expect(adminList.length).to.be.eq(1);101    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())102      .to.be.eq(admin.toLocaleLowerCase());103  });104105  itWeb3('(!negative tests!) Add admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => {106    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);107    const collectionHelper = evmCollectionHelpers(web3, owner);108        109    const result = await collectionHelper.methods110      .createNonfungibleCollection('A', 'B', 'C')111      .send();112    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);113114    const notAdmin = await createEthAccountWithBalance(api, web3, privateKeyWrapper);115    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);116    117    const user = await createEthAccount(web3);118    await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: notAdmin}))119      .to.be.rejectedWith('NoPermission');120121    const adminList = await api.rpc.unique.adminlist(collectionId);122    expect(adminList.length).to.be.eq(0);123  });124125  itWeb3('(!negative tests!) Add substrate admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {126    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);127    const collectionHelper = evmCollectionHelpers(web3, owner);128        129    const result = await collectionHelper.methods130      .createNonfungibleCollection('A', 'B', 'C')131      .send();132    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);133134    const admin = await createEthAccountWithBalance(api, web3, privateKeyWrapper);135    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);136    await collectionEvm.methods.addCollectionAdmin(admin).send();137138    const notAdmin = privateKey('//Alice');139    await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin.addressRaw).call({from: admin}))140      .to.be.rejectedWith('NoPermission');141142    const adminList = await api.rpc.unique.adminlist(collectionId);143    expect(adminList.length).to.be.eq(1);144    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())145      .to.be.eq(admin.toLocaleLowerCase());146  });147  148  itWeb3('(!negative tests!) Add substrate admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => {149    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);150    const collectionHelper = evmCollectionHelpers(web3, owner);151        152    const result = await collectionHelper.methods153      .createNonfungibleCollection('A', 'B', 'C')154      .send();155    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);156157    const notAdmin0 = await createEthAccountWithBalance(api, web3, privateKeyWrapper);158    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);159    const notAdmin1 = privateKey('//Alice');160    await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin1.addressRaw).call({from: notAdmin0}))161      .to.be.rejectedWith('NoPermission');162163    const adminList = await api.rpc.unique.adminlist(collectionId);164    expect(adminList.length).to.be.eq(0);165  });166});167168describe('Remove collection admins', () => {169  itWeb3('Remove admin by owner', async ({api, web3, privateKeyWrapper}) => {170    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);171    const collectionHelper = evmCollectionHelpers(web3, owner);172        173    const result = await collectionHelper.methods174      .createNonfungibleCollection('A', 'B', 'C')175      .send();176    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);177178    const newAdmin = await createEthAccount(web3);179    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);180    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();181    {182      const adminList = await api.rpc.unique.adminlist(collectionId);183      expect(adminList.length).to.be.eq(1);184      expect(adminList[0].asEthereum.toString().toLocaleLowerCase())185        .to.be.eq(newAdmin.toLocaleLowerCase());186    }187188    await collectionEvm.methods.removeCollectionAdmin(newAdmin).send();189    const adminList = await api.rpc.unique.adminlist(collectionId);190    expect(adminList.length).to.be.eq(0);191  });192193  itWeb3('Remove substrate admin by owner', async ({api, web3, privateKeyWrapper}) => {194    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);195    const collectionHelper = evmCollectionHelpers(web3, owner);196        197    const result = await collectionHelper.methods198      .createNonfungibleCollection('A', 'B', 'C')199      .send();200    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);201202    const newAdmin = privateKeyWrapper('//Alice');203    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);204    await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();205    {206      const adminList = await api.rpc.unique.adminlist(collectionId);207      expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())208        .to.be.eq(newAdmin.address.toLocaleLowerCase());209    }210    211    await collectionEvm.methods.removeCollectionAdminSubstrate(newAdmin.addressRaw).send();212    const adminList = await api.rpc.unique.adminlist(collectionId);213    expect(adminList.length).to.be.eq(0);214  });215216  itWeb3('(!negative tests!) Remove admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {217    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);218    const collectionHelper = evmCollectionHelpers(web3, owner);219        220    const result = await collectionHelper.methods221      .createNonfungibleCollection('A', 'B', 'C')222      .send();223    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);224225    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);226227    const admin0 = await createEthAccountWithBalance(api, web3, privateKeyWrapper);228    await collectionEvm.methods.addCollectionAdmin(admin0).send();229    const admin1 = await createEthAccount(web3);230    await collectionEvm.methods.addCollectionAdmin(admin1).send();231232    await expect(collectionEvm.methods.removeCollectionAdmin(admin1).call({from: admin0}))233      .to.be.rejectedWith('NoPermission');234    {235      const adminList = await api.rpc.unique.adminlist(collectionId);236      expect(adminList.length).to.be.eq(2);237      expect(adminList.toString().toLocaleLowerCase())238        .to.be.deep.contains(admin0.toLocaleLowerCase())239        .to.be.deep.contains(admin1.toLocaleLowerCase());240    }241  });242243  itWeb3('(!negative tests!) Remove admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => {244    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);245    const collectionHelper = evmCollectionHelpers(web3, owner);246        247    const result = await collectionHelper.methods248      .createNonfungibleCollection('A', 'B', 'C')249      .send();250    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);251252    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);253254    const admin = await createEthAccountWithBalance(api, web3, privateKeyWrapper);255    await collectionEvm.methods.addCollectionAdmin(admin).send();256    const notAdmin = await createEthAccount(web3);257258    await expect(collectionEvm.methods.removeCollectionAdmin(admin).call({from: notAdmin}))259      .to.be.rejectedWith('NoPermission');260    {261      const adminList = await api.rpc.unique.adminlist(collectionId);262      expect(adminList[0].asEthereum.toString().toLocaleLowerCase())263        .to.be.eq(admin.toLocaleLowerCase());264      expect(adminList.length).to.be.eq(1);265    }266  });267268  itWeb3('(!negative tests!) Remove substrate admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {269    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);270    const collectionHelper = evmCollectionHelpers(web3, owner);271        272    const result = await collectionHelper.methods273      .createNonfungibleCollection('A', 'B', 'C')274      .send();275    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);276277    const adminSub = privateKeyWrapper('//Alice');278    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);279    await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();280    const adminEth = await createEthAccountWithBalance(api, web3, privateKeyWrapper);281    await collectionEvm.methods.addCollectionAdmin(adminEth).send();282283    await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: adminEth}))284      .to.be.rejectedWith('NoPermission');285286    const adminList = await api.rpc.unique.adminlist(collectionId);287    expect(adminList.length).to.be.eq(2);288    expect(adminList.toString().toLocaleLowerCase())289      .to.be.deep.contains(adminSub.address.toLocaleLowerCase())290      .to.be.deep.contains(adminEth.toLocaleLowerCase());291  });292293  itWeb3('(!negative tests!) Remove substrate admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => {294    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);295    const collectionHelper = evmCollectionHelpers(web3, owner);296        297    const result = await collectionHelper.methods298      .createNonfungibleCollection('A', 'B', 'C')299      .send();300    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);301302    const adminSub = privateKeyWrapper('//Alice');303    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);304    await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();305    const notAdminEth = await createEthAccountWithBalance(api, web3, privateKeyWrapper);306307    await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: notAdminEth}))308      .to.be.rejectedWith('NoPermission');309310    const adminList = await api.rpc.unique.adminlist(collectionId);311    expect(adminList.length).to.be.eq(1);312    expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())313      .to.be.eq(adminSub.address.toLocaleLowerCase());314  });315});316317describe('Change owner tests', () => {318  itWeb3('Change owner', async ({api, web3, privateKeyWrapper}) => {319    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);320    const newOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);321    const collectionHelper = evmCollectionHelpers(web3, owner);322    const result = await collectionHelper.methods323      .createNonfungibleCollection('A', 'B', 'C')324      .send();325    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);326    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);327  328    await collectionEvm.methods.setOwner(newOwner).send();329  330    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;331    expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.true;332  });333334  itWeb3('change owner call fee', async ({web3, api, privateKeyWrapper}) => {335    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);336    const newOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);337    const collectionHelper = evmCollectionHelpers(web3, owner);338    const result = await collectionHelper.methods339      .createNonfungibleCollection('A', 'B', 'C')340      .send();341    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);342    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);343344    const cost = await recordEthFee(api, owner, () => collectionEvm.methods.setOwner(newOwner).send());345    expect(cost < BigInt(0.2 * Number(UNIQUE)));346    expect(cost > 0);347  });348349  itWeb3('(!negative tests!) call setOwner by non owner', async ({api, web3, privateKeyWrapper}) => {350    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);351    const newOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);352    const collectionHelper = evmCollectionHelpers(web3, owner);353    const result = await collectionHelper.methods354      .createNonfungibleCollection('A', 'B', 'C')355      .send();356    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);357    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);358  359    await expect(collectionEvm.methods.setOwner(newOwner).send({from: newOwner})).to.be.rejected;360    expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.false;361  });362});363364describe('Change substrate owner tests', () => {365  itWeb3('Change owner', async ({api, web3, privateKeyWrapper}) => {366    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);367    const newOwner = privateKeyWrapper('//Alice');368    const collectionHelper = evmCollectionHelpers(web3, owner);369    const result = await collectionHelper.methods370      .createNonfungibleCollection('A', 'B', 'C')371      .send();372    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);373    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);374  375    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.true;376    expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;377    378    await collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send();379  380    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;381    expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.true;382  });383384  itWeb3('change owner call fee', async ({web3, api, privateKeyWrapper}) => {385    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);386    const newOwner = privateKeyWrapper('//Alice');387    const collectionHelper = evmCollectionHelpers(web3, owner);388    const result = await collectionHelper.methods389      .createNonfungibleCollection('A', 'B', 'C')390      .send();391    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);392    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);393394    const cost = await recordEthFee(api, owner, () => collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send());395    expect(cost < BigInt(0.2 * Number(UNIQUE)));396    expect(cost > 0);397  });398399  itWeb3('(!negative tests!) call setOwner by non owner', async ({api, web3, privateKeyWrapper}) => {400    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);401    const otherReceiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);402    const newOwner = privateKeyWrapper('//Alice');403    const collectionHelper = evmCollectionHelpers(web3, owner);404    const result = await collectionHelper.methods405      .createNonfungibleCollection('A', 'B', 'C')406      .send();407    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);408    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);409  410    await expect(collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send({from: otherReceiver})).to.be.rejected;411    expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;412  });413});
modifiedtests/src/xcm/xcmUnique.test.tsdiffbeforeafterboth
--- a/tests/src/xcm/xcmUnique.test.ts
+++ b/tests/src/xcm/xcmUnique.test.ts
@@ -36,232 +36,232 @@
 const TRANSFER_AMOUNT = 2000000000000000000000000n;
 
 describe('Integration test: Exchanging UNQ with Acala', () => {
-    let alice: IKeyringPair;
-    let randomAccount: IKeyringPair;
+  let alice: IKeyringPair;
+  let randomAccount: IKeyringPair;
   
-    let balanceUniqueTokenBefore: bigint;
-    let balanceUniqueTokenAfter: bigint;
-    let balanceUniqueTokenFinal: bigint;
-    let balanceAcalaTokenBefore: bigint;
-    let balanceAcalaTokenAfter: bigint;
-    let balanceAcalaTokenFinal: bigint;
-    let balanceUniqueForeignTokenAfter: bigint;
-    let balanceUniqueForeignTokenBefore: bigint;
-    let balanceUniqueForeignTokenFinal: bigint;
+  let balanceUniqueTokenBefore: bigint;
+  let balanceUniqueTokenAfter: bigint;
+  let balanceUniqueTokenFinal: bigint;
+  let balanceAcalaTokenBefore: bigint;
+  let balanceAcalaTokenAfter: bigint;
+  let balanceAcalaTokenFinal: bigint;
+  let balanceUniqueForeignTokenAfter: bigint;
+  let balanceUniqueForeignTokenBefore: bigint;
+  let balanceUniqueForeignTokenFinal: bigint;
   
-    before(async () => {
-      await usingApi(async (api, privateKeyWrapper) => {
-        alice = privateKeyWrapper('//Alice');
-        randomAccount = generateKeyringPair();
-      });
+  before(async () => {
+    await usingApi(async (api, privateKeyWrapper) => {
+      alice = privateKeyWrapper('//Alice');
+      randomAccount = generateKeyringPair();
+    });
   
-      const acalaApiOptions: ApiOptions = {
-        provider: new WsProvider('ws://127.0.0.1:' + ACALA_PORT),
-      };
+    const acalaApiOptions: ApiOptions = {
+      provider: new WsProvider('ws://127.0.0.1:' + ACALA_PORT),
+    };
   
-      // Acala side
-      await usingApi(
-        async (api) => {
-          const destination = {
-            V0: {
-              X2: [
-                'Parent',
-                {
-                  Parachain: UNIQUE_CHAIN,
-                },
-              ],
-            },
-          };
+    // Acala side
+    await usingApi(
+      async (api) => {
+        const destination = {
+          V0: {
+            X2: [
+              'Parent',
+              {
+                Parachain: UNIQUE_CHAIN,
+              },
+            ],
+          },
+        };
   
-          const metadata = {
-            name: 'UNQ',
-            symbol: 'UNQ',
-            decimals: 18,
-            minimalBalance: 1,
-          };
+        const metadata = {
+          name: 'UNQ',
+          symbol: 'UNQ',
+          decimals: 18,
+          minimalBalance: 1,
+        };
   
-          const tx = api.tx.assetRegistry.registerForeignAsset(destination, metadata);
-          const sudoTx = api.tx.sudo.sudo(tx as any);
-          const events = await submitTransactionAsync(alice, sudoTx);
-          const result = getGenericResult(events);
-          expect(result.success).to.be.true;
+        const tx = api.tx.assetRegistry.registerForeignAsset(destination, metadata);
+        const sudoTx = api.tx.sudo.sudo(tx as any);
+        const events = await submitTransactionAsync(alice, sudoTx);
+        const result = getGenericResult(events);
+        expect(result.success).to.be.true;
   
-          const tx1 = api.tx.balances.transfer(randomAccount.address, 10000000000000n);
-          const events1 = await submitTransactionAsync(alice, tx1);
-          const result1 = getGenericResult(events1);
-          expect(result1.success).to.be.true;
+        const tx1 = api.tx.balances.transfer(randomAccount.address, 10000000000000n);
+        const events1 = await submitTransactionAsync(alice, tx1);
+        const result1 = getGenericResult(events1);
+        expect(result1.success).to.be.true;
   
-          [balanceAcalaTokenBefore] = await getBalance(api, [randomAccount.address]);
-          {
-            const {free} = (await api.query.tokens.accounts(randomAccount.addressRaw, {ForeignAsset: 0})).toJSON() as any;
-            balanceUniqueForeignTokenBefore = BigInt(free);
-          }
-        },
-        acalaApiOptions,
-      );
+        [balanceAcalaTokenBefore] = await getBalance(api, [randomAccount.address]);
+        {
+          const {free} = (await api.query.tokens.accounts(randomAccount.addressRaw, {ForeignAsset: 0})).toJSON() as any;
+          balanceUniqueForeignTokenBefore = BigInt(free);
+        }
+      },
+      acalaApiOptions,
+    );
   
-      // Unique side
-      await usingApi(async (api) => {
-        const tx0 = api.tx.balances.transfer(randomAccount.address, 10n * TRANSFER_AMOUNT);
-        const events0 = await submitTransactionAsync(alice, tx0);
-        const result0 = getGenericResult(events0);
-        expect(result0.success).to.be.true;
+    // Unique side
+    await usingApi(async (api) => {
+      const tx0 = api.tx.balances.transfer(randomAccount.address, 10n * TRANSFER_AMOUNT);
+      const events0 = await submitTransactionAsync(alice, tx0);
+      const result0 = getGenericResult(events0);
+      expect(result0.success).to.be.true;
   
-        [balanceUniqueTokenBefore] = await getBalance(api, [randomAccount.address]);
-      });
+      [balanceUniqueTokenBefore] = await getBalance(api, [randomAccount.address]);
     });
+  });
   
-    it('Should connect and send UNQ to Acala', async () => {
+  it('Should connect and send UNQ to Acala', async () => {
   
-      // Unique side
-      await usingApi(async (api) => {
+    // Unique side
+    await usingApi(async (api) => {
   
-        const destination = {
-          V0: {
-            X2: [
-              'Parent',
-              {
-                Parachain: ACALA_CHAIN,
-              },
-            ],
-          },
-        };
+      const destination = {
+        V0: {
+          X2: [
+            'Parent',
+            {
+              Parachain: ACALA_CHAIN,
+            },
+          ],
+        },
+      };
   
-        const beneficiary = {
-          V0: {
-            X1: {
-              AccountId32: {
-                network: 'Any',
-                id: randomAccount.addressRaw,
-              },
+      const beneficiary = {
+        V0: {
+          X1: {
+            AccountId32: {
+              network: 'Any',
+              id: randomAccount.addressRaw,
             },
           },
-        };
+        },
+      };
   
-        const assets = {
-          V1: [
-            {
-              id: {
-                Concrete: {
-                  parents: 0,
-                  interior: 'Here',
-                },
+      const assets = {
+        V1: [
+          {
+            id: {
+              Concrete: {
+                parents: 0,
+                interior: 'Here',
               },
-              fun: {
-                Fungible: TRANSFER_AMOUNT,
-              },
             },
-          ],
-        };
+            fun: {
+              Fungible: TRANSFER_AMOUNT,
+            },
+          },
+        ],
+      };
   
-        const feeAssetItem = 0;
+      const feeAssetItem = 0;
   
-        const weightLimit = {
-          Limited: 5000000000,
-        };
+      const weightLimit = {
+        Limited: 5000000000,
+      };
   
-        const tx = api.tx.polkadotXcm.limitedReserveTransferAssets(destination, beneficiary, assets, feeAssetItem, weightLimit);
-        const events = await submitTransactionAsync(randomAccount, tx);
-        const result = getGenericResult(events);
-        expect(result.success).to.be.true;
+      const tx = api.tx.polkadotXcm.limitedReserveTransferAssets(destination, beneficiary, assets, feeAssetItem, weightLimit);
+      const events = await submitTransactionAsync(randomAccount, tx);
+      const result = getGenericResult(events);
+      expect(result.success).to.be.true;
   
-        [balanceUniqueTokenAfter] = await getBalance(api, [randomAccount.address]);
+      [balanceUniqueTokenAfter] = await getBalance(api, [randomAccount.address]);
   
-        const unqFees = balanceUniqueTokenBefore - balanceUniqueTokenAfter;
-        console.log('[Unique -> Acala] transaction fees on Unique: %s UNQ', unqFees);
-        expect(unqFees > 0n).to.be.true;
-      });
+      const unqFees = balanceUniqueTokenBefore - balanceUniqueTokenAfter;
+      console.log('[Unique -> Acala] transaction fees on Unique: %s UNQ', unqFees);
+      expect(unqFees > 0n).to.be.true;
+    });
   
-      // Acala side
-      await usingApi(
-        async (api) => {
-          // todo do something about instant sealing, where there might not be any new blocks
-          await waitNewBlocks(api, 3);
-          const {free} = (await api.query.tokens.accounts(randomAccount.addressRaw, {ForeignAsset: 0})).toJSON() as any;
-          balanceUniqueForeignTokenAfter = BigInt(free);
+    // Acala side
+    await usingApi(
+      async (api) => {
+        // todo do something about instant sealing, where there might not be any new blocks
+        await waitNewBlocks(api, 3);
+        const {free} = (await api.query.tokens.accounts(randomAccount.addressRaw, {ForeignAsset: 0})).toJSON() as any;
+        balanceUniqueForeignTokenAfter = BigInt(free);
   
-          [balanceAcalaTokenAfter] = await getBalance(api, [randomAccount.address]);
+        [balanceAcalaTokenAfter] = await getBalance(api, [randomAccount.address]);
 
-          const acaFees = balanceAcalaTokenBefore - balanceAcalaTokenAfter;
-          const unqDiffAfterIncomeTransfer = balanceUniqueForeignTokenAfter - balanceUniqueForeignTokenBefore;
+        const acaFees = balanceAcalaTokenBefore - balanceAcalaTokenAfter;
+        const unqDiffAfterIncomeTransfer = balanceUniqueForeignTokenAfter - balanceUniqueForeignTokenBefore;
 
-          const unqFees = unqDiffAfterIncomeTransfer - TRANSFER_AMOUNT;
+        const unqFees = unqDiffAfterIncomeTransfer - TRANSFER_AMOUNT;
 
-          console.log('[Unique -> Acala] transaction fees on Acala: %s ACA', acaFees);
-          console.log('[Unique -> Acala] transaction fees on Acala: %s UNQ', unqFees);
-          expect(acaFees == 0n).to.be.true;
-          expect(unqFees == 0n).to.be.true;
-        },
-        {provider: new WsProvider('ws://127.0.0.1:' + ACALA_PORT)},
-      );
-    });
+        console.log('[Unique -> Acala] transaction fees on Acala: %s ACA', acaFees);
+        console.log('[Unique -> Acala] transaction fees on Acala: %s UNQ', unqFees);
+        expect(acaFees == 0n).to.be.true;
+        expect(unqFees == 0n).to.be.true;
+      },
+      {provider: new WsProvider('ws://127.0.0.1:' + ACALA_PORT)},
+    );
+  });
   
-    it('Should connect to Acala and send UNQ back', async () => {
+  it('Should connect to Acala and send UNQ back', async () => {
   
-      // Acala side
-      await usingApi(
-        async (api) => {
-          const destination = {
-            V1: {
-              parents: 1,
-              interior: {
-                X2: [
-                  {Parachain: UNIQUE_CHAIN},
-                  {
-                    AccountId32: {
-                      network: 'Any',
-                      id: randomAccount.addressRaw,
-                    },
+    // Acala side
+    await usingApi(
+      async (api) => {
+        const destination = {
+          V1: {
+            parents: 1,
+            interior: {
+              X2: [
+                {Parachain: UNIQUE_CHAIN},
+                {
+                  AccountId32: {
+                    network: 'Any',
+                    id: randomAccount.addressRaw,
                   },
-                ],
-              },
+                },
+              ],
             },
-          };
+          },
+        };
   
-          const id = {
-            ForeignAsset: 0,
-          };
+        const id = {
+          ForeignAsset: 0,
+        };
   
-          const amount = TRANSFER_AMOUNT;
-          const destWeight = 50000000;
+        const amount = TRANSFER_AMOUNT;
+        const destWeight = 50000000;
   
-          const tx = api.tx.xTokens.transfer(id, amount, destination, destWeight);
-          const events = await submitTransactionAsync(randomAccount, tx);
-          const result = getGenericResult(events);
-          expect(result.success).to.be.true;
+        const tx = api.tx.xTokens.transfer(id, amount, destination, destWeight);
+        const events = await submitTransactionAsync(randomAccount, tx);
+        const result = getGenericResult(events);
+        expect(result.success).to.be.true;
   
-          [balanceAcalaTokenFinal] = await getBalance(api, [randomAccount.address]);
-          {
-            const {free} = (await api.query.tokens.accounts(randomAccount.addressRaw, {ForeignAsset: 0})).toJSON() as any;
-            balanceUniqueForeignTokenFinal = BigInt(free);
-          }
+        [balanceAcalaTokenFinal] = await getBalance(api, [randomAccount.address]);
+        {
+          const {free} = (await api.query.tokens.accounts(randomAccount.addressRaw, {ForeignAsset: 0})).toJSON() as any;
+          balanceUniqueForeignTokenFinal = BigInt(free);
+        }
   
-          const acaFees = balanceAcalaTokenAfter - balanceAcalaTokenFinal;
-          const unqDiffAfterOutcomeTransfer = balanceUniqueForeignTokenAfter - TRANSFER_AMOUNT;
+        const acaFees = balanceAcalaTokenAfter - balanceAcalaTokenFinal;
+        const unqDiffAfterOutcomeTransfer = balanceUniqueForeignTokenAfter - TRANSFER_AMOUNT;
 
-          const unqFees = unqDiffAfterOutcomeTransfer - balanceUniqueForeignTokenFinal;
+        const unqFees = unqDiffAfterOutcomeTransfer - balanceUniqueForeignTokenFinal;
 
-          console.log('[Acala -> Unique] transaction fees on Acala: %s ACA', acaFees);
-          console.log('[Acala -> Unique] transaction fees on Acala: %s UNQ', unqFees);
+        console.log('[Acala -> Unique] transaction fees on Acala: %s ACA', acaFees);
+        console.log('[Acala -> Unique] transaction fees on Acala: %s UNQ', unqFees);
 
-          expect(acaFees > 0).to.be.true;
-          expect(unqFees == 0n).to.be.true;
-        },
-        {provider: new WsProvider('ws://127.0.0.1:' + ACALA_PORT)},
-      );
+        expect(acaFees > 0).to.be.true;
+        expect(unqFees == 0n).to.be.true;
+      },
+      {provider: new WsProvider('ws://127.0.0.1:' + ACALA_PORT)},
+    );
 
-      // Unique side
-      await usingApi(async (api) => {
-        // todo do something about instant sealing, where there might not be any new blocks
-        await waitNewBlocks(api, 3);
+    // Unique side
+    await usingApi(async (api) => {
+      // todo do something about instant sealing, where there might not be any new blocks
+      await waitNewBlocks(api, 3);
   
-        [balanceUniqueTokenFinal] = await getBalance(api, [randomAccount.address]);
-        const actuallyDelivered = balanceUniqueTokenFinal - balanceUniqueTokenAfter;
-        expect(actuallyDelivered > 0).to.be.true;
+      [balanceUniqueTokenFinal] = await getBalance(api, [randomAccount.address]);
+      const actuallyDelivered = balanceUniqueTokenFinal - balanceUniqueTokenAfter;
+      expect(actuallyDelivered > 0).to.be.true;
   
-        const unqFees = TRANSFER_AMOUNT - actuallyDelivered;
-        console.log('[Acala -> Unique] transaction fees on Unique: %s UNQ', unqFees);
-        expect(unqFees == 0n).to.be.true;
-      });
+      const unqFees = TRANSFER_AMOUNT - actuallyDelivered;
+      console.log('[Acala -> Unique] transaction fees on Unique: %s UNQ', unqFees);
+      expect(unqFees == 0n).to.be.true;
     });
   });
+});