git.delta.rocks / unique-network / refs/commits / 25ce44862797

difftreelog

test fixed and improved tests for ERC721Metadata compatible collections. WIP, 1 test still fails

Alex Saft2022-10-15parent: #49ed2a2.patch.diff
in: master

13 files changed

modifiedtests/src/eth/base.test.tsdiffbeforeafterboth
--- a/tests/src/eth/base.test.ts
+++ b/tests/src/eth/base.test.ts
@@ -23,7 +23,7 @@
 describe('Contract calls', () => {
   let donor: IKeyringPair;
 
-  before(async function() {
+  before(async function () {
     await usingEthPlaygrounds(async (_helper, privateKey) => {
       donor = privateKey('//Alice');
     });
@@ -40,7 +40,12 @@
   itEth('Balance transfer fee is less than 0.2 UNQ', async ({helper}) => {
     const userA = await helper.eth.createAccountWithBalance(donor);
     const userB = helper.eth.createAccount();
-    const cost = await helper.eth.calculateFee({Ethereum: userA}, () => helper.getWeb3().eth.sendTransaction({from: userA, to: userB, value: '1000000', gas: helper.eth.DEFAULT_GAS}));
+    const cost = await helper.eth.calculateFee({Ethereum: userA}, () => helper.getWeb3().eth.sendTransaction({
+      from: userA,
+      to: userB,
+      value: '1000000',
+      gas: helper.eth.DEFAULT_GAS
+    }));
     const balanceB = await helper.balance.getEthereum(userB);
     expect(cost - balanceB < BigInt(0.2 * Number(helper.balance.getOneTokenNominal()))).to.be.true;
   });
@@ -69,67 +74,59 @@
 describe('ERC165 tests', async () => {
   // https://eips.ethereum.org/EIPS/eip-165
 
-  let collection: number;
+  let erc721MetadataCompatibleNftCollectionId: number;
+  let simpleNftCollectionId: number;
   let minter: string;
 
-  function contract(helper: EthUniqueHelper): Contract {
-    return helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection), 'nft', minter);
+  const BASE_URI = 'base/';
+
+  async function checkInterface(helper: EthUniqueHelper, interfaceId: string, simpleResult: boolean, compatibleResult: boolean) {
+    const simple = helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(simpleNftCollectionId), 'nft', minter);
+    const compatible = helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(erc721MetadataCompatibleNftCollectionId), 'nft', minter);
+
+    expect(await simple.methods.supportsInterface(interfaceId).call()).to.equal(simpleResult, `empty (not ERC721Metadata compatible) NFT collection returns not ${simpleResult}`);
+    expect(await compatible.methods.supportsInterface(interfaceId).call()).to.equal(compatibleResult, `ERC721Metadata compatible NFT collection returns not ${compatibleResult}`);
   }
 
   before(async () => {
     await usingEthPlaygrounds(async (helper, privateKey) => {
       const donor = privateKey('//Alice');
-      const [alice] = await helper.arrange.createAccounts([10n], donor);
-      ({collectionId: collection} = await helper.nft.mintCollection(
-        alice,
-        {
-          name: 'test',
-          description: 'test',
-          tokenPrefix: 'test',
-          properties: [{key: 'ERC721Metadata', value: '1'}],
-          tokenPropertyPermissions: [{
-            key: 'URI',
-            permission: {
-              mutable: true,
-              collectionAdmin: true,
-              tokenOwner: false,
-            },
-          }],
-        },
-      ));
-      minter = helper.eth.createAccount();
+      minter = await helper.eth.createAccountWithBalance(donor);
+
+      simpleNftCollectionId = (await helper.eth.createNFTCollection(minter, 'n', 'd', 'p')).collectionId;
+      erc721MetadataCompatibleNftCollectionId = (await helper.eth.createERC721MetadataCompatibleNFTCollection(minter, 'n', 'd', 'p', BASE_URI)).collectionId;
     });
   });
 
-  itEth('interfaceID == 0xffffffff always false', async ({helper}) => {
-    expect(await contract(helper).methods.supportsInterface('0xffffffff').call()).to.be.false;
+  itEth('nonexistent interfaceID - 0xffffffff - always false', async ({helper}) => {
+    await checkInterface(helper, '0xffffffff', false, false);
   });
 
-  itEth('ERC721 support', async ({helper}) => {
-    expect(await contract(helper).methods.supportsInterface('0x780e9d63').call()).to.be.true;
+  itEth('ERC721 - 0x780e9d63 - support', async ({helper}) => {
+    await checkInterface(helper, '0x780e9d63', true, true);
   });
 
-  itEth('ERC721Metadata support', async ({helper}) => {
-    expect(await contract(helper).methods.supportsInterface('0x5b5e139f').call()).to.be.true;
+  itEth('ERC721Metadata - 0x5b5e139f - support', async ({helper}) => {
+    await checkInterface(helper, '0x5b5e139f', false, true);
   });
 
-  itEth('ERC721Mintable support', async ({helper}) => {
-    expect(await contract(helper).methods.supportsInterface('0x68ccfe89').call()).to.be.true;
+  itEth('ERC721UniqueMintable - 0x476ff149 - support', async ({helper}) => {
+    await checkInterface(helper, '0x476ff149', true, true);
   });
 
-  itEth('ERC721Enumerable support', async ({helper}) => {
-    expect(await contract(helper).methods.supportsInterface('0x780e9d63').call()).to.be.true;
+  itEth('ERC721Enumerable - 0x780e9d63 - support', async ({helper}) => {
+    await checkInterface(helper, '0x780e9d63', true, true);
   });
 
-  itEth('ERC721UniqueExtensions support', async ({helper}) => {
-    expect(await contract(helper).methods.supportsInterface('0xd74d154f').call()).to.be.true;
+  itEth('ERC721UniqueExtensions - 0x4468500d - support', async ({helper}) => {
+    await checkInterface(helper, '0x4468500d', true, true);
   });
 
-  itEth('ERC721Burnable support', async ({helper}) => {
-    expect(await contract(helper).methods.supportsInterface('0x42966c68').call()).to.be.true;
+  itEth('ERC721Burnable - 0x42966c68 - support', async ({helper}) => {
+    await checkInterface(helper, '0x42966c68', true, true);
   });
 
-  itEth('ERC165 support', async ({helper}) => {
-    expect(await contract(helper).methods.supportsInterface('0x01ffc9a7').call()).to.be.true;
+  itEth('ERC165 - 0x01ffc9a7 - support', async ({helper}) => {
+    await checkInterface(helper, '0x01ffc9a7', true, true);
   });
 });
modifiedtests/src/eth/collectionProperties.test.tsdiffbeforeafterboth
--- a/tests/src/eth/collectionProperties.test.ts
+++ b/tests/src/eth/collectionProperties.test.ts
@@ -1,6 +1,7 @@
-import {itEth, usingEthPlaygrounds, expect} from './util/playgrounds';
+import {itEth, usingEthPlaygrounds, expect, EthUniqueHelper} from './util/playgrounds';
 import {IKeyringPair} from '@polkadot/types/types';
 import {Pallets} from '../util/playgrounds';
+import {IProperty, ITokenPropertyPermission} from "../util/playgrounds/types";
 
 describe('EVM collection properties', () => {
   let donor: IKeyringPair;
@@ -65,52 +66,82 @@
     });
   });
 
-  itEth('ERC721Metadata property can be set for NFT collection', async({helper}) => {
+  const checkERC721Metadata = async (helper: EthUniqueHelper, mode: 'nft' | 'rft') => {
     const caller = await helper.eth.createAccountWithBalance(donor);
-    const tokenPropertyPermissions = [{
-      key: 'URI',
-      permission: {
-        mutable: true,
-        collectionAdmin: true,
-        tokenOwner: false,
-      },
-    }];
-    const collection = await helper.nft.mintCollection(donor, {name: 'col', description: 'descr', tokenPrefix: 'COL', tokenPropertyPermissions});
+    const bruh = await helper.eth.createAccountWithBalance(donor);
 
-    await collection.addAdmin(donor, {Ethereum: caller});
-    const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);
+    const BASE_URI = 'base/'
+    const SUFFIX = 'suffix1'
+    const URI = 'uri1'
 
-    await contract.methods.setCollectionProperty('ERC721Metadata', Buffer.from('1')).send({from: caller});
+    const collectionHelpers = helper.ethNativeContract.collectionHelpers(caller);
+    const creatorMethod = mode === 'rft' ? 'createRFTCollection' : 'createNFTCollection'
 
-    expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.true;
+    const {collectionId, collectionAddress} = await helper.eth[creatorMethod](caller, 'n', 'd', 'p')
 
-    await contract.methods.setCollectionProperty('ERC721Metadata', Buffer.from('0')).send({from: caller});
+    const contract = helper.ethNativeContract.collectionById(collectionId, mode, caller);
+    await contract.methods.addCollectionAdmin(bruh).send(); // to check that admin will work too
 
+    const collection1 = await helper.nft.getCollectionObject(collectionId);
+    const data1 = await collection1.getData()
+    expect(data1?.raw.flags.erc721metadata).to.be.false;
     expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.false;
-  });
 
-  itEth.ifWithPallets('ERC721Metadata property can be set for RFT collection', [Pallets.ReFungible], async({helper}) => {
-    const caller = await helper.eth.createAccountWithBalance(donor);
-    const tokenPropertyPermissions = [{
-      key: 'URI',
-      permission: {
-        mutable: true,
-        collectionAdmin: true,
-        tokenOwner: false,
-      },
-    }];
-    const collection = await helper.rft.mintCollection(donor, {name: 'col', description: 'descr', tokenPrefix: 'COL', tokenPropertyPermissions});
+    await collectionHelpers.methods.makeCollectionERC721MetadataCompatible(collectionAddress, BASE_URI)
+      .send({from: bruh});
 
-    await collection.addAdmin(donor, {Ethereum: caller});
+    expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.true;
 
-    const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);
+    const collection2 = await helper.nft.getCollectionObject(collectionId);
+    const data2 = await collection2.getData()
+    expect(data2?.raw.flags.erc721metadata).to.be.true;
 
-    await contract.methods.setCollectionProperty('ERC721Metadata', Buffer.from('1')).send({from: caller});
+    const TPPs = data2?.raw.tokenPropertyPermissions
+    expect(TPPs?.length).to.equal(2);
 
-    expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.true;
+    expect(TPPs.find((tpp: ITokenPropertyPermission) => {
+      return tpp.key === "URI" && tpp.permission.mutable && tpp.permission.collectionAdmin && !tpp.permission.tokenOwner
+    })).to.be.not.null
 
-    await contract.methods.setCollectionProperty('ERC721Metadata', Buffer.from('0')).send({from: caller});
+    expect(TPPs.find((tpp: ITokenPropertyPermission) => {
+      return tpp.key === "URISuffix" && tpp.permission.mutable && tpp.permission.collectionAdmin && !tpp.permission.tokenOwner
+    })).to.be.not.null
+
+    expect(data2?.raw.properties?.find((property: IProperty) => {
+      return property.key === "baseURI" && property.value === BASE_URI
+    })).to.be.not.null
+
+    const token1Result = await contract.methods.mint(bruh).send();
+    const tokenId1 = token1Result.events.Transfer.returnValues.tokenId;
+
+    expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(BASE_URI);
+
+    await contract.methods.setProperty(tokenId1, "URISuffix", Buffer.from(SUFFIX)).send();
+    expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(BASE_URI + SUFFIX);
 
-    expect(await contract.methods.supportsInterface('0x5b5e139f').call()).to.be.false;
+    await contract.methods.setProperty(tokenId1, "URI", Buffer.from(URI)).send();
+    expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(URI);
+
+    await contract.methods.deleteProperty(tokenId1, "URI").send();
+    expect(await contract.methods.tokenURI(tokenId1).call()).to.equal(BASE_URI + SUFFIX);
+
+    const token2Result = await contract.methods.mintWithTokenURI(bruh, URI).send();
+    const tokenId2 = token2Result.events.Transfer.returnValues.tokenId;
+
+    expect(await contract.methods.tokenURI(tokenId2).call()).to.equal(URI);
+
+    await contract.methods.deleteProperty(tokenId2, "URI").send();
+    expect(await contract.methods.tokenURI(tokenId2).call()).to.equal(BASE_URI);
+
+    await contract.methods.setProperty(tokenId2, "URISuffix", Buffer.from(SUFFIX)).send();
+    expect(await contract.methods.tokenURI(tokenId2).call()).to.equal(BASE_URI + SUFFIX);
+  }
+
+  itEth('ERC721Metadata property can be set for NFT collection', async({helper}) => {
+    await checkERC721Metadata(helper, 'nft');
+  });
+
+  itEth.ifWithPallets('ERC721Metadata property can be set for RFT collection', [Pallets.ReFungible], async({helper}) => {
+    await checkERC721Metadata(helper, 'rft');
   });
 });
modifiedtests/src/eth/collectionSponsoring.test.tsdiffbeforeafterboth
--- a/tests/src/eth/collectionSponsoring.test.ts
+++ b/tests/src/eth/collectionSponsoring.test.ts
@@ -33,9 +33,8 @@
 
     await collection.addToAllowList(alice, {Ethereum: minter});
 
-    const nextTokenId = await contract.methods.nextTokenId().call();
-    expect(nextTokenId).to.equal('1');
-    const result = await contract.methods.mint(minter, nextTokenId).send();
+    const result = await contract.methods.mint(minter).send();
+
     const events = helper.eth.normalizeEvents(result.events);
     expect(events).to.be.deep.equal([
       {
@@ -44,7 +43,7 @@
         args: {
           from: '0x0000000000000000000000000000000000000000',
           to: minter,
-          tokenId: nextTokenId,
+          tokenId: '1',
         },
       },
     ]);
@@ -62,11 +61,11 @@
   //   expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;
   //   result = await collectionEvm.methods.setCollectionSponsorSubstrate(sponsor.addressRaw).send({from: owner});
   //   expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;
-    
+
   //   const confirmTx = await api.tx.unique.confirmSponsorship(collectionId);
   //   await submitTransactionAsync(sponsor, confirmTx);
   //   expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;
-    
+
   //   const sponsorTuple = await collectionEvm.methods.collectionSponsor().call({from: owner});
   //   expect(bigIntToSub(api, BigInt(sponsorTuple[1]))).to.be.eq(sponsor.address);
   // });
@@ -83,28 +82,26 @@
     expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;
     result = await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner});
     expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;
-    
+
     await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});
     expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;
-    
+
     await collectionEvm.methods.removeCollectionSponsor().send({from: owner});
-    
+
     const sponsorTuple = await collectionEvm.methods.collectionSponsor().call({from: owner});
     expect(sponsorTuple.field_0).to.be.eq('0x0000000000000000000000000000000000000000');
   });
 
   itEth('Sponsoring collection from evm address via access list', async ({helper}) => {
     const owner = await helper.eth.createAccountWithBalance(donor);
-    const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);
 
-    let result = await collectionHelpers.methods.createERC721MetadataCompatibleNFTCollection('Sponsor collection', '1', '1', '').send({value: Number(2n * nominal)});
-    const collectionIdAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
-    const collectionId = helper.ethAddress.extractCollectionId(collectionIdAddress);
+    const {collectionId, collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Sponsor collection', '1', '1', '');
+
     const collection = helper.nft.getCollectionObject(collectionId);
     const sponsor = await helper.eth.createAccountWithBalance(donor);
-    const collectionEvm = helper.ethNativeContract.collection(collectionIdAddress, 'nft', owner);
+    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
 
-    result = await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner});
+    await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner});
     let collectionData = (await collection.getData())!;
     expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
     await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');
@@ -133,23 +130,17 @@
     const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
 
     {
-      const nextTokenId = await collectionEvm.methods.nextTokenId().call();
-      expect(nextTokenId).to.be.equal('1');
-      const result = await collectionEvm.methods.mintWithTokenURI(
-        user,
-        nextTokenId,
-        'Test URI',
-      ).send({from: user});
+      const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});
       const events = helper.eth.normalizeEvents(result.events);
 
       expect(events).to.be.deep.equal([
         {
-          address: collectionIdAddress,
+          address: collectionAddress,
           event: 'Transfer',
           args: {
             from: '0x0000000000000000000000000000000000000000',
             to: user,
-            tokenId: nextTokenId,
+            tokenId: '1',
           },
         },
       ]);
@@ -173,10 +164,10 @@
   //   const collectionEvm = evmCollection(web3, owner, collectionIdAddress);
 
   //   await collectionEvm.methods.setCollectionSponsorSubstrate(sponsor.addressRaw).send({from: owner});
-    
+
   //   const confirmTx = await api.tx.unique.confirmSponsorship(collectionId);
   //   await submitTransactionAsync(sponsor, confirmTx);
-    
+
   //   const user = createEthAccount(web3);
   //   const nextTokenId = await collectionEvm.methods.nextTokenId().call();
   //   expect(nextTokenId).to.be.equal('1');
@@ -221,39 +212,32 @@
 
   itEth('Check that transaction via EVM spend money from sponsor address', async ({helper}) => {
     const owner = await helper.eth.createAccountWithBalance(donor);
-    const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);
 
-    let result = await collectionHelpers.methods.createERC721MetadataCompatibleNFTCollection('Sponsor collection', '1', '1', '').send({value: Number(2n * nominal)});
-    const collectionIdAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
-    const collectionId = helper.ethAddress.extractCollectionId(collectionIdAddress);
+    const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner,'Sponsor collection', '1', '1', '');
     const collection = helper.nft.getCollectionObject(collectionId);
     const sponsor = await helper.eth.createAccountWithBalance(donor);
-    const collectionEvm = helper.ethNativeContract.collection(collectionIdAddress, 'nft', owner);
+    const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
 
-    result = await collectionEvm.methods.setCollectionSponsor(sponsor).send();
+    await collectionEvm.methods.setCollectionSponsor(sponsor).send();
     let collectionData = (await collection.getData())!;
     expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
     await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');
 
-    const sponsorCollection = helper.ethNativeContract.collection(collectionIdAddress, 'nft', sponsor);
+    const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'nft', sponsor);
     await sponsorCollection.methods.confirmCollectionSponsorship().send();
     collectionData = (await collection.getData())!;
     expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));
 
     const user = helper.eth.createAccount();
     await collectionEvm.methods.addCollectionAdmin(user).send();
-    
+
     const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
     const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
 
-    const userCollectionEvm = helper.ethNativeContract.collection(collectionIdAddress, 'nft', user);
-    const nextTokenId = await userCollectionEvm.methods.nextTokenId().call();
-    expect(nextTokenId).to.be.equal('1');
-    result = await userCollectionEvm.methods.mintWithTokenURI(
-      user,
-      nextTokenId,
-      'Test URI',
-    ).send();
+    const userCollectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', user);
+
+    let result = await userCollectionEvm.methods.mintWithTokenURI(user, 'Test URI',).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
 
     const events = helper.eth.normalizeEvents(result.events);
     const address = helper.ethAddress.fromCollectionId(collectionId);
@@ -265,12 +249,12 @@
         args: {
           from: '0x0000000000000000000000000000000000000000',
           to: user,
-          tokenId: nextTokenId,
+          tokenId: '1',
         },
       },
     ]);
