Execute taker side in trade simulation

Fill if the taker address is open
This commit is contained in:
Jacob Evans
2018-04-30 18:05:45 +10:00
parent 47604384d4
commit b36587fac8
3 changed files with 44 additions and 23 deletions

View File

@@ -5,6 +5,7 @@ import * as _ from 'lodash';
import { TokenWrapper } from '../contract_wrappers/token_wrapper';
import { BalanceAndProxyAllowanceLazyStore } from '../stores/balance_proxy_allowance_lazy_store';
import { ExchangeContractErrs, TradeSide, TransferType } from '../types';
import { constants } from '../utils/constants';
enum FailureReason {
Balance = 'balance',
@@ -66,6 +67,11 @@ export class ExchangeTransferSimulator {
tradeSide: TradeSide,
transferType: TransferType,
): Promise<void> {
// If we are simulating an open order then 0x0 will have no balance or allowance
if (from === constants.NULL_ADDRESS && tradeSide === TradeSide.Taker) {
await this._increaseBalanceAsync(tokenAddress, to, amountInBaseUnits);
return;
}
const balance = await this._store.getBalanceAsync(tokenAddress, from);
const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, from);
if (proxyAllowance.lessThan(amountInBaseUnits)) {

View File

@@ -124,31 +124,12 @@ export class OrderValidationUtils {
if (!_.isUndefined(expectedFillTakerTokenAmount)) {
fillTakerTokenAmount = expectedFillTakerTokenAmount;
}
const fillMakerTokenAmount = OrderValidationUtils._getPartialAmount(
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
exchangeTradeEmulator,
signedOrder,
fillTakerTokenAmount,
signedOrder.takerTokenAmount,
signedOrder.makerTokenAmount,
);
await exchangeTradeEmulator.transferFromAsync(
signedOrder.makerTokenAddress,
signedOrder.maker,
signedOrder.taker,
fillMakerTokenAmount,
TradeSide.Maker,
TransferType.Trade,
);
const makerFeeAmount = OrderValidationUtils._getPartialAmount(
fillTakerTokenAmount,
signedOrder.takerTokenAmount,
signedOrder.makerFee,
);
await exchangeTradeEmulator.transferFromAsync(
zrxTokenAddress,
signedOrder.maker,
signedOrder.feeRecipient,
makerFeeAmount,
TradeSide.Maker,
TransferType.Fee,
);
}
public async validateFillOrderThrowIfInvalidAsync(

View File

@@ -68,6 +68,40 @@ describe('OrderValidation', () => {
);
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 () => {
const makerFillableAmount = fillableAmount;
const takerFillableAmount = fillableAmount.minus(4);
@@ -469,4 +503,4 @@ describe('OrderValidation', () => {
expect(partialTakerFee).to.be.bignumber.equal(takerPartialFee);
});
});
});
}); // tslint:disable-line:max-file-line-count