git.delta.rocks / unique-network / refs/commits / 7c4183b4cb3a

difftreelog

source

tests/src/eth/marketplace/marketplace.test.ts12.1 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 {readFile} from 'fs/promises';18import {getBalanceSingle} from '../../substrate/get-balance';19import privateKey from '../../substrate/privateKey';20import {21  addToAllowListExpectSuccess, 22  confirmSponsorshipExpectSuccess, 23  createCollectionExpectSuccess, 24  createItemExpectSuccess, 25  getTokenOwner,26  setCollectionLimitsExpectSuccess, 27  setCollectionSponsorExpectSuccess, 28  transferExpectSuccess, 29  transferFromExpectSuccess,30  transferBalanceTo,31} from '../../util/helpers';32import {collectionIdToAddress, contractHelpers, createEthAccountWithBalance, executeEthTxOnSub, GAS_ARGS, itWeb3, SponsoringMode, subToEth, subToEthLowercase, transferBalanceToEth} from '../util/helpers';33import {evmToAddress} from '@polkadot/util-crypto';34import nonFungibleAbi from '../nonFungibleAbi.json';3536import {expect} from 'chai';3738const PRICE = 2000n;3940describe('Matcher contract usage', () => {41  itWeb3('With UNQ', async ({api, web3}) => {42    const alice = privateKey('//Alice');43    const matcherOwner = await createEthAccountWithBalance(api, web3);44    const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {45      from: matcherOwner,46      ...GAS_ARGS,47    });48    const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner});49    const helpers = contractHelpers(web3, matcherOwner);50    await helpers.methods.setSponsoringMode(matcher.options.address, SponsoringMode.Allowlisted).send({from: matcherOwner});51    await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner});52    await transferBalanceToEth(api, alice, matcher.options.address);5354    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});55    await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1});56    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});57    await setCollectionSponsorExpectSuccess(collectionId, alice.address);58    await transferBalanceToEth(api, alice, subToEth(alice.address));59    await confirmSponsorshipExpectSuccess(collectionId);6061    await helpers.methods.toggleAllowed(matcher.options.address, subToEth(alice.address), true).send({from: matcherOwner});62    await addToAllowListExpectSuccess(alice, collectionId, evmToAddress(subToEth(alice.address)));6364    const seller = privateKey(`//Seller/${Date.now()}`);65    await helpers.methods.toggleAllowed(matcher.options.address, subToEth(seller.address), true).send({from: matcherOwner});6667    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);6869    // To transfer item to matcher it first needs to be transfered to EVM account of bob70    await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});7172    // Token is owned by seller initially73    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});7475    // Ask76    {77      await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));78      await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId));79    }8081    // Token is transferred to matcher82    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});8384    // Buy85    {86      const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address);87      await executeEthTxOnSub(web3, api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId), {value: PRICE});88      expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE);89    }9091    // Token is transferred to evm account of alice92    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});9394    // Transfer token to substrate side of alice95    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});9697    // Token is transferred to substrate account of alice, seller received funds98    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});99  });100101102  itWeb3('With escrow', async ({api, web3}) => {103    const alice = privateKey('//Alice');104    const matcherOwner = await createEthAccountWithBalance(api, web3);105    const escrow = await createEthAccountWithBalance(api, web3);106    const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {107      from: matcherOwner,108      ...GAS_ARGS,109    });110    const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments: [matcherOwner]}).send({from: matcherOwner, gas: 10000000});111    await matcher.methods.setEscrow(escrow).send({from: matcherOwner});112    const helpers = contractHelpers(web3, matcherOwner);113    await helpers.methods.setSponsoringMode(matcher.options.address, SponsoringMode.Allowlisted).send({from: matcherOwner});114    await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner});115    await transferBalanceToEth(api, alice, matcher.options.address);116117    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});118    await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1});119    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});120    await setCollectionSponsorExpectSuccess(collectionId, alice.address);121    await transferBalanceToEth(api, alice, subToEth(alice.address));122    await confirmSponsorshipExpectSuccess(collectionId);123124    await helpers.methods.toggleAllowed(matcher.options.address, subToEth(alice.address), true).send({from: matcherOwner});125    await addToAllowListExpectSuccess(alice, collectionId, evmToAddress(subToEth(alice.address)));126127    const seller = privateKey(`//Seller/${Date.now()}`);128    await helpers.methods.toggleAllowed(matcher.options.address, subToEth(seller.address), true).send({from: matcherOwner});129130    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);131132    // To transfer item to matcher it first needs to be transfered to EVM account of bob133    await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});134135    // Token is owned by seller initially136    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});137138    // Ask139    {140      await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));141      await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId));142    }143144    // Token is transferred to matcher145    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});146147    // Give buyer KSM148    await matcher.methods.depositKSM(PRICE, subToEth(alice.address)).send({from: escrow});149150    // Buy151    {152      expect(await matcher.methods.balanceKSM(subToEth(seller.address)).call()).to.be.equal('0');153      expect(await matcher.methods.balanceKSM(subToEth(alice.address)).call()).to.be.equal(PRICE.toString());154155      await executeEthTxOnSub(web3, api, alice, matcher, m => m.buyKSM(evmCollection.options.address, tokenId, subToEth(alice.address), subToEth(alice.address)));156157      // Price is removed from buyer balance, and added to seller158      expect(await matcher.methods.balanceKSM(subToEth(alice.address)).call()).to.be.equal('0');159      expect(await matcher.methods.balanceKSM(subToEth(seller.address)).call()).to.be.equal(PRICE.toString());160    }161162    // Token is transferred to evm account of alice163    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});164165    // Transfer token to substrate side of alice166    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});167168    // Token is transferred to substrate account of alice, seller received funds169    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});170  });171172173  itWeb3('Sell tokens from substrate user via EVM contract', async ({api, web3}) => {174    const alice = privateKey('//Alice');175    const matcherOwner = await createEthAccountWithBalance(api, web3);176    const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {177      from: matcherOwner,178      ...GAS_ARGS,179    });180    const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner});181    await transferBalanceToEth(api, alice, matcher.options.address);182183    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});184    await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1});185    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});186187    const seller = privateKey(`//Seller/${Date.now()}`);188    await transferBalanceTo(api, alice, seller.address);189    190    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);191192    // To transfer item to matcher it first needs to be transfered to EVM account of bob193    await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});194195    // Token is owned by seller initially196    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});197198    // Ask199    {200      await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));201      await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId));202    }203204    // Token is transferred to matcher205    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});206207    // Buy208    {209      const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address);210      await executeEthTxOnSub(web3, api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId), {value: PRICE});211      expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE);212    }213214    // Token is transferred to evm account of alice215    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});216217    // Transfer token to substrate side of alice218    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});219220    // Token is transferred to substrate account of alice, seller received funds221    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});222  });223});