-    expect(await userCollectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
-  
+    expect(await userCollectionEvm.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
+
     const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));
     expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);
     const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));
modifiedtests/src/eth/fractionalizer/Fractionalizer.soldiffbeforeafterboth
--- a/tests/src/eth/fractionalizer/Fractionalizer.sol
+++ b/tests/src/eth/fractionalizer/Fractionalizer.sol
@@ -124,8 +124,7 @@
 		address rftTokenAddress;
 		UniqueRefungibleToken rftTokenContract;
 		if (nft2rftMapping[_collection][_token] == 0) {
-			rftTokenId = rftCollectionContract.nextTokenId();
-			rftCollectionContract.mint(address(this), rftTokenId);
+            rftTokenId = rftCollectionContract.mint(address(this));
 			rftTokenAddress = rftCollectionContract.tokenContractAddress(rftTokenId);
 			nft2rftMapping[_collection][_token] = rftTokenId;
 			rft2nftMapping[rftTokenAddress] = Token(_collection, _token);
modifiedtests/src/eth/fractionalizer/fractionalizer.test.tsdiffbeforeafterboth
--- a/tests/src/eth/fractionalizer/fractionalizer.test.ts
+++ b/tests/src/eth/fractionalizer/fractionalizer.test.ts
@@ -64,8 +64,8 @@
 }> => {
   const nftCollection = await helper.eth.createNFTCollection(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({from: owner});
+  const mintResult = await nftContract.methods.mint(owner).send({from: owner});
+  const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
 
   await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});
   await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});
