aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Hysen <greg.hysen@gmail.com>2018-12-14 06:26:11 +0800
committerGreg Hysen <greg.hysen@gmail.com>2018-12-19 05:36:05 +0800
commitdea6f35b0471913551d58a08f547974701fc0057 (patch)
tree17e04945fc4385fcc952a9c0e05f5a2eaedde9e6
parentf3a2e3b6f3adb75d1920779df9dabb7cf476a996 (diff)
downloaddexon-sol-tools-dea6f35b0471913551d58a08f547974701fc0057.tar
dexon-sol-tools-dea6f35b0471913551d58a08f547974701fc0057.tar.gz
dexon-sol-tools-dea6f35b0471913551d58a08f547974701fc0057.tar.bz2
dexon-sol-tools-dea6f35b0471913551d58a08f547974701fc0057.tar.lz
dexon-sol-tools-dea6f35b0471913551d58a08f547974701fc0057.tar.xz
dexon-sol-tools-dea6f35b0471913551d58a08f547974701fc0057.tar.zst
dexon-sol-tools-dea6f35b0471913551d58a08f547974701fc0057.zip
Refactoring balance threshold filter
-rw-r--r--contracts/extensions/contracts/BalanceThresholdFilter/BalanceThresholdFilter.sol1
-rw-r--r--contracts/extensions/contracts/BalanceThresholdFilter/MixinBalanceThresholdFilterCore.sol63
-rw-r--r--contracts/extensions/contracts/BalanceThresholdFilter/MixinExchangeCalldata.sol102
-rw-r--r--contracts/extensions/contracts/BalanceThresholdFilter/interfaces/IBalanceThresholdFilterCore.sol56
-rw-r--r--contracts/extensions/contracts/BalanceThresholdFilter/mixins/MBalanceThresholdFilterCore.sol50
-rw-r--r--contracts/extensions/contracts/BalanceThresholdFilter/mixins/MExchangeCalldata.sol57
-rw-r--r--contracts/libs/contracts/libs/LibAddressArray.sol75
-rw-r--r--contracts/libs/contracts/libs/LibExchangeSelectors.sol151
8 files changed, 481 insertions, 74 deletions
diff --git a/contracts/extensions/contracts/BalanceThresholdFilter/BalanceThresholdFilter.sol b/contracts/extensions/contracts/BalanceThresholdFilter/BalanceThresholdFilter.sol
index ea248793f..16cacd461 100644
--- a/contracts/extensions/contracts/BalanceThresholdFilter/BalanceThresholdFilter.sol
+++ b/contracts/extensions/contracts/BalanceThresholdFilter/BalanceThresholdFilter.sol
@@ -17,7 +17,6 @@
*/
pragma solidity 0.4.24;
-pragma experimental ABIEncoderV2;
import "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchange.sol";
import "./interfaces/IThresholdAsset.sol";
diff --git a/contracts/extensions/contracts/BalanceThresholdFilter/MixinBalanceThresholdFilterCore.sol b/contracts/extensions/contracts/BalanceThresholdFilter/MixinBalanceThresholdFilterCore.sol
index 8d15fe6c8..a8947751a 100644
--- a/contracts/extensions/contracts/BalanceThresholdFilter/MixinBalanceThresholdFilterCore.sol
+++ b/contracts/extensions/contracts/BalanceThresholdFilter/MixinBalanceThresholdFilterCore.sol
@@ -62,8 +62,19 @@ contract MixinBalanceThresholdFilterCore is
)
external
{
- // Validate addresses.
- validateBalanceThresholdsOrRevert(signerAddress);
+ // Get accounts whose balances must be validated
+ address[] memory addressesToValidate = getAddressesToValidate(signerAddress);
+
+ // Validate account balances
+ uint256 balanceThreshold = BALANCE_THRESHOLD;
+ IThresholdAsset thresholdAsset = THRESHOLD_ASSET;
+ for(uint256 i = 0; i < addressesToValidate.length; ++i) {
+ uint256 addressBalance = thresholdAsset.balanceOf(addressesToValidate[i]);
+ if (addressBalance < balanceThreshold) {
+ revert("AT_LEAST_ONE_ADDRESS_DOES_NOT_MEET_BALANCE_THRESHOLD");
+ }
+ }
+ emit ValidatedAddresses(addressesToValidate);
// All addresses are valid. Execute fillOrder.
EXCHANGE.executeTransaction(
@@ -74,20 +85,15 @@ contract MixinBalanceThresholdFilterCore is
);
}
-
-
- /// @dev Validates addresses meet the balance threshold specified by `BALANCE_THRESHOLD`
- /// for the asset `THRESHOLD_ASSET`. If one address does not meet the thresold
- /// then this function will revert. Which addresses are validated depends on
- /// which Exchange function is to be called (defined by `signedExchangeTransaction` above).
- /// No parameters are taken as this function reads arguments directly from calldata, to save gas.
- /// If all addresses are valid then this function emits a ValidatedAddresses event, listing all
- /// of the addresses whose balance thresholds it checked.
- function validateBalanceThresholdsOrRevert(address signerAddress)
- internal
+ /// @dev Constructs an array of addresses to be validated.
+ /// Addresses depend on which Exchange function is to be called
+ /// (defined by `signedExchangeTransaction` above).
+ /// @param signerAddress Address of transaction signer.
+ /// @return addressesToValidate Array of addresses to validate.
+ function getAddressesToValidate(address signerAddress)
+ internal pure
+ returns (address[] memory addressesToValidate)
{
- // Extract addresses to validate from Exchange calldata
- address[] memory addressesToValidate = new address[](0);
bytes4 exchangeFunctionSelector = bytes4(exchangeCalldataload(0));
if(
exchangeFunctionSelector == batchFillOrdersSelector ||
@@ -99,21 +105,21 @@ contract MixinBalanceThresholdFilterCore is
exchangeFunctionSelector == marketSellOrdersNoThrowSelector
) {
addressesToValidate = loadMakerAddressesFromOrderArray(0);
- recordAddressToValidate(signerAddress, addressesToValidate);
+ addressesToValidate = addressesToValidate.append(signerAddress);
} else if(
exchangeFunctionSelector == fillOrderSelector ||
exchangeFunctionSelector == fillOrderNoThrowSelector ||
exchangeFunctionSelector == fillOrKillOrderSelector
) {
address makerAddress = loadMakerAddressFromOrder(0);
- recordAddressToValidate(makerAddress, addressesToValidate);
- recordAddressToValidate(signerAddress, addressesToValidate);
+ addressesToValidate = addressesToValidate.append(makerAddress);
+ addressesToValidate = addressesToValidate.append(signerAddress);
} else if(exchangeFunctionSelector == matchOrdersSelector) {
- address leftOrderAddress = loadMakerAddressFromOrder(0);
- recordAddressToValidate(leftOrderAddress, addressesToValidate);
- address rightOrderAddress = loadMakerAddressFromOrder(1);
- recordAddressToValidate(rightOrderAddress, addressesToValidate);
- recordAddressToValidate(signerAddress, addressesToValidate);
+ address leftMakerAddress = loadMakerAddressFromOrder(0);
+ addressesToValidate = addressesToValidate.append(leftMakerAddress);
+ address rightMakerAddress = loadMakerAddressFromOrder(1);
+ addressesToValidate = addressesToValidate.append(rightMakerAddress);
+ addressesToValidate = addressesToValidate.append(signerAddress);
} else if(
exchangeFunctionSelector != cancelOrderSelector &&
exchangeFunctionSelector != batchCancelOrdersSelector &&
@@ -121,16 +127,5 @@ contract MixinBalanceThresholdFilterCore is
) {
revert("INVALID_OR_BLOCKED_EXCHANGE_SELECTOR");
}
-
- // Validate account balances
- uint256 balanceThreshold = BALANCE_THRESHOLD;
- IThresholdAsset thresholdAsset = THRESHOLD_ASSET;
- for(uint i = 0; i < addressesToValidate.length; ++i) {
- uint256 addressBalance = thresholdAsset.balanceOf(addressesToValidate[i]);
- if (addressBalance < balanceThreshold) {
- revert("AT_LEAST_ONE_ADDRESS_DOES_NOT_MEET_BALANCE_THRESHOLD");
- }
- }
- emit ValidatedAddresses(addressesToValidate);
}
}
diff --git a/contracts/extensions/contracts/BalanceThresholdFilter/MixinExchangeCalldata.sol b/contracts/extensions/contracts/BalanceThresholdFilter/MixinExchangeCalldata.sol
new file mode 100644
index 000000000..12f601dea
--- /dev/null
+++ b/contracts/extensions/contracts/BalanceThresholdFilter/MixinExchangeCalldata.sol
@@ -0,0 +1,102 @@
+
+ /*
+
+ 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/LICENSE2.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 "./mixins/MExchangeCalldata.sol";
+import "@0x/contracts-libs/contracts/libs/LibAddressArray.sol";
+
+
+contract MixinExchangeCalldata is
+ MExchangeCalldata
+{
+
+ using LibAddressArray for address[];
+
+ /// @dev Emulates the `calldataload` opcode on the embedded Exchange calldata,
+ /// which is accessed through `signedExchangeTransaction`.
+ /// @param offset Offset into the Exchange calldata.
+ /// @return value Corresponding 32 byte value stored at `offset`.
+ function exchangeCalldataload(uint256 offset)
+ internal pure
+ returns (bytes32 value)
+ {
+ assembly {
+ // Pointer to exchange transaction
+ // 0x04 for calldata selector
+ // 0x40 to access `signedExchangeTransaction`, which is the third parameter
+ let exchangeTxPtr := calldataload(0x44)
+
+ // Offset into Exchange calldata
+ // We compute this by adding 0x24 to the `exchangeTxPtr` computed above.
+ // 0x04 for calldata selector
+ // 0x20 for length field of `signedExchangeTransaction`
+ let exchangeCalldataOffset := add(exchangeTxPtr, add(0x24, offset))
+ value := calldataload(exchangeCalldataOffset)
+ }
+ }
+
+ /// @dev Convenience function that skips the 4 byte selector when loading
+ /// from the embedded Exchange calldata.
+ /// @param offset Offset into the Exchange calldata (minus the 4 byte selector)
+ /// @return value Corresponding 32 byte value stored at `offset` + 4.
+ function loadExchangeData(uint256 offset)
+ internal pure
+ returns (bytes32 value)
+ {
+ value = exchangeCalldataload(offset + 4);
+ }
+
+ /// @dev Extracts the maker address from an order stored in the Exchange calldata
+ /// (which is embedded in `signedExchangeTransaction`).
+ /// @param orderParamIndex Index of the order in the Exchange function's signature.
+ /// @return makerAddress The extracted maker address.
+ function loadMakerAddressFromOrder(uint256 orderParamIndex)
+ internal pure
+ returns (address makerAddress)
+ {
+ uint256 orderOffsetInBytes = orderParamIndex * 32;
+ uint256 orderPtr = uint256(loadExchangeData(orderOffsetInBytes));
+ makerAddress = address(loadExchangeData(orderPtr));
+ return makerAddress;
+ }
+
+ /// @dev Extracts the maker addresses from an array of orders stored in the Exchange calldata
+ /// (which is embedded in `signedExchangeTransaction`), and records them in
+ /// the running list of addresses to validate.
+ /// @param orderArrayParamIndex Index of the order array in the Exchange function's signature
+ /// @return makerAddresses The extracted maker addresses.
+ function loadMakerAddressesFromOrderArray(uint256 orderArrayParamIndex)
+ internal pure
+ returns (address[] makerAddresses)
+ {
+ uint256 orderArrayOffsetInBytes = orderArrayParamIndex * 32;
+ uint256 orderArrayPtr = uint256(loadExchangeData(orderArrayOffsetInBytes));
+ uint256 orderArrayLength = uint256(loadExchangeData(orderArrayPtr));
+ uint256 orderArrayLengthInBytes = orderArrayLength * 32;
+ uint256 orderArrayElementPtr = orderArrayPtr + 32;
+ uint256 orderArrayElementEndPtr = orderArrayElementPtr + orderArrayLengthInBytes;
+ for(uint orderPtrOffset = orderArrayElementPtr; orderPtrOffset < orderArrayElementEndPtr; orderPtrOffset += 32) {
+ uint256 orderPtr = uint256(loadExchangeData(orderPtrOffset));
+ address makerAddress = address(loadExchangeData(orderPtr + orderArrayElementPtr));
+ makerAddresses = makerAddresses.append(makerAddress);
+ }
+ return makerAddresses;
+ }
+}
diff --git a/contracts/extensions/contracts/BalanceThresholdFilter/interfaces/IBalanceThresholdFilterCore.sol b/contracts/extensions/contracts/BalanceThresholdFilter/interfaces/IBalanceThresholdFilterCore.sol
new file mode 100644
index 000000000..37e607be1
--- /dev/null
+++ b/contracts/extensions/contracts/BalanceThresholdFilter/interfaces/IBalanceThresholdFilterCore.sol
@@ -0,0 +1,56 @@
+
+/*
+
+ 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 IBalanceThresholdFilterCore {
+
+ /// @dev Executes an Exchange transaction iff the maker and taker meet
+ /// the hold at least `BALANCE_THRESHOLD` of the asset `THRESHOLD_ASSET` OR
+ /// the exchange function is a cancellation.
+ /// Supported Exchange functions:
+ /// - batchFillOrders
+ /// - batchFillOrdersNoThrow
+ /// - batchFillOrKillOrders
+ /// - fillOrder
+ /// - fillOrderNoThrow
+ /// - fillOrKillOrder
+ /// - marketBuyOrders
+ /// - marketBuyOrdersNoThrow
+ /// - marketSellOrders
+ /// - marketSellOrdersNoThrow
+ /// - matchOrders
+ /// - cancelOrder
+ /// - batchCancelOrders
+ /// - cancelOrdersUpTo
+ /// Trying to call any other exchange function will throw.
+ /// @param salt Arbitrary number to ensure uniqueness of transaction hash.
+ /// @param signerAddress Address of transaction signer.
+ /// @param signedExchangeTransaction AbiV2 encoded calldata.
+ /// @param signature Proof of signer transaction by signer.
+ function executeTransaction(
+ uint256 salt,
+ address signerAddress,
+ bytes signedExchangeTransaction,
+ bytes signature
+ )
+ external;
+} \ No newline at end of file
diff --git a/contracts/extensions/contracts/BalanceThresholdFilter/mixins/MBalanceThresholdFilterCore.sol b/contracts/extensions/contracts/BalanceThresholdFilter/mixins/MBalanceThresholdFilterCore.sol
index 6aaa729fb..b8b67e6ee 100644
--- a/contracts/extensions/contracts/BalanceThresholdFilter/mixins/MBalanceThresholdFilterCore.sol
+++ b/contracts/extensions/contracts/BalanceThresholdFilter/mixins/MBalanceThresholdFilterCore.sol
@@ -20,9 +20,12 @@ pragma solidity 0.4.24;
import "@0x/contracts-interfaces/contracts/protocol/Exchange/IExchange.sol";
import "../interfaces/IThresholdAsset.sol";
+import "../interfaces/IBalanceThresholdFilterCore.sol";
-contract MBalanceThresholdFilterCore {
+contract MBalanceThresholdFilterCore is
+ IBalanceThresholdFilterCore
+{
// Points to 0x exchange contract
// solhint-disable var-name-mixedcase
@@ -40,43 +43,12 @@ contract MBalanceThresholdFilterCore {
address[] addresses
);
- /// @dev Executes an Exchange transaction iff the maker and taker meet
- /// the hold at least `BALANCE_THRESHOLD` of the asset `THRESHOLD_ASSET` OR
- /// the exchange function is a cancellation.
- /// Supported Exchange functions:
- /// - batchFillOrders
- /// - batchFillOrdersNoThrow
- /// - batchFillOrKillOrders
- /// - fillOrder
- /// - fillOrderNoThrow
- /// - fillOrKillOrder
- /// - marketBuyOrders
- /// - marketBuyOrdersNoThrow
- /// - marketSellOrders
- /// - marketSellOrdersNoThrow
- /// - matchOrders
- /// - cancelOrder
- /// - batchCancelOrders
- /// - cancelOrdersUpTo
- /// Trying to call any other exchange function will throw.
- /// @param salt Arbitrary number to ensure uniqueness of transaction hash.
+ /// @dev Constructs an array of addresses to be validated.
+ /// Addresses depend on which Exchange function is to be called
+ /// (defined by `signedExchangeTransaction` above).
/// @param signerAddress Address of transaction signer.
- /// @param signedExchangeTransaction AbiV2 encoded calldata.
- /// @param signature Proof of signer transaction by signer.
- function executeTransaction(
- uint256 salt,
- address signerAddress,
- bytes signedExchangeTransaction,
- bytes signature
- )
- external;
-
- /// @dev Validates addresses meet the balance threshold specified by `BALANCE_THRESHOLD`
- /// for the asset `THRESHOLD_ASSET`. If one address does not meet the thresold
- /// then this function will revert. Which addresses are validated depends on
- /// which Exchange function is to be called (defined by `signedExchangeTransaction` above).
- /// No parameters are taken as this function reads arguments directly from calldata, to save gas.
- /// If all addresses are valid then this function emits a ValidatedAddresses event, listing all
- /// of the addresses whose balance thresholds it checked.
- function validateBalanceThresholdsOrRevert(address signerAddress) internal;
+ /// @return addressesToValidate Array of addresses to validate.
+ function getAddressesToValidate(address signerAddress)
+ internal pure
+ returns (address[] memory addressesToValidate);
}
diff --git a/contracts/extensions/contracts/BalanceThresholdFilter/mixins/MExchangeCalldata.sol b/contracts/extensions/contracts/BalanceThresholdFilter/mixins/MExchangeCalldata.sol
new file mode 100644
index 000000000..8e0414c17
--- /dev/null
+++ b/contracts/extensions/contracts/BalanceThresholdFilter/mixins/MExchangeCalldata.sol
@@ -0,0 +1,57 @@
+
+ /*
+
+ 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/LICENSE2.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 MExchangeCalldata {
+
+ /// @dev Emulates the `calldataload` opcode on the embedded Exchange calldata,
+ /// which is accessed through `signedExchangeTransaction`.
+ /// @param offset Offset into the Exchange calldata.
+ /// @return value Corresponding 32 byte value stored at `offset`.
+ function exchangeCalldataload(uint256 offset)
+ internal pure
+ returns (bytes32 value);
+
+ /// @dev Convenience function that skips the 4 byte selector when loading
+ /// from the embedded Exchange calldata.
+ /// @param offset Offset into the Exchange calldata (minus the 4 byte selector)
+ /// @return value Corresponding 32 byte value stored at `offset` + 4.
+ function loadExchangeData(uint256 offset)
+ internal pure
+ returns (bytes32 value);
+
+ /// @dev Extracts the maker address from an order stored in the Exchange calldata
+ /// (which is embedded in `signedExchangeTransaction`).
+ /// @param orderParamIndex Index of the order in the Exchange function's signature.
+ /// @return makerAddress The extracted maker address.
+ function loadMakerAddressFromOrder(uint256 orderParamIndex)
+ internal pure
+ returns (address makerAddress);
+
+ /// @dev Extracts the maker addresses from an array of orders stored in the Exchange calldata
+ /// (which is embedded in `signedExchangeTransaction`), and records them in
+ /// the running list of addresses to validate.
+ /// @param orderArrayParamIndex Index of the order array in the Exchange function's signature
+ /// @return makerAddresses The extracted maker addresses.
+ function loadMakerAddressesFromOrderArray(uint256 orderArrayParamIndex)
+ internal pure
+ returns (address[] makerAddresses);
+}
diff --git a/contracts/libs/contracts/libs/LibAddressArray.sol b/contracts/libs/contracts/libs/LibAddressArray.sol
new file mode 100644
index 000000000..db76ddedb
--- /dev/null
+++ b/contracts/libs/contracts/libs/LibAddressArray.sol
@@ -0,0 +1,75 @@
+/*
+
+ 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 "@0x/contracts-utils/contracts/utils/LibBytes/LibBytes.sol";
+
+
+library LibAddressArray {
+
+ /// @dev Append a new address to an array of addresses.
+ /// The `addressArray` may need to be reallocated to make space
+ /// for the new address. Because of this we return the resulting
+ /// memory location of `addressArray`.
+ /// @param addressToAppend Address to append.
+ /// @return Array of addresses: [... addressArray, addressToAppend]
+ function append(address[] memory addressArray, address addressToAppend)
+ internal pure
+ returns (address[])
+ {
+ // Get stats on address array and free memory
+ uint256 freeMemPtr = 0;
+ uint256 addressArrayBeginPtr = 0;
+ uint256 addressArrayEndPtr = 0;
+ uint256 addressArrayLength = addressArray.length;
+ uint256 addressArrayMemSizeInBytes = 32 + (32 * addressArrayLength);
+ assembly {
+ freeMemPtr := mload(0x40)
+ addressArrayBeginPtr := addressArray
+ addressArrayEndPtr := add(addressArray, addressArrayMemSizeInBytes)
+ }
+
+ // If free memory begins at the end of `addressArray`
+ // then we can append `addressToAppend` directly.
+ // Otherwise, we must copy the array to free memory
+ // before appending new values to it.
+ if (freeMemPtr != addressArrayEndPtr) {
+ LibBytes.memCopy(freeMemPtr, addressArrayBeginPtr, addressArrayMemSizeInBytes);
+ assembly {
+ addressArray := freeMemPtr
+ addressArrayBeginPtr := addressArray
+ }
+ }
+
+ // Append `addressToAppend`
+ addressArrayLength += 1;
+ addressArrayMemSizeInBytes += 32;
+ addressArrayEndPtr = addressArrayBeginPtr + addressArrayMemSizeInBytes;
+ freeMemPtr = addressArrayEndPtr;
+ assembly {
+ // Store new array length
+ mstore(addressArray, addressArrayLength)
+
+ // Update `freeMemPtr`
+ mstore(0x40, freeMemPtr)
+ }
+ addressArray[addressArrayLength - 1] = addressToAppend;
+ return addressArray;
+ }
+}
diff --git a/contracts/libs/contracts/libs/LibExchangeSelectors.sol b/contracts/libs/contracts/libs/LibExchangeSelectors.sol
new file mode 100644
index 000000000..6a5344340
--- /dev/null
+++ b/contracts/libs/contracts/libs/LibExchangeSelectors.sol
@@ -0,0 +1,151 @@
+/*
+
+ 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 LibExchangeSelectors {
+
+ // allowedValidators
+ bytes4 constant allowedValidatorsSelector = 0x7b8e3514;
+ bytes4 constant allowedValidatorsSelectorGenerator = bytes4(keccak256('allowedValidators(address,address)'));
+
+ // assetProxies
+ bytes4 constant assetProxiesSelector = 0x3fd3c997;
+ bytes4 constant assetProxiesSelectorGenerator = bytes4(keccak256('assetProxies(bytes4)'));
+
+ // batchCancelOrders
+ bytes4 constant batchCancelOrdersSelector = 0x4ac14782;
+ bytes4 constant batchCancelOrdersSelectorGenerator = bytes4(keccak256('batchCancelOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[])'));
+
+ // batchFillOrKillOrders
+ bytes4 constant batchFillOrKillOrdersSelector = 0x4d0ae546;
+ bytes4 constant batchFillOrKillOrdersSelectorGenerator = bytes4(keccak256('batchFillOrKillOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256[],bytes[])'));
+
+ // batchFillOrders
+ bytes4 constant batchFillOrdersSelector = 0x297bb70b;
+ bytes4 constant batchFillOrdersSelectorGenerator = bytes4(keccak256('batchFillOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256[],bytes[])'));
+
+ // batchFillOrdersNoThrow
+ bytes4 constant batchFillOrdersNoThrowSelector = 0x50dde190;
+ bytes4 constant batchFillOrdersNoThrowSelectorGenerator = bytes4(keccak256('batchFillOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256[],bytes[])'));
+
+ // cancelOrder
+ bytes4 constant cancelOrderSelector = 0xd46b02c3;
+ bytes4 constant cancelOrderSelectorGenerator = bytes4(keccak256('cancelOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes))'));
+
+ // cancelOrdersUpTo
+ bytes4 constant cancelOrdersUpToSelector = 0x4f9559b1;
+ bytes4 constant cancelOrdersUpToSelectorGenerator = bytes4(keccak256('cancelOrdersUpTo(uint256)'));
+
+ // cancelled
+ bytes4 constant cancelledSelector = 0x2ac12622;
+ bytes4 constant cancelledSelectorGenerator = bytes4(keccak256('cancelled(bytes32)'));
+
+ // currentContextAddress
+ bytes4 constant currentContextAddressSelector = 0xeea086ba;
+ bytes4 constant currentContextAddressSelectorGenerator = bytes4(keccak256('currentContextAddress()'));
+
+ // executeTransaction
+ bytes4 constant executeTransactionSelector = 0xbfc8bfce;
+ bytes4 constant executeTransactionSelectorGenerator = bytes4(keccak256('executeTransaction(uint256,address,bytes,bytes)'));
+
+ // fillOrKillOrder
+ bytes4 constant fillOrKillOrderSelector = 0x64a3bc15;
+ bytes4 constant fillOrKillOrderSelectorGenerator = bytes4(keccak256('fillOrKillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),uint256,bytes)'));
+
+ // fillOrder
+ bytes4 constant fillOrderSelector = 0xb4be83d5;
+ bytes4 constant fillOrderSelectorGenerator = bytes4(keccak256('fillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),uint256,bytes)'));
+
+ // fillOrderNoThrow
+ bytes4 constant fillOrderNoThrowSelector = 0x3e228bae;
+ bytes4 constant fillOrderNoThrowSelectorGenerator = bytes4(keccak256('fillOrderNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),uint256,bytes)'));
+
+ // filled
+ bytes4 constant filledSelector = 0x288cdc91;
+ bytes4 constant filledSelectorGenerator = bytes4(keccak256('filled(bytes32)'));
+
+ // getAssetProxy
+ bytes4 constant getAssetProxySelector = 0x60704108;
+ bytes4 constant getAssetProxySelectorGenerator = bytes4(keccak256('getAssetProxy(bytes4)'));
+
+ // getOrderInfo
+ bytes4 constant getOrderInfoSelector = 0xc75e0a81;
+ bytes4 constant getOrderInfoSelectorGenerator = bytes4(keccak256('getOrderInfo((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes))'));
+
+ // getOrdersInfo
+ bytes4 constant getOrdersInfoSelector = 0x7e9d74dc;
+ bytes4 constant getOrdersInfoSelectorGenerator = bytes4(keccak256('getOrdersInfo((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[])'));
+
+ // isValidSignature
+ bytes4 constant isValidSignatureSelector = 0x93634702;
+ bytes4 constant isValidSignatureSelectorGenerator = bytes4(keccak256('isValidSignature(bytes32,address,bytes)'));
+
+ // marketBuyOrders
+ bytes4 constant marketBuyOrdersSelector = 0xe5fa431b;
+ bytes4 constant marketBuyOrdersSelectorGenerator = bytes4(keccak256('marketBuyOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256,bytes[])'));
+
+ // marketBuyOrdersNoThrow
+ bytes4 constant marketBuyOrdersNoThrowSelector = 0xa3e20380;
+ bytes4 constant marketBuyOrdersNoThrowSelectorGenerator = bytes4(keccak256('marketBuyOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256,bytes[])'));
+
+ // marketSellOrders
+ bytes4 constant marketSellOrdersSelector = 0x7e1d9808;
+ bytes4 constant marketSellOrdersSelectorGenerator = bytes4(keccak256('marketSellOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256,bytes[])'));
+
+ // marketSellOrdersNoThrow
+ bytes4 constant marketSellOrdersNoThrowSelector = 0xdd1c7d18;
+ bytes4 constant marketSellOrdersNoThrowSelectorGenerator = bytes4(keccak256('marketSellOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],uint256,bytes[])'));
+
+ // matchOrders
+ bytes4 constant matchOrdersSelector = 0x3c28d861;
+ bytes4 constant matchOrdersSelectorGenerator = bytes4(keccak256('matchOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes),bytes,bytes)'));
+
+ // orderEpoch
+ bytes4 constant orderEpochSelector = 0xd9bfa73e;
+ bytes4 constant orderEpochSelectorGenerator = bytes4(keccak256('orderEpoch(address,address)'));
+
+ // owner
+ bytes4 constant ownerSelector = 0x8da5cb5b;
+ bytes4 constant ownerSelectorGenerator = bytes4(keccak256('owner()'));
+
+ // preSign
+ bytes4 constant preSignSelector = 0x3683ef8e;
+ bytes4 constant preSignSelectorGenerator = bytes4(keccak256('preSign(bytes32,address,bytes)'));
+
+ // preSigned
+ bytes4 constant preSignedSelector = 0x82c174d0;
+ bytes4 constant preSignedSelectorGenerator = bytes4(keccak256('preSigned(bytes32,address)'));
+
+ // registerAssetProxy
+ bytes4 constant registerAssetProxySelector = 0xc585bb93;
+ bytes4 constant registerAssetProxySelectorGenerator = bytes4(keccak256('registerAssetProxy(address)'));
+
+ // setSignatureValidatorApproval
+ bytes4 constant setSignatureValidatorApprovalSelector = 0x77fcce68;
+ bytes4 constant setSignatureValidatorApprovalSelectorGenerator = bytes4(keccak256('setSignatureValidatorApproval(address,bool)'));
+
+ // transactions
+ bytes4 constant transactionsSelector = 0x642f2eaf;
+ bytes4 constant transactionsSelectorGenerator = bytes4(keccak256('transactions(bytes32)'));
+
+ // transferOwnership
+ bytes4 constant transferOwnershipSelector = 0xf2fde38b;
+ bytes4 constant transferOwnershipSelectorGenerator = bytes4(keccak256('transferOwnership(address)'));
+} \ No newline at end of file