diff options
Diffstat (limited to 'packages/contracts/util')
-rw-r--r-- | packages/contracts/util/exchange_wrapper.ts | 30 | ||||
-rw-r--r-- | packages/contracts/util/formatters.ts | 100 | ||||
-rw-r--r-- | packages/contracts/util/order.ts | 47 | ||||
-rw-r--r-- | packages/contracts/util/order_factory.ts | 44 | ||||
-rw-r--r-- | packages/contracts/util/signed_order.ts | 92 | ||||
-rw-r--r-- | packages/contracts/util/signed_order_utils.ts | 49 | ||||
-rw-r--r-- | packages/contracts/util/types.ts | 35 |
7 files changed, 142 insertions, 255 deletions
diff --git a/packages/contracts/util/exchange_wrapper.ts b/packages/contracts/util/exchange_wrapper.ts index ff263246f..03d04629d 100644 --- a/packages/contracts/util/exchange_wrapper.ts +++ b/packages/contracts/util/exchange_wrapper.ts @@ -1,4 +1,4 @@ -import { TransactionReceiptWithDecodedLogs, ZeroEx } from '0x.js'; +import { SignedOrder, TransactionReceiptWithDecodedLogs, ZeroEx } from '0x.js'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import * as Web3 from 'web3'; @@ -6,7 +6,7 @@ import * as Web3 from 'web3'; import { ExchangeContract } from '../src/contract_wrappers/generated/exchange'; import { formatters } from './formatters'; -import { SignedOrder } from './signed_order'; +import { signedOrderUtils } from './signed_order_utils'; export class ExchangeWrapper { private _exchange: ExchangeContract; @@ -24,7 +24,11 @@ export class ExchangeWrapper { } = {}, ): Promise<TransactionReceiptWithDecodedLogs> { const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance; - const params = signedOrder.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount); + const params = signedOrderUtils.createFill( + signedOrder, + shouldThrowOnInsufficientBalanceOrAllowance, + opts.fillTakerTokenAmount, + ); const txHash = await this._exchange.fillOrder.sendTransactionAsync( params.orderAddresses, params.orderValues, @@ -45,7 +49,7 @@ export class ExchangeWrapper { from: string, opts: { cancelTakerTokenAmount?: BigNumber } = {}, ): Promise<TransactionReceiptWithDecodedLogs> { - const params = signedOrder.createCancel(opts.cancelTakerTokenAmount); + const params = signedOrderUtils.createCancel(signedOrder, opts.cancelTakerTokenAmount); const txHash = await this._exchange.cancelOrder.sendTransactionAsync( params.orderAddresses, params.orderValues, @@ -63,7 +67,11 @@ export class ExchangeWrapper { opts: { fillTakerTokenAmount?: BigNumber } = {}, ): Promise<TransactionReceiptWithDecodedLogs> { const shouldThrowOnInsufficientBalanceOrAllowance = true; - const params = signedOrder.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount); + const params = signedOrderUtils.createFill( + signedOrder, + shouldThrowOnInsufficientBalanceOrAllowance, + opts.fillTakerTokenAmount, + ); const txHash = await this._exchange.fillOrKillOrder.sendTransactionAsync( params.orderAddresses, params.orderValues, @@ -177,17 +185,17 @@ export class ExchangeWrapper { } public async getOrderHashAsync(signedOrder: SignedOrder): Promise<string> { const shouldThrowOnInsufficientBalanceOrAllowance = false; - const params = signedOrder.createFill(shouldThrowOnInsufficientBalanceOrAllowance); + const params = signedOrderUtils.getOrderAddressesAndValues(signedOrder); const orderHash = await this._exchange.getOrderHash(params.orderAddresses, params.orderValues); return orderHash; } public async isValidSignatureAsync(signedOrder: SignedOrder): Promise<boolean> { const isValidSignature = await this._exchange.isValidSignature( - signedOrder.params.maker, - signedOrder.getOrderHashHex(), - signedOrder.params.v, - signedOrder.params.r, - signedOrder.params.s, + signedOrder.maker, + ZeroEx.getOrderHashHex(signedOrder), + signedOrder.ecSignature.v, + signedOrder.ecSignature.r, + signedOrder.ecSignature.s, ); return isValidSignature; } diff --git a/packages/contracts/util/formatters.ts b/packages/contracts/util/formatters.ts index 6c225268e..8e0dfb09e 100644 --- a/packages/contracts/util/formatters.ts +++ b/packages/contracts/util/formatters.ts @@ -1,12 +1,12 @@ +import { SignedOrder } from '0x.js'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; -import { SignedOrder } from './signed_order'; import { BatchCancelOrders, BatchFillOrders, FillOrdersUpTo } from './types'; export const formatters = { createBatchFill( - orders: SignedOrder[], + signedOrders: SignedOrder[], shouldThrowOnInsufficientBalanceOrAllowance: boolean, fillTakerTokenAmounts: BigNumber[] = [], ) { @@ -19,33 +19,33 @@ export const formatters = { r: [], s: [], }; - _.forEach(orders, order => { + _.forEach(signedOrders, signedOrder => { batchFill.orderAddresses.push([ - order.params.maker, - order.params.taker, - order.params.makerToken, - order.params.takerToken, - order.params.feeRecipient, + signedOrder.maker, + signedOrder.taker, + signedOrder.makerTokenAddress, + signedOrder.takerTokenAddress, + signedOrder.feeRecipient, ]); batchFill.orderValues.push([ - order.params.makerTokenAmount, - order.params.takerTokenAmount, - order.params.makerFee, - order.params.takerFee, - order.params.expirationTimestampInSec, - order.params.salt, + signedOrder.makerTokenAmount, + signedOrder.takerTokenAmount, + signedOrder.makerFee, + signedOrder.takerFee, + signedOrder.expirationUnixTimestampSec, + signedOrder.salt, ]); - batchFill.v.push(order.params.v); - batchFill.r.push(order.params.r); - batchFill.s.push(order.params.s); - if (fillTakerTokenAmounts.length < orders.length) { - batchFill.fillTakerTokenAmounts.push(order.params.takerTokenAmount); + batchFill.v.push(signedOrder.ecSignature.v); + batchFill.r.push(signedOrder.ecSignature.r); + batchFill.s.push(signedOrder.ecSignature.s); + if (fillTakerTokenAmounts.length < signedOrders.length) { + batchFill.fillTakerTokenAmounts.push(signedOrder.takerTokenAmount); } }); return batchFill; }, createFillUpTo( - orders: SignedOrder[], + signedOrders: SignedOrder[], shouldThrowOnInsufficientBalanceOrAllowance: boolean, fillTakerTokenAmount: BigNumber, ) { @@ -58,52 +58,52 @@ export const formatters = { r: [], s: [], }; - orders.forEach(order => { + signedOrders.forEach(signedOrder => { fillUpTo.orderAddresses.push([ - order.params.maker, - order.params.taker, - order.params.makerToken, - order.params.takerToken, - order.params.feeRecipient, + signedOrder.maker, + signedOrder.taker, + signedOrder.makerTokenAddress, + signedOrder.takerTokenAddress, + signedOrder.feeRecipient, ]); fillUpTo.orderValues.push([ - order.params.makerTokenAmount, - order.params.takerTokenAmount, - order.params.makerFee, - order.params.takerFee, - order.params.expirationTimestampInSec, - order.params.salt, + signedOrder.makerTokenAmount, + signedOrder.takerTokenAmount, + signedOrder.makerFee, + signedOrder.takerFee, + signedOrder.expirationUnixTimestampSec, + signedOrder.salt, ]); - fillUpTo.v.push(order.params.v); - fillUpTo.r.push(order.params.r); - fillUpTo.s.push(order.params.s); + fillUpTo.v.push(signedOrder.ecSignature.v); + fillUpTo.r.push(signedOrder.ecSignature.r); + fillUpTo.s.push(signedOrder.ecSignature.s); }); return fillUpTo; }, - createBatchCancel(orders: SignedOrder[], cancelTakerTokenAmounts: BigNumber[] = []) { + createBatchCancel(signedOrders: SignedOrder[], cancelTakerTokenAmounts: BigNumber[] = []) { const batchCancel: BatchCancelOrders = { orderAddresses: [], orderValues: [], cancelTakerTokenAmounts, }; - orders.forEach(order => { + signedOrders.forEach(signedOrder => { batchCancel.orderAddresses.push([ - order.params.maker, - order.params.taker, - order.params.makerToken, - order.params.takerToken, - order.params.feeRecipient, + signedOrder.maker, + signedOrder.taker, + signedOrder.makerTokenAddress, + signedOrder.takerTokenAddress, + signedOrder.feeRecipient, ]); batchCancel.orderValues.push([ - order.params.makerTokenAmount, - order.params.takerTokenAmount, - order.params.makerFee, - order.params.takerFee, - order.params.expirationTimestampInSec, - order.params.salt, + signedOrder.makerTokenAmount, + signedOrder.takerTokenAmount, + signedOrder.makerFee, + signedOrder.takerFee, + signedOrder.expirationUnixTimestampSec, + signedOrder.salt, ]); - if (cancelTakerTokenAmounts.length < orders.length) { - batchCancel.cancelTakerTokenAmounts.push(order.params.takerTokenAmount); + if (cancelTakerTokenAmounts.length < signedOrders.length) { + batchCancel.cancelTakerTokenAmounts.push(signedOrder.takerTokenAmount); } }); return batchCancel; diff --git a/packages/contracts/util/order.ts b/packages/contracts/util/order.ts deleted file mode 100644 index 6d412e2af..000000000 --- a/packages/contracts/util/order.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import ethUtil = require('ethereumjs-util'); -import * as _ from 'lodash'; - -import { crypto } from './crypto'; -import { SignedOrder } from './signed_order'; -import { OrderParams } from './types'; - -export class Order { - public params: OrderParams; - private _web3Wrapper: Web3Wrapper; - constructor(web3Wrapper: Web3Wrapper, params: OrderParams) { - this.params = params; - this._web3Wrapper = web3Wrapper; - } - public async signAsync(): Promise<SignedOrder> { - const orderHash = this.getOrderHashHex(); - const signature = await this._web3Wrapper.signTransactionAsync(this.params.maker, orderHash); - const { v, r, s } = ethUtil.fromRpcSig(signature); - const signedOrderParams = _.assign(this.params, { - v, - r: ethUtil.bufferToHex(r), - s: ethUtil.bufferToHex(s), - }); - const signedOrder = new SignedOrder(this._web3Wrapper, signedOrderParams); - return signedOrder; - } - public getOrderHashHex(): string { - const orderHash = crypto.solSHA3([ - this.params.exchangeContractAddress, - this.params.maker, - this.params.taker, - this.params.makerToken, - this.params.takerToken, - this.params.feeRecipient, - this.params.makerTokenAmount, - this.params.takerTokenAmount, - this.params.makerFee, - this.params.takerFee, - this.params.expirationTimestampInSec, - this.params.salt, - ]); - const orderHashHex = ethUtil.bufferToHex(orderHash); - return orderHashHex; - } -} diff --git a/packages/contracts/util/order_factory.ts b/packages/contracts/util/order_factory.ts index 788f60a88..8ba5df24a 100644 --- a/packages/contracts/util/order_factory.ts +++ b/packages/contracts/util/order_factory.ts @@ -1,33 +1,37 @@ -import { ZeroEx } from '0x.js'; +import { Order, SignedOrder, ZeroEx } from '0x.js'; import { BigNumber } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; -import { Order } from './order'; -import { SignedOrder } from './signed_order'; -import { DefaultOrderParams, OptionalOrderParams, OrderParams } from './types'; +import { DefaultOrderParams } from './types'; export class OrderFactory { - private _defaultOrderParams: DefaultOrderParams; - private _web3Wrapper: Web3Wrapper; - constructor(web3Wrapper: Web3Wrapper, defaultOrderParams: DefaultOrderParams) { + private _defaultOrderParams: Partial<Order>; + private _zeroEx: ZeroEx; + constructor(zeroEx: ZeroEx, defaultOrderParams: Partial<Order>) { this._defaultOrderParams = defaultOrderParams; - this._web3Wrapper = web3Wrapper; + this._zeroEx = zeroEx; } - public async newSignedOrderAsync(customOrderParams: OptionalOrderParams = {}): Promise<SignedOrder> { + public async newSignedOrderAsync(customOrderParams: Partial<Order> = {}): Promise<SignedOrder> { const randomExpiration = new BigNumber(Math.floor((Date.now() + Math.random() * 100000000000) / 1000)); - const orderParams: OrderParams = _.assign( - {}, - { - expirationTimestampInSec: randomExpiration, - salt: ZeroEx.generatePseudoRandomSalt(), - taker: ZeroEx.NULL_ADDRESS, - }, - this._defaultOrderParams, - customOrderParams, + const order = ({ + expirationUnixTimestampSec: randomExpiration, + salt: ZeroEx.generatePseudoRandomSalt(), + taker: ZeroEx.NULL_ADDRESS, + ...this._defaultOrderParams, + ...customOrderParams, + } as any) as Order; + const orderHashHex = ZeroEx.getOrderHashHex(order); + const shouldAddPersonalMessagePrefix = false; + const ecSignature = await this._zeroEx.signOrderHashAsync( + orderHashHex, + order.maker, + shouldAddPersonalMessagePrefix, ); - const order = new Order(this._web3Wrapper, orderParams); - const signedOrder = await order.signAsync(); + const signedOrder = { + ...order, + ecSignature, + }; return signedOrder; } } diff --git a/packages/contracts/util/signed_order.ts b/packages/contracts/util/signed_order.ts deleted file mode 100644 index a84e0686c..000000000 --- a/packages/contracts/util/signed_order.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import ethUtil = require('ethereumjs-util'); -import * as _ from 'lodash'; - -import { crypto } from './crypto'; -import { SignedOrderParams } from './types'; - -export class SignedOrder { - public params: SignedOrderParams; - private _web3Wrapper: Web3Wrapper; - constructor(web3Wrapper: Web3Wrapper, params: SignedOrderParams) { - this.params = params; - this._web3Wrapper = web3Wrapper; - } - public isValidSignature() { - const { v, r, s } = this.params; - const orderHash = this.getOrderHashHex(); - const msgHash = ethUtil.hashPersonalMessage(ethUtil.toBuffer(orderHash)); - try { - const pubKey = ethUtil.ecrecover(msgHash, v, ethUtil.toBuffer(r), ethUtil.toBuffer(s)); - const recoveredAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey)); - return recoveredAddress === this.params.maker; - } catch (err) { - return false; - } - } - public createFill(shouldThrowOnInsufficientBalanceOrAllowance?: boolean, fillTakerTokenAmount?: BigNumber) { - const fill = { - orderAddresses: [ - this.params.maker, - this.params.taker, - this.params.makerToken, - this.params.takerToken, - this.params.feeRecipient, - ], - orderValues: [ - this.params.makerTokenAmount, - this.params.takerTokenAmount, - this.params.makerFee, - this.params.takerFee, - this.params.expirationTimestampInSec, - this.params.salt, - ], - fillTakerTokenAmount: fillTakerTokenAmount || this.params.takerTokenAmount, - shouldThrowOnInsufficientBalanceOrAllowance: !!shouldThrowOnInsufficientBalanceOrAllowance, - v: this.params.v, - r: this.params.r, - s: this.params.s, - }; - return fill; - } - public createCancel(cancelTakerTokenAmount?: BigNumber) { - const cancel = { - orderAddresses: [ - this.params.maker, - this.params.taker, - this.params.makerToken, - this.params.takerToken, - this.params.feeRecipient, - ], - orderValues: [ - this.params.makerTokenAmount, - this.params.takerTokenAmount, - this.params.makerFee, - this.params.takerFee, - this.params.expirationTimestampInSec, - this.params.salt, - ], - cancelTakerTokenAmount: cancelTakerTokenAmount || this.params.takerTokenAmount, - }; - return cancel; - } - public getOrderHashHex(): string { - const orderHash = crypto.solSHA3([ - this.params.exchangeContractAddress, - this.params.maker, - this.params.taker, - this.params.makerToken, - this.params.takerToken, - this.params.feeRecipient, - this.params.makerTokenAmount, - this.params.takerTokenAmount, - this.params.makerFee, - this.params.takerFee, - this.params.expirationTimestampInSec, - this.params.salt, - ]); - const orderHashHex = ethUtil.bufferToHex(orderHash); - return orderHashHex; - } -} diff --git a/packages/contracts/util/signed_order_utils.ts b/packages/contracts/util/signed_order_utils.ts new file mode 100644 index 000000000..fc2f800cd --- /dev/null +++ b/packages/contracts/util/signed_order_utils.ts @@ -0,0 +1,49 @@ +import { SignedOrder } from '0x.js'; +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import ethUtil = require('ethereumjs-util'); +import * as _ from 'lodash'; + +import { crypto } from './crypto'; + +export const signedOrderUtils = { + createFill: ( + signedOrder: SignedOrder, + shouldThrowOnInsufficientBalanceOrAllowance?: boolean, + fillTakerTokenAmount?: BigNumber, + ) => { + const fill = { + ...signedOrderUtils.getOrderAddressesAndValues(signedOrder), + fillTakerTokenAmount: fillTakerTokenAmount || signedOrder.takerTokenAmount, + shouldThrowOnInsufficientBalanceOrAllowance: !!shouldThrowOnInsufficientBalanceOrAllowance, + ...signedOrder.ecSignature, + }; + return fill; + }, + createCancel(signedOrder: SignedOrder, cancelTakerTokenAmount?: BigNumber) { + const cancel = { + ...signedOrderUtils.getOrderAddressesAndValues(signedOrder), + cancelTakerTokenAmount: cancelTakerTokenAmount || signedOrder.takerTokenAmount, + }; + return cancel; + }, + getOrderAddressesAndValues(signedOrder: SignedOrder) { + return { + orderAddresses: [ + signedOrder.maker, + signedOrder.taker, + signedOrder.makerTokenAddress, + signedOrder.takerTokenAddress, + signedOrder.feeRecipient, + ], + orderValues: [ + signedOrder.makerTokenAmount, + signedOrder.takerTokenAmount, + signedOrder.makerFee, + signedOrder.takerFee, + signedOrder.expirationUnixTimestampSec, + signedOrder.salt, + ], + }; + }, +}; diff --git a/packages/contracts/util/types.ts b/packages/contracts/util/types.ts index 1bd8940ad..65bc26f79 100644 --- a/packages/contracts/util/types.ts +++ b/packages/contracts/util/types.ts @@ -49,41 +49,6 @@ export interface DefaultOrderParams { takerFee: BigNumber; } -export interface OptionalOrderParams { - exchangeContractAddress?: string; - maker?: string; - taker?: string; - feeRecipient?: string; - makerToken?: string; - takerToken?: string; - makerTokenAmount?: BigNumber; - takerTokenAmount?: BigNumber; - makerFee?: BigNumber; - takerFee?: BigNumber; - expirationTimestampInSec?: BigNumber; -} - -export interface OrderParams { - exchangeContractAddress: string; - maker: string; - taker: string; - feeRecipient: string; - makerToken: string; - takerToken: string; - makerTokenAmount: BigNumber; - takerTokenAmount: BigNumber; - makerFee: BigNumber; - takerFee: BigNumber; - expirationTimestampInSec: BigNumber; - salt: BigNumber; -} - -export interface SignedOrderParams extends OrderParams { - v: number; - r: string; - s: string; -} - export interface TransactionDataParams { name: string; abi: Web3.AbiDefinition[]; |