@@ -148,8 +148,8 @@
 
     const nftCollection = await helper.eth.createNFTCollection(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({from: owner});
+    const mintResult = await nftContract.methods.mint(owner).send({from: owner});
+    const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
 
     const {contract: fractionalizer} = await initContract(helper, owner);
 
@@ -280,8 +280,8 @@
 
     const nftCollection = await helper.eth.createNFTCollection(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({from: owner});
+    const mintResult = await nftContract.methods.mint(owner).send({from: owner});
+    const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
 
     const fractionalizer = await deployContract(helper, owner);
 
@@ -295,8 +295,8 @@
 
     const nftCollection = await helper.eth.createNFTCollection(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({from: owner});
+    const mintResult = await nftContract.methods.mint(owner).send({from: owner});
+    const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
     await nftContract.methods.transfer(nftOwner, 1).send({from: owner});
 
 
@@ -312,8 +312,8 @@
 
     const nftCollection = await helper.eth.createNFTCollection(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({from: owner});
+    const mintResult = await nftContract.methods.mint(owner).send({from: owner});
+    const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
 
     const {contract: fractionalizer} = await initContract(helper, owner);
 
@@ -327,8 +327,8 @@
 
     const nftCollection = await helper.eth.createNFTCollection(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({from: owner});
+    const mintResult = await nftContract.methods.mint(owner).send({from: owner});
+    const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
 
     const {contract: fractionalizer} = await initContract(helper, owner);
 
@@ -343,9 +343,9 @@
     const fractionalizer = await deployContract(helper, owner);
     const rftCollection = await helper.eth.createRFTCollection(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({from: owner});
-    
+    const mintResult = await refungibleContract.methods.mint(owner).send({from: owner});
+    const rftTokenId = mintResult.events.Transfer.returnValues.tokenId;
+
     await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call({from: owner}))
       .to.be.rejectedWith(/RFT collection is not set$/g);
   });
@@ -356,9 +356,9 @@
     const {contract: fractionalizer} = await initContract(helper, owner);
     const rftCollection = await helper.eth.createRFTCollection(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({from: owner});
-    
+    const mintResult = await refungibleContract.methods.mint(owner).send({from: owner});
+    const rftTokenId = mintResult.events.Transfer.returnValues.tokenId;
+
     await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call())
       .to.be.rejectedWith(/Wrong RFT collection$/g);
   });
@@ -373,9 +373,9 @@
     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({from: owner});
-    
+    const mintResult = await refungibleContract.methods.mint(owner).send({from: owner});
+    const rftTokenId = mintResult.events.Transfer.returnValues.tokenId;
+
     await expect(fractionalizer.methods.rft2nft(rftCollection.collectionAddress, rftTokenId).call())
       .to.be.rejectedWith(/No corresponding NFT token found$/g);
   });
@@ -386,7 +386,7 @@
 
     const {contract: fractionalizer, rftCollectionAddress} = await initContract(helper, owner);
     const {rftTokenAddress} = await mintRFTToken(helper, owner, fractionalizer, 100n);
-    
+
     const {tokenId} = helper.ethAddress.extractTokenId(rftTokenAddress);
     const refungibleTokenContract = helper.ethNativeContract.rftToken(rftTokenAddress, owner);
     await refungibleTokenContract.methods.transfer(receiver, 50).send({from: owner});
@@ -420,7 +420,7 @@
     await expect(fractionalizer.methods.nft2rft(nftCollectionAddress, nftToken.tokenId, 100).call())
       .to.be.rejectedWith(/TransferNotAllowed$/g);
   });
-  
+
   itEth('fractionalize NFT with RFT transfers disallowed', async ({helper}) => {
     const owner = await helper.eth.createAccountWithBalance(donor, 20n);
 
@@ -434,8 +434,8 @@
 
     const nftCollection = await helper.eth.createNFTCollection(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({from: owner});
+    const mintResult = await nftContract.methods.mint(owner).send({from: owner});
+    const nftTokenId = mintResult.events.Transfer.returnValues.tokenId;
 
     await fractionalizer.methods.setNftCollectionIsAllowed(nftCollection.collectionAddress, true).send({from: owner});
     await nftContract.methods.approve(fractionalizer.options.address, nftTokenId).send({from: owner});
modifiedtests/src/eth/nesting/nest.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nesting/nest.test.ts
+++ b/tests/src/eth/nesting/nest.test.ts
@@ -29,74 +29,53 @@
     itEth('NFT: allows an Owner to nest/unnest their token', async ({helper}) => {
       const owner = await helper.eth.createAccountWithBalance(donor);
       const {collectionId, contract} = await createNestingCollection(helper, owner);
-  
-      // Create a token to be nested
-      const targetNFTTokenId = await contract.methods.nextTokenId().call();
-      await contract.methods.mint(
-        owner,
-        targetNFTTokenId,
-      ).send({from: owner});
-  
+
+      // Create a token to be nested to
+      const mintingTargetNFTTokenIdResult = await contract.methods.mint(owner).send({from: owner});
+      const targetNFTTokenId = mintingTargetNFTTokenIdResult.events.Transfer.returnValues.tokenId;
       const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetNFTTokenId);
-  
+
       // Create a nested token
-      const firstTokenId = await contract.methods.nextTokenId().call();
-      await contract.methods.mint(
-        targetNftTokenAddress,
-        firstTokenId,
-      ).send({from: owner});
-  
+      const mintingFirstTokenIdResult = await contract.methods.mint(targetNftTokenAddress).send({from: owner});
+      const firstTokenId = mintingFirstTokenIdResult.events.Transfer.returnValues.tokenId;
       expect(await contract.methods.ownerOf(firstTokenId).call()).to.be.equal(targetNftTokenAddress);
-  
+
       // Create a token to be nested and nest
-      const secondTokenId = await contract.methods.nextTokenId().call();
-      await contract.methods.mint(
-        owner,
-        secondTokenId,
-      ).send({from: owner});
-  
+      const mintingSecondTokenIdResult = await contract.methods.mint(owner).send({from: owner});
+      const secondTokenId = mintingSecondTokenIdResult.events.Transfer.returnValues.tokenId;
+
       await contract.methods.transfer(targetNftTokenAddress, secondTokenId).send({from: owner});
-  
       expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(targetNftTokenAddress);
-  
+
       // Unnest token back
       await contract.methods.transferFrom(targetNftTokenAddress, owner, secondTokenId).send({from: owner});
       expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(owner);
     });
-  
+
     itEth('NFT: allows an Owner to nest/unnest their token (Restricted nesting)', async ({helper}) => {
       const owner = await helper.eth.createAccountWithBalance(donor);
-  
+
       const {collectionId: collectionIdA, collectionAddress: collectionAddressA, contract: contractA} = await createNestingCollection(helper, owner);
       const {collectionAddress: collectionAddressB, contract: contractB} = await createNestingCollection(helper, owner);
       await contractA.methods.setCollectionNesting(true, [collectionAddressA, collectionAddressB]).send({from: owner});
-  
+
       // Create a token to nest into
-      const targetNftTokenId = await contractA.methods.nextTokenId().call();
-      await contractA.methods.mint(
-        owner,
-        targetNftTokenId,
-      ).send({from: owner});
+      const mintingtargetNftTokenIdResult = await contractA.methods.mint(owner).send({from: owner});
+      const targetNftTokenId = mintingtargetNftTokenIdResult.events.Transfer.returnValues.tokenId;
       const nftTokenAddressA1 = helper.ethAddress.fromTokenId(collectionIdA, targetNftTokenId);
-  
+
       // Create a token for nesting in the same collection as the target
-      const nftTokenIdA = await contractA.methods.nextTokenId().call();
-      await contractA.methods.mint(
-        owner,
-        nftTokenIdA,
-      ).send({from: owner});
-  
+      const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});
+      const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;
+
       // Create a token for nesting in a different collection
-      const nftTokenIdB = await contractB.methods.nextTokenId().call();
-      await contractB.methods.mint(
-        owner,
-        nftTokenIdB,
-      ).send({from: owner});
-  
+      const mintingTokenIdBResult = await contractB.methods.mint(owner).send({from: owner});
+      const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;
+
       // Nest
       await contractA.methods.transfer(nftTokenAddressA1, nftTokenIdA).send({from: owner});
       expect(await contractA.methods.ownerOf(nftTokenIdA).call()).to.be.equal(nftTokenAddressA1);
-  
+
       await contractB.methods.transfer(nftTokenAddressA1, nftTokenIdB).send({from: owner});
       expect(await contractB.methods.ownerOf(nftTokenIdB).call()).to.be.equal(nftTokenAddressA1);
     });
