import { Currency , getETHPayment , getSignedPayment , Order , CreditCardEscrow } from '@imtbl/platform' ; import { Blockchain , Ganache , generatedWallets , expectRevert } from '@imtbl/test-utils' ; import { ethers } from 'ethers' ; import 'jest' ; import { GU_S1_RARE_PACK_PRICE , GU_S1_RARE_PACK_SKU } from '../../../deployment/constants' ; import { RarePack , S1Sale } from '../../../src/contracts' ; import { deployRarePack , deployStandards , StandardContracts } from './utils' ; jest . setTimeout ( 600000 ) ; const provider = new Ganache ( Ganache . DefaultOptions ) ; const blockchain = new Blockchain ( provider ) ; ethers . errors . setLogLevel ( 'error' ) ; describe ( 'Sale' , ( ) => { const [ owner , other ] = generatedWallets ( provider ) ; beforeEach ( async ( ) => { await blockchain . resetAsync ( ) ; await blockchain . saveSnapshotAsync ( ) ; } ) ; afterEach ( async ( ) => { await blockchain . revertAsync ( ) ; } ) ; describe ( 'purchaseFor with USD' , ( ) => { let shared ; let rare ; let sale ; beforeAll ( async ( ) => { shared = await deployStandards ( owner ) ; } ) ; beforeEach ( async ( ) => { rare = await deployRarePack ( owner , shared ) ; sale = await S1Sale . deploy ( owner ) ; await sale . setVendorApproval ( true , [ rare . address ] ) ; } ) ; async function purchasePacks ( products , quantities , prices ) { const payments = await Promise . all ( quantities . map ( async ( quantity , i ) => { const cost = prices [ i ] ; const order = { quantity , sku : GU_S1_RARE_PACK_SKU , assetRecipient : owner . address , changeRecipient : sale . address , totalPrice : cost * quantity , currency : Currency . USDCents , alreadyPaid : 0 } ; const params = { escrowFor : 0 , nonce : i , value : cost * quantity } ; return { quantity , payment : await getSignedPayment ( owner , shared . processor . address , rare . address , order , params ) , vendor : products [ i ] , } ; } ) ) ; await sale . purchaseFor ( owner . address , payments , ethers . constants . AddressZero ) ; } it ( 'should purchase one item' , async ( ) => { await purchasePacks ( [ rare . address ] , [ 1 ] , [ GU_S1_RARE_PACK_PRICE ] ) ; } ) ; it ( 'should purchase two items' , async ( ) => { await purchasePacks ( [ rare . address , rare . address ] , [ 1 , 1 ] , [ GU_S1_RARE_PACK_PRICE , GU_S1_RARE_PACK_PRICE ] ) ; } ) ; } ) ; describe ( 'referred purchaseFor with USD' , ( ) => { let shared ; let rare ; let sale ; beforeAll ( async ( ) => { shared = await deployStandards ( owner ) ; } ) ; beforeEach ( async ( ) => { rare = await deployRarePack ( owner , shared ) ; sale = await S1Sale . deploy ( owner ) ; await sale . setVendorApproval ( true , [ rare . address ] ) ; } ) ; async function purchasePacks ( products , quantities , prices ) { const payments = await Promise . all ( quantities . map ( async ( quantity , i ) => { const cost = prices [ i ] ; const order = { quantity , sku : GU_S1_RARE_PACK_SKU , assetRecipient : owner . address , changeRecipient : sale . address , totalPrice : cost * quantity , currency : Currency . USDCents , alreadyPaid : 0 } ; const params = { escrowFor : 0 , nonce : i , value : cost * quantity } ; return { quantity , payment : await getSignedPayment ( owner , shared . processor . address , rare . address , order , params ) , vendor : products [ i ] , } ; } ) ) ; await sale . purchaseFor ( owner . address , payments , other . address ) ; } it ( 'should purchase one item' , async ( ) => { await purchasePacks ( [ rare . address ] , [ 1 ] , [ GU_S1_RARE_PACK_PRICE ] ) ; } ) ; it ( 'should purchase two items' , async ( ) => { await purchasePacks ( [ rare . address , rare . address ] , [ 1 , 1 ] , [ GU_S1_RARE_PACK_PRICE , GU_S1_RARE_PACK_PRICE ] ) ; } ) ; } ) ; describe ( 'should do the whole purchase lifecycle' , ( ) => { let shared ; let rare ; let sale ; beforeAll ( async ( ) => { shared = await deployStandards ( owner ) ; } ) ; beforeEach ( async ( ) => { rare = await deployRarePack ( owner , shared ) ; sale = await S1Sale . deploy ( owner ) ; await sale . setVendorApproval ( true , [ rare . address ] ) ; } ) ; async function purchasePacks ( user , escrowFor , products , quantities , prices ) { const payments = await Promise . all ( quantities . map ( async ( quantity , i ) => { const cost = prices [ i ] ; const order = { quantity , sku : GU_S1_RARE_PACK_SKU , assetRecipient : user , changeRecipient : sale . address , totalPrice : cost * quantity , currency : Currency . USDCents , alreadyPaid : 0 } ; const params = { escrowFor : escrowFor , nonce : i , value : cost * quantity } ; return { quantity , payment : await getSignedPayment ( owner , shared . processor . address , rare . address , order , params ) , vendor : products [ i ] , } ; } ) ) ; await sale . purchaseFor ( user , payments , other . address ) ; } } ) ; describe ( 'purchaseFor with ETH' , ( ) => { let shared ; let rare ; let sale ; beforeAll ( async ( ) => { shared = await deployStandards ( owner ) ; } ) ; beforeEach ( async ( ) => { rare = await deployRarePack ( owner , shared ) ; sale = await S1Sale . deploy ( owner ) ; await sale . setVendorApproval ( true , [ rare . address ] ) ; } ) ; async function purchasePacks ( products , quantities , prices ) { let totalCost = 0 ; const payments = quantities . map ( ( quantity , i ) => { totalCost += quantity * prices [ i ] ; return { quantity , payment : getETHPayment ( ) , vendor : products [ i ] , } ; } ) ; const ethRequired = await shared . oracle . convert ( 1 , 0 , totalCost ) ; await sale . purchaseFor ( owner . address , payments , ethers . constants . AddressZero , { value : ethRequired . mul ( 10 ) } ) ; } it ( 'should purchase one item' , async ( ) => { await purchasePacks ( [ rare . address ] , [ 1 ] , [ GU_S1_RARE_PACK_PRICE ] ) ; } ) ; it ( 'should purchase two items' , async ( ) => { await purchasePacks ( [ rare . address , rare . address ] , [ 1 , 1 ] , [ GU_S1_RARE_PACK_PRICE , GU_S1_RARE_PACK_PRICE ] ) ; } ) ; } ) ; describe ( 'referred purchaseFor with ETH' , ( ) => { let shared ; let rare ; let sale ; beforeAll ( async ( ) => { shared = await deployStandards ( owner ) ; } ) ; beforeEach ( async ( ) => { rare = await deployRarePack ( owner , shared ) ; sale = await S1Sale . deploy ( owner ) ; await sale . setVendorApproval ( true , [ rare . address ] ) ; } ) ; async function purchasePacks ( products , quantities , prices ) { let totalCost = 0 ; const payments = quantities . map ( ( quantity , i ) => { totalCost += quantity * prices [ i ] ; return { quantity , payment : getETHPayment ( ) , vendor : products [ i ] , } ; } ) ; const ethRequired = await shared . oracle . convert ( 1 , 0 , totalCost ) ; await sale . purchaseFor ( owner . address , payments , other . address , { value : ethRequired } ) ; } it ( 'should purchase one item' , async ( ) => { await purchasePacks ( [ rare . address ] , [ 1 ] , [ GU_S1_RARE_PACK_PRICE ] ) ; } ) ; it ( 'should purchase two items' , async ( ) => { await purchasePacks ( [ rare . address , rare . address ] , [ 1 , 1 ] , [ GU_S1_RARE_PACK_PRICE , GU_S1_RARE_PACK_PRICE ] ) ; } ) ; } ) ; describe ( 'purchaseForAll with ETH' , ( ) => { let shared ; let rare ; let sale ; beforeAll ( async ( ) => { shared = await deployStandards ( owner ) ; } ) ; beforeEach ( async ( ) => { rare = await deployRarePack ( owner , shared ) ; sale = await S1Sale . deploy ( owner ) ; await sale . setVendorApproval ( true , [ rare . address ] ) ; } ) ; async function purchasePacks ( products , quantities , prices ) { let totalCost = 0 ; const payments = quantities . map ( ( quantity , i ) => { totalCost += quantity * prices [ i ] ; return { quantity , recipient : owner . address , payment : getETHPayment ( ) , vendor : products [ i ] , } ; } ) ; const ethRequired = await shared . oracle . convert ( 1 , 0 , totalCost ) ; await sale . purchaseForAll ( payments , other . address , { value : ethRequired } ) ; } it ( 'should purchase one item' , async ( ) => { await purchasePacks ( [ rare . address ] , [ 1 ] , [ GU_S1_RARE_PACK_PRICE ] ) ; } ) ; it ( 'should purchase two items' , async ( ) => { await purchasePacks ( [ rare . address , rare . address ] , [ 1 , 1 ] , [ GU_S1_RARE_PACK_PRICE , GU_S1_RARE_PACK_PRICE ] ) ; } ) ; } ) ; } ) ;