1234567891011121314151617import {IKeyringPair} from '@polkadot/types/types';18import {expect, itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds} from '../../util';1920describe('Refungible nesting', () => {21 let alice: IKeyringPair;22 let charlie: IKeyringPair;2324 before(async function() {25 await usingPlaygrounds(async (helper, privateKey) => {26 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);27 const donor = await privateKey({filename: __filename});28 [alice, charlie] = await helper.arrange.createAccounts([50n, 10n], donor);29 });30 });3132 [33 {restrictedMode: true},34 {restrictedMode: false},35 ].map(testCase => {36 itSub(`Owner can nest their token${testCase.restrictedMode ? ': Restricted mode' : ''}`, async ({helper}) => {37 const collectionNFT = await helper.nft.mintCollection(alice, {permissions: {access: 'AllowList', mintMode: true, nesting: {tokenOwner: true}}});38 const collectionRFT = await helper.rft.mintCollection(alice);39 const targetToken = await collectionNFT.mintToken(alice, {Substrate: charlie.address});4041 await collectionNFT.setPermissions(alice, {access: 'AllowList', mintMode: true, nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionRFT.collectionId] : null}});42 await collectionNFT.addToAllowList(alice, {Substrate: charlie.address});43 await collectionNFT.addToAllowList(alice, targetToken.nestingAccount());4445 await collectionRFT.setPermissions(alice, {access: 'AllowList', mintMode: true});46 await collectionRFT.addToAllowList(alice, {Substrate: charlie.address});47 await collectionRFT.addToAllowList(alice, targetToken.nestingAccount());4849 50 const nestedToken = await collectionRFT.mintToken(charlie, 5n, targetToken.nestingAccount());51 expect(await nestedToken.getBalance(targetToken.nestingAccount())).to.be.equal(5n);5253 54 const newToken = await collectionRFT.mintToken(charlie, 5n);55 await newToken.transfer(charlie, targetToken.nestingAccount(), 2n);56 expect(await newToken.getBalance(targetToken.nestingAccount())).to.be.equal(2n);57 expect(await newToken.getBalance({Substrate: charlie.address})).to.be.equal(3n);58 });59 });6061 itSub('owner can unnest nested token', async ({helper}) => {62 const collection = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});63 const targetToken = await collection.mintToken(alice);6465 66 const collectionRFT = await helper.rft.mintCollection(alice);67 const token = await collectionRFT.mintToken(alice, 10n, targetToken.nestingAccount());6869 70 await token.transferFrom(alice, targetToken.nestingAccount(), {Substrate: alice.address}, 9n);71 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(9n);72 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(1n);7374 75 await token.transferFrom(alice, targetToken.nestingAccount(), {Substrate: alice.address}, 1n);76 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(10n);77 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(0n);78 });7980 itSub('owner can burn nested token', async ({helper}) => {81 const collection = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});82 const targetToken = await collection.mintToken(alice);8384 85 const collectionRFT = await helper.rft.mintCollection(alice);86 const token = await collectionRFT.mintToken(alice, 10n, targetToken.nestingAccount());8788 89 await token.burnFrom(alice, targetToken.nestingAccount(), 6n);90 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);91 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(4n);92 expect(await targetToken.getChildren()).to.has.length(1);9394 95 await token.burnFrom(alice, targetToken.nestingAccount(), 4n);96 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(0n);97 expect(await targetToken.getChildren()).to.has.length(0);98 expect(await token.doesExist()).to.be.false;99 });100});101102describe('Refungible nesting negative tests', () => {103 let alice: IKeyringPair;104 let bob: IKeyringPair;105106 before(async function() {107 await usingPlaygrounds(async (helper, privateKey) => {108 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);109 const donor = await privateKey({filename: __filename});110 [alice, bob] = await helper.arrange.createAccounts([100n, 50n], donor);111 });112 });113114 itSub('cannot nest token if nesting is disabled', async ({helper}) => {115 const collectionNFT = await helper.nft.mintCollection(alice);116 const collectionRFT = await helper.rft.mintCollection(alice);117 const targetToken = await collectionNFT.mintToken(alice);118119 120 await expect(collectionRFT.mintToken(alice, 5n, targetToken.nestingAccount()))121 .to.be.rejectedWith(/common\.UserIsNotAllowedToNest/);122123 124 const token = await collectionRFT.mintToken(alice, 5n);125 await expect(token.transfer(alice, targetToken.nestingAccount(), 2n))126 .to.be.rejectedWith(/common\.UserIsNotAllowedToNest/);127 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(5n);128 });129130 [131 {restrictedMode: true},132 {restrictedMode: false},133 ].map(testCase => {134 itSub(`non-Owner cannot nest someone else's token${testCase.restrictedMode ? ': Restricted mode' : ''}`, async ({helper}) => {135 const collectionNFT = await helper.nft.mintCollection(alice);136 const collectionRFT = await helper.rft.mintCollection(alice);137 const targetToken = await collectionNFT.mintToken(alice);138139 await collectionNFT.setPermissions(alice, {access: 'AllowList', mintMode: true, nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionRFT.collectionId] : null}});140 await collectionNFT.addToAllowList(alice, {Substrate: bob.address});141 await collectionNFT.addToAllowList(alice, targetToken.nestingAccount());142143 144 const newToken = await collectionRFT.mintToken(alice);145 await expect(newToken.transfer(bob, targetToken.nestingAccount())).to.be.rejectedWith(/common\.TokenValueTooLow/);146147 expect(await targetToken.getChildren()).to.be.length(0);148 expect(await newToken.getBalance({Substrate: alice.address})).to.be.equal(1n);149150 151 await newToken.transfer(alice, targetToken.nestingAccount());152153 154 await expect(newToken.transferFrom(bob, targetToken.nestingAccount(), {Substrate: alice.address}, 1n))155 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);156 expect(await newToken.getBalance(targetToken.nestingAccount())).to.be.equal(1n);157 });158 });159160 itSub('ReFungible: disallows to nest token to an unlisted collection', async ({helper}) => {161 const collectionNFT = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true, restricted: []}}});162 const collectionRFT = await helper.rft.mintCollection(alice);163 const targetToken = await collectionNFT.mintToken(alice);164165 166 await expect(collectionRFT.mintToken(alice, 5n, targetToken.nestingAccount()))167 .to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);168169 170 const token = await collectionRFT.mintToken(alice, 5n);171 await expect(token.transfer(alice, targetToken.nestingAccount(), 2n))172 .to.be.rejectedWith(/common\.SourceCollectionIsNotAllowedToNest/);173 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(5n);174 });175});