diff options
Diffstat (limited to 'packages/contracts/contracts/protocol/Exchange')
29 files changed, 0 insertions, 3802 deletions
diff --git a/packages/contracts/contracts/protocol/Exchange/Exchange.sol b/packages/contracts/contracts/protocol/Exchange/Exchange.sol deleted file mode 100644 index ead36009f..000000000 --- a/packages/contracts/contracts/protocol/Exchange/Exchange.sol +++ /dev/null @@ -1,53 +0,0 @@ -/* - - Copyright 2018 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.24; -pragma experimental ABIEncoderV2; - -import "./libs/LibConstants.sol"; -import "./MixinExchangeCore.sol"; -import "./MixinSignatureValidator.sol"; -import "./MixinWrapperFunctions.sol"; -import "./MixinAssetProxyDispatcher.sol"; -import "./MixinTransactions.sol"; -import "./MixinMatchOrders.sol"; - - -// solhint-disable no-empty-blocks -contract Exchange is - MixinExchangeCore, - MixinMatchOrders, - MixinSignatureValidator, - MixinTransactions, - MixinAssetProxyDispatcher, - MixinWrapperFunctions -{ - string constant public VERSION = "2.0.1-alpha"; - - // Mixins are instantiated in the order they are inherited - constructor (bytes memory _zrxAssetData) - public - LibConstants(_zrxAssetData) // @TODO: Remove when we deploy. - MixinExchangeCore() - MixinMatchOrders() - MixinSignatureValidator() - MixinTransactions() - MixinAssetProxyDispatcher() - MixinWrapperFunctions() - {} -} diff --git a/packages/contracts/contracts/protocol/Exchange/MixinAssetProxyDispatcher.sol b/packages/contracts/contracts/protocol/Exchange/MixinAssetProxyDispatcher.sol deleted file mode 100644 index 87b09b6b3..000000000 --- a/packages/contracts/contracts/protocol/Exchange/MixinAssetProxyDispatcher.sol +++ /dev/null @@ -1,174 +0,0 @@ -/* - - Copyright 2018 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.24; - -import "../../utils/Ownable/Ownable.sol"; -import "./mixins/MAssetProxyDispatcher.sol"; -import "../AssetProxy/interfaces/IAssetProxy.sol"; - - -contract MixinAssetProxyDispatcher is - Ownable, - MAssetProxyDispatcher -{ - // Mapping from Asset Proxy Id's to their respective Asset Proxy - mapping (bytes4 => IAssetProxy) public assetProxies; - - /// @dev Registers an asset proxy to its asset proxy id. - /// Once an asset proxy is registered, it cannot be unregistered. - /// @param assetProxy Address of new asset proxy to register. - function registerAssetProxy(address assetProxy) - external - onlyOwner - { - IAssetProxy assetProxyContract = IAssetProxy(assetProxy); - - // Ensure that no asset proxy exists with current id. - bytes4 assetProxyId = assetProxyContract.getProxyId(); - address currentAssetProxy = assetProxies[assetProxyId]; - require( - currentAssetProxy == address(0), - "ASSET_PROXY_ALREADY_EXISTS" - ); - - // Add asset proxy and log registration. - assetProxies[assetProxyId] = assetProxyContract; - emit AssetProxyRegistered( - assetProxyId, - assetProxy - ); - } - - /// @dev Gets an asset proxy. - /// @param assetProxyId Id of the asset proxy. - /// @return The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered. - function getAssetProxy(bytes4 assetProxyId) - external - view - returns (address) - { - return assetProxies[assetProxyId]; - } - - /// @dev Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws. - /// @param assetData Byte array encoded for the asset. - /// @param from Address to transfer token from. - /// @param to Address to transfer token to. - /// @param amount Amount of token to transfer. - function dispatchTransferFrom( - bytes memory assetData, - address from, - address to, - uint256 amount - ) - internal - { - // Do nothing if no amount should be transferred. - if (amount > 0 && from != to) { - // Ensure assetData length is valid - require( - assetData.length > 3, - "LENGTH_GREATER_THAN_3_REQUIRED" - ); - - // Lookup assetProxy. We do not use `LibBytes.readBytes4` for gas efficiency reasons. - bytes4 assetProxyId; - assembly { - assetProxyId := and(mload( - add(assetData, 32)), - 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000 - ) - } - address assetProxy = assetProxies[assetProxyId]; - - // Ensure that assetProxy exists - require( - assetProxy != address(0), - "ASSET_PROXY_DOES_NOT_EXIST" - ); - - // We construct calldata for the `assetProxy.transferFrom` ABI. - // The layout of this calldata is in the table below. - // - // | Area | Offset | Length | Contents | - // | -------- |--------|---------|-------------------------------------------- | - // | Header | 0 | 4 | function selector | - // | Params | | 4 * 32 | function parameters: | - // | | 4 | | 1. offset to assetData (*) | - // | | 36 | | 2. from | - // | | 68 | | 3. to | - // | | 100 | | 4. amount | - // | Data | | | assetData: | - // | | 132 | 32 | assetData Length | - // | | 164 | ** | assetData Contents | - - assembly { - /////// Setup State /////// - // `cdStart` is the start of the calldata for `assetProxy.transferFrom` (equal to free memory ptr). - let cdStart := mload(64) - // `dataAreaLength` is the total number of words needed to store `assetData` - // As-per the ABI spec, this value is padded up to the nearest multiple of 32, - // and includes 32-bytes for length. - let dataAreaLength := and(add(mload(assetData), 63), 0xFFFFFFFFFFFE0) - // `cdEnd` is the end of the calldata for `assetProxy.transferFrom`. - let cdEnd := add(cdStart, add(132, dataAreaLength)) - - - /////// Setup Header Area /////// - // This area holds the 4-byte `transferFromSelector`. - // bytes4(keccak256("transferFrom(bytes,address,address,uint256)")) = 0xa85e59e4 - mstore(cdStart, 0xa85e59e400000000000000000000000000000000000000000000000000000000) - - /////// Setup Params Area /////// - // Each parameter is padded to 32-bytes. The entire Params Area is 128 bytes. - // Notes: - // 1. The offset to `assetData` is the length of the Params Area (128 bytes). - // 2. A 20-byte mask is applied to addresses to zero-out the unused bytes. - mstore(add(cdStart, 4), 128) - mstore(add(cdStart, 36), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) - mstore(add(cdStart, 68), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) - mstore(add(cdStart, 100), amount) - - /////// Setup Data Area /////// - // This area holds `assetData`. - let dataArea := add(cdStart, 132) - // solhint-disable-next-line no-empty-blocks - for {} lt(dataArea, cdEnd) {} { - mstore(dataArea, mload(assetData)) - dataArea := add(dataArea, 32) - assetData := add(assetData, 32) - } - - /////// Call `assetProxy.transferFrom` using the constructed calldata /////// - let success := call( - gas, // forward all gas - assetProxy, // call address of asset proxy - 0, // don't send any ETH - cdStart, // pointer to start of input - sub(cdEnd, cdStart), // length of input - cdStart, // write output over input - 512 // reserve 512 bytes for output - ) - if iszero(success) { - revert(cdStart, returndatasize()) - } - } - } - } -} diff --git a/packages/contracts/contracts/protocol/Exchange/MixinExchangeCore.sol b/packages/contracts/contracts/protocol/Exchange/MixinExchangeCore.sol deleted file mode 100644 index 736dcd0b1..000000000 --- a/packages/contracts/contracts/protocol/Exchange/MixinExchangeCore.sol +++ /dev/null @@ -1,529 +0,0 @@ -/* - - Copyright 2018 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.24; -pragma experimental ABIEncoderV2; - -import "../../utils/ReentrancyGuard/ReentrancyGuard.sol"; -import "./libs/LibConstants.sol"; -import "./libs/LibFillResults.sol"; -import "./libs/LibOrder.sol"; -import "./libs/LibMath.sol"; -import "./mixins/MExchangeCore.sol"; -import "./mixins/MSignatureValidator.sol"; -import "./mixins/MTransactions.sol"; -import "./mixins/MAssetProxyDispatcher.sol"; - - -contract MixinExchangeCore is - ReentrancyGuard, - LibConstants, - LibMath, - LibOrder, - LibFillResults, - MAssetProxyDispatcher, - MExchangeCore, - MSignatureValidator, - MTransactions -{ - // Mapping of orderHash => amount of takerAsset already bought by maker - mapping (bytes32 => uint256) public filled; - - // Mapping of orderHash => cancelled - mapping (bytes32 => bool) public cancelled; - - // Mapping of makerAddress => senderAddress => lowest salt an order can have in order to be fillable - // Orders with specified senderAddress and with a salt less than their epoch are considered cancelled - mapping (address => mapping (address => uint256)) public orderEpoch; - - /// @dev Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch - /// and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress). - /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled. - function cancelOrdersUpTo(uint256 targetOrderEpoch) - external - nonReentrant - { - address makerAddress = getCurrentContextAddress(); - // If this function is called via `executeTransaction`, we only update the orderEpoch for the makerAddress/msg.sender combination. - // This allows external filter contracts to add rules to how orders are cancelled via this function. - address senderAddress = makerAddress == msg.sender ? address(0) : msg.sender; - - // orderEpoch is initialized to 0, so to cancelUpTo we need salt + 1 - uint256 newOrderEpoch = targetOrderEpoch + 1; - uint256 oldOrderEpoch = orderEpoch[makerAddress][senderAddress]; - - // Ensure orderEpoch is monotonically increasing - require( - newOrderEpoch > oldOrderEpoch, - "INVALID_NEW_ORDER_EPOCH" - ); - - // Update orderEpoch - orderEpoch[makerAddress][senderAddress] = newOrderEpoch; - emit CancelUpTo( - makerAddress, - senderAddress, - newOrderEpoch - ); - } - - /// @dev Fills the input order. - /// @param order Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signature Proof that order has been created by maker. - /// @return Amounts filled and fees paid by maker and taker. - function fillOrder( - Order memory order, - uint256 takerAssetFillAmount, - bytes memory signature - ) - public - nonReentrant - returns (FillResults memory fillResults) - { - fillResults = fillOrderInternal( - order, - takerAssetFillAmount, - signature - ); - return fillResults; - } - - /// @dev After calling, the order can not be filled anymore. - /// Throws if order is invalid or sender does not have permission to cancel. - /// @param order Order to cancel. Order must be OrderStatus.FILLABLE. - function cancelOrder(Order memory order) - public - nonReentrant - { - cancelOrderInternal(order); - } - - /// @dev Gets information about an order: status, hash, and amount filled. - /// @param order Order to gather information on. - /// @return OrderInfo Information about the order and its state. - /// See LibOrder.OrderInfo for a complete description. - function getOrderInfo(Order memory order) - public - view - returns (OrderInfo memory orderInfo) - { - // Compute the order hash - orderInfo.orderHash = getOrderHash(order); - - // Fetch filled amount - orderInfo.orderTakerAssetFilledAmount = filled[orderInfo.orderHash]; - - // If order.makerAssetAmount is zero, we also reject the order. - // While the Exchange contract handles them correctly, they create - // edge cases in the supporting infrastructure because they have - // an 'infinite' price when computed by a simple division. - if (order.makerAssetAmount == 0) { - orderInfo.orderStatus = uint8(OrderStatus.INVALID_MAKER_ASSET_AMOUNT); - return orderInfo; - } - - // If order.takerAssetAmount is zero, then the order will always - // be considered filled because 0 == takerAssetAmount == orderTakerAssetFilledAmount - // Instead of distinguishing between unfilled and filled zero taker - // amount orders, we choose not to support them. - if (order.takerAssetAmount == 0) { - orderInfo.orderStatus = uint8(OrderStatus.INVALID_TAKER_ASSET_AMOUNT); - return orderInfo; - } - - // Validate order availability - if (orderInfo.orderTakerAssetFilledAmount >= order.takerAssetAmount) { - orderInfo.orderStatus = uint8(OrderStatus.FULLY_FILLED); - return orderInfo; - } - - // Validate order expiration - // solhint-disable-next-line not-rely-on-time - if (block.timestamp >= order.expirationTimeSeconds) { - orderInfo.orderStatus = uint8(OrderStatus.EXPIRED); - return orderInfo; - } - - // Check if order has been cancelled - if (cancelled[orderInfo.orderHash]) { - orderInfo.orderStatus = uint8(OrderStatus.CANCELLED); - return orderInfo; - } - if (orderEpoch[order.makerAddress][order.senderAddress] > order.salt) { - orderInfo.orderStatus = uint8(OrderStatus.CANCELLED); - return orderInfo; - } - - // All other statuses are ruled out: order is Fillable - orderInfo.orderStatus = uint8(OrderStatus.FILLABLE); - return orderInfo; - } - - /// @dev Fills the input order. - /// @param order Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signature Proof that order has been created by maker. - /// @return Amounts filled and fees paid by maker and taker. - function fillOrderInternal( - Order memory order, - uint256 takerAssetFillAmount, - bytes memory signature - ) - internal - returns (FillResults memory fillResults) - { - // Fetch order info - OrderInfo memory orderInfo = getOrderInfo(order); - - // Fetch taker address - address takerAddress = getCurrentContextAddress(); - - // Assert that the order is fillable by taker - assertFillableOrder( - order, - orderInfo, - takerAddress, - signature - ); - - // Get amount of takerAsset to fill - uint256 remainingTakerAssetAmount = safeSub(order.takerAssetAmount, orderInfo.orderTakerAssetFilledAmount); - uint256 takerAssetFilledAmount = min256(takerAssetFillAmount, remainingTakerAssetAmount); - - // Validate context - assertValidFill( - order, - orderInfo, - takerAssetFillAmount, - takerAssetFilledAmount, - fillResults.makerAssetFilledAmount - ); - - // Compute proportional fill amounts - fillResults = calculateFillResults(order, takerAssetFilledAmount); - - // Update exchange internal state - updateFilledState( - order, - takerAddress, - orderInfo.orderHash, - orderInfo.orderTakerAssetFilledAmount, - fillResults - ); - - // Settle order - settleOrder( - order, - takerAddress, - fillResults - ); - - return fillResults; - } - - /// @dev After calling, the order can not be filled anymore. - /// Throws if order is invalid or sender does not have permission to cancel. - /// @param order Order to cancel. Order must be OrderStatus.FILLABLE. - function cancelOrderInternal(Order memory order) - internal - { - // Fetch current order status - OrderInfo memory orderInfo = getOrderInfo(order); - - // Validate context - assertValidCancel(order, orderInfo); - - // Perform cancel - updateCancelledState(order, orderInfo.orderHash); - } - - /// @dev Updates state with results of a fill order. - /// @param order that was filled. - /// @param takerAddress Address of taker who filled the order. - /// @param orderTakerAssetFilledAmount Amount of order already filled. - function updateFilledState( - Order memory order, - address takerAddress, - bytes32 orderHash, - uint256 orderTakerAssetFilledAmount, - FillResults memory fillResults - ) - internal - { - // Update state - filled[orderHash] = safeAdd(orderTakerAssetFilledAmount, fillResults.takerAssetFilledAmount); - - // Log order - emit Fill( - order.makerAddress, - order.feeRecipientAddress, - takerAddress, - msg.sender, - fillResults.makerAssetFilledAmount, - fillResults.takerAssetFilledAmount, - fillResults.makerFeePaid, - fillResults.takerFeePaid, - orderHash, - order.makerAssetData, - order.takerAssetData - ); - } - - /// @dev Updates state with results of cancelling an order. - /// State is only updated if the order is currently fillable. - /// Otherwise, updating state would have no effect. - /// @param order that was cancelled. - /// @param orderHash Hash of order that was cancelled. - function updateCancelledState( - Order memory order, - bytes32 orderHash - ) - internal - { - // Perform cancel - cancelled[orderHash] = true; - - // Log cancel - emit Cancel( - order.makerAddress, - order.feeRecipientAddress, - msg.sender, - orderHash, - order.makerAssetData, - order.takerAssetData - ); - } - - /// @dev Validates context for fillOrder. Succeeds or throws. - /// @param order to be filled. - /// @param orderInfo OrderStatus, orderHash, and amount already filled of order. - /// @param takerAddress Address of order taker. - /// @param signature Proof that the orders was created by its maker. - function assertFillableOrder( - Order memory order, - OrderInfo memory orderInfo, - address takerAddress, - bytes memory signature - ) - internal - view - { - // An order can only be filled if its status is FILLABLE. - require( - orderInfo.orderStatus == uint8(OrderStatus.FILLABLE), - "ORDER_UNFILLABLE" - ); - - // Validate sender is allowed to fill this order - if (order.senderAddress != address(0)) { - require( - order.senderAddress == msg.sender, - "INVALID_SENDER" - ); - } - - // Validate taker is allowed to fill this order - if (order.takerAddress != address(0)) { - require( - order.takerAddress == takerAddress, - "INVALID_TAKER" - ); - } - - // Validate Maker signature (check only if first time seen) - if (orderInfo.orderTakerAssetFilledAmount == 0) { - require( - isValidSignature( - orderInfo.orderHash, - order.makerAddress, - signature - ), - "INVALID_ORDER_SIGNATURE" - ); - } - } - - /// @dev Validates context for fillOrder. Succeeds or throws. - /// @param order to be filled. - /// @param orderInfo OrderStatus, orderHash, and amount already filled of order. - /// @param takerAssetFillAmount Desired amount of order to fill by taker. - /// @param takerAssetFilledAmount Amount of takerAsset that will be filled. - /// @param makerAssetFilledAmount Amount of makerAsset that will be transfered. - function assertValidFill( - Order memory order, - OrderInfo memory orderInfo, - uint256 takerAssetFillAmount, // TODO: use FillResults - uint256 takerAssetFilledAmount, - uint256 makerAssetFilledAmount - ) - internal - view - { - // Revert if fill amount is invalid - // TODO: reconsider necessity for v2.1 - require( - takerAssetFillAmount != 0, - "INVALID_TAKER_AMOUNT" - ); - - // Make sure taker does not pay more than desired amount - // NOTE: This assertion should never fail, it is here - // as an extra defence against potential bugs. - require( - takerAssetFilledAmount <= takerAssetFillAmount, - "TAKER_OVERPAY" - ); - - // Make sure order is not overfilled - // NOTE: This assertion should never fail, it is here - // as an extra defence against potential bugs. - require( - safeAdd(orderInfo.orderTakerAssetFilledAmount, takerAssetFilledAmount) <= order.takerAssetAmount, - "ORDER_OVERFILL" - ); - - // Make sure order is filled at acceptable price. - // The order has an implied price from the makers perspective: - // order price = order.makerAssetAmount / order.takerAssetAmount - // i.e. the number of makerAsset maker is paying per takerAsset. The - // maker is guaranteed to get this price or a better (lower) one. The - // actual price maker is getting in this fill is: - // fill price = makerAssetFilledAmount / takerAssetFilledAmount - // We need `fill price <= order price` for the fill to be fair to maker. - // This amounts to: - // makerAssetFilledAmount order.makerAssetAmount - // ------------------------ <= ----------------------- - // takerAssetFilledAmount order.takerAssetAmount - // or, equivalently: - // makerAssetFilledAmount * order.takerAssetAmount <= - // order.makerAssetAmount * takerAssetFilledAmount - // NOTE: This assertion should never fail, it is here - // as an extra defence against potential bugs. - require( - safeMul(makerAssetFilledAmount, order.takerAssetAmount) - <= - safeMul(order.makerAssetAmount, takerAssetFilledAmount), - "INVALID_FILL_PRICE" - ); - } - - /// @dev Validates context for cancelOrder. Succeeds or throws. - /// @param order to be cancelled. - /// @param orderInfo OrderStatus, orderHash, and amount already filled of order. - function assertValidCancel( - Order memory order, - OrderInfo memory orderInfo - ) - internal - view - { - // Ensure order is valid - // An order can only be cancelled if its status is FILLABLE. - require( - orderInfo.orderStatus == uint8(OrderStatus.FILLABLE), - "ORDER_UNFILLABLE" - ); - - // Validate sender is allowed to cancel this order - if (order.senderAddress != address(0)) { - require( - order.senderAddress == msg.sender, - "INVALID_SENDER" - ); - } - - // Validate transaction signed by maker - address makerAddress = getCurrentContextAddress(); - require( - order.makerAddress == makerAddress, - "INVALID_MAKER" - ); - } - - /// @dev Calculates amounts filled and fees paid by maker and taker. - /// @param order to be filled. - /// @param takerAssetFilledAmount Amount of takerAsset that will be filled. - /// @return fillResults Amounts filled and fees paid by maker and taker. - function calculateFillResults( - Order memory order, - uint256 takerAssetFilledAmount - ) - internal - pure - returns (FillResults memory fillResults) - { - // Compute proportional transfer amounts - fillResults.takerAssetFilledAmount = takerAssetFilledAmount; - fillResults.makerAssetFilledAmount = safeGetPartialAmountFloor( - takerAssetFilledAmount, - order.takerAssetAmount, - order.makerAssetAmount - ); - fillResults.makerFeePaid = safeGetPartialAmountFloor( - fillResults.makerAssetFilledAmount, - order.makerAssetAmount, - order.makerFee - ); - fillResults.takerFeePaid = safeGetPartialAmountFloor( - takerAssetFilledAmount, - order.takerAssetAmount, - order.takerFee - ); - - return fillResults; - } - - /// @dev Settles an order by transferring assets between counterparties. - /// @param order Order struct containing order specifications. - /// @param takerAddress Address selling takerAsset and buying makerAsset. - /// @param fillResults Amounts to be filled and fees paid by maker and taker. - function settleOrder( - LibOrder.Order memory order, - address takerAddress, - LibFillResults.FillResults memory fillResults - ) - private - { - bytes memory zrxAssetData = ZRX_ASSET_DATA; - dispatchTransferFrom( - order.makerAssetData, - order.makerAddress, - takerAddress, - fillResults.makerAssetFilledAmount - ); - dispatchTransferFrom( - order.takerAssetData, - takerAddress, - order.makerAddress, - fillResults.takerAssetFilledAmount - ); - dispatchTransferFrom( - zrxAssetData, - order.makerAddress, - order.feeRecipientAddress, - fillResults.makerFeePaid - ); - dispatchTransferFrom( - zrxAssetData, - takerAddress, - order.feeRecipientAddress, - fillResults.takerFeePaid - ); - } -} diff --git a/packages/contracts/contracts/protocol/Exchange/MixinMatchOrders.sol b/packages/contracts/contracts/protocol/Exchange/MixinMatchOrders.sol deleted file mode 100644 index b4f6bdb26..000000000 --- a/packages/contracts/contracts/protocol/Exchange/MixinMatchOrders.sol +++ /dev/null @@ -1,335 +0,0 @@ -/* - Copyright 2018 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.24; -pragma experimental ABIEncoderV2; - -import "../../utils/ReentrancyGuard/ReentrancyGuard.sol"; -import "./libs/LibConstants.sol"; -import "./libs/LibMath.sol"; -import "./libs/LibOrder.sol"; -import "./libs/LibFillResults.sol"; -import "./mixins/MExchangeCore.sol"; -import "./mixins/MMatchOrders.sol"; -import "./mixins/MTransactions.sol"; -import "./mixins/MAssetProxyDispatcher.sol"; - - -contract MixinMatchOrders is - ReentrancyGuard, - LibConstants, - LibMath, - MAssetProxyDispatcher, - MExchangeCore, - MMatchOrders, - MTransactions -{ - /// @dev Match two complementary orders that have a profitable spread. - /// Each order is filled at their respective price point. However, the calculations are - /// carried out as though the orders are both being filled at the right order's price point. - /// The profit made by the left order goes to the taker (who matched the two orders). - /// @param leftOrder First order to match. - /// @param rightOrder Second order to match. - /// @param leftSignature Proof that order was created by the left maker. - /// @param rightSignature Proof that order was created by the right maker. - /// @return matchedFillResults Amounts filled and fees paid by maker and taker of matched orders. - function matchOrders( - LibOrder.Order memory leftOrder, - LibOrder.Order memory rightOrder, - bytes memory leftSignature, - bytes memory rightSignature - ) - public - nonReentrant - returns (LibFillResults.MatchedFillResults memory matchedFillResults) - { - // We assume that rightOrder.takerAssetData == leftOrder.makerAssetData and rightOrder.makerAssetData == leftOrder.takerAssetData. - // If this assumption isn't true, the match will fail at signature validation. - rightOrder.makerAssetData = leftOrder.takerAssetData; - rightOrder.takerAssetData = leftOrder.makerAssetData; - - // Get left & right order info - LibOrder.OrderInfo memory leftOrderInfo = getOrderInfo(leftOrder); - LibOrder.OrderInfo memory rightOrderInfo = getOrderInfo(rightOrder); - - // Fetch taker address - address takerAddress = getCurrentContextAddress(); - - // Either our context is valid or we revert - assertFillableOrder( - leftOrder, - leftOrderInfo, - takerAddress, - leftSignature - ); - assertFillableOrder( - rightOrder, - rightOrderInfo, - takerAddress, - rightSignature - ); - assertValidMatch(leftOrder, rightOrder); - - // Compute proportional fill amounts - matchedFillResults = calculateMatchedFillResults( - leftOrder, - rightOrder, - leftOrderInfo.orderTakerAssetFilledAmount, - rightOrderInfo.orderTakerAssetFilledAmount - ); - - // Validate fill contexts - assertValidFill( - leftOrder, - leftOrderInfo, - matchedFillResults.left.takerAssetFilledAmount, - matchedFillResults.left.takerAssetFilledAmount, - matchedFillResults.left.makerAssetFilledAmount - ); - assertValidFill( - rightOrder, - rightOrderInfo, - matchedFillResults.right.takerAssetFilledAmount, - matchedFillResults.right.takerAssetFilledAmount, - matchedFillResults.right.makerAssetFilledAmount - ); - - // Update exchange state - updateFilledState( - leftOrder, - takerAddress, - leftOrderInfo.orderHash, - leftOrderInfo.orderTakerAssetFilledAmount, - matchedFillResults.left - ); - updateFilledState( - rightOrder, - takerAddress, - rightOrderInfo.orderHash, - rightOrderInfo.orderTakerAssetFilledAmount, - matchedFillResults.right - ); - - // Settle matched orders. Succeeds or throws. - settleMatchedOrders( - leftOrder, - rightOrder, - takerAddress, - matchedFillResults - ); - - return matchedFillResults; - } - - /// @dev Validates context for matchOrders. Succeeds or throws. - /// @param leftOrder First order to match. - /// @param rightOrder Second order to match. - function assertValidMatch( - LibOrder.Order memory leftOrder, - LibOrder.Order memory rightOrder - ) - internal - pure - { - // Make sure there is a profitable spread. - // There is a profitable spread iff the cost per unit bought (OrderA.MakerAmount/OrderA.TakerAmount) for each order is greater - // than the profit per unit sold of the matched order (OrderB.TakerAmount/OrderB.MakerAmount). - // This is satisfied by the equations below: - // <leftOrder.makerAssetAmount> / <leftOrder.takerAssetAmount> >= <rightOrder.takerAssetAmount> / <rightOrder.makerAssetAmount> - // AND - // <rightOrder.makerAssetAmount> / <rightOrder.takerAssetAmount> >= <leftOrder.takerAssetAmount> / <leftOrder.makerAssetAmount> - // These equations can be combined to get the following: - require( - safeMul(leftOrder.makerAssetAmount, rightOrder.makerAssetAmount) >= - safeMul(leftOrder.takerAssetAmount, rightOrder.takerAssetAmount), - "NEGATIVE_SPREAD_REQUIRED" - ); - } - - /// @dev Calculates fill amounts for the matched orders. - /// Each order is filled at their respective price point. However, the calculations are - /// carried out as though the orders are both being filled at the right order's price point. - /// The profit made by the leftOrder order goes to the taker (who matched the two orders). - /// @param leftOrder First order to match. - /// @param rightOrder Second order to match. - /// @param leftOrderTakerAssetFilledAmount Amount of left order already filled. - /// @param rightOrderTakerAssetFilledAmount Amount of right order already filled. - /// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders. - function calculateMatchedFillResults( - LibOrder.Order memory leftOrder, - LibOrder.Order memory rightOrder, - uint256 leftOrderTakerAssetFilledAmount, - uint256 rightOrderTakerAssetFilledAmount - ) - internal - pure - returns (LibFillResults.MatchedFillResults memory matchedFillResults) - { - // Derive maker asset amounts for left & right orders, given store taker assert amounts - uint256 leftTakerAssetAmountRemaining = safeSub(leftOrder.takerAssetAmount, leftOrderTakerAssetFilledAmount); - uint256 leftMakerAssetAmountRemaining = safeGetPartialAmountFloor( - leftOrder.makerAssetAmount, - leftOrder.takerAssetAmount, - leftTakerAssetAmountRemaining - ); - uint256 rightTakerAssetAmountRemaining = safeSub(rightOrder.takerAssetAmount, rightOrderTakerAssetFilledAmount); - uint256 rightMakerAssetAmountRemaining = safeGetPartialAmountFloor( - rightOrder.makerAssetAmount, - rightOrder.takerAssetAmount, - rightTakerAssetAmountRemaining - ); - - // Calculate fill results for maker and taker assets: at least one order will be fully filled. - // The maximum amount the left maker can buy is `leftTakerAssetAmountRemaining` - // The maximum amount the right maker can sell is `rightMakerAssetAmountRemaining` - // We have two distinct cases for calculating the fill results: - // Case 1. - // If the left maker can buy more than the right maker can sell, then only the right order is fully filled. - // If the left maker can buy exactly what the right maker can sell, then both orders are fully filled. - // Case 2. - // If the left maker cannot buy more than the right maker can sell, then only the left order is fully filled. - if (leftTakerAssetAmountRemaining >= rightMakerAssetAmountRemaining) { - // Case 1: Right order is fully filled - matchedFillResults.right.makerAssetFilledAmount = rightMakerAssetAmountRemaining; - matchedFillResults.right.takerAssetFilledAmount = rightTakerAssetAmountRemaining; - matchedFillResults.left.takerAssetFilledAmount = matchedFillResults.right.makerAssetFilledAmount; - // Round down to ensure the maker's exchange rate does not exceed the price specified by the order. - // We favor the maker when the exchange rate must be rounded. - matchedFillResults.left.makerAssetFilledAmount = safeGetPartialAmountFloor( - leftOrder.makerAssetAmount, - leftOrder.takerAssetAmount, - matchedFillResults.left.takerAssetFilledAmount - ); - } else { - // Case 2: Left order is fully filled - matchedFillResults.left.makerAssetFilledAmount = leftMakerAssetAmountRemaining; - matchedFillResults.left.takerAssetFilledAmount = leftTakerAssetAmountRemaining; - matchedFillResults.right.makerAssetFilledAmount = matchedFillResults.left.takerAssetFilledAmount; - // Round up to ensure the maker's exchange rate does not exceed the price specified by the order. - // We favor the maker when the exchange rate must be rounded. - matchedFillResults.right.takerAssetFilledAmount = safeGetPartialAmountCeil( - rightOrder.takerAssetAmount, - rightOrder.makerAssetAmount, - matchedFillResults.right.makerAssetFilledAmount - ); - } - - // Calculate amount given to taker - matchedFillResults.leftMakerAssetSpreadAmount = safeSub( - matchedFillResults.left.makerAssetFilledAmount, - matchedFillResults.right.takerAssetFilledAmount - ); - - // Compute fees for left order - matchedFillResults.left.makerFeePaid = safeGetPartialAmountFloor( - matchedFillResults.left.makerAssetFilledAmount, - leftOrder.makerAssetAmount, - leftOrder.makerFee - ); - matchedFillResults.left.takerFeePaid = safeGetPartialAmountFloor( - matchedFillResults.left.takerAssetFilledAmount, - leftOrder.takerAssetAmount, - leftOrder.takerFee - ); - - // Compute fees for right order - matchedFillResults.right.makerFeePaid = safeGetPartialAmountFloor( - matchedFillResults.right.makerAssetFilledAmount, - rightOrder.makerAssetAmount, - rightOrder.makerFee - ); - matchedFillResults.right.takerFeePaid = safeGetPartialAmountFloor( - matchedFillResults.right.takerAssetFilledAmount, - rightOrder.takerAssetAmount, - rightOrder.takerFee - ); - - // Return fill results - return matchedFillResults; - } - - /// @dev Settles matched order by transferring appropriate funds between order makers, taker, and fee recipient. - /// @param leftOrder First matched order. - /// @param rightOrder Second matched order. - /// @param takerAddress Address that matched the orders. The taker receives the spread between orders as profit. - /// @param matchedFillResults Struct holding amounts to transfer between makers, taker, and fee recipients. - function settleMatchedOrders( - LibOrder.Order memory leftOrder, - LibOrder.Order memory rightOrder, - address takerAddress, - LibFillResults.MatchedFillResults memory matchedFillResults - ) - private - { - bytes memory zrxAssetData = ZRX_ASSET_DATA; - // Order makers and taker - dispatchTransferFrom( - leftOrder.makerAssetData, - leftOrder.makerAddress, - rightOrder.makerAddress, - matchedFillResults.right.takerAssetFilledAmount - ); - dispatchTransferFrom( - rightOrder.makerAssetData, - rightOrder.makerAddress, - leftOrder.makerAddress, - matchedFillResults.left.takerAssetFilledAmount - ); - dispatchTransferFrom( - leftOrder.makerAssetData, - leftOrder.makerAddress, - takerAddress, - matchedFillResults.leftMakerAssetSpreadAmount - ); - - // Maker fees - dispatchTransferFrom( - zrxAssetData, - leftOrder.makerAddress, - leftOrder.feeRecipientAddress, - matchedFillResults.left.makerFeePaid - ); - dispatchTransferFrom( - zrxAssetData, - rightOrder.makerAddress, - rightOrder.feeRecipientAddress, - matchedFillResults.right.makerFeePaid - ); - - // Taker fees - if (leftOrder.feeRecipientAddress == rightOrder.feeRecipientAddress) { - dispatchTransferFrom( - zrxAssetData, - takerAddress, - leftOrder.feeRecipientAddress, - safeAdd( - matchedFillResults.left.takerFeePaid, - matchedFillResults.right.takerFeePaid - ) - ); - } else { - dispatchTransferFrom( - zrxAssetData, - takerAddress, - leftOrder.feeRecipientAddress, - matchedFillResults.left.takerFeePaid - ); - dispatchTransferFrom( - zrxAssetData, - takerAddress, - rightOrder.feeRecipientAddress, - matchedFillResults.right.takerFeePaid - ); - } - } -} diff --git a/packages/contracts/contracts/protocol/Exchange/MixinSignatureValidator.sol b/packages/contracts/contracts/protocol/Exchange/MixinSignatureValidator.sol deleted file mode 100644 index 176e28351..000000000 --- a/packages/contracts/contracts/protocol/Exchange/MixinSignatureValidator.sol +++ /dev/null @@ -1,324 +0,0 @@ -/* - - Copyright 2018 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.24; - -import "../../utils/LibBytes/LibBytes.sol"; -import "../../utils/ReentrancyGuard/ReentrancyGuard.sol"; -import "./mixins/MSignatureValidator.sol"; -import "./mixins/MTransactions.sol"; -import "./interfaces/IWallet.sol"; -import "./interfaces/IValidator.sol"; - - -contract MixinSignatureValidator is - ReentrancyGuard, - MSignatureValidator, - MTransactions -{ - using LibBytes for bytes; - - // Mapping of hash => signer => signed - mapping (bytes32 => mapping (address => bool)) public preSigned; - - // Mapping of signer => validator => approved - mapping (address => mapping (address => bool)) public allowedValidators; - - /// @dev Approves a hash on-chain using any valid signature type. - /// After presigning a hash, the preSign signature type will become valid for that hash and signer. - /// @param signerAddress Address that should have signed the given hash. - /// @param signature Proof that the hash has been signed by signer. - function preSign( - bytes32 hash, - address signerAddress, - bytes signature - ) - external - { - if (signerAddress != msg.sender) { - require( - isValidSignature( - hash, - signerAddress, - signature - ), - "INVALID_SIGNATURE" - ); - } - preSigned[hash][signerAddress] = true; - } - - /// @dev Approves/unnapproves a Validator contract to verify signatures on signer's behalf. - /// @param validatorAddress Address of Validator contract. - /// @param approval Approval or disapproval of Validator contract. - function setSignatureValidatorApproval( - address validatorAddress, - bool approval - ) - external - nonReentrant - { - address signerAddress = getCurrentContextAddress(); - allowedValidators[signerAddress][validatorAddress] = approval; - emit SignatureValidatorApproval( - signerAddress, - validatorAddress, - approval - ); - } - - /// @dev Verifies that a hash has been signed by the given signer. - /// @param hash Any 32 byte hash. - /// @param signerAddress Address that should have signed the given hash. - /// @param signature Proof that the hash has been signed by signer. - /// @return True if the address recovered from the provided signature matches the input signer address. - function isValidSignature( - bytes32 hash, - address signerAddress, - bytes memory signature - ) - public - view - returns (bool isValid) - { - require( - signature.length > 0, - "LENGTH_GREATER_THAN_0_REQUIRED" - ); - - // Pop last byte off of signature byte array. - uint8 signatureTypeRaw = uint8(signature.popLastByte()); - - // Ensure signature is supported - require( - signatureTypeRaw < uint8(SignatureType.NSignatureTypes), - "SIGNATURE_UNSUPPORTED" - ); - - SignatureType signatureType = SignatureType(signatureTypeRaw); - - // Variables are not scoped in Solidity. - uint8 v; - bytes32 r; - bytes32 s; - address recovered; - - // Always illegal signature. - // This is always an implicit option since a signer can create a - // signature array with invalid type or length. We may as well make - // it an explicit option. This aids testing and analysis. It is - // also the initialization value for the enum type. - if (signatureType == SignatureType.Illegal) { - revert("SIGNATURE_ILLEGAL"); - - // Always invalid signature. - // Like Illegal, this is always implicitly available and therefore - // offered explicitly. It can be implicitly created by providing - // a correctly formatted but incorrect signature. - } else if (signatureType == SignatureType.Invalid) { - require( - signature.length == 0, - "LENGTH_0_REQUIRED" - ); - isValid = false; - return isValid; - - // Signature using EIP712 - } else if (signatureType == SignatureType.EIP712) { - require( - signature.length == 65, - "LENGTH_65_REQUIRED" - ); - v = uint8(signature[0]); - r = signature.readBytes32(1); - s = signature.readBytes32(33); - recovered = ecrecover( - hash, - v, - r, - s - ); - isValid = signerAddress == recovered; - return isValid; - - // Signed using web3.eth_sign - } else if (signatureType == SignatureType.EthSign) { - require( - signature.length == 65, - "LENGTH_65_REQUIRED" - ); - v = uint8(signature[0]); - r = signature.readBytes32(1); - s = signature.readBytes32(33); - recovered = ecrecover( - keccak256(abi.encodePacked( - "\x19Ethereum Signed Message:\n32", - hash - )), - v, - r, - s - ); - isValid = signerAddress == recovered; - return isValid; - - // Signature verified by wallet contract. - // If used with an order, the maker of the order is the wallet contract. - } else if (signatureType == SignatureType.Wallet) { - isValid = isValidWalletSignature( - hash, - signerAddress, - signature - ); - return isValid; - - // Signature verified by validator contract. - // If used with an order, the maker of the order can still be an EOA. - // A signature using this type should be encoded as: - // | Offset | Length | Contents | - // | 0x00 | x | Signature to validate | - // | 0x00 + x | 20 | Address of validator contract | - // | 0x14 + x | 1 | Signature type is always "\x06" | - } else if (signatureType == SignatureType.Validator) { - // Pop last 20 bytes off of signature byte array. - address validatorAddress = signature.popLast20Bytes(); - - // Ensure signer has approved validator. - if (!allowedValidators[signerAddress][validatorAddress]) { - return false; - } - isValid = isValidValidatorSignature( - validatorAddress, - hash, - signerAddress, - signature - ); - return isValid; - - // Signer signed hash previously using the preSign function. - } else if (signatureType == SignatureType.PreSigned) { - isValid = preSigned[hash][signerAddress]; - return isValid; - } - - // Anything else is illegal (We do not return false because - // the signature may actually be valid, just not in a format - // that we currently support. In this case returning false - // may lead the caller to incorrectly believe that the - // signature was invalid.) - revert("SIGNATURE_UNSUPPORTED"); - } - - /// @dev Verifies signature using logic defined by Wallet contract. - /// @param hash Any 32 byte hash. - /// @param walletAddress Address that should have signed the given hash - /// and defines its own signature verification method. - /// @param signature Proof that the hash has been signed by signer. - /// @return True if signature is valid for given wallet.. - function isValidWalletSignature( - bytes32 hash, - address walletAddress, - bytes signature - ) - internal - view - returns (bool isValid) - { - bytes memory calldata = abi.encodeWithSelector( - IWallet(walletAddress).isValidSignature.selector, - hash, - signature - ); - assembly { - let cdStart := add(calldata, 32) - let success := staticcall( - gas, // forward all gas - walletAddress, // address of Wallet contract - cdStart, // pointer to start of input - mload(calldata), // length of input - cdStart, // write output over input - 32 // output size is 32 bytes - ) - - switch success - case 0 { - // Revert with `Error("WALLET_ERROR")` - mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) - mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000) - mstore(64, 0x0000000c57414c4c45545f4552524f5200000000000000000000000000000000) - mstore(96, 0) - revert(0, 100) - } - case 1 { - // Signature is valid if call did not revert and returned true - isValid := mload(cdStart) - } - } - return isValid; - } - - /// @dev Verifies signature using logic defined by Validator contract. - /// @param validatorAddress Address of validator contract. - /// @param hash Any 32 byte hash. - /// @param signerAddress Address that should have signed the given hash. - /// @param signature Proof that the hash has been signed by signer. - /// @return True if the address recovered from the provided signature matches the input signer address. - function isValidValidatorSignature( - address validatorAddress, - bytes32 hash, - address signerAddress, - bytes signature - ) - internal - view - returns (bool isValid) - { - bytes memory calldata = abi.encodeWithSelector( - IValidator(signerAddress).isValidSignature.selector, - hash, - signerAddress, - signature - ); - assembly { - let cdStart := add(calldata, 32) - let success := staticcall( - gas, // forward all gas - validatorAddress, // address of Validator contract - cdStart, // pointer to start of input - mload(calldata), // length of input - cdStart, // write output over input - 32 // output size is 32 bytes - ) - - switch success - case 0 { - // Revert with `Error("VALIDATOR_ERROR")` - mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000) - mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000) - mstore(64, 0x0000000f56414c494441544f525f4552524f5200000000000000000000000000) - mstore(96, 0) - revert(0, 100) - } - case 1 { - // Signature is valid if call did not revert and returned true - isValid := mload(cdStart) - } - } - return isValid; - } -} diff --git a/packages/contracts/contracts/protocol/Exchange/MixinTransactions.sol b/packages/contracts/contracts/protocol/Exchange/MixinTransactions.sol deleted file mode 100644 index 3a76ca202..000000000 --- a/packages/contracts/contracts/protocol/Exchange/MixinTransactions.sol +++ /dev/null @@ -1,152 +0,0 @@ -/* - - Copyright 2018 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.24; - -import "./libs/LibExchangeErrors.sol"; -import "./mixins/MSignatureValidator.sol"; -import "./mixins/MTransactions.sol"; -import "./libs/LibEIP712.sol"; - - -contract MixinTransactions is - LibEIP712, - MSignatureValidator, - MTransactions -{ - // Mapping of transaction hash => executed - // This prevents transactions from being executed more than once. - mapping (bytes32 => bool) public transactions; - - // Address of current transaction signer - address public currentContextAddress; - - /// @dev Executes an exchange method call in the context of signer. - /// @param salt Arbitrary number to ensure uniqueness of transaction hash. - /// @param signerAddress Address of transaction signer. - /// @param data AbiV2 encoded calldata. - /// @param signature Proof of signer transaction by signer. - function executeTransaction( - uint256 salt, - address signerAddress, - bytes data, - bytes signature - ) - external - { - // Prevent reentrancy - require( - currentContextAddress == address(0), - "REENTRANCY_ILLEGAL" - ); - - bytes32 transactionHash = hashEIP712Message(hashZeroExTransaction( - salt, - signerAddress, - data - )); - - // Validate transaction has not been executed - require( - !transactions[transactionHash], - "INVALID_TX_HASH" - ); - - // Transaction always valid if signer is sender of transaction - if (signerAddress != msg.sender) { - // Validate signature - require( - isValidSignature( - transactionHash, - signerAddress, - signature - ), - "INVALID_TX_SIGNATURE" - ); - - // Set the current transaction signer - currentContextAddress = signerAddress; - } - - // Execute transaction - transactions[transactionHash] = true; - require( - address(this).delegatecall(data), - "FAILED_EXECUTION" - ); - - // Reset current transaction signer if it was previously updated - if (signerAddress != msg.sender) { - currentContextAddress = address(0); - } - } - - /// @dev Calculates EIP712 hash of the Transaction. - /// @param salt Arbitrary number to ensure uniqueness of transaction hash. - /// @param signerAddress Address of transaction signer. - /// @param data AbiV2 encoded calldata. - /// @return EIP712 hash of the Transaction. - function hashZeroExTransaction( - uint256 salt, - address signerAddress, - bytes memory data - ) - internal - pure - returns (bytes32 result) - { - bytes32 schemaHash = EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH; - bytes32 dataHash = keccak256(data); - - // Assembly for more efficiently computing: - // keccak256(abi.encodePacked( - // EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH, - // salt, - // bytes32(signerAddress), - // keccak256(data) - // )); - - assembly { - // Load free memory pointer - let memPtr := mload(64) - - mstore(memPtr, schemaHash) // hash of schema - mstore(add(memPtr, 32), salt) // salt - mstore(add(memPtr, 64), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff)) // signerAddress - mstore(add(memPtr, 96), dataHash) // hash of data - - // Compute hash - result := keccak256(memPtr, 128) - } - return result; - } - - /// @dev The current function will be called in the context of this address (either 0x transaction signer or `msg.sender`). - /// If calling a fill function, this address will represent the taker. - /// If calling a cancel function, this address will represent the maker. - /// @return Signer of 0x transaction if entry point is `executeTransaction`. - /// `msg.sender` if entry point is any other function. - function getCurrentContextAddress() - internal - view - returns (address) - { - address currentContextAddress_ = currentContextAddress; - address contextAddress = currentContextAddress_ == address(0) ? msg.sender : currentContextAddress_; - return contextAddress; - } -} diff --git a/packages/contracts/contracts/protocol/Exchange/MixinWrapperFunctions.sol b/packages/contracts/contracts/protocol/Exchange/MixinWrapperFunctions.sol deleted file mode 100644 index cddff0e5f..000000000 --- a/packages/contracts/contracts/protocol/Exchange/MixinWrapperFunctions.sol +++ /dev/null @@ -1,426 +0,0 @@ -/* - - Copyright 2018 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.24; -pragma experimental ABIEncoderV2; - -import "../../utils/ReentrancyGuard/ReentrancyGuard.sol"; -import "./libs/LibMath.sol"; -import "./libs/LibOrder.sol"; -import "./libs/LibFillResults.sol"; -import "./libs/LibAbiEncoder.sol"; -import "./mixins/MExchangeCore.sol"; -import "./mixins/MWrapperFunctions.sol"; - - -contract MixinWrapperFunctions is - ReentrancyGuard, - LibMath, - LibFillResults, - LibAbiEncoder, - MExchangeCore, - MWrapperFunctions -{ - /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled. - /// @param order Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signature Proof that order has been created by maker. - function fillOrKillOrder( - LibOrder.Order memory order, - uint256 takerAssetFillAmount, - bytes memory signature - ) - public - nonReentrant - returns (FillResults memory fillResults) - { - fillResults = fillOrKillOrderInternal( - order, - takerAssetFillAmount, - signature - ); - return fillResults; - } - - /// @dev Fills the input order. - /// Returns false if the transaction would otherwise revert. - /// @param order Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signature Proof that order has been created by maker. - /// @return Amounts filled and fees paid by maker and taker. - function fillOrderNoThrow( - LibOrder.Order memory order, - uint256 takerAssetFillAmount, - bytes memory signature - ) - public - returns (FillResults memory fillResults) - { - // ABI encode calldata for `fillOrder` - bytes memory fillOrderCalldata = abiEncodeFillOrder( - order, - takerAssetFillAmount, - signature - ); - - // Delegate to `fillOrder` and handle any exceptions gracefully - assembly { - let success := delegatecall( - gas, // forward all gas - address, // call address of this contract - add(fillOrderCalldata, 32), // pointer to start of input (skip array length in first 32 bytes) - mload(fillOrderCalldata), // length of input - fillOrderCalldata, // write output over input - 128 // output size is 128 bytes - ) - if success { - mstore(fillResults, mload(fillOrderCalldata)) - mstore(add(fillResults, 32), mload(add(fillOrderCalldata, 32))) - mstore(add(fillResults, 64), mload(add(fillOrderCalldata, 64))) - mstore(add(fillResults, 96), mload(add(fillOrderCalldata, 96))) - } - } - // fillResults values will be 0 by default if call was unsuccessful - return fillResults; - } - - /// @dev Synchronously executes multiple calls of fillOrder. - /// @param orders Array of order specifications. - /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders. - /// @param signatures Proofs that orders have been created by makers. - /// @return Amounts filled and fees paid by makers and taker. - /// NOTE: makerAssetFilledAmount and takerAssetFilledAmount may include amounts filled of different assets. - function batchFillOrders( - LibOrder.Order[] memory orders, - uint256[] memory takerAssetFillAmounts, - bytes[] memory signatures - ) - public - nonReentrant - returns (FillResults memory totalFillResults) - { - uint256 ordersLength = orders.length; - for (uint256 i = 0; i != ordersLength; i++) { - FillResults memory singleFillResults = fillOrderInternal( - orders[i], - takerAssetFillAmounts[i], - signatures[i] - ); - addFillResults(totalFillResults, singleFillResults); - } - return totalFillResults; - } - - /// @dev Synchronously executes multiple calls of fillOrKill. - /// @param orders Array of order specifications. - /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders. - /// @param signatures Proofs that orders have been created by makers. - /// @return Amounts filled and fees paid by makers and taker. - /// NOTE: makerAssetFilledAmount and takerAssetFilledAmount may include amounts filled of different assets. - function batchFillOrKillOrders( - LibOrder.Order[] memory orders, - uint256[] memory takerAssetFillAmounts, - bytes[] memory signatures - ) - public - nonReentrant - returns (FillResults memory totalFillResults) - { - uint256 ordersLength = orders.length; - for (uint256 i = 0; i != ordersLength; i++) { - FillResults memory singleFillResults = fillOrKillOrderInternal( - orders[i], - takerAssetFillAmounts[i], - signatures[i] - ); - addFillResults(totalFillResults, singleFillResults); - } - return totalFillResults; - } - - /// @dev Fills an order with specified parameters and ECDSA signature. - /// Returns false if the transaction would otherwise revert. - /// @param orders Array of order specifications. - /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders. - /// @param signatures Proofs that orders have been created by makers. - /// @return Amounts filled and fees paid by makers and taker. - /// NOTE: makerAssetFilledAmount and takerAssetFilledAmount may include amounts filled of different assets. - function batchFillOrdersNoThrow( - LibOrder.Order[] memory orders, - uint256[] memory takerAssetFillAmounts, - bytes[] memory signatures - ) - public - returns (FillResults memory totalFillResults) - { - uint256 ordersLength = orders.length; - for (uint256 i = 0; i != ordersLength; i++) { - FillResults memory singleFillResults = fillOrderNoThrow( - orders[i], - takerAssetFillAmounts[i], - signatures[i] - ); - addFillResults(totalFillResults, singleFillResults); - } - return totalFillResults; - } - - /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker. - /// @param orders Array of order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signatures Proofs that orders have been created by makers. - /// @return Amounts filled and fees paid by makers and taker. - function marketSellOrders( - LibOrder.Order[] memory orders, - uint256 takerAssetFillAmount, - bytes[] memory signatures - ) - public - nonReentrant - returns (FillResults memory totalFillResults) - { - bytes memory takerAssetData = orders[0].takerAssetData; - - uint256 ordersLength = orders.length; - for (uint256 i = 0; i != ordersLength; i++) { - - // We assume that asset being sold by taker is the same for each order. - // Rather than passing this in as calldata, we use the takerAssetData from the first order in all later orders. - orders[i].takerAssetData = takerAssetData; - - // Calculate the remaining amount of takerAsset to sell - uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount); - - // Attempt to sell the remaining amount of takerAsset - FillResults memory singleFillResults = fillOrderInternal( - orders[i], - remainingTakerAssetFillAmount, - signatures[i] - ); - - // Update amounts filled and fees paid by maker and taker - addFillResults(totalFillResults, singleFillResults); - - // Stop execution if the entire amount of takerAsset has been sold - if (totalFillResults.takerAssetFilledAmount >= takerAssetFillAmount) { - break; - } - } - return totalFillResults; - } - - /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker. - /// Returns false if the transaction would otherwise revert. - /// @param orders Array of order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signatures Proofs that orders have been signed by makers. - /// @return Amounts filled and fees paid by makers and taker. - function marketSellOrdersNoThrow( - LibOrder.Order[] memory orders, - uint256 takerAssetFillAmount, - bytes[] memory signatures - ) - public - returns (FillResults memory totalFillResults) - { - bytes memory takerAssetData = orders[0].takerAssetData; - - uint256 ordersLength = orders.length; - for (uint256 i = 0; i != ordersLength; i++) { - - // We assume that asset being sold by taker is the same for each order. - // Rather than passing this in as calldata, we use the takerAssetData from the first order in all later orders. - orders[i].takerAssetData = takerAssetData; - - // Calculate the remaining amount of takerAsset to sell - uint256 remainingTakerAssetFillAmount = safeSub(takerAssetFillAmount, totalFillResults.takerAssetFilledAmount); - - // Attempt to sell the remaining amount of takerAsset - FillResults memory singleFillResults = fillOrderNoThrow( - orders[i], - remainingTakerAssetFillAmount, - signatures[i] - ); - - // Update amounts filled and fees paid by maker and taker - addFillResults(totalFillResults, singleFillResults); - - // Stop execution if the entire amount of takerAsset has been sold - if (totalFillResults.takerAssetFilledAmount >= takerAssetFillAmount) { - break; - } - } - return totalFillResults; - } - - /// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker. - /// @param orders Array of order specifications. - /// @param makerAssetFillAmount Desired amount of makerAsset to buy. - /// @param signatures Proofs that orders have been signed by makers. - /// @return Amounts filled and fees paid by makers and taker. - function marketBuyOrders( - LibOrder.Order[] memory orders, - uint256 makerAssetFillAmount, - bytes[] memory signatures - ) - public - nonReentrant - returns (FillResults memory totalFillResults) - { - bytes memory makerAssetData = orders[0].makerAssetData; - - uint256 ordersLength = orders.length; - for (uint256 i = 0; i != ordersLength; i++) { - - // We assume that asset being bought by taker is the same for each order. - // Rather than passing this in as calldata, we copy the makerAssetData from the first order onto all later orders. - orders[i].makerAssetData = makerAssetData; - - // Calculate the remaining amount of makerAsset to buy - uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount); - - // Convert the remaining amount of makerAsset to buy into remaining amount - // of takerAsset to sell, assuming entire amount can be sold in the current order - uint256 remainingTakerAssetFillAmount = getPartialAmountFloor( - orders[i].takerAssetAmount, - orders[i].makerAssetAmount, - remainingMakerAssetFillAmount - ); - - // Attempt to sell the remaining amount of takerAsset - FillResults memory singleFillResults = fillOrderInternal( - orders[i], - remainingTakerAssetFillAmount, - signatures[i] - ); - - // Update amounts filled and fees paid by maker and taker - addFillResults(totalFillResults, singleFillResults); - - // Stop execution if the entire amount of makerAsset has been bought - if (totalFillResults.makerAssetFilledAmount >= makerAssetFillAmount) { - break; - } - } - return totalFillResults; - } - - /// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker. - /// Returns false if the transaction would otherwise revert. - /// @param orders Array of order specifications. - /// @param makerAssetFillAmount Desired amount of makerAsset to buy. - /// @param signatures Proofs that orders have been signed by makers. - /// @return Amounts filled and fees paid by makers and taker. - function marketBuyOrdersNoThrow( - LibOrder.Order[] memory orders, - uint256 makerAssetFillAmount, - bytes[] memory signatures - ) - public - returns (FillResults memory totalFillResults) - { - bytes memory makerAssetData = orders[0].makerAssetData; - - uint256 ordersLength = orders.length; - for (uint256 i = 0; i != ordersLength; i++) { - - // We assume that asset being bought by taker is the same for each order. - // Rather than passing this in as calldata, we copy the makerAssetData from the first order onto all later orders. - orders[i].makerAssetData = makerAssetData; - - // Calculate the remaining amount of makerAsset to buy - uint256 remainingMakerAssetFillAmount = safeSub(makerAssetFillAmount, totalFillResults.makerAssetFilledAmount); - - // Convert the remaining amount of makerAsset to buy into remaining amount - // of takerAsset to sell, assuming entire amount can be sold in the current order - uint256 remainingTakerAssetFillAmount = getPartialAmountFloor( - orders[i].takerAssetAmount, - orders[i].makerAssetAmount, - remainingMakerAssetFillAmount - ); - - // Attempt to sell the remaining amount of takerAsset - FillResults memory singleFillResults = fillOrderNoThrow( - orders[i], - remainingTakerAssetFillAmount, - signatures[i] - ); - - // Update amounts filled and fees paid by maker and taker - addFillResults(totalFillResults, singleFillResults); - - // Stop execution if the entire amount of makerAsset has been bought - if (totalFillResults.makerAssetFilledAmount >= makerAssetFillAmount) { - break; - } - } - return totalFillResults; - } - - /// @dev Synchronously cancels multiple orders in a single transaction. - /// @param orders Array of order specifications. - function batchCancelOrders(LibOrder.Order[] memory orders) - public - nonReentrant - { - uint256 ordersLength = orders.length; - for (uint256 i = 0; i != ordersLength; i++) { - cancelOrderInternal(orders[i]); - } - } - - /// @dev Fetches information for all passed in orders. - /// @param orders Array of order specifications. - /// @return Array of OrderInfo instances that correspond to each order. - function getOrdersInfo(LibOrder.Order[] memory orders) - public - view - returns (LibOrder.OrderInfo[] memory) - { - uint256 ordersLength = orders.length; - LibOrder.OrderInfo[] memory ordersInfo = new LibOrder.OrderInfo[](ordersLength); - for (uint256 i = 0; i != ordersLength; i++) { - ordersInfo[i] = getOrderInfo(orders[i]); - } - return ordersInfo; - } - - /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled. - /// @param order Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signature Proof that order has been created by maker. - function fillOrKillOrderInternal( - LibOrder.Order memory order, - uint256 takerAssetFillAmount, - bytes memory signature - ) - internal - returns (FillResults memory fillResults) - { - fillResults = fillOrderInternal( - order, - takerAssetFillAmount, - signature - ); - require( - fillResults.takerAssetFilledAmount == takerAssetFillAmount, - "COMPLETE_FILL_FAILED" - ); - return fillResults; - } -} diff --git a/packages/contracts/contracts/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol b/packages/contracts/contracts/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol deleted file mode 100644 index 8db8d6f6c..000000000 --- a/packages/contracts/contracts/protocol/Exchange/interfaces/IAssetProxyDispatcher.sol +++ /dev/null @@ -1,37 +0,0 @@ -/* - - Copyright 2018 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.24; - - -contract IAssetProxyDispatcher { - - /// @dev Registers an asset proxy to its asset proxy id. - /// Once an asset proxy is registered, it cannot be unregistered. - /// @param assetProxy Address of new asset proxy to register. - function registerAssetProxy(address assetProxy) - external; - - /// @dev Gets an asset proxy. - /// @param assetProxyId Id of the asset proxy. - /// @return The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered. - function getAssetProxy(bytes4 assetProxyId) - external - view - returns (address); -} diff --git a/packages/contracts/contracts/protocol/Exchange/interfaces/IExchange.sol b/packages/contracts/contracts/protocol/Exchange/interfaces/IExchange.sol deleted file mode 100644 index b92abba04..000000000 --- a/packages/contracts/contracts/protocol/Exchange/interfaces/IExchange.sol +++ /dev/null @@ -1,38 +0,0 @@ -/* - - Copyright 2018 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.24; -pragma experimental ABIEncoderV2; - -import "./IExchangeCore.sol"; -import "./IMatchOrders.sol"; -import "./ISignatureValidator.sol"; -import "./ITransactions.sol"; -import "./IAssetProxyDispatcher.sol"; -import "./IWrapperFunctions.sol"; - - -// solhint-disable no-empty-blocks -contract IExchange is - IExchangeCore, - IMatchOrders, - ISignatureValidator, - ITransactions, - IAssetProxyDispatcher, - IWrapperFunctions -{} diff --git a/packages/contracts/contracts/protocol/Exchange/interfaces/IExchangeCore.sol b/packages/contracts/contracts/protocol/Exchange/interfaces/IExchangeCore.sol deleted file mode 100644 index 9995e0385..000000000 --- a/packages/contracts/contracts/protocol/Exchange/interfaces/IExchangeCore.sol +++ /dev/null @@ -1,60 +0,0 @@ -/* - - Copyright 2018 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.24; -pragma experimental ABIEncoderV2; - -import "../libs/LibOrder.sol"; -import "../libs/LibFillResults.sol"; - - -contract IExchangeCore { - - /// @dev Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch - /// and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress). - /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled. - function cancelOrdersUpTo(uint256 targetOrderEpoch) - external; - - /// @dev Fills the input order. - /// @param order Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signature Proof that order has been created by maker. - /// @return Amounts filled and fees paid by maker and taker. - function fillOrder( - LibOrder.Order memory order, - uint256 takerAssetFillAmount, - bytes memory signature - ) - public - returns (LibFillResults.FillResults memory fillResults); - - /// @dev After calling, the order can not be filled anymore. - /// @param order Order struct containing order specifications. - function cancelOrder(LibOrder.Order memory order) - public; - - /// @dev Gets information about an order: status, hash, and amount filled. - /// @param order Order to gather information on. - /// @return OrderInfo Information about the order and its state. - /// See LibOrder.OrderInfo for a complete description. - function getOrderInfo(LibOrder.Order memory order) - public - view - returns (LibOrder.OrderInfo memory orderInfo); -} diff --git a/packages/contracts/contracts/protocol/Exchange/interfaces/IMatchOrders.sol b/packages/contracts/contracts/protocol/Exchange/interfaces/IMatchOrders.sol deleted file mode 100644 index 73447f3ae..000000000 --- a/packages/contracts/contracts/protocol/Exchange/interfaces/IMatchOrders.sol +++ /dev/null @@ -1,44 +0,0 @@ -/* - - Copyright 2018 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.24; -pragma experimental ABIEncoderV2; - -import "../libs/LibOrder.sol"; -import "../libs/LibFillResults.sol"; - - -contract IMatchOrders { - - /// @dev Match two complementary orders that have a profitable spread. - /// Each order is filled at their respective price point. However, the calculations are - /// carried out as though the orders are both being filled at the right order's price point. - /// The profit made by the left order goes to the taker (who matched the two orders). - /// @param leftOrder First order to match. - /// @param rightOrder Second order to match. - /// @param leftSignature Proof that order was created by the left maker. - /// @param rightSignature Proof that order was created by the right maker. - /// @return matchedFillResults Amounts filled and fees paid by maker and taker of matched orders. - function matchOrders( - LibOrder.Order memory leftOrder, - LibOrder.Order memory rightOrder, - bytes memory leftSignature, - bytes memory rightSignature - ) - public - returns (LibFillResults.MatchedFillResults memory matchedFillResults); -} diff --git a/packages/contracts/contracts/protocol/Exchange/interfaces/ISignatureValidator.sol b/packages/contracts/contracts/protocol/Exchange/interfaces/ISignatureValidator.sol deleted file mode 100644 index 1fd0eccf0..000000000 --- a/packages/contracts/contracts/protocol/Exchange/interfaces/ISignatureValidator.sol +++ /dev/null @@ -1,57 +0,0 @@ -/* - - Copyright 2018 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.24; - - -contract ISignatureValidator { - - /// @dev Approves a hash on-chain using any valid signature type. - /// After presigning a hash, the preSign signature type will become valid for that hash and signer. - /// @param signerAddress Address that should have signed the given hash. - /// @param signature Proof that the hash has been signed by signer. - function preSign( - bytes32 hash, - address signerAddress, - bytes signature - ) - external; - - /// @dev Approves/unnapproves a Validator contract to verify signatures on signer's behalf. - /// @param validatorAddress Address of Validator contract. - /// @param approval Approval or disapproval of Validator contract. - function setSignatureValidatorApproval( - address validatorAddress, - bool approval - ) - external; - - /// @dev Verifies that a signature is valid. - /// @param hash Message hash that is signed. - /// @param signerAddress Address of signer. - /// @param signature Proof of signing. - /// @return Validity of order signature. - function isValidSignature( - bytes32 hash, - address signerAddress, - bytes memory signature - ) - public - view - returns (bool isValid); -} diff --git a/packages/contracts/contracts/protocol/Exchange/interfaces/ITransactions.sol b/packages/contracts/contracts/protocol/Exchange/interfaces/ITransactions.sol deleted file mode 100644 index 4446c55ce..000000000 --- a/packages/contracts/contracts/protocol/Exchange/interfaces/ITransactions.sol +++ /dev/null @@ -1,35 +0,0 @@ -/* - - Copyright 2018 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.24; - - -contract ITransactions { - - /// @dev Executes an exchange method call in the context of signer. - /// @param salt Arbitrary number to ensure uniqueness of transaction hash. - /// @param signerAddress Address of transaction signer. - /// @param data AbiV2 encoded calldata. - /// @param signature Proof of signer transaction by signer. - function executeTransaction( - uint256 salt, - address signerAddress, - bytes data, - bytes signature - ) - external; -} diff --git a/packages/contracts/contracts/protocol/Exchange/interfaces/IValidator.sol b/packages/contracts/contracts/protocol/Exchange/interfaces/IValidator.sol deleted file mode 100644 index 2dd69100c..000000000 --- a/packages/contracts/contracts/protocol/Exchange/interfaces/IValidator.sol +++ /dev/null @@ -1,37 +0,0 @@ -/* - - Copyright 2018 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.24; - - -contract IValidator { - - /// @dev Verifies that a signature is valid. - /// @param hash Message hash that is signed. - /// @param signerAddress Address that should have signed the given hash. - /// @param signature Proof of signing. - /// @return Validity of order signature. - function isValidSignature( - bytes32 hash, - address signerAddress, - bytes signature - ) - external - view - returns (bool isValid); -} diff --git a/packages/contracts/contracts/protocol/Exchange/interfaces/IWallet.sol b/packages/contracts/contracts/protocol/Exchange/interfaces/IWallet.sol deleted file mode 100644 index c97161ca6..000000000 --- a/packages/contracts/contracts/protocol/Exchange/interfaces/IWallet.sol +++ /dev/null @@ -1,35 +0,0 @@ -/* - - Copyright 2018 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.24; - - -contract IWallet { - - /// @dev Verifies that a signature is valid. - /// @param hash Message hash that is signed. - /// @param signature Proof of signing. - /// @return Validity of order signature. - function isValidSignature( - bytes32 hash, - bytes signature - ) - external - view - returns (bool isValid); -} diff --git a/packages/contracts/contracts/protocol/Exchange/interfaces/IWrapperFunctions.sol b/packages/contracts/contracts/protocol/Exchange/interfaces/IWrapperFunctions.sol deleted file mode 100644 index 56a533646..000000000 --- a/packages/contracts/contracts/protocol/Exchange/interfaces/IWrapperFunctions.sol +++ /dev/null @@ -1,160 +0,0 @@ -/* - - Copyright 2018 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.24; -pragma experimental ABIEncoderV2; - -import "../libs/LibOrder.sol"; -import "../libs/LibFillResults.sol"; - - -contract IWrapperFunctions { - - /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled. - /// @param order LibOrder.Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signature Proof that order has been created by maker. - function fillOrKillOrder( - LibOrder.Order memory order, - uint256 takerAssetFillAmount, - bytes memory signature - ) - public - returns (LibFillResults.FillResults memory fillResults); - - /// @dev Fills an order with specified parameters and ECDSA signature. - /// Returns false if the transaction would otherwise revert. - /// @param order LibOrder.Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signature Proof that order has been created by maker. - /// @return Amounts filled and fees paid by maker and taker. - function fillOrderNoThrow( - LibOrder.Order memory order, - uint256 takerAssetFillAmount, - bytes memory signature - ) - public - returns (LibFillResults.FillResults memory fillResults); - - /// @dev Synchronously executes multiple calls of fillOrder. - /// @param orders Array of order specifications. - /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders. - /// @param signatures Proofs that orders have been created by makers. - /// @return Amounts filled and fees paid by makers and taker. - function batchFillOrders( - LibOrder.Order[] memory orders, - uint256[] memory takerAssetFillAmounts, - bytes[] memory signatures - ) - public - returns (LibFillResults.FillResults memory totalFillResults); - - /// @dev Synchronously executes multiple calls of fillOrKill. - /// @param orders Array of order specifications. - /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders. - /// @param signatures Proofs that orders have been created by makers. - /// @return Amounts filled and fees paid by makers and taker. - function batchFillOrKillOrders( - LibOrder.Order[] memory orders, - uint256[] memory takerAssetFillAmounts, - bytes[] memory signatures - ) - public - returns (LibFillResults.FillResults memory totalFillResults); - - /// @dev Fills an order with specified parameters and ECDSA signature. - /// Returns false if the transaction would otherwise revert. - /// @param orders Array of order specifications. - /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders. - /// @param signatures Proofs that orders have been created by makers. - /// @return Amounts filled and fees paid by makers and taker. - function batchFillOrdersNoThrow( - LibOrder.Order[] memory orders, - uint256[] memory takerAssetFillAmounts, - bytes[] memory signatures - ) - public - returns (LibFillResults.FillResults memory totalFillResults); - - /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker. - /// @param orders Array of order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signatures Proofs that orders have been created by makers. - /// @return Amounts filled and fees paid by makers and taker. - function marketSellOrders( - LibOrder.Order[] memory orders, - uint256 takerAssetFillAmount, - bytes[] memory signatures - ) - public - returns (LibFillResults.FillResults memory totalFillResults); - - /// @dev Synchronously executes multiple calls of fillOrder until total amount of takerAsset is sold by taker. - /// Returns false if the transaction would otherwise revert. - /// @param orders Array of order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signatures Proofs that orders have been signed by makers. - /// @return Amounts filled and fees paid by makers and taker. - function marketSellOrdersNoThrow( - LibOrder.Order[] memory orders, - uint256 takerAssetFillAmount, - bytes[] memory signatures - ) - public - returns (LibFillResults.FillResults memory totalFillResults); - - /// @dev Synchronously executes multiple calls of fillOrder until total amount of makerAsset is bought by taker. - /// @param orders Array of order specifications. - /// @param makerAssetFillAmount Desired amount of makerAsset to buy. - /// @param signatures Proofs that orders have been signed by makers. - /// @return Amounts filled and fees paid by makers and taker. - function marketBuyOrders( - LibOrder.Order[] memory orders, - uint256 makerAssetFillAmount, - bytes[] memory signatures - ) - public - returns (LibFillResults.FillResults memory totalFillResults); - - /// @dev Synchronously executes multiple fill orders in a single transaction until total amount is bought by taker. - /// Returns false if the transaction would otherwise revert. - /// @param orders Array of order specifications. - /// @param makerAssetFillAmount Desired amount of makerAsset to buy. - /// @param signatures Proofs that orders have been signed by makers. - /// @return Amounts filled and fees paid by makers and taker. - function marketBuyOrdersNoThrow( - LibOrder.Order[] memory orders, - uint256 makerAssetFillAmount, - bytes[] memory signatures - ) - public - returns (LibFillResults.FillResults memory totalFillResults); - - /// @dev Synchronously cancels multiple orders in a single transaction. - /// @param orders Array of order specifications. - function batchCancelOrders(LibOrder.Order[] memory orders) - public; - - /// @dev Fetches information for all passed in orders - /// @param orders Array of order specifications. - /// @return Array of OrderInfo instances that correspond to each order. - function getOrdersInfo(LibOrder.Order[] memory orders) - public - view - returns (LibOrder.OrderInfo[] memory); -} diff --git a/packages/contracts/contracts/protocol/Exchange/libs/LibAbiEncoder.sol b/packages/contracts/contracts/protocol/Exchange/libs/LibAbiEncoder.sol deleted file mode 100644 index 4aad37709..000000000 --- a/packages/contracts/contracts/protocol/Exchange/libs/LibAbiEncoder.sol +++ /dev/null @@ -1,215 +0,0 @@ -/* - - Copyright 2018 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.24; -pragma experimental ABIEncoderV2; - -import "./LibOrder.sol"; - - -contract LibAbiEncoder { - - /// @dev ABI encodes calldata for `fillOrder`. - /// @param order Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signature Proof that order has been created by maker. - /// @return ABI encoded calldata for `fillOrder`. - function abiEncodeFillOrder( - LibOrder.Order memory order, - uint256 takerAssetFillAmount, - bytes memory signature - ) - internal - pure - returns (bytes memory fillOrderCalldata) - { - // We need to call MExchangeCore.fillOrder using a delegatecall in - // assembly so that we can intercept a call that throws. For this, we - // need the input encoded in memory in the Ethereum ABIv2 format [1]. - - // | Area | Offset | Length | Contents | - // | -------- |--------|---------|-------------------------------------------- | - // | Header | 0x00 | 4 | function selector | - // | Params | | 3 * 32 | function parameters: | - // | | 0x00 | | 1. offset to order (*) | - // | | 0x20 | | 2. takerAssetFillAmount | - // | | 0x40 | | 3. offset to signature (*) | - // | Data | | 12 * 32 | order: | - // | | 0x000 | | 1. senderAddress | - // | | 0x020 | | 2. makerAddress | - // | | 0x040 | | 3. takerAddress | - // | | 0x060 | | 4. feeRecipientAddress | - // | | 0x080 | | 5. makerAssetAmount | - // | | 0x0A0 | | 6. takerAssetAmount | - // | | 0x0C0 | | 7. makerFeeAmount | - // | | 0x0E0 | | 8. takerFeeAmount | - // | | 0x100 | | 9. expirationTimeSeconds | - // | | 0x120 | | 10. salt | - // | | 0x140 | | 11. Offset to makerAssetData (*) | - // | | 0x160 | | 12. Offset to takerAssetData (*) | - // | | 0x180 | 32 | makerAssetData Length | - // | | 0x1A0 | ** | makerAssetData Contents | - // | | 0x1C0 | 32 | takerAssetData Length | - // | | 0x1E0 | ** | takerAssetData Contents | - // | | 0x200 | 32 | signature Length | - // | | 0x220 | ** | signature Contents | - - // * Offsets are calculated from the beginning of the current area: Header, Params, Data: - // An offset stored in the Params area is calculated from the beginning of the Params section. - // An offset stored in the Data area is calculated from the beginning of the Data section. - - // ** The length of dynamic array contents are stored in the field immediately preceeding the contents. - - // [1]: https://solidity.readthedocs.io/en/develop/abi-spec.html - - assembly { - - // Areas below may use the following variables: - // 1. <area>Start -- Start of this area in memory - // 2. <area>End -- End of this area in memory. This value may - // be precomputed (before writing contents), - // or it may be computed as contents are written. - // 3. <area>Offset -- Current offset into area. If an area's End - // is precomputed, this variable tracks the - // offsets of contents as they are written. - - /////// Setup Header Area /////// - // Load free memory pointer - fillOrderCalldata := mload(0x40) - // bytes4(keccak256("fillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),uint256,bytes)")) - // = 0xb4be83d5 - // Leave 0x20 bytes to store the length - mstore(add(fillOrderCalldata, 0x20), 0xb4be83d500000000000000000000000000000000000000000000000000000000) - let headerAreaEnd := add(fillOrderCalldata, 0x24) - - /////// Setup Params Area /////// - // This area is preallocated and written to later. - // This is because we need to fill in offsets that have not yet been calculated. - let paramsAreaStart := headerAreaEnd - let paramsAreaEnd := add(paramsAreaStart, 0x60) - let paramsAreaOffset := paramsAreaStart - - /////// Setup Data Area /////// - let dataAreaStart := paramsAreaEnd - let dataAreaEnd := dataAreaStart - - // Offset from the source data we're reading from - let sourceOffset := order - // arrayLenBytes and arrayLenWords track the length of a dynamically-allocated bytes array. - let arrayLenBytes := 0 - let arrayLenWords := 0 - - /////// Write order Struct /////// - // Write memory location of Order, relative to the start of the - // parameter list, then increment the paramsAreaOffset respectively. - mstore(paramsAreaOffset, sub(dataAreaEnd, paramsAreaStart)) - paramsAreaOffset := add(paramsAreaOffset, 0x20) - - // Write values for each field in the order - // It would be nice to use a loop, but we save on gas by writing - // the stores sequentially. - mstore(dataAreaEnd, mload(sourceOffset)) // makerAddress - mstore(add(dataAreaEnd, 0x20), mload(add(sourceOffset, 0x20))) // takerAddress - mstore(add(dataAreaEnd, 0x40), mload(add(sourceOffset, 0x40))) // feeRecipientAddress - mstore(add(dataAreaEnd, 0x60), mload(add(sourceOffset, 0x60))) // senderAddress - mstore(add(dataAreaEnd, 0x80), mload(add(sourceOffset, 0x80))) // makerAssetAmount - mstore(add(dataAreaEnd, 0xA0), mload(add(sourceOffset, 0xA0))) // takerAssetAmount - mstore(add(dataAreaEnd, 0xC0), mload(add(sourceOffset, 0xC0))) // makerFeeAmount - mstore(add(dataAreaEnd, 0xE0), mload(add(sourceOffset, 0xE0))) // takerFeeAmount - mstore(add(dataAreaEnd, 0x100), mload(add(sourceOffset, 0x100))) // expirationTimeSeconds - mstore(add(dataAreaEnd, 0x120), mload(add(sourceOffset, 0x120))) // salt - mstore(add(dataAreaEnd, 0x140), mload(add(sourceOffset, 0x140))) // Offset to makerAssetData - mstore(add(dataAreaEnd, 0x160), mload(add(sourceOffset, 0x160))) // Offset to takerAssetData - dataAreaEnd := add(dataAreaEnd, 0x180) - sourceOffset := add(sourceOffset, 0x180) - - // Write offset to <order.makerAssetData> - mstore(add(dataAreaStart, mul(10, 0x20)), sub(dataAreaEnd, dataAreaStart)) - - // Calculate length of <order.makerAssetData> - sourceOffset := mload(add(order, 0x140)) // makerAssetData - arrayLenBytes := mload(sourceOffset) - sourceOffset := add(sourceOffset, 0x20) - arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20) - - // Write length of <order.makerAssetData> - mstore(dataAreaEnd, arrayLenBytes) - dataAreaEnd := add(dataAreaEnd, 0x20) - - // Write contents of <order.makerAssetData> - for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} { - mstore(dataAreaEnd, mload(sourceOffset)) - dataAreaEnd := add(dataAreaEnd, 0x20) - sourceOffset := add(sourceOffset, 0x20) - } - - // Write offset to <order.takerAssetData> - mstore(add(dataAreaStart, mul(11, 0x20)), sub(dataAreaEnd, dataAreaStart)) - - // Calculate length of <order.takerAssetData> - sourceOffset := mload(add(order, 0x160)) // takerAssetData - arrayLenBytes := mload(sourceOffset) - sourceOffset := add(sourceOffset, 0x20) - arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20) - - // Write length of <order.takerAssetData> - mstore(dataAreaEnd, arrayLenBytes) - dataAreaEnd := add(dataAreaEnd, 0x20) - - // Write contents of <order.takerAssetData> - for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} { - mstore(dataAreaEnd, mload(sourceOffset)) - dataAreaEnd := add(dataAreaEnd, 0x20) - sourceOffset := add(sourceOffset, 0x20) - } - - /////// Write takerAssetFillAmount /////// - mstore(paramsAreaOffset, takerAssetFillAmount) - paramsAreaOffset := add(paramsAreaOffset, 0x20) - - /////// Write signature /////// - // Write offset to paramsArea - mstore(paramsAreaOffset, sub(dataAreaEnd, paramsAreaStart)) - - // Calculate length of signature - sourceOffset := signature - arrayLenBytes := mload(sourceOffset) - sourceOffset := add(sourceOffset, 0x20) - arrayLenWords := div(add(arrayLenBytes, 0x1F), 0x20) - - // Write length of signature - mstore(dataAreaEnd, arrayLenBytes) - dataAreaEnd := add(dataAreaEnd, 0x20) - - // Write contents of signature - for {let i := 0} lt(i, arrayLenWords) {i := add(i, 1)} { - mstore(dataAreaEnd, mload(sourceOffset)) - dataAreaEnd := add(dataAreaEnd, 0x20) - sourceOffset := add(sourceOffset, 0x20) - } - - // Set length of calldata - mstore(fillOrderCalldata, sub(dataAreaEnd, add(fillOrderCalldata, 0x20))) - - // Increment free memory pointer - mstore(0x40, dataAreaEnd) - } - - return fillOrderCalldata; - } -} diff --git a/packages/contracts/contracts/protocol/Exchange/libs/LibConstants.sol b/packages/contracts/contracts/protocol/Exchange/libs/LibConstants.sol deleted file mode 100644 index 8d2732cd3..000000000 --- a/packages/contracts/contracts/protocol/Exchange/libs/LibConstants.sol +++ /dev/null @@ -1,49 +0,0 @@ -/* - - Copyright 2018 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.24; - - -// solhint-disable max-line-length -contract LibConstants { - - // Asset data for ZRX token. Used for fee transfers. - // @TODO: Hardcode constant when we deploy. Currently - // not constant to make testing easier. - - // The proxyId for ZRX_ASSET_DATA is bytes4(keccak256("ERC20Token(address)")) = 0xf47261b0 - - // Kovan ZRX address is 0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570. - // The ABI encoded proxyId and address is 0xf47261b00000000000000000000000006ff6c0ff1d68b964901f986d4c9fa3ac68346570 - // bytes constant public ZRX_ASSET_DATA = "\xf4\x72\x61\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6f\xf6\xc0\xff\x1d\x68\xb9\x64\x90\x1f\x98\x6d\x4c\x9f\xa3\xac\x68\x34\x65\x70"; - - // Mainnet ZRX address is 0xe41d2489571d322189246dafa5ebde1f4699f498. - // The ABI encoded proxyId and address is 0xf47261b0000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498 - // bytes constant public ZRX_ASSET_DATA = "\xf4\x72\x61\xb0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x1d\x24\x89\x57\x1d\x32\x21\x89\x24\x6d\xaf\xa5\xeb\xde\x1f\x46\x99\xf4\x98"; - - // solhint-disable-next-line var-name-mixedcase - bytes public ZRX_ASSET_DATA; - - // @TODO: Remove when we deploy. - constructor (bytes memory zrxAssetData) - public - { - ZRX_ASSET_DATA = zrxAssetData; - } -} -// solhint-enable max-line-length diff --git a/packages/contracts/contracts/protocol/Exchange/libs/LibEIP712.sol b/packages/contracts/contracts/protocol/Exchange/libs/LibEIP712.sol deleted file mode 100644 index 203edc1fd..000000000 --- a/packages/contracts/contracts/protocol/Exchange/libs/LibEIP712.sol +++ /dev/null @@ -1,87 +0,0 @@ -/* - - Copyright 2018 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.24; - - -contract LibEIP712 { - - // EIP191 header for EIP712 prefix - string constant internal EIP191_HEADER = "\x19\x01"; - - // EIP712 Domain Name value - string constant internal EIP712_DOMAIN_NAME = "0x Protocol"; - - // EIP712 Domain Version value - string constant internal EIP712_DOMAIN_VERSION = "2"; - - // Hash of the EIP712 Domain Separator Schema - bytes32 constant internal EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = keccak256(abi.encodePacked( - "EIP712Domain(", - "string name,", - "string version,", - "address verifyingContract", - ")" - )); - - // Hash of the EIP712 Domain Separator data - // solhint-disable-next-line var-name-mixedcase - bytes32 public EIP712_DOMAIN_HASH; - - constructor () - public - { - EIP712_DOMAIN_HASH = keccak256(abi.encodePacked( - EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH, - keccak256(bytes(EIP712_DOMAIN_NAME)), - keccak256(bytes(EIP712_DOMAIN_VERSION)), - bytes32(address(this)) - )); - } - - /// @dev Calculates EIP712 encoding for a hash struct in this EIP712 Domain. - /// @param hashStruct The EIP712 hash struct. - /// @return EIP712 hash applied to this EIP712 Domain. - function hashEIP712Message(bytes32 hashStruct) - internal - view - returns (bytes32 result) - { - bytes32 eip712DomainHash = EIP712_DOMAIN_HASH; - - // Assembly for more efficient computing: - // keccak256(abi.encodePacked( - // EIP191_HEADER, - // EIP712_DOMAIN_HASH, - // hashStruct - // )); - - assembly { - // Load free memory pointer - let memPtr := mload(64) - - mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000) // EIP191 header - mstore(add(memPtr, 2), eip712DomainHash) // EIP712 domain hash - mstore(add(memPtr, 34), hashStruct) // Hash of struct - - // Compute hash - result := keccak256(memPtr, 66) - } - return result; - } -} diff --git a/packages/contracts/contracts/protocol/Exchange/libs/LibExchangeErrors.sol b/packages/contracts/contracts/protocol/Exchange/libs/LibExchangeErrors.sol deleted file mode 100644 index a0f75bc06..000000000 --- a/packages/contracts/contracts/protocol/Exchange/libs/LibExchangeErrors.sol +++ /dev/null @@ -1,70 +0,0 @@ -/* - - Copyright 2018 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. - -*/ - -// solhint-disable -pragma solidity 0.4.24; - - -/// @dev This contract documents the revert reasons used in the Exchange contract. -/// This contract is intended to serve as a reference, but is not actually used for efficiency reasons. -contract LibExchangeErrors { - - /// Order validation errors /// - string constant ORDER_UNFILLABLE = "ORDER_UNFILLABLE"; // Order cannot be filled. - string constant INVALID_MAKER = "INVALID_MAKER"; // Invalid makerAddress. - string constant INVALID_TAKER = "INVALID_TAKER"; // Invalid takerAddress. - string constant INVALID_SENDER = "INVALID_SENDER"; // Invalid `msg.sender`. - string constant INVALID_ORDER_SIGNATURE = "INVALID_ORDER_SIGNATURE"; // Signature validation failed. - - /// fillOrder validation errors /// - string constant INVALID_TAKER_AMOUNT = "INVALID_TAKER_AMOUNT"; // takerAssetFillAmount cannot equal 0. - string constant ROUNDING_ERROR = "ROUNDING_ERROR"; // Rounding error greater than 0.1% of takerAssetFillAmount. - - /// Signature validation errors /// - string constant INVALID_SIGNATURE = "INVALID_SIGNATURE"; // Signature validation failed. - string constant SIGNATURE_ILLEGAL = "SIGNATURE_ILLEGAL"; // Signature type is illegal. - string constant SIGNATURE_UNSUPPORTED = "SIGNATURE_UNSUPPORTED"; // Signature type unsupported. - - /// cancelOrdersUptTo errors /// - string constant INVALID_NEW_ORDER_EPOCH = "INVALID_NEW_ORDER_EPOCH"; // Specified salt must be greater than or equal to existing orderEpoch. - - /// fillOrKillOrder errors /// - string constant COMPLETE_FILL_FAILED = "COMPLETE_FILL_FAILED"; // Desired takerAssetFillAmount could not be completely filled. - - /// matchOrders errors /// - string constant NEGATIVE_SPREAD_REQUIRED = "NEGATIVE_SPREAD_REQUIRED"; // Matched orders must have a negative spread. - - /// Transaction errors /// - string constant REENTRANCY_ILLEGAL = "REENTRANCY_ILLEGAL"; // Recursive reentrancy is not allowed. - string constant INVALID_TX_HASH = "INVALID_TX_HASH"; // Transaction has already been executed. - string constant INVALID_TX_SIGNATURE = "INVALID_TX_SIGNATURE"; // Signature validation failed. - string constant FAILED_EXECUTION = "FAILED_EXECUTION"; // Transaction execution failed. - - /// registerAssetProxy errors /// - string constant ASSET_PROXY_ALREADY_EXISTS = "ASSET_PROXY_ALREADY_EXISTS"; // AssetProxy with same id already exists. - - /// dispatchTransferFrom errors /// - string constant ASSET_PROXY_DOES_NOT_EXIST = "ASSET_PROXY_DOES_NOT_EXIST"; // No assetProxy registered at given id. - string constant TRANSFER_FAILED = "TRANSFER_FAILED"; // Asset transfer unsuccesful. - - /// Length validation errors /// - string constant LENGTH_GREATER_THAN_0_REQUIRED = "LENGTH_GREATER_THAN_0_REQUIRED"; // Byte array must have a length greater than 0. - string constant LENGTH_GREATER_THAN_3_REQUIRED = "LENGTH_GREATER_THAN_3_REQUIRED"; // Byte array must have a length greater than 3. - string constant LENGTH_0_REQUIRED = "LENGTH_0_REQUIRED"; // Byte array must have a length of 0. - string constant LENGTH_65_REQUIRED = "LENGTH_65_REQUIRED"; // Byte array must have a length of 65. -} diff --git a/packages/contracts/contracts/protocol/Exchange/libs/LibFillResults.sol b/packages/contracts/contracts/protocol/Exchange/libs/LibFillResults.sol deleted file mode 100644 index 659ae9a69..000000000 --- a/packages/contracts/contracts/protocol/Exchange/libs/LibFillResults.sol +++ /dev/null @@ -1,53 +0,0 @@ -/* - - Copyright 2018 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.24; - -import "../../../utils/SafeMath/SafeMath.sol"; - - -contract LibFillResults is - SafeMath -{ - struct FillResults { - uint256 makerAssetFilledAmount; // Total amount of makerAsset(s) filled. - uint256 takerAssetFilledAmount; // Total amount of takerAsset(s) filled. - uint256 makerFeePaid; // Total amount of ZRX paid by maker(s) to feeRecipient(s). - uint256 takerFeePaid; // Total amount of ZRX paid by taker to feeRecipients(s). - } - - struct MatchedFillResults { - FillResults left; // Amounts filled and fees paid of left order. - FillResults right; // Amounts filled and fees paid of right order. - uint256 leftMakerAssetSpreadAmount; // Spread between price of left and right order, denominated in the left order's makerAsset, paid to taker. - } - - /// @dev Adds properties of both FillResults instances. - /// Modifies the first FillResults instance specified. - /// @param totalFillResults Fill results instance that will be added onto. - /// @param singleFillResults Fill results instance that will be added to totalFillResults. - function addFillResults(FillResults memory totalFillResults, FillResults memory singleFillResults) - internal - pure - { - totalFillResults.makerAssetFilledAmount = safeAdd(totalFillResults.makerAssetFilledAmount, singleFillResults.makerAssetFilledAmount); - totalFillResults.takerAssetFilledAmount = safeAdd(totalFillResults.takerAssetFilledAmount, singleFillResults.takerAssetFilledAmount); - totalFillResults.makerFeePaid = safeAdd(totalFillResults.makerFeePaid, singleFillResults.makerFeePaid); - totalFillResults.takerFeePaid = safeAdd(totalFillResults.takerFeePaid, singleFillResults.takerFeePaid); - } -} diff --git a/packages/contracts/contracts/protocol/Exchange/libs/LibMath.sol b/packages/contracts/contracts/protocol/Exchange/libs/LibMath.sol deleted file mode 100644 index c0b85ea10..000000000 --- a/packages/contracts/contracts/protocol/Exchange/libs/LibMath.sol +++ /dev/null @@ -1,253 +0,0 @@ -/* - - Copyright 2018 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.24; - -import "../../../utils/SafeMath/SafeMath.sol"; - - -contract LibMath is - SafeMath -{ - /// @dev Calculates partial value given a numerator and denominator rounded down. - /// Reverts if rounding error is >= 0.1% - /// @param numerator Numerator. - /// @param denominator Denominator. - /// @param target Value to calculate partial of. - /// @return Partial value of target rounded down. - function safeGetPartialAmountFloor( - uint256 numerator, - uint256 denominator, - uint256 target - ) - internal - pure - returns (uint256 partialAmount) - { - require( - denominator > 0, - "DIVISION_BY_ZERO" - ); - - require( - !isRoundingErrorFloor( - numerator, - denominator, - target - ), - "ROUNDING_ERROR" - ); - - partialAmount = safeDiv( - safeMul(numerator, target), - denominator - ); - return partialAmount; - } - - /// @dev Calculates partial value given a numerator and denominator rounded down. - /// Reverts if rounding error is >= 0.1% - /// @param numerator Numerator. - /// @param denominator Denominator. - /// @param target Value to calculate partial of. - /// @return Partial value of target rounded up. - function safeGetPartialAmountCeil( - uint256 numerator, - uint256 denominator, - uint256 target - ) - internal - pure - returns (uint256 partialAmount) - { - require( - denominator > 0, - "DIVISION_BY_ZERO" - ); - - require( - !isRoundingErrorCeil( - numerator, - denominator, - target - ), - "ROUNDING_ERROR" - ); - - // safeDiv computes `floor(a / b)`. We use the identity (a, b integer): - // ceil(a / b) = floor((a + b - 1) / b) - // To implement `ceil(a / b)` using safeDiv. - partialAmount = safeDiv( - safeAdd( - safeMul(numerator, target), - safeSub(denominator, 1) - ), - denominator - ); - return partialAmount; - } - - /// @dev Calculates partial value given a numerator and denominator rounded down. - /// @param numerator Numerator. - /// @param denominator Denominator. - /// @param target Value to calculate partial of. - /// @return Partial value of target rounded down. - function getPartialAmountFloor( - uint256 numerator, - uint256 denominator, - uint256 target - ) - internal - pure - returns (uint256 partialAmount) - { - require( - denominator > 0, - "DIVISION_BY_ZERO" - ); - - partialAmount = safeDiv( - safeMul(numerator, target), - denominator - ); - return partialAmount; - } - - /// @dev Calculates partial value given a numerator and denominator rounded down. - /// @param numerator Numerator. - /// @param denominator Denominator. - /// @param target Value to calculate partial of. - /// @return Partial value of target rounded up. - function getPartialAmountCeil( - uint256 numerator, - uint256 denominator, - uint256 target - ) - internal - pure - returns (uint256 partialAmount) - { - require( - denominator > 0, - "DIVISION_BY_ZERO" - ); - - // safeDiv computes `floor(a / b)`. We use the identity (a, b integer): - // ceil(a / b) = floor((a + b - 1) / b) - // To implement `ceil(a / b)` using safeDiv. - partialAmount = safeDiv( - safeAdd( - safeMul(numerator, target), - safeSub(denominator, 1) - ), - denominator - ); - return partialAmount; - } - - /// @dev Checks if rounding error >= 0.1% when rounding down. - /// @param numerator Numerator. - /// @param denominator Denominator. - /// @param target Value to multiply with numerator/denominator. - /// @return Rounding error is present. - function isRoundingErrorFloor( - uint256 numerator, - uint256 denominator, - uint256 target - ) - internal - pure - returns (bool isError) - { - require( - denominator > 0, - "DIVISION_BY_ZERO" - ); - - // The absolute rounding error is the difference between the rounded - // value and the ideal value. The relative rounding error is the - // absolute rounding error divided by the absolute value of the - // ideal value. This is undefined when the ideal value is zero. - // - // The ideal value is `numerator * target / denominator`. - // Let's call `numerator * target % denominator` the remainder. - // The absolute error is `remainder / denominator`. - // - // When the ideal value is zero, we require the absolute error to - // be zero. Fortunately, this is always the case. The ideal value is - // zero iff `numerator == 0` and/or `target == 0`. In this case the - // remainder and absolute error are also zero. - if (target == 0 || numerator == 0) { - return false; - } - - // Otherwise, we want the relative rounding error to be strictly - // less than 0.1%. - // The relative error is `remainder / (numerator * target)`. - // We want the relative error less than 1 / 1000: - // remainder / (numerator * denominator) < 1 / 1000 - // or equivalently: - // 1000 * remainder < numerator * target - // so we have a rounding error iff: - // 1000 * remainder >= numerator * target - uint256 remainder = mulmod( - target, - numerator, - denominator - ); - isError = safeMul(1000, remainder) >= safeMul(numerator, target); - return isError; - } - - /// @dev Checks if rounding error >= 0.1% when rounding up. - /// @param numerator Numerator. - /// @param denominator Denominator. - /// @param target Value to multiply with numerator/denominator. - /// @return Rounding error is present. - function isRoundingErrorCeil( - uint256 numerator, - uint256 denominator, - uint256 target - ) - internal - pure - returns (bool isError) - { - require( - denominator > 0, - "DIVISION_BY_ZERO" - ); - - // See the comments in `isRoundingError`. - if (target == 0 || numerator == 0) { - // When either is zero, the ideal value and rounded value are zero - // and there is no rounding error. (Although the relative error - // is undefined.) - return false; - } - // Compute remainder as before - uint256 remainder = mulmod( - target, - numerator, - denominator - ); - remainder = safeSub(denominator, remainder) % denominator; - isError = safeMul(1000, remainder) >= safeMul(numerator, target); - return isError; - } -} diff --git a/packages/contracts/contracts/protocol/Exchange/libs/LibOrder.sol b/packages/contracts/contracts/protocol/Exchange/libs/LibOrder.sol deleted file mode 100644 index 0fe7c2161..000000000 --- a/packages/contracts/contracts/protocol/Exchange/libs/LibOrder.sol +++ /dev/null @@ -1,145 +0,0 @@ -/* - - Copyright 2018 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.24; - -import "./LibEIP712.sol"; - - -contract LibOrder is - LibEIP712 -{ - // Hash for the EIP712 Order Schema - bytes32 constant internal EIP712_ORDER_SCHEMA_HASH = keccak256(abi.encodePacked( - "Order(", - "address makerAddress,", - "address takerAddress,", - "address feeRecipientAddress,", - "address senderAddress,", - "uint256 makerAssetAmount,", - "uint256 takerAssetAmount,", - "uint256 makerFee,", - "uint256 takerFee,", - "uint256 expirationTimeSeconds,", - "uint256 salt,", - "bytes makerAssetData,", - "bytes takerAssetData", - ")" - )); - - // A valid order remains fillable until it is expired, fully filled, or cancelled. - // An order's state is unaffected by external factors, like account balances. - enum OrderStatus { - INVALID, // Default value - INVALID_MAKER_ASSET_AMOUNT, // Order does not have a valid maker asset amount - INVALID_TAKER_ASSET_AMOUNT, // Order does not have a valid taker asset amount - FILLABLE, // Order is fillable - EXPIRED, // Order has already expired - FULLY_FILLED, // Order is fully filled - CANCELLED // Order has been cancelled - } - - // solhint-disable max-line-length - struct Order { - address makerAddress; // Address that created the order. - address takerAddress; // Address that is allowed to fill the order. If set to 0, any address is allowed to fill the order. - address feeRecipientAddress; // Address that will recieve fees when order is filled. - address senderAddress; // Address that is allowed to call Exchange contract methods that affect this order. If set to 0, any address is allowed to call these methods. - uint256 makerAssetAmount; // Amount of makerAsset being offered by maker. Must be greater than 0. - uint256 takerAssetAmount; // Amount of takerAsset being bid on by maker. Must be greater than 0. - uint256 makerFee; // Amount of ZRX paid to feeRecipient by maker when order is filled. If set to 0, no transfer of ZRX from maker to feeRecipient will be attempted. - uint256 takerFee; // Amount of ZRX paid to feeRecipient by taker when order is filled. If set to 0, no transfer of ZRX from taker to feeRecipient will be attempted. - uint256 expirationTimeSeconds; // Timestamp in seconds at which order expires. - uint256 salt; // Arbitrary number to facilitate uniqueness of the order's hash. - bytes makerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring makerAsset. The last byte references the id of this proxy. - bytes takerAssetData; // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The last byte references the id of this proxy. - } - // solhint-enable max-line-length - - struct OrderInfo { - uint8 orderStatus; // Status that describes order's validity and fillability. - bytes32 orderHash; // EIP712 hash of the order (see LibOrder.getOrderHash). - uint256 orderTakerAssetFilledAmount; // Amount of order that has already been filled. - } - - /// @dev Calculates Keccak-256 hash of the order. - /// @param order The order structure. - /// @return Keccak-256 EIP712 hash of the order. - function getOrderHash(Order memory order) - internal - view - returns (bytes32 orderHash) - { - orderHash = hashEIP712Message(hashOrder(order)); - return orderHash; - } - - /// @dev Calculates EIP712 hash of the order. - /// @param order The order structure. - /// @return EIP712 hash of the order. - function hashOrder(Order memory order) - internal - pure - returns (bytes32 result) - { - bytes32 schemaHash = EIP712_ORDER_SCHEMA_HASH; - bytes32 makerAssetDataHash = keccak256(order.makerAssetData); - bytes32 takerAssetDataHash = keccak256(order.takerAssetData); - - // Assembly for more efficiently computing: - // keccak256(abi.encodePacked( - // EIP712_ORDER_SCHEMA_HASH, - // bytes32(order.makerAddress), - // bytes32(order.takerAddress), - // bytes32(order.feeRecipientAddress), - // bytes32(order.senderAddress), - // order.makerAssetAmount, - // order.takerAssetAmount, - // order.makerFee, - // order.takerFee, - // order.expirationTimeSeconds, - // order.salt, - // keccak256(order.makerAssetData), - // keccak256(order.takerAssetData) - // )); - - assembly { - // Calculate memory addresses that will be swapped out before hashing - let pos1 := sub(order, 32) - let pos2 := add(order, 320) - let pos3 := add(order, 352) - - // Backup - let temp1 := mload(pos1) - let temp2 := mload(pos2) - let temp3 := mload(pos3) - - // Hash in place - mstore(pos1, schemaHash) - mstore(pos2, makerAssetDataHash) - mstore(pos3, takerAssetDataHash) - result := keccak256(pos1, 416) - - // Restore - mstore(pos1, temp1) - mstore(pos2, temp2) - mstore(pos3, temp3) - } - return result; - } -} diff --git a/packages/contracts/contracts/protocol/Exchange/mixins/MAssetProxyDispatcher.sol b/packages/contracts/contracts/protocol/Exchange/mixins/MAssetProxyDispatcher.sol deleted file mode 100644 index 0ddfca270..000000000 --- a/packages/contracts/contracts/protocol/Exchange/mixins/MAssetProxyDispatcher.sol +++ /dev/null @@ -1,45 +0,0 @@ -/* - - Copyright 2018 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.24; - -import "../interfaces/IAssetProxyDispatcher.sol"; - - -contract MAssetProxyDispatcher is - IAssetProxyDispatcher -{ - // Logs registration of new asset proxy - event AssetProxyRegistered( - bytes4 id, // Id of new registered AssetProxy. - address assetProxy // Address of new registered AssetProxy. - ); - - /// @dev Forwards arguments to assetProxy and calls `transferFrom`. Either succeeds or throws. - /// @param assetData Byte array encoded for the asset. - /// @param from Address to transfer token from. - /// @param to Address to transfer token to. - /// @param amount Amount of token to transfer. - function dispatchTransferFrom( - bytes memory assetData, - address from, - address to, - uint256 amount - ) - internal; -} diff --git a/packages/contracts/contracts/protocol/Exchange/mixins/MExchangeCore.sol b/packages/contracts/contracts/protocol/Exchange/mixins/MExchangeCore.sol deleted file mode 100644 index 742499568..000000000 --- a/packages/contracts/contracts/protocol/Exchange/mixins/MExchangeCore.sol +++ /dev/null @@ -1,157 +0,0 @@ -/* - - Copyright 2018 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.24; -pragma experimental ABIEncoderV2; - -import "../libs/LibOrder.sol"; -import "../libs/LibFillResults.sol"; -import "../interfaces/IExchangeCore.sol"; - - -contract MExchangeCore is - IExchangeCore -{ - // Fill event is emitted whenever an order is filled. - event Fill( - address indexed makerAddress, // Address that created the order. - address indexed feeRecipientAddress, // Address that received fees. - address takerAddress, // Address that filled the order. - address senderAddress, // Address that called the Exchange contract (msg.sender). - uint256 makerAssetFilledAmount, // Amount of makerAsset sold by maker and bought by taker. - uint256 takerAssetFilledAmount, // Amount of takerAsset sold by taker and bought by maker. - uint256 makerFeePaid, // Amount of ZRX paid to feeRecipient by maker. - uint256 takerFeePaid, // Amount of ZRX paid to feeRecipient by taker. - bytes32 indexed orderHash, // EIP712 hash of order (see LibOrder.getOrderHash). - bytes makerAssetData, // Encoded data specific to makerAsset. - bytes takerAssetData // Encoded data specific to takerAsset. - ); - - // Cancel event is emitted whenever an individual order is cancelled. - event Cancel( - address indexed makerAddress, // Address that created the order. - address indexed feeRecipientAddress, // Address that would have recieved fees if order was filled. - address senderAddress, // Address that called the Exchange contract (msg.sender). - bytes32 indexed orderHash, // EIP712 hash of order (see LibOrder.getOrderHash). - bytes makerAssetData, // Encoded data specific to makerAsset. - bytes takerAssetData // Encoded data specific to takerAsset. - ); - - // CancelUpTo event is emitted whenever `cancelOrdersUpTo` is executed succesfully. - event CancelUpTo( - address indexed makerAddress, // Orders cancelled must have been created by this address. - address indexed senderAddress, // Orders cancelled must have a `senderAddress` equal to this address. - uint256 orderEpoch // Orders with specified makerAddress and senderAddress with a salt less than this value are considered cancelled. - ); - - /// @dev Fills the input order. - /// @param order Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signature Proof that order has been created by maker. - /// @return Amounts filled and fees paid by maker and taker. - function fillOrderInternal( - LibOrder.Order memory order, - uint256 takerAssetFillAmount, - bytes memory signature - ) - internal - returns (LibFillResults.FillResults memory fillResults); - - /// @dev After calling, the order can not be filled anymore. - /// @param order Order struct containing order specifications. - function cancelOrderInternal(LibOrder.Order memory order) - internal; - - /// @dev Updates state with results of a fill order. - /// @param order that was filled. - /// @param takerAddress Address of taker who filled the order. - /// @param orderTakerAssetFilledAmount Amount of order already filled. - /// @return fillResults Amounts filled and fees paid by maker and taker. - function updateFilledState( - LibOrder.Order memory order, - address takerAddress, - bytes32 orderHash, - uint256 orderTakerAssetFilledAmount, - LibFillResults.FillResults memory fillResults - ) - internal; - - /// @dev Updates state with results of cancelling an order. - /// State is only updated if the order is currently fillable. - /// Otherwise, updating state would have no effect. - /// @param order that was cancelled. - /// @param orderHash Hash of order that was cancelled. - function updateCancelledState( - LibOrder.Order memory order, - bytes32 orderHash - ) - internal; - - /// @dev Validates context for fillOrder. Succeeds or throws. - /// @param order to be filled. - /// @param orderInfo OrderStatus, orderHash, and amount already filled of order. - /// @param takerAddress Address of order taker. - /// @param signature Proof that the orders was created by its maker. - function assertFillableOrder( - LibOrder.Order memory order, - LibOrder.OrderInfo memory orderInfo, - address takerAddress, - bytes memory signature - ) - internal - view; - - /// @dev Validates context for fillOrder. Succeeds or throws. - /// @param order to be filled. - /// @param orderInfo Status, orderHash, and amount already filled of order. - /// @param takerAssetFillAmount Desired amount of order to fill by taker. - /// @param takerAssetFilledAmount Amount of takerAsset that will be filled. - /// @param makerAssetFilledAmount Amount of makerAsset that will be transfered. - function assertValidFill( - LibOrder.Order memory order, - LibOrder.OrderInfo memory orderInfo, - uint256 takerAssetFillAmount, - uint256 takerAssetFilledAmount, - uint256 makerAssetFilledAmount - ) - internal - view; - - /// @dev Validates context for cancelOrder. Succeeds or throws. - /// @param order to be cancelled. - /// @param orderInfo OrderStatus, orderHash, and amount already filled of order. - function assertValidCancel( - LibOrder.Order memory order, - LibOrder.OrderInfo memory orderInfo - ) - internal - view; - - /// @dev Calculates amounts filled and fees paid by maker and taker. - /// @param order to be filled. - /// @param takerAssetFilledAmount Amount of takerAsset that will be filled. - /// @return fillResults Amounts filled and fees paid by maker and taker. - function calculateFillResults( - LibOrder.Order memory order, - uint256 takerAssetFilledAmount - ) - internal - pure - returns (LibFillResults.FillResults memory fillResults); - -} diff --git a/packages/contracts/contracts/protocol/Exchange/mixins/MMatchOrders.sol b/packages/contracts/contracts/protocol/Exchange/mixins/MMatchOrders.sol deleted file mode 100644 index 96fa34bc0..000000000 --- a/packages/contracts/contracts/protocol/Exchange/mixins/MMatchOrders.sol +++ /dev/null @@ -1,58 +0,0 @@ -/* - - Copyright 2018 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.24; -pragma experimental ABIEncoderV2; - -import "../libs/LibOrder.sol"; -import "../libs/LibFillResults.sol"; -import "../interfaces/IMatchOrders.sol"; - - -contract MMatchOrders is - IMatchOrders -{ - /// @dev Validates context for matchOrders. Succeeds or throws. - /// @param leftOrder First order to match. - /// @param rightOrder Second order to match. - function assertValidMatch( - LibOrder.Order memory leftOrder, - LibOrder.Order memory rightOrder - ) - internal - pure; - - /// @dev Calculates fill amounts for the matched orders. - /// Each order is filled at their respective price point. However, the calculations are - /// carried out as though the orders are both being filled at the right order's price point. - /// The profit made by the leftOrder order goes to the taker (who matched the two orders). - /// @param leftOrder First order to match. - /// @param rightOrder Second order to match. - /// @param leftOrderTakerAssetFilledAmount Amount of left order already filled. - /// @param rightOrderTakerAssetFilledAmount Amount of right order already filled. - /// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders. - function calculateMatchedFillResults( - LibOrder.Order memory leftOrder, - LibOrder.Order memory rightOrder, - uint256 leftOrderTakerAssetFilledAmount, - uint256 rightOrderTakerAssetFilledAmount - ) - internal - pure - returns (LibFillResults.MatchedFillResults memory matchedFillResults); - -} diff --git a/packages/contracts/contracts/protocol/Exchange/mixins/MSignatureValidator.sol b/packages/contracts/contracts/protocol/Exchange/mixins/MSignatureValidator.sol deleted file mode 100644 index 1fe88b908..000000000 --- a/packages/contracts/contracts/protocol/Exchange/mixins/MSignatureValidator.sol +++ /dev/null @@ -1,75 +0,0 @@ -/* - - Copyright 2018 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.24; - -import "../interfaces/ISignatureValidator.sol"; - - -contract MSignatureValidator is - ISignatureValidator -{ - event SignatureValidatorApproval( - address indexed signerAddress, // Address that approves or disapproves a contract to verify signatures. - address indexed validatorAddress, // Address of signature validator contract. - bool approved // Approval or disapproval of validator contract. - ); - - // Allowed signature types. - enum SignatureType { - Illegal, // 0x00, default value - Invalid, // 0x01 - EIP712, // 0x02 - EthSign, // 0x03 - Wallet, // 0x04 - Validator, // 0x05 - PreSigned, // 0x06 - NSignatureTypes // 0x07, number of signature types. Always leave at end. - } - - /// @dev Verifies signature using logic defined by Wallet contract. - /// @param hash Any 32 byte hash. - /// @param walletAddress Address that should have signed the given hash - /// and defines its own signature verification method. - /// @param signature Proof that the hash has been signed by signer. - /// @return True if the address recovered from the provided signature matches the input signer address. - function isValidWalletSignature( - bytes32 hash, - address walletAddress, - bytes signature - ) - internal - view - returns (bool isValid); - - /// @dev Verifies signature using logic defined by Validator contract. - /// @param validatorAddress Address of validator contract. - /// @param hash Any 32 byte hash. - /// @param signerAddress Address that should have signed the given hash. - /// @param signature Proof that the hash has been signed by signer. - /// @return True if the address recovered from the provided signature matches the input signer address. - function isValidValidatorSignature( - address validatorAddress, - bytes32 hash, - address signerAddress, - bytes signature - ) - internal - view - returns (bool isValid); -} diff --git a/packages/contracts/contracts/protocol/Exchange/mixins/MTransactions.sol b/packages/contracts/contracts/protocol/Exchange/mixins/MTransactions.sol deleted file mode 100644 index 4f61a4945..000000000 --- a/packages/contracts/contracts/protocol/Exchange/mixins/MTransactions.sol +++ /dev/null @@ -1,58 +0,0 @@ -/* - - Copyright 2018 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.24; - -import "../interfaces/ITransactions.sol"; - - -contract MTransactions is - ITransactions -{ - // Hash for the EIP712 ZeroEx Transaction Schema - bytes32 constant internal EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = keccak256(abi.encodePacked( - "ZeroExTransaction(", - "uint256 salt,", - "address signerAddress,", - "bytes data", - ")" - )); - - /// @dev Calculates EIP712 hash of the Transaction. - /// @param salt Arbitrary number to ensure uniqueness of transaction hash. - /// @param signerAddress Address of transaction signer. - /// @param data AbiV2 encoded calldata. - /// @return EIP712 hash of the Transaction. - function hashZeroExTransaction( - uint256 salt, - address signerAddress, - bytes memory data - ) - internal - pure - returns (bytes32 result); - - /// @dev The current function will be called in the context of this address (either 0x transaction signer or `msg.sender`). - /// If calling a fill function, this address will represent the taker. - /// If calling a cancel function, this address will represent the maker. - /// @return Signer of 0x transaction if entry point is `executeTransaction`. - /// `msg.sender` if entry point is any other function. - function getCurrentContextAddress() - internal - view - returns (address); -} diff --git a/packages/contracts/contracts/protocol/Exchange/mixins/MWrapperFunctions.sol b/packages/contracts/contracts/protocol/Exchange/mixins/MWrapperFunctions.sol deleted file mode 100644 index 4adfbde01..000000000 --- a/packages/contracts/contracts/protocol/Exchange/mixins/MWrapperFunctions.sol +++ /dev/null @@ -1,41 +0,0 @@ -/* - - Copyright 2018 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.24; -pragma experimental ABIEncoderV2; - -import "../libs/LibOrder.sol"; -import "../libs/LibFillResults.sol"; -import "../interfaces/IWrapperFunctions.sol"; - - -contract MWrapperFunctions is - IWrapperFunctions -{ - /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled. - /// @param order LibOrder.Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerAsset to sell. - /// @param signature Proof that order has been created by maker. - function fillOrKillOrderInternal( - LibOrder.Order memory order, - uint256 takerAssetFillAmount, - bytes memory signature - ) - internal - returns (LibFillResults.FillResults memory fillResults); -} |