diff --git a/test/exchangeMatchMultiple.js b/test/exchangeMatchMultiple.js new file mode 100644 index 00000000..eadb98d9 --- /dev/null +++ b/test/exchangeMatchMultiple.js @@ -0,0 +1,256 @@ +const testHelpers = new require("./helpers/testHelpers.js"); +const tokenTestHelpers = require("./helpers/tokenTestHelpers.js"); +const exchangeTestHelper = require("./helpers/exchangeTestHelpers.js"); + +const TOKEN_BUY = testHelpers.TOKEN_BUY; +const TOKEN_SELL = testHelpers.TOKEN_SELL; + +let snapshotId; +let exchange = null; +let maker; +let taker; + +contract("Exchange Multiple Matching tests", () => { + before(async function() { + exchange = exchangeTestHelper.exchange; + maker = global.accounts[1]; + taker = global.accounts[2]; + await tokenTestHelpers.issueToken(global.accounts[0], maker, 1000000); + await tokenTestHelpers.issueToken(global.accounts[0], taker, 1000000); + }); + + beforeEach(async function() { + snapshotId = await testHelpers.takeSnapshot(); + }); + + afterEach(async function() { + await testHelpers.revertSnapshot(snapshotId); + }); + + it("should match multiple sell orders", async function() { + const makerPrice = 1010000; + const tokenAmount = 10000; + + const buyOrder1 = { + amount: global.web3v1.utils.toWei("10"), + maker: maker, + price: makerPrice, + orderType: TOKEN_BUY + }; + const buyOrder2 = { + amount: global.web3v1.utils.toWei("20"), + maker: maker, + price: makerPrice, + orderType: TOKEN_BUY + }; + const sellOrder1 = { + amount: tokenAmount, + maker: taker, + price: 990000, + orderType: TOKEN_SELL + }; + const sellOrder2 = Object.assign({}, sellOrder1); + const sellOrder3 = Object.assign({}, sellOrder1); + + await exchangeTestHelper.newOrder(this, buyOrder1); + await exchangeTestHelper.newOrder(this, buyOrder2); + await exchangeTestHelper.newOrder(this, sellOrder1), + await exchangeTestHelper.newOrder(this, sellOrder2), + await exchangeTestHelper.newOrder(this, sellOrder3); + + // await exchangeTestHelper.printOrderBook(10); + + const tx = await exchange.matchMultipleOrders( + [buyOrder1.id, buyOrder2.id, buyOrder1.id], + [sellOrder1.id, sellOrder2.id, sellOrder3.id] + ); + testHelpers.logGasUse(this, tx, "matchMultipleOrders"); + + // await exchangeTestHelper.printOrderBook(10); + + const stateAfter = await exchangeTestHelper.getState(); + assert.equal(stateAfter.sellCount, 0, "Sell token order count should be 0"); + assert.equal(stateAfter.buyCount, 2, "Buy token order count should be 2"); + + await testHelpers.assertEvent(exchange, "OrderFill", [ + { + sellTokenOrderId: sellOrder1.id, + buyTokenOrderId: buyOrder1.id, + tokenSeller: taker, + tokenBuyer: maker, + publishedRate: () => {}, // ignore, not testing it here, + price: makerPrice, + weiAmount: () => {}, // ignore, not testing it here + tokenAmount: tokenAmount + }, + { + sellTokenOrderId: sellOrder2.id, + buyTokenOrderId: buyOrder2.id, + tokenSeller: taker, + tokenBuyer: maker, + publishedRate: () => {}, // ignore, not testing it here, + price: makerPrice, + weiAmount: () => {}, // ignore, not testing it here + tokenAmount: tokenAmount + }, + { + sellTokenOrderId: sellOrder3.id, + buyTokenOrderId: buyOrder1.id, + tokenSeller: taker, + tokenBuyer: maker, + publishedRate: () => {}, // ignore, not testing it here, + price: makerPrice, + weiAmount: () => {}, // ignore, not testing it here + tokenAmount: tokenAmount + } + ]); + }); + + // ensure edge cases of passing the same order twice + it("matchMultipleOrders should match as many orders as fits into gas provided", async function() { + const makerPrice = 1010000; + const tokenAmount = 10000; + const buyOrder = { + amount: global.web3v1.utils.toWei("10"), + maker: maker, + price: makerPrice, + orderType: TOKEN_BUY + }; + + const sellOrder1 = { + amount: tokenAmount, + maker: taker, + price: 990000, + orderType: TOKEN_SELL + }; + const sellOrder2 = Object.assign({}, sellOrder1); + const sellOrder3 = Object.assign({}, sellOrder1); + const sellOrder4 = Object.assign({}, sellOrder1); + + await exchangeTestHelper.newOrder(this, buyOrder); + await exchangeTestHelper.newOrder(this, sellOrder1), + await exchangeTestHelper.newOrder(this, sellOrder2), + await exchangeTestHelper.newOrder(this, sellOrder3); + await exchangeTestHelper.newOrder(this, sellOrder4); + + // await exchangeTestHelper.printOrderBook(10); + + const tx = await exchange.matchMultipleOrders( + [buyOrder.id, buyOrder.id, buyOrder.id, buyOrder.id], + [sellOrder1.id, sellOrder2.id, sellOrder3.id, sellOrder4.id], + { gas: 300000 } + ); + + testHelpers.logGasUse(this, tx, "matchMultipleOrders"); + + // await exchangeTestHelper.printOrderBook(10); + + await testHelpers.assertEvent(exchange, "OrderFill", [ + { + sellTokenOrderId: sellOrder1.id, + buyTokenOrderId: buyOrder.id, + tokenSeller: taker, + tokenBuyer: maker, + publishedRate: () => {}, // ignore, not testing it here, + price: makerPrice, + weiAmount: () => {}, // ignore, not testing it here + tokenAmount: tokenAmount + }, + { + sellTokenOrderId: sellOrder2.id, + buyTokenOrderId: buyOrder.id, + tokenSeller: taker, + tokenBuyer: maker, + publishedRate: () => {}, // ignore, not testing it here, + price: makerPrice, + weiAmount: () => {}, // ignore, not testing it here + tokenAmount: tokenAmount + }, + { + sellTokenOrderId: sellOrder3.id, + buyTokenOrderId: buyOrder.id, + tokenSeller: taker, + tokenBuyer: maker, + publishedRate: () => {}, // ignore, not testing it here, + price: makerPrice, + weiAmount: () => {}, // ignore, not testing it here + tokenAmount: tokenAmount + } + ]); + + const stateAfter = await exchangeTestHelper.getState(); + assert.equal(stateAfter.sellCount, 1, "Sell token order count should be 1"); // 1 didn't have enough gas + assert.equal(stateAfter.buyCount, 1, "Buy token order count should be 1"); + }); + + it("matchMultipleOrders should carry on if one is duplicate, non-matching or removed", async function() { + const makerPrice = 1010000; + const tokenAmount = 10000; + const buyOrder = { + amount: global.web3v1.utils.toWei("10"), + maker: maker, + price: makerPrice, + orderType: TOKEN_BUY + }; + const sellOrder1 = { + amount: tokenAmount, + maker: taker, + price: 990000, + orderType: TOKEN_SELL + }; + const sellOrder2Cancelled = Object.assign({}, sellOrder1); + const sellOrder3 = Object.assign({}, sellOrder1); + const sellOrder4Matched = Object.assign({}, sellOrder1); + + await exchangeTestHelper.newOrder(this, buyOrder); + await exchangeTestHelper.newOrder(this, sellOrder1), + await exchangeTestHelper.newOrder(this, sellOrder2Cancelled), + await exchangeTestHelper.newOrder(this, sellOrder3); + await exchangeTestHelper.newOrder(this, sellOrder4Matched); + + await Promise.all([ + exchange.cancelSellTokenOrder(sellOrder2Cancelled.id, { from: sellOrder2Cancelled.maker }), + exchange.matchOrders(buyOrder.id, sellOrder4Matched.id) + ]); + + // await exchangeTestHelper.printOrderBook(10); + + const tx = await exchange.matchMultipleOrders( + [buyOrder.id, buyOrder.id, buyOrder.id, buyOrder.id, buyOrder.id, buyOrder.id], + [sellOrder1.id, sellOrder2Cancelled.id, sellOrder3.id, sellOrder4Matched.id, sellOrder3.id, sellOrder1.id], + { gas: 300000 } + ); + + testHelpers.logGasUse(this, tx, "matchMultipleOrders"); + + // await exchangeTestHelper.printOrderBook(10); + + await testHelpers.assertEvent(exchange, "OrderFill", [ + { + sellTokenOrderId: sellOrder1.id, + buyTokenOrderId: buyOrder.id, + tokenSeller: taker, + tokenBuyer: maker, + publishedRate: () => {}, // ignore, not testing it here, + price: makerPrice, + weiAmount: () => {}, // ignore, not testing it here + tokenAmount: tokenAmount + }, + + { + sellTokenOrderId: sellOrder3.id, + buyTokenOrderId: buyOrder.id, + tokenSeller: taker, + tokenBuyer: maker, + publishedRate: () => {}, // ignore, not testing it here, + price: makerPrice, + weiAmount: () => {}, // ignore, not testing it here + tokenAmount: tokenAmount + } + ]); + + const stateAfter = await exchangeTestHelper.getState(); + assert.equal(stateAfter.sellCount, 0, "Sell token order count should be 1"); + assert.equal(stateAfter.buyCount, 1, "Buy token order count should be 1"); + }); +}); diff --git a/test/exchangeMatching.js b/test/exchangeMatching.js index b1d0e787..11a3d2cc 100644 --- a/test/exchangeMatching.js +++ b/test/exchangeMatching.js @@ -246,10 +246,4 @@ contract("Exchange matching tests", () => { await testHelpers.expectThrow(exchange.matchMultipleOrders([buyOrder1.id], [sellOrder1.id, sellOrder2.id])); }); - - it("should match multiple orders"); // ensure edge cases of passing the same order twice - it("matchMultipleOrders should match as many orders as fits into gas provided"); - it("matchMultipleOrders should stop if one is non-matching"); - it("matchMultipleOrders should stop if one of the orders removed"); - it("matchMultipleOrders should stop if one of the orders filled"); });