Merge pull request #568 from 0xProject/bug/0x.js/trade-simulator-trading-zrx
Execute Taker side in trade simulation
This commit is contained in:
		@@ -5,6 +5,7 @@ import * as _ from 'lodash';
 | 
				
			|||||||
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
 | 
					import { TokenWrapper } from '../contract_wrappers/token_wrapper';
 | 
				
			||||||
import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
 | 
					import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
 | 
				
			||||||
import { ExchangeContractErrs, TradeSide, TransferType } from '../types';
 | 
					import { ExchangeContractErrs, TradeSide, TransferType } from '../types';
 | 
				
			||||||
 | 
					import { constants } from '../utils/constants';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum FailureReason {
 | 
					enum FailureReason {
 | 
				
			||||||
    Balance = 'balance',
 | 
					    Balance = 'balance',
 | 
				
			||||||
@@ -66,6 +67,13 @@ export class ExchangeTransferSimulator {
 | 
				
			|||||||
        tradeSide: TradeSide,
 | 
					        tradeSide: TradeSide,
 | 
				
			||||||
        transferType: TransferType,
 | 
					        transferType: TransferType,
 | 
				
			||||||
    ): Promise<void> {
 | 
					    ): Promise<void> {
 | 
				
			||||||
 | 
					        // HACK: When simulating an open order (e.g taker is NULL_ADDRESS), we don't want to adjust balances/
 | 
				
			||||||
 | 
					        // allowances for the taker. We do however, want to increase the balance of the maker since the maker
 | 
				
			||||||
 | 
					        // might be relying on those funds to fill subsequent orders or pay the order's fees.
 | 
				
			||||||
 | 
					        if (from === constants.NULL_ADDRESS && tradeSide === TradeSide.Taker) {
 | 
				
			||||||
 | 
					            await this._increaseBalanceAsync(tokenAddress, to, amountInBaseUnits);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        const balance = await this._store.getBalanceAsync(tokenAddress, from);
 | 
					        const balance = await this._store.getBalanceAsync(tokenAddress, from);
 | 
				
			||||||
        const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, from);
 | 
					        const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, from);
 | 
				
			||||||
        if (proxyAllowance.lessThan(amountInBaseUnits)) {
 | 
					        if (proxyAllowance.lessThan(amountInBaseUnits)) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -124,31 +124,12 @@ export class OrderValidationUtils {
 | 
				
			|||||||
        if (!_.isUndefined(expectedFillTakerTokenAmount)) {
 | 
					        if (!_.isUndefined(expectedFillTakerTokenAmount)) {
 | 
				
			||||||
            fillTakerTokenAmount = expectedFillTakerTokenAmount;
 | 
					            fillTakerTokenAmount = expectedFillTakerTokenAmount;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        const fillMakerTokenAmount = OrderValidationUtils._getPartialAmount(
 | 
					        await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
 | 
				
			||||||
 | 
					            exchangeTradeEmulator,
 | 
				
			||||||
 | 
					            signedOrder,
 | 
				
			||||||
            fillTakerTokenAmount,
 | 
					            fillTakerTokenAmount,
 | 
				
			||||||
            signedOrder.takerTokenAmount,
 | 
					 | 
				
			||||||
            signedOrder.makerTokenAmount,
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        await exchangeTradeEmulator.transferFromAsync(
 | 
					 | 
				
			||||||
            signedOrder.makerTokenAddress,
 | 
					 | 
				
			||||||
            signedOrder.maker,
 | 
					 | 
				
			||||||
            signedOrder.taker,
 | 
					            signedOrder.taker,
 | 
				
			||||||
            fillMakerTokenAmount,
 | 
					 | 
				
			||||||
            TradeSide.Maker,
 | 
					 | 
				
			||||||
            TransferType.Trade,
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        const makerFeeAmount = OrderValidationUtils._getPartialAmount(
 | 
					 | 
				
			||||||
            fillTakerTokenAmount,
 | 
					 | 
				
			||||||
            signedOrder.takerTokenAmount,
 | 
					 | 
				
			||||||
            signedOrder.makerFee,
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        await exchangeTradeEmulator.transferFromAsync(
 | 
					 | 
				
			||||||
            zrxTokenAddress,
 | 
					            zrxTokenAddress,
 | 
				
			||||||
            signedOrder.maker,
 | 
					 | 
				
			||||||
            signedOrder.feeRecipient,
 | 
					 | 
				
			||||||
            makerFeeAmount,
 | 
					 | 
				
			||||||
            TradeSide.Maker,
 | 
					 | 
				
			||||||
            TransferType.Fee,
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async validateFillOrderThrowIfInvalidAsync(
 | 
					    public async validateFillOrderThrowIfInvalidAsync(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,6 +68,40 @@ describe('OrderValidation', () => {
 | 
				
			|||||||
            );
 | 
					            );
 | 
				
			||||||
            await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
 | 
					            await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					        it('should succeed if the maker is buying ZRX and has no ZRX balance', async () => {
 | 
				
			||||||
 | 
					            const makerFee = new BigNumber(2);
 | 
				
			||||||
 | 
					            const takerFee = new BigNumber(2);
 | 
				
			||||||
 | 
					            const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
 | 
				
			||||||
 | 
					                makerTokenAddress,
 | 
				
			||||||
 | 
					                zrxTokenAddress,
 | 
				
			||||||
 | 
					                makerFee,
 | 
				
			||||||
 | 
					                takerFee,
 | 
				
			||||||
 | 
					                makerAddress,
 | 
				
			||||||
 | 
					                takerAddress,
 | 
				
			||||||
 | 
					                fillableAmount,
 | 
				
			||||||
 | 
					                feeRecipient,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            const zrxMakerBalance = await zeroEx.token.getBalanceAsync(zrxTokenAddress, makerAddress);
 | 
				
			||||||
 | 
					            await zeroEx.token.transferAsync(zrxTokenAddress, makerAddress, takerAddress, zrxMakerBalance);
 | 
				
			||||||
 | 
					            await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it('should succeed if the maker is buying ZRX and has no ZRX balance and there is no specified taker', async () => {
 | 
				
			||||||
 | 
					            const makerFee = new BigNumber(2);
 | 
				
			||||||
 | 
					            const takerFee = new BigNumber(2);
 | 
				
			||||||
 | 
					            const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
 | 
				
			||||||
 | 
					                makerTokenAddress,
 | 
				
			||||||
 | 
					                zrxTokenAddress,
 | 
				
			||||||
 | 
					                makerFee,
 | 
				
			||||||
 | 
					                takerFee,
 | 
				
			||||||
 | 
					                makerAddress,
 | 
				
			||||||
 | 
					                constants.NULL_ADDRESS,
 | 
				
			||||||
 | 
					                fillableAmount,
 | 
				
			||||||
 | 
					                feeRecipient,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            const zrxMakerBalance = await zeroEx.token.getBalanceAsync(zrxTokenAddress, makerAddress);
 | 
				
			||||||
 | 
					            await zeroEx.token.transferAsync(zrxTokenAddress, makerAddress, takerAddress, zrxMakerBalance);
 | 
				
			||||||
 | 
					            await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
        it('should succeed if the order is asymmetric and fillable', async () => {
 | 
					        it('should succeed if the order is asymmetric and fillable', async () => {
 | 
				
			||||||
            const makerFillableAmount = fillableAmount;
 | 
					            const makerFillableAmount = fillableAmount;
 | 
				
			||||||
            const takerFillableAmount = fillableAmount.minus(4);
 | 
					            const takerFillableAmount = fillableAmount.minus(4);
 | 
				
			||||||
@@ -469,4 +503,4 @@ describe('OrderValidation', () => {
 | 
				
			|||||||
            expect(partialTakerFee).to.be.bignumber.equal(takerPartialFee);
 | 
					            expect(partialTakerFee).to.be.bignumber.equal(takerPartialFee);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
});
 | 
					}); // tslint:disable-line:max-file-line-count
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user