@@ -105,112 +84,88 @@
   describe('Negative Test: EVM Nesting', async() => {
     itEth('NFT: disallows to nest token if nesting is disabled', async ({helper}) => {
       const owner = await helper.eth.createAccountWithBalance(donor);
-  
+
       const {collectionId, contract} = await createNestingCollection(helper, owner);
       await contract.methods.setCollectionNesting(false).send({from: owner});
-  
+
       // Create a token to nest into
-      const targetNftTokenId = await contract.methods.nextTokenId().call();
-      await contract.methods.mint(
-        owner,
-        targetNftTokenId,
-      ).send({from: owner});
-  
-      const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetNftTokenId);
-  
+      const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});
+      const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;
+      const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);
+
       // Create a token to nest
-      const nftTokenId = await contract.methods.nextTokenId().call();
-      await contract.methods.mint(
-        owner,
-        nftTokenId,
-      ).send({from: owner});
-  
+      const mintingNftTokenIdResult = await contract.methods.mint(owner).send({from: owner});
+      const nftTokenId = mintingNftTokenIdResult.events.Transfer.returnValues.tokenId;
+
       // Try to nest
       await expect(contract.methods
         .transfer(targetNftTokenAddress, nftTokenId)
         .call({from: owner})).to.be.rejectedWith('UserIsNotAllowedToNest');
     });
-  
+
     itEth('NFT: disallows a non-Owner to nest someone else\'s token', async ({helper}) => {
       const owner = await helper.eth.createAccountWithBalance(donor);
       const malignant = await helper.eth.createAccountWithBalance(donor);
-  
+
       const {collectionId, contract} = await createNestingCollection(helper, owner);
-  
+
       // Mint a token
-      const targetTokenId = await contract.methods.nextTokenId().call();
-      await contract.methods.mint(
-        owner,
-        targetTokenId,
-      ).send({from: owner});
+      const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});
+      const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;
       const targetTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);
-  
+
       // Mint a token belonging to a different account
-      const tokenId = await contract.methods.nextTokenId().call();
-      await contract.methods.mint(
-        malignant,
-        tokenId,
-      ).send({from: owner});
-  
+      const mintingTokenIdResult = await contract.methods.mint(malignant).send({from: owner});
+      const tokenId = mintingTokenIdResult.events.Transfer.returnValues.tokenId;
+
       // Try to nest one token in another as a non-owner account
       await expect(contract.methods
         .transfer(targetTokenAddress, tokenId)
         .call({from: malignant})).to.be.rejectedWith('UserIsNotAllowedToNest');
     });
-  
+
     itEth('NFT: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async ({helper}) => {
       const owner = await helper.eth.createAccountWithBalance(donor);
       const malignant = await helper.eth.createAccountWithBalance(donor);
-  
+
       const {collectionId: collectionIdA, collectionAddress: collectionAddressA, contract: contractA} = await createNestingCollection(helper, owner);
       const {collectionAddress: collectionAddressB, contract: contractB} = await createNestingCollection(helper, owner);
-  
+
       await contractA.methods.setCollectionNesting(true, [collectionAddressA, collectionAddressB]).send({from: owner});
-  
+
       // Create a token in one collection
-      const nftTokenIdA = await contractA.methods.nextTokenId().call();
-      await contractA.methods.mint(
-        owner,
-        nftTokenIdA,
-      ).send({from: owner});
+      const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});
+      const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;
       const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);
-  
-      // Create a token in another collection belonging to someone else
-      const nftTokenIdB = await contractB.methods.nextTokenId().call();
-      await contractB.methods.mint(
-        malignant,
-        nftTokenIdB,
-      ).send({from: owner});
-  
+
+      // Create a token in another collection
+      const mintingTokenIdBResult = await contractB.methods.mint(malignant).send({from: owner});
+      const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;
+
       // Try to drag someone else's token into the other collection and nest
       await expect(contractB.methods
         .transfer(nftTokenAddressA, nftTokenIdB)
         .call({from: malignant})).to.be.rejectedWith('UserIsNotAllowedToNest');
     });
-  
+
     itEth('NFT: disallows to nest token in an unlisted collection', async ({helper}) => {
       const owner = await helper.eth.createAccountWithBalance(donor);
-  
+
       const {collectionId: collectionIdA, collectionAddress: collectionAddressA, contract: contractA} = await createNestingCollection(helper, owner);
       const {contract: contractB} = await createNestingCollection(helper, owner);
-  
+
       await contractA.methods.setCollectionNesting(true, [collectionAddressA]).send({from: owner});
-  
+
       // Create a token in one collection
-      const nftTokenIdA = await contractA.methods.nextTokenId().call();
-      await contractA.methods.mint(
-        owner,
-        nftTokenIdA,
-      ).send({from: owner});
+      const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});
+      const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;
       const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);
-  
+
       // Create a token in another collection
-      const nftTokenIdB = await contractB.methods.nextTokenId().call();
-      await contractB.methods.mint(
-        owner,
-        nftTokenIdB,
-      ).send({from: owner});
-  
+      const mintingTokenIdBResult = await contractB.methods.mint(owner).send({from: owner});
+      const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;
+
+
       // Try to nest into a token in the other collection, disallowed in the first
       await expect(contractB.methods
         .transfer(nftTokenAddressA, nftTokenIdB)
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nonFungible.test.ts
+++ b/tests/src/eth/nonFungible.test.ts
@@ -29,7 +29,7 @@
       [alice] = await helper.arrange.createAccounts([10n], donor);
     });
   });
-  
+
   itEth('totalSupply', async ({helper}) => {
     const collection = await helper.nft.mintCollection(alice, {});
     await collection.mintToken(alice);
@@ -95,26 +95,23 @@
 
     const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', 'a', 'b', baseUri);
     const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
-    
-    const nextTokenId = await contract.methods.nextTokenId().call();
-    expect(nextTokenId).to.be.equal('1');
-    const result = await contract.methods.mint(
-      receiver,
-      nextTokenId,
-    ).send();
 
+    const result = await contract.methods.mint(receiver).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
+    expect(tokenId).to.be.equal('1');
+
     if (propertyKey && propertyValue) {
       // Set URL or suffix
-      await contract.methods.setProperty(nextTokenId, propertyKey, Buffer.from(propertyValue)).send();
+      await contract.methods.setProperty(tokenId, propertyKey, Buffer.from(propertyValue)).send();
     }
 
     const event = result.events.Transfer;
     expect(event.address).to.be.equal(collectionAddress);
     expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');
     expect(event.returnValues.to).to.be.equal(receiver);
-    expect(event.returnValues.tokenId).to.be.equal(nextTokenId);
+    expect(event.returnValues.tokenId).to.be.equal(tokenId);
 
-    return {contract, nextTokenId};
+    return {contract, nextTokenId: tokenId};
   }
 
   itEth('Empty tokenURI', async ({helper}) => {
@@ -156,22 +153,17 @@
 
     const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', '6', '6', '');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
-    const nextTokenId = await contract.methods.nextTokenId().call();
 
-    expect(nextTokenId).to.be.equal('1');
-    const result = await contract.methods.mintWithTokenURI(
-      receiver,
-      nextTokenId,
-      'Test URI',
-    ).send();
+    const result = await contract.methods.mintWithTokenURI(receiver, 'Test URI').send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
+    expect(tokenId).to.be.equal('1');
 
     const event = result.events.Transfer;
     expect(event.address).to.be.equal(collectionAddress);
     expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');
     expect(event.returnValues.to).to.be.equal(receiver);
-    expect(event.returnValues.tokenId).to.be.equal(nextTokenId);
 
-    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
+    expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
 
     // TODO: this wont work right now, need release 919000 first
     // await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send();
@@ -224,7 +216,7 @@
 
     {
       const result = await contract.methods.burn(tokenId).send({from: caller});
-      
+
       const event = result.events.Transfer;
       expect(event.address).to.be.equal(collectionAddress);
       expect(event.returnValues.from).to.be.equal(caller);
@@ -330,7 +322,7 @@
       [alice] = await helper.arrange.createAccounts([10n], donor);
     });
   });
