git.delta.rocks / unique-network / refs/commits / 6afd9fe97b2d

difftreelog

source

tests/src/eth/fungible.test.ts19.9 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {expect, itEth, usingEthPlaygrounds} from './util';18import {IKeyringPair} from '@polkadot/types/types';1920describe('Fungible: Information getting', () => {21  let donor: IKeyringPair;22  let alice: IKeyringPair;2324  before(async function() {25    await usingEthPlaygrounds(async (helper, privateKey) => {26      donor = await privateKey({filename: __filename});27      [alice] = await helper.arrange.createAccounts([20n], donor);28    });29  });3031  itEth('totalSupply', async ({helper}) => {32    const caller = await helper.eth.createAccountWithBalance(donor);33    const collection = await helper.ft.mintCollection(alice);34    await collection.mint(alice, 200n);3536    const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'ft', caller);37    const totalSupply = await contract.methods.totalSupply().call();38    expect(totalSupply).to.equal('200');39  });4041  itEth('balanceOf', async ({helper}) => {42    const caller = await helper.eth.createAccountWithBalance(donor);43    const collection = await helper.ft.mintCollection(alice);44    await collection.mint(alice, 200n, {Ethereum: caller});4546    const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'ft', caller);47    const balance = await contract.methods.balanceOf(caller).call();48    expect(balance).to.equal('200');49  });50});5152describe('Fungible: Plain calls', () => {53  let donor: IKeyringPair;54  let alice: IKeyringPair;5556  before(async function() {57    await usingEthPlaygrounds(async (helper, privateKey) => {58      donor = await privateKey({filename: __filename});59      [alice] = await helper.arrange.createAccounts([20n], donor);60    });61  });6263  itEth('Can perform mint()', async ({helper}) => {64    const owner = await helper.eth.createAccountWithBalance(donor);65    const receiver = helper.eth.createAccount();66    const collection = await helper.ft.mintCollection(alice);67    await collection.addAdmin(alice, {Ethereum: owner});6869    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);70    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);7172    const result = await contract.methods.mint(receiver, 100).send();73    74    const event = result.events.Transfer;75    expect(event.address).to.equal(collectionAddress);76    expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');77    expect(event.returnValues.to).to.equal(receiver);78    expect(event.returnValues.value).to.equal('100');79  });8081  itEth('Can perform mintBulk()', async ({helper}) => {82    const owner = await helper.eth.createAccountWithBalance(donor);83    const bulkSize = 3;84    const receivers = [...new Array(bulkSize)].map(() => helper.eth.createAccount());85    const collection = await helper.ft.mintCollection(alice);86    await collection.addAdmin(alice, {Ethereum: owner});8788    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);89    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);9091    const result = await contract.methods.mintBulk(Array.from({length: bulkSize}, (_, i) => (92      [receivers[i], (i + 1) * 10]93    ))).send();94    const events = result.events.Transfer.sort((a: any, b: any) => +a.returnValues.value - b.returnValues.value);95    for (let i = 0; i < bulkSize; i++) {96      const event = events[i];97      expect(event.address).to.equal(collectionAddress);98      expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');99      expect(event.returnValues.to).to.equal(receivers[i]);100      expect(event.returnValues.value).to.equal(String(10 * (i + 1)));101    }102  });103104  itEth('Can perform burn()', async ({helper}) => {105    const owner = await helper.eth.createAccountWithBalance(donor);106    const receiver = await helper.eth.createAccountWithBalance(donor);107    const collection = await helper.ft.mintCollection(alice);108    await collection.addAdmin(alice, {Ethereum: owner});109110    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);111    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);112    await contract.methods.mint(receiver, 100).send();113114    const result = await contract.methods.burnFrom(receiver, 49).send({from: receiver});115    116    const event = result.events.Transfer;117    expect(event.address).to.equal(collectionAddress);118    expect(event.returnValues.from).to.equal(receiver);119    expect(event.returnValues.to).to.equal('0x0000000000000000000000000000000000000000');120    expect(event.returnValues.value).to.equal('49');121122    const balance = await contract.methods.balanceOf(receiver).call();123    expect(balance).to.equal('51');124  });125126  itEth('Can perform approve()', async ({helper}) => {127    const owner = await helper.eth.createAccountWithBalance(donor);128    const spender = helper.eth.createAccount();129    const collection = await helper.ft.mintCollection(alice);130    await collection.mint(alice, 200n, {Ethereum: owner});131132    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);133    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);134135    {136      const result = await contract.methods.approve(spender, 100).send({from: owner});137138      const event = result.events.Approval;139      expect(event.address).to.be.equal(collectionAddress);140      expect(event.returnValues.owner).to.be.equal(owner);141      expect(event.returnValues.spender).to.be.equal(spender);142      expect(event.returnValues.value).to.be.equal('100');143    }144145    {146      const allowance = await contract.methods.allowance(owner, spender).call();147      expect(+allowance).to.equal(100);148    }149  });150151  itEth('Can perform burnFromCross()', async ({helper, privateKey}) => {152    const alice = privateKey('//Alice');153    const sender = await helper.eth.createAccountWithBalance(alice, 100n);154155    const collection = await helper.ft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'}, 0);156157    await collection.mint(alice, 200n, {Substrate: alice.address});158    await collection.approveTokens(alice, {Ethereum: sender}, 100n);159160    const address = helper.ethAddress.fromCollectionId(collection.collectionId);161    const contract = helper.ethNativeContract.collection(address, 'ft');162163    const fromBalanceBefore = await collection.getBalance({Substrate: alice.address});164    165    const ownerCross = helper.ethCrossAccount.fromKeyringPair(alice);166    const result = await contract.methods.burnFromCross(ownerCross, 49).send({from: sender});167    const events = result.events;168169    expect(events).to.be.like({170      Transfer: {171        address: helper.ethAddress.fromCollectionId(collection.collectionId),172        event: 'Transfer',173        returnValues: {174          from: helper.address.substrateToEth(alice.address),175          to: '0x0000000000000000000000000000000000000000',176          value: '49',177        },178      },179      Approval: {180        address: helper.ethAddress.fromCollectionId(collection.collectionId),181        returnValues: {182          owner: helper.address.substrateToEth(alice.address),183          spender: sender,184          value: '51',185        },186        event: 'Approval',187      },188    });189190    const fromBalanceAfter = await collection.getBalance({Substrate: alice.address});191    expect(fromBalanceBefore - fromBalanceAfter).to.be.eq(49n);192  });193194  itEth('Can perform transferFrom()', async ({helper}) => {195    const owner = await helper.eth.createAccountWithBalance(donor);196    const spender = await helper.eth.createAccountWithBalance(donor);197    const receiver = helper.eth.createAccount();198    const collection = await helper.ft.mintCollection(alice);199    await collection.mint(alice, 200n, {Ethereum: owner});200201    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);202    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);203204    await contract.methods.approve(spender, 100).send();205206    {207      const result = await contract.methods.transferFrom(owner, receiver, 49).send({from: spender});208      209      let event = result.events.Transfer;210      expect(event.address).to.be.equal(collectionAddress);211      expect(event.returnValues.from).to.be.equal(owner);212      expect(event.returnValues.to).to.be.equal(receiver);213      expect(event.returnValues.value).to.be.equal('49');214215      event = result.events.Approval;216      expect(event.address).to.be.equal(collectionAddress);217      expect(event.returnValues.owner).to.be.equal(owner);218      expect(event.returnValues.spender).to.be.equal(spender);219      expect(event.returnValues.value).to.be.equal('51');220    }221222    {223      const balance = await contract.methods.balanceOf(receiver).call();224      expect(+balance).to.equal(49);225    }226227    {228      const balance = await contract.methods.balanceOf(owner).call();229      expect(+balance).to.equal(151);230    }231  });232233  itEth('Can perform transfer()', async ({helper}) => {234    const owner = await helper.eth.createAccountWithBalance(donor);235    const receiver = await helper.eth.createAccountWithBalance(donor);236    const collection = await helper.ft.mintCollection(alice);237    await collection.mint(alice, 200n, {Ethereum: owner});238239    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);240    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);241242    {243      const result = await contract.methods.transfer(receiver, 50).send({from: owner});244      245      const event = result.events.Transfer;246      expect(event.address).to.be.equal(collectionAddress);247      expect(event.returnValues.from).to.be.equal(owner);248      expect(event.returnValues.to).to.be.equal(receiver);249      expect(event.returnValues.value).to.be.equal('50');250    }251252    {253      const balance = await contract.methods.balanceOf(owner).call();254      expect(+balance).to.equal(150);255    }256257    {258      const balance = await contract.methods.balanceOf(receiver).call();259      expect(+balance).to.equal(50);260    }261  });262263  itEth('Can perform transferFromCross()', async ({helper, privateKey}) => {264    const alice = privateKey('//Alice');265    const sender = await helper.eth.createAccountWithBalance(alice, 100n);266267    const collection = await helper.ft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'}, 0);268269    const receiver = helper.eth.createAccount();270271    await collection.mint(alice, 200n, {Substrate: alice.address});272    await collection.approveTokens(alice, {Ethereum: sender}, 100n);273274    const address = helper.ethAddress.fromCollectionId(collection.collectionId);275    const contract = helper.ethNativeContract.collection(address, 'ft');276277    const from = helper.ethCrossAccount.fromKeyringPair(alice);278    const to = helper.ethCrossAccount.fromAddress(receiver);279280    const fromBalanceBefore = await collection.getBalance({Substrate: alice.address});281    const toBalanceBefore = await collection.getBalance({Ethereum: receiver});282    283    const result = await contract.methods.transferFromCross(from, to, 51).send({from: sender});284285    expect(result.events).to.be.like({286      Transfer: {287        address,288        event: 'Transfer',289        returnValues: {290          from: helper.address.substrateToEth(alice.address),291          to: receiver,292          value: '51',293        },294      },295      Approval: {296        address,297        event: 'Approval',298        returnValues: {299          owner: helper.address.substrateToEth(alice.address),300          spender: sender,301          value: '49',302        },303      }});304305    const fromBalanceAfter = await collection.getBalance({Substrate: alice.address});306    expect(fromBalanceBefore - fromBalanceAfter).to.be.eq(51n);307    const toBalanceAfter = await collection.getBalance({Ethereum: receiver});308    expect(toBalanceAfter - toBalanceBefore).to.be.eq(51n);309  });310});311312describe('Fungible: Fees', () => {313  let donor: IKeyringPair;314  let alice: IKeyringPair;315316  before(async function() {317    await usingEthPlaygrounds(async (helper, privateKey) => {318      donor = await privateKey({filename: __filename});319      [alice] = await helper.arrange.createAccounts([20n], donor);320    });321  });322  323  itEth('approve() call fee is less than 0.2UNQ', async ({helper}) => {324    const owner = await helper.eth.createAccountWithBalance(donor);325    const spender = helper.eth.createAccount();326    const collection = await helper.ft.mintCollection(alice);327    await collection.mint(alice, 200n, {Ethereum: owner});328329    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);330    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);331332    const cost = await helper.eth.recordCallFee(owner, () => contract.methods.approve(spender, 100).send({from: owner}));333    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));334  });335336  itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {337    const owner = await helper.eth.createAccountWithBalance(donor);338    const spender = await helper.eth.createAccountWithBalance(donor);339    const collection = await helper.ft.mintCollection(alice);340    await collection.mint(alice, 200n, {Ethereum: owner});341342    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);343    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);344345    await contract.methods.approve(spender, 100).send({from: owner});346347    const cost = await helper.eth.recordCallFee(spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));348    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));349  });350351  itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {352    const owner = await helper.eth.createAccountWithBalance(donor);353    const receiver = helper.eth.createAccount();354    const collection = await helper.ft.mintCollection(alice);355    await collection.mint(alice, 200n, {Ethereum: owner});356357    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);358    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);359360    const cost = await helper.eth.recordCallFee(owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));361    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));362  });363});364365describe('Fungible: Substrate calls', () => {366  let donor: IKeyringPair;367  let alice: IKeyringPair;368369  before(async function() {370    await usingEthPlaygrounds(async (helper, privateKey) => {371      donor = await privateKey({filename: __filename});372      [alice] = await helper.arrange.createAccounts([20n], donor);373    });374  });375376  itEth('Events emitted for approve()', async ({helper}) => {377    const receiver = helper.eth.createAccount();378    const collection = await helper.ft.mintCollection(alice);379    await collection.mint(alice, 200n);380381    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);382    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft');383384    const events: any = [];385    contract.events.allEvents((_: any, event: any) => {386      events.push(event);387    });388    389    await collection.approveTokens(alice, {Ethereum: receiver}, 100n);390    if (events.length == 0) await helper.wait.newBlocks(1);391    const event = events[0];392393    expect(event.event).to.be.equal('Approval');394    expect(event.address).to.be.equal(collectionAddress);395    expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));396    expect(event.returnValues.spender).to.be.equal(receiver);397    expect(event.returnValues.value).to.be.equal('100');398  });399400  itEth('Events emitted for transferFrom()', async ({helper}) => {401    const [bob] = await helper.arrange.createAccounts([10n], donor);402    const receiver = helper.eth.createAccount();403    const collection = await helper.ft.mintCollection(alice);404    await collection.mint(alice, 200n);405    await collection.approveTokens(alice, {Substrate: bob.address}, 100n);406407    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);408    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft');409410    const events: any = [];411    contract.events.allEvents((_: any, event: any) => {412      events.push(event);413    });414415    await collection.transferFrom(bob, {Substrate: alice.address}, {Ethereum: receiver}, 51n);416    if (events.length == 0) await helper.wait.newBlocks(1);417    let event = events[0];418419    expect(event.event).to.be.equal('Transfer');420    expect(event.address).to.be.equal(collectionAddress);421    expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));422    expect(event.returnValues.to).to.be.equal(receiver);423    expect(event.returnValues.value).to.be.equal('51');424425    event = events[1];426    expect(event.event).to.be.equal('Approval');427    expect(event.address).to.be.equal(collectionAddress);428    expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));429    expect(event.returnValues.spender).to.be.equal(helper.address.substrateToEth(bob.address));430    expect(event.returnValues.value).to.be.equal('49');431  });432433  itEth('Events emitted for transfer()', async ({helper}) => {434    const receiver = helper.eth.createAccount();435    const collection = await helper.ft.mintCollection(alice);436    await collection.mint(alice, 200n);437438    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);439    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft');440441    const events: any = [];442    contract.events.allEvents((_: any, event: any) => {443      events.push(event);444    });445    446    await collection.transfer(alice, {Ethereum:receiver}, 51n);447    if (events.length == 0) await helper.wait.newBlocks(1);448    const event = events[0];449450    expect(event.event).to.be.equal('Transfer');451    expect(event.address).to.be.equal(collectionAddress);452    expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));453    expect(event.returnValues.to).to.be.equal(receiver);454    expect(event.returnValues.value).to.be.equal('51');455  });456457  itEth('Events emitted for transferFromCross()', async ({helper, privateKey}) => {458    const alice = privateKey('//Alice');459    const sender = await helper.eth.createAccountWithBalance(alice, 100n);460461    const collection = await helper.ft.mintCollection(alice, {name: 'A', description: 'B', tokenPrefix: 'C'}, 0);462463    const receiver = helper.eth.createAccount();464465    await collection.mint(alice, 200n, {Substrate: alice.address});466    await collection.approveTokens(alice, {Ethereum: sender}, 100n);467468    const address = helper.ethAddress.fromCollectionId(collection.collectionId);469    const contract = helper.ethNativeContract.collection(address, 'ft');470471    const from = helper.ethCrossAccount.fromKeyringPair(alice);472    const to = helper.ethCrossAccount.fromAddress(receiver);473    474    const result = await contract.methods.transferFromCross(from, to, 51).send({from: sender});475476    expect(result.events).to.be.like({477      Transfer: {478        address,479        event: 'Transfer',480        returnValues: {481          from: helper.address.substrateToEth(alice.address),482          to: receiver,483          value: '51',484        },485      },486      Approval: {487        address,488        event: 'Approval',489        returnValues: {490          owner: helper.address.substrateToEth(alice.address),491          spender: sender,492          value: '49',493        },494      }});495  });496});