aboutsummaryrefslogtreecommitdiffstats
path: root/contracts/exchange-libs/contracts/libs/LibOrder.sol
diff options
context:
space:
mode:
Diffstat (limited to 'contracts/exchange-libs/contracts/libs/LibOrder.sol')
-rw-r--r--contracts/exchange-libs/contracts/libs/LibOrder.sol145
1 files changed, 145 insertions, 0 deletions
diff --git a/contracts/exchange-libs/contracts/libs/LibOrder.sol b/contracts/exchange-libs/contracts/libs/LibOrder.sol
new file mode 100644
index 000000000..fcf5da5fb
--- /dev/null
+++ b/contracts/exchange-libs/contracts/libs/LibOrder.sol
@@ -0,0 +1,145 @@
+/*
+
+ 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;
+ }
+}