-  
+
   itEth('approve() call fee is less than 0.2UNQ', async ({helper}) => {
     const owner = await helper.eth.createAccountWithBalance(donor);
     const spender = helper.eth.createAccount();
@@ -409,7 +401,7 @@
 
     const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
     const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');
-    
+
     const events: any = [];
     contract.events.allEvents((_: any, event: any) => {
       events.push(event);
@@ -433,7 +425,7 @@
 
     const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
     const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');
-    
+
     const events: any = [];
     contract.events.allEvents((_: any, event: any) => {
       events.push(event);
@@ -459,14 +451,14 @@
 
     const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
     const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');
-    
+
     const events: any = [];
     contract.events.allEvents((_: any, event: any) => {
       events.push(event);
     });
 
     await token.transferFrom(bob, {Substrate: alice.address}, {Ethereum: receiver});
-    
+
     const event = events[0];
     expect(event.address).to.be.equal(collectionAddress);
     expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));
@@ -482,14 +474,14 @@
 
     const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);
     const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');
-    
+
     const events: any = [];
     contract.events.allEvents((_: any, event: any) => {
       events.push(event);
     });
 
     await token.transfer(alice, {Ethereum: receiver});
-    
+
     const event = events[0];
     expect(event.address).to.be.equal(collectionAddress);
     expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));
@@ -558,4 +550,4 @@
     const symbol = await contract.methods.symbol().call();
     expect(symbol).to.equal('CHANGE');
   });
-});
\ No newline at end of file
+});
modifiedtests/src/eth/payable.test.tsdiffbeforeafterboth
--- a/tests/src/eth/payable.test.ts
+++ b/tests/src/eth/payable.test.ts
@@ -118,7 +118,7 @@
     const deployer = await helper.eth.createAccountWithBalance(donor);
     const caller = await helper.eth.createAccountWithBalance(donor);
     const contract = await helper.eth.deployFlipper(deployer);
-    
+
     const initialCallerBalance = await helper.balance.getEthereum(caller);
     await contract.methods.flip().send({from: caller});
     const finalCallerBalance = await helper.balance.getEthereum(caller);
@@ -129,7 +129,7 @@
     const deployer = await helper.eth.createAccountWithBalance(donor);
     const caller = await helper.eth.createAccountWithBalance(donor);
     const contract = await deployProxyContract(helper, deployer);
-    
+
     const initialCallerBalance = await helper.balance.getEthereum(caller);
     const initialContractBalance = await helper.balance.getEthereum(contract.options.address);
     await contract.methods.flip().send({from: caller});
@@ -138,7 +138,7 @@
     expect(finalCallerBalance < initialCallerBalance).to.be.true;
     expect(finalContractBalance == initialContractBalance).to.be.true;
   });
-  
+
   itEth('Fee for nested calls to native methods is withdrawn from the user', async({helper}) => {
     const CONTRACT_BALANCE = 2n * helper.balance.getOneTokenNominal();
 
@@ -155,7 +155,7 @@
     expect(finalCallerBalance < initialCallerBalance).to.be.true;
     expect(finalContractBalance == initialContractBalance).to.be.true;
   });
-  
+
   itEth('Fee for nested calls to create*Collection methods is withdrawn from the user and from the contract', async({helper}) => {
     const CONTRACT_BALANCE = 2n * helper.balance.getOneTokenNominal();
     const deployer = await helper.eth.createAccountWithBalance(donor);
@@ -176,7 +176,7 @@
     const BIG_FEE = 3n * helper.balance.getOneTokenNominal();
     const caller = await helper.eth.createAccountWithBalance(donor);
     const collectionHelper = helper.ethNativeContract.collectionHelpers(caller);
-        
+
     await expect(collectionHelper.methods.createNFTCollection('A', 'B', 'C').call({value: Number(SMALL_FEE)})).to.be.rejectedWith('Sent amount not equals to collection creation price (2000000000000000000)');
     await expect(collectionHelper.methods.createNFTCollection('A', 'B', 'C').call({value: Number(BIG_FEE)})).to.be.rejectedWith('Sent amount not equals to collection creation price (2000000000000000000)');
   });
@@ -186,7 +186,7 @@
     const BIG_FEE = 3n * helper.balance.getOneTokenNominal();
     const caller = await helper.eth.createAccountWithBalance(donor);
     const collectionHelper = helper.ethNativeContract.collectionHelpers(caller);
-        
+
     await expect(collectionHelper.methods.createRFTCollection('A', 'B', 'C').call({value: Number(SMALL_FEE)})).to.be.rejectedWith('Sent amount not equals to collection creation price (2000000000000000000)');
     await expect(collectionHelper.methods.createRFTCollection('A', 'B', 'C').call({value: Number(BIG_FEE)})).to.be.rejectedWith('Sent amount not equals to collection creation price (2000000000000000000)');
   });
@@ -235,8 +235,7 @@
 
         function mintNftToken(address collectionAddress) external  {
           UniqueNFT collection = UniqueNFT(collectionAddress);
-          uint256 tokenId = collection.nextTokenId();
-          collection.mint(msg.sender, tokenId);
+          uint256 tokenId = collection.mint(msg.sender);
           emit TokenMinted(tokenId);
         }
 
modifiedtests/src/eth/proxy/UniqueNFTProxy.soldiffbeforeafterboth
--- a/tests/src/eth/proxy/UniqueNFTProxy.sol
+++ b/tests/src/eth/proxy/UniqueNFTProxy.sol
@@ -120,20 +120,19 @@
         return proxied.mintingFinished();
     }
 
-    function mint(address to, uint256 tokenId)
+    function mint(address to)
         external
         override
-        returns (bool)
+        returns (uint256)
     {
-        return proxied.mint(to, tokenId);
+        return proxied.mint(to);
     }
 
     function mintWithTokenURI(
         address to,
-        uint256 tokenId,
         string memory tokenUri
-    ) external override returns (bool) {
-        return proxied.mintWithTokenURI(to, tokenId, tokenUri);
+    ) external override returns (uint256) {
+        return proxied.mintWithTokenURI(to, tokenUri);
     }
 
     function finishMinting() external override returns (bool) {
@@ -169,7 +168,7 @@
         return proxied.mintBulk(to, tokenIds);
     }
 
-    function mintBulkWithTokenURI(address to, Tuple0[] memory tokens)
+    function mintBulkWithTokenURI(address to, Tuple6[] memory tokens)
         external
         override
         returns (bool)
modifiedtests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterboth
--- a/tests/src/eth/proxy/nonFungibleProxy.test.ts
+++ b/tests/src/eth/proxy/nonFungibleProxy.test.ts
@@ -111,13 +111,10 @@
     await collectionEvmOwned.methods.addCollectionAdmin(contract.options.address).send();
 
     {
-      const nextTokenId = await contract.methods.nextTokenId().call();
-      expect(nextTokenId).to.be.equal('1');
-      const result = await contract.methods.mintWithTokenURI(
-        receiver,
-        nextTokenId,
-        'Test URI',
-      ).send({from: caller});
+      const result = await contract.methods.mintWithTokenURI(receiver, 'Test URI').send({from: caller});
+      const tokenId = result.events.Transfer.returnValues.tokenId;
+      expect(tokenId).to.be.equal('1');
+
       const events = helper.eth.normalizeEvents(result.events);
       events[0].address = events[0].address.toLocaleLowerCase();
 
@@ -128,12 +125,12 @@
           args: {
             from: '0x0000000000000000000000000000000000000000',
             to: receiver,
-            tokenId: nextTokenId,
+            tokenId,
           },
         },
       ]);
 
-      expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
+      expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
     }
   });
 
modifiedtests/src/eth/reFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/reFungible.test.ts
+++ b/tests/src/eth/reFungible.test.ts
@@ -33,8 +33,9 @@
     const caller = await helper.eth.createAccountWithBalance(donor);
     const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'TotalSupply', '6', '6');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
