From 7201a74aeaa6b646e97d7c9c2c4cc979ace5f4f7 Mon Sep 17 00:00:00 2001 From: Amir Bandeali Date: Thu, 8 Feb 2018 17:09:34 -0800 Subject: Move utils dir into src --- packages/contracts/src/utils/artifacts.ts | 25 +++ packages/contracts/src/utils/balances.ts | 30 +++ packages/contracts/src/utils/constants.ts | 14 ++ packages/contracts/src/utils/crypto.ts | 43 +++++ packages/contracts/src/utils/exchange_wrapper.ts | 204 +++++++++++++++++++++ packages/contracts/src/utils/formatters.ts | 107 +++++++++++ packages/contracts/src/utils/multi_sig_wrapper.ts | 43 +++++ packages/contracts/src/utils/order_factory.ts | 37 ++++ .../contracts/src/utils/token_registry_wrapper.ts | 60 ++++++ packages/contracts/src/utils/types.ts | 116 ++++++++++++ packages/contracts/test/ether_token.ts | 4 +- packages/contracts/test/exchange/core.ts | 12 +- packages/contracts/test/exchange/helpers.ts | 15 +- packages/contracts/test/exchange/wrapper.ts | 10 +- .../contracts/test/multi_sig_with_time_lock.ts | 8 +- ...i_sig_with_time_lock_except_remove_auth_addr.ts | 10 +- packages/contracts/test/token_registry.ts | 6 +- .../contracts/test/token_transfer_proxy/auth.ts | 4 +- .../test/token_transfer_proxy/transfer_from.ts | 6 +- .../contracts/test/unlimited_allowance_token.ts | 4 +- packages/contracts/test/utils/deployer.ts | 2 +- packages/contracts/test/zrx_token.ts | 4 +- packages/contracts/util/artifacts.ts | 25 --- packages/contracts/util/balances.ts | 30 --- packages/contracts/util/constants.ts | 14 -- packages/contracts/util/crypto.ts | 43 ----- packages/contracts/util/exchange_wrapper.ts | 204 --------------------- packages/contracts/util/formatters.ts | 107 ----------- packages/contracts/util/multi_sig_wrapper.ts | 43 ----- packages/contracts/util/order_factory.ts | 37 ---- packages/contracts/util/token_registry_wrapper.ts | 60 ------ packages/contracts/util/types.ts | 116 ------------ 32 files changed, 719 insertions(+), 724 deletions(-) create mode 100644 packages/contracts/src/utils/artifacts.ts create mode 100644 packages/contracts/src/utils/balances.ts create mode 100644 packages/contracts/src/utils/constants.ts create mode 100644 packages/contracts/src/utils/crypto.ts create mode 100644 packages/contracts/src/utils/exchange_wrapper.ts create mode 100644 packages/contracts/src/utils/formatters.ts create mode 100644 packages/contracts/src/utils/multi_sig_wrapper.ts create mode 100644 packages/contracts/src/utils/order_factory.ts create mode 100644 packages/contracts/src/utils/token_registry_wrapper.ts create mode 100644 packages/contracts/src/utils/types.ts delete mode 100644 packages/contracts/util/artifacts.ts delete mode 100644 packages/contracts/util/balances.ts delete mode 100644 packages/contracts/util/constants.ts delete mode 100644 packages/contracts/util/crypto.ts delete mode 100644 packages/contracts/util/exchange_wrapper.ts delete mode 100644 packages/contracts/util/formatters.ts delete mode 100644 packages/contracts/util/multi_sig_wrapper.ts delete mode 100644 packages/contracts/util/order_factory.ts delete mode 100644 packages/contracts/util/token_registry_wrapper.ts delete mode 100644 packages/contracts/util/types.ts (limited to 'packages') diff --git a/packages/contracts/src/utils/artifacts.ts b/packages/contracts/src/utils/artifacts.ts new file mode 100644 index 000000000..fd9380d1d --- /dev/null +++ b/packages/contracts/src/utils/artifacts.ts @@ -0,0 +1,25 @@ +import * as DummyTokenArtifact from '../artifacts/DummyToken.json'; +import * as ExchangeArtifact from '../artifacts/Exchange.json'; +import * as MaliciousTokenArtifact from '../artifacts/MaliciousToken.json'; +import * as MultiSigWalletWithTimeLockArtifact from '../artifacts/MultiSigWalletWithTimeLock.json'; +import * as MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact from '../artifacts/MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.json'; +import * as TokenArtifact from '../artifacts/Token.json'; +import * as TokenRegistryArtifact from '../artifacts/TokenRegistry.json'; +import * as TokenTransferProxyArtifact from '../artifacts/TokenTransferProxy.json'; +import * as EtherTokenArtifact from '../artifacts/WETH9.json'; +import * as ZRXArtifact from '../artifacts/ZRXToken.json'; + +import { Artifact } from './types'; + +export const artifacts = { + ZRXArtifact: (ZRXArtifact as any) as Artifact, + DummyTokenArtifact: (DummyTokenArtifact as any) as Artifact, + TokenArtifact: (TokenArtifact as any) as Artifact, + ExchangeArtifact: (ExchangeArtifact as any) as Artifact, + EtherTokenArtifact: (EtherTokenArtifact as any) as Artifact, + TokenRegistryArtifact: (TokenRegistryArtifact as any) as Artifact, + MaliciousTokenArtifact: (MaliciousTokenArtifact as any) as Artifact, + TokenTransferProxyArtifact: (TokenTransferProxyArtifact as any) as Artifact, + MultiSigWalletWithTimeLockArtifact: (MultiSigWalletWithTimeLockArtifact as any) as Artifact, + MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact: (MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact as any) as Artifact, +}; diff --git a/packages/contracts/src/utils/balances.ts b/packages/contracts/src/utils/balances.ts new file mode 100644 index 000000000..2ebc10313 --- /dev/null +++ b/packages/contracts/src/utils/balances.ts @@ -0,0 +1,30 @@ +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; +import * as Web3 from 'web3'; + +import { DummyTokenContract } from '../contract_wrappers/generated/dummy_token'; + +import { BalancesByOwner } from './types'; + +export class Balances { + private _tokenContractInstances: DummyTokenContract[]; + private _ownerAddresses: string[]; + constructor(tokenContractInstances: DummyTokenContract[], ownerAddresses: string[]) { + this._tokenContractInstances = tokenContractInstances; + this._ownerAddresses = ownerAddresses; + } + public async getAsync(): Promise { + const balancesByOwner: BalancesByOwner = {}; + for (const tokenContractInstance of this._tokenContractInstances) { + for (const ownerAddress of this._ownerAddresses) { + let balance = await tokenContractInstance.balanceOf.callAsync(ownerAddress); + balance = new BigNumber(balance); + if (_.isUndefined(balancesByOwner[ownerAddress])) { + balancesByOwner[ownerAddress] = {}; + } + balancesByOwner[ownerAddress][tokenContractInstance.address] = balance; + } + } + return balancesByOwner; + } +} diff --git a/packages/contracts/src/utils/constants.ts b/packages/contracts/src/utils/constants.ts new file mode 100644 index 000000000..d1152e683 --- /dev/null +++ b/packages/contracts/src/utils/constants.ts @@ -0,0 +1,14 @@ +const DUMMY_TOKEN_NAME = ''; +const DUMMY_TOKEN_SYMBOL = ''; +const DUMMY_TOKEN_DECIMALS = 18; +const DUMMY_TOKEN_TOTAL_SUPPLY = 0; + +export const constants = { + INVALID_OPCODE: 'invalid opcode', + REVERT: 'revert', + TESTRPC_NETWORK_ID: 50, + MAX_ETHERTOKEN_WITHDRAW_GAS: 43000, + MAX_TOKEN_TRANSFERFROM_GAS: 80000, + MAX_TOKEN_APPROVE_GAS: 60000, + DUMMY_TOKEN_ARGS: [DUMMY_TOKEN_NAME, DUMMY_TOKEN_SYMBOL, DUMMY_TOKEN_DECIMALS, DUMMY_TOKEN_TOTAL_SUPPLY], +}; diff --git a/packages/contracts/src/utils/crypto.ts b/packages/contracts/src/utils/crypto.ts new file mode 100644 index 000000000..810072d2f --- /dev/null +++ b/packages/contracts/src/utils/crypto.ts @@ -0,0 +1,43 @@ +import BN = require('bn.js'); +import ABI = require('ethereumjs-abi'); +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 + * string -> string + * boolean -> bool + * valid Ethereum address -> address + */ + solSHA3(args: any[]): Buffer { + return crypto._solHash(args, ABI.soliditySHA3); + }, + solSHA256(args: any[]): Buffer { + return crypto._solHash(args, ABI.soliditySHA256); + }, + _solHash(args: any[], hashFunction: (types: string[], values: 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 = hashFunction(argTypes, args); + return hash; + }, +}; diff --git a/packages/contracts/src/utils/exchange_wrapper.ts b/packages/contracts/src/utils/exchange_wrapper.ts new file mode 100644 index 000000000..75b452b04 --- /dev/null +++ b/packages/contracts/src/utils/exchange_wrapper.ts @@ -0,0 +1,204 @@ +import { SignedOrder, TransactionReceiptWithDecodedLogs, ZeroEx } from '0x.js'; +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; +import * as Web3 from 'web3'; + +import { ExchangeContract } from '../contract_wrappers/generated/exchange'; + +import { formatters } from './formatters'; +import { signedOrderUtils } from './signed_order_utils'; + +export class ExchangeWrapper { + private _exchange: ExchangeContract; + private _zeroEx: ZeroEx; + constructor(exchangeContract: ExchangeContract, zeroEx: ZeroEx) { + this._exchange = exchangeContract; + this._zeroEx = zeroEx; + } + public async fillOrderAsync( + signedOrder: SignedOrder, + from: string, + opts: { takerTokenFillAmount?: BigNumber } = {}, + ): Promise { + const params = signedOrderUtils.createFill( + signedOrder, + opts.takerTokenFillAmount, + ); + const txHash = await this._exchange.fillOrder.sendTransactionAsync( + params.orderAddresses, + params.orderValues, + params.takerTokenFillAmount, + params.v, + params.r, + params.s, + { from }, + ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async cancelOrderAsync( + signedOrder: SignedOrder, + from: string, + opts: { takerTokenCancelAmount?: BigNumber } = {}, + ): Promise { + const params = signedOrderUtils.createCancel(signedOrder, opts.takerTokenCancelAmount); + const txHash = await this._exchange.cancelOrder.sendTransactionAsync( + params.orderAddresses, + params.orderValues, + params.takerTokenCancelAmount, + { from }, + ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async fillOrKillOrderAsync( + signedOrder: SignedOrder, + from: string, + opts: { takerTokenFillAmount?: BigNumber } = {}, + ): Promise { + const params = signedOrderUtils.createFill( + signedOrder, + opts.takerTokenFillAmount, + ); + const txHash = await this._exchange.fillOrKillOrder.sendTransactionAsync( + params.orderAddresses, + params.orderValues, + params.takerTokenFillAmount, + params.v, + params.r, + params.s, + { from }, + ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async batchFillOrdersAsync( + orders: SignedOrder[], + from: string, + opts: { + takerTokenFillAmounts?: BigNumber[]; + shouldThrowOnInsufficientBalanceOrAllowance?: boolean; + } = {}, + ): Promise { + const params = formatters.createBatchFill(orders, opts.takerTokenFillAmounts); + const txHash = await this._exchange.batchFillOrders.sendTransactionAsync( + params.orderAddresses, + params.orderValues, + params.takerTokenFillAmounts, + params.v, + params.r, + params.s, + { from }, + ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async batchFillOrKillOrdersAsync( + orders: SignedOrder[], + from: string, + opts: { takerTokenFillAmounts?: BigNumber[] } = {}, + ): Promise { + const params = formatters.createBatchFill(orders, opts.takerTokenFillAmounts); + const txHash = await this._exchange.batchFillOrKillOrders.sendTransactionAsync( + params.orderAddresses, + params.orderValues, + params.takerTokenFillAmounts, + params.v, + params.r, + params.s, + { from }, + ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async marketFillOrdersAsync( + orders: SignedOrder[], + from: string, + opts: { takerTokenFillAmount: BigNumber }, + ): Promise { + const params = formatters.createMarketFillOrders(orders, opts.takerTokenFillAmount); + const txHash = await this._exchange.marketFillOrders.sendTransactionAsync( + params.orderAddresses, + params.orderValues, + params.takerTokenFillAmount, + params.v, + params.r, + params.s, + { from }, + ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async batchCancelOrdersAsync( + orders: SignedOrder[], + from: string, + opts: { takerTokenCancelAmounts?: BigNumber[] } = {}, + ): Promise { + const params = formatters.createBatchCancel(orders, opts.takerTokenCancelAmounts); + const txHash = await this._exchange.batchCancelOrders.sendTransactionAsync( + params.orderAddresses, + params.orderValues, + params.takerTokenCancelAmounts, + { from }, + ); + const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); + tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); + _.each(tx.logs, log => wrapLogBigNumbers(log)); + return tx; + } + public async getOrderHashAsync(signedOrder: SignedOrder): Promise { + const params = signedOrderUtils.getOrderAddressesAndValues(signedOrder); + const orderHash = await this._exchange.getOrderHash.callAsync(params.orderAddresses, params.orderValues); + return orderHash; + } + public async isValidSignatureAsync(signedOrder: SignedOrder): Promise { + const isValidSignature = await this._exchange.isValidSignature.callAsync( + signedOrder.maker, + ZeroEx.getOrderHashHex(signedOrder), + signedOrder.ecSignature.v, + signedOrder.ecSignature.r, + signedOrder.ecSignature.s, + ); + return isValidSignature; + } + public async isRoundingErrorAsync( + numerator: BigNumber, + denominator: BigNumber, + target: BigNumber, + ): Promise { + const isRoundingError = await this._exchange.isRoundingError.callAsync(numerator, denominator, target); + return isRoundingError; + } + public async getPartialAmountAsync( + numerator: BigNumber, + denominator: BigNumber, + target: BigNumber, + ): Promise { + const partialAmount = new BigNumber( + await this._exchange.getPartialAmount.callAsync(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]); + } + } +} diff --git a/packages/contracts/src/utils/formatters.ts b/packages/contracts/src/utils/formatters.ts new file mode 100644 index 000000000..88e12a6b4 --- /dev/null +++ b/packages/contracts/src/utils/formatters.ts @@ -0,0 +1,107 @@ +import { SignedOrder } from '0x.js'; +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; + +import { BatchCancelOrders, BatchFillOrders, MarketFillOrders } from './types'; + +export const formatters = { + createBatchFill( + signedOrders: SignedOrder[], + takerTokenFillAmounts: BigNumber[] = [], + ) { + const batchFill: BatchFillOrders = { + orderAddresses: [], + orderValues: [], + takerTokenFillAmounts, + v: [], + r: [], + s: [], + }; + _.forEach(signedOrders, signedOrder => { + batchFill.orderAddresses.push([ + signedOrder.maker, + signedOrder.taker, + signedOrder.makerTokenAddress, + signedOrder.takerTokenAddress, + signedOrder.feeRecipient, + ]); + batchFill.orderValues.push([ + signedOrder.makerTokenAmount, + signedOrder.takerTokenAmount, + signedOrder.makerFee, + signedOrder.takerFee, + signedOrder.expirationUnixTimestampSec, + signedOrder.salt, + ]); + batchFill.v.push(signedOrder.ecSignature.v); + batchFill.r.push(signedOrder.ecSignature.r); + batchFill.s.push(signedOrder.ecSignature.s); + if (takerTokenFillAmounts.length < signedOrders.length) { + batchFill.takerTokenFillAmounts.push(signedOrder.takerTokenAmount); + } + }); + return batchFill; + }, + createMarketFillOrders( + signedOrders: SignedOrder[], + takerTokenFillAmount: BigNumber, + ) { + const marketFillOrders: MarketFillOrders = { + orderAddresses: [], + orderValues: [], + takerTokenFillAmount, + v: [], + r: [], + s: [], + }; + signedOrders.forEach(signedOrder => { + marketFillOrders.orderAddresses.push([ + signedOrder.maker, + signedOrder.taker, + signedOrder.makerTokenAddress, + signedOrder.takerTokenAddress, + signedOrder.feeRecipient, + ]); + marketFillOrders.orderValues.push([ + signedOrder.makerTokenAmount, + signedOrder.takerTokenAmount, + signedOrder.makerFee, + signedOrder.takerFee, + signedOrder.expirationUnixTimestampSec, + signedOrder.salt, + ]); + marketFillOrders.v.push(signedOrder.ecSignature.v); + marketFillOrders.r.push(signedOrder.ecSignature.r); + marketFillOrders.s.push(signedOrder.ecSignature.s); + }); + return marketFillOrders; + }, + createBatchCancel(signedOrders: SignedOrder[], takerTokenCancelAmounts: BigNumber[] = []) { + const batchCancel: BatchCancelOrders = { + orderAddresses: [], + orderValues: [], + takerTokenCancelAmounts, + }; + signedOrders.forEach(signedOrder => { + batchCancel.orderAddresses.push([ + signedOrder.maker, + signedOrder.taker, + signedOrder.makerTokenAddress, + signedOrder.takerTokenAddress, + signedOrder.feeRecipient, + ]); + batchCancel.orderValues.push([ + signedOrder.makerTokenAmount, + signedOrder.takerTokenAmount, + signedOrder.makerFee, + signedOrder.takerFee, + signedOrder.expirationUnixTimestampSec, + signedOrder.salt, + ]); + if (takerTokenCancelAmounts.length < signedOrders.length) { + batchCancel.takerTokenCancelAmounts.push(signedOrder.takerTokenAmount); + } + }); + return batchCancel; + }, +}; diff --git a/packages/contracts/src/utils/multi_sig_wrapper.ts b/packages/contracts/src/utils/multi_sig_wrapper.ts new file mode 100644 index 000000000..84fed7944 --- /dev/null +++ b/packages/contracts/src/utils/multi_sig_wrapper.ts @@ -0,0 +1,43 @@ +import { AbiDefinition, MethodAbi } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; +import ABI = require('ethereumjs-abi'); +import ethUtil = require('ethereumjs-util'); +import * as _ from 'lodash'; +import * as Web3 from 'web3'; + +import { MultiSigWalletContract } from '../contract_wrappers/generated/multi_sig_wallet'; + +import { TransactionDataParams } from './types'; + +export class MultiSigWrapper { + private _multiSig: MultiSigWalletContract; + public static encodeFnArgs(name: string, abi: AbiDefinition[], args: any[]) { + const abiEntity = _.find(abi, { name }) as 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(''); + } + constructor(multiSigContract: MultiSigWalletContract) { + this._multiSig = multiSigContract; + } + public async submitTransactionAsync( + destination: string, + from: string, + dataParams: TransactionDataParams, + value: BigNumber = new BigNumber(0), + ) { + const { name, abi, args = [] } = dataParams; + const encoded = MultiSigWrapper.encodeFnArgs(name, abi, args); + return this._multiSig.submitTransaction.sendTransactionAsync(destination, value, encoded, { + from, + }); + } +} diff --git a/packages/contracts/src/utils/order_factory.ts b/packages/contracts/src/utils/order_factory.ts new file mode 100644 index 000000000..8ba5df24a --- /dev/null +++ b/packages/contracts/src/utils/order_factory.ts @@ -0,0 +1,37 @@ +import { Order, SignedOrder, ZeroEx } from '0x.js'; +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as _ from 'lodash'; + +import { DefaultOrderParams } from './types'; + +export class OrderFactory { + private _defaultOrderParams: Partial; + private _zeroEx: ZeroEx; + constructor(zeroEx: ZeroEx, defaultOrderParams: Partial) { + this._defaultOrderParams = defaultOrderParams; + this._zeroEx = zeroEx; + } + public async newSignedOrderAsync(customOrderParams: Partial = {}): Promise { + const randomExpiration = new BigNumber(Math.floor((Date.now() + Math.random() * 100000000000) / 1000)); + 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 signedOrder = { + ...order, + ecSignature, + }; + return signedOrder; + } +} diff --git a/packages/contracts/src/utils/token_registry_wrapper.ts b/packages/contracts/src/utils/token_registry_wrapper.ts new file mode 100644 index 000000000..91bd5503d --- /dev/null +++ b/packages/contracts/src/utils/token_registry_wrapper.ts @@ -0,0 +1,60 @@ +import * as Web3 from 'web3'; + +import { TokenRegistryContract } from '../contract_wrappers/generated/token_registry'; + +import { Token } from './types'; + +export class TokenRegWrapper { + private _tokenReg: TokenRegistryContract; + constructor(tokenRegContract: TokenRegistryContract) { + this._tokenReg = tokenRegContract; + } + public async addTokenAsync(token: Token, from: string) { + const tx = this._tokenReg.addToken.sendTransactionAsync( + token.address as string, + token.name, + token.symbol, + token.decimals, + token.ipfsHash, + token.swarmHash, + { from }, + ); + return tx; + } + public async getTokenMetaDataAsync(tokenAddress: string) { + const data = await this._tokenReg.getTokenMetaData.callAsync(tokenAddress); + const token: Token = { + address: data[0], + name: data[1], + symbol: data[2], + decimals: data[3], + ipfsHash: data[4], + swarmHash: data[5], + }; + return token; + } + public async getTokenByNameAsync(tokenName: string) { + const data = await this._tokenReg.getTokenByName.callAsync(tokenName); + const token: Token = { + address: data[0], + name: data[1], + symbol: data[2], + decimals: data[3], + ipfsHash: data[4], + swarmHash: data[5], + }; + return token; + } + public async getTokenBySymbolAsync(tokenSymbol: string) { + const data = await this._tokenReg.getTokenBySymbol.callAsync(tokenSymbol); + const token: Token = { + address: data[0], + name: data[1], + symbol: data[2], + decimals: data[3], + ipfsHash: data[4], + swarmHash: data[5], + }; + return token; + } +} diff --git a/packages/contracts/src/utils/types.ts b/packages/contracts/src/utils/types.ts new file mode 100644 index 000000000..2ffc84f04 --- /dev/null +++ b/packages/contracts/src/utils/types.ts @@ -0,0 +1,116 @@ +import { AbiDefinition, ContractAbi } from '@0xproject/types'; +import { BigNumber } from '@0xproject/utils'; + +export interface BalancesByOwner { + [ownerAddress: string]: { + [tokenAddress: string]: BigNumber; + }; +} + +export interface SubmissionContractEventArgs { + transactionId: BigNumber; +} + +export interface BatchFillOrders { + orderAddresses: string[][]; + orderValues: BigNumber[][]; + takerTokenFillAmounts: BigNumber[]; + v: number[]; + r: string[]; + s: string[]; +} + +export interface MarketFillOrders { + orderAddresses: string[][]; + orderValues: BigNumber[][]; + takerTokenFillAmount: BigNumber; + v: number[]; + r: string[]; + s: string[]; +} + +export interface BatchCancelOrders { + orderAddresses: string[][]; + orderValues: BigNumber[][]; + takerTokenCancelAmounts: BigNumber[]; +} + +export interface DefaultOrderParams { + exchangeContractAddress: string; + maker: string; + feeRecipient: string; + makerTokenAddress: string; + takerTokenAddress: string; + makerTokenAmount: BigNumber; + takerTokenAmount: BigNumber; + makerFee: BigNumber; + takerFee: BigNumber; +} + +export interface TransactionDataParams { + name: string; + abi: AbiDefinition[]; + args: any[]; +} + +export interface MultiSigConfig { + owners: string[]; + confirmationsRequired: number; + secondsRequired: number; +} + +export interface MultiSigConfigByNetwork { + [networkName: string]: MultiSigConfig; +} + +export interface Token { + address?: string; + name: string; + symbol: string; + decimals: number; + ipfsHash: string; + swarmHash: string; +} + +export interface TokenInfoByNetwork { + development: Token[]; + live: Token[]; +} + +export enum ExchangeContractErrs { + ERROR_ORDER_EXPIRED, + ERROR_ORDER_FULLY_FILLED_OR_CANCELLED, + ERROR_ROUNDING_ERROR_TOO_LARGE, + ERROR_INSUFFICIENT_BALANCE_OR_ALLOWANCE, +} + +export enum ContractName { + TokenTransferProxy = 'TokenTransferProxy', + TokenRegistry = 'TokenRegistry', + MultiSigWalletWithTimeLock = 'MultiSigWalletWithTimeLock', + Exchange = 'Exchange', + ZRXToken = 'ZRXToken', + DummyToken = 'DummyToken', + EtherToken = 'WETH9', + MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = 'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', + MaliciousToken = 'MaliciousToken', + AccountLevels = 'AccountLevels', + EtherDelta = 'EtherDelta', + Arbitrage = 'Arbitrage', +} + +export interface Artifact { + contract_name: ContractName; + networks: { + [networkId: number]: { + abi: ContractAbi; + solc_version: string; + keccak256: string; + optimizer_enabled: number; + unlinked_binary: string; + updated_at: number; + address: string; + constructor_args: string; + }; + }; +} diff --git a/packages/contracts/test/ether_token.ts b/packages/contracts/test/ether_token.ts index 4023abad0..e9aba07c5 100644 --- a/packages/contracts/test/ether_token.ts +++ b/packages/contracts/test/ether_token.ts @@ -4,8 +4,8 @@ import { BigNumber, promisify } from '@0xproject/utils'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; -import { constants } from '../util/constants'; -import { ContractName } from '../util/types'; +import { constants } from '../src/utils/constants'; +import { ContractName } from '../src/utils/types'; import { chaiSetup } from './utils/chai_setup'; import { deployer } from './utils/deployer'; diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index 4fd837d51..a1758457b 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -15,12 +15,12 @@ import { LogFillContractEventArgs, } from '../../src/contract_wrappers/generated/exchange'; import { TokenTransferProxyContract } from '../../src/contract_wrappers/generated/token_transfer_proxy'; -import { Balances } from '../../util/balances'; -import { constants } from '../../util/constants'; -import { crypto } from '../../util/crypto'; -import { ExchangeWrapper } from '../../util/exchange_wrapper'; -import { OrderFactory } from '../../util/order_factory'; -import { BalancesByOwner, ContractName, ExchangeContractErrs } from '../../util/types'; +import { Balances } from '../../src/utils/balances'; +import { constants } from '../../src/utils/constants'; +import { crypto } from '../../src/utils/crypto'; +import { ExchangeWrapper } from '../../src/utils/exchange_wrapper'; +import { OrderFactory } from '../../src/utils/order_factory'; +import { BalancesByOwner, ContractName, ExchangeContractErrs } from '../../src/utils/types'; import { chaiSetup } from '../utils/chai_setup'; import { deployer } from '../utils/deployer'; import { provider, web3Wrapper } from '../utils/web3_wrapper'; diff --git a/packages/contracts/test/exchange/helpers.ts b/packages/contracts/test/exchange/helpers.ts index 8fc30c0b5..d41f37446 100644 --- a/packages/contracts/test/exchange/helpers.ts +++ b/packages/contracts/test/exchange/helpers.ts @@ -5,16 +5,11 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as chai from 'chai'; import ethUtil = require('ethereumjs-util'); -import { - ExchangeContract, - LogCancelContractEventArgs, - LogErrorContractEventArgs, - LogFillContractEventArgs, -} from '../../src/contract_wrappers/generated/exchange'; -import { constants } from '../../util/constants'; -import { ExchangeWrapper } from '../../util/exchange_wrapper'; -import { OrderFactory } from '../../util/order_factory'; -import { ContractName } from '../../util/types'; +import { ExchangeContract } from '../../src/contract_wrappers/generated/exchange'; +import { constants } from '../../src/utils/constants'; +import { ExchangeWrapper } from '../../src/utils/exchange_wrapper'; +import { OrderFactory } from '../../src/utils/order_factory'; +import { ContractName } from '../../src/utils/types'; import { chaiSetup } from '../utils/chai_setup'; import { deployer } from '../utils/deployer'; import { provider, web3Wrapper } from '../utils/web3_wrapper'; diff --git a/packages/contracts/test/exchange/wrapper.ts b/packages/contracts/test/exchange/wrapper.ts index 440fd0517..2a803e2ac 100644 --- a/packages/contracts/test/exchange/wrapper.ts +++ b/packages/contracts/test/exchange/wrapper.ts @@ -15,11 +15,11 @@ import { } from '../../src/contract_wrappers/generated/exchange'; import { TokenRegistryContract } from '../../src/contract_wrappers/generated/token_registry'; import { TokenTransferProxyContract } from '../../src/contract_wrappers/generated/token_transfer_proxy'; -import { Balances } from '../../util/balances'; -import { constants } from '../../util/constants'; -import { ExchangeWrapper } from '../../util/exchange_wrapper'; -import { OrderFactory } from '../../util/order_factory'; -import { BalancesByOwner, ContractName } from '../../util/types'; +import { Balances } from '../../src/utils/balances'; +import { constants } from '../../src/utils/constants'; +import { ExchangeWrapper } from '../../src/utils/exchange_wrapper'; +import { OrderFactory } from '../../src/utils/order_factory'; +import { BalancesByOwner, ContractName } from '../../src/utils/types'; import { chaiSetup } from '../utils/chai_setup'; import { deployer } from '../utils/deployer'; import { provider, web3Wrapper } from '../utils/web3_wrapper'; diff --git a/packages/contracts/test/multi_sig_with_time_lock.ts b/packages/contracts/test/multi_sig_with_time_lock.ts index b7604457f..48600ae3d 100644 --- a/packages/contracts/test/multi_sig_with_time_lock.ts +++ b/packages/contracts/test/multi_sig_with_time_lock.ts @@ -8,10 +8,10 @@ import * as Web3 from 'web3'; import * as multiSigWalletJSON from '../../build/contracts/MultiSigWalletWithTimeLock.json'; import { MultiSigWalletContract } from '../src/contract_wrappers/generated/multi_sig_wallet'; import { MultiSigWalletWithTimeLockContract } from '../src/contract_wrappers/generated/multi_sig_wallet_with_time_lock'; -import { artifacts } from '../util/artifacts'; -import { constants } from '../util/constants'; -import { MultiSigWrapper } from '../util/multi_sig_wrapper'; -import { ContractName, SubmissionContractEventArgs } from '../util/types'; +import { artifacts } from '../src/utils/artifacts'; +import { constants } from '../src/utils/constants'; +import { MultiSigWrapper } from '../src/utils/multi_sig_wrapper'; +import { ContractName, SubmissionContractEventArgs } from '../src/utils/types'; import { chaiSetup } from './utils/chai_setup'; import { deployer } from './utils/deployer'; diff --git a/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts b/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts index 2f928ede2..f29d26fca 100644 --- a/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts +++ b/packages/contracts/test/multi_sig_with_time_lock_except_remove_auth_addr.ts @@ -8,11 +8,11 @@ import * as Web3 from 'web3'; import { MultiSigWalletContract } from '../src/contract_wrappers/generated/multi_sig_wallet'; import { MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressContract } from '../src/contract_wrappers/generated/multi_sig_wallet_with_time_lock_except_remove_authorized_address'; import { TokenTransferProxyContract } from '../src/contract_wrappers/generated/token_transfer_proxy'; -import { artifacts } from '../util/artifacts'; -import { constants } from '../util/constants'; -import { crypto } from '../util/crypto'; -import { MultiSigWrapper } from '../util/multi_sig_wrapper'; -import { ContractName, SubmissionContractEventArgs, TransactionDataParams } from '../util/types'; +import { artifacts } from '../src/utils/artifacts'; +import { constants } from '../src/utils/constants'; +import { crypto } from '../src/utils/crypto'; +import { MultiSigWrapper } from '../src/utils/multi_sig_wrapper'; +import { ContractName, SubmissionContractEventArgs, TransactionDataParams } from '../src/utils/types'; import { chaiSetup } from './utils/chai_setup'; import { deployer } from './utils/deployer'; diff --git a/packages/contracts/test/token_registry.ts b/packages/contracts/test/token_registry.ts index 4c404176b..c34478b65 100644 --- a/packages/contracts/test/token_registry.ts +++ b/packages/contracts/test/token_registry.ts @@ -8,9 +8,9 @@ import * as _ from 'lodash'; import * as Web3 from 'web3'; import { TokenRegistryContract } from '../src/contract_wrappers/generated/token_registry'; -import { constants } from '../util/constants'; -import { TokenRegWrapper } from '../util/token_registry_wrapper'; -import { ContractName } from '../util/types'; +import { constants } from '../src/utils/constants'; +import { TokenRegWrapper } from '../src/utils/token_registry_wrapper'; +import { ContractName } from '../src/utils/types'; import { chaiSetup } from './utils/chai_setup'; import { deployer } from './utils/deployer'; diff --git a/packages/contracts/test/token_transfer_proxy/auth.ts b/packages/contracts/test/token_transfer_proxy/auth.ts index 885ff3bc1..dc9eae4ff 100644 --- a/packages/contracts/test/token_transfer_proxy/auth.ts +++ b/packages/contracts/test/token_transfer_proxy/auth.ts @@ -4,8 +4,8 @@ import * as chai from 'chai'; import * as Web3 from 'web3'; import { TokenTransferProxyContract } from '../../src/contract_wrappers/generated/token_transfer_proxy'; -import { constants } from '../../util/constants'; -import { ContractName } from '../../util/types'; +import { constants } from '../../src/utils/constants'; +import { ContractName } from '../../src/utils/types'; import { chaiSetup } from '../utils/chai_setup'; import { deployer } from '../utils/deployer'; import { provider, web3Wrapper } from '../utils/web3_wrapper'; diff --git a/packages/contracts/test/token_transfer_proxy/transfer_from.ts b/packages/contracts/test/token_transfer_proxy/transfer_from.ts index dff1a0cfb..dc6757cd9 100644 --- a/packages/contracts/test/token_transfer_proxy/transfer_from.ts +++ b/packages/contracts/test/token_transfer_proxy/transfer_from.ts @@ -6,9 +6,9 @@ import * as Web3 from 'web3'; import { DummyTokenContract } from '../../src/contract_wrappers/generated/dummy_token'; import { TokenTransferProxyContract } from '../../src/contract_wrappers/generated/token_transfer_proxy'; -import { Balances } from '../../util/balances'; -import { constants } from '../../util/constants'; -import { ContractName } from '../../util/types'; +import { Balances } from '../../src/utils/balances'; +import { constants } from '../../src/utils/constants'; +import { ContractName } from '../../src/utils/types'; import { chaiSetup } from '../utils/chai_setup'; import { deployer } from '../utils/deployer'; import { provider, web3Wrapper } from '../utils/web3_wrapper'; diff --git a/packages/contracts/test/unlimited_allowance_token.ts b/packages/contracts/test/unlimited_allowance_token.ts index 618bda72d..50d5c4d03 100644 --- a/packages/contracts/test/unlimited_allowance_token.ts +++ b/packages/contracts/test/unlimited_allowance_token.ts @@ -6,8 +6,8 @@ import * as chai from 'chai'; import * as Web3 from 'web3'; import { DummyTokenContract } from '../src/contract_wrappers/generated/dummy_token'; -import { constants } from '../util/constants'; -import { ContractName } from '../util/types'; +import { constants } from '../src/utils/constants'; +import { ContractName } from '../src/utils/types'; import { chaiSetup } from './utils/chai_setup'; import { deployer } from './utils/deployer'; diff --git a/packages/contracts/test/utils/deployer.ts b/packages/contracts/test/utils/deployer.ts index 2f0951475..967cdd903 100644 --- a/packages/contracts/test/utils/deployer.ts +++ b/packages/contracts/test/utils/deployer.ts @@ -2,7 +2,7 @@ import { Deployer } from '@0xproject/deployer'; import { devConstants } from '@0xproject/dev-utils'; import * as path from 'path'; -import { constants } from '../../util/constants'; +import { constants } from '../../src/utils/constants'; import { web3 } from './web3_wrapper'; diff --git a/packages/contracts/test/zrx_token.ts b/packages/contracts/test/zrx_token.ts index b01615b39..259b4310e 100644 --- a/packages/contracts/test/zrx_token.ts +++ b/packages/contracts/test/zrx_token.ts @@ -6,8 +6,8 @@ import * as chai from 'chai'; import * as Web3 from 'web3'; import { ZRXTokenContract } from '../src/contract_wrappers/generated/zrx_token'; -import { constants } from '../util/constants'; -import { ContractName } from '../util/types'; +import { constants } from '../src/utils/constants'; +import { ContractName } from '../src/utils/types'; import { chaiSetup } from './utils/chai_setup'; import { deployer } from './utils/deployer'; diff --git a/packages/contracts/util/artifacts.ts b/packages/contracts/util/artifacts.ts deleted file mode 100644 index 7c375c1b7..000000000 --- a/packages/contracts/util/artifacts.ts +++ /dev/null @@ -1,25 +0,0 @@ -import * as DummyTokenArtifact from '../src/artifacts/DummyToken.json'; -import * as ExchangeArtifact from '../src/artifacts/Exchange.json'; -import * as MaliciousTokenArtifact from '../src/artifacts/MaliciousToken.json'; -import * as MultiSigWalletWithTimeLockArtifact from '../src/artifacts/MultiSigWalletWithTimeLock.json'; -import * as MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact from '../src/artifacts/MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.json'; -import * as TokenArtifact from '../src/artifacts/Token.json'; -import * as TokenRegistryArtifact from '../src/artifacts/TokenRegistry.json'; -import * as TokenTransferProxyArtifact from '../src/artifacts/TokenTransferProxy.json'; -import * as EtherTokenArtifact from '../src/artifacts/WETH9.json'; -import * as ZRXArtifact from '../src/artifacts/ZRXToken.json'; - -import { Artifact } from './types'; - -export const artifacts = { - ZRXArtifact: (ZRXArtifact as any) as Artifact, - DummyTokenArtifact: (DummyTokenArtifact as any) as Artifact, - TokenArtifact: (TokenArtifact as any) as Artifact, - ExchangeArtifact: (ExchangeArtifact as any) as Artifact, - EtherTokenArtifact: (EtherTokenArtifact as any) as Artifact, - TokenRegistryArtifact: (TokenRegistryArtifact as any) as Artifact, - MaliciousTokenArtifact: (MaliciousTokenArtifact as any) as Artifact, - TokenTransferProxyArtifact: (TokenTransferProxyArtifact as any) as Artifact, - MultiSigWalletWithTimeLockArtifact: (MultiSigWalletWithTimeLockArtifact as any) as Artifact, - MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact: (MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddressArtifact as any) as Artifact, -}; diff --git a/packages/contracts/util/balances.ts b/packages/contracts/util/balances.ts deleted file mode 100644 index d03d4b3c5..000000000 --- a/packages/contracts/util/balances.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { BigNumber } from '@0xproject/utils'; -import * as _ from 'lodash'; -import * as Web3 from 'web3'; - -import { DummyTokenContract } from '../src/contract_wrappers/generated/dummy_token'; - -import { BalancesByOwner } from './types'; - -export class Balances { - private _tokenContractInstances: DummyTokenContract[]; - private _ownerAddresses: string[]; - constructor(tokenContractInstances: DummyTokenContract[], ownerAddresses: string[]) { - this._tokenContractInstances = tokenContractInstances; - this._ownerAddresses = ownerAddresses; - } - public async getAsync(): Promise { - const balancesByOwner: BalancesByOwner = {}; - for (const tokenContractInstance of this._tokenContractInstances) { - for (const ownerAddress of this._ownerAddresses) { - let balance = await tokenContractInstance.balanceOf.callAsync(ownerAddress); - balance = new BigNumber(balance); - if (_.isUndefined(balancesByOwner[ownerAddress])) { - balancesByOwner[ownerAddress] = {}; - } - balancesByOwner[ownerAddress][tokenContractInstance.address] = balance; - } - } - return balancesByOwner; - } -} diff --git a/packages/contracts/util/constants.ts b/packages/contracts/util/constants.ts deleted file mode 100644 index d1152e683..000000000 --- a/packages/contracts/util/constants.ts +++ /dev/null @@ -1,14 +0,0 @@ -const DUMMY_TOKEN_NAME = ''; -const DUMMY_TOKEN_SYMBOL = ''; -const DUMMY_TOKEN_DECIMALS = 18; -const DUMMY_TOKEN_TOTAL_SUPPLY = 0; - -export const constants = { - INVALID_OPCODE: 'invalid opcode', - REVERT: 'revert', - TESTRPC_NETWORK_ID: 50, - MAX_ETHERTOKEN_WITHDRAW_GAS: 43000, - MAX_TOKEN_TRANSFERFROM_GAS: 80000, - MAX_TOKEN_APPROVE_GAS: 60000, - DUMMY_TOKEN_ARGS: [DUMMY_TOKEN_NAME, DUMMY_TOKEN_SYMBOL, DUMMY_TOKEN_DECIMALS, DUMMY_TOKEN_TOTAL_SUPPLY], -}; diff --git a/packages/contracts/util/crypto.ts b/packages/contracts/util/crypto.ts deleted file mode 100644 index 810072d2f..000000000 --- a/packages/contracts/util/crypto.ts +++ /dev/null @@ -1,43 +0,0 @@ -import BN = require('bn.js'); -import ABI = require('ethereumjs-abi'); -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 - * string -> string - * boolean -> bool - * valid Ethereum address -> address - */ - solSHA3(args: any[]): Buffer { - return crypto._solHash(args, ABI.soliditySHA3); - }, - solSHA256(args: any[]): Buffer { - return crypto._solHash(args, ABI.soliditySHA256); - }, - _solHash(args: any[], hashFunction: (types: string[], values: 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 = hashFunction(argTypes, args); - return hash; - }, -}; diff --git a/packages/contracts/util/exchange_wrapper.ts b/packages/contracts/util/exchange_wrapper.ts deleted file mode 100644 index d51efc025..000000000 --- a/packages/contracts/util/exchange_wrapper.ts +++ /dev/null @@ -1,204 +0,0 @@ -import { SignedOrder, TransactionReceiptWithDecodedLogs, ZeroEx } from '0x.js'; -import { BigNumber } from '@0xproject/utils'; -import * as _ from 'lodash'; -import * as Web3 from 'web3'; - -import { ExchangeContract } from '../src/contract_wrappers/generated/exchange'; - -import { formatters } from './formatters'; -import { signedOrderUtils } from './signed_order_utils'; - -export class ExchangeWrapper { - private _exchange: ExchangeContract; - private _zeroEx: ZeroEx; - constructor(exchangeContract: ExchangeContract, zeroEx: ZeroEx) { - this._exchange = exchangeContract; - this._zeroEx = zeroEx; - } - public async fillOrderAsync( - signedOrder: SignedOrder, - from: string, - opts: { takerTokenFillAmount?: BigNumber } = {}, - ): Promise { - const params = signedOrderUtils.createFill( - signedOrder, - opts.takerTokenFillAmount, - ); - const txHash = await this._exchange.fillOrder.sendTransactionAsync( - params.orderAddresses, - params.orderValues, - params.takerTokenFillAmount, - params.v, - params.r, - params.s, - { from }, - ); - const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); - tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async cancelOrderAsync( - signedOrder: SignedOrder, - from: string, - opts: { takerTokenCancelAmount?: BigNumber } = {}, - ): Promise { - const params = signedOrderUtils.createCancel(signedOrder, opts.takerTokenCancelAmount); - const txHash = await this._exchange.cancelOrder.sendTransactionAsync( - params.orderAddresses, - params.orderValues, - params.takerTokenCancelAmount, - { from }, - ); - const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); - tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async fillOrKillOrderAsync( - signedOrder: SignedOrder, - from: string, - opts: { takerTokenFillAmount?: BigNumber } = {}, - ): Promise { - const params = signedOrderUtils.createFill( - signedOrder, - opts.takerTokenFillAmount, - ); - const txHash = await this._exchange.fillOrKillOrder.sendTransactionAsync( - params.orderAddresses, - params.orderValues, - params.takerTokenFillAmount, - params.v, - params.r, - params.s, - { from }, - ); - const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); - tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async batchFillOrdersAsync( - orders: SignedOrder[], - from: string, - opts: { - takerTokenFillAmounts?: BigNumber[]; - shouldThrowOnInsufficientBalanceOrAllowance?: boolean; - } = {}, - ): Promise { - const params = formatters.createBatchFill(orders, opts.takerTokenFillAmounts); - const txHash = await this._exchange.batchFillOrders.sendTransactionAsync( - params.orderAddresses, - params.orderValues, - params.takerTokenFillAmounts, - params.v, - params.r, - params.s, - { from }, - ); - const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); - tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async batchFillOrKillOrdersAsync( - orders: SignedOrder[], - from: string, - opts: { takerTokenFillAmounts?: BigNumber[] } = {}, - ): Promise { - const params = formatters.createBatchFill(orders, opts.takerTokenFillAmounts); - const txHash = await this._exchange.batchFillOrKillOrders.sendTransactionAsync( - params.orderAddresses, - params.orderValues, - params.takerTokenFillAmounts, - params.v, - params.r, - params.s, - { from }, - ); - const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); - tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async marketFillOrdersAsync( - orders: SignedOrder[], - from: string, - opts: { takerTokenFillAmount: BigNumber }, - ): Promise { - const params = formatters.createMarketFillOrders(orders, opts.takerTokenFillAmount); - const txHash = await this._exchange.marketFillOrders.sendTransactionAsync( - params.orderAddresses, - params.orderValues, - params.takerTokenFillAmount, - params.v, - params.r, - params.s, - { from }, - ); - const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); - tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async batchCancelOrdersAsync( - orders: SignedOrder[], - from: string, - opts: { takerTokenCancelAmounts?: BigNumber[] } = {}, - ): Promise { - const params = formatters.createBatchCancel(orders, opts.takerTokenCancelAmounts); - const txHash = await this._exchange.batchCancelOrders.sendTransactionAsync( - params.orderAddresses, - params.orderValues, - params.takerTokenCancelAmounts, - { from }, - ); - const tx = await this._zeroEx.awaitTransactionMinedAsync(txHash); - tx.logs = _.filter(tx.logs, log => log.address === this._exchange.address); - _.each(tx.logs, log => wrapLogBigNumbers(log)); - return tx; - } - public async getOrderHashAsync(signedOrder: SignedOrder): Promise { - const params = signedOrderUtils.getOrderAddressesAndValues(signedOrder); - const orderHash = await this._exchange.getOrderHash.callAsync(params.orderAddresses, params.orderValues); - return orderHash; - } - public async isValidSignatureAsync(signedOrder: SignedOrder): Promise { - const isValidSignature = await this._exchange.isValidSignature.callAsync( - signedOrder.maker, - ZeroEx.getOrderHashHex(signedOrder), - signedOrder.ecSignature.v, - signedOrder.ecSignature.r, - signedOrder.ecSignature.s, - ); - return isValidSignature; - } - public async isRoundingErrorAsync( - numerator: BigNumber, - denominator: BigNumber, - target: BigNumber, - ): Promise { - const isRoundingError = await this._exchange.isRoundingError.callAsync(numerator, denominator, target); - return isRoundingError; - } - public async getPartialAmountAsync( - numerator: BigNumber, - denominator: BigNumber, - target: BigNumber, - ): Promise { - const partialAmount = new BigNumber( - await this._exchange.getPartialAmount.callAsync(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]); - } - } -} diff --git a/packages/contracts/util/formatters.ts b/packages/contracts/util/formatters.ts deleted file mode 100644 index 88e12a6b4..000000000 --- a/packages/contracts/util/formatters.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { SignedOrder } from '0x.js'; -import { BigNumber } from '@0xproject/utils'; -import * as _ from 'lodash'; - -import { BatchCancelOrders, BatchFillOrders, MarketFillOrders } from './types'; - -export const formatters = { - createBatchFill( - signedOrders: SignedOrder[], - takerTokenFillAmounts: BigNumber[] = [], - ) { - const batchFill: BatchFillOrders = { - orderAddresses: [], - orderValues: [], - takerTokenFillAmounts, - v: [], - r: [], - s: [], - }; - _.forEach(signedOrders, signedOrder => { - batchFill.orderAddresses.push([ - signedOrder.maker, - signedOrder.taker, - signedOrder.makerTokenAddress, - signedOrder.takerTokenAddress, - signedOrder.feeRecipient, - ]); - batchFill.orderValues.push([ - signedOrder.makerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.makerFee, - signedOrder.takerFee, - signedOrder.expirationUnixTimestampSec, - signedOrder.salt, - ]); - batchFill.v.push(signedOrder.ecSignature.v); - batchFill.r.push(signedOrder.ecSignature.r); - batchFill.s.push(signedOrder.ecSignature.s); - if (takerTokenFillAmounts.length < signedOrders.length) { - batchFill.takerTokenFillAmounts.push(signedOrder.takerTokenAmount); - } - }); - return batchFill; - }, - createMarketFillOrders( - signedOrders: SignedOrder[], - takerTokenFillAmount: BigNumber, - ) { - const marketFillOrders: MarketFillOrders = { - orderAddresses: [], - orderValues: [], - takerTokenFillAmount, - v: [], - r: [], - s: [], - }; - signedOrders.forEach(signedOrder => { - marketFillOrders.orderAddresses.push([ - signedOrder.maker, - signedOrder.taker, - signedOrder.makerTokenAddress, - signedOrder.takerTokenAddress, - signedOrder.feeRecipient, - ]); - marketFillOrders.orderValues.push([ - signedOrder.makerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.makerFee, - signedOrder.takerFee, - signedOrder.expirationUnixTimestampSec, - signedOrder.salt, - ]); - marketFillOrders.v.push(signedOrder.ecSignature.v); - marketFillOrders.r.push(signedOrder.ecSignature.r); - marketFillOrders.s.push(signedOrder.ecSignature.s); - }); - return marketFillOrders; - }, - createBatchCancel(signedOrders: SignedOrder[], takerTokenCancelAmounts: BigNumber[] = []) { - const batchCancel: BatchCancelOrders = { - orderAddresses: [], - orderValues: [], - takerTokenCancelAmounts, - }; - signedOrders.forEach(signedOrder => { - batchCancel.orderAddresses.push([ - signedOrder.maker, - signedOrder.taker, - signedOrder.makerTokenAddress, - signedOrder.takerTokenAddress, - signedOrder.feeRecipient, - ]); - batchCancel.orderValues.push([ - signedOrder.makerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.makerFee, - signedOrder.takerFee, - signedOrder.expirationUnixTimestampSec, - signedOrder.salt, - ]); - if (takerTokenCancelAmounts.length < signedOrders.length) { - batchCancel.takerTokenCancelAmounts.push(signedOrder.takerTokenAmount); - } - }); - return batchCancel; - }, -}; diff --git a/packages/contracts/util/multi_sig_wrapper.ts b/packages/contracts/util/multi_sig_wrapper.ts deleted file mode 100644 index 9f6dcec52..000000000 --- a/packages/contracts/util/multi_sig_wrapper.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { AbiDefinition, MethodAbi } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; -import ABI = require('ethereumjs-abi'); -import ethUtil = require('ethereumjs-util'); -import * as _ from 'lodash'; -import * as Web3 from 'web3'; - -import { MultiSigWalletContract } from '../src/contract_wrappers/generated/multi_sig_wallet'; - -import { TransactionDataParams } from './types'; - -export class MultiSigWrapper { - private _multiSig: MultiSigWalletContract; - public static encodeFnArgs(name: string, abi: AbiDefinition[], args: any[]) { - const abiEntity = _.find(abi, { name }) as 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(''); - } - constructor(multiSigContract: MultiSigWalletContract) { - this._multiSig = multiSigContract; - } - public async submitTransactionAsync( - destination: string, - from: string, - dataParams: TransactionDataParams, - value: BigNumber = new BigNumber(0), - ) { - const { name, abi, args = [] } = dataParams; - const encoded = MultiSigWrapper.encodeFnArgs(name, abi, args); - return this._multiSig.submitTransaction.sendTransactionAsync(destination, value, encoded, { - from, - }); - } -} diff --git a/packages/contracts/util/order_factory.ts b/packages/contracts/util/order_factory.ts deleted file mode 100644 index 8ba5df24a..000000000 --- a/packages/contracts/util/order_factory.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Order, SignedOrder, ZeroEx } from '0x.js'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; -import * as _ from 'lodash'; - -import { DefaultOrderParams } from './types'; - -export class OrderFactory { - private _defaultOrderParams: Partial; - private _zeroEx: ZeroEx; - constructor(zeroEx: ZeroEx, defaultOrderParams: Partial) { - this._defaultOrderParams = defaultOrderParams; - this._zeroEx = zeroEx; - } - public async newSignedOrderAsync(customOrderParams: Partial = {}): Promise { - const randomExpiration = new BigNumber(Math.floor((Date.now() + Math.random() * 100000000000) / 1000)); - 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 signedOrder = { - ...order, - ecSignature, - }; - return signedOrder; - } -} diff --git a/packages/contracts/util/token_registry_wrapper.ts b/packages/contracts/util/token_registry_wrapper.ts deleted file mode 100644 index d78c8a64e..000000000 --- a/packages/contracts/util/token_registry_wrapper.ts +++ /dev/null @@ -1,60 +0,0 @@ -import * as Web3 from 'web3'; - -import { TokenRegistryContract } from '../src/contract_wrappers/generated/token_registry'; - -import { Token } from './types'; - -export class TokenRegWrapper { - private _tokenReg: TokenRegistryContract; - constructor(tokenRegContract: TokenRegistryContract) { - this._tokenReg = tokenRegContract; - } - public async addTokenAsync(token: Token, from: string) { - const tx = this._tokenReg.addToken.sendTransactionAsync( - token.address as string, - token.name, - token.symbol, - token.decimals, - token.ipfsHash, - token.swarmHash, - { from }, - ); - return tx; - } - public async getTokenMetaDataAsync(tokenAddress: string) { - const data = await this._tokenReg.getTokenMetaData.callAsync(tokenAddress); - const token: Token = { - address: data[0], - name: data[1], - symbol: data[2], - decimals: data[3], - ipfsHash: data[4], - swarmHash: data[5], - }; - return token; - } - public async getTokenByNameAsync(tokenName: string) { - const data = await this._tokenReg.getTokenByName.callAsync(tokenName); - const token: Token = { - address: data[0], - name: data[1], - symbol: data[2], - decimals: data[3], - ipfsHash: data[4], - swarmHash: data[5], - }; - return token; - } - public async getTokenBySymbolAsync(tokenSymbol: string) { - const data = await this._tokenReg.getTokenBySymbol.callAsync(tokenSymbol); - const token: Token = { - address: data[0], - name: data[1], - symbol: data[2], - decimals: data[3], - ipfsHash: data[4], - swarmHash: data[5], - }; - return token; - } -} diff --git a/packages/contracts/util/types.ts b/packages/contracts/util/types.ts deleted file mode 100644 index 2ffc84f04..000000000 --- a/packages/contracts/util/types.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { AbiDefinition, ContractAbi } from '@0xproject/types'; -import { BigNumber } from '@0xproject/utils'; - -export interface BalancesByOwner { - [ownerAddress: string]: { - [tokenAddress: string]: BigNumber; - }; -} - -export interface SubmissionContractEventArgs { - transactionId: BigNumber; -} - -export interface BatchFillOrders { - orderAddresses: string[][]; - orderValues: BigNumber[][]; - takerTokenFillAmounts: BigNumber[]; - v: number[]; - r: string[]; - s: string[]; -} - -export interface MarketFillOrders { - orderAddresses: string[][]; - orderValues: BigNumber[][]; - takerTokenFillAmount: BigNumber; - v: number[]; - r: string[]; - s: string[]; -} - -export interface BatchCancelOrders { - orderAddresses: string[][]; - orderValues: BigNumber[][]; - takerTokenCancelAmounts: BigNumber[]; -} - -export interface DefaultOrderParams { - exchangeContractAddress: string; - maker: string; - feeRecipient: string; - makerTokenAddress: string; - takerTokenAddress: string; - makerTokenAmount: BigNumber; - takerTokenAmount: BigNumber; - makerFee: BigNumber; - takerFee: BigNumber; -} - -export interface TransactionDataParams { - name: string; - abi: AbiDefinition[]; - args: any[]; -} - -export interface MultiSigConfig { - owners: string[]; - confirmationsRequired: number; - secondsRequired: number; -} - -export interface MultiSigConfigByNetwork { - [networkName: string]: MultiSigConfig; -} - -export interface Token { - address?: string; - name: string; - symbol: string; - decimals: number; - ipfsHash: string; - swarmHash: string; -} - -export interface TokenInfoByNetwork { - development: Token[]; - live: Token[]; -} - -export enum ExchangeContractErrs { - ERROR_ORDER_EXPIRED, - ERROR_ORDER_FULLY_FILLED_OR_CANCELLED, - ERROR_ROUNDING_ERROR_TOO_LARGE, - ERROR_INSUFFICIENT_BALANCE_OR_ALLOWANCE, -} - -export enum ContractName { - TokenTransferProxy = 'TokenTransferProxy', - TokenRegistry = 'TokenRegistry', - MultiSigWalletWithTimeLock = 'MultiSigWalletWithTimeLock', - Exchange = 'Exchange', - ZRXToken = 'ZRXToken', - DummyToken = 'DummyToken', - EtherToken = 'WETH9', - MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = 'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', - MaliciousToken = 'MaliciousToken', - AccountLevels = 'AccountLevels', - EtherDelta = 'EtherDelta', - Arbitrage = 'Arbitrage', -} - -export interface Artifact { - contract_name: ContractName; - networks: { - [networkId: number]: { - abi: ContractAbi; - solc_version: string; - keccak256: string; - optimizer_enabled: number; - unlinked_binary: string; - updated_at: number; - address: string; - constructor_args: string; - }; - }; -} -- cgit v1.2.3