From ba987b0574211f67a734a21fc885e446a03cad63 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 18 Jan 2018 15:17:17 +0100 Subject: Move tests to a separate folder --- packages/contracts/package.json | 4 +- packages/deployer/package.json | 12 +- packages/deployer/src/test/deploy_test.ts | 91 ---- .../src/test/fixtures/contracts/Exchange.sol | 602 --------------------- .../test/fixtures/contracts/TokenTransferProxy.sol | 115 ---- .../src/test/fixtures/contracts/base/Ownable.sol | 27 - .../src/test/fixtures/contracts/base/SafeMath.sol | 41 -- .../src/test/fixtures/contracts/base/Token.sol | 38 -- .../deployer/src/test/fixtures/exchange_bin.ts | 4 - packages/deployer/src/test/util/constants.ts | 11 - packages/deployer/test/deploy_test.ts | 91 ++++ .../deployer/test/fixtures/contracts/Exchange.sol | 602 +++++++++++++++++++++ .../test/fixtures/contracts/TokenTransferProxy.sol | 115 ++++ .../test/fixtures/contracts/base/Ownable.sol | 27 + .../test/fixtures/contracts/base/SafeMath.sol | 41 ++ .../test/fixtures/contracts/base/Token.sol | 38 ++ packages/deployer/test/fixtures/exchange_bin.ts | 4 + packages/deployer/test/util/constants.ts | 11 + packages/deployer/tsconfig.json | 1 + 19 files changed, 938 insertions(+), 937 deletions(-) delete mode 100644 packages/deployer/src/test/deploy_test.ts delete mode 100644 packages/deployer/src/test/fixtures/contracts/Exchange.sol delete mode 100644 packages/deployer/src/test/fixtures/contracts/TokenTransferProxy.sol delete mode 100644 packages/deployer/src/test/fixtures/contracts/base/Ownable.sol delete mode 100644 packages/deployer/src/test/fixtures/contracts/base/SafeMath.sol delete mode 100644 packages/deployer/src/test/fixtures/contracts/base/Token.sol delete mode 100644 packages/deployer/src/test/fixtures/exchange_bin.ts delete mode 100644 packages/deployer/src/test/util/constants.ts create mode 100644 packages/deployer/test/deploy_test.ts create mode 100644 packages/deployer/test/fixtures/contracts/Exchange.sol create mode 100644 packages/deployer/test/fixtures/contracts/TokenTransferProxy.sol create mode 100644 packages/deployer/test/fixtures/contracts/base/Ownable.sol create mode 100644 packages/deployer/test/fixtures/contracts/base/SafeMath.sol create mode 100644 packages/deployer/test/fixtures/contracts/base/Token.sol create mode 100644 packages/deployer/test/fixtures/exchange_bin.ts create mode 100644 packages/deployer/test/util/constants.ts diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 0f70ab308..4040c0d39 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -11,9 +11,9 @@ "build": "rm -rf ./lib; copyfiles ./build/**/* ./deploy/solc/solc_bin/* ./deploy/test/fixtures/contracts/**/* ./deploy/test/fixtures/contracts/* ./lib; tsc;", "test": "npm run build; truffle test", - "compile": "node ../deployer/lib/cli.js compile", + "compile": "node ../deployer/lib/src/cli.js compile", "clean": "rm -rf ./lib", - "migrate": "node ../deployer/lib/cli.js migrate", + "migrate": "node ../deployer/lib/src/cli.js migrate", "lint": "tslint --project . 'migrations/**/*.ts' 'test/**/*.ts' 'util/**/*.ts' 'deploy/**/*.ts'", "test:circleci": "yarn test" }, diff --git a/packages/deployer/package.json b/packages/deployer/package.json index d664b050c..b359382c5 100644 --- a/packages/deployer/package.json +++ b/packages/deployer/package.json @@ -2,18 +2,18 @@ "name": "@0xproject/deployer", "version": "0.0.1", "description": "Smart contract deployer of 0x protocol", - "main": "lib/cli.js", + "main": "lib/src/cli.js", "scripts": { - "build": "yarn clean && copyfiles -u 1 'src/test/fixtures/contracts/**/*' src/solc/solc_bin/* ./lib && tsc", + "build": "yarn clean && copyfiles 'test/fixtures/contracts/**/*' src/solc/solc_bin/* ./lib && tsc", "test": "npm run build; mocha lib/test/*_test.js", - "compile": "npm run build; node lib/cli.js compile", + "compile": "npm run build; node lib/src/cli.js compile", "clean": "rm -rf ./lib", - "migrate": "npm run build; node lib/cli.js migrate", - "lint": "tslint --project . 'src/**/*.ts'", + "migrate": "npm run build; node lib/src/cli.js migrate", + "lint": "tslint --project . 'src/**/*.ts' 'test/**/*.ts'", "test:circleci": "yarn test" }, "bin": { - "0x-deployer": "lib/cli.js" + "0x-deployer": "lib/src/cli.js" }, "repository": { "type": "git", diff --git a/packages/deployer/src/test/deploy_test.ts b/packages/deployer/src/test/deploy_test.ts deleted file mode 100644 index e15985e11..000000000 --- a/packages/deployer/src/test/deploy_test.ts +++ /dev/null @@ -1,91 +0,0 @@ -import * as chai from 'chai'; -import 'mocha'; - -import { Compiler } from '../compiler'; -import { Deployer } from '../deployer'; -import { fsWrapper } from '../utils/fs_wrapper'; -import { CompilerOptions, ContractArtifact, ContractData, DoneCallback } from '../utils/types'; -import { constructor_args, exchange_binary } from './fixtures/exchange_bin'; -import { constants } from './util/constants'; - -const expect = chai.expect; -const artifactsDir = `${__dirname}/fixtures/artifacts`; -const contractsDir = `${__dirname}/fixtures/contracts`; -const exchangeArtifactPath = `${artifactsDir}/Exchange.json`; -const compilerOpts: CompilerOptions = { - artifactsDir, - contractsDir, - networkId: constants.networkId, - optimizerEnabled: constants.optimizerEnabled, -}; -const compiler = new Compiler(compilerOpts); -const deployerOpts = { - artifactsDir, - networkId: constants.networkId, - jsonrpcPort: constants.jsonrpcPort, - defaults: { - gasPrice: constants.gasPrice, - }, -}; -const deployer = new Deployer(deployerOpts); - -/* tslint:disable */ -beforeEach(function(done: DoneCallback) { - this.timeout(constants.timeoutMs); - (async () => { - if (fsWrapper.doesPathExistSync(exchangeArtifactPath)) { - await fsWrapper.removeFileAsync(exchangeArtifactPath); - } - await compiler.compileAllAsync(); - done(); - })().catch(done); -}); -/* tslint:enable */ - -describe('#Compiler', () => { - it('should create an Exchange artifact with the correct unlinked binary', async () => { - const opts = { - encoding: 'utf8', - }; - const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts); - const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString); - const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId]; - // The last 43 bytes of the binaries are metadata which may not be equivalent - const unlinkedBinaryWithoutMetadata = exchangeContractData.unlinked_binary.slice(0, -86); - const exchangeBinaryWithoutMetadata = exchange_binary.slice(0, -86); - expect(unlinkedBinaryWithoutMetadata).to.equal(exchangeBinaryWithoutMetadata); - }); -}); -describe('#Deployer', () => { - describe('#deployAsync', () => { - it('should deploy the Exchange contract without updating the Exchange artifact', async () => { - const exchangeConstructorArgs = [constants.zrxTokenAddress, constants.tokenTransferProxyAddress]; - const exchangeContractInstance = await deployer.deployAsync('Exchange', exchangeConstructorArgs); - const opts = { - encoding: 'utf8', - }; - const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts); - const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString); - const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId]; - const exchangeAddress = exchangeContractInstance.address; - expect(exchangeAddress).to.not.equal(undefined); - expect(exchangeContractData.address).to.equal(undefined); - expect(exchangeContractData.constructor_args).to.equal(undefined); - }); - }); - describe('#deployAndSaveAsync', () => { - it('should save the correct contract address and constructor arguments to the Exchange artifact', async () => { - const exchangeConstructorArgs = [constants.zrxTokenAddress, constants.tokenTransferProxyAddress]; - const exchangeContractInstance = await deployer.deployAndSaveAsync('Exchange', exchangeConstructorArgs); - const opts = { - encoding: 'utf8', - }; - const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts); - const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString); - const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId]; - const exchangeAddress = exchangeContractInstance.address; - expect(exchangeAddress).to.be.equal(exchangeContractData.address); - expect(constructor_args).to.be.equal(exchangeContractData.constructor_args); - }); - }); -}); diff --git a/packages/deployer/src/test/fixtures/contracts/Exchange.sol b/packages/deployer/src/test/fixtures/contracts/Exchange.sol deleted file mode 100644 index 1b6819700..000000000 --- a/packages/deployer/src/test/fixtures/contracts/Exchange.sol +++ /dev/null @@ -1,602 +0,0 @@ -/* - - Copyright 2017 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity 0.4.14; - -import "./TokenTransferProxy.sol"; -import "./base/Token.sol"; -import "./base/SafeMath.sol"; - -/// @title Exchange - Facilitates exchange of ERC20 tokens. -/// @author Amir Bandeali - , Will Warren - -contract Exchange is SafeMath { - - // Error Codes - enum Errors { - ORDER_EXPIRED, // Order has already expired - ORDER_FULLY_FILLED_OR_CANCELLED, // Order has already been fully filled or cancelled - ROUNDING_ERROR_TOO_LARGE, // Rounding error too large - INSUFFICIENT_BALANCE_OR_ALLOWANCE // Insufficient balance or allowance for token transfer - } - - string constant public VERSION = "1.0.0"; - uint16 constant public EXTERNAL_QUERY_GAS_LIMIT = 4999; // Changes to state require at least 5000 gas - - address public ZRX_TOKEN_CONTRACT; - address public TOKEN_TRANSFER_PROXY_CONTRACT; - - // Mappings of orderHash => amounts of takerTokenAmount filled or cancelled. - mapping (bytes32 => uint) public filled; - mapping (bytes32 => uint) public cancelled; - - event LogFill( - address indexed maker, - address taker, - address indexed feeRecipient, - address makerToken, - address takerToken, - uint filledMakerTokenAmount, - uint filledTakerTokenAmount, - uint paidMakerFee, - uint paidTakerFee, - bytes32 indexed tokens, // keccak256(makerToken, takerToken), allows subscribing to a token pair - bytes32 orderHash - ); - - event LogCancel( - address indexed maker, - address indexed feeRecipient, - address makerToken, - address takerToken, - uint cancelledMakerTokenAmount, - uint cancelledTakerTokenAmount, - bytes32 indexed tokens, - bytes32 orderHash - ); - - event LogError(uint8 indexed errorId, bytes32 indexed orderHash); - - struct Order { - address maker; - address taker; - address makerToken; - address takerToken; - address feeRecipient; - uint makerTokenAmount; - uint takerTokenAmount; - uint makerFee; - uint takerFee; - uint expirationTimestampInSec; - bytes32 orderHash; - } - - function Exchange(address _zrxToken, address _tokenTransferProxy) { - ZRX_TOKEN_CONTRACT = _zrxToken; - TOKEN_TRANSFER_PROXY_CONTRACT = _tokenTransferProxy; - } - - /* - * Core exchange functions - */ - - /// @dev Fills the input order. - /// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient. - /// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt. - /// @param fillTakerTokenAmount Desired amount of takerToken to fill. - /// @param shouldThrowOnInsufficientBalanceOrAllowance Test if transfer will fail before attempting. - /// @param v ECDSA signature parameter v. - /// @param r ECDSA signature parameters r. - /// @param s ECDSA signature parameters s. - /// @return Total amount of takerToken filled in trade. - function fillOrder( - address[5] orderAddresses, - uint[6] orderValues, - uint fillTakerTokenAmount, - bool shouldThrowOnInsufficientBalanceOrAllowance, - uint8 v, - bytes32 r, - bytes32 s) - public - returns (uint filledTakerTokenAmount) - { - Order memory order = Order({ - maker: orderAddresses[0], - taker: orderAddresses[1], - makerToken: orderAddresses[2], - takerToken: orderAddresses[3], - feeRecipient: orderAddresses[4], - makerTokenAmount: orderValues[0], - takerTokenAmount: orderValues[1], - makerFee: orderValues[2], - takerFee: orderValues[3], - expirationTimestampInSec: orderValues[4], - orderHash: getOrderHash(orderAddresses, orderValues) - }); - - require(order.taker == address(0) || order.taker == msg.sender); - require(order.makerTokenAmount > 0 && order.takerTokenAmount > 0 && fillTakerTokenAmount > 0); - require(isValidSignature( - order.maker, - order.orderHash, - v, - r, - s - )); - - if (block.timestamp >= order.expirationTimestampInSec) { - LogError(uint8(Errors.ORDER_EXPIRED), order.orderHash); - return 0; - } - - uint remainingTakerTokenAmount = safeSub(order.takerTokenAmount, getUnavailableTakerTokenAmount(order.orderHash)); - filledTakerTokenAmount = min256(fillTakerTokenAmount, remainingTakerTokenAmount); - if (filledTakerTokenAmount == 0) { - LogError(uint8(Errors.ORDER_FULLY_FILLED_OR_CANCELLED), order.orderHash); - return 0; - } - - if (isRoundingError(filledTakerTokenAmount, order.takerTokenAmount, order.makerTokenAmount)) { - LogError(uint8(Errors.ROUNDING_ERROR_TOO_LARGE), order.orderHash); - return 0; - } - - if (!shouldThrowOnInsufficientBalanceOrAllowance && !isTransferable(order, filledTakerTokenAmount)) { - LogError(uint8(Errors.INSUFFICIENT_BALANCE_OR_ALLOWANCE), order.orderHash); - return 0; - } - - uint filledMakerTokenAmount = getPartialAmount(filledTakerTokenAmount, order.takerTokenAmount, order.makerTokenAmount); - uint paidMakerFee; - uint paidTakerFee; - filled[order.orderHash] = safeAdd(filled[order.orderHash], filledTakerTokenAmount); - require(transferViaTokenTransferProxy( - order.makerToken, - order.maker, - msg.sender, - filledMakerTokenAmount - )); - require(transferViaTokenTransferProxy( - order.takerToken, - msg.sender, - order.maker, - filledTakerTokenAmount - )); - if (order.feeRecipient != address(0)) { - if (order.makerFee > 0) { - paidMakerFee = getPartialAmount(filledTakerTokenAmount, order.takerTokenAmount, order.makerFee); - require(transferViaTokenTransferProxy( - ZRX_TOKEN_CONTRACT, - order.maker, - order.feeRecipient, - paidMakerFee - )); - } - if (order.takerFee > 0) { - paidTakerFee = getPartialAmount(filledTakerTokenAmount, order.takerTokenAmount, order.takerFee); - require(transferViaTokenTransferProxy( - ZRX_TOKEN_CONTRACT, - msg.sender, - order.feeRecipient, - paidTakerFee - )); - } - } - - LogFill( - order.maker, - msg.sender, - order.feeRecipient, - order.makerToken, - order.takerToken, - filledMakerTokenAmount, - filledTakerTokenAmount, - paidMakerFee, - paidTakerFee, - keccak256(order.makerToken, order.takerToken), - order.orderHash - ); - return filledTakerTokenAmount; - } - - /// @dev Cancels the input order. - /// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient. - /// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt. - /// @param cancelTakerTokenAmount Desired amount of takerToken to cancel in order. - /// @return Amount of takerToken cancelled. - function cancelOrder( - address[5] orderAddresses, - uint[6] orderValues, - uint cancelTakerTokenAmount) - public - returns (uint) - { - Order memory order = Order({ - maker: orderAddresses[0], - taker: orderAddresses[1], - makerToken: orderAddresses[2], - takerToken: orderAddresses[3], - feeRecipient: orderAddresses[4], - makerTokenAmount: orderValues[0], - takerTokenAmount: orderValues[1], - makerFee: orderValues[2], - takerFee: orderValues[3], - expirationTimestampInSec: orderValues[4], - orderHash: getOrderHash(orderAddresses, orderValues) - }); - - require(order.maker == msg.sender); - require(order.makerTokenAmount > 0 && order.takerTokenAmount > 0 && cancelTakerTokenAmount > 0); - - if (block.timestamp >= order.expirationTimestampInSec) { - LogError(uint8(Errors.ORDER_EXPIRED), order.orderHash); - return 0; - } - - uint remainingTakerTokenAmount = safeSub(order.takerTokenAmount, getUnavailableTakerTokenAmount(order.orderHash)); - uint cancelledTakerTokenAmount = min256(cancelTakerTokenAmount, remainingTakerTokenAmount); - if (cancelledTakerTokenAmount == 0) { - LogError(uint8(Errors.ORDER_FULLY_FILLED_OR_CANCELLED), order.orderHash); - return 0; - } - - cancelled[order.orderHash] = safeAdd(cancelled[order.orderHash], cancelledTakerTokenAmount); - - LogCancel( - order.maker, - order.feeRecipient, - order.makerToken, - order.takerToken, - getPartialAmount(cancelledTakerTokenAmount, order.takerTokenAmount, order.makerTokenAmount), - cancelledTakerTokenAmount, - keccak256(order.makerToken, order.takerToken), - order.orderHash - ); - return cancelledTakerTokenAmount; - } - - /* - * Wrapper functions - */ - - /// @dev Fills an order with specified parameters and ECDSA signature, throws if specified amount not filled entirely. - /// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient. - /// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt. - /// @param fillTakerTokenAmount Desired amount of takerToken to fill. - /// @param v ECDSA signature parameter v. - /// @param r ECDSA signature parameters r. - /// @param s ECDSA signature parameters s. - function fillOrKillOrder( - address[5] orderAddresses, - uint[6] orderValues, - uint fillTakerTokenAmount, - uint8 v, - bytes32 r, - bytes32 s) - public - { - require(fillOrder( - orderAddresses, - orderValues, - fillTakerTokenAmount, - false, - v, - r, - s - ) == fillTakerTokenAmount); - } - - /// @dev Synchronously executes multiple fill orders in a single transaction. - /// @param orderAddresses Array of address arrays containing individual order addresses. - /// @param orderValues Array of uint arrays containing individual order values. - /// @param fillTakerTokenAmounts Array of desired amounts of takerToken to fill in orders. - /// @param shouldThrowOnInsufficientBalanceOrAllowance Test if transfers will fail before attempting. - /// @param v Array ECDSA signature v parameters. - /// @param r Array of ECDSA signature r parameters. - /// @param s Array of ECDSA signature s parameters. - function batchFillOrders( - address[5][] orderAddresses, - uint[6][] orderValues, - uint[] fillTakerTokenAmounts, - bool shouldThrowOnInsufficientBalanceOrAllowance, - uint8[] v, - bytes32[] r, - bytes32[] s) - public - { - for (uint i = 0; i < orderAddresses.length; i++) { - fillOrder( - orderAddresses[i], - orderValues[i], - fillTakerTokenAmounts[i], - shouldThrowOnInsufficientBalanceOrAllowance, - v[i], - r[i], - s[i] - ); - } - } - - /// @dev Synchronously executes multiple fillOrKill orders in a single transaction. - /// @param orderAddresses Array of address arrays containing individual order addresses. - /// @param orderValues Array of uint arrays containing individual order values. - /// @param fillTakerTokenAmounts Array of desired amounts of takerToken to fill in orders. - /// @param v Array ECDSA signature v parameters. - /// @param r Array of ECDSA signature r parameters. - /// @param s Array of ECDSA signature s parameters. - function batchFillOrKillOrders( - address[5][] orderAddresses, - uint[6][] orderValues, - uint[] fillTakerTokenAmounts, - uint8[] v, - bytes32[] r, - bytes32[] s) - public - { - for (uint i = 0; i < orderAddresses.length; i++) { - fillOrKillOrder( - orderAddresses[i], - orderValues[i], - fillTakerTokenAmounts[i], - v[i], - r[i], - s[i] - ); - } - } - - /// @dev Synchronously executes multiple fill orders in a single transaction until total fillTakerTokenAmount filled. - /// @param orderAddresses Array of address arrays containing individual order addresses. - /// @param orderValues Array of uint arrays containing individual order values. - /// @param fillTakerTokenAmount Desired total amount of takerToken to fill in orders. - /// @param shouldThrowOnInsufficientBalanceOrAllowance Test if transfers will fail before attempting. - /// @param v Array ECDSA signature v parameters. - /// @param r Array of ECDSA signature r parameters. - /// @param s Array of ECDSA signature s parameters. - /// @return Total amount of fillTakerTokenAmount filled in orders. - function fillOrdersUpTo( - address[5][] orderAddresses, - uint[6][] orderValues, - uint fillTakerTokenAmount, - bool shouldThrowOnInsufficientBalanceOrAllowance, - uint8[] v, - bytes32[] r, - bytes32[] s) - public - returns (uint) - { - uint filledTakerTokenAmount = 0; - for (uint i = 0; i < orderAddresses.length; i++) { - require(orderAddresses[i][3] == orderAddresses[0][3]); // takerToken must be the same for each order - filledTakerTokenAmount = safeAdd(filledTakerTokenAmount, fillOrder( - orderAddresses[i], - orderValues[i], - safeSub(fillTakerTokenAmount, filledTakerTokenAmount), - shouldThrowOnInsufficientBalanceOrAllowance, - v[i], - r[i], - s[i] - )); - if (filledTakerTokenAmount == fillTakerTokenAmount) break; - } - return filledTakerTokenAmount; - } - - /// @dev Synchronously cancels multiple orders in a single transaction. - /// @param orderAddresses Array of address arrays containing individual order addresses. - /// @param orderValues Array of uint arrays containing individual order values. - /// @param cancelTakerTokenAmounts Array of desired amounts of takerToken to cancel in orders. - function batchCancelOrders( - address[5][] orderAddresses, - uint[6][] orderValues, - uint[] cancelTakerTokenAmounts) - public - { - for (uint i = 0; i < orderAddresses.length; i++) { - cancelOrder( - orderAddresses[i], - orderValues[i], - cancelTakerTokenAmounts[i] - ); - } - } - - /* - * Constant public functions - */ - - /// @dev Calculates Keccak-256 hash of order with specified parameters. - /// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient. - /// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt. - /// @return Keccak-256 hash of order. - function getOrderHash(address[5] orderAddresses, uint[6] orderValues) - public - constant - returns (bytes32) - { - return keccak256( - address(this), - orderAddresses[0], // maker - orderAddresses[1], // taker - orderAddresses[2], // makerToken - orderAddresses[3], // takerToken - orderAddresses[4], // feeRecipient - orderValues[0], // makerTokenAmount - orderValues[1], // takerTokenAmount - orderValues[2], // makerFee - orderValues[3], // takerFee - orderValues[4], // expirationTimestampInSec - orderValues[5] // salt - ); - } - - /// @dev Verifies that an order signature is valid. - /// @param signer address of signer. - /// @param hash Signed Keccak-256 hash. - /// @param v ECDSA signature parameter v. - /// @param r ECDSA signature parameters r. - /// @param s ECDSA signature parameters s. - /// @return Validity of order signature. - function isValidSignature( - address signer, - bytes32 hash, - uint8 v, - bytes32 r, - bytes32 s) - public - constant - returns (bool) - { - return signer == ecrecover( - keccak256("\x19Ethereum Signed Message:\n32", hash), - v, - r, - s - ); - } - - /// @dev Checks if rounding error > 0.1%. - /// @param numerator Numerator. - /// @param denominator Denominator. - /// @param target Value to multiply with numerator/denominator. - /// @return Rounding error is present. - function isRoundingError(uint numerator, uint denominator, uint target) - public - constant - returns (bool) - { - uint remainder = mulmod(target, numerator, denominator); - if (remainder == 0) return false; // No rounding error. - - uint errPercentageTimes1000000 = safeDiv( - safeMul(remainder, 1000000), - safeMul(numerator, target) - ); - return errPercentageTimes1000000 > 1000; - } - - /// @dev Calculates partial value given a numerator and denominator. - /// @param numerator Numerator. - /// @param denominator Denominator. - /// @param target Value to calculate partial of. - /// @return Partial value of target. - function getPartialAmount(uint numerator, uint denominator, uint target) - public - constant - returns (uint) - { - return safeDiv(safeMul(numerator, target), denominator); - } - - /// @dev Calculates the sum of values already filled and cancelled for a given order. - /// @param orderHash The Keccak-256 hash of the given order. - /// @return Sum of values already filled and cancelled. - function getUnavailableTakerTokenAmount(bytes32 orderHash) - public - constant - returns (uint) - { - return safeAdd(filled[orderHash], cancelled[orderHash]); - } - - - /* - * Internal functions - */ - - /// @dev Transfers a token using TokenTransferProxy transferFrom function. - /// @param token Address of token to transferFrom. - /// @param from Address transfering token. - /// @param to Address receiving token. - /// @param value Amount of token to transfer. - /// @return Success of token transfer. - function transferViaTokenTransferProxy( - address token, - address from, - address to, - uint value) - internal - returns (bool) - { - return TokenTransferProxy(TOKEN_TRANSFER_PROXY_CONTRACT).transferFrom(token, from, to, value); - } - - /// @dev Checks if any order transfers will fail. - /// @param order Order struct of params that will be checked. - /// @param fillTakerTokenAmount Desired amount of takerToken to fill. - /// @return Predicted result of transfers. - function isTransferable(Order order, uint fillTakerTokenAmount) - internal - constant // The called token contracts may attempt to change state, but will not be able to due to gas limits on getBalance and getAllowance. - returns (bool) - { - address taker = msg.sender; - uint fillMakerTokenAmount = getPartialAmount(fillTakerTokenAmount, order.takerTokenAmount, order.makerTokenAmount); - - if (order.feeRecipient != address(0)) { - bool isMakerTokenZRX = order.makerToken == ZRX_TOKEN_CONTRACT; - bool isTakerTokenZRX = order.takerToken == ZRX_TOKEN_CONTRACT; - uint paidMakerFee = getPartialAmount(fillTakerTokenAmount, order.takerTokenAmount, order.makerFee); - uint paidTakerFee = getPartialAmount(fillTakerTokenAmount, order.takerTokenAmount, order.takerFee); - uint requiredMakerZRX = isMakerTokenZRX ? safeAdd(fillMakerTokenAmount, paidMakerFee) : paidMakerFee; - uint requiredTakerZRX = isTakerTokenZRX ? safeAdd(fillTakerTokenAmount, paidTakerFee) : paidTakerFee; - - if ( getBalance(ZRX_TOKEN_CONTRACT, order.maker) < requiredMakerZRX - || getAllowance(ZRX_TOKEN_CONTRACT, order.maker) < requiredMakerZRX - || getBalance(ZRX_TOKEN_CONTRACT, taker) < requiredTakerZRX - || getAllowance(ZRX_TOKEN_CONTRACT, taker) < requiredTakerZRX - ) return false; - - if (!isMakerTokenZRX && ( getBalance(order.makerToken, order.maker) < fillMakerTokenAmount // Don't double check makerToken if ZRX - || getAllowance(order.makerToken, order.maker) < fillMakerTokenAmount) - ) return false; - if (!isTakerTokenZRX && ( getBalance(order.takerToken, taker) < fillTakerTokenAmount // Don't double check takerToken if ZRX - || getAllowance(order.takerToken, taker) < fillTakerTokenAmount) - ) return false; - } else if ( getBalance(order.makerToken, order.maker) < fillMakerTokenAmount - || getAllowance(order.makerToken, order.maker) < fillMakerTokenAmount - || getBalance(order.takerToken, taker) < fillTakerTokenAmount - || getAllowance(order.takerToken, taker) < fillTakerTokenAmount - ) return false; - - return true; - } - - /// @dev Get token balance of an address. - /// @param token Address of token. - /// @param owner Address of owner. - /// @return Token balance of owner. - function getBalance(address token, address owner) - internal - constant // The called token contract may attempt to change state, but will not be able to due to an added gas limit. - returns (uint) - { - return Token(token).balanceOf.gas(EXTERNAL_QUERY_GAS_LIMIT)(owner); // Limit gas to prevent reentrancy - } - - /// @dev Get allowance of token given to TokenTransferProxy by an address. - /// @param token Address of token. - /// @param owner Address of owner. - /// @return Allowance of token given to TokenTransferProxy by owner. - function getAllowance(address token, address owner) - internal - constant // The called token contract may attempt to change state, but will not be able to due to an added gas limit. - returns (uint) - { - return Token(token).allowance.gas(EXTERNAL_QUERY_GAS_LIMIT)(owner, TOKEN_TRANSFER_PROXY_CONTRACT); // Limit gas to prevent reentrancy - } -} diff --git a/packages/deployer/src/test/fixtures/contracts/TokenTransferProxy.sol b/packages/deployer/src/test/fixtures/contracts/TokenTransferProxy.sol deleted file mode 100644 index 90c8e7d66..000000000 --- a/packages/deployer/src/test/fixtures/contracts/TokenTransferProxy.sol +++ /dev/null @@ -1,115 +0,0 @@ -/* - - Copyright 2017 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -pragma solidity 0.4.14; - -import "./base/Token.sol"; -import "./base/Ownable.sol"; - -/// @title TokenTransferProxy - Transfers tokens on behalf of contracts that have been approved via decentralized governance. -/// @author Amir Bandeali - , Will Warren - -contract TokenTransferProxy is Ownable { - - /// @dev Only authorized addresses can invoke functions with this modifier. - modifier onlyAuthorized { - require(authorized[msg.sender]); - _; - } - - modifier targetAuthorized(address target) { - require(authorized[target]); - _; - } - - modifier targetNotAuthorized(address target) { - require(!authorized[target]); - _; - } - - mapping (address => bool) public authorized; - address[] public authorities; - - event LogAuthorizedAddressAdded(address indexed target, address indexed caller); - event LogAuthorizedAddressRemoved(address indexed target, address indexed caller); - - /* - * Public functions - */ - - /// @dev Authorizes an address. - /// @param target Address to authorize. - function addAuthorizedAddress(address target) - public - onlyOwner - targetNotAuthorized(target) - { - authorized[target] = true; - authorities.push(target); - LogAuthorizedAddressAdded(target, msg.sender); - } - - /// @dev Removes authorizion of an address. - /// @param target Address to remove authorization from. - function removeAuthorizedAddress(address target) - public - onlyOwner - targetAuthorized(target) - { - delete authorized[target]; - for (uint i = 0; i < authorities.length; i++) { - if (authorities[i] == target) { - authorities[i] = authorities[authorities.length - 1]; - authorities.length -= 1; - break; - } - } - LogAuthorizedAddressRemoved(target, msg.sender); - } - - /// @dev Calls into ERC20 Token contract, invoking transferFrom. - /// @param token Address of token to transfer. - /// @param from Address to transfer token from. - /// @param to Address to transfer token to. - /// @param value Amount of token to transfer. - /// @return Success of transfer. - function transferFrom( - address token, - address from, - address to, - uint value) - public - onlyAuthorized - returns (bool) - { - return Token(token).transferFrom(from, to, value); - } - - /* - * Public constant functions - */ - - /// @dev Gets all authorized addresses. - /// @return Array of authorized addresses. - function getAuthorizedAddresses() - public - constant - returns (address[]) - { - return authorities; - } -} diff --git a/packages/deployer/src/test/fixtures/contracts/base/Ownable.sol b/packages/deployer/src/test/fixtures/contracts/base/Ownable.sol deleted file mode 100644 index 2a74c3717..000000000 --- a/packages/deployer/src/test/fixtures/contracts/base/Ownable.sol +++ /dev/null @@ -1,27 +0,0 @@ -pragma solidity 0.4.14; - -/* - * Ownable - * - * Base contract with an owner. - * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner. - */ - -contract Ownable { - address public owner; - - function Ownable() { - owner = msg.sender; - } - - modifier onlyOwner() { - require(msg.sender == owner); - _; - } - - function transferOwnership(address newOwner) onlyOwner { - if (newOwner != address(0)) { - owner = newOwner; - } - } -} diff --git a/packages/deployer/src/test/fixtures/contracts/base/SafeMath.sol b/packages/deployer/src/test/fixtures/contracts/base/SafeMath.sol deleted file mode 100644 index 7414684a8..000000000 --- a/packages/deployer/src/test/fixtures/contracts/base/SafeMath.sol +++ /dev/null @@ -1,41 +0,0 @@ -pragma solidity 0.4.14; - -contract SafeMath { - function safeMul(uint a, uint b) internal constant returns (uint256) { - uint c = a * b; - assert(a == 0 || c / a == b); - return c; - } - - function safeDiv(uint a, uint b) internal constant returns (uint256) { - uint c = a / b; - return c; - } - - function safeSub(uint a, uint b) internal constant returns (uint256) { - assert(b <= a); - return a - b; - } - - function safeAdd(uint a, uint b) internal constant returns (uint256) { - uint c = a + b; - assert(c >= a); - return c; - } - - function max64(uint64 a, uint64 b) internal constant returns (uint64) { - return a >= b ? a : b; - } - - function min64(uint64 a, uint64 b) internal constant returns (uint64) { - return a < b ? a : b; - } - - function max256(uint256 a, uint256 b) internal constant returns (uint256) { - return a >= b ? a : b; - } - - function min256(uint256 a, uint256 b) internal constant returns (uint256) { - return a < b ? a : b; - } -} diff --git a/packages/deployer/src/test/fixtures/contracts/base/Token.sol b/packages/deployer/src/test/fixtures/contracts/base/Token.sol deleted file mode 100644 index c03f8c567..000000000 --- a/packages/deployer/src/test/fixtures/contracts/base/Token.sol +++ /dev/null @@ -1,38 +0,0 @@ -pragma solidity 0.4.14; - -contract Token { - - /// @return total amount of tokens - function totalSupply() constant returns (uint supply) {} - - /// @param _owner The address from which the balance will be retrieved - /// @return The balance - function balanceOf(address _owner) constant returns (uint balance) {} - - /// @notice send `_value` token to `_to` from `msg.sender` - /// @param _to The address of the recipient - /// @param _value The amount of token to be transferred - /// @return Whether the transfer was successful or not - function transfer(address _to, uint _value) returns (bool success) {} - - /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from` - /// @param _from The address of the sender - /// @param _to The address of the recipient - /// @param _value The amount of token to be transferred - /// @return Whether the transfer was successful or not - function transferFrom(address _from, address _to, uint _value) returns (bool success) {} - - /// @notice `msg.sender` approves `_addr` to spend `_value` tokens - /// @param _spender The address of the account able to transfer the tokens - /// @param _value The amount of wei to be approved for transfer - /// @return Whether the approval was successful or not - function approve(address _spender, uint _value) returns (bool success) {} - - /// @param _owner The address of the account owning tokens - /// @param _spender The address of the account able to transfer the tokens - /// @return Amount of remaining tokens allowed to spent - function allowance(address _owner, address _spender) constant returns (uint remaining) {} - - event Transfer(address indexed _from, address indexed _to, uint _value); - event Approval(address indexed _owner, address indexed _spender, uint _value); -} diff --git a/packages/deployer/src/test/fixtures/exchange_bin.ts b/packages/deployer/src/test/fixtures/exchange_bin.ts deleted file mode 100644 index a6eae515e..000000000 --- a/packages/deployer/src/test/fixtures/exchange_bin.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const constructor_args = - '0x000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000008da0d80f5007ef1e431dd2127178d224e32c2ef4'; -export const exchange_binary = - '0x6060604052341561000f57600080fd5b604051604080612c4d833981016040528080519060200190919080519060200190919050505b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50505b612b84806100c96000396000f300606060405236156100fa576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806314df96ee146100ff578063288cdc911461014c5780632ac1262214610187578063363349be146101c2578063394c21e7146103bc5780633b30ba591461044b5780634f150787146104a0578063741bcc93146106b25780637e9abb50146107535780638163681e1461078e57806398024a8b14610812578063add1cbc51461085b578063b7b2c7d6146108b0578063baa0181d14610acd578063bc61394a14610c1f578063cfc4d0ec14610cdf578063f06bbf7514610d6d578063ffa1ad7414610d9e575b600080fd5b341561010a57600080fd5b6101326004808035906020019091908035906020019091908035906020019091905050610e2d565b604051808215151515815260200191505060405180910390f35b341561015757600080fd5b610171600480803560001916906020019091905050610e7c565b6040518082815260200191505060405180910390f35b341561019257600080fd5b6101ac600480803560001916906020019091905050610e94565b6040518082815260200191505060405180910390f35b34156101cd57600080fd5b6103a660048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561024857848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610203565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156102c457848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061027f565b5050505050919080359060200190919080351515906020019091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050610eac565b6040518082815260200191505060405180910390f35b34156103c757600080fd5b6104356004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091905050611013565b6040518082815260200191505060405180910390f35b341561045657600080fd5b61045e6114fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104ab57600080fd5b6106b060048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561052657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906104e1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156105a257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061055d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050611520565b005b34156106bd57600080fd5b6107516004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c00190600680602002604051908101604052809291908260066020028082843782019150505050509190803590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506115df565b005b341561075e57600080fd5b610778600480803560001916906020019091905050611605565b6040518082815260200191505060405180910390f35b341561079957600080fd5b6107f8600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356000191690602001909190803560ff16906020019091908035600019169060200190919080356000191690602001909190505061164f565b604051808215151515815260200191505060405180910390f35b341561081d57600080fd5b6108456004808035906020019091908035906020019091908035906020019091905050611757565b6040518082815260200191505060405180910390f35b341561086657600080fd5b61086e611776565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156108bb57600080fd5b610acb60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561093657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906108f1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156109b257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061096d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035151590602001909190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061179c565b005b3415610ad857600080fd5b610c1d60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610b5357848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610b0e565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610bcf57848483905060c002016006806020026040519081016040528092919082600660200280828437820191505050505081526020019060010190610b8a565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061185e565b005b3415610c2a57600080fd5b610cc96004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091908035151590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506118d3565b6040518082815260200191505060405180910390f35b3415610cea57600080fd5b610d4f6004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091905050612073565b60405180826000191660001916815260200191505060405180910390f35b3415610d7857600080fd5b610d8061231f565b604051808261ffff1661ffff16815260200191505060405180910390f35b3415610da957600080fd5b610db1612325565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610df25780820151818401525b602081019050610dd6565b50505050905090810190601f168015610e1f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60008060008486850991506000821415610e4a5760009250610e73565b610e69610e5a83620f424061235e565b610e64888761235e565b612392565b90506103e8811192505b50509392505050565b60026020528060005260406000206000915090505481565b60036020528060005260406000206000915090505481565b6000806000809150600090505b895181101561100257896000815181101515610ed157fe5b906020019060200201516003600581101515610ee957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff168a82815181101515610f1257fe5b906020019060200201516003600581101515610f2a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16141515610f5157600080fd5b610fe582610fe08c84815181101515610f6657fe5b906020019060200201518c85815181101515610f7e57fe5b90602001906020020151610f928d886123ae565b8c8c88815181101515610fa157fe5b906020019060200201518c89815181101515610fb957fe5b906020019060200201518c8a815181101515610fd157fe5b906020019060200201516118d3565b6123c8565b915087821415610ff457611002565b5b8080600101915050610eb9565b8192505b5050979650505050505050565b600061101d612a8c565b6000806101606040519081016040528088600060058110151561103c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600160058110151561106b57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600260058110151561109a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860036005811015156110c957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860046005811015156110f857fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200187600060068110151561112757fe5b6020020151815260200187600160068110151561114057fe5b6020020151815260200187600260068110151561115957fe5b6020020151815260200187600360068110151561117257fe5b6020020151815260200187600460068110151561118b57fe5b6020020151815260200161119f8989612073565b6000191681525092503373ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161415156111e657600080fd5b60008360a001511180156111fe575060008360c00151115b801561120a5750600085115b151561121557600080fd5b8261012001514210151561127257826101400151600019166000600381111561123a57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61128d8360c00151611288856101400151611605565b6123ae565b915061129985836123e7565b905060008114156112f35782610140015160001916600160038111156112bb57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61131d600360008561014001516000191660001916815260200190815260200160002054826123c8565b60036000856101400151600019166000191681526020019081526020016000208190555082604001518360600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916836080015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b0458713186604001518760600151611455878a60c001518b60a00151611757565b878a6101400151604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182600019166000191681526020019550505050505060405180910390a48093505b5050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b86518110156115d5576115c7878281518110151561154057fe5b90602001906020020151878381518110151561155857fe5b90602001906020020151878481518110151561157057fe5b90602001906020020151878581518110151561158857fe5b9060200190602002015187868151811015156115a057fe5b9060200190602002015187878151811015156115b857fe5b906020019060200201516115df565b5b8080600101915050611526565b5b50505050505050565b836115f087878760008888886118d3565b1415156115fc57600080fd5b5b505050505050565b600061164760026000846000191660001916815260200190815260200160002054600360008560001916600019168152602001908152602001600020546123c8565b90505b919050565b600060018560405180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040518091039020858585604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f1151561171457600080fd5b50506020604051035173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161490505b95945050505050565b600061176c611766858461235e565b84612392565b90505b9392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b87518110156118535761184488828151811015156117bc57fe5b9060200190602002015188838151811015156117d457fe5b9060200190602002015188848151811015156117ec57fe5b9060200190602002015188888681518110151561180557fe5b90602001906020020151888781518110151561181d57fe5b90602001906020020151888881518110151561183557fe5b906020019060200201516118d3565b505b80806001019150506117a2565b5b5050505050505050565b60008090505b83518110156118cc576118bd848281518110151561187e57fe5b90602001906020020151848381518110151561189657fe5b9060200190602002015184848151811015156118ae57fe5b90602001906020020151611013565b505b8080600101915050611864565b5b50505050565b60006118dd612a8c565b600080600080610160604051908101604052808e60006005811015156118ff57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600160058110151561192e57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600260058110151561195d57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600360058110151561198c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60046005811015156119bb57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60006006811015156119ea57fe5b602002015181526020018d6001600681101515611a0357fe5b602002015181526020018d6002600681101515611a1c57fe5b602002015181526020018d6003600681101515611a3557fe5b602002015181526020018d6004600681101515611a4e57fe5b60200201518152602001611a628f8f612073565b600019168152509450600073ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff161480611ad957503373ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff16145b1515611ae457600080fd5b60008560a00151118015611afc575060008560c00151115b8015611b08575060008b115b1515611b1357600080fd5b611b2985600001518661014001518b8b8b61164f565b1515611b3457600080fd5b84610120015142101515611b91578461014001516000191660006003811115611b5957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611bac8560c00151611ba7876101400151611605565b6123ae565b9350611bb88b856123e7565b95506000861415611c12578461014001516000191660016003811115611bda57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611c25868660c001518760a00151610e2d565b15611c79578461014001516000191660026003811115611c4157fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b89158015611c8e5750611c8c8587612401565b155b15611ce15784610140015160001916600380811115611ca957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611cf4868660c001518760a00151611757565b9250611d20600260008761014001516000191660001916815260200190815260200160002054876123c8565b600260008761014001516000191660001916815260200190815260200160002081905550611d58856040015186600001513386612751565b1515611d6357600080fd5b611d77856060015133876000015189612751565b1515611d8257600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16856080015173ffffffffffffffffffffffffffffffffffffffff16141515611e815760008560e001511115611e1f57611ddc868660c001518760e00151611757565b9150611e136000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660000151876080015185612751565b1515611e1e57600080fd5b5b60008561010001511115611e8057611e41868660c00151876101000151611757565b9050611e746000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633876080015184612751565b1515611e7f57600080fd5b5b5b84604001518560600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916856080015173ffffffffffffffffffffffffffffffffffffffff16866000015173ffffffffffffffffffffffffffffffffffffffff167f0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb33389604001518a60600151898d8a8a8f6101400151604051808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200186815260200185815260200184815260200183815260200182600019166000191681526020019850505050505050505060405180910390a48595505b5050505050979650505050505050565b60003083600060058110151561208557fe5b602002015184600160058110151561209957fe5b60200201518560026005811015156120ad57fe5b60200201518660036005811015156120c157fe5b60200201518760046005811015156120d557fe5b60200201518760006006811015156120e957fe5b60200201518860016006811015156120fd57fe5b602002015189600260068110151561211157fe5b60200201518a600360068110151561212557fe5b60200201518b600460068110151561213957fe5b60200201518c600560068110151561214d57fe5b6020020151604051808d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018781526020018681526020018581526020018481526020018381526020018281526020019c50505050505050505050505050604051809103902090505b92915050565b61138781565b6040805190810160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6000808284029050600084148061237f575082848281151561237c57fe5b04145b151561238757fe5b8091505b5092915050565b60008082848115156123a057fe5b0490508091505b5092915050565b60008282111515156123bc57fe5b81830390505b92915050565b60008082840190508381101515156123dc57fe5b8091505b5092915050565b60008183106123f657816123f8565b825b90505b92915050565b60008060008060008060008060003397506124258a8c60c001518d60a00151611757565b9650600073ffffffffffffffffffffffffffffffffffffffff168b6080015173ffffffffffffffffffffffffffffffffffffffff161415156126d2576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6040015173ffffffffffffffffffffffffffffffffffffffff161495506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6060015173ffffffffffffffffffffffffffffffffffffffff161494506125208a8c60c001518d60e00151611757565b93506125368a8c60c001518d6101000151611757565b925085612543578361254e565b61254d87856123c8565b5b91508461255b5782612566565b6125658a846123c8565b5b9050816125986000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d600001516128ae565b10806125d15750816125cf6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d60000151612972565b105b806126055750806126036000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a6128ae565b105b806126395750806126376000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a612972565b105b156126475760009850612743565b851580156126805750866126638c604001518d600001516128ae565b108061267f57508661267d8c604001518d60000151612972565b105b5b1561268e5760009850612743565b841580156126bf5750896126a68c606001518a6128ae565b10806126be5750896126bc8c606001518a612972565b105b5b156126cd5760009850612743565b61273e565b866126e58c604001518d600001516128ae565b10806127015750866126ff8c604001518d60000151612972565b105b806127185750896127168c606001518a6128ae565b105b8061272f57508961272d8c606001518a612972565b105b1561273d5760009850612743565b5b600198505b505050505050505092915050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166315dacbea868686866000604051602001526040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050602060405180830381600087803b151561288857600080fd5b6102c65a03f1151561289957600080fd5b5050506040518051905090505b949350505050565b60008273ffffffffffffffffffffffffffffffffffffffff166370a0823161138761ffff16846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600088803b151561295157600080fd5b87f1151561295e57600080fd5b505050506040518051905090505b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e61138761ffff1684600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600088803b1515612a6b57600080fd5b87f11515612a7857600080fd5b505050506040518051905090505b92915050565b61016060405190810160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000801916815250905600a165627a7a72305820df5cabdc3a116e993e10bfb14823d18d9b798038d4c463a1703f9a584c456b7e0029'; diff --git a/packages/deployer/src/test/util/constants.ts b/packages/deployer/src/test/util/constants.ts deleted file mode 100644 index d52076607..000000000 --- a/packages/deployer/src/test/util/constants.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BigNumber } from '@0xproject/utils'; - -export const constants = { - networkId: 0, - jsonrpcPort: 8545, - optimizerEnabled: 0, - gasPrice: new BigNumber(20000000000), - timeoutMs: 20000, - zrxTokenAddress: '0xe41d2489571d322189246dafa5ebde1f4699f498', - tokenTransferProxyAddress: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4', -}; diff --git a/packages/deployer/test/deploy_test.ts b/packages/deployer/test/deploy_test.ts new file mode 100644 index 000000000..5df729a04 --- /dev/null +++ b/packages/deployer/test/deploy_test.ts @@ -0,0 +1,91 @@ +import * as chai from 'chai'; +import 'mocha'; + +import { Compiler } from '../src/compiler'; +import { Deployer } from '../src/deployer'; +import { fsWrapper } from '../src/utils/fs_wrapper'; +import { CompilerOptions, ContractArtifact, ContractData, DoneCallback } from '../src/utils/types'; +import { constructor_args, exchange_binary } from './fixtures/exchange_bin'; +import { constants } from './util/constants'; + +const expect = chai.expect; +const artifactsDir = `${__dirname}/fixtures/artifacts`; +const contractsDir = `${__dirname}/fixtures/contracts`; +const exchangeArtifactPath = `${artifactsDir}/Exchange.json`; +const compilerOpts: CompilerOptions = { + artifactsDir, + contractsDir, + networkId: constants.networkId, + optimizerEnabled: constants.optimizerEnabled, +}; +const compiler = new Compiler(compilerOpts); +const deployerOpts = { + artifactsDir, + networkId: constants.networkId, + jsonrpcPort: constants.jsonrpcPort, + defaults: { + gasPrice: constants.gasPrice, + }, +}; +const deployer = new Deployer(deployerOpts); + +/* tslint:disable */ +beforeEach(function(done: DoneCallback) { + this.timeout(constants.timeoutMs); + (async () => { + if (fsWrapper.doesPathExistSync(exchangeArtifactPath)) { + await fsWrapper.removeFileAsync(exchangeArtifactPath); + } + await compiler.compileAllAsync(); + done(); + })().catch(done); +}); +/* tslint:enable */ + +describe('#Compiler', () => { + it('should create an Exchange artifact with the correct unlinked binary', async () => { + const opts = { + encoding: 'utf8', + }; + const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts); + const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString); + const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId]; + // The last 43 bytes of the binaries are metadata which may not be equivalent + const unlinkedBinaryWithoutMetadata = exchangeContractData.unlinked_binary.slice(0, -86); + const exchangeBinaryWithoutMetadata = exchange_binary.slice(0, -86); + expect(unlinkedBinaryWithoutMetadata).to.equal(exchangeBinaryWithoutMetadata); + }); +}); +describe('#Deployer', () => { + describe('#deployAsync', () => { + it('should deploy the Exchange contract without updating the Exchange artifact', async () => { + const exchangeConstructorArgs = [constants.zrxTokenAddress, constants.tokenTransferProxyAddress]; + const exchangeContractInstance = await deployer.deployAsync('Exchange', exchangeConstructorArgs); + const opts = { + encoding: 'utf8', + }; + const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts); + const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString); + const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId]; + const exchangeAddress = exchangeContractInstance.address; + expect(exchangeAddress).to.not.equal(undefined); + expect(exchangeContractData.address).to.equal(undefined); + expect(exchangeContractData.constructor_args).to.equal(undefined); + }); + }); + describe('#deployAndSaveAsync', () => { + it('should save the correct contract address and constructor arguments to the Exchange artifact', async () => { + const exchangeConstructorArgs = [constants.zrxTokenAddress, constants.tokenTransferProxyAddress]; + const exchangeContractInstance = await deployer.deployAndSaveAsync('Exchange', exchangeConstructorArgs); + const opts = { + encoding: 'utf8', + }; + const exchangeArtifactString = await fsWrapper.readFileAsync(exchangeArtifactPath, opts); + const exchangeArtifact: ContractArtifact = JSON.parse(exchangeArtifactString); + const exchangeContractData: ContractData = exchangeArtifact.networks[constants.networkId]; + const exchangeAddress = exchangeContractInstance.address; + expect(exchangeAddress).to.be.equal(exchangeContractData.address); + expect(constructor_args).to.be.equal(exchangeContractData.constructor_args); + }); + }); +}); diff --git a/packages/deployer/test/fixtures/contracts/Exchange.sol b/packages/deployer/test/fixtures/contracts/Exchange.sol new file mode 100644 index 000000000..1b6819700 --- /dev/null +++ b/packages/deployer/test/fixtures/contracts/Exchange.sol @@ -0,0 +1,602 @@ +/* + + Copyright 2017 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity 0.4.14; + +import "./TokenTransferProxy.sol"; +import "./base/Token.sol"; +import "./base/SafeMath.sol"; + +/// @title Exchange - Facilitates exchange of ERC20 tokens. +/// @author Amir Bandeali - , Will Warren - +contract Exchange is SafeMath { + + // Error Codes + enum Errors { + ORDER_EXPIRED, // Order has already expired + ORDER_FULLY_FILLED_OR_CANCELLED, // Order has already been fully filled or cancelled + ROUNDING_ERROR_TOO_LARGE, // Rounding error too large + INSUFFICIENT_BALANCE_OR_ALLOWANCE // Insufficient balance or allowance for token transfer + } + + string constant public VERSION = "1.0.0"; + uint16 constant public EXTERNAL_QUERY_GAS_LIMIT = 4999; // Changes to state require at least 5000 gas + + address public ZRX_TOKEN_CONTRACT; + address public TOKEN_TRANSFER_PROXY_CONTRACT; + + // Mappings of orderHash => amounts of takerTokenAmount filled or cancelled. + mapping (bytes32 => uint) public filled; + mapping (bytes32 => uint) public cancelled; + + event LogFill( + address indexed maker, + address taker, + address indexed feeRecipient, + address makerToken, + address takerToken, + uint filledMakerTokenAmount, + uint filledTakerTokenAmount, + uint paidMakerFee, + uint paidTakerFee, + bytes32 indexed tokens, // keccak256(makerToken, takerToken), allows subscribing to a token pair + bytes32 orderHash + ); + + event LogCancel( + address indexed maker, + address indexed feeRecipient, + address makerToken, + address takerToken, + uint cancelledMakerTokenAmount, + uint cancelledTakerTokenAmount, + bytes32 indexed tokens, + bytes32 orderHash + ); + + event LogError(uint8 indexed errorId, bytes32 indexed orderHash); + + struct Order { + address maker; + address taker; + address makerToken; + address takerToken; + address feeRecipient; + uint makerTokenAmount; + uint takerTokenAmount; + uint makerFee; + uint takerFee; + uint expirationTimestampInSec; + bytes32 orderHash; + } + + function Exchange(address _zrxToken, address _tokenTransferProxy) { + ZRX_TOKEN_CONTRACT = _zrxToken; + TOKEN_TRANSFER_PROXY_CONTRACT = _tokenTransferProxy; + } + + /* + * Core exchange functions + */ + + /// @dev Fills the input order. + /// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient. + /// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt. + /// @param fillTakerTokenAmount Desired amount of takerToken to fill. + /// @param shouldThrowOnInsufficientBalanceOrAllowance Test if transfer will fail before attempting. + /// @param v ECDSA signature parameter v. + /// @param r ECDSA signature parameters r. + /// @param s ECDSA signature parameters s. + /// @return Total amount of takerToken filled in trade. + function fillOrder( + address[5] orderAddresses, + uint[6] orderValues, + uint fillTakerTokenAmount, + bool shouldThrowOnInsufficientBalanceOrAllowance, + uint8 v, + bytes32 r, + bytes32 s) + public + returns (uint filledTakerTokenAmount) + { + Order memory order = Order({ + maker: orderAddresses[0], + taker: orderAddresses[1], + makerToken: orderAddresses[2], + takerToken: orderAddresses[3], + feeRecipient: orderAddresses[4], + makerTokenAmount: orderValues[0], + takerTokenAmount: orderValues[1], + makerFee: orderValues[2], + takerFee: orderValues[3], + expirationTimestampInSec: orderValues[4], + orderHash: getOrderHash(orderAddresses, orderValues) + }); + + require(order.taker == address(0) || order.taker == msg.sender); + require(order.makerTokenAmount > 0 && order.takerTokenAmount > 0 && fillTakerTokenAmount > 0); + require(isValidSignature( + order.maker, + order.orderHash, + v, + r, + s + )); + + if (block.timestamp >= order.expirationTimestampInSec) { + LogError(uint8(Errors.ORDER_EXPIRED), order.orderHash); + return 0; + } + + uint remainingTakerTokenAmount = safeSub(order.takerTokenAmount, getUnavailableTakerTokenAmount(order.orderHash)); + filledTakerTokenAmount = min256(fillTakerTokenAmount, remainingTakerTokenAmount); + if (filledTakerTokenAmount == 0) { + LogError(uint8(Errors.ORDER_FULLY_FILLED_OR_CANCELLED), order.orderHash); + return 0; + } + + if (isRoundingError(filledTakerTokenAmount, order.takerTokenAmount, order.makerTokenAmount)) { + LogError(uint8(Errors.ROUNDING_ERROR_TOO_LARGE), order.orderHash); + return 0; + } + + if (!shouldThrowOnInsufficientBalanceOrAllowance && !isTransferable(order, filledTakerTokenAmount)) { + LogError(uint8(Errors.INSUFFICIENT_BALANCE_OR_ALLOWANCE), order.orderHash); + return 0; + } + + uint filledMakerTokenAmount = getPartialAmount(filledTakerTokenAmount, order.takerTokenAmount, order.makerTokenAmount); + uint paidMakerFee; + uint paidTakerFee; + filled[order.orderHash] = safeAdd(filled[order.orderHash], filledTakerTokenAmount); + require(transferViaTokenTransferProxy( + order.makerToken, + order.maker, + msg.sender, + filledMakerTokenAmount + )); + require(transferViaTokenTransferProxy( + order.takerToken, + msg.sender, + order.maker, + filledTakerTokenAmount + )); + if (order.feeRecipient != address(0)) { + if (order.makerFee > 0) { + paidMakerFee = getPartialAmount(filledTakerTokenAmount, order.takerTokenAmount, order.makerFee); + require(transferViaTokenTransferProxy( + ZRX_TOKEN_CONTRACT, + order.maker, + order.feeRecipient, + paidMakerFee + )); + } + if (order.takerFee > 0) { + paidTakerFee = getPartialAmount(filledTakerTokenAmount, order.takerTokenAmount, order.takerFee); + require(transferViaTokenTransferProxy( + ZRX_TOKEN_CONTRACT, + msg.sender, + order.feeRecipient, + paidTakerFee + )); + } + } + + LogFill( + order.maker, + msg.sender, + order.feeRecipient, + order.makerToken, + order.takerToken, + filledMakerTokenAmount, + filledTakerTokenAmount, + paidMakerFee, + paidTakerFee, + keccak256(order.makerToken, order.takerToken), + order.orderHash + ); + return filledTakerTokenAmount; + } + + /// @dev Cancels the input order. + /// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient. + /// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt. + /// @param cancelTakerTokenAmount Desired amount of takerToken to cancel in order. + /// @return Amount of takerToken cancelled. + function cancelOrder( + address[5] orderAddresses, + uint[6] orderValues, + uint cancelTakerTokenAmount) + public + returns (uint) + { + Order memory order = Order({ + maker: orderAddresses[0], + taker: orderAddresses[1], + makerToken: orderAddresses[2], + takerToken: orderAddresses[3], + feeRecipient: orderAddresses[4], + makerTokenAmount: orderValues[0], + takerTokenAmount: orderValues[1], + makerFee: orderValues[2], + takerFee: orderValues[3], + expirationTimestampInSec: orderValues[4], + orderHash: getOrderHash(orderAddresses, orderValues) + }); + + require(order.maker == msg.sender); + require(order.makerTokenAmount > 0 && order.takerTokenAmount > 0 && cancelTakerTokenAmount > 0); + + if (block.timestamp >= order.expirationTimestampInSec) { + LogError(uint8(Errors.ORDER_EXPIRED), order.orderHash); + return 0; + } + + uint remainingTakerTokenAmount = safeSub(order.takerTokenAmount, getUnavailableTakerTokenAmount(order.orderHash)); + uint cancelledTakerTokenAmount = min256(cancelTakerTokenAmount, remainingTakerTokenAmount); + if (cancelledTakerTokenAmount == 0) { + LogError(uint8(Errors.ORDER_FULLY_FILLED_OR_CANCELLED), order.orderHash); + return 0; + } + + cancelled[order.orderHash] = safeAdd(cancelled[order.orderHash], cancelledTakerTokenAmount); + + LogCancel( + order.maker, + order.feeRecipient, + order.makerToken, + order.takerToken, + getPartialAmount(cancelledTakerTokenAmount, order.takerTokenAmount, order.makerTokenAmount), + cancelledTakerTokenAmount, + keccak256(order.makerToken, order.takerToken), + order.orderHash + ); + return cancelledTakerTokenAmount; + } + + /* + * Wrapper functions + */ + + /// @dev Fills an order with specified parameters and ECDSA signature, throws if specified amount not filled entirely. + /// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient. + /// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt. + /// @param fillTakerTokenAmount Desired amount of takerToken to fill. + /// @param v ECDSA signature parameter v. + /// @param r ECDSA signature parameters r. + /// @param s ECDSA signature parameters s. + function fillOrKillOrder( + address[5] orderAddresses, + uint[6] orderValues, + uint fillTakerTokenAmount, + uint8 v, + bytes32 r, + bytes32 s) + public + { + require(fillOrder( + orderAddresses, + orderValues, + fillTakerTokenAmount, + false, + v, + r, + s + ) == fillTakerTokenAmount); + } + + /// @dev Synchronously executes multiple fill orders in a single transaction. + /// @param orderAddresses Array of address arrays containing individual order addresses. + /// @param orderValues Array of uint arrays containing individual order values. + /// @param fillTakerTokenAmounts Array of desired amounts of takerToken to fill in orders. + /// @param shouldThrowOnInsufficientBalanceOrAllowance Test if transfers will fail before attempting. + /// @param v Array ECDSA signature v parameters. + /// @param r Array of ECDSA signature r parameters. + /// @param s Array of ECDSA signature s parameters. + function batchFillOrders( + address[5][] orderAddresses, + uint[6][] orderValues, + uint[] fillTakerTokenAmounts, + bool shouldThrowOnInsufficientBalanceOrAllowance, + uint8[] v, + bytes32[] r, + bytes32[] s) + public + { + for (uint i = 0; i < orderAddresses.length; i++) { + fillOrder( + orderAddresses[i], + orderValues[i], + fillTakerTokenAmounts[i], + shouldThrowOnInsufficientBalanceOrAllowance, + v[i], + r[i], + s[i] + ); + } + } + + /// @dev Synchronously executes multiple fillOrKill orders in a single transaction. + /// @param orderAddresses Array of address arrays containing individual order addresses. + /// @param orderValues Array of uint arrays containing individual order values. + /// @param fillTakerTokenAmounts Array of desired amounts of takerToken to fill in orders. + /// @param v Array ECDSA signature v parameters. + /// @param r Array of ECDSA signature r parameters. + /// @param s Array of ECDSA signature s parameters. + function batchFillOrKillOrders( + address[5][] orderAddresses, + uint[6][] orderValues, + uint[] fillTakerTokenAmounts, + uint8[] v, + bytes32[] r, + bytes32[] s) + public + { + for (uint i = 0; i < orderAddresses.length; i++) { + fillOrKillOrder( + orderAddresses[i], + orderValues[i], + fillTakerTokenAmounts[i], + v[i], + r[i], + s[i] + ); + } + } + + /// @dev Synchronously executes multiple fill orders in a single transaction until total fillTakerTokenAmount filled. + /// @param orderAddresses Array of address arrays containing individual order addresses. + /// @param orderValues Array of uint arrays containing individual order values. + /// @param fillTakerTokenAmount Desired total amount of takerToken to fill in orders. + /// @param shouldThrowOnInsufficientBalanceOrAllowance Test if transfers will fail before attempting. + /// @param v Array ECDSA signature v parameters. + /// @param r Array of ECDSA signature r parameters. + /// @param s Array of ECDSA signature s parameters. + /// @return Total amount of fillTakerTokenAmount filled in orders. + function fillOrdersUpTo( + address[5][] orderAddresses, + uint[6][] orderValues, + uint fillTakerTokenAmount, + bool shouldThrowOnInsufficientBalanceOrAllowance, + uint8[] v, + bytes32[] r, + bytes32[] s) + public + returns (uint) + { + uint filledTakerTokenAmount = 0; + for (uint i = 0; i < orderAddresses.length; i++) { + require(orderAddresses[i][3] == orderAddresses[0][3]); // takerToken must be the same for each order + filledTakerTokenAmount = safeAdd(filledTakerTokenAmount, fillOrder( + orderAddresses[i], + orderValues[i], + safeSub(fillTakerTokenAmount, filledTakerTokenAmount), + shouldThrowOnInsufficientBalanceOrAllowance, + v[i], + r[i], + s[i] + )); + if (filledTakerTokenAmount == fillTakerTokenAmount) break; + } + return filledTakerTokenAmount; + } + + /// @dev Synchronously cancels multiple orders in a single transaction. + /// @param orderAddresses Array of address arrays containing individual order addresses. + /// @param orderValues Array of uint arrays containing individual order values. + /// @param cancelTakerTokenAmounts Array of desired amounts of takerToken to cancel in orders. + function batchCancelOrders( + address[5][] orderAddresses, + uint[6][] orderValues, + uint[] cancelTakerTokenAmounts) + public + { + for (uint i = 0; i < orderAddresses.length; i++) { + cancelOrder( + orderAddresses[i], + orderValues[i], + cancelTakerTokenAmounts[i] + ); + } + } + + /* + * Constant public functions + */ + + /// @dev Calculates Keccak-256 hash of order with specified parameters. + /// @param orderAddresses Array of order's maker, taker, makerToken, takerToken, and feeRecipient. + /// @param orderValues Array of order's makerTokenAmount, takerTokenAmount, makerFee, takerFee, expirationTimestampInSec, and salt. + /// @return Keccak-256 hash of order. + function getOrderHash(address[5] orderAddresses, uint[6] orderValues) + public + constant + returns (bytes32) + { + return keccak256( + address(this), + orderAddresses[0], // maker + orderAddresses[1], // taker + orderAddresses[2], // makerToken + orderAddresses[3], // takerToken + orderAddresses[4], // feeRecipient + orderValues[0], // makerTokenAmount + orderValues[1], // takerTokenAmount + orderValues[2], // makerFee + orderValues[3], // takerFee + orderValues[4], // expirationTimestampInSec + orderValues[5] // salt + ); + } + + /// @dev Verifies that an order signature is valid. + /// @param signer address of signer. + /// @param hash Signed Keccak-256 hash. + /// @param v ECDSA signature parameter v. + /// @param r ECDSA signature parameters r. + /// @param s ECDSA signature parameters s. + /// @return Validity of order signature. + function isValidSignature( + address signer, + bytes32 hash, + uint8 v, + bytes32 r, + bytes32 s) + public + constant + returns (bool) + { + return signer == ecrecover( + keccak256("\x19Ethereum Signed Message:\n32", hash), + v, + r, + s + ); + } + + /// @dev Checks if rounding error > 0.1%. + /// @param numerator Numerator. + /// @param denominator Denominator. + /// @param target Value to multiply with numerator/denominator. + /// @return Rounding error is present. + function isRoundingError(uint numerator, uint denominator, uint target) + public + constant + returns (bool) + { + uint remainder = mulmod(target, numerator, denominator); + if (remainder == 0) return false; // No rounding error. + + uint errPercentageTimes1000000 = safeDiv( + safeMul(remainder, 1000000), + safeMul(numerator, target) + ); + return errPercentageTimes1000000 > 1000; + } + + /// @dev Calculates partial value given a numerator and denominator. + /// @param numerator Numerator. + /// @param denominator Denominator. + /// @param target Value to calculate partial of. + /// @return Partial value of target. + function getPartialAmount(uint numerator, uint denominator, uint target) + public + constant + returns (uint) + { + return safeDiv(safeMul(numerator, target), denominator); + } + + /// @dev Calculates the sum of values already filled and cancelled for a given order. + /// @param orderHash The Keccak-256 hash of the given order. + /// @return Sum of values already filled and cancelled. + function getUnavailableTakerTokenAmount(bytes32 orderHash) + public + constant + returns (uint) + { + return safeAdd(filled[orderHash], cancelled[orderHash]); + } + + + /* + * Internal functions + */ + + /// @dev Transfers a token using TokenTransferProxy transferFrom function. + /// @param token Address of token to transferFrom. + /// @param from Address transfering token. + /// @param to Address receiving token. + /// @param value Amount of token to transfer. + /// @return Success of token transfer. + function transferViaTokenTransferProxy( + address token, + address from, + address to, + uint value) + internal + returns (bool) + { + return TokenTransferProxy(TOKEN_TRANSFER_PROXY_CONTRACT).transferFrom(token, from, to, value); + } + + /// @dev Checks if any order transfers will fail. + /// @param order Order struct of params that will be checked. + /// @param fillTakerTokenAmount Desired amount of takerToken to fill. + /// @return Predicted result of transfers. + function isTransferable(Order order, uint fillTakerTokenAmount) + internal + constant // The called token contracts may attempt to change state, but will not be able to due to gas limits on getBalance and getAllowance. + returns (bool) + { + address taker = msg.sender; + uint fillMakerTokenAmount = getPartialAmount(fillTakerTokenAmount, order.takerTokenAmount, order.makerTokenAmount); + + if (order.feeRecipient != address(0)) { + bool isMakerTokenZRX = order.makerToken == ZRX_TOKEN_CONTRACT; + bool isTakerTokenZRX = order.takerToken == ZRX_TOKEN_CONTRACT; + uint paidMakerFee = getPartialAmount(fillTakerTokenAmount, order.takerTokenAmount, order.makerFee); + uint paidTakerFee = getPartialAmount(fillTakerTokenAmount, order.takerTokenAmount, order.takerFee); + uint requiredMakerZRX = isMakerTokenZRX ? safeAdd(fillMakerTokenAmount, paidMakerFee) : paidMakerFee; + uint requiredTakerZRX = isTakerTokenZRX ? safeAdd(fillTakerTokenAmount, paidTakerFee) : paidTakerFee; + + if ( getBalance(ZRX_TOKEN_CONTRACT, order.maker) < requiredMakerZRX + || getAllowance(ZRX_TOKEN_CONTRACT, order.maker) < requiredMakerZRX + || getBalance(ZRX_TOKEN_CONTRACT, taker) < requiredTakerZRX + || getAllowance(ZRX_TOKEN_CONTRACT, taker) < requiredTakerZRX + ) return false; + + if (!isMakerTokenZRX && ( getBalance(order.makerToken, order.maker) < fillMakerTokenAmount // Don't double check makerToken if ZRX + || getAllowance(order.makerToken, order.maker) < fillMakerTokenAmount) + ) return false; + if (!isTakerTokenZRX && ( getBalance(order.takerToken, taker) < fillTakerTokenAmount // Don't double check takerToken if ZRX + || getAllowance(order.takerToken, taker) < fillTakerTokenAmount) + ) return false; + } else if ( getBalance(order.makerToken, order.maker) < fillMakerTokenAmount + || getAllowance(order.makerToken, order.maker) < fillMakerTokenAmount + || getBalance(order.takerToken, taker) < fillTakerTokenAmount + || getAllowance(order.takerToken, taker) < fillTakerTokenAmount + ) return false; + + return true; + } + + /// @dev Get token balance of an address. + /// @param token Address of token. + /// @param owner Address of owner. + /// @return Token balance of owner. + function getBalance(address token, address owner) + internal + constant // The called token contract may attempt to change state, but will not be able to due to an added gas limit. + returns (uint) + { + return Token(token).balanceOf.gas(EXTERNAL_QUERY_GAS_LIMIT)(owner); // Limit gas to prevent reentrancy + } + + /// @dev Get allowance of token given to TokenTransferProxy by an address. + /// @param token Address of token. + /// @param owner Address of owner. + /// @return Allowance of token given to TokenTransferProxy by owner. + function getAllowance(address token, address owner) + internal + constant // The called token contract may attempt to change state, but will not be able to due to an added gas limit. + returns (uint) + { + return Token(token).allowance.gas(EXTERNAL_QUERY_GAS_LIMIT)(owner, TOKEN_TRANSFER_PROXY_CONTRACT); // Limit gas to prevent reentrancy + } +} diff --git a/packages/deployer/test/fixtures/contracts/TokenTransferProxy.sol b/packages/deployer/test/fixtures/contracts/TokenTransferProxy.sol new file mode 100644 index 000000000..90c8e7d66 --- /dev/null +++ b/packages/deployer/test/fixtures/contracts/TokenTransferProxy.sol @@ -0,0 +1,115 @@ +/* + + Copyright 2017 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity 0.4.14; + +import "./base/Token.sol"; +import "./base/Ownable.sol"; + +/// @title TokenTransferProxy - Transfers tokens on behalf of contracts that have been approved via decentralized governance. +/// @author Amir Bandeali - , Will Warren - +contract TokenTransferProxy is Ownable { + + /// @dev Only authorized addresses can invoke functions with this modifier. + modifier onlyAuthorized { + require(authorized[msg.sender]); + _; + } + + modifier targetAuthorized(address target) { + require(authorized[target]); + _; + } + + modifier targetNotAuthorized(address target) { + require(!authorized[target]); + _; + } + + mapping (address => bool) public authorized; + address[] public authorities; + + event LogAuthorizedAddressAdded(address indexed target, address indexed caller); + event LogAuthorizedAddressRemoved(address indexed target, address indexed caller); + + /* + * Public functions + */ + + /// @dev Authorizes an address. + /// @param target Address to authorize. + function addAuthorizedAddress(address target) + public + onlyOwner + targetNotAuthorized(target) + { + authorized[target] = true; + authorities.push(target); + LogAuthorizedAddressAdded(target, msg.sender); + } + + /// @dev Removes authorizion of an address. + /// @param target Address to remove authorization from. + function removeAuthorizedAddress(address target) + public + onlyOwner + targetAuthorized(target) + { + delete authorized[target]; + for (uint i = 0; i < authorities.length; i++) { + if (authorities[i] == target) { + authorities[i] = authorities[authorities.length - 1]; + authorities.length -= 1; + break; + } + } + LogAuthorizedAddressRemoved(target, msg.sender); + } + + /// @dev Calls into ERC20 Token contract, invoking transferFrom. + /// @param token Address of token to transfer. + /// @param from Address to transfer token from. + /// @param to Address to transfer token to. + /// @param value Amount of token to transfer. + /// @return Success of transfer. + function transferFrom( + address token, + address from, + address to, + uint value) + public + onlyAuthorized + returns (bool) + { + return Token(token).transferFrom(from, to, value); + } + + /* + * Public constant functions + */ + + /// @dev Gets all authorized addresses. + /// @return Array of authorized addresses. + function getAuthorizedAddresses() + public + constant + returns (address[]) + { + return authorities; + } +} diff --git a/packages/deployer/test/fixtures/contracts/base/Ownable.sol b/packages/deployer/test/fixtures/contracts/base/Ownable.sol new file mode 100644 index 000000000..2a74c3717 --- /dev/null +++ b/packages/deployer/test/fixtures/contracts/base/Ownable.sol @@ -0,0 +1,27 @@ +pragma solidity 0.4.14; + +/* + * Ownable + * + * Base contract with an owner. + * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner. + */ + +contract Ownable { + address public owner; + + function Ownable() { + owner = msg.sender; + } + + modifier onlyOwner() { + require(msg.sender == owner); + _; + } + + function transferOwnership(address newOwner) onlyOwner { + if (newOwner != address(0)) { + owner = newOwner; + } + } +} diff --git a/packages/deployer/test/fixtures/contracts/base/SafeMath.sol b/packages/deployer/test/fixtures/contracts/base/SafeMath.sol new file mode 100644 index 000000000..7414684a8 --- /dev/null +++ b/packages/deployer/test/fixtures/contracts/base/SafeMath.sol @@ -0,0 +1,41 @@ +pragma solidity 0.4.14; + +contract SafeMath { + function safeMul(uint a, uint b) internal constant returns (uint256) { + uint c = a * b; + assert(a == 0 || c / a == b); + return c; + } + + function safeDiv(uint a, uint b) internal constant returns (uint256) { + uint c = a / b; + return c; + } + + function safeSub(uint a, uint b) internal constant returns (uint256) { + assert(b <= a); + return a - b; + } + + function safeAdd(uint a, uint b) internal constant returns (uint256) { + uint c = a + b; + assert(c >= a); + return c; + } + + function max64(uint64 a, uint64 b) internal constant returns (uint64) { + return a >= b ? a : b; + } + + function min64(uint64 a, uint64 b) internal constant returns (uint64) { + return a < b ? a : b; + } + + function max256(uint256 a, uint256 b) internal constant returns (uint256) { + return a >= b ? a : b; + } + + function min256(uint256 a, uint256 b) internal constant returns (uint256) { + return a < b ? a : b; + } +} diff --git a/packages/deployer/test/fixtures/contracts/base/Token.sol b/packages/deployer/test/fixtures/contracts/base/Token.sol new file mode 100644 index 000000000..c03f8c567 --- /dev/null +++ b/packages/deployer/test/fixtures/contracts/base/Token.sol @@ -0,0 +1,38 @@ +pragma solidity 0.4.14; + +contract Token { + + /// @return total amount of tokens + function totalSupply() constant returns (uint supply) {} + + /// @param _owner The address from which the balance will be retrieved + /// @return The balance + function balanceOf(address _owner) constant returns (uint balance) {} + + /// @notice send `_value` token to `_to` from `msg.sender` + /// @param _to The address of the recipient + /// @param _value The amount of token to be transferred + /// @return Whether the transfer was successful or not + function transfer(address _to, uint _value) returns (bool success) {} + + /// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from` + /// @param _from The address of the sender + /// @param _to The address of the recipient + /// @param _value The amount of token to be transferred + /// @return Whether the transfer was successful or not + function transferFrom(address _from, address _to, uint _value) returns (bool success) {} + + /// @notice `msg.sender` approves `_addr` to spend `_value` tokens + /// @param _spender The address of the account able to transfer the tokens + /// @param _value The amount of wei to be approved for transfer + /// @return Whether the approval was successful or not + function approve(address _spender, uint _value) returns (bool success) {} + + /// @param _owner The address of the account owning tokens + /// @param _spender The address of the account able to transfer the tokens + /// @return Amount of remaining tokens allowed to spent + function allowance(address _owner, address _spender) constant returns (uint remaining) {} + + event Transfer(address indexed _from, address indexed _to, uint _value); + event Approval(address indexed _owner, address indexed _spender, uint _value); +} diff --git a/packages/deployer/test/fixtures/exchange_bin.ts b/packages/deployer/test/fixtures/exchange_bin.ts new file mode 100644 index 000000000..a6eae515e --- /dev/null +++ b/packages/deployer/test/fixtures/exchange_bin.ts @@ -0,0 +1,4 @@ +export const constructor_args = + '0x000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f4980000000000000000000000008da0d80f5007ef1e431dd2127178d224e32c2ef4'; +export const exchange_binary = + '0x6060604052341561000f57600080fd5b604051604080612c4d833981016040528080519060200190919080519060200190919050505b816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50505b612b84806100c96000396000f300606060405236156100fa576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806314df96ee146100ff578063288cdc911461014c5780632ac1262214610187578063363349be146101c2578063394c21e7146103bc5780633b30ba591461044b5780634f150787146104a0578063741bcc93146106b25780637e9abb50146107535780638163681e1461078e57806398024a8b14610812578063add1cbc51461085b578063b7b2c7d6146108b0578063baa0181d14610acd578063bc61394a14610c1f578063cfc4d0ec14610cdf578063f06bbf7514610d6d578063ffa1ad7414610d9e575b600080fd5b341561010a57600080fd5b6101326004808035906020019091908035906020019091908035906020019091905050610e2d565b604051808215151515815260200191505060405180910390f35b341561015757600080fd5b610171600480803560001916906020019091905050610e7c565b6040518082815260200191505060405180910390f35b341561019257600080fd5b6101ac600480803560001916906020019091905050610e94565b6040518082815260200191505060405180910390f35b34156101cd57600080fd5b6103a660048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561024857848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610203565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156102c457848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061027f565b5050505050919080359060200190919080351515906020019091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050610eac565b6040518082815260200191505060405180910390f35b34156103c757600080fd5b6104356004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091905050611013565b6040518082815260200191505060405180910390f35b341561045657600080fd5b61045e6114fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104ab57600080fd5b6106b060048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561052657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906104e1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156105a257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061055d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091905050611520565b005b34156106bd57600080fd5b6107516004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c00190600680602002604051908101604052809291908260066020028082843782019150505050509190803590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506115df565b005b341561075e57600080fd5b610778600480803560001916906020019091905050611605565b6040518082815260200191505060405180910390f35b341561079957600080fd5b6107f8600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080356000191690602001909190803560ff16906020019091908035600019169060200190919080356000191690602001909190505061164f565b604051808215151515815260200191505060405180910390f35b341561081d57600080fd5b6108456004808035906020019091908035906020019091908035906020019091905050611757565b6040518082815260200191505060405180910390f35b341561086657600080fd5b61086e611776565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156108bb57600080fd5b610acb60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b8282101561093657848483905060a0020160058060200260405190810160405280929190826005602002808284378201915050505050815260200190600101906108f1565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b828210156109b257848483905060c00201600680602002604051908101604052809291908260066020028082843782019150505050508152602001906001019061096d565b50505050509190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035151590602001909190803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091908035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061179c565b005b3415610ad857600080fd5b610c1d60048080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610b5357848483905060a002016005806020026040519081016040528092919082600560200280828437820191505050505081526020019060010190610b0e565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020016000905b82821015610bcf57848483905060c002016006806020026040519081016040528092919082600660200280828437820191505050505081526020019060010190610b8a565b5050505050919080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509190505061185e565b005b3415610c2a57600080fd5b610cc96004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091908035906020019091908035151590602001909190803560ff1690602001909190803560001916906020019091908035600019169060200190919050506118d3565b6040518082815260200191505060405180910390f35b3415610cea57600080fd5b610d4f6004808060a001906005806020026040519081016040528092919082600560200280828437820191505050505091908060c001906006806020026040519081016040528092919082600660200280828437820191505050505091905050612073565b60405180826000191660001916815260200191505060405180910390f35b3415610d7857600080fd5b610d8061231f565b604051808261ffff1661ffff16815260200191505060405180910390f35b3415610da957600080fd5b610db1612325565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610df25780820151818401525b602081019050610dd6565b50505050905090810190601f168015610e1f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60008060008486850991506000821415610e4a5760009250610e73565b610e69610e5a83620f424061235e565b610e64888761235e565b612392565b90506103e8811192505b50509392505050565b60026020528060005260406000206000915090505481565b60036020528060005260406000206000915090505481565b6000806000809150600090505b895181101561100257896000815181101515610ed157fe5b906020019060200201516003600581101515610ee957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff168a82815181101515610f1257fe5b906020019060200201516003600581101515610f2a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16141515610f5157600080fd5b610fe582610fe08c84815181101515610f6657fe5b906020019060200201518c85815181101515610f7e57fe5b90602001906020020151610f928d886123ae565b8c8c88815181101515610fa157fe5b906020019060200201518c89815181101515610fb957fe5b906020019060200201518c8a815181101515610fd157fe5b906020019060200201516118d3565b6123c8565b915087821415610ff457611002565b5b8080600101915050610eb9565b8192505b5050979650505050505050565b600061101d612a8c565b6000806101606040519081016040528088600060058110151561103c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600160058110151561106b57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200188600260058110151561109a57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860036005811015156110c957fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018860046005811015156110f857fe5b602002015173ffffffffffffffffffffffffffffffffffffffff16815260200187600060068110151561112757fe5b6020020151815260200187600160068110151561114057fe5b6020020151815260200187600260068110151561115957fe5b6020020151815260200187600360068110151561117257fe5b6020020151815260200187600460068110151561118b57fe5b6020020151815260200161119f8989612073565b6000191681525092503373ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff161415156111e657600080fd5b60008360a001511180156111fe575060008360c00151115b801561120a5750600085115b151561121557600080fd5b8261012001514210151561127257826101400151600019166000600381111561123a57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61128d8360c00151611288856101400151611605565b6123ae565b915061129985836123e7565b905060008114156112f35782610140015160001916600160038111156112bb57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a3600093506114f1565b61131d600360008561014001516000191660001916815260200190815260200160002054826123c8565b60036000856101400151600019166000191681526020019081526020016000208190555082604001518360600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916836080015173ffffffffffffffffffffffffffffffffffffffff16846000015173ffffffffffffffffffffffffffffffffffffffff167f67d66f160bc93d925d05dae1794c90d2d6d6688b29b84ff069398a9b0458713186604001518760600151611455878a60c001518b60a00151611757565b878a6101400151604051808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182600019166000191681526020019550505050505060405180910390a48093505b5050509392505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b86518110156115d5576115c7878281518110151561154057fe5b90602001906020020151878381518110151561155857fe5b90602001906020020151878481518110151561157057fe5b90602001906020020151878581518110151561158857fe5b9060200190602002015187868151811015156115a057fe5b9060200190602002015187878151811015156115b857fe5b906020019060200201516115df565b5b8080600101915050611526565b5b50505050505050565b836115f087878760008888886118d3565b1415156115fc57600080fd5b5b505050505050565b600061164760026000846000191660001916815260200190815260200160002054600360008560001916600019168152602001908152602001600020546123c8565b90505b919050565b600060018560405180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040518091039020858585604051600081526020016040526000604051602001526040518085600019166000191681526020018460ff1660ff16815260200183600019166000191681526020018260001916600019168152602001945050505050602060405160208103908084039060008661646e5a03f1151561171457600080fd5b50506020604051035173ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161490505b95945050505050565b600061176c611766858461235e565b84612392565b90505b9392505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008090505b87518110156118535761184488828151811015156117bc57fe5b9060200190602002015188838151811015156117d457fe5b9060200190602002015188848151811015156117ec57fe5b9060200190602002015188888681518110151561180557fe5b90602001906020020151888781518110151561181d57fe5b90602001906020020151888881518110151561183557fe5b906020019060200201516118d3565b505b80806001019150506117a2565b5b5050505050505050565b60008090505b83518110156118cc576118bd848281518110151561187e57fe5b90602001906020020151848381518110151561189657fe5b9060200190602002015184848151811015156118ae57fe5b90602001906020020151611013565b505b8080600101915050611864565b5b50505050565b60006118dd612a8c565b600080600080610160604051908101604052808e60006005811015156118ff57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600160058110151561192e57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600260058110151561195d57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e600360058110151561198c57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018e60046005811015156119bb57fe5b602002015173ffffffffffffffffffffffffffffffffffffffff1681526020018d60006006811015156119ea57fe5b602002015181526020018d6001600681101515611a0357fe5b602002015181526020018d6002600681101515611a1c57fe5b602002015181526020018d6003600681101515611a3557fe5b602002015181526020018d6004600681101515611a4e57fe5b60200201518152602001611a628f8f612073565b600019168152509450600073ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff161480611ad957503373ffffffffffffffffffffffffffffffffffffffff16856020015173ffffffffffffffffffffffffffffffffffffffff16145b1515611ae457600080fd5b60008560a00151118015611afc575060008560c00151115b8015611b08575060008b115b1515611b1357600080fd5b611b2985600001518661014001518b8b8b61164f565b1515611b3457600080fd5b84610120015142101515611b91578461014001516000191660006003811115611b5957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611bac8560c00151611ba7876101400151611605565b6123ae565b9350611bb88b856123e7565b95506000861415611c12578461014001516000191660016003811115611bda57fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611c25868660c001518760a00151610e2d565b15611c79578461014001516000191660026003811115611c4157fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b89158015611c8e5750611c8c8587612401565b155b15611ce15784610140015160001916600380811115611ca957fe5b60ff167f36d86c59e00bd73dc19ba3adfe068e4b64ac7e92be35546adeddf1b956a87e9060405160405180910390a360009550612063565b611cf4868660c001518760a00151611757565b9250611d20600260008761014001516000191660001916815260200190815260200160002054876123c8565b600260008761014001516000191660001916815260200190815260200160002081905550611d58856040015186600001513386612751565b1515611d6357600080fd5b611d77856060015133876000015189612751565b1515611d8257600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16856080015173ffffffffffffffffffffffffffffffffffffffff16141515611e815760008560e001511115611e1f57611ddc868660c001518760e00151611757565b9150611e136000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168660000151876080015185612751565b1515611e1e57600080fd5b5b60008561010001511115611e8057611e41868660c00151876101000151611757565b9050611e746000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1633876080015184612751565b1515611e7f57600080fd5b5b5b84604001518560600151604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140192505050604051809103902060001916856080015173ffffffffffffffffffffffffffffffffffffffff16866000015173ffffffffffffffffffffffffffffffffffffffff167f0d0b9391970d9a25552f37d436d2aae2925e2bfe1b2a923754bada030c498cb33389604001518a60600151898d8a8a8f6101400151604051808973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200186815260200185815260200184815260200183815260200182600019166000191681526020019850505050505050505060405180910390a48595505b5050505050979650505050505050565b60003083600060058110151561208557fe5b602002015184600160058110151561209957fe5b60200201518560026005811015156120ad57fe5b60200201518660036005811015156120c157fe5b60200201518760046005811015156120d557fe5b60200201518760006006811015156120e957fe5b60200201518860016006811015156120fd57fe5b602002015189600260068110151561211157fe5b60200201518a600360068110151561212557fe5b60200201518b600460068110151561213957fe5b60200201518c600560068110151561214d57fe5b6020020151604051808d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000000281526014018781526020018681526020018581526020018481526020018381526020018281526020019c50505050505050505050505050604051809103902090505b92915050565b61138781565b6040805190810160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6000808284029050600084148061237f575082848281151561237c57fe5b04145b151561238757fe5b8091505b5092915050565b60008082848115156123a057fe5b0490508091505b5092915050565b60008282111515156123bc57fe5b81830390505b92915050565b60008082840190508381101515156123dc57fe5b8091505b5092915050565b60008183106123f657816123f8565b825b90505b92915050565b60008060008060008060008060003397506124258a8c60c001518d60a00151611757565b9650600073ffffffffffffffffffffffffffffffffffffffff168b6080015173ffffffffffffffffffffffffffffffffffffffff161415156126d2576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6040015173ffffffffffffffffffffffffffffffffffffffff161495506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b6060015173ffffffffffffffffffffffffffffffffffffffff161494506125208a8c60c001518d60e00151611757565b93506125368a8c60c001518d6101000151611757565b925085612543578361254e565b61254d87856123c8565b5b91508461255b5782612566565b6125658a846123c8565b5b9050816125986000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d600001516128ae565b10806125d15750816125cf6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168d60000151612972565b105b806126055750806126036000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a6128ae565b105b806126395750806126376000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff168a612972565b105b156126475760009850612743565b851580156126805750866126638c604001518d600001516128ae565b108061267f57508661267d8c604001518d60000151612972565b105b5b1561268e5760009850612743565b841580156126bf5750896126a68c606001518a6128ae565b10806126be5750896126bc8c606001518a612972565b105b5b156126cd5760009850612743565b61273e565b866126e58c604001518d600001516128ae565b10806127015750866126ff8c604001518d60000151612972565b105b806127185750896127168c606001518a6128ae565b105b8061272f57508961272d8c606001518a612972565b105b1561273d5760009850612743565b5b600198505b505050505050505092915050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166315dacbea868686866000604051602001526040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001945050505050602060405180830381600087803b151561288857600080fd5b6102c65a03f1151561289957600080fd5b5050506040518051905090505b949350505050565b60008273ffffffffffffffffffffffffffffffffffffffff166370a0823161138761ffff16846040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600088803b151561295157600080fd5b87f1151561295e57600080fd5b505050506040518051905090505b92915050565b60008273ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e61138761ffff1684600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600088803b1515612a6b57600080fd5b87f11515612a7857600080fd5b505050506040518051905090505b92915050565b61016060405190810160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600081526020016000801916815250905600a165627a7a72305820df5cabdc3a116e993e10bfb14823d18d9b798038d4c463a1703f9a584c456b7e0029'; diff --git a/packages/deployer/test/util/constants.ts b/packages/deployer/test/util/constants.ts new file mode 100644 index 000000000..d52076607 --- /dev/null +++ b/packages/deployer/test/util/constants.ts @@ -0,0 +1,11 @@ +import { BigNumber } from '@0xproject/utils'; + +export const constants = { + networkId: 0, + jsonrpcPort: 8545, + optimizerEnabled: 0, + gasPrice: new BigNumber(20000000000), + timeoutMs: 20000, + zrxTokenAddress: '0xe41d2489571d322189246dafa5ebde1f4699f498', + tokenTransferProxyAddress: '0x8da0d80f5007ef1e431dd2127178d224e32c2ef4', +}; diff --git a/packages/deployer/tsconfig.json b/packages/deployer/tsconfig.json index 25c28b72a..4e1edb510 100644 --- a/packages/deployer/tsconfig.json +++ b/packages/deployer/tsconfig.json @@ -7,6 +7,7 @@ }, "include": [ "./src/**/*", + "./test/**/*", "../../node_modules/types-bn/index.d.ts", "../../node_modules/types-ethereumjs-util/index.d.ts", "../../node_modules/chai-typescript-typings/index.d.ts", -- cgit v1.2.3