git.delta.rocks / unique-network / refs/commits / 2d2f157aedaf

difftreelog

source

tests/src/eth/fractionalizer/fractionalizer.test.ts24.0 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.161718import {readFile} from 'fs/promises';1920import {IKeyringPair} from '@polkadot/types/types';21import {evmToAddress} from '@polkadot/util-crypto';2223import {Contract} from 'web3-eth-contract';2425import {usingEthPlaygrounds, expect, itEth, EthUniqueHelper} from '../util';26import {CompiledContract} from '../util/playgrounds/types';27import {requirePalletsOrSkip, Pallets, makeNames} from '../../util';2829const {dirname} = makeNames(import.meta.url);3031let compiledFractionalizer: CompiledContract;3233const compileContract = async (helper: EthUniqueHelper): Promise<CompiledContract> => {34  if(!compiledFractionalizer) {35    compiledFractionalizer = await helper.ethContract.compile('Fractionalizer', (await readFile(`${dirname}/Fractionalizer.sol`)).toString(), [36      {solPath: 'api/CollectionHelpers.sol', fsPath: `${dirname}/../api/CollectionHelpers.sol`},37      {solPath: 'api/ContractHelpers.sol', fsPath: `${dirname}/../api/ContractHelpers.sol`},38      {solPath: 'api/UniqueRefungibleToken.sol', fsPath: `${dirname}/../api/UniqueRefungibleToken.sol`},39      {solPath: 'api/UniqueRefungible.sol', fsPath: `${dirname}/../api/UniqueRefungible.sol`},40      {solPath: 'api/UniqueNFT.sol', fsPath: `${dirname}/../api/UniqueNFT.sol`},41    ]);42  }43  return compiledFractionalizer;44};454647const deployContract = async (helper: EthUniqueHelper, owner: string): Promise<Contract> => {48  const compiled = await compileContract(helper);49  return await helper.ethContract.deployByAbi(owner, compiled.abi, compiled.object);50};515253const initContract = async (helper: EthUniqueHelper, owner: string): Promise<{contract: Contract, rftCollectionAddress: string}> => {54  const fractionalizer = await deployContract(helper, owner);55  const amount = 10n * helper.balance.getOneTokenNominal();56  const web3 = helper.getWeb3();57  await web3.eth.sendTransaction({from: owner, to: fractionalizer.options.address, value: `${amount}`, gas: helper.eth.DEFAULT_GAS});58  const result = await fractionalizer.methods.createAndSetRFTCollection('A', 'B', 'C').send({value: Number(2n * helper.balance.getOneTokenNominal())});59  const rftCollectionAddress = result.events.RFTCollectionSet.returnValues._collection;60  return {contract: fractionalizer, rftCollectionAddress};61};6263const mintRFTToken = async (helper: EthUniqueHelper, owner: string, fractionalizer: Contract, amount: bigint): Promise<{64  nftCollectionAddress: string, nftTokenId: number, rftTokenAddress: string65}> => {66  const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');67  const nftContract = await helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);68  const mintResult = await nftContract.methods.mint(owner).send({from: owner});69  const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;7071  await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});72  await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});73  const result = await fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, amount).send({from: owner});74  const {_collection, _tokenId, _rftToken} = result.events.Fractionalized.returnValues;75  return {76    nftCollectionAddress: _collection,77    nftTokenId: _tokenId,78    rftTokenAddress: _rftToken,79  };80};818283describe('Fractionalizer contract usage', () => {84  let donor: IKeyringPair;8586  before(async function() {87    await usingEthPlaygrounds(async (helper: EthUniqueHelper, privateKey) => {88      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);89      donor = await privateKey({url: import.meta.url});90    });91  });9293  itEth('Set RFT collection', async ({helper}) => {94    const owner = await helper.eth.createAccountWithBalance(donor, 10n);95    const fractionalizer = await deployContract(helper, owner);96    const rftCollection = await helper.eth.createRFTCollection(owner, 'rft', 'RFT collection', 'RFT');97    const rftContract = await helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);9899    const fractionalizerAddressCross = helper.ethCrossAccount.fromAddress(fractionalizer.options.address);100    await rftContract.methods.addCollectionAdminCross(fractionalizerAddressCross).send({from: owner});101    const result = await fractionalizer.methods.setRFTCollection(rftCollection.collectionAddress).send({from: owner});102    expect(result.events).to.be.like({103      RFTCollectionSet: {104        returnValues: {105          _collection: rftCollection.collectionAddress,106        },107      },108    });109  });110111  itEth('Mint RFT collection', async ({helper}) => {112    const owner = await helper.eth.createAccountWithBalance(donor, 10n);113    const fractionalizer = await deployContract(helper, owner);114    await helper.balance.transferToSubstrate(donor, evmToAddress(fractionalizer.options.address), 10n * helper.balance.getOneTokenNominal());115116    const result = await fractionalizer.methods.createAndSetRFTCollection('A', 'B', 'C').send({from: owner, value: Number(2n * helper.balance.getOneTokenNominal())});117    expect(result.events).to.be.like({118      RFTCollectionSet: {},119    });120    expect(result.events.RFTCollectionSet.returnValues._collection).to.be.ok;121  });122123  itEth('Set Allowlist', async ({helper}) => {124    const owner = await helper.eth.createAccountWithBalance(donor, 20n);125    const {contract: fractionalizer} = await initContract(helper, owner);126    const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');127128    const result1 = await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});129    expect(result1.events).to.be.like({130      AllowListSet: {131        returnValues: {132          _collection: nftCollection.collectionAddress,133          _status: true,134        },135      },136    });137    const result2 = await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, false).send({from: owner});138    expect(result2.events).to.be.like({139      AllowListSet: {140        returnValues: {141          _collection: nftCollection.collectionAddress,142          _status: false,143        },144      },145    });146  });147148  itEth('NFT to RFT', async ({helper}) => {149    const owner = await helper.eth.createAccountWithBalance(donor, 20n);150151    const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');152    const nftContract = await helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);153    const mintResult = await nftContract.methods.mint(owner).send({from: owner});154    const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;155156    const {contract: fractionalizer} = await initContract(helper, owner);157158    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});159    await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});160    const result = await fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, 100).send({from: owner});161    expect(result.events).to.be.like({162      Fractionalized: {163        returnValues: {164          _collection: nftCollection.collectionAddress,165          _tokenId: nftTokenId,166          _amount: '100',167        },168      },169    });170    const rftTokenAddress = result.events.Fractionalized.returnValues._rftToken;171172    const rftTokenContract = await helper.ethNativeContract.rftToken(rftTokenAddress);173    expect(await rftTokenContract.methods.balanceOf(owner).call()).to.equal('100');174  });175176  itEth('RFT to NFT', async ({helper}) => {177    const owner = await helper.eth.createAccountWithBalance(donor, 30n);178179    const {contract: fractionalizer, rftCollectionAddress} = await initContract(helper, owner);180    const {rftTokenAddress, nftCollectionAddress, nftTokenId} = await mintRFTToken(helper, owner, fractionalizer, 100n);181182    const {collectionId, tokenId} = helper.ethAddress.extractTokenId(rftTokenAddress);183    const refungibleAddress = helper.ethAddress.fromCollectionId(collectionId);184    expect(rftCollectionAddress).to.be.equal(refungibleAddress);185    const refungibleTokenContract = await helper.ethNativeContract.rftToken(rftTokenAddress, owner);186    await refungibleTokenContract.methods.approve(fractionalizer.options.address, 100).send({from: owner});187    const result = await fractionalizer.methods.rft2nft(refungibleAddress, tokenId).send({from: owner});188    expect(result.events).to.be.like({189      Defractionalized: {190        returnValues: {191          _rftToken: rftTokenAddress,192          _nftCollection: nftCollectionAddress,193          _nftTokenId: nftTokenId,194        },195      },196    });197  });198199  itEth('Test fractionalizer NFT <-> RFT mapping ', async ({helper}) => {200    const owner = await helper.eth.createAccountWithBalance(donor, 200n);201202    const {contract: fractionalizer, rftCollectionAddress} = await initContract(helper, owner);203    const {rftTokenAddress, nftCollectionAddress, nftTokenId} = await mintRFTToken(helper, owner, fractionalizer, 100n);204205    const {collectionId, tokenId} = helper.ethAddress.extractTokenId(rftTokenAddress);206    const refungibleAddress = helper.ethAddress.fromCollectionId(collectionId);207    expect(rftCollectionAddress).to.be.equal(refungibleAddress);208    const refungibleTokenContract = await helper.ethNativeContract.rftToken(rftTokenAddress, owner);209    await refungibleTokenContract.methods.approve(fractionalizer.options.address, 100).send({from: owner});210211    const rft2nft = await fractionalizer.methods.rft2nftMapping(rftTokenAddress).call();212    expect(rft2nft).to.be.like({213      _collection: nftCollectionAddress,214      _tokenId: nftTokenId,215    });216217    const nft2rft = await fractionalizer.methods.nft2rftMapping(nftCollectionAddress, nftTokenId).call();218    expect(nft2rft).to.be.eq(tokenId.toString());219  });220});221222223224describe('Negative Integration Tests for fractionalizer', () => {225  let donor: IKeyringPair;226227  before(async function() {228    await usingEthPlaygrounds(async (helper: EthUniqueHelper, privateKey) => {229      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);230      donor = await privateKey({url: import.meta.url});231    });232  });233234  itEth('call setRFTCollection twice', async ({helper}) => {235    const owner = await helper.eth.createAccountWithBalance(donor, 20n);236    const rftCollection = await helper.eth.createRFTCollection(owner, 'rft', 'RFT collection', 'RFT');237    const refungibleContract = await helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);238239    const fractionalizer = await deployContract(helper, owner);240    const fractionalizerAddressCross = helper.ethCrossAccount.fromAddress(fractionalizer.options.address);241    await refungibleContract.methods.addCollectionAdminCross(fractionalizerAddressCross).send({from: owner});242    await fractionalizer.methods.setRFTCollection(rftCollection.collectionAddress).send({from: owner});243244    await expect(fractionalizer.methods.setRFTCollection(rftCollection.collectionAddress).call())245      .to.be.rejectedWith(/RFT collection is already set$/g);246  });247248  itEth('call setRFTCollection with NFT collection', async ({helper}) => {249    const owner = await helper.eth.createAccountWithBalance(donor, 20n);250    const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');251    const nftContract = await helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);252253    const fractionalizer = await deployContract(helper, owner);254    const fractionalizerAddressCross = helper.ethCrossAccount.fromAddress(fractionalizer.options.address);255    await nftContract.methods.addCollectionAdminCross(fractionalizerAddressCross).send({from: owner});256257    await expect(fractionalizer.methods.setRFTCollection(nftCollection.collectionAddress).call())258      .to.be.rejectedWith(/Wrong collection type. Collection is not refungible.$/g);259  });260261  itEth('call setRFTCollection while not collection admin', async ({helper}) => {262    const owner = await helper.eth.createAccountWithBalance(donor, 20n);263    const fractionalizer = await deployContract(helper, owner);264    const rftCollection = await helper.eth.createRFTCollection(owner, 'rft', 'RFT collection', 'RFT');265266    await expect(fractionalizer.methods.setRFTCollection(rftCollection.collectionAddress).call())267      .to.be.rejectedWith(/Fractionalizer contract should be an admin of the collection$/g);268  });269270  itEth('call setRFTCollection after createAndSetRFTCollection', async ({helper}) => {271    const owner = await helper.eth.createAccountWithBalance(donor, 20n);272    const fractionalizer = await deployContract(helper, owner);273    await helper.balance.transferToSubstrate(donor, evmToAddress(fractionalizer.options.address), 10n * helper.balance.getOneTokenNominal());274275    const result = await fractionalizer.methods.createAndSetRFTCollection('A', 'B', 'C').send({from: owner, value: Number(2n * helper.balance.getOneTokenNominal())});276    const collectionIdAddress = result.events.RFTCollectionSet.returnValues._collection;277278    await expect(fractionalizer.methods.setRFTCollection(collectionIdAddress).call())279      .to.be.rejectedWith(/RFT collection is already set$/g);280  });281282  itEth('call nft2rft without setting RFT collection for contract', async ({helper}) => {283    const owner = await helper.eth.createAccountWithBalance(donor, 20n);284285    const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');286    const nftContract = await helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);287    const mintResult = await nftContract.methods.mint(owner).send({from: owner});288    const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;289290    const fractionalizer = await deployContract(helper, owner);291292    await expect(fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, 100).call())293      .to.be.rejectedWith(/RFT collection is not set$/g);294  });295296  itEth('call nft2rft while not owner of NFT token', async ({helper}) => {297    const owner = await helper.eth.createAccountWithBalance(donor, 20n);298    const nftOwner = await helper.eth.createAccountWithBalance(donor, 10n);299300    const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');301    const nftContract = await helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);302    const mintResult = await nftContract.methods.mint(owner).send({from: owner});303    const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;304    await nftContract.methods.transfer(nftOwner, 1).send({from: owner});305306307    const {contract: fractionalizer} = await initContract(helper, owner);308    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});309310    await expect(fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, 100).call({from: owner}))311      .to.be.rejectedWith(/Only token owner could fractionalize it$/g);312  });313314  itEth('call nft2rft while not in list of allowed accounts', async ({helper}) => {315    const owner = await helper.eth.createAccountWithBalance(donor, 20n);316317    const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');318    const nftContract = await helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);319    const mintResult = await nftContract.methods.mint(owner).send({from: owner});320    const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;321322    const {contract: fractionalizer} = await initContract(helper, owner);323324    await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});325    await expect(fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, 100).call())326      .to.be.rejectedWith(/Fractionalization of this collection is not allowed by admin$/g);327  });328329  itEth('call nft2rft while fractionalizer doesnt have approval for nft token', async ({helper}) => {330    const owner = await helper.eth.createAccountWithBalance(donor, 20n);331332    const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');333    const nftContract = await helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);334    const mintResult = await nftContract.methods.mint(owner).send({from: owner});335    const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;336337    const {contract: fractionalizer} = await initContract(helper, owner);338339    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});340    await expect(fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, 100).call())341      .to.be.rejectedWith(/ApprovedValueTooLow$/g);342  });343344  itEth('call rft2nft without setting RFT collection for contract', async ({helper}) => {345    const owner = await helper.eth.createAccountWithBalance(donor, 20n);346347    const fractionalizer = await deployContract(helper, owner);348    const rftCollection = await helper.eth.createRFTCollection(owner, 'rft', 'RFT collection', 'RFT');349    const refungibleContract = await helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);350    const mintResult = await refungibleContract.methods.mint(owner).send({from: owner});351    const rftTokenId = mintResult.events.Transfer.returnValues.tokenId;352353    await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call({from: owner}))354      .to.be.rejectedWith(/RFT collection is not set$/g);355  });356357  itEth('call rft2nft for RFT token that is not from configured RFT collection', async ({helper}) => {358    const owner = await helper.eth.createAccountWithBalance(donor, 20n);359360    const {contract: fractionalizer} = await initContract(helper, owner);361    const rftCollection = await helper.eth.createRFTCollection(owner, 'rft', 'RFT collection', 'RFT');362    const refungibleContract = await helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);363    const mintResult = await refungibleContract.methods.mint(owner).send({from: owner});364    const rftTokenId = mintResult.events.Transfer.returnValues.tokenId;365366    await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call())367      .to.be.rejectedWith(/Wrong RFT collection$/g);368  });369370  itEth('call rft2nft for RFT token that was not minted by fractionalizer contract', async ({helper}) => {371    const owner = await helper.eth.createAccountWithBalance(donor, 20n);372    const rftCollection = await helper.eth.createRFTCollection(owner, 'rft', 'RFT collection', 'RFT');373    const refungibleContract = await helper.ethNativeContract.collection(rftCollection.collectionAddress, 'rft', owner);374375    const fractionalizer = await deployContract(helper, owner);376377    const fractionalizerAddressCross = helper.ethCrossAccount.fromAddress(fractionalizer.options.address);378    await refungibleContract.methods.addCollectionAdminCross(fractionalizerAddressCross).send({from: owner});379    await fractionalizer.methods.setRFTCollection(rftCollection.collectionAddress).send({from: owner});380381    const mintResult = await refungibleContract.methods.mint(owner).send({from: owner});382    const rftTokenId = mintResult.events.Transfer.returnValues.tokenId;383384    await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call())385      .to.be.rejectedWith(/No corresponding NFT token found$/g);386  });387388  itEth('call rft2nft without owning all RFT pieces', async ({helper}) => {389    const owner = await helper.eth.createAccountWithBalance(donor, 200n);390    const receiver = await helper.eth.createAccountWithBalance(donor, 10n);391392    const {contract: fractionalizer, rftCollectionAddress} = await initContract(helper, owner);393    const {rftTokenAddress} = await mintRFTToken(helper, owner, fractionalizer, 100n);394395    const {tokenId} = helper.ethAddress.extractTokenId(rftTokenAddress);396    const refungibleTokenContract = await helper.ethNativeContract.rftToken(rftTokenAddress, owner);397    await refungibleTokenContract.methods.transfer(receiver, 50).send({from: owner});398    await refungibleTokenContract.methods.approve(fractionalizer.options.address, 50).send({from: receiver});399    await expect(fractionalizer.methods.rft2nft(rftCollectionAddress, tokenId).call({from: receiver}))400      .to.be.rejectedWith(/Not all pieces are owned by the caller$/g);401  });402403  itEth('send QTZ/UNQ to contract from non owner', async ({helper}) => {404    const owner = await helper.eth.createAccountWithBalance(donor, 20n);405    const payer = await helper.eth.createAccountWithBalance(donor, 10n);406407    const fractionalizer = await deployContract(helper, owner);408    const amount = 10n * helper.balance.getOneTokenNominal();409    const web3 = helper.getWeb3();410    await expect(web3.eth.sendTransaction({from: payer, to: fractionalizer.options.address, value: `${amount}`, gas: helper.eth.DEFAULT_GAS})).to.be.rejected;411  });412413  itEth('fractionalize NFT with NFT transfers disallowed', async ({helper}) => {414    const nftCollection = await helper.nft.mintCollection(donor, {name: 'A', description: 'B', tokenPrefix: 'C'});415416    const owner = await helper.eth.createAccountWithBalance(donor, 20n);417    const nftToken = await nftCollection.mintToken(donor, {Ethereum: owner});418    await helper.executeExtrinsic(donor, 'api.tx.unique.setTransfersEnabledFlag', [nftCollection.collectionId, false], true);419    const nftCollectionAddress = helper.ethAddress.fromCollectionId(nftCollection.collectionId);420    const {contract: fractionalizer} = await initContract(helper, owner);421    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollectionAddress, true).send({from: owner});422423    const nftContract = await helper.ethNativeContract.collection(nftCollectionAddress, 'nft', owner);424    await nftContract.methods.approve(fractionalizer.options.address, nftToken.tokenId).send({from: owner});425    await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftToken.tokenId, 100).call())426      .to.be.rejectedWith(/TransferNotAllowed$/g);427  });428429  itEth('fractionalize NFT with RFT transfers disallowed', async ({helper}) => {430    const owner = await helper.eth.createAccountWithBalance(donor, 20n);431432    const rftCollection = await helper.rft.mintCollection(donor, {name: 'A', description: 'B', tokenPrefix: 'C'});433    const rftCollectionAddress = helper.ethAddress.fromCollectionId(rftCollection.collectionId);434    const fractionalizer = await deployContract(helper, owner);435    await rftCollection.addAdmin(donor, {Ethereum: fractionalizer.options.address});436437    await fractionalizer.methods.setRFTCollection(rftCollectionAddress).send({from: owner});438    await helper.executeExtrinsic(donor, 'api.tx.unique.setTransfersEnabledFlag', [rftCollection.collectionId, false], true);439440    const nftCollection = await helper.eth.createNFTCollection(owner, 'nft', 'NFT collection', 'NFT');441    const nftContract = await helper.ethNativeContract.collection(nftCollection.collectionAddress, 'nft', owner);442    const mintResult = await nftContract.methods.mint(owner).send({from: owner});443    const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;444445    await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});446    await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});447448    await expect(fractionalizer.methods.nft2rft(nftCollection.collectionAddress, nftTokenId, 100n).call())449      .to.be.rejectedWith(/TransferNotAllowed$/g);450  });451});