-    const nextTokenId = await contract.methods.nextTokenId().call();
-    await contract.methods.mint(caller, nextTokenId).send();
+
+    await contract.methods.mint(caller).send();
+
     const totalSupply = await contract.methods.totalSupply().call();
     expect(totalSupply).to.equal('1');
   });
@@ -44,18 +45,9 @@
     const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'BalanceOf', '6', '6');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
 
-    {
-      const nextTokenId = await contract.methods.nextTokenId().call();
-      await contract.methods.mint(caller, nextTokenId).send();
-    }
-    {
-      const nextTokenId = await contract.methods.nextTokenId().call();
-      await contract.methods.mint(caller, nextTokenId).send();
-    }
-    {
-      const nextTokenId = await contract.methods.nextTokenId().call();
-      await contract.methods.mint(caller, nextTokenId).send();
-    }
+    await contract.methods.mint(caller).send();
+    await contract.methods.mint(caller).send();
+    await contract.methods.mint(caller).send();
 
     const balance = await contract.methods.balanceOf(caller).call();
     expect(balance).to.equal('3');
@@ -66,8 +58,8 @@
     const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'OwnerOf', '6', '6');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
 
-    const tokenId = await contract.methods.nextTokenId().call();
-    await contract.methods.mint(caller, tokenId).send();
+    const result = await contract.methods.mint(caller).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
 
     const owner = await contract.methods.ownerOf(tokenId).call();
     expect(owner).to.equal(caller);
@@ -79,8 +71,8 @@
     const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'OwnerOf-AfterBurn', '6', '6');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
 
-    const tokenId = await contract.methods.nextTokenId().call();
-    await contract.methods.mint(caller, tokenId).send();
+    const result = await contract.methods.mint(caller).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
     const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
 
     await tokenContract.methods.repartition(2).send();
@@ -98,8 +90,8 @@
     const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Partial-OwnerOf', '6', '6');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
 
-    const tokenId = await contract.methods.nextTokenId().call();
-    await contract.methods.mint(caller, tokenId).send();
+    const result = await contract.methods.mint(caller).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
     const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
 
     await tokenContract.methods.repartition(2).send();
@@ -126,22 +118,17 @@
     const receiver = helper.eth.createAccount();
     const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Minty', '6', '6', '');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
-    
-    const nextTokenId = await contract.methods.nextTokenId().call();
-    expect(nextTokenId).to.be.equal('1');
-    const result = await contract.methods.mintWithTokenURI(
-      receiver,
-      nextTokenId,
-      'Test URI',
-    ).send();
 
+    const result = await contract.methods.mintWithTokenURI(receiver, 'Test URI').send();
+
     const event = result.events.Transfer;
     expect(event.address).to.equal(collectionAddress);
     expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');
     expect(event.returnValues.to).to.equal(receiver);
-    expect(event.returnValues.tokenId).to.equal(nextTokenId);
+    const tokenId = event.returnValues.tokenId;
+    expect(tokenId).to.be.equal('1');
 
-    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');
+    expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');
   });
 
   itEth('Can perform mintBulk()', async ({helper}) => {
@@ -182,8 +169,8 @@
     const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Burny', '6', '6');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
 
-    const tokenId = await contract.methods.nextTokenId().call();
-    await contract.methods.mint(caller, tokenId).send();
+    const result = await contract.methods.mint(caller).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
     {
       const result = await contract.methods.burn(tokenId).send();
       const event = result.events.Transfer;
@@ -200,9 +187,10 @@
     const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'TransferFromy', '6', '6');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
 
-    const tokenId = await contract.methods.nextTokenId().call();
+    const result = await contract.methods.mint(caller).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
+
     const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);
-    await contract.methods.mint(caller, tokenId).send();
 
     const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, caller);
     await tokenContract.methods.repartition(15).send();
@@ -244,12 +232,12 @@
     const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Transferry', '6', '6');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
 
-    const tokenId = await contract.methods.nextTokenId().call();
-    await contract.methods.mint(caller, tokenId).send();
+    const result = await contract.methods.mint(caller).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
 
     {
       const result = await contract.methods.transfer(receiver, tokenId).send();
-      
+
       const event = result.events.Transfer;
       expect(event.address).to.equal(collectionAddress);
       expect(event.returnValues.from).to.equal(caller);
@@ -274,8 +262,8 @@
     const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Transferry-Partial-to-Full', '6', '6');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
 
-    const tokenId = await contract.methods.nextTokenId().call();
-    await contract.methods.mint(caller, tokenId).send();
+    const result = await contract.methods.mint(caller).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
 
     const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
 
@@ -301,8 +289,8 @@
     const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Transferry-Full-to-Partial', '6', '6');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
 
-    const tokenId = await contract.methods.nextTokenId().call();
-    await contract.methods.mint(caller, tokenId).send();
+    const result = await contract.methods.mint(caller).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
 
     const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, caller);
 
@@ -339,8 +327,8 @@
     const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Feeful-Transfer-From', '6', '6');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
 
-    const tokenId = await contract.methods.nextTokenId().call();
-    await contract.methods.mint(caller, tokenId).send();
+    const result = await contract.methods.mint(caller).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
 
     const cost = await helper.eth.recordCallFee(caller, () => contract.methods.transferFrom(caller, receiver, tokenId).send());
     expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
@@ -353,8 +341,8 @@
     const {collectionAddress} = await helper.eth.createRFTCollection(caller, 'Feeful-Transfer', '6', '6');
     const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);
 
-    const tokenId = await contract.methods.nextTokenId().call();
-    await contract.methods.mint(caller, tokenId).send();
+    const result = await contract.methods.mint(caller).send();
+    const tokenId = result.events.Transfer.returnValues.tokenId;
 
     const cost = await helper.eth.recordCallFee(caller, () => contract.methods.transfer(receiver, tokenId).send());
     expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
@@ -394,7 +382,7 @@
         tokenPropertyPermissions,
       },
     );
-    
+
     const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'rft', caller);
     const name = await contract.methods.name().call();
     expect(name).to.equal('Leviathan');
