git.delta.rocks / unique-network / refs/commits / 149c99dda705

difftreelog

source

tests/src/eth/fungible.test.ts21.8 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;55  let owner: IKeyringPair;5657  before(async function() {58    await usingEthPlaygrounds(async (helper, privateKey) => {59      donor = await privateKey({filename: __filename});60      [alice, owner] = await helper.arrange.createAccounts([20n, 20n], donor);61    });62  });6364  itEth('Can perform mint()', async ({helper}) => {65    const owner = await helper.eth.createAccountWithBalance(donor);66    const receiver = helper.eth.createAccount();67    const collection = await helper.ft.mintCollection(alice);68    await collection.addAdmin(alice, {Ethereum: owner});6970    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);71    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);7273    const result = await contract.methods.mint(receiver, 100).send();74    75    const event = result.events.Transfer;76    expect(event.address).to.equal(collectionAddress);77    expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');78    expect(event.returnValues.to).to.equal(receiver);79    expect(event.returnValues.value).to.equal('100');80  });8182  itEth('Can perform mintBulk()', async ({helper}) => {83    const owner = await helper.eth.createAccountWithBalance(donor);84    const bulkSize = 3;85    const receivers = [...new Array(bulkSize)].map(() => helper.eth.createAccount());86    const collection = await helper.ft.mintCollection(alice);87    await collection.addAdmin(alice, {Ethereum: owner});8889    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);90    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);9192    const result = await contract.methods.mintBulk(Array.from({length: bulkSize}, (_, i) => (93      [receivers[i], (i + 1) * 10]94    ))).send();95    const events = result.events.Transfer.sort((a: any, b: any) => +a.returnValues.value - b.returnValues.value);96    for (let i = 0; i < bulkSize; i++) {97      const event = events[i];98      expect(event.address).to.equal(collectionAddress);99      expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');100      expect(event.returnValues.to).to.equal(receivers[i]);101      expect(event.returnValues.value).to.equal(String(10 * (i + 1)));102    }103  });104105  itEth('Can perform burn()', async ({helper}) => {106    const owner = await helper.eth.createAccountWithBalance(donor);107    const receiver = await helper.eth.createAccountWithBalance(donor);108    const collection = await helper.ft.mintCollection(alice);109    await collection.addAdmin(alice, {Ethereum: owner});110111    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);112    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);113    await contract.methods.mint(receiver, 100).send();114115    const result = await contract.methods.burnFrom(receiver, 49).send({from: receiver});116    117    const event = result.events.Transfer;118    expect(event.address).to.equal(collectionAddress);119    expect(event.returnValues.from).to.equal(receiver);120    expect(event.returnValues.to).to.equal('0x0000000000000000000000000000000000000000');121    expect(event.returnValues.value).to.equal('49');122123    const balance = await contract.methods.balanceOf(receiver).call();124    expect(balance).to.equal('51');125  });126127  itEth('Can perform approve()', async ({helper}) => {128    const owner = await helper.eth.createAccountWithBalance(donor);129    const spender = helper.eth.createAccount();130    const collection = await helper.ft.mintCollection(alice);131    await collection.mint(alice, 200n, {Ethereum: owner});132133    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);134    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);135136    {137      const result = await contract.methods.approve(spender, 100).send({from: owner});138139      const event = result.events.Approval;140      expect(event.address).to.be.equal(collectionAddress);141      expect(event.returnValues.owner).to.be.equal(owner);142      expect(event.returnValues.spender).to.be.equal(spender);143      expect(event.returnValues.value).to.be.equal('100');144    }145146    {147      const allowance = await contract.methods.allowance(owner, spender).call();148      expect(+allowance).to.equal(100);149    }150  });151152  itEth('Can perform burnFromCross()', async ({helper}) => {153    const sender = await helper.eth.createAccountWithBalance(donor, 100n);154155    const collection = await helper.ft.mintCollection(owner, {name: 'A', description: 'B', tokenPrefix: 'C'}, 0);156157    await collection.mint(owner, 200n, {Substrate: owner.address});158    await collection.approveTokens(owner, {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: owner.address});164    165    const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);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(owner.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(owner.address),183          spender: sender,184          value: '51',185        },186        event: 'Approval',187      },188    });189190    const fromBalanceAfter = await collection.getBalance({Substrate: owner.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 transferCross()', async ({helper}) => {234    const owner = await helper.eth.createAccountWithBalance(donor);235    const receiver = await helper.eth.createAccountWithBalance(donor);236    const to = helper.ethCrossAccount.fromAddress(receiver);237    const toSubstrate = helper.ethCrossAccount.fromKeyringPair(donor);238    const collection = await helper.ft.mintCollection(alice);239    await collection.mint(alice, 200n, {Ethereum: owner});240241    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);242    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);243244    {245      const result = await contract.methods.transferCross(to, 50).send({from: owner});246      247      const event = result.events.Transfer;248      expect(event.address).to.be.equal(collectionAddress);249      expect(event.returnValues.from).to.be.equal(owner);250      expect(event.returnValues.to).to.be.equal(receiver);251      expect(event.returnValues.value).to.be.equal('50');252    }253254    {255      const balance = await contract.methods.balanceOf(owner).call();256      expect(+balance).to.equal(150);257    }258259    {260      const balance = await contract.methods.balanceOf(receiver).call();261      expect(+balance).to.equal(50);262    }263    264    {265      const result = await contract.methods.transferCross(toSubstrate, 50).send({from: owner});266      267      const event = result.events.Transfer;268      expect(event.address).to.be.equal(collectionAddress);269      expect(event.returnValues.from).to.be.equal(owner);270      expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(donor.address));271      expect(event.returnValues.value).to.be.equal('50');272    }273274    {275      const balance = await collection.getBalance({Ethereum: owner});276      expect(balance).to.equal(100n);277    }278279    {280      const balance = await collection.getBalance({Substrate: donor.address});281      expect(balance).to.equal(50n);282    }283    284  });285  286  itEth('Can perform transfer()', async ({helper}) => {287    const owner = await helper.eth.createAccountWithBalance(donor);288    const receiver = await helper.eth.createAccountWithBalance(donor);289    const collection = await helper.ft.mintCollection(alice);290    await collection.mint(alice, 200n, {Ethereum: owner});291292    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);293    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);294295    {296      const result = await contract.methods.transfer(receiver, 50).send({from: owner});297      298      const event = result.events.Transfer;299      expect(event.address).to.be.equal(collectionAddress);300      expect(event.returnValues.from).to.be.equal(owner);301      expect(event.returnValues.to).to.be.equal(receiver);302      expect(event.returnValues.value).to.be.equal('50');303    }304305    {306      const balance = await contract.methods.balanceOf(owner).call();307      expect(+balance).to.equal(150);308    }309310    {311      const balance = await contract.methods.balanceOf(receiver).call();312      expect(+balance).to.equal(50);313    }314  });315316  itEth('Can perform transferFromCross()', async ({helper, privateKey}) => {317    const sender = await helper.eth.createAccountWithBalance(donor, 100n);318319    const collection = await helper.ft.mintCollection(owner, {name: 'A', description: 'B', tokenPrefix: 'C'}, 0);320321    const receiver = helper.eth.createAccount();322323    await collection.mint(owner, 200n, {Substrate: owner.address});324    await collection.approveTokens(owner, {Ethereum: sender}, 100n);325326    const address = helper.ethAddress.fromCollectionId(collection.collectionId);327    const contract = helper.ethNativeContract.collection(address, 'ft');328329    const from = helper.ethCrossAccount.fromKeyringPair(owner);330    const to = helper.ethCrossAccount.fromAddress(receiver);331332    const fromBalanceBefore = await collection.getBalance({Substrate: owner.address});333    const toBalanceBefore = await collection.getBalance({Ethereum: receiver});334    335    const result = await contract.methods.transferFromCross(from, to, 51).send({from: sender});336337    expect(result.events).to.be.like({338      Transfer: {339        address,340        event: 'Transfer',341        returnValues: {342          from: helper.address.substrateToEth(owner.address),343          to: receiver,344          value: '51',345        },346      },347      Approval: {348        address,349        event: 'Approval',350        returnValues: {351          owner: helper.address.substrateToEth(owner.address),352          spender: sender,353          value: '49',354        },355      }});356357    const fromBalanceAfter = await collection.getBalance({Substrate: owner.address});358    expect(fromBalanceBefore - fromBalanceAfter).to.be.eq(51n);359    const toBalanceAfter = await collection.getBalance({Ethereum: receiver});360    expect(toBalanceAfter - toBalanceBefore).to.be.eq(51n);361  });362});363364describe('Fungible: Fees', () => {365  let donor: IKeyringPair;366  let alice: IKeyringPair;367368  before(async function() {369    await usingEthPlaygrounds(async (helper, privateKey) => {370      donor = await privateKey({filename: __filename});371      [alice] = await helper.arrange.createAccounts([20n], donor);372    });373  });374  375  itEth('approve() call fee is less than 0.2UNQ', async ({helper}) => {376    const owner = await helper.eth.createAccountWithBalance(donor);377    const spender = helper.eth.createAccount();378    const collection = await helper.ft.mintCollection(alice);379    await collection.mint(alice, 200n, {Ethereum: owner});380381    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);382    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);383384    const cost = await helper.eth.recordCallFee(owner, () => contract.methods.approve(spender, 100).send({from: owner}));385    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));386  });387388  itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {389    const owner = await helper.eth.createAccountWithBalance(donor);390    const spender = await helper.eth.createAccountWithBalance(donor);391    const collection = await helper.ft.mintCollection(alice);392    await collection.mint(alice, 200n, {Ethereum: owner});393394    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);395    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);396397    await contract.methods.approve(spender, 100).send({from: owner});398399    const cost = await helper.eth.recordCallFee(spender, () => contract.methods.transferFrom(owner, spender, 100).send({from: spender}));400    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));401  });402403  itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {404    const owner = await helper.eth.createAccountWithBalance(donor);405    const receiver = helper.eth.createAccount();406    const collection = await helper.ft.mintCollection(alice);407    await collection.mint(alice, 200n, {Ethereum: owner});408409    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);410    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft', owner);411412    const cost = await helper.eth.recordCallFee(owner, () => contract.methods.transfer(receiver, 100).send({from: owner}));413    expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));414  });415});416417describe('Fungible: Substrate calls', () => {418  let donor: IKeyringPair;419  let alice: IKeyringPair;420  let owner: IKeyringPair;421422  before(async function() {423    await usingEthPlaygrounds(async (helper, privateKey) => {424      donor = await privateKey({filename: __filename});425      [alice, owner] = await helper.arrange.createAccounts([20n, 20n], donor);426    });427  });428429  itEth('Events emitted for approve()', async ({helper}) => {430    const receiver = helper.eth.createAccount();431    const collection = await helper.ft.mintCollection(alice);432    await collection.mint(alice, 200n);433434    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);435    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft');436437    const events: any = [];438    contract.events.allEvents((_: any, event: any) => {439      events.push(event);440    });441    442    await collection.approveTokens(alice, {Ethereum: receiver}, 100n);443    if (events.length == 0) await helper.wait.newBlocks(1);444    const event = events[0];445446    expect(event.event).to.be.equal('Approval');447    expect(event.address).to.be.equal(collectionAddress);448    expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));449    expect(event.returnValues.spender).to.be.equal(receiver);450    expect(event.returnValues.value).to.be.equal('100');451  });452453  itEth('Events emitted for transferFrom()', async ({helper}) => {454    const [bob] = await helper.arrange.createAccounts([10n], donor);455    const receiver = helper.eth.createAccount();456    const collection = await helper.ft.mintCollection(alice);457    await collection.mint(alice, 200n);458    await collection.approveTokens(alice, {Substrate: bob.address}, 100n);459460    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);461    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft');462463    const events: any = [];464    contract.events.allEvents((_: any, event: any) => {465      events.push(event);466    });467468    await collection.transferFrom(bob, {Substrate: alice.address}, {Ethereum: receiver}, 51n);469    if (events.length == 0) await helper.wait.newBlocks(1);470    let event = events[0];471472    expect(event.event).to.be.equal('Transfer');473    expect(event.address).to.be.equal(collectionAddress);474    expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));475    expect(event.returnValues.to).to.be.equal(receiver);476    expect(event.returnValues.value).to.be.equal('51');477478    event = events[1];479    expect(event.event).to.be.equal('Approval');480    expect(event.address).to.be.equal(collectionAddress);481    expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));482    expect(event.returnValues.spender).to.be.equal(helper.address.substrateToEth(bob.address));483    expect(event.returnValues.value).to.be.equal('49');484  });485486  itEth('Events emitted for transfer()', async ({helper}) => {487    const receiver = helper.eth.createAccount();488    const collection = await helper.ft.mintCollection(alice);489    await collection.mint(alice, 200n);490491    const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);492    const contract = helper.ethNativeContract.collection(collectionAddress, 'ft');493494    const events: any = [];495    contract.events.allEvents((_: any, event: any) => {496      events.push(event);497    });498    499    await collection.transfer(alice, {Ethereum:receiver}, 51n);500    if (events.length == 0) await helper.wait.newBlocks(1);501    const event = events[0];502503    expect(event.event).to.be.equal('Transfer');504    expect(event.address).to.be.equal(collectionAddress);505    expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));506    expect(event.returnValues.to).to.be.equal(receiver);507    expect(event.returnValues.value).to.be.equal('51');508  });509510  itEth('Events emitted for transferFromCross()', async ({helper, privateKey}) => {511    const sender = await helper.eth.createAccountWithBalance(donor, 100n);512513    const collection = await helper.ft.mintCollection(owner, {name: 'A', description: 'B', tokenPrefix: 'C'}, 0);514515    const receiver = helper.eth.createAccount();516517    await collection.mint(owner, 200n, {Substrate: owner.address});518    await collection.approveTokens(owner, {Ethereum: sender}, 100n);519520    const address = helper.ethAddress.fromCollectionId(collection.collectionId);521    const contract = helper.ethNativeContract.collection(address, 'ft');522523    const from = helper.ethCrossAccount.fromKeyringPair(owner);524    const to = helper.ethCrossAccount.fromAddress(receiver);525    526    const result = await contract.methods.transferFromCross(from, to, 51).send({from: sender});527528    expect(result.events).to.be.like({529      Transfer: {530        address,531        event: 'Transfer',532        returnValues: {533          from: helper.address.substrateToEth(owner.address),534          to: receiver,535          value: '51',536        },537      },538      Approval: {539        address,540        event: 'Approval',541        returnValues: {542          owner: helper.address.substrateToEth(owner.address),543          spender: sender,544          value: '49',545        },546      }});547  });548});