aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/0x.js/package.json2
-rw-r--r--packages/contract-wrappers/package.json2
-rw-r--r--packages/contracts/package.json2
-rw-r--r--packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol2
-rw-r--r--packages/contracts/src/utils/address_utils.ts4
-rw-r--r--packages/contracts/src/utils/exchange_wrapper.ts4
-rw-r--r--packages/contracts/src/utils/formatters.ts16
-rw-r--r--packages/contracts/src/utils/match_order_tester.ts15
-rw-r--r--packages/contracts/src/utils/order_factory.ts17
-rw-r--r--packages/contracts/src/utils/order_utils.ts78
-rw-r--r--packages/contracts/src/utils/signing_utils.ts5
-rw-r--r--packages/contracts/src/utils/transaction_factory.ts11
-rw-r--r--packages/contracts/src/utils/types.ts51
-rw-r--r--packages/contracts/test/asset_proxy/proxies.ts4
-rw-r--r--packages/contracts/test/exchange/core.ts47
-rw-r--r--packages/contracts/test/exchange/dispatcher.ts4
-rw-r--r--packages/contracts/test/exchange/libs.ts9
-rw-r--r--packages/contracts/test/exchange/match_orders.ts10
-rw-r--r--packages/contracts/test/exchange/signature_validator.ts8
-rw-r--r--packages/contracts/test/exchange/transactions.ts33
-rw-r--r--packages/contracts/test/exchange/wrapper.ts6
-rw-r--r--packages/contracts/test/libraries/lib_bytes.ts2
-rw-r--r--packages/fill-scenarios/package.json2
-rw-r--r--packages/json-schemas/package.json2
-rw-r--r--packages/json-schemas/schemas/ec_signature_schema.ts20
-rw-r--r--packages/json-schemas/schemas/order_schemas.ts4
-rw-r--r--packages/json-schemas/src/schemas.ts2
-rw-r--r--packages/json-schemas/test/schema_test.ts2
-rw-r--r--packages/migrations/artifacts/2.0.0/ISigner.json76
-rw-r--r--packages/migrations/compiler.json15
-rw-r--r--packages/order-utils/package.json17
-rw-r--r--packages/order-utils/src/artifacts.ts10
-rw-r--r--packages/order-utils/src/assert.ts14
-rw-r--r--packages/order-utils/src/asset_proxy_utils.ts (renamed from packages/contracts/src/utils/asset_proxy_utils.ts)21
-rw-r--r--packages/order-utils/src/crypto.ts (renamed from packages/contracts/src/utils/crypto.ts)3
-rw-r--r--packages/order-utils/src/formatters.ts23
-rw-r--r--packages/order-utils/src/index.ts9
-rw-r--r--packages/order-utils/src/order_factory.ts75
-rw-r--r--packages/order-utils/src/order_hash.ts182
-rw-r--r--packages/order-utils/src/order_state_utils.ts32
-rw-r--r--packages/order-utils/src/remaining_fillable_calculator.ts12
-rw-r--r--packages/order-utils/src/signature_utils.ts229
-rw-r--r--packages/order-utils/src/types.ts22
-rw-r--r--packages/order-utils/src/utils.ts9
-rw-r--r--packages/order-utils/test/order_hash_test.ts47
-rw-r--r--packages/order-utils/test/signature_utils_test.ts132
-rw-r--r--packages/order-watcher/package.json2
-rw-r--r--packages/sra-report/package.json2
-rw-r--r--packages/types/package.json2
-rw-r--r--packages/types/src/index.ts72
50 files changed, 864 insertions, 506 deletions
diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json
index 63e9997ff..1324a73d1 100644
--- a/packages/0x.js/package.json
+++ b/packages/0x.js/package.json
@@ -102,7 +102,7 @@
"@0xproject/assert": "^0.2.10",
"@0xproject/base-contract": "^0.3.2",
"@0xproject/contract-wrappers": "^0.0.2",
- "@0xproject/order-utils": "^0.0.5",
+ "@0xproject/order-utils": "0.0.5",
"@0xproject/order-watcher": "^0.0.2",
"@0xproject/sol-compiler": "^0.5.0",
"@0xproject/types": "0.7.0",
diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json
index 8680613a3..61e92903f 100644
--- a/packages/contract-wrappers/package.json
+++ b/packages/contract-wrappers/package.json
@@ -80,7 +80,7 @@
"@0xproject/base-contract": "^0.3.2",
"@0xproject/fill-scenarios": "^0.0.2",
"@0xproject/json-schemas": "0.7.22",
- "@0xproject/order-utils": "^0.0.5",
+ "@0xproject/order-utils": "0.0.5",
"@0xproject/types": "0.7.0",
"@0xproject/typescript-typings": "^0.3.2",
"@0xproject/utils": "^0.6.2",
diff --git a/packages/contracts/package.json b/packages/contracts/package.json
index 300a5331a..8b2945861 100644
--- a/packages/contracts/package.json
+++ b/packages/contracts/package.json
@@ -69,7 +69,7 @@
},
"dependencies": {
"@0xproject/base-contract": "^0.3.2",
- "@0xproject/order-utils": "^0.0.5",
+ "@0xproject/order-utils": "^0.0.6",
"@0xproject/sol-compiler": "^0.5.0",
"@0xproject/types": "^0.7.0",
"@0xproject/typescript-typings": "^0.3.2",
diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol b/packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol
index d40974e5f..79dc87af0 100644
--- a/packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol
+++ b/packages/contracts/src/contracts/current/protocol/Exchange/MixinSignatureValidator.sol
@@ -97,7 +97,7 @@ contract MixinSignatureValidator is
bytes32 r;
bytes32 s;
address recovered;
-
+
// Always illegal signature.
// This is always an implicit option since a signer can create a
// signature array with invalid type or length. We may as well make
diff --git a/packages/contracts/src/utils/address_utils.ts b/packages/contracts/src/utils/address_utils.ts
index dc63459f9..a9fb6921a 100644
--- a/packages/contracts/src/utils/address_utils.ts
+++ b/packages/contracts/src/utils/address_utils.ts
@@ -1,6 +1,4 @@
-import { generatePseudoRandomSalt } from '@0xproject/order-utils';
-
-import { crypto } from './crypto';
+import { crypto, generatePseudoRandomSalt } from '@0xproject/order-utils';
export const addressUtils = {
generatePseudoRandomAddress(): string {
diff --git a/packages/contracts/src/utils/exchange_wrapper.ts b/packages/contracts/src/utils/exchange_wrapper.ts
index 14d183b09..dd278e77c 100644
--- a/packages/contracts/src/utils/exchange_wrapper.ts
+++ b/packages/contracts/src/utils/exchange_wrapper.ts
@@ -1,4 +1,4 @@
-import { SignedOrder } from '@0xproject/types';
+import { AssetProxyId, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { LogEntry, Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
@@ -10,7 +10,7 @@ import { constants } from './constants';
import { formatters } from './formatters';
import { LogDecoder } from './log_decoder';
import { orderUtils } from './order_utils';
-import { AssetProxyId, OrderInfo, SignedTransaction } from './types';
+import { OrderInfo, SignedTransaction } from './types';
export class ExchangeWrapper {
private _exchange: ExchangeContract;
diff --git a/packages/contracts/src/utils/formatters.ts b/packages/contracts/src/utils/formatters.ts
index c46d668bc..1035f2d7c 100644
--- a/packages/contracts/src/utils/formatters.ts
+++ b/packages/contracts/src/utils/formatters.ts
@@ -13,8 +13,8 @@ export const formatters = {
takerAssetFillAmounts,
};
_.forEach(signedOrders, signedOrder => {
- const orderStruct = orderUtils.getOrderStruct(signedOrder);
- batchFill.orders.push(orderStruct);
+ const orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
+ batchFill.orders.push(orderWithoutExchangeAddress);
batchFill.signatures.push(signedOrder.signature);
if (takerAssetFillAmounts.length < signedOrders.length) {
batchFill.takerAssetFillAmounts.push(signedOrder.takerAssetAmount);
@@ -29,8 +29,8 @@ export const formatters = {
takerAssetFillAmount,
};
_.forEach(signedOrders, signedOrder => {
- const orderStruct = orderUtils.getOrderStruct(signedOrder);
- marketSellOrders.orders.push(orderStruct);
+ const orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
+ marketSellOrders.orders.push(orderWithoutExchangeAddress);
marketSellOrders.signatures.push(signedOrder.signature);
});
return marketSellOrders;
@@ -42,8 +42,8 @@ export const formatters = {
makerAssetFillAmount,
};
_.forEach(signedOrders, signedOrder => {
- const orderStruct = orderUtils.getOrderStruct(signedOrder);
- marketBuyOrders.orders.push(orderStruct);
+ const orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
+ marketBuyOrders.orders.push(orderWithoutExchangeAddress);
marketBuyOrders.signatures.push(signedOrder.signature);
});
return marketBuyOrders;
@@ -53,8 +53,8 @@ export const formatters = {
orders: [],
};
_.forEach(signedOrders, signedOrder => {
- const orderStruct = orderUtils.getOrderStruct(signedOrder);
- batchCancel.orders.push(orderStruct);
+ const orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
+ batchCancel.orders.push(orderWithoutExchangeAddress);
});
return batchCancel;
},
diff --git a/packages/contracts/src/utils/match_order_tester.ts b/packages/contracts/src/utils/match_order_tester.ts
index ec8931a20..09c0d8083 100644
--- a/packages/contracts/src/utils/match_order_tester.ts
+++ b/packages/contracts/src/utils/match_order_tester.ts
@@ -1,5 +1,6 @@
import { BlockchainLifecycle } from '@0xproject/dev-utils';
-import { SignedOrder } from '@0xproject/types';
+import { assetProxyUtils, crypto, orderHashUtils } from '@0xproject/order-utils';
+import { AssetProxyId, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import { LogWithDecodedArgs } from 'ethereum-types';
@@ -15,17 +16,13 @@ import {
ExchangeContract,
FillContractEventArgs,
} from '../contract_wrappers/generated/exchange';
-import { assetProxyUtils } from '../utils/asset_proxy_utils';
import { chaiSetup } from '../utils/chai_setup';
import { constants } from '../utils/constants';
-import { crypto } from '../utils/crypto';
import { ERC20Wrapper } from '../utils/erc20_wrapper';
import { ERC721Wrapper } from '../utils/erc721_wrapper';
import { ExchangeWrapper } from '../utils/exchange_wrapper';
import { OrderFactory } from '../utils/order_factory';
-import { orderUtils } from '../utils/order_utils';
import {
- AssetProxyId,
ContractName,
ERC20BalancesByOwner,
ERC721TokenIdsByOwner,
@@ -123,7 +120,7 @@ export class MatchOrderTester {
const feeRecipientAddressRight = signedOrderRight.feeRecipientAddress;
// Verify Left order preconditions
const orderTakerAssetFilledAmountLeft = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrderLeft),
+ orderHashUtils.getOrderHashHex(signedOrderLeft),
);
const expectedOrderFilledAmountLeft = initialTakerAssetFilledAmountLeft
? initialTakerAssetFilledAmountLeft
@@ -131,7 +128,7 @@ export class MatchOrderTester {
expect(expectedOrderFilledAmountLeft).to.be.bignumber.equal(orderTakerAssetFilledAmountLeft);
// Verify Right order preconditions
const orderTakerAssetFilledAmountRight = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrderRight),
+ orderHashUtils.getOrderHashHex(signedOrderRight),
);
const expectedOrderFilledAmountRight = initialTakerAssetFilledAmountRight
? initialTakerAssetFilledAmountRight
@@ -182,7 +179,7 @@ export class MatchOrderTester {
orderTakerAssetFilledAmountRight: BigNumber,
): Promise<TransferAmounts> {
let amountBoughtByLeftMaker = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrderLeft),
+ orderHashUtils.getOrderHashHex(signedOrderLeft),
);
amountBoughtByLeftMaker = amountBoughtByLeftMaker.minus(orderTakerAssetFilledAmountLeft);
const amountSoldByLeftMaker = amountBoughtByLeftMaker
@@ -193,7 +190,7 @@ export class MatchOrderTester {
.dividedToIntegerBy(signedOrderRight.makerAssetAmount);
const amountReceivedByTaker = amountSoldByLeftMaker.minus(amountReceivedByRightMaker);
let amountBoughtByRightMaker = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrderRight),
+ orderHashUtils.getOrderHashHex(signedOrderRight),
);
amountBoughtByRightMaker = amountBoughtByRightMaker.minus(orderTakerAssetFilledAmountRight);
const amountSoldByRightMaker = amountBoughtByRightMaker
diff --git a/packages/contracts/src/utils/order_factory.ts b/packages/contracts/src/utils/order_factory.ts
index f704c26ec..fc491d967 100644
--- a/packages/contracts/src/utils/order_factory.ts
+++ b/packages/contracts/src/utils/order_factory.ts
@@ -1,23 +1,22 @@
import { generatePseudoRandomSalt } from '@0xproject/order-utils';
-import { SignedOrder, UnsignedOrder } from '@0xproject/types';
+import { orderHashUtils } from '@0xproject/order-utils';
+import { Order, SignatureType, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import { constants } from './constants';
-import { orderUtils } from './order_utils';
import { signingUtils } from './signing_utils';
-import { SignatureType } from './types';
export class OrderFactory {
- private _defaultOrderParams: Partial<UnsignedOrder>;
+ private _defaultOrderParams: Partial<Order>;
private _privateKey: Buffer;
- constructor(privateKey: Buffer, defaultOrderParams: Partial<UnsignedOrder>) {
+ constructor(privateKey: Buffer, defaultOrderParams: Partial<Order>) {
this._defaultOrderParams = defaultOrderParams;
this._privateKey = privateKey;
}
public newSignedOrder(
- customOrderParams: Partial<UnsignedOrder> = {},
- signatureType: SignatureType = SignatureType.Ecrecover,
+ customOrderParams: Partial<Order> = {},
+ signatureType: SignatureType = SignatureType.EthSign,
): SignedOrder {
const randomExpiration = new BigNumber(Math.floor((Date.now() + Math.random() * 100000000000) / 1000));
const order = ({
@@ -27,8 +26,8 @@ export class OrderFactory {
takerAddress: constants.NULL_ADDRESS,
...this._defaultOrderParams,
...customOrderParams,
- } as any) as UnsignedOrder;
- const orderHashBuff = orderUtils.getOrderHashBuff(order);
+ } as any) as Order;
+ const orderHashBuff = orderHashUtils.getOrderHashBuff(order);
const signature = signingUtils.signMessage(orderHashBuff, this._privateKey, signatureType);
const signedOrder = {
...order,
diff --git a/packages/contracts/src/utils/order_utils.ts b/packages/contracts/src/utils/order_utils.ts
index 6d1aaa06b..0d0329aa1 100644
--- a/packages/contracts/src/utils/order_utils.ts
+++ b/packages/contracts/src/utils/order_utils.ts
@@ -1,14 +1,13 @@
-import { Order, SignedOrder, UnsignedOrder } from '@0xproject/types';
+import { Order, OrderWithoutExchangeAddress, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import ethUtil = require('ethereumjs-util');
-import { crypto } from './crypto';
import { CancelOrder, MatchOrder } from './types';
export const orderUtils = {
createFill: (signedOrder: SignedOrder, takerAssetFillAmount?: BigNumber) => {
const fill = {
- order: orderUtils.getOrderStruct(signedOrder),
+ order: orderUtils.getOrderWithoutExchangeAddress(signedOrder),
takerAssetFillAmount: takerAssetFillAmount || signedOrder.takerAssetAmount,
signature: signedOrder.signature,
};
@@ -16,12 +15,12 @@ export const orderUtils = {
},
createCancel(signedOrder: SignedOrder, takerAssetCancelAmount?: BigNumber): CancelOrder {
const cancel = {
- order: orderUtils.getOrderStruct(signedOrder),
+ order: orderUtils.getOrderWithoutExchangeAddress(signedOrder),
takerAssetCancelAmount: takerAssetCancelAmount || signedOrder.takerAssetAmount,
};
return cancel;
},
- getOrderStruct(signedOrder: SignedOrder): Order {
+ getOrderWithoutExchangeAddress(signedOrder: SignedOrder): OrderWithoutExchangeAddress {
const orderStruct = {
senderAddress: signedOrder.senderAddress,
makerAddress: signedOrder.makerAddress,
@@ -38,75 +37,10 @@ export const orderUtils = {
};
return orderStruct;
},
- getDomainSeparatorSchemaHex(): string {
- const domainSeparatorSchemaHashBuff = crypto.solSHA3(['DomainSeparator(address contract)']);
- const schemaHashHex = `0x${domainSeparatorSchemaHashBuff.toString('hex')}`;
- return schemaHashHex;
- },
- getDomainSeparatorHashHex(exchangeAddress: string): string {
- const domainSeparatorHashBuff = crypto.solSHA3([exchangeAddress]);
- const domainSeparatorHashHex = `0x${domainSeparatorHashBuff.toString('hex')}`;
- return domainSeparatorHashHex;
- },
- getOrderSchemaHex(): string {
- const orderSchemaHashBuff = crypto.solSHA3([
- 'Order(',
- 'address makerAddress,',
- 'address takerAddress,',
- 'address feeRecipientAddress,',
- 'address senderAddress,',
- 'uint256 makerAssetAmount,',
- 'uint256 takerAssetAmount,',
- 'uint256 makerFee,',
- 'uint256 takerFee,',
- 'uint256 expirationTimeSeconds,',
- 'uint256 salt,',
- 'bytes makerAssetData,',
- 'bytes takerAssetData,',
- ')',
- ]);
- const schemaHashHex = `0x${orderSchemaHashBuff.toString('hex')}`;
- return schemaHashHex;
- },
- getOrderHashBuff(order: SignedOrder | UnsignedOrder): Buffer {
- const makerAssetDataHash = crypto.solSHA3([ethUtil.toBuffer(order.makerAssetData)]);
- const takerAssetDataHash = crypto.solSHA3([ethUtil.toBuffer(order.takerAssetData)]);
-
- const orderParamsHashBuff = crypto.solSHA3([
- order.makerAddress,
- order.takerAddress,
- order.feeRecipientAddress,
- order.senderAddress,
- order.makerAssetAmount,
- order.takerAssetAmount,
- order.makerFee,
- order.takerFee,
- order.expirationTimeSeconds,
- order.salt,
- makerAssetDataHash,
- takerAssetDataHash,
- ]);
- const orderParamsHashHex = `0x${orderParamsHashBuff.toString('hex')}`;
- const orderSchemaHashHex = orderUtils.getOrderSchemaHex();
- const domainSeparatorHashHex = this.getDomainSeparatorHashHex(order.exchangeAddress);
- const domainSeparatorSchemaHex = this.getDomainSeparatorSchemaHex();
- const orderHashBuff = crypto.solSHA3([
- new BigNumber(domainSeparatorSchemaHex),
- new BigNumber(domainSeparatorHashHex),
- new BigNumber(orderSchemaHashHex),
- new BigNumber(orderParamsHashHex),
- ]);
- return orderHashBuff;
- },
- getOrderHashHex(order: SignedOrder | UnsignedOrder): string {
- const orderHashBuff = orderUtils.getOrderHashBuff(order);
- const orderHashHex = `0x${orderHashBuff.toString('hex')}`;
- return orderHashHex;
- },
createMatchOrders(signedOrderLeft: SignedOrder, signedOrderRight: SignedOrder): MatchOrder {
const fill = {
- left: orderUtils.getOrderStruct(signedOrderLeft),
- right: orderUtils.getOrderStruct(signedOrderRight),
+ left: orderUtils.getOrderWithoutExchangeAddress(signedOrderLeft),
+ right: orderUtils.getOrderWithoutExchangeAddress(signedOrderRight),
leftSignature: signedOrderLeft.signature,
rightSignature: signedOrderRight.signature,
};
diff --git a/packages/contracts/src/utils/signing_utils.ts b/packages/contracts/src/utils/signing_utils.ts
index 4c36c8310..9c711c72c 100644
--- a/packages/contracts/src/utils/signing_utils.ts
+++ b/packages/contracts/src/utils/signing_utils.ts
@@ -1,10 +1,9 @@
+import { SignatureType } from '@0xproject/types';
import * as ethUtil from 'ethereumjs-util';
-import { SignatureType } from './types';
-
export const signingUtils = {
signMessage(message: Buffer, privateKey: Buffer, signatureType: SignatureType): Buffer {
- if (signatureType === SignatureType.Ecrecover) {
+ if (signatureType === SignatureType.EthSign) {
const prefixedMessage = ethUtil.hashPersonalMessage(message);
const ecSignature = ethUtil.ecsign(prefixedMessage, privateKey);
const signature = Buffer.concat([
diff --git a/packages/contracts/src/utils/transaction_factory.ts b/packages/contracts/src/utils/transaction_factory.ts
index 65cdb3f89..434611908 100644
--- a/packages/contracts/src/utils/transaction_factory.ts
+++ b/packages/contracts/src/utils/transaction_factory.ts
@@ -1,10 +1,10 @@
-import { generatePseudoRandomSalt } from '@0xproject/order-utils';
+import { crypto, generatePseudoRandomSalt } from '@0xproject/order-utils';
+import { SignatureType } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as ethUtil from 'ethereumjs-util';
-import { crypto } from './crypto';
import { signingUtils } from './signing_utils';
-import { SignatureType, SignedTransaction } from './types';
+import { SignedTransaction } from './types';
export class TransactionFactory {
private _signerBuff: Buffer;
@@ -15,10 +15,7 @@ export class TransactionFactory {
this._exchangeAddress = exchangeAddress;
this._signerBuff = ethUtil.privateToAddress(this._privateKey);
}
- public newSignedTransaction(
- data: string,
- signatureType: SignatureType = SignatureType.Ecrecover,
- ): SignedTransaction {
+ public newSignedTransaction(data: string, signatureType: SignatureType = SignatureType.EthSign): SignedTransaction {
const salt = generatePseudoRandomSalt();
const txHash = crypto.solSHA3([this._exchangeAddress, this._signerBuff, salt, ethUtil.toBuffer(data)]);
const signature = signingUtils.signMessage(txHash, this._privateKey, signatureType);
diff --git a/packages/contracts/src/utils/types.ts b/packages/contracts/src/utils/types.ts
index d68a81b51..6340c4a51 100644
--- a/packages/contracts/src/utils/types.ts
+++ b/packages/contracts/src/utils/types.ts
@@ -1,4 +1,4 @@
-import { Order } from '@0xproject/types';
+import { Order, OrderWithoutExchangeAddress } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { AbiDefinition, ContractAbi } from 'ethereum-types';
@@ -19,37 +19,31 @@ export interface SubmissionContractEventArgs {
}
export interface BatchFillOrders {
- orders: Order[];
+ orders: OrderWithoutExchangeAddress[];
signatures: string[];
takerAssetFillAmounts: BigNumber[];
}
export interface MarketSellOrders {
- orders: Order[];
+ orders: OrderWithoutExchangeAddress[];
signatures: string[];
takerAssetFillAmount: BigNumber;
}
export interface MarketBuyOrders {
- orders: Order[];
+ orders: OrderWithoutExchangeAddress[];
signatures: string[];
makerAssetFillAmount: BigNumber;
}
export interface BatchCancelOrders {
- orders: Order[];
+ orders: OrderWithoutExchangeAddress[];
}
export interface CancelOrdersBefore {
salt: BigNumber;
}
-export enum AssetProxyId {
- INVALID,
- ERC20,
- ERC721,
-}
-
export interface TransactionDataParams {
name: string;
abi: AbiDefinition[];
@@ -115,18 +109,6 @@ export enum ContractName {
Whitelist = 'Whitelist',
}
-export enum SignatureType {
- Illegal,
- Invalid,
- EIP712,
- Ecrecover,
- TxOrigin,
- Caller,
- Contract,
- PreSigned,
- Trezor,
-}
-
export interface SignedTransaction {
exchangeAddress: string;
salt: BigNumber;
@@ -162,31 +144,14 @@ export interface OrderInfo {
orderTakerAssetFilledAmount: BigNumber;
}
-export interface ERC20ProxyData {
- assetProxyId: AssetProxyId;
- tokenAddress: string;
-}
-
-export interface ERC721ProxyData {
- assetProxyId: AssetProxyId;
- tokenAddress: string;
- tokenId: BigNumber;
-}
-
-export interface ProxyData {
- assetProxyId: AssetProxyId;
- tokenAddress?: string;
- data?: any;
-}
-
export interface CancelOrder {
- order: Order;
+ order: OrderWithoutExchangeAddress;
takerAssetCancelAmount: BigNumber;
}
export interface MatchOrder {
- left: Order;
- right: Order;
+ left: OrderWithoutExchangeAddress;
+ right: OrderWithoutExchangeAddress;
leftSignature: string;
rightSignature: string;
}
diff --git a/packages/contracts/test/asset_proxy/proxies.ts b/packages/contracts/test/asset_proxy/proxies.ts
index 9bcdfa2b8..faab39759 100644
--- a/packages/contracts/test/asset_proxy/proxies.ts
+++ b/packages/contracts/test/asset_proxy/proxies.ts
@@ -1,4 +1,6 @@
import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { assetProxyUtils } from '@0xproject/order-utils';
+import { AssetProxyId } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import * as _ from 'lodash';
@@ -8,12 +10,10 @@ import { DummyERC20TokenContract } from '../../src/contract_wrappers/generated/d
import { DummyERC721TokenContract } from '../../src/contract_wrappers/generated/dummy_e_r_c721_token';
import { ERC20ProxyContract } from '../../src/contract_wrappers/generated/e_r_c20_proxy';
import { ERC721ProxyContract } from '../../src/contract_wrappers/generated/e_r_c721_proxy';
-import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
import { chaiSetup } from '../../src/utils/chai_setup';
import { constants } from '../../src/utils/constants';
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
-import { AssetProxyId } from '../../src/utils/types';
import { provider, web3Wrapper } from '../../src/utils/web3_wrapper';
chaiSetup.configure();
diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts
index 6282a51ea..8320e97d6 100644
--- a/packages/contracts/test/exchange/core.ts
+++ b/packages/contracts/test/exchange/core.ts
@@ -1,5 +1,6 @@
import { BlockchainLifecycle } from '@0xproject/dev-utils';
-import { SignedOrder } from '@0xproject/types';
+import { assetProxyUtils, crypto, orderHashUtils } from '@0xproject/order-utils';
+import { AssetProxyId, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as chai from 'chai';
@@ -18,16 +19,13 @@ import {
FillContractEventArgs,
} from '../../src/contract_wrappers/generated/exchange';
import { artifacts } from '../../src/utils/artifacts';
-import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
import { chaiSetup } from '../../src/utils/chai_setup';
import { constants } from '../../src/utils/constants';
-import { crypto } from '../../src/utils/crypto';
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
import { OrderFactory } from '../../src/utils/order_factory';
-import { orderUtils } from '../../src/utils/order_utils';
-import { AssetProxyId, ContractName, ERC20BalancesByOwner, ExchangeStatus } from '../../src/utils/types';
+import { ContractName, ERC20BalancesByOwner, ExchangeStatus } from '../../src/utils/types';
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
chaiSetup.configure();
@@ -128,7 +126,6 @@ describe('Exchange core', () => {
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
-
describe('fillOrder', () => {
beforeEach(async () => {
erc20Balances = await erc20Wrapper.getBalancesAsync();
@@ -142,7 +139,7 @@ describe('Exchange core', () => {
});
const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrder),
+ orderHashUtils.getOrderHashHex(signedOrder),
);
expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
@@ -152,7 +149,7 @@ describe('Exchange core', () => {
});
const takerAssetFilledAmountAfter1 = await exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrder),
+ orderHashUtils.getOrderHashHex(signedOrder),
);
expect(takerAssetFilledAmountAfter1).to.be.bignumber.equal(fillTakerAssetAmount1);
@@ -162,7 +159,7 @@ describe('Exchange core', () => {
});
const takerAssetFilledAmountAfter2 = await exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrder),
+ orderHashUtils.getOrderHashHex(signedOrder),
);
expect(takerAssetFilledAmountAfter2).to.be.bignumber.equal(takerAssetFilledAmountAfter1);
});
@@ -174,7 +171,7 @@ describe('Exchange core', () => {
});
const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrder),
+ orderHashUtils.getOrderHashHex(signedOrder),
);
expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
@@ -182,7 +179,7 @@ describe('Exchange core', () => {
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrder),
+ orderHashUtils.getOrderHashHex(signedOrder),
);
expect(makerAmountBoughtAfter).to.be.bignumber.equal(takerAssetFillAmount);
@@ -227,7 +224,7 @@ describe('Exchange core', () => {
});
const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrder),
+ orderHashUtils.getOrderHashHex(signedOrder),
);
expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
@@ -235,7 +232,7 @@ describe('Exchange core', () => {
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrder),
+ orderHashUtils.getOrderHashHex(signedOrder),
);
expect(makerAmountBoughtAfter).to.be.bignumber.equal(takerAssetFillAmount);
@@ -280,7 +277,7 @@ describe('Exchange core', () => {
});
const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrder),
+ orderHashUtils.getOrderHashHex(signedOrder),
);
expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
@@ -288,7 +285,7 @@ describe('Exchange core', () => {
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrder),
+ orderHashUtils.getOrderHashHex(signedOrder),
);
expect(makerAmountBoughtAfter).to.be.bignumber.equal(takerAssetFillAmount);
@@ -334,7 +331,7 @@ describe('Exchange core', () => {
});
const takerAssetFilledAmountBefore = await exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrder),
+ orderHashUtils.getOrderHashHex(signedOrder),
);
expect(takerAssetFilledAmountBefore).to.be.bignumber.equal(0);
@@ -342,7 +339,7 @@ describe('Exchange core', () => {
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
const makerAmountBoughtAfter = await exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderUtils.getOrderHashHex(signedOrder),
+ orderHashUtils.getOrderHashHex(signedOrder),
);
const expectedMakerAmountBoughtAfter = takerAssetFillAmount.add(takerAssetFilledAmountBefore);
expect(makerAmountBoughtAfter).to.be.bignumber.equal(expectedMakerAmountBoughtAfter);
@@ -442,7 +439,7 @@ describe('Exchange core', () => {
expect(expectedFilledTakerAssetAmount).to.be.bignumber.equal(logArgs.takerAssetFilledAmount);
expect(expectedFeeMPaid).to.be.bignumber.equal(logArgs.makerFeePaid);
expect(expectedFeeTPaid).to.be.bignumber.equal(logArgs.takerFeePaid);
- expect(orderUtils.getOrderHashHex(signedOrder)).to.be.equal(logArgs.orderHash);
+ expect(orderHashUtils.getOrderHashHex(signedOrder)).to.be.equal(logArgs.orderHash);
});
it('should throw when taker is specified and order is claimed by other', async () => {
@@ -536,12 +533,6 @@ describe('Exchange core', () => {
await expect(exchangeWrapper.fillOrderAsync(signedOrder, takerAddress)).to.be.rejectedWith(
constants.REVERT,
);
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, {
- from: makerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
});
it('should throw if taker allowances are too low to fill order', async () => {
@@ -557,12 +548,6 @@ describe('Exchange core', () => {
await expect(exchangeWrapper.fillOrderAsync(signedOrder, takerAddress)).to.be.rejectedWith(
constants.REVERT,
);
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE, {
- from: takerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
});
it('should not change erc20Balances if an order is expired', async () => {
@@ -653,7 +638,7 @@ describe('Exchange core', () => {
expect(signedOrder.feeRecipientAddress).to.be.equal(logArgs.feeRecipientAddress);
expect(signedOrder.makerAssetData).to.be.equal(logArgs.makerAssetData);
expect(signedOrder.takerAssetData).to.be.equal(logArgs.takerAssetData);
- expect(orderUtils.getOrderHashHex(signedOrder)).to.be.equal(logArgs.orderHash);
+ expect(orderHashUtils.getOrderHashHex(signedOrder)).to.be.equal(logArgs.orderHash);
});
it('should log an error if already cancelled', async () => {
diff --git a/packages/contracts/test/exchange/dispatcher.ts b/packages/contracts/test/exchange/dispatcher.ts
index b9c7039bd..8bc66e3cf 100644
--- a/packages/contracts/test/exchange/dispatcher.ts
+++ b/packages/contracts/test/exchange/dispatcher.ts
@@ -1,4 +1,6 @@
import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { assetProxyUtils } from '@0xproject/order-utils';
+import { AssetProxyId } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import * as Web3 from 'web3';
@@ -8,12 +10,10 @@ import { ERC20ProxyContract } from '../../src/contract_wrappers/generated/e_r_c2
import { ERC721ProxyContract } from '../../src/contract_wrappers/generated/e_r_c721_proxy';
import { TestAssetProxyDispatcherContract } from '../../src/contract_wrappers/generated/test_asset_proxy_dispatcher';
import { artifacts } from '../../src/utils/artifacts';
-import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
import { chaiSetup } from '../../src/utils/chai_setup';
import { constants } from '../../src/utils/constants';
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
-import { AssetProxyId } from '../../src/utils/types';
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
chaiSetup.configure();
diff --git a/packages/contracts/test/exchange/libs.ts b/packages/contracts/test/exchange/libs.ts
index a3282876b..10cb8b34e 100644
--- a/packages/contracts/test/exchange/libs.ts
+++ b/packages/contracts/test/exchange/libs.ts
@@ -1,4 +1,5 @@
import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils';
import { SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
@@ -7,11 +8,9 @@ import ethUtil = require('ethereumjs-util');
import { TestLibsContract } from '../../src/contract_wrappers/generated/test_libs';
import { addressUtils } from '../../src/utils/address_utils';
import { artifacts } from '../../src/utils/artifacts';
-import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
import { chaiSetup } from '../../src/utils/chai_setup';
import { constants } from '../../src/utils/constants';
import { OrderFactory } from '../../src/utils/order_factory';
-import { orderUtils } from '../../src/utils/order_utils';
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
chaiSetup.configure();
@@ -58,20 +57,20 @@ describe('Exchange libs', () => {
describe('getOrderSchema', () => {
it('should output the correct order schema hash', async () => {
const orderSchema = await libs.getOrderSchemaHash.callAsync();
- expect(orderUtils.getOrderSchemaHex()).to.be.equal(orderSchema);
+ expect(orderHashUtils._getOrderSchemaHex()).to.be.equal(orderSchema);
});
});
describe('getDomainSeparatorSchema', () => {
it('should output the correct domain separator schema hash', async () => {
const domainSeparatorSchema = await libs.getDomainSeparatorSchemaHash.callAsync();
- expect(orderUtils.getDomainSeparatorSchemaHex()).to.be.equal(domainSeparatorSchema);
+ expect(orderHashUtils._getDomainSeparatorSchemaHex()).to.be.equal(domainSeparatorSchema);
});
});
describe('getOrderHash', () => {
it('should output the correct orderHash', async () => {
signedOrder = orderFactory.newSignedOrder();
const orderHashHex = await libs.publicGetOrderHash.callAsync(signedOrder);
- expect(orderUtils.getOrderHashHex(signedOrder)).to.be.equal(orderHashHex);
+ expect(orderHashUtils.getOrderHashHex(signedOrder)).to.be.equal(orderHashHex);
});
});
});
diff --git a/packages/contracts/test/exchange/match_orders.ts b/packages/contracts/test/exchange/match_orders.ts
index c901c29b9..07295d78a 100644
--- a/packages/contracts/test/exchange/match_orders.ts
+++ b/packages/contracts/test/exchange/match_orders.ts
@@ -1,5 +1,6 @@
import { BlockchainLifecycle } from '@0xproject/dev-utils';
-import { SignedOrder } from '@0xproject/types';
+import { assetProxyUtils, crypto } from '@0xproject/order-utils';
+import { AssetProxyId, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as chai from 'chai';
@@ -18,17 +19,14 @@ import {
FillContractEventArgs,
} from '../../src/contract_wrappers/generated/exchange';
import { artifacts } from '../../src/utils/artifacts';
-import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
import { chaiSetup } from '../../src/utils/chai_setup';
import { constants } from '../../src/utils/constants';
-import { crypto } from '../../src/utils/crypto';
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
+import { MatchOrderTester } from '../../src/utils/match_order_tester';
import { OrderFactory } from '../../src/utils/order_factory';
-import { orderUtils } from '../../src/utils/order_utils';
import {
- AssetProxyId,
ContractName,
ERC20BalancesByOwner,
ERC721TokenIdsByOwner,
@@ -37,8 +35,6 @@ import {
} from '../../src/utils/types';
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
-import { MatchOrderTester } from '../../src/utils/match_order_tester';
-
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts
index 1f030b742..194053abc 100644
--- a/packages/contracts/test/exchange/signature_validator.ts
+++ b/packages/contracts/test/exchange/signature_validator.ts
@@ -1,4 +1,6 @@
import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { orderHashUtils } from '@0xproject/order-utils';
+import { assetProxyUtils } from '@0xproject/order-utils';
import { SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
@@ -7,11 +9,9 @@ import ethUtil = require('ethereumjs-util');
import { TestSignatureValidatorContract } from '../../src/contract_wrappers/generated/test_signature_validator';
import { addressUtils } from '../../src/utils/address_utils';
import { artifacts } from '../../src/utils/artifacts';
-import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
import { chaiSetup } from '../../src/utils/chai_setup';
import { constants } from '../../src/utils/constants';
import { OrderFactory } from '../../src/utils/order_factory';
-import { orderUtils } from '../../src/utils/order_utils';
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
chaiSetup.configure();
@@ -64,7 +64,7 @@ describe('MixinSignatureValidator', () => {
});
it('should return true with a valid signature', async () => {
- const orderHashHex = orderUtils.getOrderHashHex(signedOrder);
+ const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
orderHashHex,
signedOrder.makerAddress,
@@ -81,7 +81,7 @@ describe('MixinSignatureValidator', () => {
const invalidSigBuff = Buffer.concat([v, invalidR, invalidS, signatureType]);
const invalidSigHex = `0x${invalidSigBuff.toString('hex')}`;
signedOrder.signature = invalidSigHex;
- const orderHashHex = orderUtils.getOrderHashHex(signedOrder);
+ const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
const isValidSignature = await signatureValidator.publicIsValidSignature.callAsync(
orderHashHex,
signedOrder.makerAddress,
diff --git a/packages/contracts/test/exchange/transactions.ts b/packages/contracts/test/exchange/transactions.ts
index fc7aa8404..2f3f6b43a 100644
--- a/packages/contracts/test/exchange/transactions.ts
+++ b/packages/contracts/test/exchange/transactions.ts
@@ -1,6 +1,6 @@
import { BlockchainLifecycle } from '@0xproject/dev-utils';
-import { generatePseudoRandomSalt } from '@0xproject/order-utils';
-import { Order, SignedOrder } from '@0xproject/types';
+import { assetProxyUtils, generatePseudoRandomSalt } from '@0xproject/order-utils';
+import { AssetProxyId, Order, OrderWithoutExchangeAddress, SignatureType, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import * as ethUtil from 'ethereumjs-util';
@@ -11,7 +11,6 @@ import { ERC20ProxyContract } from '../../src/contract_wrappers/generated/e_r_c2
import { ExchangeContract } from '../../src/contract_wrappers/generated/exchange';
import { WhitelistContract } from '../../src/contract_wrappers/generated/whitelist';
import { artifacts } from '../../src/utils/artifacts';
-import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
import { chaiSetup } from '../../src/utils/chai_setup';
import { constants } from '../../src/utils/constants';
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
@@ -19,13 +18,7 @@ import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
import { OrderFactory } from '../../src/utils/order_factory';
import { orderUtils } from '../../src/utils/order_utils';
import { TransactionFactory } from '../../src/utils/transaction_factory';
-import {
- AssetProxyId,
- ERC20BalancesByOwner,
- ExchangeStatus,
- SignatureType,
- SignedTransaction,
-} from '../../src/utils/types';
+import { ERC20BalancesByOwner, ExchangeStatus, SignedTransaction } from '../../src/utils/types';
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
chaiSetup.configure();
@@ -48,7 +41,7 @@ describe('Exchange transactions', () => {
let erc20Balances: ERC20BalancesByOwner;
let signedOrder: SignedOrder;
let signedTx: SignedTransaction;
- let order: Order;
+ let orderWithoutExchangeAddress: OrderWithoutExchangeAddress;
let orderFactory: OrderFactory;
let makerTransactionFactory: TransactionFactory;
let takerTransactionFactory: TransactionFactory;
@@ -121,11 +114,11 @@ describe('Exchange transactions', () => {
beforeEach(async () => {
erc20Balances = await erc20Wrapper.getBalancesAsync();
signedOrder = orderFactory.newSignedOrder();
- order = orderUtils.getOrderStruct(signedOrder);
+ orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
const data = exchange.fillOrder.getABIEncodedTransactionData(
- order,
+ orderWithoutExchangeAddress,
takerAssetFillAmount,
signedOrder.signature,
);
@@ -189,7 +182,7 @@ describe('Exchange transactions', () => {
describe('cancelOrder', () => {
beforeEach(async () => {
- const data = exchange.cancelOrder.getABIEncodedTransactionData(order);
+ const data = exchange.cancelOrder.getABIEncodedTransactionData(orderWithoutExchangeAddress);
signedTx = makerTransactionFactory.newSignedTransaction(data);
});
@@ -248,12 +241,12 @@ describe('Exchange transactions', () => {
await whitelist.updateWhitelistStatus.sendTransactionAsync(takerAddress, isApproved, { from: owner }),
);
- const orderStruct = orderUtils.getOrderStruct(signedOrder);
+ orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
const takerAssetFillAmount = signedOrder.takerAssetAmount;
const salt = generatePseudoRandomSalt();
return expect(
whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
- orderStruct,
+ orderWithoutExchangeAddress,
takerAssetFillAmount,
salt,
signedOrder.signature,
@@ -268,12 +261,12 @@ describe('Exchange transactions', () => {
await whitelist.updateWhitelistStatus.sendTransactionAsync(makerAddress, isApproved, { from: owner }),
);
- const orderStruct = orderUtils.getOrderStruct(signedOrder);
+ orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
const takerAssetFillAmount = signedOrder.takerAssetAmount;
const salt = generatePseudoRandomSalt();
return expect(
whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
- orderStruct,
+ orderWithoutExchangeAddress,
takerAssetFillAmount,
salt,
signedOrder.signature,
@@ -292,12 +285,12 @@ describe('Exchange transactions', () => {
await whitelist.updateWhitelistStatus.sendTransactionAsync(takerAddress, isApproved, { from: owner }),
);
- const orderStruct = orderUtils.getOrderStruct(signedOrder);
+ orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
const takerAssetFillAmount = signedOrder.takerAssetAmount;
const salt = generatePseudoRandomSalt();
await web3Wrapper.awaitTransactionSuccessAsync(
await whitelist.fillOrderIfWhitelisted.sendTransactionAsync(
- orderStruct,
+ orderWithoutExchangeAddress,
takerAssetFillAmount,
salt,
signedOrder.signature,
diff --git a/packages/contracts/test/exchange/wrapper.ts b/packages/contracts/test/exchange/wrapper.ts
index 7e1818f4a..d8055908a 100644
--- a/packages/contracts/test/exchange/wrapper.ts
+++ b/packages/contracts/test/exchange/wrapper.ts
@@ -1,5 +1,5 @@
import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils';
-import { SignedOrder } from '@0xproject/types';
+import { AssetProxyId, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as chai from 'chai';
@@ -14,14 +14,14 @@ import { ERC721ProxyContract } from '../../src/contract_wrappers/generated/e_r_c
import { ExchangeContract } from '../../src/contract_wrappers/generated/exchange';
import { TokenRegistryContract } from '../../src/contract_wrappers/generated/token_registry';
import { artifacts } from '../../src/utils/artifacts';
-import { assetProxyUtils } from '../../src/utils/asset_proxy_utils';
+import { assetProxyUtils } from '@0xproject/order-utils';
import { chaiSetup } from '../../src/utils/chai_setup';
import { constants } from '../../src/utils/constants';
import { ERC20Wrapper } from '../../src/utils/erc20_wrapper';
import { ERC721Wrapper } from '../../src/utils/erc721_wrapper';
import { ExchangeWrapper } from '../../src/utils/exchange_wrapper';
import { OrderFactory } from '../../src/utils/order_factory';
-import { AssetProxyId, ERC20BalancesByOwner } from '../../src/utils/types';
+import { ERC20BalancesByOwner } from '../../src/utils/types';
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
chaiSetup.configure();
diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts
index f8d75080a..26cfa8291 100644
--- a/packages/contracts/test/libraries/lib_bytes.ts
+++ b/packages/contracts/test/libraries/lib_bytes.ts
@@ -1,4 +1,5 @@
import { BlockchainLifecycle, devConstants, web3Factory } from '@0xproject/dev-utils';
+import { AssetProxyId } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import BN = require('bn.js');
@@ -11,7 +12,6 @@ import { TestLibBytesContract } from '../../src/contract_wrappers/generated/test
import { artifacts } from '../../src/utils/artifacts';
import { chaiSetup } from '../../src/utils/chai_setup';
import { constants } from '../../src/utils/constants';
-import { AssetProxyId } from '../../src/utils/types';
import { provider, txDefaults, web3Wrapper } from '../../src/utils/web3_wrapper';
chaiSetup.configure();
diff --git a/packages/fill-scenarios/package.json b/packages/fill-scenarios/package.json
index 6d47fe534..d0d3d9ec4 100644
--- a/packages/fill-scenarios/package.json
+++ b/packages/fill-scenarios/package.json
@@ -37,7 +37,7 @@
},
"dependencies": {
"@0xproject/base-contract": "^0.3.2",
- "@0xproject/order-utils": "^0.0.5",
+ "@0xproject/order-utils": "0.0.5",
"@0xproject/types": "0.7.0",
"ethereum-types": "^0.0.1",
"@0xproject/typescript-typings": "^0.3.2",
diff --git a/packages/json-schemas/package.json b/packages/json-schemas/package.json
index 60a79d165..603e5ab73 100644
--- a/packages/json-schemas/package.json
+++ b/packages/json-schemas/package.json
@@ -1,6 +1,6 @@
{
"name": "@0xproject/json-schemas",
- "version": "0.7.24",
+ "version": "1.0.0",
"engines": {
"node": ">=6.12"
},
diff --git a/packages/json-schemas/schemas/ec_signature_schema.ts b/packages/json-schemas/schemas/ec_signature_schema.ts
new file mode 100644
index 000000000..71b840dd8
--- /dev/null
+++ b/packages/json-schemas/schemas/ec_signature_schema.ts
@@ -0,0 +1,20 @@
+export const ecSignatureParameterSchema = {
+ id: '/ECSignatureParameter',
+ type: 'string',
+ pattern: '^0[xX][0-9A-Fa-f]{64}$',
+};
+
+export const ecSignatureSchema = {
+ id: '/ECSignature',
+ properties: {
+ v: {
+ type: 'number',
+ minimum: 27,
+ maximum: 28,
+ },
+ r: { $ref: '/ECSignatureParameter' },
+ s: { $ref: '/ECSignatureParameter' },
+ },
+ required: ['v', 'r', 's'],
+ type: 'object',
+};
diff --git a/packages/json-schemas/schemas/order_schemas.ts b/packages/json-schemas/schemas/order_schemas.ts
index 183118c23..dcbfde6e0 100644
--- a/packages/json-schemas/schemas/order_schemas.ts
+++ b/packages/json-schemas/schemas/order_schemas.ts
@@ -5,11 +5,13 @@ export const orderSchema = {
takerAddress: { $ref: '/Address' },
makerFee: { $ref: '/Number' },
takerFee: { $ref: '/Number' },
+ senderAddress: { $ref: '/Address' },
makerAssetAmount: { $ref: '/Number' },
takerAssetAmount: { $ref: '/Number' },
makerAssetData: { $ref: '/Hex' },
takerAssetData: { $ref: '/Hex' },
salt: { $ref: '/Number' },
+ exchangeAddress: { $ref: '/Address' },
feeRecipientAddress: { $ref: '/Address' },
expirationTimeSeconds: { $ref: '/Number' },
},
@@ -18,11 +20,13 @@ export const orderSchema = {
'takerAddress',
'makerFee',
'takerFee',
+ 'senderAddress',
'makerAssetAmount',
'takerAssetAmount',
'makerAssetData',
'takerAssetData',
'salt',
+ 'exchangeAddress',
'feeRecipientAddress',
'expirationTimeSeconds',
],
diff --git a/packages/json-schemas/src/schemas.ts b/packages/json-schemas/src/schemas.ts
index 26d6e6cf1..77ea88f5c 100644
--- a/packages/json-schemas/src/schemas.ts
+++ b/packages/json-schemas/src/schemas.ts
@@ -1,5 +1,6 @@
import { addressSchema, hexSchema, numberSchema } from '../schemas/basic_type_schemas';
import { blockParamSchema, blockRangeSchema } from '../schemas/block_range_schema';
+import { ecSignatureSchema } from '../schemas/ec_signature_schema';
import { indexFilterValuesSchema } from '../schemas/index_filter_values_schema';
import { orderCancellationRequestsSchema } from '../schemas/order_cancel_schema';
import { orderFillOrKillRequestsSchema } from '../schemas/order_fill_or_kill_requests_schema';
@@ -31,6 +32,7 @@ export const schemas = {
numberSchema,
addressSchema,
hexSchema,
+ ecSignatureSchema,
indexFilterValuesSchema,
orderCancellationRequestsSchema,
orderFillOrKillRequestsSchema,
diff --git a/packages/json-schemas/test/schema_test.ts b/packages/json-schemas/test/schema_test.ts
index 379f92442..3858c7fa7 100644
--- a/packages/json-schemas/test/schema_test.ts
+++ b/packages/json-schemas/test/schema_test.ts
@@ -171,6 +171,7 @@ describe('Schema', () => {
const order = {
makerAddress: NULL_ADDRESS,
takerAddress: NULL_ADDRESS,
+ senderAddress: NULL_ADDRESS,
makerFee: '1',
takerFee: '2',
makerAssetAmount: '1',
@@ -179,6 +180,7 @@ describe('Schema', () => {
takerAssetData: NULL_ADDRESS,
salt: '67006738228878699843088602623665307406148487219438534730168799356281242528500',
feeRecipientAddress: NULL_ADDRESS,
+ exchangeAddress: NULL_ADDRESS,
expirationTimeSeconds: '42',
};
describe('#orderSchema', () => {
diff --git a/packages/migrations/artifacts/2.0.0/ISigner.json b/packages/migrations/artifacts/2.0.0/ISigner.json
new file mode 100644
index 000000000..8a0a8e06a
--- /dev/null
+++ b/packages/migrations/artifacts/2.0.0/ISigner.json
@@ -0,0 +1,76 @@
+{
+ "schemaVersion": "2.0.0",
+ "contractName": "ISigner",
+ "compilerOutput": {
+ "abi": [
+ {
+ "constant": true,
+ "inputs": [
+ {
+ "name": "hash",
+ "type": "bytes32"
+ },
+ {
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "name": "isValidSignature",
+ "outputs": [
+ {
+ "name": "isValid",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "evm": {
+ "bytecode": {
+ "linkReferences": {},
+ "object": "0x",
+ "opcodes": "",
+ "sourceMap": ""
+ },
+ "deployedBytecode": {
+ "linkReferences": {},
+ "object": "0x",
+ "opcodes": "",
+ "sourceMap": ""
+ }
+ }
+ },
+ "sources": {
+ "current/protocol/Exchange/interfaces/ISigner.sol": {
+ "id": 0
+ }
+ },
+ "sourceCodes": {
+ "current/protocol/Exchange/interfaces/ISigner.sol": "/*\n\n Copyright 2018 ZeroEx Intl.\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n\n*/\n\npragma solidity ^0.4.24;\n\ncontract ISigner {\n\n /// @dev Verifies that a signature is valid.\n /// @param hash Message hash that is signed.\n /// @param signature Proof of signing.\n /// @return Validity of order signature.\n function isValidSignature(\n bytes32 hash,\n bytes signature)\n external\n view\n returns (bool isValid);\n}\n"
+ },
+ "sourceTreeHashHex": "0x14f56e10a8ab94bb23561e6d2118d4ea6f68154b66e0833ebd915c0911073267",
+ "compiler": {
+ "name": "solc",
+ "version": "soljson-v0.4.24+commit.e67f0147.js",
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 0
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode.object",
+ "evm.bytecode.sourceMap",
+ "evm.deployedBytecode.object",
+ "evm.deployedBytecode.sourceMap"
+ ]
+ }
+ }
+ }
+ },
+ "networks": {}
+} \ No newline at end of file
diff --git a/packages/migrations/compiler.json b/packages/migrations/compiler.json
index e1204b2d1..8f330d39f 100644
--- a/packages/migrations/compiler.json
+++ b/packages/migrations/compiler.json
@@ -1,16 +1,17 @@
{
- "artifactsDir": "artifacts/1.0.0",
+ "artifactsDir": "artifacts/2.0.0",
"contractsDir": "../contracts/src/contracts",
"contracts": [
- "Exchange_v1",
"DummyERC20Token",
+ "DummyERC721Token",
+ "ERC20Proxy",
+ "ERC721Proxy",
+ "Exchange",
+ "MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress",
"ZRXToken",
"WETH9",
- "TokenTransferProxy_v1",
- "MultiSigWallet",
- "MultiSigWalletWithTimeLock",
- "MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress",
- "TokenRegistry"
+ "IWallet",
+ "IValidator"
],
"compilerSettings": {
"outputSelection": {
diff --git a/packages/order-utils/package.json b/packages/order-utils/package.json
index ddb95ba3f..ebfd8b8b4 100644
--- a/packages/order-utils/package.json
+++ b/packages/order-utils/package.json
@@ -1,6 +1,6 @@
{
"name": "@0xproject/order-utils",
- "version": "0.0.5",
+ "version": "0.0.6",
"engines": {
"node": ">=6.12"
},
@@ -9,13 +9,16 @@
"types": "lib/src/index.d.ts",
"scripts": {
"watch": "tsc -w",
+ "prebuild": "run-s clean update_artifacts generate_contract_wrappers",
"build": "tsc && copyfiles -u 3 './lib/src/monorepo_scripts/**/*' ./scripts",
- "test": "run-s clean build run_mocha",
+ "generate_contract_wrappers": "abi-gen --abis 'lib/src/artifacts/@(Exchange|IWallet|IValidator).json' --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/generated_contract_wrappers --backend ethers && prettier --write 'src/generated_contract_wrappers/**.ts'",
+ "update_artifacts": "for i in ${npm_package_config_contracts}; do copyfiles -u 4 ../migrations/artifacts/2.0.0/$i.json lib/src/artifacts; done;",
+ "test": "run-s build run_mocha",
"test:circleci": "yarn test:coverage",
"run_mocha": "mocha lib/test/**/*_test.js --bail --exit",
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
- "clean": "shx rm -rf lib scripts",
+ "clean": "shx rm -rf lib scripts lib/src/artifacts src/generated_contract_wrappers",
"lint": "tslint --project .",
"manual:postpublish": "yarn build; node ./scripts/postpublish.js",
"docs:stage": "node scripts/stage_docs.js",
@@ -23,6 +26,7 @@
"upload_docs_json": "aws s3 cp generated_docs/index.json $S3_URL --profile 0xproject --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --content-type application/json"
},
"config": {
+ "contracts": "IWallet IValidator Exchange",
"postpublish": {
"docPublishConfigs": {
"extraFileIncludes": [
@@ -66,8 +70,10 @@
},
"dependencies": {
"@0xproject/assert": "^0.2.10",
- "@0xproject/json-schemas": "0.7.22",
- "@0xproject/types": "0.7.0",
+ "@0xproject/base-contract": "^0.3.2",
+ "@0xproject/json-schemas": "1.0.0",
+ "@0xproject/sol-compiler": "^0.5.0",
+ "@0xproject/types": "^1.0.0",
"@0xproject/typescript-typings": "^0.3.2",
"@0xproject/utils": "^0.6.2",
"@0xproject/web3-wrapper": "^0.6.4",
@@ -75,6 +81,7 @@
"bn.js": "^4.11.8",
"ethereumjs-abi": "^0.6.4",
"ethereumjs-util": "^5.1.1",
+ "ethers": "^3.0.15",
"lodash": "^4.17.4"
},
"publishConfig": {
diff --git a/packages/order-utils/src/artifacts.ts b/packages/order-utils/src/artifacts.ts
new file mode 100644
index 000000000..f6fd00472
--- /dev/null
+++ b/packages/order-utils/src/artifacts.ts
@@ -0,0 +1,10 @@
+import { Artifact } from '@0xproject/types';
+
+import * as Exchange from './artifacts/Exchange.json';
+import * as IValidator from './artifacts/IValidator.json';
+import * as IWallet from './artifacts/IWallet.json';
+export const artifacts = {
+ Exchange: (Exchange as any) as Artifact,
+ IWallet: (IWallet as any) as Artifact,
+ IValidator: (IValidator as any) as Artifact,
+};
diff --git a/packages/order-utils/src/assert.ts b/packages/order-utils/src/assert.ts
index 5ac402e7e..a1318b9b8 100644
--- a/packages/order-utils/src/assert.ts
+++ b/packages/order-utils/src/assert.ts
@@ -3,12 +3,12 @@ import { assert as sharedAssert } from '@0xproject/assert';
// tslint:disable-next-line:no-unused-variable
import { Schema } from '@0xproject/json-schemas';
// tslint:disable-next-line:no-unused-variable
-import { ECSignature } from '@0xproject/types';
+import { ECSignature, SignatureType } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as _ from 'lodash';
-import { isValidSignature } from './signature_utils';
+import { utils } from './utils';
export const assert = {
...sharedAssert,
@@ -24,4 +24,14 @@ export const assert = {
`Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`,
);
},
+ isOneOfExpectedSignatureTypes(signature: string, signatureTypes: SignatureType[]): void {
+ sharedAssert.isHexString('signature', signature);
+ const signatureTypeIndexIfExists = utils.getSignatureTypeIndexIfExists(signature);
+ const isExpectedSignatureType = _.includes(signatureTypes, signatureTypeIndexIfExists);
+ if (!isExpectedSignatureType) {
+ throw new Error(
+ `Unexpected signatureType: ${signatureTypeIndexIfExists}. Valid signature types: ${signatureTypes}`,
+ );
+ }
+ },
};
diff --git a/packages/contracts/src/utils/asset_proxy_utils.ts b/packages/order-utils/src/asset_proxy_utils.ts
index a17d4cdfa..55f2d56df 100644
--- a/packages/contracts/src/utils/asset_proxy_utils.ts
+++ b/packages/order-utils/src/asset_proxy_utils.ts
@@ -1,8 +1,10 @@
+import { AssetProxyId, ERC20ProxyData, ERC721ProxyData, ProxyData } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import BN = require('bn.js');
import ethUtil = require('ethereumjs-util');
-import { AssetProxyId, ERC20ProxyData, ERC721ProxyData, ProxyData } from './types';
+const ERC20_PROXY_METADATA_BYTE_LENGTH = 21;
+const ERC721_PROXY_METADATA_BYTE_LENGTH = 53;
export const assetProxyUtils = {
encodeAssetProxyId(assetProxyId: AssetProxyId): Buffer {
@@ -26,8 +28,10 @@ export const assetProxyUtils = {
return address;
},
encodeUint256(value: BigNumber): Buffer {
- const formattedValue = new BN(value.toString(10));
+ const base = 10;
+ const formattedValue = new BN(value.toString(base));
const encodedValue = ethUtil.toBuffer(formattedValue);
+ // tslint:disable-next-line:custom-no-magic-numbers
const paddedValue = ethUtil.setLengthLeft(encodedValue, 32);
return paddedValue;
},
@@ -45,7 +49,7 @@ export const assetProxyUtils = {
},
decodeERC20ProxyData(proxyData: string): ERC20ProxyData {
const encodedProxyMetadata = ethUtil.toBuffer(proxyData);
- if (encodedProxyMetadata.byteLength !== 21) {
+ if (encodedProxyMetadata.byteLength !== ERC20_PROXY_METADATA_BYTE_LENGTH) {
throw new Error(
`Could not decode ERC20 Proxy Data. Expected length of encoded data to be 21. Got ${
encodedProxyMetadata.byteLength
@@ -61,7 +65,8 @@ export const assetProxyUtils = {
}), but got ${assetProxyId}`,
);
}
- const encodedTokenAddress = encodedProxyMetadata.slice(0, 20);
+ const addressOffset = ERC20_PROXY_METADATA_BYTE_LENGTH - 1;
+ const encodedTokenAddress = encodedProxyMetadata.slice(0, addressOffset);
const tokenAddress = assetProxyUtils.decodeAddress(encodedTokenAddress);
const erc20ProxyData = {
assetProxyId,
@@ -79,7 +84,7 @@ export const assetProxyUtils = {
},
decodeERC721ProxyData(proxyData: string): ERC721ProxyData {
const encodedProxyMetadata = ethUtil.toBuffer(proxyData);
- if (encodedProxyMetadata.byteLength !== 53) {
+ if (encodedProxyMetadata.byteLength !== ERC721_PROXY_METADATA_BYTE_LENGTH) {
throw new Error(
`Could not decode ERC20 Proxy Data. Expected length of encoded data to be 53. Got ${
encodedProxyMetadata.byteLength
@@ -95,9 +100,11 @@ export const assetProxyUtils = {
}), but got ${assetProxyId}`,
);
}
- const encodedTokenAddress = encodedProxyMetadata.slice(0, 20);
+ const addressOffset = ERC20_PROXY_METADATA_BYTE_LENGTH - 1;
+ const encodedTokenAddress = encodedProxyMetadata.slice(0, addressOffset);
const tokenAddress = assetProxyUtils.decodeAddress(encodedTokenAddress);
- const encodedTokenId = encodedProxyMetadata.slice(20, 52);
+ const tokenIdOffset = ERC721_PROXY_METADATA_BYTE_LENGTH - 1;
+ const encodedTokenId = encodedProxyMetadata.slice(addressOffset, tokenIdOffset);
const tokenId = assetProxyUtils.decodeUint256(encodedTokenId);
const erc721ProxyData = {
assetProxyId,
diff --git a/packages/contracts/src/utils/crypto.ts b/packages/order-utils/src/crypto.ts
index 80c5f30a5..517ca2840 100644
--- a/packages/contracts/src/utils/crypto.ts
+++ b/packages/order-utils/src/crypto.ts
@@ -26,7 +26,8 @@ export const crypto = {
argTypes.push('uint8');
} else if (arg.isBigNumber) {
argTypes.push('uint256');
- args[i] = new BN(arg.toString(10), 10);
+ const base = 10;
+ args[i] = new BN(arg.toString(base), base);
} else if (ethUtil.isValidAddress(arg)) {
argTypes.push('address');
} else if (_.isString(arg)) {
diff --git a/packages/order-utils/src/formatters.ts b/packages/order-utils/src/formatters.ts
deleted file mode 100644
index 2b6f4ddb7..000000000
--- a/packages/order-utils/src/formatters.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { Order, OrderAddresses, OrderValues } from '@0xproject/types';
-import { BigNumber } from '@0xproject/utils';
-
-export const formatters = {
- 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];
- },
-};
diff --git a/packages/order-utils/src/index.ts b/packages/order-utils/src/index.ts
index e9cea95ed..b844fbfcb 100644
--- a/packages/order-utils/src/index.ts
+++ b/packages/order-utils/src/index.ts
@@ -1,11 +1,12 @@
-export { getOrderHashHex, isValidOrderHash } from './order_hash';
-export { isValidSignature, signOrderHashAsync } from './signature_utils';
+export { orderHashUtils } from './order_hash';
+export { isValidSignatureAsync, ecSignOrderHashAsync, addSignedMessagePrefix } from './signature_utils';
export { orderFactory } from './order_factory';
export { constants } from './constants';
+export { crypto } from './crypto';
export { generatePseudoRandomSalt } from './salt';
-export { OrderError } from './types';
-export { formatters } from './formatters';
+export { OrderError, MessagePrefixType, MessagePrefixOpts } from './types';
export { AbstractBalanceAndProxyAllowanceFetcher } from './abstract/abstract_balance_and_proxy_allowance_fetcher';
export { AbstractOrderFilledCancelledFetcher } from './abstract/abstract_order_filled_cancelled_fetcher';
export { RemainingFillableCalculator } from './remaining_fillable_calculator';
export { OrderStateUtils } from './order_state_utils';
+export { assetProxyUtils } from './asset_proxy_utils';
diff --git a/packages/order-utils/src/order_factory.ts b/packages/order-utils/src/order_factory.ts
index 2759aac81..3f3dc524c 100644
--- a/packages/order-utils/src/order_factory.ts
+++ b/packages/order-utils/src/order_factory.ts
@@ -1,49 +1,68 @@
-import { Provider, SignedOrder } from '@0xproject/types';
+import { ECSignature, Provider, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
+import * as ethUtil from 'ethereumjs-util';
import * as _ from 'lodash';
-import { getOrderHashHex } from './order_hash';
+import { orderHashUtils } from './order_hash';
import { generatePseudoRandomSalt } from './salt';
-import { signOrderHashAsync } from './signature_utils';
-
-const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
+import { ecSignOrderHashAsync } from './signature_utils';
+import { MessagePrefixType } from './types';
export const orderFactory = {
async createSignedOrderAsync(
provider: Provider,
- maker: string,
- taker: string,
+ makerAddress: string,
+ takerAddress: string,
+ senderAddress: string,
makerFee: BigNumber,
takerFee: BigNumber,
- makerTokenAmount: BigNumber,
- makerTokenAddress: string,
- takerTokenAmount: BigNumber,
- takerTokenAddress: string,
- exchangeContractAddress: string,
- feeRecipient: string,
- expirationUnixTimestampSecIfExists?: BigNumber,
+ makerAssetAmount: BigNumber,
+ makerAssetData: string,
+ takerAssetAmount: BigNumber,
+ takerAssetData: string,
+ exchangeAddress: string,
+ feeRecipientAddress: string,
+ expirationTimeSecondsIfExists?: BigNumber,
): Promise<SignedOrder> {
const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite
- const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists)
+ const expirationTimeSeconds = _.isUndefined(expirationTimeSecondsIfExists)
? defaultExpirationUnixTimestampSec
- : expirationUnixTimestampSecIfExists;
+ : expirationTimeSecondsIfExists;
const order = {
- maker,
- taker,
+ makerAddress,
+ takerAddress,
+ senderAddress,
makerFee,
takerFee,
- makerTokenAmount,
- takerTokenAmount,
- makerTokenAddress,
- takerTokenAddress,
+ makerAssetAmount,
+ takerAssetAmount,
+ makerAssetData,
+ takerAssetData,
salt: generatePseudoRandomSalt(),
- exchangeContractAddress,
- feeRecipient,
- expirationUnixTimestampSec,
+ exchangeAddress,
+ feeRecipientAddress,
+ expirationTimeSeconds,
+ };
+ const orderHash = orderHashUtils.getOrderHashHex(order);
+ const messagePrefixOpts = {
+ prefixType: MessagePrefixType.EthSign,
+ shouldAddPrefixBeforeCallingEthSign: false,
};
- const orderHash = getOrderHashHex(order);
- const ecSignature = await signOrderHashAsync(provider, orderHash, maker, SHOULD_ADD_PERSONAL_MESSAGE_PREFIX);
- const signedOrder: SignedOrder = _.assign(order, { ecSignature });
+ const ecSignature = await ecSignOrderHashAsync(provider, orderHash, makerAddress, messagePrefixOpts);
+ const signature = getVRSHexString(ecSignature);
+ const signedOrder: SignedOrder = _.assign(order, { signature });
return signedOrder;
},
};
+
+function getVRSHexString(ecSignature: ECSignature): string {
+ const vrs = `0x${intToHex(ecSignature.v)}${ethUtil.stripHexPrefix(ecSignature.r)}${ethUtil.stripHexPrefix(
+ ecSignature.s,
+ )}`;
+ return vrs;
+}
+
+function intToHex(i: number): string {
+ const hex = ethUtil.bufferToHex(ethUtil.toBuffer(i));
+ return hex;
+}
diff --git a/packages/order-utils/src/order_hash.ts b/packages/order-utils/src/order_hash.ts
index 108344a04..a4e36ab89 100644
--- a/packages/order-utils/src/order_hash.ts
+++ b/packages/order-utils/src/order_hash.ts
@@ -1,5 +1,5 @@
import { schemas, SchemaValidator } from '@0xproject/json-schemas';
-import { Order, SignedOrder, SolidityTypes } from '@0xproject/types';
+import { Order, SignatureType, SignedOrder, SolidityTypes } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import BN = require('bn.js');
import * as ethABI from 'ethereumjs-abi';
@@ -7,84 +7,110 @@ import * as ethUtil from 'ethereumjs-util';
import * as _ from 'lodash';
import { assert } from './assert';
+import { crypto } from './crypto';
-const INVALID_TAKER_FORMAT = 'instance.taker is not of a type(s) string';
+const INVALID_TAKER_FORMAT = 'instance.takerAddress is not of a type(s) string';
-/**
- * Converts BigNumber instance to BN
- * The only reason we convert to BN is to remain compatible with `ethABI.soliditySHA3` that
- * expects values of Solidity type `uint` to be passed as type `BN`.
- * We do not use BN anywhere else in the codebase.
- */
-function bigNumberToBN(value: BigNumber): BN {
- const base = 10;
- return new BN(value.toString(), base);
-}
-
-/**
- * Computes the orderHash for a supplied order.
- * @param order An object that conforms to the Order or SignedOrder interface definitions.
- * @return The resulting orderHash from hashing the supplied order.
- */
-export function getOrderHashHex(order: Order | SignedOrder): string {
- try {
- assert.doesConformToSchema('order', order, schemas.orderSchema);
- } catch (error) {
- if (_.includes(error.message, INVALID_TAKER_FORMAT)) {
- const errMsg =
- 'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
- throw new Error(errMsg);
+export const orderHashUtils = {
+ /**
+ * Checks if the supplied hex encoded order hash is valid.
+ * Note: Valid means it has the expected format, not that an order with the orderHash exists.
+ * Use this method when processing orderHashes submitted as user input.
+ * @param orderHash Hex encoded orderHash.
+ * @return Whether the supplied orderHash has the expected format.
+ */
+ isValidOrderHash(orderHash: string): boolean {
+ // Since this method can be called to check if any arbitrary string conforms to an orderHash's
+ // format, we only assert that we were indeed passed a string.
+ assert.isString('orderHash', orderHash);
+ const schemaValidator = new SchemaValidator();
+ const isValid = schemaValidator.validate(orderHash, schemas.orderHashSchema).valid;
+ return isValid;
+ },
+ /**
+ * Computes the orderHash for a supplied order.
+ * @param order An object that conforms to the Order or SignedOrder interface definitions.
+ * @return The resulting orderHash from hashing the supplied order.
+ */
+ getOrderHashHex(order: SignedOrder | Order): string {
+ try {
+ assert.doesConformToSchema('order', order, schemas.orderSchema, [schemas.hexSchema]);
+ } catch (error) {
+ if (_.includes(error.message, INVALID_TAKER_FORMAT)) {
+ const errMsg =
+ 'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
+ throw new Error(errMsg);
+ }
+ throw error;
}
- throw error;
- }
- const orderParts = [
- { value: order.exchangeContractAddress, 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: bigNumberToBN(order.makerTokenAmount),
- type: SolidityTypes.Uint256,
- },
- {
- value: bigNumberToBN(order.takerTokenAmount),
- type: SolidityTypes.Uint256,
- },
- {
- value: bigNumberToBN(order.makerFee),
- type: SolidityTypes.Uint256,
- },
- {
- value: bigNumberToBN(order.takerFee),
- type: SolidityTypes.Uint256,
- },
- {
- value: bigNumberToBN(order.expirationUnixTimestampSec),
- type: SolidityTypes.Uint256,
- },
- { value: 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;
-}
-/**
- * Checks if the supplied hex encoded order hash is valid.
- * Note: Valid means it has the expected format, not that an order with the orderHash exists.
- * Use this method when processing orderHashes submitted as user input.
- * @param orderHash Hex encoded orderHash.
- * @return Whether the supplied orderHash has the expected format.
- */
-export function isValidOrderHash(orderHash: string): boolean {
- // Since this method can be called to check if any arbitrary string conforms to an orderHash's
- // format, we only assert that we were indeed passed a string.
- assert.isString('orderHash', orderHash);
- const schemaValidator = new SchemaValidator();
- const isValid = schemaValidator.validate(orderHash, schemas.orderHashSchema).valid;
- return isValid;
-}
+ const orderHashBuff = this.getOrderHashBuff(order);
+ const orderHashHex = `0x${orderHashBuff.toString('hex')}`;
+ return orderHashHex;
+ },
+ /**
+ * Computes the orderHash for a supplied order and returns it as a Buffer
+ * @param order An object that conforms to the Order or SignedOrder interface definitions.
+ * @return The resulting orderHash from hashing the supplied order as a Buffer
+ */
+ getOrderHashBuff(order: SignedOrder | Order): Buffer {
+ const makerAssetDataHash = crypto.solSHA3([ethUtil.toBuffer(order.makerAssetData)]);
+ const takerAssetDataHash = crypto.solSHA3([ethUtil.toBuffer(order.takerAssetData)]);
+
+ const orderParamsHashBuff = crypto.solSHA3([
+ order.makerAddress,
+ order.takerAddress,
+ order.feeRecipientAddress,
+ order.senderAddress,
+ order.makerAssetAmount,
+ order.takerAssetAmount,
+ order.makerFee,
+ order.takerFee,
+ order.expirationTimeSeconds,
+ order.salt,
+ makerAssetDataHash,
+ takerAssetDataHash,
+ ]);
+ const orderParamsHashHex = `0x${orderParamsHashBuff.toString('hex')}`;
+ const orderSchemaHashHex = this._getOrderSchemaHex();
+ const domainSeparatorHashHex = this._getDomainSeparatorHashHex(order.exchangeAddress);
+ const domainSeparatorSchemaHex = this._getDomainSeparatorSchemaHex();
+ const orderHashBuff = crypto.solSHA3([
+ new BigNumber(domainSeparatorSchemaHex),
+ new BigNumber(domainSeparatorHashHex),
+ new BigNumber(orderSchemaHashHex),
+ new BigNumber(orderParamsHashHex),
+ ]);
+ return orderHashBuff;
+ },
+ _getOrderSchemaHex(): string {
+ const orderSchemaHashBuff = crypto.solSHA3([
+ 'Order(',
+ 'address makerAddress,',
+ 'address takerAddress,',
+ 'address feeRecipientAddress,',
+ 'address senderAddress,',
+ 'uint256 makerAssetAmount,',
+ 'uint256 takerAssetAmount,',
+ 'uint256 makerFee,',
+ 'uint256 takerFee,',
+ 'uint256 expirationTimeSeconds,',
+ 'uint256 salt,',
+ 'bytes makerAssetData,',
+ 'bytes takerAssetData,',
+ ')',
+ ]);
+ const schemaHashHex = `0x${orderSchemaHashBuff.toString('hex')}`;
+ return schemaHashHex;
+ },
+ _getDomainSeparatorSchemaHex(): string {
+ const domainSeparatorSchemaHashBuff = crypto.solSHA3(['DomainSeparator(address contract)']);
+ const schemaHashHex = `0x${domainSeparatorSchemaHashBuff.toString('hex')}`;
+ return schemaHashHex;
+ },
+ _getDomainSeparatorHashHex(exchangeAddress: string): string {
+ const domainSeparatorHashBuff = crypto.solSHA3([exchangeAddress]);
+ const domainSeparatorHashHex = `0x${domainSeparatorHashBuff.toString('hex')}`;
+ return domainSeparatorHashHex;
+ },
+};
diff --git a/packages/order-utils/src/order_state_utils.ts b/packages/order-utils/src/order_state_utils.ts
index 36171f526..61050c9d6 100644
--- a/packages/order-utils/src/order_state_utils.ts
+++ b/packages/order-utils/src/order_state_utils.ts
@@ -11,7 +11,8 @@ import * as _ from 'lodash';
import { AbstractBalanceAndProxyAllowanceFetcher } from './abstract/abstract_balance_and_proxy_allowance_fetcher';
import { AbstractOrderFilledCancelledFetcher } from './abstract/abstract_order_filled_cancelled_fetcher';
-import { getOrderHashHex } from './order_hash';
+import { assetProxyUtils } from './asset_proxy_utils';
+import { orderHashUtils } from './order_hash';
import { RemainingFillableCalculator } from './remaining_fillable_calculator';
const ACCEPTABLE_RELATIVE_ROUNDING_ERROR = 0.0001;
@@ -23,7 +24,7 @@ export class OrderStateUtils {
const unavailableTakerTokenAmount = orderRelevantState.cancelledTakerTokenAmount.add(
orderRelevantState.filledTakerTokenAmount,
);
- const availableTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
+ const availableTakerTokenAmount = signedOrder.takerAssetAmount.minus(unavailableTakerTokenAmount);
if (availableTakerTokenAmount.eq(0)) {
throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
}
@@ -42,9 +43,9 @@ export class OrderStateUtils {
throw new Error(ExchangeContractErrs.InsufficientMakerFeeAllowance);
}
}
- const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerTokenAmount
+ const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerAssetAmount
.dividedBy(ACCEPTABLE_RELATIVE_ROUNDING_ERROR)
- .dividedBy(signedOrder.makerTokenAmount);
+ .dividedBy(signedOrder.makerAssetAmount);
if (
orderRelevantState.remainingFillableTakerTokenAmount.lessThan(
minFillableTakerTokenAmountWithinNoRoundingErrorRange,
@@ -62,7 +63,7 @@ export class OrderStateUtils {
}
public async getOrderStateAsync(signedOrder: SignedOrder): Promise<OrderState> {
const orderRelevantState = await this.getOrderRelevantStateAsync(signedOrder);
- const orderHash = getOrderHashHex(signedOrder);
+ const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
try {
OrderStateUtils._validateIfOrderIsValid(signedOrder, orderRelevantState);
const orderState: OrderStateValid = {
@@ -82,22 +83,22 @@ export class OrderStateUtils {
}
public async getOrderRelevantStateAsync(signedOrder: SignedOrder): Promise<OrderRelevantState> {
const zrxTokenAddress = this._orderFilledCancelledFetcher.getZRXTokenAddress();
- const orderHash = getOrderHashHex(signedOrder);
+ const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
const makerBalance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(
- signedOrder.makerTokenAddress,
- signedOrder.maker,
+ signedOrder.makerAssetData,
+ signedOrder.makerAddress,
);
const makerProxyAllowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync(
- signedOrder.makerTokenAddress,
- signedOrder.maker,
+ signedOrder.makerAssetData,
+ signedOrder.makerAddress,
);
const makerFeeBalance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(
zrxTokenAddress,
- signedOrder.maker,
+ signedOrder.makerAddress,
);
const makerFeeProxyAllowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync(
zrxTokenAddress,
- signedOrder.maker,
+ signedOrder.makerAddress,
);
const filledTakerTokenAmount = await this._orderFilledCancelledFetcher.getFilledTakerAmountAsync(orderHash);
const cancelledTakerTokenAmount = await this._orderFilledCancelledFetcher.getCancelledTakerAmountAsync(
@@ -106,8 +107,8 @@ export class OrderStateUtils {
const unavailableTakerTokenAmount = await this._orderFilledCancelledFetcher.getUnavailableTakerAmountAsync(
orderHash,
);
- const totalMakerTokenAmount = signedOrder.makerTokenAmount;
- const totalTakerTokenAmount = signedOrder.takerTokenAmount;
+ const totalMakerTokenAmount = signedOrder.makerAssetAmount;
+ const totalTakerTokenAmount = signedOrder.takerAssetAmount;
const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount);
const remainingMakerTokenAmount = remainingTakerTokenAmount
.times(totalMakerTokenAmount)
@@ -115,7 +116,8 @@ export class OrderStateUtils {
const transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]);
const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]);
- const isMakerTokenZRX = signedOrder.makerTokenAddress === zrxTokenAddress;
+ const zrxAssetData = assetProxyUtils.encodeERC20ProxyData(zrxTokenAddress);
+ const isMakerTokenZRX = signedOrder.makerAssetData === zrxAssetData;
const remainingFillableCalculator = new RemainingFillableCalculator(
signedOrder,
isMakerTokenZRX,
diff --git a/packages/order-utils/src/remaining_fillable_calculator.ts b/packages/order-utils/src/remaining_fillable_calculator.ts
index 184c13aa4..b291d8ea9 100644
--- a/packages/order-utils/src/remaining_fillable_calculator.ts
+++ b/packages/order-utils/src/remaining_fillable_calculator.ts
@@ -23,7 +23,7 @@ export class RemainingFillableCalculator {
this._remainingMakerTokenAmount = remainingMakerTokenAmount;
this._remainingMakerFeeAmount = remainingMakerTokenAmount
.times(signedOrder.makerFee)
- .dividedToIntegerBy(signedOrder.makerTokenAmount);
+ .dividedToIntegerBy(signedOrder.makerAssetAmount);
}
public computeRemainingMakerFillable(): BigNumber {
if (this._hasSufficientFundsForFeeAndTransferAmount()) {
@@ -36,8 +36,8 @@ export class RemainingFillableCalculator {
}
public computeRemainingTakerFillable(): BigNumber {
return this.computeRemainingMakerFillable()
- .times(this._signedOrder.takerTokenAmount)
- .dividedToIntegerBy(this._signedOrder.makerTokenAmount);
+ .times(this._signedOrder.takerAssetAmount)
+ .dividedToIntegerBy(this._signedOrder.makerAssetAmount);
}
private _hasSufficientFundsForFeeAndTransferAmount(): boolean {
if (this._isMakerTokenZRX) {
@@ -59,7 +59,7 @@ export class RemainingFillableCalculator {
}
private _calculatePartiallyFillableMakerTokenAmount(): BigNumber {
// Given an order for 200 wei for 2 ZRXwei fee, find 100 wei for 1 ZRXwei. Order ratio is then 100:1
- const orderToFeeRatio = this._signedOrder.makerTokenAmount.dividedBy(this._signedOrder.makerFee);
+ const orderToFeeRatio = this._signedOrder.makerAssetAmount.dividedBy(this._signedOrder.makerFee);
// The number of times the maker can fill the order, if each fill only required the transfer of a single
// baseUnit of fee tokens.
// Given 2 ZRXwei, the maximum amount of times Maker can fill this order, in terms of fees, is 2
@@ -81,10 +81,10 @@ export class RemainingFillableCalculator {
// When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored.
// This can result in a RoundingError being thrown by the Exchange Contract.
const partiallyFillableMakerTokenAmount = fillableTimesInMakerTokenUnits
- .times(this._signedOrder.makerTokenAmount)
+ .times(this._signedOrder.makerAssetAmount)
.dividedToIntegerBy(this._signedOrder.makerFee);
const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits
- .times(this._signedOrder.makerTokenAmount)
+ .times(this._signedOrder.makerAssetAmount)
.dividedToIntegerBy(this._signedOrder.makerFee);
const partiallyFillableAmount = BigNumber.min(
partiallyFillableMakerTokenAmount,
diff --git a/packages/order-utils/src/signature_utils.ts b/packages/order-utils/src/signature_utils.ts
index ebd636b20..dadf5052c 100644
--- a/packages/order-utils/src/signature_utils.ts
+++ b/packages/order-utils/src/signature_utils.ts
@@ -1,28 +1,166 @@
import { schemas } from '@0xproject/json-schemas';
-import { ECSignature, Provider } from '@0xproject/types';
+import { ECSignature, Provider, SignatureType, ValidatorSignature } from '@0xproject/types';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as ethUtil from 'ethereumjs-util';
import * as _ from 'lodash';
+import { artifacts } from './artifacts';
import { assert } from './assert';
-import { OrderError } from './types';
+import { ExchangeContract } from './generated_contract_wrappers/exchange';
+import { IValidatorContract } from './generated_contract_wrappers/i_validator';
+import { IWalletContract } from './generated_contract_wrappers/i_wallet';
+import { MessagePrefixOpts, MessagePrefixType, OrderError } from './types';
+import { utils } from './utils';
/**
- * Verifies that the elliptic curve signature `signature` was generated
- * by signing `data` with the private key corresponding to the `signerAddress` address.
+ * Verifies that the provided signature is valid according to the 0x Protocol smart contracts
* @param data The hex encoded data signed by the supplied signature.
- * @param signature An object containing the elliptic curve signature parameters.
+ * @param signature A hex encoded 0x Protocol signature made up of: [SignatureType][TypeSpecificData].
+ * E.g [SignatureType.EIP712][vrs]
* @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
* @return Whether the signature is valid for the supplied signerAddress and data.
*/
-export function isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
+export async function isValidSignatureAsync(
+ provider: Provider,
+ data: string,
+ signature: string,
+ signerAddress: string,
+): Promise<boolean> {
+ const signatureTypeIndexIfExists = utils.getSignatureTypeIndexIfExists(signature);
+ if (_.isUndefined(signatureTypeIndexIfExists)) {
+ throw new Error(`Unrecognized signatureType in signature: ${signature}`);
+ }
+
+ switch (signatureTypeIndexIfExists) {
+ case SignatureType.Illegal:
+ case SignatureType.Invalid:
+ return false;
+
+ case SignatureType.EIP712: {
+ const ecSignature = parseECSignature(signature);
+ return isValidECSignature(data, ecSignature, signerAddress);
+ }
+
+ case SignatureType.EthSign: {
+ const ecSignature = parseECSignature(signature);
+ const prefixedMessageHex = addSignedMessagePrefix(data, MessagePrefixType.EthSign);
+ return isValidECSignature(prefixedMessageHex, ecSignature, signerAddress);
+ }
+
+ case SignatureType.Caller:
+ // HACK: We currently do not "validate" the caller signature type.
+ // It can only be validated during Exchange contract execution.
+ throw new Error('Caller signature type cannot be validated off-chain');
+
+ case SignatureType.Wallet: {
+ const isValid = await isValidWalletSignatureAsync(provider, data, signature, signerAddress);
+ return isValid;
+ }
+
+ case SignatureType.Validator: {
+ const isValid = await isValidValidatorSignatureAsync(provider, data, signature, signerAddress);
+ return isValid;
+ }
+
+ case SignatureType.PreSigned: {
+ return isValidPresignedSignatureAsync(provider, data, signerAddress);
+ }
+
+ case SignatureType.Trezor: {
+ const prefixedMessageHex = addSignedMessagePrefix(data, MessagePrefixType.Trezor);
+ const ecSignature = parseECSignature(signature);
+ return isValidECSignature(prefixedMessageHex, ecSignature, signerAddress);
+ }
+
+ default:
+ throw new Error(`Unhandled SignatureType: ${signatureTypeIndexIfExists}`);
+ }
+}
+
+/**
+ * Verifies that the provided presigned signature is valid according to the 0x Protocol smart contracts
+ * @param data The hex encoded data signed by the supplied signature.
+ * @param signature A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
+ * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
+ * @return Whether the data was preSigned by the supplied signerAddress.
+ */
+export async function isValidPresignedSignatureAsync(
+ provider: Provider,
+ data: string,
+ signerAddress: string,
+): Promise<boolean> {
+ const exchangeContract = new ExchangeContract(artifacts.Exchange.abi, signerAddress, provider);
+ const isValid = await exchangeContract.preSigned.callAsync(data, signerAddress);
+ return isValid;
+}
+
+/**
+ * Verifies that the provided wallet signature is valid according to the 0x Protocol smart contracts
+ * @param data The hex encoded data signed by the supplied signature.
+ * @param signature A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
+ * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
+ * @return Whether the data was preSigned by the supplied signerAddress.
+ */
+export async function isValidWalletSignatureAsync(
+ provider: Provider,
+ data: string,
+ signature: string,
+ signerAddress: string,
+): Promise<boolean> {
+ // tslint:disable-next-line:custom-no-magic-numbers
+ const signatureWithoutType = signature.slice(-2);
+ const walletContract = new IWalletContract(artifacts.IWallet.abi, signerAddress, provider);
+ const isValid = await walletContract.isValidSignature.callAsync(data, signatureWithoutType);
+ return isValid;
+}
+
+/**
+ * Verifies that the provided validator signature is valid according to the 0x Protocol smart contracts
+ * @param data The hex encoded data signed by the supplied signature.
+ * @param signature A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
+ * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
+ * @return Whether the data was preSigned by the supplied signerAddress.
+ */
+export async function isValidValidatorSignatureAsync(
+ provider: Provider,
+ data: string,
+ signature: string,
+ signerAddress: string,
+): Promise<boolean> {
+ const validatorSignature = parseValidatorSignature(signature);
+ const exchangeContract = new ExchangeContract(artifacts.Exchange.abi, signerAddress, provider);
+ const isValidatorApproved = await exchangeContract.allowedValidators.callAsync(
+ signerAddress,
+ validatorSignature.validatorAddress,
+ );
+ if (!isValidatorApproved) {
+ throw new Error(`Validator ${validatorSignature.validatorAddress} was not pre-approved by ${signerAddress}.`);
+ }
+
+ const validatorContract = new IValidatorContract(artifacts.IValidator.abi, signerAddress, provider);
+ const isValid = await validatorContract.isValidSignature.callAsync(
+ data,
+ signerAddress,
+ validatorSignature.signature,
+ );
+ return isValid;
+}
+
+/**
+ * Checks if the supplied elliptic curve signature corresponds to signing `data` with
+ * the private key corresponding to `signerAddress`
+ * @param data The hex encoded data signed by the supplied signature.
+ * @param signature An object containing the elliptic curve signature parameters.
+ * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
+ * @return Whether the ECSignature is valid.
+ */
+export function isValidECSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
assert.isHexString('data', data);
assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema);
assert.isETHAddressHex('signerAddress', signerAddress);
const normalizedSignerAddress = signerAddress.toLowerCase();
- const dataBuff = ethUtil.toBuffer(data);
- const msgHashBuff = ethUtil.hashPersonalMessage(dataBuff);
+ const msgHashBuff = ethUtil.toBuffer(data);
try {
const pubKey = ethUtil.ecrecover(
msgHashBuff,
@@ -36,23 +174,23 @@ export function isValidSignature(data: string, signature: ECSignature, signerAdd
return false;
}
}
+
/**
* Signs an orderHash and returns it's elliptic curve signature.
* This method currently supports TestRPC, Geth and Parity above and below V1.6.6
* @param orderHash Hex encoded orderHash to sign.
* @param signerAddress The hex encoded Ethereum address you wish to sign it with. This address
* must be available via the Provider supplied to 0x.js.
- * @param shouldAddPersonalMessagePrefix Some signers add the personal message prefix `\x19Ethereum Signed Message`
- * themselves (e.g Parity Signer, Ledger, TestRPC) and others expect it to already be done by the client
- * (e.g Metamask). Depending on which signer this request is going to, decide on whether to add the prefix
- * before sending the request.
+ * @param hashPrefixOpts Different signers add/require different prefixes be appended to the message being signed.
+ * Since we cannot know ahead of time which signer you are using, you must supply both a prefixType and
+ * whether it must be added before calling `eth_sign` (some signers add it themselves)
* @return An object containing the Elliptic curve signature parameters generated by signing the orderHash.
*/
-export async function signOrderHashAsync(
+export async function ecSignOrderHashAsync(
provider: Provider,
orderHash: string,
signerAddress: string,
- shouldAddPersonalMessagePrefix: boolean,
+ messagePrefixOpts: MessagePrefixOpts,
): Promise<ECSignature> {
assert.isHexString('orderHash', orderHash);
const web3Wrapper = new Web3Wrapper(provider);
@@ -60,12 +198,10 @@ export async function signOrderHashAsync(
const normalizedSignerAddress = signerAddress.toLowerCase();
let msgHashHex = orderHash;
- if (shouldAddPersonalMessagePrefix) {
- const orderHashBuff = ethUtil.toBuffer(orderHash);
- const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff);
- msgHashHex = ethUtil.bufferToHex(msgHashBuff);
+ const prefixedMsgHashHex = addSignedMessagePrefix(orderHash, messagePrefixOpts.prefixType);
+ if (messagePrefixOpts.shouldAddPrefixBeforeCallingEthSign) {
+ msgHashHex = prefixedMsgHashHex;
}
-
const signature = await web3Wrapper.signMessageAsync(normalizedSignerAddress, msgHashHex);
// HACK: There is no consensus on whether the signatureHex string should be formatted as
@@ -76,7 +212,7 @@ export async function signOrderHashAsync(
const validVParamValues = [27, 28];
const ecSignatureVRS = parseSignatureHexAsVRS(signature);
if (_.includes(validVParamValues, ecSignatureVRS.v)) {
- const isValidVRSSignature = isValidSignature(orderHash, ecSignatureVRS, normalizedSignerAddress);
+ const isValidVRSSignature = isValidECSignature(prefixedMsgHashHex, ecSignatureVRS, normalizedSignerAddress);
if (isValidVRSSignature) {
return ecSignatureVRS;
}
@@ -84,7 +220,7 @@ export async function signOrderHashAsync(
const ecSignatureRSV = parseSignatureHexAsRSV(signature);
if (_.includes(validVParamValues, ecSignatureRSV.v)) {
- const isValidRSVSignature = isValidSignature(orderHash, ecSignatureRSV, normalizedSignerAddress);
+ const isValidRSVSignature = isValidECSignature(prefixedMsgHashHex, ecSignatureRSV, normalizedSignerAddress);
if (isValidRSVSignature) {
return ecSignatureRSV;
}
@@ -93,6 +229,57 @@ export async function signOrderHashAsync(
throw new Error(OrderError.InvalidSignature);
}
+export function addSignedMessagePrefix(message: string, messagePrefixType: MessagePrefixType): string {
+ switch (messagePrefixType) {
+ case MessagePrefixType.None:
+ return message;
+
+ case MessagePrefixType.EthSign: {
+ const msgBuff = ethUtil.toBuffer(message);
+ const prefixedMsgBuff = ethUtil.hashPersonalMessage(msgBuff);
+ const prefixedMsgHex = ethUtil.bufferToHex(prefixedMsgBuff);
+ return prefixedMsgHex;
+ }
+
+ case MessagePrefixType.Trezor: {
+ const msgBuff = ethUtil.toBuffer(message);
+ const prefixedMsgBuff = hashTrezorPersonalMessage(msgBuff);
+ const prefixedMsgHex = ethUtil.bufferToHex(prefixedMsgBuff);
+ return prefixedMsgHex;
+ }
+
+ default:
+ throw new Error(`Unrecognized MessagePrefixType: ${messagePrefixType}`);
+ }
+}
+
+function hashTrezorPersonalMessage(message: Buffer): Buffer {
+ const prefix = ethUtil.toBuffer('\x19Ethereum Signed Message:\n' + String.fromCharCode(message.length));
+ return ethUtil.sha3(Buffer.concat([prefix, message]));
+}
+
+function parseECSignature(signature: string): ECSignature {
+ const ecSignatureTypes = [SignatureType.EthSign, SignatureType.EIP712, SignatureType.Trezor];
+ assert.isOneOfExpectedSignatureTypes(signature, ecSignatureTypes);
+
+ // tslint:disable-next-line:custom-no-magic-numbers
+ const vrsHex = signature.slice(0, -2);
+ const ecSignature = parseSignatureHexAsVRS(vrsHex);
+
+ return ecSignature;
+}
+
+function parseValidatorSignature(signature: string): ValidatorSignature {
+ assert.isOneOfExpectedSignatureTypes(signature, [SignatureType.Validator]);
+ // tslint:disable:custom-no-magic-numbers
+ const validatorSignature = {
+ validatorAddress: signature.slice(-22, -2),
+ signature: signature.slice(0, -22),
+ };
+ // tslint:enable:custom-no-magic-numbers
+ return validatorSignature;
+}
+
function parseSignatureHexAsVRS(signatureHex: string): ECSignature {
const signatureBuffer = ethUtil.toBuffer(signatureHex);
let v = signatureBuffer[0];
diff --git a/packages/order-utils/src/types.ts b/packages/order-utils/src/types.ts
index f79d52359..db0bfb249 100644
--- a/packages/order-utils/src/types.ts
+++ b/packages/order-utils/src/types.ts
@@ -1,3 +1,25 @@
export enum OrderError {
InvalidSignature = 'INVALID_SIGNATURE',
}
+
+/**
+ * The requisite message prefix (is any) to add to an `eth_sign` request.
+ */
+export enum MessagePrefixType {
+ None = 'NONE',
+ EthSign = 'ETH_SIGN',
+ Trezor = 'TREZOR',
+}
+
+/**
+ * Options related to message prefixing of messages sent to `eth_sign`
+ * Some signers prepend a message prefix (e.g Parity Signer, Ledger, TestRPC), while
+ * others require it already be prepended (e.g Metamask). In addition, different signers
+ * expect slightly different prefixes (See: https://github.com/ethereum/go-ethereum/issues/14794).
+ * Depending on the signer that will receive your signing request, you must specify the
+ * desired prefix and whether it should be added before making the `eth_sign` request.
+ */
+export interface MessagePrefixOpts {
+ prefixType: MessagePrefixType;
+ shouldAddPrefixBeforeCallingEthSign: boolean;
+}
diff --git a/packages/order-utils/src/utils.ts b/packages/order-utils/src/utils.ts
new file mode 100644
index 000000000..3b465cece
--- /dev/null
+++ b/packages/order-utils/src/utils.ts
@@ -0,0 +1,9 @@
+export const utils = {
+ getSignatureTypeIndexIfExists(signature: string): number {
+ // tslint:disable-next-line:custom-no-magic-numbers
+ const signatureTypeHex = signature.slice(-2);
+ const base = 16;
+ const signatureTypeInt = parseInt(signatureTypeHex, base);
+ return signatureTypeInt;
+ },
+};
diff --git a/packages/order-utils/test/order_hash_test.ts b/packages/order-utils/test/order_hash_test.ts
index db5489509..d571fc62a 100644
--- a/packages/order-utils/test/order_hash_test.ts
+++ b/packages/order-utils/test/order_hash_test.ts
@@ -1,10 +1,11 @@
import { web3Factory } from '@0xproject/dev-utils';
+import { Order } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
import 'make-promises-safe';
import 'mocha';
-import { constants, getOrderHashHex } from '../src';
+import { constants, orderHashUtils } from '../src';
import { chaiSetup } from './utils/chai_setup';
import { web3Wrapper } from './utils/web3_wrapper';
@@ -14,34 +15,50 @@ const expect = chai.expect;
describe('Order hashing', () => {
describe('#getOrderHashHex', () => {
- const expectedOrderHash = '0x39da987067a3c9e5f1617694f1301326ba8c8b0498ebef5df4863bed394e3c83';
+ const expectedOrderHash = '0x367ad7730eb8b5feab8a9c9f47c6fcba77a2d4df125ee6a59cc26ac955710f7e';
const fakeExchangeContractAddress = '0xb69e673309512a9d726f87304c6984054f87a93b';
- const order = {
- maker: constants.NULL_ADDRESS,
- taker: constants.NULL_ADDRESS,
- feeRecipient: constants.NULL_ADDRESS,
- makerTokenAddress: constants.NULL_ADDRESS,
- takerTokenAddress: constants.NULL_ADDRESS,
- exchangeContractAddress: fakeExchangeContractAddress,
+ const order: Order = {
+ makerAddress: constants.NULL_ADDRESS,
+ takerAddress: constants.NULL_ADDRESS,
+ senderAddress: constants.NULL_ADDRESS,
+ feeRecipientAddress: constants.NULL_ADDRESS,
+ makerAssetData: constants.NULL_ADDRESS,
+ takerAssetData: constants.NULL_ADDRESS,
+ exchangeAddress: fakeExchangeContractAddress,
salt: new BigNumber(0),
makerFee: new BigNumber(0),
takerFee: new BigNumber(0),
- makerTokenAmount: new BigNumber(0),
- takerTokenAmount: new BigNumber(0),
- expirationUnixTimestampSec: new BigNumber(0),
+ makerAssetAmount: new BigNumber(0),
+ takerAssetAmount: new BigNumber(0),
+ expirationTimeSeconds: new BigNumber(0),
};
it('calculates the order hash', async () => {
- const orderHash = getOrderHashHex(order);
+ const orderHash = orderHashUtils.getOrderHashHex(order);
expect(orderHash).to.be.equal(expectedOrderHash);
});
it('throws a readable error message if taker format is invalid', async () => {
const orderWithInvalidtakerFormat = {
...order,
- taker: (null as any) as string,
+ takerAddress: (null as any) as string,
};
const expectedErrorMessage =
'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
- expect(() => getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
+ expect(() => orderHashUtils.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
+ });
+ });
+ describe('#isValidOrderHash', () => {
+ it('returns false if the value is not a hex string', () => {
+ const isValid = orderHashUtils.isValidOrderHash('not a hex');
+ expect(isValid).to.be.false();
+ });
+ it('returns false if the length is wrong', () => {
+ const isValid = orderHashUtils.isValidOrderHash('0xdeadbeef');
+ expect(isValid).to.be.false();
+ });
+ it('returns true if order hash is correct', () => {
+ const orderHashLength = 65;
+ const isValid = orderHashUtils.isValidOrderHash('0x' + Array(orderHashLength).join('0'));
+ expect(isValid).to.be.true();
});
});
});
diff --git a/packages/order-utils/test/signature_utils_test.ts b/packages/order-utils/test/signature_utils_test.ts
index e24fa0ce5..16d961ed7 100644
--- a/packages/order-utils/test/signature_utils_test.ts
+++ b/packages/order-utils/test/signature_utils_test.ts
@@ -7,8 +7,8 @@ import 'make-promises-safe';
import 'mocha';
import * as Sinon from 'sinon';
-import { generatePseudoRandomSalt, isValidOrderHash, isValidSignature, signOrderHashAsync } from '../src';
-import * as signatureUtils from '../src/signature_utils';
+import { ecSignOrderHashAsync, generatePseudoRandomSalt, MessagePrefixType, orderHashUtils } from '../src';
+import { isValidECSignature, isValidSignatureAsync } from '../src/signature_utils';
import { chaiSetup } from './utils/chai_setup';
import { provider, web3Wrapper } from './utils/web3_wrapper';
@@ -16,32 +16,82 @@ import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
const expect = chai.expect;
-const SHOULD_ADD_PERSONAL_MESSAGE_PREFIX = false;
-
describe('Signature utils', () => {
describe('#isValidSignature', () => {
- // The Exchange smart contract `isValidSignature` method only validates orderHashes and assumes
- // the length of the data is exactly 32 bytes. Thus for these tests, we use data of this size.
- const dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
+ let dataHex = '0x6927e990021d23b1eb7b8789f6a6feaf98fe104bb0cf8259421b79f9a34222b0';
+ const ethSignSignature =
+ '0x1B61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc3340349190569279751135161d22529dc25add4f6069af05be04cacbda2ace225403';
+ let address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
+
+ it("should return false if the data doesn't pertain to the signature & address", async () => {
+ expect(await isValidSignatureAsync(provider, '0x0', ethSignSignature, address)).to.be.false();
+ });
+ it("should return false if the address doesn't pertain to the signature & data", async () => {
+ const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
+ expect(
+ await isValidSignatureAsync(provider, dataHex, ethSignSignature, validUnrelatedAddress),
+ ).to.be.false();
+ });
+ it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
+ const signatureArray = ethSignSignature.split('');
+ // tslint:disable-next-line:custom-no-magic-numbers
+ signatureArray[5] = 'C'; // V = 28, instead of 27
+ const wrongSignature = signatureArray.join('');
+ expect(await isValidSignatureAsync(provider, dataHex, wrongSignature, address)).to.be.false();
+ });
+
+ it('should throw if signatureType is invalid', () => {
+ const signatureArray = ethSignSignature.split('');
+ signatureArray[3] = '9'; // SignatureType w/ index 9 doesn't exist
+ const signatureWithInvalidType = signatureArray.join('');
+ expect(isValidSignatureAsync(provider, dataHex, signatureWithInvalidType, address)).to.be.rejected();
+ });
+
+ it('should return true for a valid Ecrecover (EthSign) signature', async () => {
+ const isValidSignatureLocal = await isValidSignatureAsync(provider, dataHex, ethSignSignature, address);
+ expect(isValidSignatureLocal).to.be.true();
+ });
+
+ it('should return true for a valid EIP712 signature', async () => {
+ dataHex = '0xa1d7403bcbbcd75ec233cfd6584ff8dabed677d0e9bb32c2bea94e9dd8a109da';
+ address = '0x6ecbe1db9ef729cbe972c83fb886247691fb6beb';
+ const eip712Signature =
+ '0x1bdde07aac4bf12c12ddbb155919c43eba4146a2cfcf904a862950dbebe332554c6674975603eb5a4eaf8fd7f2e06350267e5b36cda9851a89f8bb49fe2fc9afe202';
+ const isValidSignatureLocal = await isValidSignatureAsync(provider, dataHex, eip712Signature, address);
+ expect(isValidSignatureLocal).to.be.true();
+ });
+
+ it('should return true for a valid Trezor signature', async () => {
+ dataHex = '0xd0d994e31c88f33fd8a572552a70ed339de579e5ba49ee1d17cc978bbe1cdd21';
+ address = '0x6ecbe1db9ef729cbe972c83fb886247691fb6beb';
+ const trezorSignature =
+ '0x1ce4760660e6495b5ae6723087bea073b3a99ce98ea81fdf00c240279c010e63d05b87bc34c4d67d4776e8d5aeb023a67484f4eaf0fd353b40893e5101e845cd9908';
+ const isValidSignatureLocal = await isValidSignatureAsync(provider, dataHex, trezorSignature, address);
+ expect(isValidSignatureLocal).to.be.true();
+ });
+ });
+ describe('#isValidECSignature', () => {
const signature = {
v: 27,
- r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
- s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
+ r: '0xaca7da997ad177f040240cdccf6905b71ab16b74434388c3a72f34fd25d64393',
+ s: '0x46b2bac274ff29b48b3ea6e2d04c1336eaceafda3c53ab483fc3ff12fac3ebf2',
};
- const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
+ const data = '0x47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad';
+ const address = '0x0e5cb767cce09a7f3ca594df118aa519be5e2b5a';
+
it("should return false if the data doesn't pertain to the signature & address", async () => {
- expect(isValidSignature('0x0', signature, address)).to.be.false();
+ expect(isValidECSignature('0x0', signature, address)).to.be.false();
});
it("should return false if the address doesn't pertain to the signature & data", async () => {
const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
- expect(isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false();
+ expect(isValidECSignature(data, signature, validUnrelatedAddress)).to.be.false();
});
- it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
+ it("should return false if the signature doesn't pertain to the data & address", async () => {
const wrongSignature = _.assign({}, signature, { v: 28 });
- expect(isValidSignature(dataHex, wrongSignature, address)).to.be.false();
+ expect(isValidECSignature(data, wrongSignature, address)).to.be.false();
});
- it('should return true if the signature does pertain to the dataHex & address', async () => {
- const isValidSignatureLocal = isValidSignature(dataHex, signature, address);
+ it('should return true if the signature does pertain to the data & address', async () => {
+ const isValidSignatureLocal = isValidECSignature(data, signature, address);
expect(isValidSignatureLocal).to.be.true();
});
});
@@ -58,22 +108,7 @@ describe('Signature utils', () => {
expect(salt.lessThan(twoPow256)).to.be.true();
});
});
- describe('#isValidOrderHash', () => {
- it('returns false if the value is not a hex string', () => {
- const isValid = isValidOrderHash('not a hex');
- expect(isValid).to.be.false();
- });
- it('returns false if the length is wrong', () => {
- const isValid = isValidOrderHash('0xdeadbeef');
- expect(isValid).to.be.false();
- });
- it('returns true if order hash is correct', () => {
- const orderHashLength = 65;
- const isValid = isValidOrderHash('0x' + Array(orderHashLength).join('0'));
- expect(isValid).to.be.true();
- });
- });
- describe('#signOrderHashAsync', () => {
+ describe('#ecSignOrderHashAsync', () => {
let stubs: Sinon.SinonStub[] = [];
let makerAddress: string;
before(async () => {
@@ -92,12 +127,11 @@ describe('Signature utils', () => {
r: '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33',
s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
};
- const ecSignature = await signOrderHashAsync(
- provider,
- orderHash,
- makerAddress,
- SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
- );
+ const messagePrefixOpts = {
+ prefixType: MessagePrefixType.EthSign,
+ shouldAddPrefixBeforeCallingEthSign: false,
+ };
+ const ecSignature = await ecSignOrderHashAsync(provider, orderHash, makerAddress, messagePrefixOpts);
expect(ecSignature).to.deep.equal(expectedECSignature);
});
it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
@@ -126,12 +160,11 @@ describe('Signature utils', () => {
},
};
- const ecSignature = await signOrderHashAsync(
- fakeProvider,
- orderHash,
- makerAddress,
- SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
- );
+ const messagePrefixOpts = {
+ prefixType: MessagePrefixType.EthSign,
+ shouldAddPrefixBeforeCallingEthSign: false,
+ };
+ const ecSignature = await ecSignOrderHashAsync(fakeProvider, orderHash, makerAddress, messagePrefixOpts);
expect(ecSignature).to.deep.equal(expectedECSignature);
});
it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
@@ -157,12 +190,11 @@ describe('Signature utils', () => {
},
};
- const ecSignature = await signOrderHashAsync(
- fakeProvider,
- orderHash,
- makerAddress,
- SHOULD_ADD_PERSONAL_MESSAGE_PREFIX,
- );
+ const messagePrefixOpts = {
+ prefixType: MessagePrefixType.EthSign,
+ shouldAddPrefixBeforeCallingEthSign: false,
+ };
+ const ecSignature = await ecSignOrderHashAsync(fakeProvider, orderHash, makerAddress, messagePrefixOpts);
expect(ecSignature).to.deep.equal(expectedECSignature);
});
});
diff --git a/packages/order-watcher/package.json b/packages/order-watcher/package.json
index 8d9283978..fcc40d56d 100644
--- a/packages/order-watcher/package.json
+++ b/packages/order-watcher/package.json
@@ -81,7 +81,7 @@
"@0xproject/contract-wrappers": "^0.0.2",
"@0xproject/fill-scenarios": "^0.0.2",
"@0xproject/json-schemas": "0.7.22",
- "@0xproject/order-utils": "^0.0.5",
+ "@0xproject/order-utils": "0.0.5",
"@0xproject/types": "0.7.0",
"@0xproject/typescript-typings": "^0.3.2",
"@0xproject/utils": "^0.6.2",
diff --git a/packages/sra-report/package.json b/packages/sra-report/package.json
index cc34b5ced..8903f5c81 100644
--- a/packages/sra-report/package.json
+++ b/packages/sra-report/package.json
@@ -33,7 +33,7 @@
"dependencies": {
"@0xproject/assert": "^0.2.10",
"@0xproject/types": "0.7.0",
- "@0xproject/order-utils": "^0.0.5",
+ "@0xproject/order-utils": "0.0.5",
"@0xproject/connect": "0.6.12",
"@0xproject/json-schemas": "0.7.22",
"@0xproject/typescript-typings": "^0.3.2",
diff --git a/packages/types/package.json b/packages/types/package.json
index 376eb1d68..95b7721d3 100644
--- a/packages/types/package.json
+++ b/packages/types/package.json
@@ -1,6 +1,6 @@
{
"name": "@0xproject/types",
- "version": "0.7.1",
+ "version": "1.0.0",
"engines": {
"node": ">=6.12"
},
diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts
index 47f3e3239..8bd6e097e 100644
--- a/packages/types/src/index.ts
+++ b/packages/types/src/index.ts
@@ -12,16 +12,28 @@ export interface Order {
makerAssetData: string;
takerAssetData: string;
salt: BigNumber;
+ exchangeAddress: string;
feeRecipientAddress: string;
expirationTimeSeconds: BigNumber;
}
-export interface SignedOrder extends UnsignedOrder {
- signature: string;
+export interface OrderWithoutExchangeAddress {
+ senderAddress: string;
+ makerAddress: string;
+ takerAddress: string;
+ makerFee: BigNumber;
+ takerFee: BigNumber;
+ makerAssetAmount: BigNumber;
+ takerAssetAmount: BigNumber;
+ makerAssetData: string;
+ takerAssetData: string;
+ salt: BigNumber;
+ feeRecipientAddress: string;
+ expirationTimeSeconds: BigNumber;
}
-export interface UnsignedOrder extends Order {
- exchangeAddress: string;
+export interface SignedOrder extends Order {
+ signature: string;
}
/**
@@ -34,6 +46,14 @@ export interface ECSignature {
}
/**
+ * Validator signature components
+ */
+export interface ValidatorSignature {
+ validatorAddress: string;
+ signature: string;
+}
+
+/**
* Errors originating from the 0x exchange contract
*/
export enum ExchangeContractErrs {
@@ -106,3 +126,47 @@ export interface Token {
symbol: string;
decimals: number;
}
+
+export enum SignatureType {
+ Illegal,
+ Invalid,
+ EIP712,
+ EthSign,
+ Caller,
+ Wallet,
+ Validator,
+ PreSigned,
+ Trezor,
+}
+
+/**
+ * Elliptic Curve signature
+ */
+export interface ECSignature {
+ v: number;
+ r: string;
+ s: string;
+}
+
+export enum AssetProxyId {
+ INVALID,
+ ERC20,
+ ERC721,
+}
+
+export interface ERC20ProxyData {
+ assetProxyId: AssetProxyId;
+ tokenAddress: string;
+}
+
+export interface ERC721ProxyData {
+ assetProxyId: AssetProxyId;
+ tokenAddress: string;
+ tokenId: BigNumber;
+}
+
+export interface ProxyData {
+ assetProxyId: AssetProxyId;
+ tokenAddress?: string;
+ data?: any;
+}