aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonid Logvinov <logvinov.leon@gmail.com>2017-06-07 17:04:42 +0800
committerLeonid Logvinov <logvinov.leon@gmail.com>2017-06-07 17:04:42 +0800
commit9daca6a4be95a87a63e293300d0768e3e63162d2 (patch)
treeffa51a7275532557a6bd5097f1ced3a19b0725d0
parent56dc33f3a6ef0a9ae00d62d816000dab4cfea07f (diff)
downloaddexon-sol-tools-9daca6a4be95a87a63e293300d0768e3e63162d2.tar
dexon-sol-tools-9daca6a4be95a87a63e293300d0768e3e63162d2.tar.gz
dexon-sol-tools-9daca6a4be95a87a63e293300d0768e3e63162d2.tar.bz2
dexon-sol-tools-9daca6a4be95a87a63e293300d0768e3e63162d2.tar.lz
dexon-sol-tools-9daca6a4be95a87a63e293300d0768e3e63162d2.tar.xz
dexon-sol-tools-9daca6a4be95a87a63e293300d0768e3e63162d2.tar.zst
dexon-sol-tools-9daca6a4be95a87a63e293300d0768e3e63162d2.zip
Address feedback
-rw-r--r--src/0x.js.ts28
-rw-r--r--src/contract_wrappers/exchange_wrapper.ts31
-rw-r--r--src/types.ts9
-rw-r--r--src/utils/utils.ts35
-rw-r--r--test/exchange_wrapper_test.ts4
5 files changed, 60 insertions, 47 deletions
diff --git a/src/0x.js.ts b/src/0x.js.ts
index 0f437e039..eb7698bd4 100644
--- a/src/0x.js.ts
+++ b/src/0x.js.ts
@@ -4,21 +4,18 @@ import {bigNumberConfigs} from './bignumber_config';
import * as ethUtil from 'ethereumjs-util';
import contract = require('truffle-contract');
import * as Web3 from 'web3';
-import * as ethABI from 'ethereumjs-abi';
import findVersions = require('find-versions');
import compareVersions = require('compare-versions');
import {Web3Wrapper} from './web3_wrapper';
import {constants} from './utils/constants';
import {utils} from './utils/utils';
import {assert} from './utils/assert';
-import {SchemaValidator} from './utils/schema_validator';
import {ExchangeWrapper} from './contract_wrappers/exchange_wrapper';
import {TokenRegistryWrapper} from './contract_wrappers/token_registry_wrapper';
import {ecSignatureSchema} from './schemas/ec_signature_schema';
import {TokenWrapper} from './contract_wrappers/token_wrapper';
-import {SolidityTypes, ECSignature, ZeroExError} from './types';
+import {ECSignature, ZeroExError} from './types';
import {Order, SignedOrder} from './types';
-import {orderSchema} from './schemas/order_schemas';
import * as ExchangeArtifacts from './artifacts/Exchange.json';
// Customize our BigNumber instances
@@ -133,28 +130,7 @@ export class ZeroEx {
*/
public async getOrderHashHexAsync(order: Order|SignedOrder): Promise<string> {
const exchangeContractAddr = await this.getExchangeAddressAsync();
- assert.doesConformToSchema('order',
- SchemaValidator.convertToJSONSchemaCompatibleObject(order as object),
- orderSchema);
-
- const orderParts = [
- {value: exchangeContractAddr, type: SolidityTypes.address},
- {value: order.maker, type: SolidityTypes.address},
- {value: order.taker, type: SolidityTypes.address},
- {value: order.makerTokenAddress, type: SolidityTypes.address},
- {value: order.takerTokenAddress, type: SolidityTypes.address},
- {value: order.feeRecipient, type: SolidityTypes.address},
- {value: utils.bigNumberToBN(order.makerTokenAmount), type: SolidityTypes.uint256},
- {value: utils.bigNumberToBN(order.takerTokenAmount), type: SolidityTypes.uint256},
- {value: utils.bigNumberToBN(order.makerFee), type: SolidityTypes.uint256},
- {value: utils.bigNumberToBN(order.takerFee), type: SolidityTypes.uint256},
- {value: utils.bigNumberToBN(order.expirationUnixTimestampSec), type: SolidityTypes.uint256},
- {value: utils.bigNumberToBN(order.salt), type: SolidityTypes.uint256},
- ];
- const types = _.map(orderParts, o => o.type);
- const values = _.map(orderParts, o => o.value);
- const hashBuff = ethABI.soliditySHA3(types, values);
- const hashHex = ethUtil.bufferToHex(hashBuff);
+ const hashHex = utils.getOrderHashHex(order, exchangeContractAddr);
return hashHex;
}
/**
diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts
index 4b7bd172f..537eb08a4 100644
--- a/src/contract_wrappers/exchange_wrapper.ts
+++ b/src/contract_wrappers/exchange_wrapper.ts
@@ -25,7 +25,7 @@ import {utils} from '../utils/utils';
import {ContractWrapper} from './contract_wrapper';
import * as ExchangeArtifacts from '../artifacts/Exchange.json';
import {ecSignatureSchema} from '../schemas/ec_signature_schema';
-import {signedOrderSchema} from '../schemas/order_schemas';
+import {signedOrderSchema, orderSchema} from '../schemas/order_schemas';
import {SchemaValidator} from '../utils/schema_validator';
import {constants} from '../utils/constants';
import {TokenWrapper} from './token_wrapper';
@@ -173,23 +173,23 @@ export class ExchangeWrapper extends ContractWrapper {
this.throwErrorLogsAsErrors(response.logs);
}
/**
- * Cancels the order.
+ * Cancel a given fill amount of an order. Cancellations are cumulative.
*/
- public async cancelOrderAsync(order: Order, cancelAmount: BigNumber.BigNumber): Promise<void> {
+ public async cancelOrderAsync(order: Order, takerTokenCancelAmount: BigNumber.BigNumber): Promise<void> {
assert.doesConformToSchema('order',
SchemaValidator.convertToJSONSchemaCompatibleObject(order as object),
- signedOrderSchema);
- assert.isBigNumber('cancelAmount', cancelAmount);
+ orderSchema);
+ assert.isBigNumber('takerTokenCancelAmount', takerTokenCancelAmount);
await assert.isSenderAddressAvailableAsync(this.web3Wrapper, 'order.maker', order.maker);
const exchangeInstance = await this.getExchangeContractAsync();
- await this.validateCancelOrderAndThrowIfInvalidAsync(order, cancelAmount);
+ await this.validateCancelOrderAndThrowIfInvalidAsync(order, takerTokenCancelAmount);
const [orderAddresses, orderValues] = ExchangeWrapper.getOrderAddressesAndValues(order);
const gas = await exchangeInstance.cancel.estimateGas(
orderAddresses,
orderValues,
- cancelAmount,
+ takerTokenCancelAmount,
{
from: order.maker,
},
@@ -197,7 +197,7 @@ export class ExchangeWrapper extends ContractWrapper {
const response: ContractResponse = await exchangeInstance.cancel(
orderAddresses,
orderValues,
- cancelAmount,
+ takerTokenCancelAmount,
{
from: order.maker,
gas,
@@ -231,14 +231,13 @@ export class ExchangeWrapper extends ContractWrapper {
logEventObj.watch(callback);
this.exchangeLogEventObjs.push(logEventObj);
}
-
/**
- * Get order hash
+ * Computes the orderHash for a given order and returns it as a hex encoded string.
*/
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);
+ const orderHash = utils.getOrderHashHex(order, exchangeInstance.address);
return orderHash;
}
private async stopWatchingExchangeLogEventsAsync() {
@@ -257,7 +256,7 @@ export class ExchangeWrapper extends ContractWrapper {
if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== senderAddress) {
throw new Error(ExchangeContractErrs.TRANSACTION_SENDER_IS_NOT_FILL_ORDER_TAKER);
}
- const currentUnixTimestampSec = Date.now() / 1000;
+ const currentUnixTimestampSec = utils.getCurrentUnixTimestamp();
if (signedOrder.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
throw new Error(ExchangeContractErrs.ORDER_FILL_EXPIRED);
}
@@ -272,9 +271,9 @@ export class ExchangeWrapper extends ContractWrapper {
throw new Error(ExchangeContractErrs.ORDER_FILL_ROUNDING_ERROR);
}
}
- private async validateCancelOrderAndThrowIfInvalidAsync(order: Order,
- cancelAmount: BigNumber.BigNumber): Promise<void> {
- if (cancelAmount.eq(0)) {
+ private async validateCancelOrderAndThrowIfInvalidAsync(
+ order: Order, takerTokenCancelAmount: BigNumber.BigNumber): Promise<void> {
+ if (takerTokenCancelAmount.eq(0)) {
throw new Error(ExchangeContractErrs.ORDER_CANCEL_AMOUNT_ZERO);
}
const orderHash = await this.getOrderHashAsync(order);
@@ -282,7 +281,7 @@ export class ExchangeWrapper extends ContractWrapper {
if (order.takerTokenAmount.minus(unavailableAmount).eq(0)) {
throw new Error(ExchangeContractErrs.ORDER_ALREADY_CANCELLED_OR_FILLED);
}
- const currentUnixTimestampSec = Date.now() / 1000;
+ const currentUnixTimestampSec = utils.getCurrentUnixTimestamp();
if (order.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) {
throw new Error(ExchangeContractErrs.ORDER_CANCEL_EXPIRED);
}
diff --git a/src/types.ts b/src/types.ts
index 92cafd409..fa3560ef8 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -44,7 +44,10 @@ export interface ContractEventObj {
}
export type CreateContractEvent = (indexFilterValues: IndexFilterValues,
subscriptionOpts: SubscriptionOpts) => ContractEventObj;
-export interface ExchangeContract {
+export interface ContractInstance {
+ address: string;
+}
+export interface ExchangeContract extends ContractInstance {
isValidSignature: {
call: (signerAddressHex: string, dataHex: string, v: number, r: string, s: string,
txOpts?: TxOpts) => Promise<boolean>;
@@ -85,7 +88,7 @@ export interface ExchangeContract {
};
}
-export interface TokenContract {
+export interface TokenContract extends ContractInstance {
balanceOf: {
call: (address: string) => Promise<BigNumber.BigNumber>;
};
@@ -98,7 +101,7 @@ export interface TokenContract {
approve: (proxyAddress: string, amountInBaseUnits: BigNumber.BigNumber, txOpts: TxOpts) => void;
}
-export interface TokenRegistryContract {
+export interface TokenRegistryContract extends ContractInstance {
getTokenMetaData: {
call: (address: string) => Promise<TokenMetadata>;
};
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index 114b46f6c..4cea36127 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -1,5 +1,12 @@
import * as _ from 'lodash';
import * as BN from 'bn.js';
+import * as ethABI from 'ethereumjs-abi';
+import * as ethUtil from 'ethereumjs-util';
+import {orderSchema} from '../schemas/order_schemas';
+import {SchemaValidator} from './schema_validator';
+import {Order, SolidityTypes} from '../types';
+import {assert} from './assert';
+import * as BigNumber from 'bignumber.js';
export const utils = {
/**
@@ -25,4 +32,32 @@ export const utils = {
spawnSwitchErr(name: string, value: any) {
return new Error(`Unexpected switch value: ${value} encountered for ${name}`);
},
+ getOrderHashHex(order: Order, exchangeContractAddr: string): string {
+ assert.doesConformToSchema('order',
+ SchemaValidator.convertToJSONSchemaCompatibleObject(order as object),
+ orderSchema);
+
+ const orderParts = [
+ {value: exchangeContractAddr, type: SolidityTypes.address},
+ {value: order.maker, type: SolidityTypes.address},
+ {value: order.taker, type: SolidityTypes.address},
+ {value: order.makerTokenAddress, type: SolidityTypes.address},
+ {value: order.takerTokenAddress, type: SolidityTypes.address},
+ {value: order.feeRecipient, type: SolidityTypes.address},
+ {value: utils.bigNumberToBN(order.makerTokenAmount), type: SolidityTypes.uint256},
+ {value: utils.bigNumberToBN(order.takerTokenAmount), type: SolidityTypes.uint256},
+ {value: utils.bigNumberToBN(order.makerFee), type: SolidityTypes.uint256},
+ {value: utils.bigNumberToBN(order.takerFee), type: SolidityTypes.uint256},
+ {value: utils.bigNumberToBN(order.expirationUnixTimestampSec), type: SolidityTypes.uint256},
+ {value: utils.bigNumberToBN(order.salt), type: SolidityTypes.uint256},
+ ];
+ const types = _.map(orderParts, o => o.type);
+ const values = _.map(orderParts, o => o.value);
+ const hashBuff = ethABI.soliditySHA3(types, values);
+ const hashHex = ethUtil.bufferToHex(hashBuff);
+ return hashHex;
+ },
+ getCurrentUnixTimestamp(): BigNumber.BigNumber {
+ return new BigNumber(Date.now() / 1000);
+ },
};
diff --git a/test/exchange_wrapper_test.ts b/test/exchange_wrapper_test.ts
index a60494a09..3a3ec1ca7 100644
--- a/test/exchange_wrapper_test.ts
+++ b/test/exchange_wrapper_test.ts
@@ -158,7 +158,7 @@ describe('ExchangeWrapper', () => {
)).to.be.rejectedWith(ExchangeContractErrs.TRANSACTION_SENDER_IS_NOT_FILL_ORDER_TAKER);
});
it('should throw when order is expired', async () => {
- const expirationInPast = new BigNumber(42);
+ const expirationInPast = new BigNumber(1496826058);
const fillableAmount = new BigNumber(5);
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount, expirationInPast,
@@ -350,7 +350,7 @@ describe('ExchangeWrapper', () => {
.to.be.rejectedWith(ExchangeContractErrs.ORDER_CANCEL_AMOUNT_ZERO);
});
it('should throw when order is expired', async () => {
- const expirationInPast = new BigNumber(42);
+ const expirationInPast = new BigNumber(1496826058);
const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount, expirationInPast,
);