Add validateOrderFillableThrowIfNotFillableAsync to public methods in order to validate orders in an orderbook without a specific taker in mind

This commit is contained in:
Fabio Berger
2017-09-26 11:01:33 +02:00
parent 0a19a7e8d1
commit 5e92ca039c
3 changed files with 50 additions and 0 deletions

View File

@@ -28,6 +28,7 @@ import {
LogCancelContractEventArgs,
LogWithDecodedArgs,
MethodOpts,
ValidateOrderFillableOpts,
} from '../types';
import {assert} from '../utils/assert';
import {utils} from '../utils/utils';
@@ -623,6 +624,24 @@ export class ExchangeWrapper extends ContractWrapper {
const exchangeAddress = exchangeInstance.address;
return exchangeAddress;
}
/**
* Checks if order is still fillable and throws an error otherwise.
* @param signedOrder An object that conforms to the SignedOrder interface. The
* signedOrder you wish to validate.
* @param opts An object that conforms to the ValidateOrderFillableOpts
* interface. Allows specifying a specific fillTakerTokenAmount
* to validate for.
*/
public async validateOrderFillableThrowIfNotFillableAsync(
signedOrder: SignedOrder, opts: ValidateOrderFillableOpts,
): Promise<void> {
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
const zrxTokenAddress = await this._getZRXTokenAddressAsync();
const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined;
await this._orderValidationUtils.validateOrderFillableThrowIfNotFillableAsync(
signedOrder, zrxTokenAddress, expectedFillTakerTokenAmount,
);
}
/**
* Checks if order fill will succeed and throws an error otherwise.
* @param signedOrder An object that conforms to the SignedOrder interface. The

View File

@@ -433,6 +433,16 @@ export interface Artifact {
}};
}
/*
* expectedFillTakerTokenAmount: If specified, the validation method will ensure that the
* supplied order's maker has a sufficient allowance/balance to fill this amount of the order's
* takerTokenAmount. If not specified, the validation method ensures that the maker has a sufficient
* allowance/balance to fill the entire remaining order.
*/
export interface ValidateOrderFillableOpts {
expectedFillTakerTokenAmount?: BigNumber.BigNumber;
}
/*
* defaultBlock: The block up to which to query the blockchain state. Setting this to a historical block number
* let's the user query the blockchain's state at an arbitrary point in time. In order for this to work, the

View File

@@ -1,3 +1,4 @@
import * as _ from 'lodash';
import {ExchangeContractErrs, SignedOrder, Order, ZeroExError} from '../types';
import {ZeroEx} from '../0x';
import {TokenWrapper} from '../contract_wrappers/token_wrapper';
@@ -12,6 +13,26 @@ export class OrderValidationUtils {
this.tokenWrapper = tokenWrapper;
this.exchangeWrapper = exchangeWrapper;
}
public async validateOrderFillableThrowIfNotFillableAsync(
signedOrder: SignedOrder, zrxTokenAddress: string, expectedFillTakerTokenAmount?: BigNumber.BigNumber,
): Promise<void> {
const orderHash = utils.getOrderHashHex(signedOrder);
const unavailableTakerTokenAmount = await this.exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
if (signedOrder.makerTokenAmount.eq(unavailableTakerTokenAmount)) {
throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
}
const currentUnixTimestampSec = utils.getCurrentUnixTimestamp();
if (signedOrder.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
throw new Error(ExchangeContractErrs.OrderFillExpired);
}
let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
if (!_.isUndefined(expectedFillTakerTokenAmount)) {
fillTakerTokenAmount = expectedFillTakerTokenAmount;
}
await this.validateFillOrderMakerBalancesAllowancesThrowIfInvalidAsync(
signedOrder, fillTakerTokenAmount, zrxTokenAddress,
);
}
public async validateFillOrderThrowIfInvalidAsync(signedOrder: SignedOrder,
fillTakerTokenAmount: BigNumber.BigNumber,
takerAddress: string,