1234567891011121314151617import {approve, createCollection, createRefungibleToken, transfer, transferFrom, UNIQUE} from '../util/helpers';18import {createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, tokenIdToAddress, transferBalanceToEth} from './util/helpers';19import reFungibleTokenAbi from './reFungibleTokenAbi.json';2021import chai from 'chai';22import chaiAsPromised from 'chai-as-promised';23chai.use(chaiAsPromised);24const expect = chai.expect;2526describe('Refungible token: Information getting', () => {27 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {28 const alice = privateKeyWrapper('//Alice');2930 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;3132 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);3334 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;3536 const address = tokenIdToAddress(collectionId, tokenId);37 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});38 const totalSupply = await contract.methods.totalSupply().call();3940 expect(totalSupply).to.equal('200');41 });4243 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {44 const alice = privateKeyWrapper('//Alice');4546 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;4748 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);4950 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;5152 const address = tokenIdToAddress(collectionId, tokenId);53 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});54 const balance = await contract.methods.balanceOf(caller).call();5556 expect(balance).to.equal('200');57 });5859 itWeb3('decimals', async ({api, web3, privateKeyWrapper}) => {60 const alice = privateKeyWrapper('//Alice');6162 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;6364 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);6566 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: caller})).itemId;6768 const address = tokenIdToAddress(collectionId, tokenId);69 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: caller, ...GAS_ARGS});70 const decimals = await contract.methods.decimals().call();7172 expect(decimals).to.equal('0');73 });74});7576describe('Refungible: Plain calls', () => {77 itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {78 const alice = privateKeyWrapper('//Alice');7980 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;8182 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);8384 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;8586 const address = tokenIdToAddress(collectionId, tokenId);8788 const spender = createEthAccount(web3);8990 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});9192 {93 const result = await contract.methods.approve(spender, 100).send({from: owner});94 const events = normalizeEvents(result.events);9596 expect(events).to.be.deep.equal([97 {98 address,99 event: 'Approval',100 args: {101 owner,102 spender,103 value: '100',104 },105 },106 ]);107 }108109 {110 const allowance = await contract.methods.allowance(owner, spender).call();111 expect(+allowance).to.equal(100);112 }113 });114115 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {116 const alice = privateKeyWrapper('//Alice');117118 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;119120 const owner = createEthAccount(web3);121 await transferBalanceToEth(api, alice, owner);122123 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;124125 const spender = createEthAccount(web3);126 await transferBalanceToEth(api, alice, spender);127128 const receiver = createEthAccount(web3);129130 const address = tokenIdToAddress(collectionId, tokenId);131 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});132133 await contract.methods.approve(spender, 100).send();134135 {136 const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});137 const events = normalizeEvents(result.events);138 expect(events).to.be.deep.equal([139 {140 address,141 event: 'Transfer',142 args: {143 from: owner,144 to: receiver,145 value: '49',146 },147 },148 {149 address,150 event: 'Approval',151 args: {152 owner,153 spender,154 value: '51',155 },156 },157 ]);158 }159160 {161 const balance = await contract.methods.balanceOf(receiver).call();162 expect(+balance).to.equal(49);163 }164165 {166 const balance = await contract.methods.balanceOf(owner).call();167 expect(+balance).to.equal(151);168 }169 });170171 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {172 const alice = privateKeyWrapper('//Alice');173174 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;175176 const owner = createEthAccount(web3);177 await transferBalanceToEth(api, alice, owner);178179 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;180181 const receiver = createEthAccount(web3);182 await transferBalanceToEth(api, alice, receiver);183184 const address = tokenIdToAddress(collectionId, tokenId);185 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});186187 {188 const result = await contract.methods.transfer(receiver, 50).send({from: owner});189 const events = normalizeEvents(result.events);190 expect(events).to.be.deep.equal([191 {192 address,193 event: 'Transfer',194 args: {195 from: owner,196 to: receiver,197 value: '50',198 },199 },200 ]);201 }202203 {204 const balance = await contract.methods.balanceOf(owner).call();205 expect(+balance).to.equal(150);206 }207208 {209 const balance = await contract.methods.balanceOf(receiver).call();210 expect(+balance).to.equal(50);211 }212 });213214 itWeb3('Can perform repartition()', async ({web3, api, privateKeyWrapper}) => {215 const alice = privateKeyWrapper('//Alice');216217 const collectionId = (await createCollection(api, alice, {name: 'token name', mode: {type: 'ReFungible'}})).collectionId;218219 const owner = createEthAccount(web3);220 await transferBalanceToEth(api, alice, owner);221222 const receiver = createEthAccount(web3);223 await transferBalanceToEth(api, alice, receiver);224225 const tokenId = (await createRefungibleToken(api, alice, collectionId, 100n, {Ethereum: owner})).itemId;226227 const address = tokenIdToAddress(collectionId, tokenId);228 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});229230 await contract.methods.repartition(200).send({from: owner});231 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(200);232 await contract.methods.transfer(receiver, 110).send({from: owner});233 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(90);234 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(110);235 236 await expect(contract.methods.repartition(80).send({from: owner})).to.eventually.be.rejected;237238 await contract.methods.transfer(receiver, 90).send({from: owner});239 expect(+await contract.methods.balanceOf(owner).call()).to.be.equal(0);240 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(200);241242 await contract.methods.repartition(150).send({from: receiver});243 await expect(contract.methods.transfer(owner, 160).send({from: receiver})).to.eventually.be.rejected;244 expect(+await contract.methods.balanceOf(receiver).call()).to.be.equal(150);245 });246});247248describe('Refungible: Fees', () => {249 itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {250 const alice = privateKeyWrapper('//Alice');251252 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;253254 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);255 const spender = createEthAccount(web3);256257 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;258259 const address = tokenIdToAddress(collectionId, tokenId);260 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});261262 const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({from: owner}));263 expect(cost < BigInt(0.2 * Number(UNIQUE)));264 });265266 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {267 const alice = privateKeyWrapper('//Alice');268269 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;270271 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);272 const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);273274 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;275276 const address = tokenIdToAddress(collectionId, tokenId);277 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});278279 await contract.methods.approve(spender, 100).send({from: owner});280281 const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));282 expect(cost < BigInt(0.2 * Number(UNIQUE)));283 });284285 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {286 const alice = privateKeyWrapper('//Alice');287288 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;289290 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);291 const receiver = createEthAccount(web3);292293 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;294295 const address = tokenIdToAddress(collectionId, tokenId);296 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});297298 const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));299 expect(cost < BigInt(0.2 * Number(UNIQUE)));300 });301});302303describe('Refungible: Substrate calls', () => {304 itWeb3('Events emitted for approve()', async ({web3, api, privateKeyWrapper}) => {305 const alice = privateKeyWrapper('//Alice');306307 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;308309 const receiver = createEthAccount(web3);310311 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;312313 const address = tokenIdToAddress(collectionId, tokenId);314 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);315316 const events = await recordEvents(contract, async () => {317 expect(await approve(api, collectionId, tokenId, alice, {Ethereum: receiver}, 100n)).to.be.true;318 });319320 expect(events).to.be.deep.equal([321 {322 address,323 event: 'Approval',324 args: {325 owner: subToEth(alice.address),326 spender: receiver,327 value: '100',328 },329 },330 ]);331 });332333 itWeb3('Events emitted for transferFrom()', async ({web3, api, privateKeyWrapper}) => {334 const alice = privateKeyWrapper('//Alice');335336 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;337 const bob = privateKeyWrapper('//Bob');338339 const receiver = createEthAccount(web3);340341 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;342 expect(await approve(api, collectionId, tokenId, alice, bob.address, 100n)).to.be.true;343344 const address = tokenIdToAddress(collectionId, tokenId);345 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);346347 const events = await recordEvents(contract, async () => {348 expect(await transferFrom(api, collectionId, tokenId, bob, alice, {Ethereum: receiver}, 51n)).to.be.true;349 });350351 expect(events).to.be.deep.equal([352 {353 address,354 event: 'Transfer',355 args: {356 from: subToEth(alice.address),357 to: receiver,358 value: '51',359 },360 },361 {362 address,363 event: 'Approval',364 args: {365 owner: subToEth(alice.address),366 spender: subToEth(bob.address),367 value: '49',368 },369 },370 ]);371 });372373 itWeb3('Events emitted for transfer()', async ({web3, api, privateKeyWrapper}) => {374 const alice = privateKeyWrapper('//Alice');375376 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;377378 const receiver = createEthAccount(web3);379380 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;381382 const address = tokenIdToAddress(collectionId, tokenId);383 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);384385 const events = await recordEvents(contract, async () => {386 expect(await transfer(api, collectionId, tokenId, alice, {Ethereum: receiver}, 51n)).to.be.true;387 });388389 expect(events).to.be.deep.equal([390 {391 address,392 event: 'Transfer',393 args: {394 from: subToEth(alice.address),395 to: receiver,396 value: '51',397 },398 },399 ]);400 });401});