Add test when the order was already cancelled or filled
This commit is contained in:
parent
fa910bca0e
commit
42b4952693
@ -42,6 +42,24 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
private exchangeContractIfExists?: ExchangeContract;
|
private exchangeContractIfExists?: ExchangeContract;
|
||||||
private exchangeLogEventObjs: ContractEventObj[];
|
private exchangeLogEventObjs: ContractEventObj[];
|
||||||
private tokenWrapper: TokenWrapper;
|
private tokenWrapper: TokenWrapper;
|
||||||
|
private static getOrderAddressesAndValues(order: Order): [OrderAddresses, OrderValues] {
|
||||||
|
const orderAddresses: OrderAddresses = [
|
||||||
|
order.maker,
|
||||||
|
order.taker,
|
||||||
|
order.makerTokenAddress,
|
||||||
|
order.takerTokenAddress,
|
||||||
|
order.feeRecipient,
|
||||||
|
];
|
||||||
|
const orderValues: OrderValues = [
|
||||||
|
order.makerTokenAmount,
|
||||||
|
order.takerTokenAmount,
|
||||||
|
order.makerFee,
|
||||||
|
order.takerFee,
|
||||||
|
order.expirationUnixTimestampSec,
|
||||||
|
order.salt,
|
||||||
|
];
|
||||||
|
return [orderAddresses, orderValues];
|
||||||
|
}
|
||||||
constructor(web3Wrapper: Web3Wrapper, tokenWrapper: TokenWrapper) {
|
constructor(web3Wrapper: Web3Wrapper, tokenWrapper: TokenWrapper) {
|
||||||
super(web3Wrapper);
|
super(web3Wrapper);
|
||||||
this.tokenWrapper = tokenWrapper;
|
this.tokenWrapper = tokenWrapper;
|
||||||
@ -126,21 +144,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
const exchangeInstance = await this.getExchangeContractAsync();
|
const exchangeInstance = await this.getExchangeContractAsync();
|
||||||
await this.validateFillOrderAndThrowIfInvalidAsync(signedOrder, fillTakerAmount, takerAddress);
|
await this.validateFillOrderAndThrowIfInvalidAsync(signedOrder, fillTakerAmount, takerAddress);
|
||||||
|
|
||||||
const orderAddresses: OrderAddresses = [
|
const [orderAddresses, orderValues] = ExchangeWrapper.getOrderAddressesAndValues(signedOrder);
|
||||||
signedOrder.maker,
|
|
||||||
signedOrder.taker,
|
|
||||||
signedOrder.makerTokenAddress,
|
|
||||||
signedOrder.takerTokenAddress,
|
|
||||||
signedOrder.feeRecipient,
|
|
||||||
];
|
|
||||||
const orderValues: OrderValues = [
|
|
||||||
signedOrder.makerTokenAmount,
|
|
||||||
signedOrder.takerTokenAmount,
|
|
||||||
signedOrder.makerFee,
|
|
||||||
signedOrder.takerFee,
|
|
||||||
signedOrder.expirationUnixTimestampSec,
|
|
||||||
signedOrder.salt,
|
|
||||||
];
|
|
||||||
const gas = await exchangeInstance.fill.estimateGas(
|
const gas = await exchangeInstance.fill.estimateGas(
|
||||||
orderAddresses,
|
orderAddresses,
|
||||||
orderValues,
|
orderValues,
|
||||||
@ -181,21 +185,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
const exchangeInstance = await this.getExchangeContractAsync();
|
const exchangeInstance = await this.getExchangeContractAsync();
|
||||||
await this.validateCancelOrderAndThrowIfInvalidAsync(order, cancelAmount);
|
await this.validateCancelOrderAndThrowIfInvalidAsync(order, cancelAmount);
|
||||||
|
|
||||||
const orderAddresses: OrderAddresses = [
|
const [orderAddresses, orderValues] = ExchangeWrapper.getOrderAddressesAndValues(order);
|
||||||
order.maker,
|
|
||||||
order.taker,
|
|
||||||
order.makerTokenAddress,
|
|
||||||
order.takerTokenAddress,
|
|
||||||
order.feeRecipient,
|
|
||||||
];
|
|
||||||
const orderValues: OrderValues = [
|
|
||||||
order.makerTokenAmount,
|
|
||||||
order.takerTokenAmount,
|
|
||||||
order.makerFee,
|
|
||||||
order.takerFee,
|
|
||||||
order.expirationUnixTimestampSec,
|
|
||||||
order.salt,
|
|
||||||
];
|
|
||||||
const gas = await exchangeInstance.cancel.estimateGas(
|
const gas = await exchangeInstance.cancel.estimateGas(
|
||||||
orderAddresses,
|
orderAddresses,
|
||||||
orderValues,
|
orderValues,
|
||||||
@ -241,6 +231,16 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
logEventObj.watch(callback);
|
logEventObj.watch(callback);
|
||||||
this.exchangeLogEventObjs.push(logEventObj);
|
this.exchangeLogEventObjs.push(logEventObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get order hash
|
||||||
|
*/
|
||||||
|
public async getOrderHashAsync(order: Order): Promise<string> {
|
||||||
|
const [orderAddresses, orderValues] = ExchangeWrapper.getOrderAddressesAndValues(order);
|
||||||
|
const exchangeInstance = await this.getExchangeContractAsync();
|
||||||
|
const orderHash = await exchangeInstance.getOrderHash.call(orderAddresses, orderValues);
|
||||||
|
return orderHash;
|
||||||
|
}
|
||||||
private async stopWatchingExchangeLogEventsAsync() {
|
private async stopWatchingExchangeLogEventsAsync() {
|
||||||
const stopWatchingPromises = _.map(this.exchangeLogEventObjs, logEventObj => {
|
const stopWatchingPromises = _.map(this.exchangeLogEventObjs, logEventObj => {
|
||||||
return promisify(logEventObj.stopWatching, logEventObj)();
|
return promisify(logEventObj.stopWatching, logEventObj)();
|
||||||
@ -277,12 +277,16 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
if (cancelAmount.eq(0)) {
|
if (cancelAmount.eq(0)) {
|
||||||
throw new Error(ExchangeContractErrs.ORDER_CANCEL_AMOUNT_ZERO);
|
throw new Error(ExchangeContractErrs.ORDER_CANCEL_AMOUNT_ZERO);
|
||||||
}
|
}
|
||||||
|
const orderHash = await this.getOrderHashAsync(order);
|
||||||
|
const unavailableAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
||||||
|
if (order.takerTokenAmount.minus(unavailableAmount).eq(0)) {
|
||||||
|
throw new Error(ExchangeContractErrs.ORDER_ALREADY_CANCELLED_OR_FILLED);
|
||||||
|
}
|
||||||
const currentUnixTimestampSec = Date.now() / 1000;
|
const currentUnixTimestampSec = Date.now() / 1000;
|
||||||
if (order.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
|
if (order.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
|
||||||
throw new Error(ExchangeContractErrs.ORDER_CANCEL_EXPIRED);
|
throw new Error(ExchangeContractErrs.ORDER_CANCEL_EXPIRED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method does not currently validate the edge-case where the makerToken or takerToken is also the token used
|
* This method does not currently validate the edge-case where the makerToken or takerToken is also the token used
|
||||||
* to pay fees (ZRX). It is possible for them to have enough for fees and the transfer but not both.
|
* to pay fees (ZRX). It is possible for them to have enough for fees and the transfer but not both.
|
||||||
|
@ -80,6 +80,9 @@ export interface ExchangeContract {
|
|||||||
cancelled: {
|
cancelled: {
|
||||||
call: (orderHash: string) => BigNumber.BigNumber;
|
call: (orderHash: string) => BigNumber.BigNumber;
|
||||||
};
|
};
|
||||||
|
getOrderHash: {
|
||||||
|
call: (orderAddresses: OrderAddresses, orderValues: OrderValues) => string;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TokenContract {
|
export interface TokenContract {
|
||||||
@ -123,6 +126,7 @@ export const ExchangeContractErrs = strEnum([
|
|||||||
'ORDER_FILL_EXPIRED',
|
'ORDER_FILL_EXPIRED',
|
||||||
'ORDER_CANCEL_EXPIRED',
|
'ORDER_CANCEL_EXPIRED',
|
||||||
'ORDER_CANCEL_AMOUNT_ZERO',
|
'ORDER_CANCEL_AMOUNT_ZERO',
|
||||||
|
'ORDER_ALREADY_CANCELLED_OR_FILLED',
|
||||||
'ORDER_REMAINING_FILL_AMOUNT_ZERO',
|
'ORDER_REMAINING_FILL_AMOUNT_ZERO',
|
||||||
'ORDER_FILL_ROUNDING_ERROR',
|
'ORDER_FILL_ROUNDING_ERROR',
|
||||||
'FILL_BALANCE_ALLOWANCE_ERROR',
|
'FILL_BALANCE_ALLOWANCE_ERROR',
|
||||||
|
@ -358,6 +358,11 @@ describe('ExchangeWrapper', () => {
|
|||||||
return expect(zeroEx.exchange.cancelOrderAsync(expiredSignedOrder, cancelAmount))
|
return expect(zeroEx.exchange.cancelOrderAsync(expiredSignedOrder, cancelAmount))
|
||||||
.to.be.rejectedWith(ExchangeContractErrs.ORDER_CANCEL_EXPIRED);
|
.to.be.rejectedWith(ExchangeContractErrs.ORDER_CANCEL_EXPIRED);
|
||||||
});
|
});
|
||||||
|
it.only('should throw when order is already cancelled or filled', async () => {
|
||||||
|
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
||||||
|
return expect(zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount))
|
||||||
|
.to.be.rejectedWith(ExchangeContractErrs.ORDER_ALREADY_CANCELLED_OR_FILLED);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('successful cancels', () => {
|
describe('successful cancels', () => {
|
||||||
it('should cancel an order', async () => {
|
it('should cancel an order', async () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user