modifiedtests/src/eth/reFungibleToken.test.tsdiffbeforeafterboth
before · tests/src/eth/reFungibleToken.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {Pallets, requirePalletsOrSkip} from '../util/playgrounds';18import {EthUniqueHelper, expect, itEth, usingEthPlaygrounds} from './util/playgrounds';19import {IKeyringPair} from '@polkadot/types/types';20import {Contract} from 'web3-eth-contract';212223describe('Refungible token: Information getting', () => {24  let donor: IKeyringPair;25  let alice: IKeyringPair;2627  before(async function() {28    await usingEthPlaygrounds(async (helper, privateKey) => {29      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);3031      donor = privateKey('//Alice');32      [alice] = await helper.arrange.createAccounts([20n], donor);33    });34  });3536  itEth('totalSupply', async ({helper}) => {37    const caller = await helper.eth.createAccountWithBalance(donor);38    const collection = await helper.rft.mintCollection(alice, {tokenPrefix: 'MUON'});39    const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: caller});4041    const contract = helper.ethNativeContract.rftTokenById(collection.collectionId, tokenId, caller);42    const totalSupply = await contract.methods.totalSupply().call();43    expect(totalSupply).to.equal('200');44  });4546  itEth('balanceOf', async ({helper}) => {47    const caller = await helper.eth.createAccountWithBalance(donor);48    const collection = await helper.rft.mintCollection(alice, {tokenPrefix: 'MUON'});49    const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: caller});5051    const contract = helper.ethNativeContract.rftTokenById(collection.collectionId, tokenId, caller);52    const balance = await contract.methods.balanceOf(caller).call();53    expect(balance).to.equal('200');54  });5556  itEth('decimals', async ({helper}) => {57    const caller = await helper.eth.createAccountWithBalance(donor);58    const collection = await helper.rft.mintCollection(alice, {tokenPrefix: 'MUON'});59    const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: caller});6061    const contract = helper.ethNativeContract.rftTokenById(collection.collectionId, tokenId, caller);62    const decimals = await contract.methods.decimals().call();63    expect(decimals).to.equal('0');64  });65});6667// FIXME: Need erc721 for ReFubgible.68describe('Check ERC721 token URI for ReFungible', () => {69  let donor: IKeyringPair;7071  before(async function() {72    await usingEthPlaygrounds(async (helper, privateKey) => {73      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);7475      donor = privateKey('//Alice');76    });77  });7879  async function setup(helper: EthUniqueHelper, baseUri: string, propertyKey?: string, propertyValue?: string): Promise<{contract: Contract, nextTokenId: string}> {80    const owner = await helper.eth.createAccountWithBalance(donor);81    const receiver = helper.eth.createAccount();8283    const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Mint collection', 'a', 'b', baseUri);84    const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);85    86    const nextTokenId = await contract.methods.nextTokenId().call();87    expect(nextTokenId).to.be.equal('1');88    const result = await contract.methods.mint(89      receiver,90      nextTokenId,91    ).send();9293    if (propertyKey && propertyValue) {94      // Set URL or suffix95      await contract.methods.setProperty(nextTokenId, propertyKey, Buffer.from(propertyValue)).send();96    }9798    const event = result.events.Transfer;99    expect(event.address).to.be.equal(collectionAddress);100    expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');101    expect(event.returnValues.to).to.be.equal(receiver);102    expect(event.returnValues.tokenId).to.be.equal(nextTokenId);103104    return {contract, nextTokenId};105  }106107  itEth('Empty tokenURI', async ({helper}) => {108    const {contract, nextTokenId} = await setup(helper, '');109    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('');110  });111112  itEth('TokenURI from url', async ({helper}) => {113    const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'URI', 'Token URI');114    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Token URI');115  });116117  itEth('TokenURI from baseURI', async ({helper}) => {118    const {contract, nextTokenId} = await setup(helper, 'BaseURI_');119    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_');120  });121122  itEth('TokenURI from baseURI + suffix', async ({helper}) => {123    const suffix = '/some/suffix';124    const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'URISuffix', suffix);125    expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + suffix);126  });127});128129describe('Refungible: Plain calls', () => {130  let donor: IKeyringPair;131  let alice: IKeyringPair;132133  before(async function() {134    await usingEthPlaygrounds(async (helper, privateKey) => {135      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);136137      donor = privateKey('//Alice');138      [alice] = await helper.arrange.createAccounts([50n], donor);139    });140  });141142  itEth('Can perform approve()', async ({helper}) => {143    const owner = await helper.eth.createAccountWithBalance(donor);144    const spender = helper.eth.createAccount();145    const collection = await helper.rft.mintCollection(alice);146    const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});147148    const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);149    const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);150151    {152      const result = await contract.methods.approve(spender, 100).send({from: owner});153      const event = result.events.Approval;154      expect(event.address).to.be.equal(tokenAddress);155      expect(event.returnValues.owner).to.be.equal(owner);156      expect(event.returnValues.spender).to.be.equal(spender);157      expect(event.returnValues.value).to.be.equal('100');158    }159160    {161      const allowance = await contract.methods.allowance(owner, spender).call();162      expect(+allowance).to.equal(100);163    }164  });165166  itEth('Can perform transferFrom()', async ({helper}) => {167    const owner = await helper.eth.createAccountWithBalance(donor);168    const spender = await helper.eth.createAccountWithBalance(donor);169    const receiver = helper.eth.createAccount();170    const collection = await helper.rft.mintCollection(alice);171    const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});172173    const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);174    const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);175176    await contract.methods.approve(spender, 100).send();177178    {179      const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});180      let event = result.events.Transfer;181      expect(event.address).to.be.equal(tokenAddress);182      expect(event.returnValues.from).to.be.equal(owner);183      expect(event.returnValues.to).to.be.equal(receiver);184      expect(event.returnValues.value).to.be.equal('49');185186      event = result.events.Approval;187      expect(event.address).to.be.equal(tokenAddress);188      expect(event.returnValues.owner).to.be.equal(owner);189      expect(event.returnValues.spender).to.be.equal(spender);190      expect(event.returnValues.value).to.be.equal('51');191    }192193    {194      const balance = await contract.methods.balanceOf(receiver).call();195      expect(+balance).to.equal(49);196    }197198    {199      const balance = await contract.methods.balanceOf(owner).call();200      expect(+balance).to.equal(151);201    }202  });203204  itEth('Can perform transfer()', async ({helper}) => {205    const owner = await helper.eth.createAccountWithBalance(donor);206    const receiver = helper.eth.createAccount();207    const collection = await helper.rft.mintCollection(alice);208    const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});209210    const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);211    const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);212213    {214      const result = await contract.methods.transfer(receiver, 50).send({from: owner});215      const event = result.events.Transfer;216      expect(event.address).to.be.equal(tokenAddress);217      expect(event.returnValues.from).to.be.equal(owner);218      expect(event.returnValues.to).to.be.equal(receiver);219      expect(event.returnValues.value).to.be.equal('50');220    }221222    {223      const balance = await contract.methods.balanceOf(owner).call();224      expect(+balance).to.equal(150);225    }226227    {228      const balance = await contract.methods.balanceOf(receiver).call();229      expect(+balance).to.equal(50);230    }231  });232233  itEth('Can perform repartition()', async ({helper}) => {234    const owner = await helper.eth.createAccountWithBalance(donor);235    const receiver = await helper.eth.createAccountWithBalance(donor);236    const collection = await helper.rft.mintCollection(alice);237    const {tokenId} = await collection.mintToken(alice, 100n, {Ethereum: owner});238239    const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);240    const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);241242    await contract.methods.repartition(200).send({from: owner});243    expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(200);244    await contract.methods.transfer(receiver, 110).send({from: owner});245    expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(90);246    expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(110);247248    await expect(contract.methods.repartition(80).send({from: owner})).to.eventually.be.rejected; // Transaction is reverted249250    await contract.methods.transfer(receiver, 90).send({from: owner});251    expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(0);252    expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(200);253254    await contract.methods.repartition(150).send({from: receiver});255    await expect(contract.methods.transfer(owner, 160).send({from: receiver})).to.eventually.be.rejected; // Transaction is reverted256    expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(150);257  });258259  itEth('Can repartition with increased amount', async ({helper}) => {260    const owner = await helper.eth.createAccountWithBalance(donor);261    const collection = await helper.rft.mintCollection(alice);262    const {tokenId} = await collection.mintToken(alice, 100n, {Ethereum: owner});263264    const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);265    const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);266267    const result = await contract.methods.repartition(200).send();268269    const event = result.events.Transfer;270    expect(event.address).to.be.equal(tokenAddress);271    expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');272    expect(event.returnValues.to).to.be.equal(owner);273    expect(event.returnValues.value).to.be.equal('100');274  });275276  itEth('Can repartition with decreased amount', async ({helper}) => {277    const owner = await helper.eth.createAccountWithBalance(donor);278    const collection = await helper.rft.mintCollection(alice);279    const {tokenId} = await collection.mintToken(alice, 100n, {Ethereum: owner});280281    const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);282    const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);283284    const result = await contract.methods.repartition(50).send();285    const event = result.events.Transfer;286    expect(event.address).to.be.equal(tokenAddress);287    expect(event.returnValues.from).to.be.equal(owner);288    expect(event.returnValues.to).to.be.equal('0x0000000000000000000000000000000000000000');289    expect(event.returnValues.value).to.be.equal('50');290  });291292  itEth('Receiving Transfer event on burning into full ownership', async ({helper}) => {293    const caller = await helper.eth.createAccountWithBalance(donor);294    const receiver = await helper.eth.createAccountWithBalance(donor);295    const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(caller, 'Devastation', '6', '6');296    const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', caller);297298    const tokenId = await contract.methods.nextTokenId().call();299    await contract.methods.mint(caller, tokenId).send();300    const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);301    const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, caller);302303    await tokenContract.methods.repartition(2).send();304    await tokenContract.methods.transfer(receiver, 1).send();305306    const events: any = [];307    contract.events.allEvents((_: any, event: any) => {308      events.push(event);309    });310    await tokenContract.methods.burnFrom(caller, 1).send();311312    const event = events[0];313    expect(event.address).to.be.equal(collectionAddress);314    expect(event.returnValues.from).to.be.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');315    expect(event.returnValues.to).to.be.equal(receiver);316    expect(event.returnValues.tokenId).to.be.equal(tokenId);317  });318});319320describe('Refungible: Fees', () => {321  let donor: IKeyringPair;322  let alice: IKeyringPair;323324  before(async function() {325    await usingEthPlaygrounds(async (helper, privateKey) => {326      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);327328      donor = privateKey('//Alice');329      [alice] = await helper.arrange.createAccounts([50n], donor);330    });331  });332333  itEth('approve() call fee is less than 0.2UNQ', async ({helper}) => {334    const owner = await helper.eth.createAccountWithBalance(donor);335    const spender = helper.eth.createAccount();336    const collection = await helper.rft.mintCollection(alice);337    const {tokenId} = await collection.mintToken(alice, 100n, {Ethereum: owner});338339    const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);340    const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);341342    const cost = await helper.eth.recordCallFee(owner, () => contract.methods.approve(spender, 100).send({from: owner}));343    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));344  });345346  itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {347    const owner = await helper.eth.createAccountWithBalance(donor);348    const spender = await helper.eth.createAccountWithBalance(donor);349    const collection = await helper.rft.mintCollection(alice);350    const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});351352    const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);353    const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);354355    await contract.methods.approve(spender, 100).send({from: owner});356357    const cost = await helper.eth.recordCallFee(spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));358    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));359  });360361  itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {362    const owner = await helper.eth.createAccountWithBalance(donor);363    const receiver = helper.eth.createAccount();364    const collection = await helper.rft.mintCollection(alice);365    const {tokenId} = await collection.mintToken(alice, 200n, {Ethereum: owner});366367    const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, tokenId);368    const contract = helper.ethNativeContract.rftToken(tokenAddress, owner);369370    const cost = await helper.eth.recordCallFee(owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));371    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));372  });373});374375describe('Refungible: Substrate calls', () => {376  let donor: IKeyringPair;377  let alice: IKeyringPair;378379  before(async function() {380    await usingEthPlaygrounds(async (helper, privateKey) => {381      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);382383      donor = privateKey('//Alice');384      [alice] = await helper.arrange.createAccounts([50n], donor);385    });386  });387388  itEth('Events emitted for approve()', async ({helper}) => {389    const receiver = helper.eth.createAccount();390    const collection = await helper.rft.mintCollection(alice);391    const token = await collection.mintToken(alice, 200n);392393    const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, token.tokenId);394    const contract = helper.ethNativeContract.rftToken(tokenAddress);395396    const events: any = [];397    contract.events.allEvents((_: any, event: any) => {398      events.push(event);399    });400    expect(await token.approve(alice, {Ethereum: receiver}, 100n)).to.be.true;401402    const event = events[0];403    expect(event.event).to.be.equal('Approval');404    expect(event.address).to.be.equal(tokenAddress);405    expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));406    expect(event.returnValues.spender).to.be.equal(receiver);407    expect(event.returnValues.value).to.be.equal('100');408  });409410  itEth('Events emitted for transferFrom()', async ({helper}) => {411    const [bob] = await helper.arrange.createAccounts([10n], donor);412    const receiver = helper.eth.createAccount();413    const collection = await helper.rft.mintCollection(alice);414    const token = await collection.mintToken(alice, 200n);415    await token.approve(alice, {Substrate: bob.address}, 100n);416417    const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, token.tokenId);418    const contract = helper.ethNativeContract.rftToken(tokenAddress);419420    const events: any = [];421    contract.events.allEvents((_: any, event: any) => {422      events.push(event);423    });424425    expect(await token.transferFrom(bob, {Substrate: alice.address}, {Ethereum: receiver},  51n)).to.be.true;426427    let event = events[0];428    expect(event.event).to.be.equal('Transfer');429    expect(event.address).to.be.equal(tokenAddress);430    expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));431    expect(event.returnValues.to).to.be.equal(receiver);432    expect(event.returnValues.value).to.be.equal('51');433434    event = events[1];435    expect(event.event).to.be.equal('Approval');436    expect(event.address).to.be.equal(tokenAddress);437    expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));438    expect(event.returnValues.spender).to.be.equal(helper.address.substrateToEth(bob.address));439    expect(event.returnValues.value).to.be.equal('49');440  });441442  itEth('Events emitted for transfer()', async ({helper}) => {443    const receiver = helper.eth.createAccount();444    const collection = await helper.rft.mintCollection(alice);445    const token = await collection.mintToken(alice, 200n);446447    const tokenAddress = helper.ethAddress.fromTokenId(collection.collectionId, token.tokenId);448    const contract = helper.ethNativeContract.rftToken(tokenAddress);449450    const events: any = [];451    contract.events.allEvents((_: any, event: any) => {452      events.push(event);453    });454455    expect(await token.transfer(alice, {Ethereum: receiver},  51n)).to.be.true;456457    const event = events[0];458    expect(event.event).to.be.equal('Transfer');459    expect(event.address).to.be.equal(tokenAddress);460    expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));461    expect(event.returnValues.to).to.be.equal(receiver);462    expect(event.returnValues.value).to.be.equal('51');463  });464});465466describe('ERC 1633 implementation', () => {467  let donor: IKeyringPair;468469  before(async function() {470    await usingEthPlaygrounds(async (helper, privateKey) => {471      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);472473      donor = privateKey('//Alice');474    });475  });476477  itEth('Default parent token address and id', async ({helper}) => {478    const owner = await helper.eth.createAccountWithBalance(donor);479480    const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(owner, 'Sands', '', 'GRAIN');481    const collectionContract = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);482    483    const tokenId = await collectionContract.methods.nextTokenId().call();484    await collectionContract.methods.mint(owner, tokenId).send();485    const tokenAddress = helper.ethAddress.fromTokenId(collectionId, tokenId);486    const tokenContract = helper.ethNativeContract.rftToken(tokenAddress, owner);487488    expect(await tokenContract.methods.parentToken().call()).to.be.equal(collectionAddress);489    expect(await tokenContract.methods.parentTokenId().call()).to.be.equal(tokenId);490  });491});
modifiedtests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -43,12 +43,12 @@
     if(!imports) return function(path: string) {
       return {error: `File not found: ${path}`};
     };
