aboutsummaryrefslogtreecommitdiffstats
path: root/test/order_validation_test.ts
diff options
context:
space:
mode:
Diffstat (limited to 'test/order_validation_test.ts')
-rw-r--r--test/order_validation_test.ts327
1 files changed, 0 insertions, 327 deletions
diff --git a/test/order_validation_test.ts b/test/order_validation_test.ts
deleted file mode 100644
index 4f18742d3..000000000
--- a/test/order_validation_test.ts
+++ /dev/null
@@ -1,327 +0,0 @@
-import * as chai from 'chai';
-import * as Web3 from 'web3';
-import BigNumber from 'bignumber.js';
-import * as Sinon from 'sinon';
-import {chaiSetup} from './utils/chai_setup';
-import {web3Factory} from './utils/web3_factory';
-import {ZeroEx, SignedOrder, Token, ExchangeContractErrs, ZeroExError} from '../src';
-import {TradeSide, TransferType} from '../src/types';
-import {TokenUtils} from './utils/token_utils';
-import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
-import {FillScenarios} from './utils/fill_scenarios';
-import {OrderValidationUtils} from '../src/utils/order_validation_utils';
-import {ExchangeTransferSimulator} from '../src/utils/exchange_transfer_simulator';
-
-chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle();
-
-describe('OrderValidation', () => {
- let web3: Web3;
- let zeroEx: ZeroEx;
- let userAddresses: string[];
- let tokens: Token[];
- let tokenUtils: TokenUtils;
- let exchangeContractAddress: string;
- let zrxTokenAddress: string;
- let fillScenarios: FillScenarios;
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let coinbase: string;
- let makerAddress: string;
- let takerAddress: string;
- let feeRecipient: string;
- let orderValidationUtils: OrderValidationUtils;
- const fillableAmount = new BigNumber(5);
- const fillTakerAmount = new BigNumber(5);
- before(async () => {
- web3 = web3Factory.create();
- zeroEx = new ZeroEx(web3.currentProvider);
- exchangeContractAddress = await zeroEx.exchange.getContractAddressAsync();
- userAddresses = await zeroEx.getAvailableAddressesAsync();
- [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
- tokens = await zeroEx.tokenRegistry.getTokensAsync();
- tokenUtils = new TokenUtils(tokens);
- zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
- fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
- const [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- orderValidationUtils = new OrderValidationUtils(zeroEx.token, zeroEx.exchange);
- });
- beforeEach(async () => {
- await blockchainLifecycle.startAsync();
- });
- afterEach(async () => {
- await blockchainLifecycle.revertAsync();
- });
- describe('validateOrderFillableOrThrowAsync', () => {
- it('should succeed if the order is fillable', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
- );
- await zeroEx.exchange.validateOrderFillableOrThrowAsync(
- signedOrder,
- );
- });
- it('should succeed if the order is asymmetric and fillable', async () => {
- const makerFillableAmount = fillableAmount;
- const takerFillableAmount = fillableAmount.minus(4);
- const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
- makerFillableAmount, takerFillableAmount,
- );
- await zeroEx.exchange.validateOrderFillableOrThrowAsync(
- signedOrder,
- );
- });
- it('should throw when the order is fully filled or cancelled', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
- );
- await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
- return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(
- signedOrder,
- )).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
- });
- it('should throw when order is expired', async () => {
- const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
- fillableAmount, expirationInPast,
- );
- return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(
- signedOrder,
- )).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
- });
- });
- describe('validateFillOrderAndThrowIfInvalidAsync', () => {
- it('should throw when the fill amount is zero', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
- );
- const zeroFillAmount = new BigNumber(0);
- return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder, zeroFillAmount, takerAddress,
- )).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should throw when the signature is invalid', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
- );
- // 27 <--> 28
- signedOrder.ecSignature.v = 27 + (28 - signedOrder.ecSignature.v);
- return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder, fillableAmount, takerAddress,
- )).to.be.rejectedWith(ZeroExError.InvalidSignature);
- });
- it('should throw when the order is fully filled or cancelled', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
- );
- await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
- return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder, fillableAmount, takerAddress,
- )).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
- });
- it('should throw when sender is not a taker', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
- );
- const nonTakerAddress = userAddresses[6];
- return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder, fillTakerAmount, nonTakerAddress,
- )).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
- });
- it('should throw when order is expired', async () => {
- const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
- fillableAmount, expirationInPast,
- );
- return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder, fillTakerAmount, takerAddress,
- )).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
- });
- it('should throw when there a rounding error would have occurred', async () => {
- const makerAmount = new BigNumber(3);
- const takerAmount = new BigNumber(5);
- const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
- makerAmount, takerAmount,
- );
- const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
- return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder, fillTakerAmountThatCausesRoundingError, takerAddress,
- )).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
- });
- });
- describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => {
- it('should throw if remaining fillAmount is less then the desired fillAmount', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
- );
- const tooLargeFillAmount = new BigNumber(7);
- const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
- await zeroEx.token.transferAsync(takerTokenAddress, coinbase, takerAddress, fillAmountDifference);
- await zeroEx.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, tooLargeFillAmount);
- await zeroEx.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
- await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
-
- return expect(zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
- signedOrder, tooLargeFillAmount, takerAddress,
- )).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
- });
- });
- describe('validateCancelOrderAndThrowIfInvalidAsync', () => {
- let signedOrder: SignedOrder;
- let orderHashHex: string;
- const cancelAmount = new BigNumber(3);
- beforeEach(async () => {
- [coinbase, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
- );
- orderHashHex = ZeroEx.getOrderHashHex(signedOrder);
- });
- it('should throw when cancel amount is zero', async () => {
- const zeroCancelAmount = new BigNumber(0);
- return expect(zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount))
- .to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
- });
- it('should throw when order is expired', async () => {
- const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
- const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
- fillableAmount, expirationInPast,
- );
- orderHashHex = ZeroEx.getOrderHashHex(expiredSignedOrder);
- return expect(zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount))
- .to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
- });
- it('should throw when order is already cancelled or filled', async () => {
- await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
- return expect(zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount))
- .to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
- });
- });
- describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => {
- let exchangeTransferSimulator: ExchangeTransferSimulator;
- let transferFromAsync: Sinon.SinonSpy;
- const bigNumberMatch = (expected: BigNumber) => {
- return Sinon.match((value: BigNumber) => value.eq(expected));
- };
- beforeEach('create exchangeTransferSimulator', async () => {
- exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token);
- transferFromAsync = Sinon.spy();
- exchangeTransferSimulator.transferFromAsync = transferFromAsync as any;
- });
- it('should call exchangeTransferSimulator.transferFrom in a correct order', async () => {
- const makerFee = new BigNumber(2);
- const takerFee = new BigNumber(2);
- const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerTokenAddress, takerTokenAddress, makerFee, takerFee,
- makerAddress, takerAddress, fillableAmount, feeRecipient,
- );
- await orderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
- exchangeTransferSimulator, signedOrder, fillableAmount, takerAddress, zrxTokenAddress,
- );
- expect(transferFromAsync.callCount).to.be.equal(4);
- expect(
- transferFromAsync.getCall(0).calledWith(
- makerTokenAddress, makerAddress, takerAddress, bigNumberMatch(fillableAmount),
- TradeSide.Maker, TransferType.Trade,
- ),
- ).to.be.true();
- expect(
- transferFromAsync.getCall(1).calledWith(
- takerTokenAddress, takerAddress, makerAddress, bigNumberMatch(fillableAmount),
- TradeSide.Taker, TransferType.Trade,
- ),
- ).to.be.true();
- expect(
- transferFromAsync.getCall(2).calledWith(
- zrxTokenAddress, makerAddress, feeRecipient, bigNumberMatch(makerFee),
- TradeSide.Maker, TransferType.Fee,
- ),
- ).to.be.true();
- expect(
- transferFromAsync.getCall(3).calledWith(
- zrxTokenAddress, takerAddress, feeRecipient, bigNumberMatch(takerFee),
- TradeSide.Taker, TransferType.Fee,
- ),
- ).to.be.true();
- });
- it('should call exchangeTransferSimulator.transferFrom with correct values for an open order', async () => {
- const makerFee = new BigNumber(2);
- const takerFee = new BigNumber(2);
- const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerTokenAddress, takerTokenAddress, makerFee, takerFee,
- makerAddress, ZeroEx.NULL_ADDRESS, fillableAmount, feeRecipient,
- );
- await orderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
- exchangeTransferSimulator, signedOrder, fillableAmount, takerAddress, zrxTokenAddress,
- );
- expect(transferFromAsync.callCount).to.be.equal(4);
- expect(
- transferFromAsync.getCall(0).calledWith(
- makerTokenAddress, makerAddress, takerAddress, bigNumberMatch(fillableAmount),
- TradeSide.Maker, TransferType.Trade,
- ),
- ).to.be.true();
- expect(
- transferFromAsync.getCall(1).calledWith(
- takerTokenAddress, takerAddress, makerAddress, bigNumberMatch(fillableAmount),
- TradeSide.Taker, TransferType.Trade,
- ),
- ).to.be.true();
- expect(
- transferFromAsync.getCall(2).calledWith(
- zrxTokenAddress, makerAddress, feeRecipient, bigNumberMatch(makerFee),
- TradeSide.Maker, TransferType.Fee,
- ),
- ).to.be.true();
- expect(
- transferFromAsync.getCall(3).calledWith(
- zrxTokenAddress, takerAddress, feeRecipient, bigNumberMatch(takerFee),
- TradeSide.Taker, TransferType.Fee,
- ),
- ).to.be.true();
- });
- it('should correctly round the fillMakerTokenAmount', async () => {
- const makerTokenAmount = new BigNumber(3);
- const takerTokenAmount = new BigNumber(1);
- const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
- makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, makerTokenAmount, takerTokenAmount,
- );
- await orderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
- exchangeTransferSimulator, signedOrder, takerTokenAmount, takerAddress, zrxTokenAddress,
- );
- expect(transferFromAsync.callCount).to.be.equal(4);
- const makerFillAmount = transferFromAsync.getCall(0).args[3];
- expect(makerFillAmount).to.be.bignumber.equal(makerTokenAmount);
- });
- it('should correctly round the makerFeeAmount', async () => {
- const makerFee = new BigNumber(2);
- const takerFee = new BigNumber(4);
- const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress,
- fillableAmount, ZeroEx.NULL_ADDRESS,
- );
- const fillTakerTokenAmount = fillableAmount.div(2).round(0);
- await orderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
- exchangeTransferSimulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress,
- );
- const makerPartialFee = makerFee.div(2);
- const takerPartialFee = takerFee.div(2);
- expect(transferFromAsync.callCount).to.be.equal(4);
- const partialMakerFee = transferFromAsync.getCall(2).args[3];
- expect(partialMakerFee).to.be.bignumber.equal(makerPartialFee);
- const partialTakerFee = transferFromAsync.getCall(3).args[3];
- expect(partialTakerFee).to.be.bignumber.equal(takerPartialFee);
- });
- });
-});