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 });213});214215describe('Refungible: Fees', () => {216 itWeb3('approve() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {217 const alice = privateKeyWrapper('//Alice');218219 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;220221 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);222 const spender = createEthAccount(web3);223224 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;225226 const address = tokenIdToAddress(collectionId, tokenId);227 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});228229 const cost = await recordEthFee(api, owner, () => contract.methods.approve(spender, 100).send({from: owner}));230 expect(cost < BigInt(0.2 * Number(UNIQUE)));231 });232233 itWeb3('transferFrom() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {234 const alice = privateKeyWrapper('//Alice');235236 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;237238 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);239 const spender = await createEthAccountWithBalance(api, web3, privateKeyWrapper);240241 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;242243 const address = tokenIdToAddress(collectionId, tokenId);244 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});245246 await contract.methods.approve(spender, 100).send({from: owner});247248 const cost = await recordEthFee(api, spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));249 expect(cost < BigInt(0.2 * Number(UNIQUE)));250 });251252 itWeb3('transfer() call fee is less than 0.2UNQ', async ({web3, api, privateKeyWrapper}) => {253 const alice = privateKeyWrapper('//Alice');254255 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;256257 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);258 const receiver = createEthAccount(web3);259260 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n, {Ethereum: owner})).itemId;261262 const address = tokenIdToAddress(collectionId, tokenId);263 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address, {from: owner, ...GAS_ARGS});264265 const cost = await recordEthFee(api, owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));266 expect(cost < BigInt(0.2 * Number(UNIQUE)));267 });268});269270describe('Refungible: Substrate calls', () => {271 itWeb3('Events emitted for approve()', async ({web3, api, privateKeyWrapper}) => {272 const alice = privateKeyWrapper('//Alice');273274 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;275276 const receiver = createEthAccount(web3);277278 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;279280 const address = tokenIdToAddress(collectionId, tokenId);281 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);282283 const events = await recordEvents(contract, async () => {284 expect(await approve(api, collectionId, tokenId, alice, {Ethereum: receiver}, 100n)).to.be.true;285 });286287 expect(events).to.be.deep.equal([288 {289 address,290 event: 'Approval',291 args: {292 owner: subToEth(alice.address),293 spender: receiver,294 value: '100',295 },296 },297 ]);298 });299300 itWeb3('Events emitted for transferFrom()', async ({web3, api, privateKeyWrapper}) => {301 const alice = privateKeyWrapper('//Alice');302303 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;304 const bob = privateKeyWrapper('//Bob');305306 const receiver = createEthAccount(web3);307308 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;309 expect(await approve(api, collectionId, tokenId, alice, bob.address, 100n)).to.be.true;310311 const address = tokenIdToAddress(collectionId, tokenId);312 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);313314 const events = await recordEvents(contract, async () => {315 expect(await transferFrom(api, collectionId, tokenId, bob, alice, {Ethereum: receiver}, 51n)).to.be.true;316 });317318 expect(events).to.be.deep.equal([319 {320 address,321 event: 'Transfer',322 args: {323 from: subToEth(alice.address),324 to: receiver,325 value: '51',326 },327 },328 {329 address,330 event: 'Approval',331 args: {332 owner: subToEth(alice.address),333 spender: subToEth(bob.address),334 value: '49',335 },336 },337 ]);338 });339340 itWeb3('Events emitted for transfer()', async ({web3, api, privateKeyWrapper}) => {341 const alice = privateKeyWrapper('//Alice');342343 const collectionId = (await createCollection(api, alice, {mode: {type: 'ReFungible'}})).collectionId;344345 const receiver = createEthAccount(web3);346347 const tokenId = (await createRefungibleToken(api, alice, collectionId, 200n)).itemId;348349 const address = tokenIdToAddress(collectionId, tokenId);350 const contract = new web3.eth.Contract(reFungibleTokenAbi as any, address);351352 const events = await recordEvents(contract, async () => {353 expect(await transfer(api, collectionId, tokenId, alice, {Ethereum: receiver}, 51n)).to.be.true;354 });355356 expect(events).to.be.deep.equal([357 {358 address,359 event: 'Transfer',360 args: {361 from: subToEth(alice.address),362 to: receiver,363 value: '51',364 },365 },366 ]);367 });368});