-  
+
     const knownImports = {} as {[key: string]: string};
     for(const imp of imports) {
       knownImports[imp.solPath] = (await readFile(imp.fsPath)).toString();
     }
-  
+
     return function(path: string) {
       if(path in knownImports) return {contents: knownImports[path]};
       return {error: `File not found: ${path}`};
@@ -71,7 +71,7 @@
         },
       },
     }), {import: await this.findImports(imports)})).contracts[`${name}.sol`][name];
-  
+
     return {
       abi: out.abi,
       object: '0x' + out.evm.bytecode.object,
@@ -94,7 +94,7 @@
   }
 
 }
-  
+
 class NativeContractGroup extends EthGroupBase {
 
   contractHelpers(caller: string): Contract {
@@ -145,14 +145,14 @@
   async createAccountWithBalance(donor: IKeyringPair, amount=1000n) {
     const account = this.createAccount();
     await this.transferBalanceFromSubstrate(donor, account, amount);
-  
+
     return account;
   }
 
   async transferBalanceFromSubstrate(donor: IKeyringPair, recepient: string, amount=1000n, inTokens=true) {
     return await this.helper.balance.transferToSubstrate(donor, evmToAddress(recepient), amount * (inTokens ? this.helper.balance.getOneTokenNominal() : 1n));
   }
-  
+
   async getCollectionCreationFee(signer: string) {
     const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
     return await collectionHelper.methods.collectionCreationFee().call();
@@ -177,7 +177,7 @@
   async createNFTCollection(signer: string, name: string, description: string, tokenPrefix: string): Promise<{collectionId: number, collectionAddress: string}> {
     const collectionCreationPrice = this.helper.balance.getCollectionCreationPrice();
     const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
-        
+
     const result = await collectionHelper.methods.createNFTCollection(name, description, tokenPrefix).send({value: Number(collectionCreationPrice)});
 
     const collectionAddress = this.helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
@@ -187,13 +187,11 @@
   }
 
   async createERC721MetadataCompatibleNFTCollection(signer: string, name: string, description: string, tokenPrefix: string, baseUri: string): Promise<{collectionId: number, collectionAddress: string}> {
-    const collectionCreationPrice = this.helper.balance.getCollectionCreationPrice();
     const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
-        
-    const result = await collectionHelper.methods.createERC721MetadataCompatibleNFTCollection(name, description, tokenPrefix, baseUri).send({value: Number(collectionCreationPrice)});
 
-    const collectionAddress = this.helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
-    const collectionId = this.helper.ethAddress.extractCollectionId(collectionAddress);
+    const {collectionId, collectionAddress} = await this.createNFTCollection(signer, name, description, tokenPrefix)
+
+    await collectionHelper.methods.makeCollectionERC721MetadataCompatible(collectionAddress, baseUri).send();
 
     return {collectionId, collectionAddress};
   }
@@ -201,7 +199,7 @@
   async createRFTCollection(signer: string, name: string, description: string, tokenPrefix: string): Promise<{collectionId: number, collectionAddress: string}> {
     const collectionCreationPrice = this.helper.balance.getCollectionCreationPrice();
     const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
-        
+
     const result = await collectionHelper.methods.createRFTCollection(name, description, tokenPrefix).send({value: Number(collectionCreationPrice)});
 
     const collectionAddress = this.helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
@@ -211,13 +209,11 @@
   }
 
   async createERC721MetadataCompatibleRFTCollection(signer: string, name: string, description: string, tokenPrefix: string, baseUri: string): Promise<{collectionId: number, collectionAddress: string}> {
-    const collectionCreationPrice = this.helper.balance.getCollectionCreationPrice();
     const collectionHelper = this.helper.ethNativeContract.collectionHelpers(signer);
-    
-    const result = await collectionHelper.methods.createERC721MetadataCompatibleRFTCollection(name, description, tokenPrefix, baseUri).send({value: Number(collectionCreationPrice)});
 
-    const collectionAddress = this.helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);
-    const collectionId = this.helper.ethAddress.extractCollectionId(collectionAddress);
+    const {collectionId, collectionAddress} = await this.createRFTCollection(signer, name, description, tokenPrefix)
+
+    await collectionHelper.methods.makeCollectionERC721MetadataCompatible(collectionAddress, baseUri).send();
 
     return {collectionId, collectionAddress};
   }
@@ -312,7 +308,7 @@
     };
     return await this.helper.arrange.calculcateFee(address, wrappedCode);
   }
-}  
+}
 
 class EthAddressGroup extends EthGroupBase {
   extractCollectionId(address: string): number {
@@ -343,8 +339,8 @@
   normalizeAddress(address: string): string {
     return '0x' + address.substring(address.length - 40);
   }
-}  
- 
+}
+
 export type EthUniqueHelperConstructor = new (...args: any[]) => EthUniqueHelper;
 
 export class EthUniqueHelper extends DevUniqueHelper {
@@ -396,4 +392,3 @@
     return newHelper;
   }
 }
-  
\ No newline at end of file