diff options
Diffstat (limited to 'packages/contracts/util')
-rw-r--r-- | packages/contracts/util/artifacts.ts | 46 | ||||
-rw-r--r-- | packages/contracts/util/balances.ts | 36 | ||||
-rw-r--r-- | packages/contracts/util/crypto.ts | 46 | ||||
-rw-r--r-- | packages/contracts/util/exchange_wrapper.ts | 303 | ||||
-rw-r--r-- | packages/contracts/util/formatters.ts | 131 | ||||
-rw-r--r-- | packages/contracts/util/multi_sig_wrapper.ts | 48 | ||||
-rw-r--r-- | packages/contracts/util/order.ts | 184 | ||||
-rw-r--r-- | packages/contracts/util/order_factory.ts | 30 | ||||
-rw-r--r-- | packages/contracts/util/rpc.ts | 74 | ||||
-rw-r--r-- | packages/contracts/util/token_registry_wrapper.ts | 104 | ||||
-rw-r--r-- | packages/contracts/util/types.ts | 150 |
11 files changed, 577 insertions, 575 deletions
diff --git a/packages/contracts/util/artifacts.ts b/packages/contracts/util/artifacts.ts index 8114972d0..b15c9216f 100644 --- a/packages/contracts/util/artifacts.ts +++ b/packages/contracts/util/artifacts.ts @@ -1,25 +1,25 @@ export class Artifacts { - public Migrations: any; - public TokenTransferProxy: any; - public TokenRegistry: any; - public MultiSigWalletWithTimeLock: any; - public Exchange: any; - public ZRXToken: any; - public DummyToken: any; - public EtherToken: any; - public MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress: any; - public MaliciousToken: any; - constructor(artifacts: any) { - this.Migrations = artifacts.require('Migrations'); - this.TokenTransferProxy = artifacts.require('TokenTransferProxy'); - this.TokenRegistry = artifacts.require('TokenRegistry'); - this.MultiSigWalletWithTimeLock = artifacts.require('MultiSigWalletWithTimeLock'); - this.Exchange = artifacts.require('Exchange'); - this.ZRXToken = artifacts.require('ZRXToken'); - this.DummyToken = artifacts.require('DummyToken'); - this.EtherToken = artifacts.require('EtherToken'); - this.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = artifacts.require( - 'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress'); - this.MaliciousToken = artifacts.require('MaliciousToken'); - } + public Migrations: any; + public TokenTransferProxy: any; + public TokenRegistry: any; + public MultiSigWalletWithTimeLock: any; + public Exchange: any; + public ZRXToken: any; + public DummyToken: any; + public EtherToken: any; + public MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress: any; + public MaliciousToken: any; + constructor(artifacts: any) { + this.Migrations = artifacts.require('Migrations'); + this.TokenTransferProxy = artifacts.require('TokenTransferProxy'); + this.TokenRegistry = artifacts.require('TokenRegistry'); + this.MultiSigWalletWithTimeLock = artifacts.require('MultiSigWalletWithTimeLock'); + this.Exchange = artifacts.require('Exchange'); + this.ZRXToken = artifacts.require('ZRXToken'); + this.DummyToken = artifacts.require('DummyToken'); + this.EtherToken = artifacts.require('EtherToken'); + this.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = artifacts.require( + 'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress'); + this.MaliciousToken = artifacts.require('MaliciousToken'); + } } diff --git a/packages/contracts/util/balances.ts b/packages/contracts/util/balances.ts index ef4abd7bf..fce15db6d 100644 --- a/packages/contracts/util/balances.ts +++ b/packages/contracts/util/balances.ts @@ -7,24 +7,24 @@ import {BalancesByOwner, ContractInstance} from './types'; bigNumberConfigs.configure(); export class Balances { - private tokenContractInstances: ContractInstance[]; - private ownerAddresses: string[]; - constructor(tokenContractInstances: ContractInstance[], ownerAddresses: string[]) { - this.tokenContractInstances = tokenContractInstances; - this.ownerAddresses = ownerAddresses; - } - public async getAsync(): Promise<BalancesByOwner> { - const balancesByOwner: BalancesByOwner = {}; - for (const tokenContractInstance of this.tokenContractInstances) { - for (const ownerAddress of this.ownerAddresses) { - let balance = await tokenContractInstance.balanceOf(ownerAddress); - balance = new BigNumber(balance); - if (_.isUndefined(balancesByOwner[ownerAddress])) { - balancesByOwner[ownerAddress] = {}; + private tokenContractInstances: ContractInstance[]; + private ownerAddresses: string[]; + constructor(tokenContractInstances: ContractInstance[], ownerAddresses: string[]) { + this.tokenContractInstances = tokenContractInstances; + this.ownerAddresses = ownerAddresses; + } + public async getAsync(): Promise<BalancesByOwner> { + const balancesByOwner: BalancesByOwner = {}; + for (const tokenContractInstance of this.tokenContractInstances) { + for (const ownerAddress of this.ownerAddresses) { + let balance = await tokenContractInstance.balanceOf(ownerAddress); + balance = new BigNumber(balance); + if (_.isUndefined(balancesByOwner[ownerAddress])) { + balancesByOwner[ownerAddress] = {}; + } + balancesByOwner[ownerAddress][tokenContractInstance.address] = balance; + } } - balancesByOwner[ownerAddress][tokenContractInstance.address] = balance; - } + return balancesByOwner; } - return balancesByOwner; - } } diff --git a/packages/contracts/util/crypto.ts b/packages/contracts/util/crypto.ts index e4baee021..5253b8c15 100644 --- a/packages/contracts/util/crypto.ts +++ b/packages/contracts/util/crypto.ts @@ -5,7 +5,7 @@ import ethUtil = require('ethereumjs-util'); import * as _ from 'lodash'; export const crypto = { - /* + /* * We convert types from JS to Solidity as follows: * BigNumber -> uint256 * number -> uint8 @@ -13,26 +13,26 @@ export const crypto = { * boolean -> bool * valid Ethereum address -> address */ - solSHA3(args: any[]): Buffer { - const argTypes: string[] = []; - _.each(args, (arg, i) => { - const isNumber = _.isFinite(arg); - if (isNumber) { - argTypes.push('uint8'); - } else if ((arg).isBigNumber) { - argTypes.push('uint256'); - args[i] = new BN(arg.toString(10), 10); - } else if (ethUtil.isValidAddress(arg)) { - argTypes.push('address'); - } else if (_.isString(arg)) { - argTypes.push('string'); - } else if (_.isBoolean(arg)) { - argTypes.push('bool'); - } else { - throw new Error(`Unable to guess arg type: ${arg}`); - } - }); - const hash = ABI.soliditySHA3(argTypes, args); - return hash; - }, + solSHA3(args: any[]): Buffer { + const argTypes: string[] = []; + _.each(args, (arg, i) => { + const isNumber = _.isFinite(arg); + if (isNumber) { + argTypes.push('uint8'); + } else if ((arg).isBigNumber) { + argTypes.push('uint256'); + args[i] = new BN(arg.toString(10), 10); + } else if (ethUtil.isValidAddress(arg)) { + argTypes.push('address'); + } else if (_.isString(arg)) { + argTypes.push('string'); + } else if (_.isBoolean(arg)) { + argTypes.push('bool'); + } else { + throw new Error(`Unable to guess arg type: ${arg}`); + } + }); + const hash = ABI.soliditySHA3(argTypes, args); + return hash; + }, }; diff --git a/packages/contracts/util/exchange_wrapper.ts b/packages/contracts/util/exchange_wrapper.ts index 062ea292b..304dcdacf 100644 --- a/packages/contracts/util/exchange_wrapper.ts +++ b/packages/contracts/util/exchange_wrapper.ts @@ -6,163 +6,162 @@ import {Order} from './order'; import {ContractInstance} from './types'; export class ExchangeWrapper { - private exchange: ContractInstance; - constructor(exchangeContractInstance: ContractInstance) { - this.exchange = exchangeContractInstance; - } - public async fillOrderAsync(order: Order, from: string, - opts: { - fillTakerTokenAmount?: BigNumber; - shouldThrowOnInsufficientBalanceOrAllowance?: boolean; - } = {}) { - const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance; - const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount); - const tx = await this.exchange.fillOrder( - params.orderAddresses, - params.orderValues, - params.fillTakerTokenAmount, - params.shouldThrowOnInsufficientBalanceOrAllowance, - params.v, - params.r, - params.s, - {from}, - ); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async cancelOrderAsync(order: Order, from: string, - opts: {cancelTakerTokenAmount?: BigNumber} = {}) { - const params = order.createCancel(opts.cancelTakerTokenAmount); - const tx = await this.exchange.cancelOrder( - params.orderAddresses, - params.orderValues, - params.cancelTakerTokenAmount, - {from}, - ); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async fillOrKillOrderAsync(order: Order, from: string, - opts: {fillTakerTokenAmount?: BigNumber} = {}) { - const shouldThrowOnInsufficientBalanceOrAllowance = true; - const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount); - const tx = await this.exchange.fillOrKillOrder( - params.orderAddresses, - params.orderValues, - params.fillTakerTokenAmount, - params.v, - params.r, - params.s, - {from}, - ); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async batchFillOrdersAsync(orders: Order[], from: string, - opts: { - fillTakerTokenAmounts?: BigNumber[]; - shouldThrowOnInsufficientBalanceOrAllowance?: boolean; - } = {}) { - const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance; - const params = formatters.createBatchFill( - orders, shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmounts); - const tx = await this.exchange.batchFillOrders( - params.orderAddresses, - params.orderValues, - params.fillTakerTokenAmounts, - params.shouldThrowOnInsufficientBalanceOrAllowance, - params.v, - params.r, - params.s, - {from}, - ); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async batchFillOrKillOrdersAsync(orders: Order[], from: string, - opts: { - fillTakerTokenAmounts?: BigNumber[]; - } = {}) { - const params = formatters.createBatchFill(orders, undefined, opts.fillTakerTokenAmounts); - const tx = await this.exchange.batchFillOrKillOrders( - params.orderAddresses, - params.orderValues, - params.fillTakerTokenAmounts, - params.v, - params.r, - params.s, - {from}, - ); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async fillOrdersUpToAsync(orders: Order[], from: string, - opts: {fillTakerTokenAmount?: BigNumber; + private exchange: ContractInstance; + constructor(exchangeContractInstance: ContractInstance) { + this.exchange = exchangeContractInstance; + } + public async fillOrderAsync(order: Order, from: string, + opts: { + fillTakerTokenAmount?: BigNumber; + shouldThrowOnInsufficientBalanceOrAllowance?: boolean; + } = {}) { + const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance; + const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount); + const tx = await this.exchange.fillOrder( + params.orderAddresses, + params.orderValues, + params.fillTakerTokenAmount, + params.shouldThrowOnInsufficientBalanceOrAllowance, + params.v, + params.r, + params.s, + {from}, + ); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async cancelOrderAsync(order: Order, from: string, + opts: {cancelTakerTokenAmount?: BigNumber} = {}) { + const params = order.createCancel(opts.cancelTakerTokenAmount); + const tx = await this.exchange.cancelOrder( + params.orderAddresses, + params.orderValues, + params.cancelTakerTokenAmount, + {from}, + ); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async fillOrKillOrderAsync(order: Order, from: string, + opts: {fillTakerTokenAmount?: BigNumber} = {}) { + const shouldThrowOnInsufficientBalanceOrAllowance = true; + const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount); + const tx = await this.exchange.fillOrKillOrder( + params.orderAddresses, + params.orderValues, + params.fillTakerTokenAmount, + params.v, + params.r, + params.s, + {from}, + ); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async batchFillOrdersAsync(orders: Order[], from: string, + opts: { + fillTakerTokenAmounts?: BigNumber[]; shouldThrowOnInsufficientBalanceOrAllowance?: boolean; - } = {}) { - const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance; - const params = formatters.createFillUpTo(orders, + } = {}) { + const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance; + const params = formatters.createBatchFill( + orders, shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmounts); + const tx = await this.exchange.batchFillOrders( + params.orderAddresses, + params.orderValues, + params.fillTakerTokenAmounts, + params.shouldThrowOnInsufficientBalanceOrAllowance, + params.v, + params.r, + params.s, + {from}, + ); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async batchFillOrKillOrdersAsync(orders: Order[], from: string, + opts: {fillTakerTokenAmounts?: BigNumber[]} = {}) { + const params = formatters.createBatchFill(orders, undefined, opts.fillTakerTokenAmounts); + const tx = await this.exchange.batchFillOrKillOrders( + params.orderAddresses, + params.orderValues, + params.fillTakerTokenAmounts, + params.v, + params.r, + params.s, + {from}, + ); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async fillOrdersUpToAsync(orders: Order[], from: string, + opts: { + fillTakerTokenAmount?: BigNumber; + shouldThrowOnInsufficientBalanceOrAllowance?: boolean; + } = {}) { + const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance; + const params = formatters.createFillUpTo(orders, shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount); - const tx = await this.exchange.fillOrdersUpTo( - params.orderAddresses, - params.orderValues, - params.fillTakerTokenAmount, - params.shouldThrowOnInsufficientBalanceOrAllowance, - params.v, - params.r, - params.s, - {from}, - ); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async batchCancelOrdersAsync(orders: Order[], from: string, - opts: {cancelTakerTokenAmounts?: BigNumber[]} = {}) { - const params = formatters.createBatchCancel(orders, opts.cancelTakerTokenAmounts); - const tx = await this.exchange.batchCancelOrders( - params.orderAddresses, - params.orderValues, - params.cancelTakerTokenAmounts, - {from}, - ); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async getOrderHashAsync(order: Order): Promise<string> { - const shouldThrowOnInsufficientBalanceOrAllowance = false; - const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance); - const orderHash = await this.exchange.getOrderHash(params.orderAddresses, params.orderValues); - return orderHash; - } - public async isValidSignatureAsync(order: Order): Promise<boolean> { - const isValidSignature = await this.exchange.isValidSignature( - order.params.maker, - order.params.orderHashHex, - order.params.v, - order.params.r, - order.params.s, - ); - return isValidSignature; - } - public async isRoundingErrorAsync(numerator: BigNumber, denominator: BigNumber, - target: BigNumber): Promise<boolean> { - const isRoundingError = await this.exchange.isRoundingError(numerator, denominator, target); - return isRoundingError; - } - public async getPartialAmountAsync(numerator: BigNumber, denominator: BigNumber, - target: BigNumber): Promise<BigNumber> { - const partialAmount = new BigNumber(await this.exchange.getPartialAmount(numerator, denominator, target)); - return partialAmount; - } + const tx = await this.exchange.fillOrdersUpTo( + params.orderAddresses, + params.orderValues, + params.fillTakerTokenAmount, + params.shouldThrowOnInsufficientBalanceOrAllowance, + params.v, + params.r, + params.s, + {from}, + ); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async batchCancelOrdersAsync(orders: Order[], from: string, + opts: {cancelTakerTokenAmounts?: BigNumber[]} = {}) { + const params = formatters.createBatchCancel(orders, opts.cancelTakerTokenAmounts); + const tx = await this.exchange.batchCancelOrders( + params.orderAddresses, + params.orderValues, + params.cancelTakerTokenAmounts, + {from}, + ); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async getOrderHashAsync(order: Order): Promise<string> { + const shouldThrowOnInsufficientBalanceOrAllowance = false; + const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance); + const orderHash = await this.exchange.getOrderHash(params.orderAddresses, params.orderValues); + return orderHash; + } + public async isValidSignatureAsync(order: Order): Promise<boolean> { + const isValidSignature = await this.exchange.isValidSignature( + order.params.maker, + order.params.orderHashHex, + order.params.v, + order.params.r, + order.params.s, + ); + return isValidSignature; + } + public async isRoundingErrorAsync(numerator: BigNumber, denominator: BigNumber, + target: BigNumber): Promise<boolean> { + const isRoundingError = await this.exchange.isRoundingError(numerator, denominator, target); + return isRoundingError; + } + public async getPartialAmountAsync(numerator: BigNumber, denominator: BigNumber, + target: BigNumber): Promise<BigNumber> { + const partialAmount = new BigNumber(await this.exchange.getPartialAmount(numerator, denominator, target)); + return partialAmount; + } } function wrapLogBigNumbers(log: any): any { - const argNames = _.keys(log.args); - for (const argName of argNames) { - const isWeb3BigNumber = _.startsWith(log.args[argName].constructor.toString(), 'function BigNumber('); - if (isWeb3BigNumber) { - log.args[argName] = new BigNumber(log.args[argName]); + const argNames = _.keys(log.args); + for (const argName of argNames) { + const isWeb3BigNumber = _.startsWith(log.args[argName].constructor.toString(), 'function BigNumber('); + if (isWeb3BigNumber) { + log.args[argName] = new BigNumber(log.args[argName]); + } } - } } diff --git a/packages/contracts/util/formatters.ts b/packages/contracts/util/formatters.ts index cda548617..0ad44481a 100644 --- a/packages/contracts/util/formatters.ts +++ b/packages/contracts/util/formatters.ts @@ -5,70 +5,73 @@ import {Order} from './order'; import {BatchCancelOrders, BatchFillOrders, FillOrdersUpTo} from './types'; export const formatters = { - createBatchFill(orders: Order[], - shouldThrowOnInsufficientBalanceOrAllowance: boolean, - fillTakerTokenAmounts: BigNumber[] = []) { - const batchFill: BatchFillOrders = { - orderAddresses: [], - orderValues: [], - fillTakerTokenAmounts, - shouldThrowOnInsufficientBalanceOrAllowance, - v: [], - r: [], - s: [], - }; - _.forEach(orders, order => { - batchFill.orderAddresses.push([order.params.maker, order.params.taker, order.params.makerToken, + createBatchFill(orders: Order[], + shouldThrowOnInsufficientBalanceOrAllowance: boolean, + fillTakerTokenAmounts: BigNumber[] = []) { + const batchFill: BatchFillOrders = { + orderAddresses: [], + orderValues: [], + fillTakerTokenAmounts, + shouldThrowOnInsufficientBalanceOrAllowance, + v: [], + r: [], + s: [], + }; + _.forEach(orders, order => { + batchFill.orderAddresses.push([order.params.maker, order.params.taker, order.params.makerToken, order.params.takerToken, order.params.feeRecipient]); - batchFill.orderValues.push([order.params.makerTokenAmount, order.params.takerTokenAmount, order.params.makerFee, - order.params.takerFee, order.params.expirationTimestampInSec, order.params.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); - } - }); - return batchFill; - }, - createFillUpTo(orders: Order[], - shouldThrowOnInsufficientBalanceOrAllowance: boolean, - fillTakerTokenAmount: BigNumber) { - const fillUpTo: FillOrdersUpTo = { - orderAddresses: [], - orderValues: [], - fillTakerTokenAmount, - shouldThrowOnInsufficientBalanceOrAllowance, - v: [], - r: [], - s: [], - }; - orders.forEach(order => { - fillUpTo.orderAddresses.push([order.params.maker, order.params.taker, order.params.makerToken, - order.params.takerToken, order.params.feeRecipient]); - fillUpTo.orderValues.push([order.params.makerTokenAmount, order.params.takerTokenAmount, order.params.makerFee, - order.params.takerFee, order.params.expirationTimestampInSec, order.params.salt]); - fillUpTo.v.push(order.params.v); - fillUpTo.r.push(order.params.r); - fillUpTo.s.push(order.params.s); - }); - return fillUpTo; - }, - createBatchCancel(orders: Order[], cancelTakerTokenAmounts: BigNumber[] = []) { - const batchCancel: BatchCancelOrders = { - orderAddresses: [], - orderValues: [], - cancelTakerTokenAmounts, - }; - orders.forEach(order => { - batchCancel.orderAddresses.push([order.params.maker, order.params.taker, order.params.makerToken, + batchFill.orderValues.push([order.params.makerTokenAmount, order.params.takerTokenAmount, + order.params.makerFee, order.params.takerFee, + order.params.expirationTimestampInSec, order.params.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); + } + }); + return batchFill; + }, + createFillUpTo(orders: Order[], + shouldThrowOnInsufficientBalanceOrAllowance: boolean, + fillTakerTokenAmount: BigNumber) { + const fillUpTo: FillOrdersUpTo = { + orderAddresses: [], + orderValues: [], + fillTakerTokenAmount, + shouldThrowOnInsufficientBalanceOrAllowance, + v: [], + r: [], + s: [], + }; + orders.forEach(order => { + fillUpTo.orderAddresses.push([order.params.maker, order.params.taker, order.params.makerToken, + order.params.takerToken, order.params.feeRecipient]); + fillUpTo.orderValues.push([order.params.makerTokenAmount, order.params.takerTokenAmount, + order.params.makerFee, order.params.takerFee, + order.params.expirationTimestampInSec, order.params.salt]); + fillUpTo.v.push(order.params.v); + fillUpTo.r.push(order.params.r); + fillUpTo.s.push(order.params.s); + }); + return fillUpTo; + }, + createBatchCancel(orders: Order[], cancelTakerTokenAmounts: BigNumber[] = []) { + const batchCancel: BatchCancelOrders = { + orderAddresses: [], + orderValues: [], + cancelTakerTokenAmounts, + }; + orders.forEach(order => { + batchCancel.orderAddresses.push([order.params.maker, order.params.taker, order.params.makerToken, order.params.takerToken, order.params.feeRecipient]); - batchCancel.orderValues.push([order.params.makerTokenAmount, order.params.takerTokenAmount, order.params.makerFee, - order.params.takerFee, order.params.expirationTimestampInSec, order.params.salt]); - if (cancelTakerTokenAmounts.length < orders.length) { - batchCancel.cancelTakerTokenAmounts.push(order.params.takerTokenAmount); - } - }); - return batchCancel; - }, + batchCancel.orderValues.push([order.params.makerTokenAmount, order.params.takerTokenAmount, + order.params.makerFee, order.params.takerFee, + order.params.expirationTimestampInSec, order.params.salt]); + if (cancelTakerTokenAmounts.length < orders.length) { + batchCancel.cancelTakerTokenAmounts.push(order.params.takerTokenAmount); + } + }); + return batchCancel; + }, }; diff --git a/packages/contracts/util/multi_sig_wrapper.ts b/packages/contracts/util/multi_sig_wrapper.ts index 7c13dae97..3adaab592 100644 --- a/packages/contracts/util/multi_sig_wrapper.ts +++ b/packages/contracts/util/multi_sig_wrapper.ts @@ -6,29 +6,29 @@ import * as Web3 from 'web3'; import {ContractInstance, TransactionDataParams} from './types'; export class MultiSigWrapper { - private multiSig: ContractInstance; - constructor(multiSigContractInstance: ContractInstance) { - this.multiSig = multiSigContractInstance; - } - public async submitTransactionAsync(destination: string, from: string, - dataParams: TransactionDataParams, - value: number = 0) { - const {name, abi, args = []} = dataParams; - const encoded = this.encodeFnArgs(name, abi, args); - return this.multiSig.submitTransaction(destination, value, encoded, {from}); - } - public encodeFnArgs(name: string, abi: Web3.AbiDefinition[], args: any[]) { - const abiEntity = _.find(abi, {name}) as Web3.MethodAbi; - if (_.isUndefined(abiEntity)) { - throw new Error(`Did not find abi entry for name: ${name}`); + private multiSig: ContractInstance; + constructor(multiSigContractInstance: ContractInstance) { + this.multiSig = multiSigContractInstance; + } + public async submitTransactionAsync(destination: string, from: string, + dataParams: TransactionDataParams, + value: number = 0) { + const {name, abi, args = []} = dataParams; + const encoded = this.encodeFnArgs(name, abi, args); + return this.multiSig.submitTransaction(destination, value, encoded, {from}); + } + public encodeFnArgs(name: string, abi: Web3.AbiDefinition[], args: any[]) { + const abiEntity = _.find(abi, {name}) as Web3.MethodAbi; + if (_.isUndefined(abiEntity)) { + throw new Error(`Did not find abi entry for name: ${name}`); + } + const types = _.map(abiEntity.inputs, input => input.type); + const funcSig = ethUtil.bufferToHex(ABI.methodID(name, types)); + const argsData = _.map(args, arg => { + const target = _.isBoolean(arg) ? +arg : arg; + const targetBuff = ethUtil.toBuffer(target); + return ethUtil.setLengthLeft(targetBuff, 32).toString('hex'); + }); + return funcSig + argsData.join(''); } - const types = _.map(abiEntity.inputs, input => input.type); - const funcSig = ethUtil.bufferToHex(ABI.methodID(name, types)); - const argsData = _.map(args, arg => { - const target = _.isBoolean(arg) ? +arg : arg; - const targetBuff = ethUtil.toBuffer(target); - return ethUtil.setLengthLeft(targetBuff, 32).toString('hex'); - }); - return funcSig + argsData.join(''); - } } diff --git a/packages/contracts/util/order.ts b/packages/contracts/util/order.ts index 635999348..8e3822188 100644 --- a/packages/contracts/util/order.ts +++ b/packages/contracts/util/order.ts @@ -12,98 +12,98 @@ import {OrderParams} from './types'; const web3: Web3 = (global as any).web3; export class Order { - public params: OrderParams; - constructor(params: OrderParams) { - this.params = params; - } - public isValidSignature() { - const {v, r, s} = this.params; - if (_.isUndefined(v) || _.isUndefined(r) || _.isUndefined(s)) { - throw new Error('Cannot call isValidSignature on unsigned order'); + public params: OrderParams; + constructor(params: OrderParams) { + this.params = params; } - const orderHash = this.getOrderHash(); - 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 isValidSignature() { + const {v, r, s} = this.params; + if (_.isUndefined(v) || _.isUndefined(r) || _.isUndefined(s)) { + throw new Error('Cannot call isValidSignature on unsigned order'); + } + const orderHash = this.getOrderHash(); + 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 async signAsync() { + const orderHash = this.getOrderHash(); + const signature = await promisify(web3.eth.sign)(this.params.maker, orderHash); + const {v, r, s} = ethUtil.fromRpcSig(signature); + this.params = _.assign(this.params, { + orderHashHex: orderHash, + v, + r: ethUtil.bufferToHex(r), + s: ethUtil.bufferToHex(s), + }); + } + 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; + } + private getOrderHash(): 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; } - } - public async signAsync() { - const orderHash = this.getOrderHash(); - const signature = await promisify(web3.eth.sign)(this.params.maker, orderHash); - const {v, r, s} = ethUtil.fromRpcSig(signature); - this.params = _.assign(this.params, { - orderHashHex: orderHash, - v, - r: ethUtil.bufferToHex(r), - s: ethUtil.bufferToHex(s), - }); - } - 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; - } - private getOrderHash(): 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 cdce7d18a..526e229a4 100644 --- a/packages/contracts/util/order_factory.ts +++ b/packages/contracts/util/order_factory.ts @@ -6,19 +6,19 @@ import {Order} from './order'; import {DefaultOrderParams, OptionalOrderParams, OrderParams} from './types'; export class OrderFactory { - private defaultOrderParams: DefaultOrderParams; - constructor(defaultOrderParams: DefaultOrderParams) { - this.defaultOrderParams = defaultOrderParams; - } - public async newSignedOrderAsync(customOrderParams: OptionalOrderParams = {}) { - 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 = new Order(orderParams); - await order.signAsync(); - return order; - } + private defaultOrderParams: DefaultOrderParams; + constructor(defaultOrderParams: DefaultOrderParams) { + this.defaultOrderParams = defaultOrderParams; + } + public async newSignedOrderAsync(customOrderParams: OptionalOrderParams = {}) { + 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 = new Order(orderParams); + await order.signAsync(); + return order; + } } diff --git a/packages/contracts/util/rpc.ts b/packages/contracts/util/rpc.ts index 37643874c..023602bd6 100644 --- a/packages/contracts/util/rpc.ts +++ b/packages/contracts/util/rpc.ts @@ -3,41 +3,41 @@ import 'isomorphic-fetch'; import * as truffleConf from '../truffle.js'; export class RPC { - private host: string; - private port: number; - private id: number; - constructor() { - this.host = truffleConf.networks.development.host; - this.port = truffleConf.networks.development.port; - this.id = 0; - } - public async increaseTimeAsync(time: number) { - const method = 'evm_increaseTime'; - const params = [time]; - const payload = this.toPayload(method, params); - return this.sendAsync(payload); - } - public async mineBlockAsync() { - const method = 'evm_mine'; - const payload = this.toPayload(method); - return this.sendAsync(payload); - } - private toPayload(method: string, params: any[] = []) { - const payload = JSON.stringify({ - id: this.id, - method, - params, - }); - this.id++; - return payload; - } - private async sendAsync(payload: string): Promise<any> { - const opts = { - method: 'POST', - body: payload, - }; - const response = await fetch(`http://${this.host}:${this.port}`, opts); - const responsePayload = await response.json(); - return responsePayload; - } + private host: string; + private port: number; + private id: number; + constructor() { + this.host = truffleConf.networks.development.host; + this.port = truffleConf.networks.development.port; + this.id = 0; + } + public async increaseTimeAsync(time: number) { + const method = 'evm_increaseTime'; + const params = [time]; + const payload = this.toPayload(method, params); + return this.sendAsync(payload); + } + public async mineBlockAsync() { + const method = 'evm_mine'; + const payload = this.toPayload(method); + return this.sendAsync(payload); + } + private toPayload(method: string, params: any[] = []) { + const payload = JSON.stringify({ + id: this.id, + method, + params, + }); + this.id++; + return payload; + } + private async sendAsync(payload: string): Promise<any> { + const opts = { + method: 'POST', + body: payload, + }; + const response = await fetch(`http://${this.host}:${this.port}`, opts); + const responsePayload = await response.json(); + return responsePayload; + } } diff --git a/packages/contracts/util/token_registry_wrapper.ts b/packages/contracts/util/token_registry_wrapper.ts index 5065a1802..5e1c627cc 100644 --- a/packages/contracts/util/token_registry_wrapper.ts +++ b/packages/contracts/util/token_registry_wrapper.ts @@ -1,56 +1,56 @@ import {ContractInstance, Token} from './types'; export class TokenRegWrapper { - private tokenReg: ContractInstance; - constructor(tokenRegContractInstance: ContractInstance) { - this.tokenReg = tokenRegContractInstance; - } - public addTokenAsync(token: Token, from: string) { - const tx = this.tokenReg.addToken( - token.address, - token.name, - token.symbol, - token.decimals, - token.ipfsHash, - token.swarmHash, - {from}, - ); - return tx; - } - public async getTokenMetaDataAsync(tokenAddress: string) { - const data = await this.tokenReg.getTokenMetaData(tokenAddress); - const token: Token = { - address: data[0], - name: data[1], - symbol: data[2], - decimals: data[3].toNumber(), - ipfsHash: data[4], - swarmHash: data[5], - }; - return token; - } - public async getTokenByNameAsync(tokenName: string) { - const data = await this.tokenReg.getTokenByName(tokenName); - const token: Token = { - address: data[0], - name: data[1], - symbol: data[2], - decimals: data[3].toNumber(), - ipfsHash: data[4], - swarmHash: data[5], - }; - return token; - } - public async getTokenBySymbolAsync(tokenSymbol: string) { - const data = await this.tokenReg.getTokenBySymbol(tokenSymbol); - const token: Token = { - address: data[0], - name: data[1], - symbol: data[2], - decimals: data[3].toNumber(), - ipfsHash: data[4], - swarmHash: data[5], - }; - return token; - } + private tokenReg: ContractInstance; + constructor(tokenRegContractInstance: ContractInstance) { + this.tokenReg = tokenRegContractInstance; + } + public addTokenAsync(token: Token, from: string) { + const tx = this.tokenReg.addToken( + token.address, + token.name, + token.symbol, + token.decimals, + token.ipfsHash, + token.swarmHash, + {from}, + ); + return tx; + } + public async getTokenMetaDataAsync(tokenAddress: string) { + const data = await this.tokenReg.getTokenMetaData(tokenAddress); + const token: Token = { + address: data[0], + name: data[1], + symbol: data[2], + decimals: data[3].toNumber(), + ipfsHash: data[4], + swarmHash: data[5], + }; + return token; + } + public async getTokenByNameAsync(tokenName: string) { + const data = await this.tokenReg.getTokenByName(tokenName); + const token: Token = { + address: data[0], + name: data[1], + symbol: data[2], + decimals: data[3].toNumber(), + ipfsHash: data[4], + swarmHash: data[5], + }; + return token; + } + public async getTokenBySymbolAsync(tokenSymbol: string) { + const data = await this.tokenReg.getTokenBySymbol(tokenSymbol); + const token: Token = { + address: data[0], + name: data[1], + symbol: data[2], + decimals: data[3].toNumber(), + ipfsHash: data[4], + swarmHash: data[5], + }; + return token; + } } diff --git a/packages/contracts/util/types.ts b/packages/contracts/util/types.ts index 2e16fac7a..b2cf786df 100644 --- a/packages/contracts/util/types.ts +++ b/packages/contracts/util/types.ts @@ -2,118 +2,118 @@ import {BigNumber} from 'bignumber.js'; import * as Web3 from 'web3'; export interface BalancesByOwner { - [ownerAddress: string]: { - [tokenAddress: string]: BigNumber; - }; + [ownerAddress: string]: { + [tokenAddress: string]: BigNumber; + }; } export interface BatchFillOrders { - orderAddresses: string[][]; - orderValues: BigNumber[][]; - fillTakerTokenAmounts: BigNumber[]; - shouldThrowOnInsufficientBalanceOrAllowance: boolean; - v: number[]; - r: string[]; - s: string[]; + orderAddresses: string[][]; + orderValues: BigNumber[][]; + fillTakerTokenAmounts: BigNumber[]; + shouldThrowOnInsufficientBalanceOrAllowance: boolean; + v: number[]; + r: string[]; + s: string[]; } export interface FillOrdersUpTo { - orderAddresses: string[][]; - orderValues: BigNumber[][]; - fillTakerTokenAmount: BigNumber; - shouldThrowOnInsufficientBalanceOrAllowance: boolean; - v: number[]; - r: string[]; - s: string[]; + orderAddresses: string[][]; + orderValues: BigNumber[][]; + fillTakerTokenAmount: BigNumber; + shouldThrowOnInsufficientBalanceOrAllowance: boolean; + v: number[]; + r: string[]; + s: string[]; } export interface BatchCancelOrders { - orderAddresses: string[][]; - orderValues: BigNumber[][]; - cancelTakerTokenAmounts: BigNumber[]; + orderAddresses: string[][]; + orderValues: BigNumber[][]; + cancelTakerTokenAmounts: BigNumber[]; } export interface DefaultOrderParams { - exchangeContractAddress: string; - maker: string; - feeRecipient: string; - makerToken: string; - takerToken: string; - makerTokenAmount: BigNumber; - takerTokenAmount: BigNumber; - makerFee: BigNumber; - takerFee: BigNumber; + exchangeContractAddress: string; + maker: string; + feeRecipient: string; + makerToken: string; + takerToken: string; + makerTokenAmount: BigNumber; + takerTokenAmount: BigNumber; + makerFee: BigNumber; + 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; + 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; - orderHashHex?: string; - v?: number; - r?: string; - s?: string; + exchangeContractAddress: string; + maker: string; + taker: string; + feeRecipient: string; + makerToken: string; + takerToken: string; + makerTokenAmount: BigNumber; + takerTokenAmount: BigNumber; + makerFee: BigNumber; + takerFee: BigNumber; + expirationTimestampInSec: BigNumber; + salt: BigNumber; + orderHashHex?: string; + v?: number; + r?: string; + s?: string; } export interface TransactionDataParams { - name: string; - abi: Web3.AbiDefinition[]; - args: any[]; + name: string; + abi: Web3.AbiDefinition[]; + args: any[]; } export interface Token { - address?: string; - name: string; - symbol: string; - decimals: number; - ipfsHash: string; - swarmHash: string; + address?: string; + name: string; + symbol: string; + decimals: number; + ipfsHash: string; + swarmHash: string; } export interface MultiSigConfig { - owners: string[]; - confirmationsRequired: number; - secondsRequired: number; + owners: string[]; + confirmationsRequired: number; + secondsRequired: number; } export interface MultiSigConfigByNetwork { - [networkName: string]: MultiSigConfig; + [networkName: string]: MultiSigConfig; } export interface TokenInfoByNetwork { - development: Token[]; - live: Token[]; + development: Token[]; + live: Token[]; } // Named type aliases to improve readability export type ContractInstance = any; export enum ExchangeContractErrs { - ERROR_ORDER_EXPIRED, - ERROR_ORDER_FULLY_FILLED_OR_CANCELLED, - ERROR_ROUNDING_ERROR_TOO_LARGE, - ERROR_INSUFFICIENT_BALANCE_OR_ALLOWANCE, + ERROR_ORDER_EXPIRED, + ERROR_ORDER_FULLY_FILLED_OR_CANCELLED, + ERROR_ROUNDING_ERROR_TOO_LARGE, + ERROR_INSUFFICIENT_BALANCE_OR_ALLOWANCE, } |