1234567891011121314151617import {createCollectionExpectSuccess, UNIQUE, requirePallets, Pallets} from '../util/helpers';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents, recordEthFee, recordEvents, tokenIdToAddress} from './util/helpers';19import reFungibleTokenAbi from './reFungibleTokenAbi.json';20import {expect} from 'chai';2122describe('Refungible: Information getting', () => {23 before(async function() {24 await requirePallets(this, [Pallets.ReFungible]);25 });2627 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {28 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);29 const helper = evmCollectionHelpers(web3, caller);30 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();31 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);32 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});33 const nextTokenId = await contract.methods.nextTokenId().call();34 await contract.methods.mint(caller, nextTokenId).send();35 const totalSupply = await contract.methods.totalSupply().call();36 expect(totalSupply).to.equal('1');37 });3839 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {40 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);41 const helper = evmCollectionHelpers(web3, caller);42 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();43 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);44 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});4546 {47 const nextTokenId = await contract.methods.nextTokenId().call();48 await contract.methods.mint(caller, nextTokenId).send();49 }50 {51 const nextTokenId = await contract.methods.nextTokenId().call();52 await contract.methods.mint(caller, nextTokenId).send();53 }54 {55 const nextTokenId = await contract.methods.nextTokenId().call();56 await contract.methods.mint(caller, nextTokenId).send();57 }5859 const balance = await contract.methods.balanceOf(caller).call();6061 expect(balance).to.equal('3');62 });6364 itWeb3('ownerOf', async ({api, web3, privateKeyWrapper}) => {65 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);66 const helper = evmCollectionHelpers(web3, caller);67 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();68 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);69 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});7071 const tokenId = await contract.methods.nextTokenId().call();72 await contract.methods.mint(caller, tokenId).send();7374 const owner = await contract.methods.ownerOf(tokenId).call();7576 expect(owner).to.equal(caller);77 });7879 itWeb3('ownerOf after burn', async ({api, web3, privateKeyWrapper}) => {80 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);81 const receiver = createEthAccount(web3);82 const helper = evmCollectionHelpers(web3, caller);83 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();84 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);85 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});8687 const tokenId = await contract.methods.nextTokenId().call();88 await contract.methods.mint(caller, tokenId).send();8990 const tokenAddress = tokenIdToAddress(collectionId, tokenId);91 const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, tokenAddress, {from: caller, ...GAS_ARGS});9293 await tokenContract.methods.repartition(2).send();94 await tokenContract.methods.transfer(receiver, 1).send();9596 await tokenContract.methods.burnFrom(caller, 1).send();9798 const owner = await contract.methods.ownerOf(tokenId).call();99100 expect(owner).to.equal(receiver);101 });102103 itWeb3('ownerOf for partial ownership', async ({api, web3, privateKeyWrapper}) => {104 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);105 const receiver = createEthAccount(web3);106 const helper = evmCollectionHelpers(web3, caller);107 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();108 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);109 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});110111 const tokenId = await contract.methods.nextTokenId().call();112 await contract.methods.mint(caller, tokenId).send();113114 const tokenAddress = tokenIdToAddress(collectionId, tokenId);115 const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, tokenAddress, {from: caller, ...GAS_ARGS});116117 await tokenContract.methods.repartition(2).send();118 await tokenContract.methods.transfer(receiver, 1).send();119120 const owner = await contract.methods.ownerOf(tokenId).call();121122 expect(owner).to.equal('0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF');123 });124});125126describe('Refungible: Plain calls', () => {127 before(async function() {128 await requirePallets(this, [Pallets.ReFungible]);129 });130131 itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => {132 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);133 const helper = evmCollectionHelpers(web3, owner);134 let result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();135 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);136 const receiver = createEthAccount(web3);137 const contract = evmCollection(web3, owner, collectionIdAddress, {type: 'ReFungible'});138 const nextTokenId = await contract.methods.nextTokenId().call();139140 expect(nextTokenId).to.be.equal('1');141 result = await contract.methods.mintWithTokenURI(142 receiver,143 nextTokenId,144 'Test URI',145 ).send();146147 const events = normalizeEvents(result.events);148149 expect(events).to.include.deep.members([150 {151 address: collectionIdAddress,152 event: 'Transfer',153 args: {154 from: '0x0000000000000000000000000000000000000000',155 to: receiver,156 tokenId: nextTokenId,157 },158 },159 ]);160161 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');162 });163164 itWeb3('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {165 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);166 const helper = evmCollectionHelpers(web3, caller);167 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();168 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);169 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});170171 const receiver = createEthAccount(web3);172173 {174 const nextTokenId = await contract.methods.nextTokenId().call();175 expect(nextTokenId).to.be.equal('1');176 const result = await contract.methods.mintBulkWithTokenURI(177 receiver,178 [179 [nextTokenId, 'Test URI 0'],180 [+nextTokenId + 1, 'Test URI 1'],181 [+nextTokenId + 2, 'Test URI 2'],182 ],183 ).send();184 const events = normalizeEvents(result.events);185186 expect(events).to.include.deep.members([187 {188 address: collectionIdAddress,189 event: 'Transfer',190 args: {191 from: '0x0000000000000000000000000000000000000000',192 to: receiver,193 tokenId: nextTokenId,194 },195 },196 {197 address: collectionIdAddress,198 event: 'Transfer',199 args: {200 from: '0x0000000000000000000000000000000000000000',201 to: receiver,202 tokenId: String(+nextTokenId + 1),203 },204 },205 {206 address: collectionIdAddress,207 event: 'Transfer',208 args: {209 from: '0x0000000000000000000000000000000000000000',210 to: receiver,211 tokenId: String(+nextTokenId + 2),212 },213 },214 ]);215216 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI 0');217 expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');218 expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');219 }220 });221222 itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {223 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);224 const helper = evmCollectionHelpers(web3, caller);225 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();226 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);227 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});228229 const tokenId = await contract.methods.nextTokenId().call();230 await contract.methods.mint(caller, tokenId).send();231 {232 const result = await contract.methods.burn(tokenId).send();233 const events = normalizeEvents(result.events);234 expect(events).to.include.deep.members([235 {236 address: collectionIdAddress,237 event: 'Transfer',238 args: {239 from: caller,240 to: '0x0000000000000000000000000000000000000000',241 tokenId: tokenId.toString(),242 },243 },244 ]);245 }246 });247248 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {249 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);250 const helper = evmCollectionHelpers(web3, caller);251 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();252 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);253 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});254255 const receiver = createEthAccount(web3);256257 const tokenId = await contract.methods.nextTokenId().call();258 await contract.methods.mint(caller, tokenId).send();259260 const address = tokenIdToAddress(collectionId, tokenId);261 const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});262 await tokenContract.methods.repartition(15).send();263264 {265 const erc20Events = await recordEvents(tokenContract, async () => {266 const result = await contract.methods.transferFrom(caller, receiver, tokenId).send();267 const events = normalizeEvents(result.events);268 expect(events).to.include.deep.members([269 {270 address: collectionIdAddress,271 event: 'Transfer',272 args: {273 from: caller,274 to: receiver,275 tokenId: tokenId.toString(),276 },277 },278 ]);279 });280 281 expect(erc20Events).to.include.deep.members([282 {283 address,284 event: 'Transfer',285 args: {286 from: caller,287 to: receiver,288 value: '15',289 },290 },291 ]);292 }293294 {295 const balance = await contract.methods.balanceOf(receiver).call();296 expect(+balance).to.equal(1);297 }298299 {300 const balance = await contract.methods.balanceOf(caller).call();301 expect(+balance).to.equal(0);302 }303 });304305 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {306 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);307 const helper = evmCollectionHelpers(web3, caller);308 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();309 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);310 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});311312 const receiver = createEthAccount(web3);313314 const tokenId = await contract.methods.nextTokenId().call();315 await contract.methods.mint(caller, tokenId).send();316317 {318 const result = await contract.methods.transfer(receiver, tokenId).send();319 const events = normalizeEvents(result.events);320 expect(events).to.include.deep.members([321 {322 address: collectionIdAddress,323 event: 'Transfer',324 args: {325 from: caller,326 to: receiver,327 tokenId: tokenId.toString(),328 },329 },330 ]);331 }332333 {334 const balance = await contract.methods.balanceOf(caller).call();335 expect(+balance).to.equal(0);336 }337338 {339 const balance = await contract.methods.balanceOf(receiver).call();340 expect(+balance).to.equal(1);341 }342 });343344 itWeb3('transfer event on transfer from partial ownership to full ownership', async ({api, web3, privateKeyWrapper}) => {345 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);346 const receiver = createEthAccount(web3);347 const helper = evmCollectionHelpers(web3, caller);348 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();349 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);350 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});351352 const tokenId = await contract.methods.nextTokenId().call();353 await contract.methods.mint(caller, tokenId).send();354355 const tokenAddress = tokenIdToAddress(collectionId, tokenId);356 const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, tokenAddress, {from: caller, ...GAS_ARGS});357358 await tokenContract.methods.repartition(2).send();359 await tokenContract.methods.transfer(receiver, 1).send();360361 const events = await recordEvents(contract, async () => 362 await tokenContract.methods.transfer(receiver, 1).send());363 expect(events).to.deep.equal([364 {365 address: collectionIdAddress,366 event: 'Transfer',367 args: {368 from: '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF',369 to: receiver,370 tokenId: tokenId.toString(),371 },372 },373 ]);374 });375376 itWeb3('transfer event on transfer from full ownership to partial ownership', async ({api, web3, privateKeyWrapper}) => {377 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);378 const receiver = createEthAccount(web3);379 const helper = evmCollectionHelpers(web3, caller);380 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();381 const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);382 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});383384 const tokenId = await contract.methods.nextTokenId().call();385 await contract.methods.mint(caller, tokenId).send();386387 const tokenAddress = tokenIdToAddress(collectionId, tokenId);388 const tokenContract = new web3.eth.Contract(reFungibleTokenAbi as any, tokenAddress, {from: caller, ...GAS_ARGS});389390 await tokenContract.methods.repartition(2).send();391 392 const events = await recordEvents(contract, async () => 393 await tokenContract.methods.transfer(receiver, 1).send());394 395 expect(events).to.deep.equal([396 {397 address: collectionIdAddress,398 event: 'Transfer',399 args: {400 from: caller,401 to: '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF',402 tokenId: tokenId.toString(),403 },404 },405 ]);406 });407});408409describe('RFT: Fees', () => {410 before(async function() {411 await requirePallets(this, [Pallets.ReFungible]);412 });413414 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {415 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);416 const helper = evmCollectionHelpers(web3, caller);417 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();418 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);419 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});420421 const receiver = createEthAccount(web3);422423 const tokenId = await contract.methods.nextTokenId().call();424 await contract.methods.mint(caller, tokenId).send();425426 const cost = await recordEthFee(api, caller, () => contract.methods.transferFrom(caller, receiver, tokenId).send());427 expect(cost < BigInt(0.2 * Number(UNIQUE)));428 expect(cost > 0n);429 });430431 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {432 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);433 const helper = evmCollectionHelpers(web3, caller);434 const result = await helper.methods.createRefungibleCollection('Mint collection', '6', '6').send();435 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);436 const contract = evmCollection(web3, caller, collectionIdAddress, {type: 'ReFungible'});437438 const receiver = createEthAccount(web3);439440 const tokenId = await contract.methods.nextTokenId().call();441 await contract.methods.mint(caller, tokenId).send();442443 const cost = await recordEthFee(api, caller, () => contract.methods.transfer(receiver, tokenId).send());444 expect(cost < BigInt(0.2 * Number(UNIQUE)));445 expect(cost > 0n);446 });447});448449describe('Common metadata', () => {450 before(async function() {451 await requirePallets(this, [Pallets.ReFungible]);452 });453454 itWeb3('Returns collection name', async ({api, web3, privateKeyWrapper}) => {455 const collection = await createCollectionExpectSuccess({456 name: 'token name',457 mode: {type: 'ReFungible'},458 });459 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);460461 const address = collectionIdToAddress(collection);462 const contract = evmCollection(web3, caller, address, {type: 'ReFungible'});463 const name = await contract.methods.name().call();464465 expect(name).to.equal('token name');466 });467468 itWeb3('Returns symbol name', async ({api, web3, privateKeyWrapper}) => {469 const collection = await createCollectionExpectSuccess({470 tokenPrefix: 'TOK',471 mode: {type: 'ReFungible'},472 });473 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);474475 const address = collectionIdToAddress(collection);476 const contract = evmCollection(web3, caller, address, {type: 'ReFungible'});477 const symbol = await contract.methods.symbol().call();478479 expect(symbol).to.equal('TOK');480 });481});