git.delta.rocks / unique-network / refs/commits / dc1fefd785d4

difftreelog

source

tests/src/eth/marketplace/marketplace.test.ts10.7 KiBsourcehistory
1import {readFile} from 'fs/promises';2import {getBalanceSingle, transferBalanceExpectSuccess} from '../../substrate/get-balance';3import privateKey from '../../substrate/privateKey';4import {createCollectionExpectSuccess, createFungibleItemExpectSuccess, createItemExpectSuccess, getTokenOwner, transferExpectSuccess, transferFromExpectSuccess} from '../../util/helpers';5import {collectionIdToAddress, createEthAccountWithBalance, executeEthTxOnSub, GAS_ARGS, itWeb3, subToEth, subToEthLowercase} from '../util/helpers';6import {evmToAddress} from '@polkadot/util-crypto';7import nonFungibleAbi from '../nonFungibleAbi.json';8import fungibleAbi from '../fungibleAbi.json';9import {expect} from 'chai';1011const PRICE = 2000n;1213describe('Matcher contract usage', () => {14  itWeb3('With UNQ', async ({api, web3}) => {15    const matcherOwner = await createEthAccountWithBalance(api, web3);16    const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceUNQ.abi`)).toString()), undefined, {17      from: matcherOwner,18      ...GAS_ARGS,19    });20    const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlaceUNQ.bin`)).toString()}).send({from: matcherOwner});2122    const alice = privateKey('//Alice');23    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});24    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});2526    const seller = privateKey('//Bob');2728    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);2930    // To transfer item to matcher it first needs to be transfered to EVM account of bob31    await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});32    // Fees will be paid from EVM account, so we should have some balance here33    await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);34    await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);3536    // Token is owned by seller initially37    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});3839    // Ask40    {41      await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));42      await executeEthTxOnSub(web3, api, seller, matcher, m => m.setAsk(PRICE, '0x0000000000000000000000000000000000000000', evmCollection.options.address, tokenId, 1));43    }4445    // Token is transferred to matcher46    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});4748    // Buy49    {50      const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address);51      // There is two functions named 'buy', so we should provide full signature52      await executeEthTxOnSub(web3, api, alice, matcher, m => m['buy(address,uint256)'](evmCollection.options.address, tokenId), {value: PRICE});53      expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE);54    }5556    // Token is transferred to evm account of alice57    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});585960    // Transfer token to substrate side of alice61    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});6263    // Token is transferred to substrate account of alice, seller received funds64    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});65  });6667  itWeb3('With custom ERC20', async ({api, web3}) => {68    const matcherOwner = await createEthAccountWithBalance(api, web3);69    const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceUNQ.abi`)).toString()), undefined, {70      from: matcherOwner,71      ...GAS_ARGS,72    });73    const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlaceUNQ.bin`)).toString()}).send({from: matcherOwner});7475    const alice = privateKey('//Alice');76    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});77    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});7879    const fungibleId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});80    const evmFungible = new web3.eth.Contract(fungibleAbi as any, collectionIdToAddress(fungibleId), {from: matcherOwner, ...GAS_ARGS});81    await createFungibleItemExpectSuccess(alice, fungibleId, {Value: PRICE}, {Ethereum: subToEth(alice.address)});8283    const seller = privateKey('//Bob');8485    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);8687    // To transfer item to matcher it first needs to be transfered to EVM account of bob88    await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});89    // Fees will be paid from EVM account, so we should have some balance here90    await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);91    await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);9293    // Token is owned by seller initially94    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});9596    // Ask97    {98      await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));99      await executeEthTxOnSub(web3, api, seller, matcher, m => m.setAsk(PRICE, evmFungible.options.address, evmCollection.options.address, tokenId, 1));100    }101102    // Token is transferred to matcher103    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});104105    // Buy106    {107      const sellerBalanceBeforePurchase = BigInt(await evmFungible.methods.balanceOf(subToEth(seller.address)).call());108      const buyerBalanceBeforePurchase = BigInt(await evmFungible.methods.balanceOf(subToEth(alice.address)).call());109110      await executeEthTxOnSub(web3, api, alice, evmFungible, m => m.approve(matcher.options.address, PRICE));111      // There is two functions named 'buy', so we should provide full signature112      await executeEthTxOnSub(web3, api, alice, matcher, m =>113        m['buy(address,uint256,address,uint256)'](evmCollection.options.address, tokenId, evmFungible.options.address, PRICE));114115      // Approved price is removed from buyer balance, and added to seller116      expect(BigInt(await evmFungible.methods.balanceOf(subToEth(seller.address)).call()) - sellerBalanceBeforePurchase === PRICE);117      expect(buyerBalanceBeforePurchase - BigInt(await evmFungible.methods.balanceOf(subToEth(alice.address)).call()) === PRICE);118    }119120    // Token is transferred to evm account of alice121    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});122123124    // Transfer token to substrate side of alice125    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});126127    // Token is transferred to substrate account of alice128    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});129  });130131  itWeb3('With escrow', async ({api, web3}) => {132    const matcherOwner = await createEthAccountWithBalance(api, web3);133    const escrow = await createEthAccountWithBalance(api, web3);134    const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlaceKSM.abi`)).toString()), undefined, {135      from: matcherOwner,136      ...GAS_ARGS,137    });138    const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlaceKSM.bin`)).toString(), arguments: [escrow]}).send({from: matcherOwner});139140    const ksmToken = 11;141142    const alice = privateKey('//Alice');143    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});144    const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});145146    const seller = privateKey('//Bob');147148    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);149150    // To transfer item to matcher it first needs to be transfered to EVM account of bob151    await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});152    // Fees will be paid from EVM account, so we should have some balance here153    await transferBalanceExpectSuccess(api, seller, evmToAddress(subToEth(seller.address)), 10n ** 18n);154    await transferBalanceExpectSuccess(api, alice, evmToAddress(subToEth(alice.address)), 10n ** 18n);155156    // Token is owned by seller initially157    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});158159    // Ask160    {161      await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));162      await executeEthTxOnSub(web3, api, seller, matcher, m => m.setAsk(PRICE, ksmToken, evmCollection.options.address, tokenId, 1));163    }164165    // Token is transferred to matcher166    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});167168    // Give buyer KSM169    await matcher.methods.deposit(PRICE, ksmToken, subToEth(alice.address)).send({from: escrow});170171    // Buy172    {173      expect(await matcher.methods.escrowBalance(ksmToken, subToEth(seller.address)).call()).to.be.equal('0');174      expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal(PRICE.toString());175176      await executeEthTxOnSub(web3, api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId));177178      // Price is removed from buyer balance, and added to seller179      expect(await matcher.methods.escrowBalance(ksmToken, subToEth(alice.address)).call()).to.be.equal('0');180      expect(await matcher.methods.escrowBalance(ksmToken, subToEth(seller.address)).call()).to.be.equal(PRICE.toString());181    }182183    // Token is transferred to evm account of alice184    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});185186    // Transfer token to substrate side of alice187    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});188189    // Token is transferred to substrate account of alice, seller received funds190    expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});191  });192});