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

difftreelog

source

tests/src/nesting/unnest.test.ts7.3 KiBsourcehistory
1import {expect} from 'chai';2import {tokenIdToAddress} from '../eth/util/helpers';3import privateKey from '../substrate/privateKey';4import usingApi, {executeTransaction} from '../substrate/substrate-api';5import {6  createCollectionExpectSuccess,7  createItemExpectFailure,8  createItemExpectSuccess,9  getBalance,10  getTokenOwner,11  getTopmostTokenOwner,12  normalizeAccountId,13  setCollectionLimitsExpectSuccess,14  transferExpectSuccess,15  transferFromExpectSuccess,16} from '../util/helpers';17import {IKeyringPair} from '@polkadot/types/types';1819let alice: IKeyringPair;20let bob: IKeyringPair;2122describe('Integration Test: Unnesting', () => {23  before(async () => {24    await usingApi(async api => {25      alice = privateKey('//Alice');26      bob = privateKey('//Bob');27    });28  });2930  it('NFT: allows the owner to successfully unnest a token', async () => {31    await usingApi(async api => {32      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});33      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});34      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');35      const targetAddress = {Ethereum: tokenIdToAddress(collection, targetToken)};3637      // Create a nested token38      const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', targetAddress);3940      // Unnest41      await expect(executeTransaction(42        api,43        alice,44        api.tx.unique.transferFrom(normalizeAccountId(targetAddress), normalizeAccountId(alice), collection, nestedToken, 1),45      ), 'while unnesting').to.not.be.rejected;46      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Substrate: alice.address});4748      // Nest and burn49      await transferExpectSuccess(collection, nestedToken, alice, targetAddress);50      await expect(executeTransaction(51        api,52        alice,53        api.tx.unique.burnFrom(collection, normalizeAccountId(targetAddress), nestedToken, 1),54      ), 'while burning').to.not.be.rejected;55      await expect(getTokenOwner(api, collection, nestedToken)).to.be.rejected;56    });57  });5859  it('Fungible: allows the owner to successfully unnest a token', async () => {60    await usingApi(async api => {61      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});62      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});63      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');64      const targetAddress = {Ethereum: tokenIdToAddress(collection, targetToken)};6566      const collectionFT = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});67      const nestedToken = await createItemExpectSuccess(alice, collectionFT, 'Fungible');6869      // Nest and unnest70      await transferExpectSuccess(collectionFT, nestedToken, alice, targetAddress, 1, 'Fungible');71      await transferFromExpectSuccess(collectionFT, nestedToken, alice, targetAddress, alice, 1, 'Fungible');7273      // Nest and burn74      await transferExpectSuccess(collectionFT, nestedToken, alice, targetAddress, 1, 'Fungible');75      const balanceBefore = await getBalance(api, collectionFT, normalizeAccountId(targetAddress), nestedToken);76      await expect(executeTransaction(77        api,78        alice,79        api.tx.unique.burnFrom(collectionFT, normalizeAccountId(targetAddress), nestedToken, 1),80      ), 'while burning').to.not.be.rejected;81      const balanceAfter = await getBalance(api, collectionFT, normalizeAccountId(targetAddress), nestedToken);82      expect(balanceAfter + BigInt(1)).to.be.equal(balanceBefore);83    });84  });8586  it('ReFungible: allows the owner to successfully unnest a token', async () => {87    await usingApi(async api => {88      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});89      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});90      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');91      const targetAddress = {Ethereum: tokenIdToAddress(collection, targetToken)};9293      const collectionRFT = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});94      const nestedToken = await createItemExpectSuccess(alice, collectionRFT, 'ReFungible');9596      // Nest and unnest97      await transferExpectSuccess(collectionRFT, nestedToken, alice, targetAddress, 1, 'ReFungible');98      await transferFromExpectSuccess(collectionRFT, nestedToken, alice, targetAddress, alice, 1, 'ReFungible');99100      // Nest and burn101      await transferExpectSuccess(collectionRFT, nestedToken, alice, targetAddress, 1, 'ReFungible');102      await expect(executeTransaction(103        api,104        alice,105        api.tx.unique.burnFrom(collectionRFT, normalizeAccountId(targetAddress), nestedToken, 1),106      ), 'while burning').to.not.be.rejected;107      const balance = await getBalance(api, collectionRFT, normalizeAccountId(targetAddress), nestedToken);108      expect(balance).to.be.equal(0n);109    });110  });111});112113describe('Negative Test: Unnesting', () => {114  before(async () => {115    await usingApi(async api => {116      alice = privateKey('//Alice');117      bob = privateKey('//Bob');118    });119  });120121  it('Disallows a non-owner to unnest/burn a token', async () => {122    await usingApi(async api => {123      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});124      await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});125      const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');126      const targetAddress = {Ethereum: tokenIdToAddress(collection, targetToken)};127128      // Create a nested token129      const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', targetAddress);130131      // Try to unnest132      await expect(executeTransaction(133        api,134        bob,135        api.tx.unique.transferFrom(normalizeAccountId(targetAddress), normalizeAccountId(bob), collection, nestedToken, 1),136      ), 'while unnesting').to.be.rejectedWith(/^structure\.DepthLimit$/); // todo ApprovedValueTooLow?137      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});138139      // Try to burn140      await expect(executeTransaction(141        api,142        bob,143        api.tx.unique.burnFrom(collection, normalizeAccountId(bob.address), nestedToken, 1),144      ), 'while burning').to.not.be.rejectedWith(/^common\.ApprovedValueTooLow$/);145      expect(await getTokenOwner(api, collection, nestedToken)).to.be.deep.equal({Ethereum: tokenIdToAddress(collection, targetToken).toLowerCase()});146    });147  });148149  // todo another test for creating excessive depth matryoshka with Ethereum?150151  // Recursive nesting152  it('Prevents Ouroboros creation', async () => {153    const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});154    await setCollectionLimitsExpectSuccess(alice, collection, {nestingRule: 'Owner'});155    const targetToken = await createItemExpectSuccess(alice, collection, 'NFT');156157    // Create a nested token ouroboros158    const nestedToken = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: tokenIdToAddress(collection, targetToken)});159    expect(transferExpectSuccess(collection, targetToken, alice, {Ethereum: tokenIdToAddress(collection, nestedToken)})).to.be.rejectedWith(/^structure\.OuroborosDetected$/);160  });161});