From bb73963421eaf154194f4e32a933b50cb72ededc Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Sat, 12 May 2018 13:59:12 -0700 Subject: Changes based on style guidelines put out by Amir --- .../protocol/Exchange/MixinExchangeCore.sol | 184 +++++++++++---------- .../current/protocol/Exchange/MixinMatchOrders.sol | 23 ++- .../current/protocol/Exchange/MixinSettlement.sol | 6 +- .../protocol/Exchange/interfaces/IExchangeCore.sol | 14 ++ .../protocol/Exchange/interfaces/IMatchOrders.sol | 43 +++++ .../protocol/Exchange/libs/LibFillResults.sol | 8 +- .../protocol/Exchange/mixins/MExchangeCore.sol | 58 ++----- .../protocol/Exchange/mixins/MMatchOrders.sol | 38 ++--- .../protocol/Exchange/mixins/MSettlement.sol | 8 +- 9 files changed, 210 insertions(+), 172 deletions(-) create mode 100644 packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IMatchOrders.sol (limited to 'packages/contracts') diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol b/packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol index 2c23575c7..3e14e4cb4 100644 --- a/packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol +++ b/packages/contracts/src/contracts/current/protocol/Exchange/MixinExchangeCore.sol @@ -130,6 +130,88 @@ contract MixinExchangeCore is return (orderStatus, orderHash, takerAssetFilledAmount); } + /// @dev Fills the input order. + /// @param order Order struct containing order specifications. + /// @param takerAssetFillAmount Desired amount of takerToken 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 + returns (FillResults memory fillResults) + { + // Fetch order info + bytes32 orderHash; + uint8 orderStatus; + uint256 takerAssetFilledAmount; + (orderStatus, orderHash, takerAssetFilledAmount) = getOrderInfo(order); + + // Fetch taker address + address takerAddress = getCurrentContextAddress(); + + // Either our context is valid or we revert + validateFillOrRevert( + order, + orderStatus, + orderHash, + takerAddress, + takerAssetFilledAmount, + takerAssetFillAmount, + signature + ); + + // Compute proportional fill amounts + uint8 status; + (status, fillResults) = calculateFillResults( + order, + orderStatus, + takerAssetFilledAmount, + takerAssetFillAmount + ); + if (status != uint8(Status.SUCCESS)) { + emit ExchangeStatus(uint8(status), orderHash); + return fillResults; + } + + // Settle order + settleOrder(order, takerAddress, fillResults); + + // Update exchange internal state + updateFilledState( + order, + takerAddress, + orderHash, + takerAssetFilledAmount, + 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 Status.FILLABLE. + /// @return True if the order state changed to cancelled. + /// False if the order was order was in a valid, but + /// unfillable state (see LibStatus.STATUS for order states) + function cancelOrder(Order memory order) + public + returns (bool) + { + // Fetch current order status + bytes32 orderHash; + uint8 orderStatus; + (orderStatus, orderHash, ) = getOrderInfo(order); + + // Validate context + validateCancelOrRevert(order, orderStatus, orderHash); + + // Perform cancel + return updateCancelledState(order, orderStatus, orderHash); + } + /// @dev Validates context for fillOrder. Succeeds or throws. /// @param order to be filled. /// @param orderStatus Status of order to be filled. @@ -145,7 +227,8 @@ contract MixinExchangeCore is address takerAddress, uint256 takerAssetFilledAmount, uint256 takerAssetFillAmount, - bytes memory signature) + bytes memory signature + ) internal { // Ensure order is valid @@ -200,8 +283,9 @@ contract MixinExchangeCore is Order memory order, uint8 orderStatus, uint256 takerAssetFilledAmount, - uint256 takerAssetFillAmount) - public + uint256 takerAssetFillAmount + ) + internal pure returns ( uint8 status, @@ -241,15 +325,18 @@ contract MixinExchangeCore is fillResults.makerAssetFilledAmount = getPartialAmount( fillResults.takerAssetFilledAmount, order.takerAssetAmount, - order.makerAssetAmount); + order.makerAssetAmount + ); fillResults.makerFeePaid = getPartialAmount( fillResults.takerAssetFilledAmount, order.takerAssetAmount, - order.makerFee); + order.makerFee + ); fillResults.takerFeePaid = getPartialAmount( fillResults.takerAssetFilledAmount, order.takerAssetAmount, - order.takerFee); + order.takerFee + ); status = uint8(Status.SUCCESS); return; @@ -265,7 +352,8 @@ contract MixinExchangeCore is address takerAddress, bytes32 orderHash, uint256 takerAssetFilledAmount, - FillResults memory fillResults) + FillResults memory fillResults + ) internal { // Update state @@ -286,60 +374,6 @@ contract MixinExchangeCore is ); } - /// @dev Fills the input order. - /// @param order Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerToken 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 - returns (FillResults memory fillResults) - { - // Fetch order info - bytes32 orderHash; - uint8 orderStatus; - uint256 takerAssetFilledAmount; - (orderStatus, orderHash, takerAssetFilledAmount) = getOrderInfo(order); - - // Fetch taker address - address takerAddress = getCurrentContextAddress(); - - // Either our context is valid or we revert - validateFillOrRevert( - order, - orderStatus, - orderHash, - takerAddress, - takerAssetFilledAmount, - takerAssetFillAmount, - signature - ); - - // Compute proportional fill amounts - uint8 status; - (status, fillResults) = calculateFillResults(order, orderStatus, takerAssetFilledAmount, takerAssetFillAmount); - if (status != uint8(Status.SUCCESS)) { - emit ExchangeStatus(uint8(status), orderHash); - return fillResults; - } - - // Settle order - settleOrder(order, takerAddress, fillResults); - - // Update exchange internal state - updateFilledState( - order, - takerAddress, - orderHash, - takerAssetFilledAmount, - fillResults - ); - return fillResults; - } - /// @dev Validates context for cancelOrder. Succeeds or throws. /// @param order that was cancelled. /// @param orderStatus Status of order that was cancelled. @@ -347,7 +381,8 @@ contract MixinExchangeCore is function validateCancelOrRevert( Order memory order, uint8 orderStatus, - bytes32 orderHash) + bytes32 orderHash + ) internal { // Ensure order is valid @@ -388,7 +423,8 @@ contract MixinExchangeCore is function updateCancelledState( Order memory order, uint8 orderStatus, - bytes32 orderHash) + bytes32 orderHash + ) internal returns (bool stateUpdated) { @@ -414,26 +450,4 @@ contract MixinExchangeCore is return stateUpdated; } - - /// @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 Status.FILLABLE. - /// @return True if the order state changed to cancelled. - /// False if the order was order was in a valid, but - /// unfillable state (see LibStatus.STATUS for order states) - function cancelOrder(Order memory order) - public - returns (bool) - { - // Fetch current order status - bytes32 orderHash; - uint8 orderStatus; - (orderStatus, orderHash, ) = getOrderInfo(order); - - // Validate context - validateCancelOrRevert(order, orderStatus, orderHash); - - // Perform cancel - return updateCancelledState(order, orderStatus, orderHash); - } } diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/MixinMatchOrders.sol b/packages/contracts/src/contracts/current/protocol/Exchange/MixinMatchOrders.sol index ab4768d02..b20bc14ad 100644 --- a/packages/contracts/src/contracts/current/protocol/Exchange/MixinMatchOrders.sol +++ b/packages/contracts/src/contracts/current/protocol/Exchange/MixinMatchOrders.sol @@ -31,6 +31,7 @@ contract MixinMatchOrders is LibMath, LibStatus, LibOrder, + LibFillResults, LibExchangeErrors, MExchangeCore, MMatchOrders, @@ -51,7 +52,8 @@ contract MixinMatchOrders is Order memory leftOrder, Order memory rightOrder, bytes leftSignature, - bytes rightSignature) + bytes rightSignature + ) public returns (MatchedFillResults memory matchedFillResults) { @@ -119,7 +121,12 @@ contract MixinMatchOrders is ); // Settle matched orders. Succeeds or throws. - settleMatchedOrders(leftOrder, rightOrder, matchedFillResults, takerAddress); + settleMatchedOrders( + leftOrder, + rightOrder, + matchedFillResults, + takerAddress + ); // Update exchange state updateFilledState( @@ -146,7 +153,8 @@ contract MixinMatchOrders is /// @param rightOrder Second order to match. function validateMatchOrThrow( Order memory leftOrder, - Order memory rightOrder) + Order memory rightOrder + ) internal { // The leftOrder maker asset must be the same as the rightOrder taker asset. @@ -198,7 +206,8 @@ contract MixinMatchOrders is !isRoundingError( matchedFillResults.left.makerAssetFilledAmount, amountSpentByLeft, - 1), + 1 + ), ROUNDING_ERROR_TRANSFER_AMOUNTS ); @@ -214,7 +223,8 @@ contract MixinMatchOrders is !isRoundingError( matchedFillResults.right.makerAssetFilledAmount, matchedFillResults.left.takerAssetFilledAmount, - 1), + 1 + ), ROUNDING_ERROR_TRANSFER_AMOUNTS ); } @@ -237,7 +247,8 @@ contract MixinMatchOrders is uint8 leftOrderStatus, uint8 rightOrderStatus, uint256 leftOrderFilledAmount, - uint256 rightOrderFilledAmount) + uint256 rightOrderFilledAmount + ) internal returns ( uint8 status, diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/MixinSettlement.sol b/packages/contracts/src/contracts/current/protocol/Exchange/MixinSettlement.sol index 4911c62b5..7e324a5d2 100644 --- a/packages/contracts/src/contracts/current/protocol/Exchange/MixinSettlement.sol +++ b/packages/contracts/src/contracts/current/protocol/Exchange/MixinSettlement.sol @@ -64,7 +64,8 @@ contract MixinSettlement is function settleOrder( LibOrder.Order memory order, address takerAddress, - FillResults memory fillResults) + FillResults memory fillResults + ) internal { dispatchTransferFrom( @@ -102,7 +103,8 @@ contract MixinSettlement is LibOrder.Order memory leftOrder, LibOrder.Order memory rightOrder, MatchedFillResults memory matchedFillResults, - address takerAddress) + address takerAddress + ) internal { // Order makers and taker diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IExchangeCore.sol b/packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IExchangeCore.sol index 0f19525ca..f97c74123 100644 --- a/packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IExchangeCore.sol +++ b/packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IExchangeCore.sol @@ -29,6 +29,20 @@ contract IExchangeCore { function cancelOrdersUpTo(uint256 salt) external; + /// @dev Gets information about an order: status, hash, and amount filled. + /// @param order Order to gather information on. + /// @return status Status of order. Statuses are defined in the LibStatus.Status struct. + /// @return orderHash Keccak-256 EIP712 hash of the order. + /// @return takerAssetFilledAmount Amount of order that has been filled. + function getOrderInfo(LibOrder.Order memory order) + public + view + returns ( + uint8 orderStatus, + bytes32 orderHash, + uint256 takerAssetFilledAmount + ); + /// @dev Fills the input order. /// @param order Order struct containing order specifications. /// @param takerAssetFillAmount Desired amount of takerAsset to sell. diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IMatchOrders.sol b/packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IMatchOrders.sol new file mode 100644 index 000000000..fe8cee5f1 --- /dev/null +++ b/packages/contracts/src/contracts/current/protocol/Exchange/interfaces/IMatchOrders.sol @@ -0,0 +1,43 @@ +/* + + 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.23; +pragma experimental ABIEncoderV2; + +import "../libs/LibOrder.sol"; +import "../libs/LibFillResults.sol"; + +contract IMatchOrders { + + /// @dev Match two complementary orders that have a positive 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 leftSignature, + bytes rightSignature + ) + public + returns (LibFillResults.MatchedFillResults memory matchedFillResults); +} diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibFillResults.sol b/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibFillResults.sol index 3b8f2acf9..c4647c44f 100644 --- a/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibFillResults.sol +++ b/packages/contracts/src/contracts/current/protocol/Exchange/libs/LibFillResults.sol @@ -31,6 +31,12 @@ contract LibFillResults is uint256 takerFeePaid; } + struct MatchedFillResults { + LibFillResults.FillResults left; + LibFillResults.FillResults right; + uint256 takerFillAmount; + } + /// @dev Adds properties of both FillResults instances. /// Modifies the first FillResults instance specified. /// @param totalFillResults Fill results instance that will be added onto. @@ -44,4 +50,4 @@ contract LibFillResults is totalFillResults.makerFeePaid = safeAdd(totalFillResults.makerFeePaid, singleFillResults.makerFeePaid); totalFillResults.takerFeePaid = safeAdd(totalFillResults.takerFeePaid, singleFillResults.takerFeePaid); } -} \ No newline at end of file +} diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MExchangeCore.sol b/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MExchangeCore.sol index 6f7d99c48..f166abb71 100644 --- a/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MExchangeCore.sol +++ b/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MExchangeCore.sol @@ -56,25 +56,6 @@ contract MExchangeCore is uint256 makerEpoch ); - /// @dev Cancels all orders reated by sender with a salt less than or equal to the specified salt value. - /// @param salt Orders created with a salt less or equal to this value will be cancelled. - function cancelOrdersUpTo(uint256 salt) - external; - - /// @dev Gets information about an order: status, hash, and amount filled. - /// @param order Order to gather information on. - /// @return status Status of order. Statuses are defined in the LibStatus.Status struct. - /// @return orderHash Keccak-256 EIP712 hash of the order. - /// @return takerAssetFilledAmount Amount of order that has been filled. - function getOrderInfo(LibOrder.Order memory order) - public - view - returns ( - uint8 orderStatus, - bytes32 orderHash, - uint256 takerAssetFilledAmount - ); - /// @dev Validates context for fillOrder. Succeeds or throws. /// @param order to be filled. /// @param orderStatus Status of order to be filled. @@ -90,7 +71,8 @@ contract MExchangeCore is address takerAddress, uint256 takerAssetFilledAmount, uint256 takerAssetFillAmount, - bytes memory signature) + bytes memory signature + ) internal; /// @dev Calculates amounts filled and fees paid by maker and taker. @@ -104,8 +86,9 @@ contract MExchangeCore is LibOrder.Order memory order, uint8 orderStatus, uint256 takerAssetFilledAmount, - uint256 takerAssetFillAmount) - public + uint256 takerAssetFillAmount + ) + internal pure returns ( uint8 status, @@ -122,21 +105,10 @@ contract MExchangeCore is address takerAddress, bytes32 orderHash, uint256 takerAssetFilledAmount, - LibFillResults.FillResults memory fillResults) + LibFillResults.FillResults memory fillResults + ) internal; - /// @dev Fills the input order. - /// @param order Order struct containing order specifications. - /// @param takerAssetFillAmount Desired amount of takerToken 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 Validates context for cancelOrder. Succeeds or throws. /// @param order that was cancelled. /// @param orderStatus Status of order that was cancelled. @@ -144,7 +116,8 @@ contract MExchangeCore is function validateCancelOrRevert( LibOrder.Order memory order, uint8 orderStatus, - bytes32 orderHash) + bytes32 orderHash + ) internal; /// @dev Updates state with results of cancelling an order. @@ -157,17 +130,8 @@ contract MExchangeCore is function updateCancelledState( LibOrder.Order memory order, uint8 orderStatus, - bytes32 orderHash) + bytes32 orderHash + ) internal returns (bool stateUpdated); - - /// @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 Status.FILLABLE. - /// @return True if the order state changed to cancelled. - /// False if the order was order was in a valid, but - /// unfillable state (see LibStatus.STATUS for order states) - function cancelOrder(LibOrder.Order memory order) - public - returns (bool); } diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MMatchOrders.sol b/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MMatchOrders.sol index 17b6cd92d..60a266250 100644 --- a/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MMatchOrders.sol +++ b/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MMatchOrders.sol @@ -21,14 +21,11 @@ pragma experimental ABIEncoderV2; import "../libs/LibOrder.sol"; import "../libs/LibFillResults.sol"; import "./MExchangeCore.sol"; +import "../interfaces/IMatchOrders.sol"; -contract MMatchOrders { - - struct MatchedFillResults { - LibFillResults.FillResults left; - LibFillResults.FillResults right; - uint256 takerFillAmount; - } +contract MMatchOrders is + IMatchOrders +{ /// This struct exists solely to avoid the stack limit constraint /// in matchOrders @@ -38,34 +35,18 @@ contract MMatchOrders { uint256 orderFilledAmount; } - /// @dev Match two complementary orders that have a positive 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 leftSignature, - bytes rightSignature) - public - returns (MatchedFillResults memory matchedFillResults); - /// @dev Validates context for matchOrders. Succeeds or throws. /// @param leftOrder First order to match. /// @param rightOrder Second order to match. function validateMatchOrThrow( LibOrder.Order memory leftOrder, - LibOrder.Order memory rightOrder) + LibOrder.Order memory rightOrder + ) internal; /// @dev Validates matched fill results. Succeeds or throws. /// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders. - function validateMatchOrThrow(MatchedFillResults memory matchedFillResults) + function validateMatchOrThrow(LibFillResults.MatchedFillResults memory matchedFillResults) internal; /// @dev Calculates fill amounts for the matched orders. @@ -86,10 +67,11 @@ contract MMatchOrders { uint8 leftOrderStatus, uint8 rightOrderStatus, uint256 leftOrderFilledAmount, - uint256 rightOrderFilledAmount) + uint256 rightOrderFilledAmount + ) internal returns ( uint8 status, - MatchedFillResults memory matchedFillResults + LibFillResults.MatchedFillResults memory matchedFillResults ); } diff --git a/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MSettlement.sol b/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MSettlement.sol index bd9042f62..d0de385db 100644 --- a/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MSettlement.sol +++ b/packages/contracts/src/contracts/current/protocol/Exchange/mixins/MSettlement.sol @@ -31,7 +31,8 @@ contract MSettlement { function settleOrder( LibOrder.Order memory order, address takerAddress, - LibFillResults.FillResults memory fillResults) + LibFillResults.FillResults memory fillResults + ) internal; /// @dev Settles matched order by transferring appropriate funds between order makers, taker, and fee recipient. @@ -42,7 +43,8 @@ contract MSettlement { function settleMatchedOrders( LibOrder.Order memory leftOrder, LibOrder.Order memory rightOrder, - MMatchOrders.MatchedFillResults memory matchedFillResults, - address takerAddress) + LibFillResults.MatchedFillResults memory matchedFillResults, + address takerAddress + ) internal; } -- cgit