Panettone cleanup (#109)
* `@0x/contracts-zero-ex`: Updates for panettone release * `@0x/contract-addresses`: Update ganache snapshot addresses Co-authored-by: Lawrence Forman <me@merklejerk.com>
This commit is contained in:
		@@ -5,6 +5,10 @@
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                "note": "Use consistent returndatasize checks in UniswapFeature",
 | 
					                "note": "Use consistent returndatasize checks in UniswapFeature",
 | 
				
			||||||
                "pr": 96
 | 
					                "pr": 96
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Remove `MetaTransactionsFeature._executeMetaTransaction()` and `SignatureValidatorFeature`",
 | 
				
			||||||
 | 
					                "pr": 109
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,6 @@ pragma experimental ABIEncoderV2;
 | 
				
			|||||||
import "./features/IOwnableFeature.sol";
 | 
					import "./features/IOwnableFeature.sol";
 | 
				
			||||||
import "./features/ISimpleFunctionRegistryFeature.sol";
 | 
					import "./features/ISimpleFunctionRegistryFeature.sol";
 | 
				
			||||||
import "./features/ITokenSpenderFeature.sol";
 | 
					import "./features/ITokenSpenderFeature.sol";
 | 
				
			||||||
import "./features/ISignatureValidatorFeature.sol";
 | 
					 | 
				
			||||||
import "./features/ITransformERC20Feature.sol";
 | 
					import "./features/ITransformERC20Feature.sol";
 | 
				
			||||||
import "./features/IMetaTransactionsFeature.sol";
 | 
					import "./features/IMetaTransactionsFeature.sol";
 | 
				
			||||||
import "./features/IUniswapFeature.sol";
 | 
					import "./features/IUniswapFeature.sol";
 | 
				
			||||||
@@ -36,7 +35,6 @@ interface IZeroEx is
 | 
				
			|||||||
    IOwnableFeature,
 | 
					    IOwnableFeature,
 | 
				
			||||||
    ISimpleFunctionRegistryFeature,
 | 
					    ISimpleFunctionRegistryFeature,
 | 
				
			||||||
    ITokenSpenderFeature,
 | 
					    ITokenSpenderFeature,
 | 
				
			||||||
    ISignatureValidatorFeature,
 | 
					 | 
				
			||||||
    ITransformERC20Feature,
 | 
					    ITransformERC20Feature,
 | 
				
			||||||
    IMetaTransactionsFeature,
 | 
					    IMetaTransactionsFeature,
 | 
				
			||||||
    IUniswapFeature,
 | 
					    IUniswapFeature,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -86,21 +86,6 @@ interface IMetaTransactionsFeature {
 | 
				
			|||||||
        payable
 | 
					        payable
 | 
				
			||||||
        returns (bytes[] memory returnResults);
 | 
					        returns (bytes[] memory returnResults);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev Execute a meta-transaction via `sender`. Privileged variant.
 | 
					 | 
				
			||||||
    ///      Only callable from within.
 | 
					 | 
				
			||||||
    /// @param sender Who is executing the meta-transaction.
 | 
					 | 
				
			||||||
    /// @param mtx The meta-transaction.
 | 
					 | 
				
			||||||
    /// @param signature The signature by `mtx.signer`.
 | 
					 | 
				
			||||||
    /// @return returnResult The ABI-encoded result of the underlying call.
 | 
					 | 
				
			||||||
    function _executeMetaTransaction(
 | 
					 | 
				
			||||||
        address sender,
 | 
					 | 
				
			||||||
        MetaTransactionData memory mtx,
 | 
					 | 
				
			||||||
        LibSignature.Signature memory signature
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        external
 | 
					 | 
				
			||||||
        payable
 | 
					 | 
				
			||||||
        returns (bytes memory returnResult);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Get the block at which a meta-transaction has been executed.
 | 
					    /// @dev Get the block at which a meta-transaction has been executed.
 | 
				
			||||||
    /// @param mtx The meta-transaction.
 | 
					    /// @param mtx The meta-transaction.
 | 
				
			||||||
    /// @return blockNumber The block height when the meta-transactioin was executed.
 | 
					    /// @return blockNumber The block height when the meta-transactioin was executed.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,64 +0,0 @@
 | 
				
			|||||||
// SPDX-License-Identifier: Apache-2.0
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Copyright 2020 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.6.5;
 | 
					 | 
				
			||||||
pragma experimental ABIEncoderV2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// @dev Feature for validating signatures.
 | 
					 | 
				
			||||||
interface ISignatureValidatorFeature {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   /// @dev Allowed signature types.
 | 
					 | 
				
			||||||
    enum SignatureType {
 | 
					 | 
				
			||||||
        Illegal,                     // 0x00, default value
 | 
					 | 
				
			||||||
        Invalid,                     // 0x01
 | 
					 | 
				
			||||||
        EIP712,                      // 0x02
 | 
					 | 
				
			||||||
        EthSign,                     // 0x03
 | 
					 | 
				
			||||||
        NSignatureTypes              // 0x04, number of signature types. Always leave at end.
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Validate that `hash` was signed by `signer` given `signature`.
 | 
					 | 
				
			||||||
    ///      Reverts otherwise.
 | 
					 | 
				
			||||||
    /// @param hash The hash that was signed.
 | 
					 | 
				
			||||||
    /// @param signer The signer of the hash.
 | 
					 | 
				
			||||||
    /// @param signature The signature. The last byte of this signature should
 | 
					 | 
				
			||||||
    ///        be a member of the `SignatureType` enum.
 | 
					 | 
				
			||||||
    function validateHashSignature(
 | 
					 | 
				
			||||||
        bytes32 hash,
 | 
					 | 
				
			||||||
        address signer,
 | 
					 | 
				
			||||||
        bytes calldata signature
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        external
 | 
					 | 
				
			||||||
        view;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Check that `hash` was signed by `signer` given `signature`.
 | 
					 | 
				
			||||||
    /// @param hash The hash that was signed.
 | 
					 | 
				
			||||||
    /// @param signer The signer of the hash.
 | 
					 | 
				
			||||||
    /// @param signature The signature. The last byte of this signature should
 | 
					 | 
				
			||||||
    ///        be a member of the `SignatureType` enum.
 | 
					 | 
				
			||||||
    /// @return isValid `true` on success.
 | 
					 | 
				
			||||||
    function isValidHashSignature(
 | 
					 | 
				
			||||||
        bytes32 hash,
 | 
					 | 
				
			||||||
        address signer,
 | 
					 | 
				
			||||||
        bytes calldata signature
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        external
 | 
					 | 
				
			||||||
        view
 | 
					 | 
				
			||||||
        returns (bool isValid);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -33,7 +33,6 @@ import "../storage/LibMetaTransactionsStorage.sol";
 | 
				
			|||||||
import "./IMetaTransactionsFeature.sol";
 | 
					import "./IMetaTransactionsFeature.sol";
 | 
				
			||||||
import "./ITransformERC20Feature.sol";
 | 
					import "./ITransformERC20Feature.sol";
 | 
				
			||||||
import "./libs/LibSignature.sol";
 | 
					import "./libs/LibSignature.sol";
 | 
				
			||||||
import "./ISignatureValidatorFeature.sol";
 | 
					 | 
				
			||||||
import "./IFeature.sol";
 | 
					import "./IFeature.sol";
 | 
				
			||||||
import "./INativeOrdersFeature.sol";
 | 
					import "./INativeOrdersFeature.sol";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -124,7 +123,6 @@ contract MetaTransactionsFeature is
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        _registerFeatureFunction(this.executeMetaTransaction.selector);
 | 
					        _registerFeatureFunction(this.executeMetaTransaction.selector);
 | 
				
			||||||
        _registerFeatureFunction(this.batchExecuteMetaTransactions.selector);
 | 
					        _registerFeatureFunction(this.batchExecuteMetaTransactions.selector);
 | 
				
			||||||
        _registerFeatureFunction(this._executeMetaTransaction.selector);
 | 
					 | 
				
			||||||
        _registerFeatureFunction(this.getMetaTransactionExecutedBlock.selector);
 | 
					        _registerFeatureFunction(this.getMetaTransactionExecutedBlock.selector);
 | 
				
			||||||
        _registerFeatureFunction(this.getMetaTransactionHashExecutedBlock.selector);
 | 
					        _registerFeatureFunction(this.getMetaTransactionHashExecutedBlock.selector);
 | 
				
			||||||
        _registerFeatureFunction(this.getMetaTransactionHash.selector);
 | 
					        _registerFeatureFunction(this.getMetaTransactionHash.selector);
 | 
				
			||||||
@@ -188,32 +186,6 @@ contract MetaTransactionsFeature is
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev Execute a meta-transaction via `sender`. Privileged variant.
 | 
					 | 
				
			||||||
    ///      Only callable from within.
 | 
					 | 
				
			||||||
    /// @param sender Who is executing the meta-transaction.
 | 
					 | 
				
			||||||
    /// @param mtx The meta-transaction.
 | 
					 | 
				
			||||||
    /// @param signature The signature by `mtx.signer`.
 | 
					 | 
				
			||||||
    /// @return returnResult The ABI-encoded result of the underlying call.
 | 
					 | 
				
			||||||
    function _executeMetaTransaction(
 | 
					 | 
				
			||||||
        address sender,
 | 
					 | 
				
			||||||
        MetaTransactionData memory mtx,
 | 
					 | 
				
			||||||
        LibSignature.Signature memory signature
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        public
 | 
					 | 
				
			||||||
        payable
 | 
					 | 
				
			||||||
        override
 | 
					 | 
				
			||||||
        onlySelf
 | 
					 | 
				
			||||||
        returns (bytes memory returnResult)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        ExecuteState memory state;
 | 
					 | 
				
			||||||
        state.sender = sender;
 | 
					 | 
				
			||||||
        state.mtx = mtx;
 | 
					 | 
				
			||||||
        state.hash = getMetaTransactionHash(mtx);
 | 
					 | 
				
			||||||
        state.signature = signature;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return _executeMetaTransactionPrivate(state);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Get the block at which a meta-transaction has been executed.
 | 
					    /// @dev Get the block at which a meta-transaction has been executed.
 | 
				
			||||||
    /// @param mtx The meta-transaction.
 | 
					    /// @param mtx The meta-transaction.
 | 
				
			||||||
    /// @return blockNumber The block height when the meta-transactioin was executed.
 | 
					    /// @return blockNumber The block height when the meta-transactioin was executed.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,275 +0,0 @@
 | 
				
			|||||||
// SPDX-License-Identifier: Apache-2.0
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Copyright 2020 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.6.5;
 | 
					 | 
				
			||||||
pragma experimental ABIEncoderV2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "@0x/contracts-utils/contracts/src/v06/errors/LibRichErrorsV06.sol";
 | 
					 | 
				
			||||||
import "@0x/contracts-utils/contracts/src/v06/LibBytesV06.sol";
 | 
					 | 
				
			||||||
import "../errors/LibSignatureRichErrors.sol";
 | 
					 | 
				
			||||||
import "../fixins/FixinCommon.sol";
 | 
					 | 
				
			||||||
import "../migrations/LibMigrate.sol";
 | 
					 | 
				
			||||||
import "./ISignatureValidatorFeature.sol";
 | 
					 | 
				
			||||||
import "./IFeature.sol";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// @dev Feature for validating signatures.
 | 
					 | 
				
			||||||
contract SignatureValidatorFeature is
 | 
					 | 
				
			||||||
    IFeature,
 | 
					 | 
				
			||||||
    ISignatureValidatorFeature,
 | 
					 | 
				
			||||||
    FixinCommon
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    using LibBytesV06 for bytes;
 | 
					 | 
				
			||||||
    using LibRichErrorsV06 for bytes;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Exclusive upper limit on ECDSA signatures 'R' values.
 | 
					 | 
				
			||||||
    ///      The valid range is given by fig (282) of the yellow paper.
 | 
					 | 
				
			||||||
    uint256 private constant ECDSA_SIGNATURE_R_LIMIT =
 | 
					 | 
				
			||||||
        uint256(0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141);
 | 
					 | 
				
			||||||
    /// @dev Exclusive upper limit on ECDSA signatures 'S' values.
 | 
					 | 
				
			||||||
    ///      The valid range is given by fig (283) of the yellow paper.
 | 
					 | 
				
			||||||
    uint256 private constant ECDSA_SIGNATURE_S_LIMIT = ECDSA_SIGNATURE_R_LIMIT / 2 + 1;
 | 
					 | 
				
			||||||
    /// @dev Name of this feature.
 | 
					 | 
				
			||||||
    string public constant override FEATURE_NAME = "SignatureValidator";
 | 
					 | 
				
			||||||
    /// @dev Version of this feature.
 | 
					 | 
				
			||||||
    uint256 public immutable override FEATURE_VERSION = _encodeVersion(1, 0, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Initialize and register this feature.
 | 
					 | 
				
			||||||
    ///      Should be delegatecalled by `Migrate.migrate()`.
 | 
					 | 
				
			||||||
    /// @return success `LibMigrate.SUCCESS` on success.
 | 
					 | 
				
			||||||
    function migrate()
 | 
					 | 
				
			||||||
        external
 | 
					 | 
				
			||||||
        returns (bytes4 success)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        _registerFeatureFunction(this.validateHashSignature.selector);
 | 
					 | 
				
			||||||
        _registerFeatureFunction(this.isValidHashSignature.selector);
 | 
					 | 
				
			||||||
        return LibMigrate.MIGRATE_SUCCESS;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Validate that `hash` was signed by `signer` given `signature`.
 | 
					 | 
				
			||||||
    ///      Reverts otherwise.
 | 
					 | 
				
			||||||
    /// @param hash The hash that was signed.
 | 
					 | 
				
			||||||
    /// @param signer The signer of the hash.
 | 
					 | 
				
			||||||
    /// @param signature The signature. The last byte of this signature should
 | 
					 | 
				
			||||||
    ///        be a member of the `SignatureType` enum.
 | 
					 | 
				
			||||||
    function validateHashSignature(
 | 
					 | 
				
			||||||
        bytes32 hash,
 | 
					 | 
				
			||||||
        address signer,
 | 
					 | 
				
			||||||
        bytes memory signature
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        public
 | 
					 | 
				
			||||||
        override
 | 
					 | 
				
			||||||
        view
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        SignatureType signatureType = _readValidSignatureType(
 | 
					 | 
				
			||||||
            hash,
 | 
					 | 
				
			||||||
            signer,
 | 
					 | 
				
			||||||
            signature
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // TODO: When we support non-hash signature types, assert that
 | 
					 | 
				
			||||||
        // `signatureType` is only `EIP712` or `EthSign` here.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        _validateHashSignatureTypes(
 | 
					 | 
				
			||||||
            signatureType,
 | 
					 | 
				
			||||||
            hash,
 | 
					 | 
				
			||||||
            signer,
 | 
					 | 
				
			||||||
            signature
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Check that `hash` was signed by `signer` given `signature`.
 | 
					 | 
				
			||||||
    /// @param hash The hash that was signed.
 | 
					 | 
				
			||||||
    /// @param signer The signer of the hash.
 | 
					 | 
				
			||||||
    /// @param signature The signature. The last byte of this signature should
 | 
					 | 
				
			||||||
    ///        be a member of the `SignatureType` enum.
 | 
					 | 
				
			||||||
    /// @return isValid `true` on success.
 | 
					 | 
				
			||||||
    function isValidHashSignature(
 | 
					 | 
				
			||||||
        bytes32 hash,
 | 
					 | 
				
			||||||
        address signer,
 | 
					 | 
				
			||||||
        bytes calldata signature
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        external
 | 
					 | 
				
			||||||
        view
 | 
					 | 
				
			||||||
        override
 | 
					 | 
				
			||||||
        returns (bool isValid)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // HACK: `validateHashSignature()` is stateless so we can just perform
 | 
					 | 
				
			||||||
        // a staticcall against the implementation contract. This avoids the
 | 
					 | 
				
			||||||
        // overhead of going through the proxy. If `validateHashSignature()` ever
 | 
					 | 
				
			||||||
        // becomes stateful this would need to change.
 | 
					 | 
				
			||||||
        (isValid, ) = _implementation.staticcall(
 | 
					 | 
				
			||||||
            abi.encodeWithSelector(
 | 
					 | 
				
			||||||
                this.validateHashSignature.selector,
 | 
					 | 
				
			||||||
                hash,
 | 
					 | 
				
			||||||
                signer,
 | 
					 | 
				
			||||||
                signature
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Validates a hash-only signature type. Low-level, hidden variant.
 | 
					 | 
				
			||||||
    /// @param signatureType The type of signature to check.
 | 
					 | 
				
			||||||
    /// @param hash The hash that was signed.
 | 
					 | 
				
			||||||
    /// @param signer The signer of the hash.
 | 
					 | 
				
			||||||
    /// @param signature The signature. The last byte of this signature should
 | 
					 | 
				
			||||||
    ///        be a member of the `SignatureType` enum.
 | 
					 | 
				
			||||||
    function _validateHashSignatureTypes(
 | 
					 | 
				
			||||||
        SignatureType signatureType,
 | 
					 | 
				
			||||||
        bytes32 hash,
 | 
					 | 
				
			||||||
        address signer,
 | 
					 | 
				
			||||||
        bytes memory signature
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        private
 | 
					 | 
				
			||||||
        pure
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        address recovered = address(0);
 | 
					 | 
				
			||||||
        if (signatureType == SignatureType.Invalid) {
 | 
					 | 
				
			||||||
            // 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.
 | 
					 | 
				
			||||||
            LibSignatureRichErrors.SignatureValidationError(
 | 
					 | 
				
			||||||
                LibSignatureRichErrors.SignatureValidationErrorCodes.ALWAYS_INVALID,
 | 
					 | 
				
			||||||
                hash,
 | 
					 | 
				
			||||||
                signer,
 | 
					 | 
				
			||||||
                signature
 | 
					 | 
				
			||||||
            ).rrevert();
 | 
					 | 
				
			||||||
        } else if (signatureType == SignatureType.EIP712) {
 | 
					 | 
				
			||||||
            // Signature using EIP712
 | 
					 | 
				
			||||||
            if (signature.length != 66) {
 | 
					 | 
				
			||||||
                LibSignatureRichErrors.SignatureValidationError(
 | 
					 | 
				
			||||||
                    LibSignatureRichErrors.SignatureValidationErrorCodes.INVALID_LENGTH,
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    signer,
 | 
					 | 
				
			||||||
                    signature
 | 
					 | 
				
			||||||
                ).rrevert();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            uint8 v = uint8(signature[0]);
 | 
					 | 
				
			||||||
            bytes32 r = signature.readBytes32(1);
 | 
					 | 
				
			||||||
            bytes32 s = signature.readBytes32(33);
 | 
					 | 
				
			||||||
            if (uint256(r) < ECDSA_SIGNATURE_R_LIMIT && uint256(s) < ECDSA_SIGNATURE_S_LIMIT) {
 | 
					 | 
				
			||||||
                recovered = ecrecover(
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    v,
 | 
					 | 
				
			||||||
                    r,
 | 
					 | 
				
			||||||
                    s
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else if (signatureType == SignatureType.EthSign) {
 | 
					 | 
				
			||||||
            // Signed using `eth_sign`
 | 
					 | 
				
			||||||
            if (signature.length != 66) {
 | 
					 | 
				
			||||||
                LibSignatureRichErrors.SignatureValidationError(
 | 
					 | 
				
			||||||
                    LibSignatureRichErrors.SignatureValidationErrorCodes.INVALID_LENGTH,
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    signer,
 | 
					 | 
				
			||||||
                    signature
 | 
					 | 
				
			||||||
                ).rrevert();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            uint8 v = uint8(signature[0]);
 | 
					 | 
				
			||||||
            bytes32 r = signature.readBytes32(1);
 | 
					 | 
				
			||||||
            bytes32 s = signature.readBytes32(33);
 | 
					 | 
				
			||||||
            if (uint256(r) < ECDSA_SIGNATURE_R_LIMIT && uint256(s) < ECDSA_SIGNATURE_S_LIMIT) {
 | 
					 | 
				
			||||||
                recovered = ecrecover(
 | 
					 | 
				
			||||||
                    keccak256(abi.encodePacked(
 | 
					 | 
				
			||||||
                        "\x19Ethereum Signed Message:\n32",
 | 
					 | 
				
			||||||
                        hash
 | 
					 | 
				
			||||||
                    )),
 | 
					 | 
				
			||||||
                    v,
 | 
					 | 
				
			||||||
                    r,
 | 
					 | 
				
			||||||
                    s
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            // This should never happen.
 | 
					 | 
				
			||||||
            revert('SignatureValidator/ILLEGAL_CODE_PATH');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (recovered == address(0) || signer != recovered) {
 | 
					 | 
				
			||||||
            LibSignatureRichErrors.SignatureValidationError(
 | 
					 | 
				
			||||||
                LibSignatureRichErrors.SignatureValidationErrorCodes.WRONG_SIGNER,
 | 
					 | 
				
			||||||
                hash,
 | 
					 | 
				
			||||||
                signer,
 | 
					 | 
				
			||||||
                signature
 | 
					 | 
				
			||||||
            ).rrevert();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Reads the `SignatureType` from the end of a signature and validates it.
 | 
					 | 
				
			||||||
    function _readValidSignatureType(
 | 
					 | 
				
			||||||
        bytes32 hash,
 | 
					 | 
				
			||||||
        address signer,
 | 
					 | 
				
			||||||
        bytes memory signature
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        private
 | 
					 | 
				
			||||||
        pure
 | 
					 | 
				
			||||||
        returns (SignatureType signatureType)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Read the signatureType from the signature
 | 
					 | 
				
			||||||
        signatureType = _readSignatureType(
 | 
					 | 
				
			||||||
            hash,
 | 
					 | 
				
			||||||
            signer,
 | 
					 | 
				
			||||||
            signature
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Ensure signature is supported
 | 
					 | 
				
			||||||
        if (uint8(signatureType) >= uint8(SignatureType.NSignatureTypes)) {
 | 
					 | 
				
			||||||
            LibSignatureRichErrors.SignatureValidationError(
 | 
					 | 
				
			||||||
                LibSignatureRichErrors.SignatureValidationErrorCodes.UNSUPPORTED,
 | 
					 | 
				
			||||||
                hash,
 | 
					 | 
				
			||||||
                signer,
 | 
					 | 
				
			||||||
                signature
 | 
					 | 
				
			||||||
            ).rrevert();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // 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) {
 | 
					 | 
				
			||||||
            LibSignatureRichErrors.SignatureValidationError(
 | 
					 | 
				
			||||||
                LibSignatureRichErrors.SignatureValidationErrorCodes.ILLEGAL,
 | 
					 | 
				
			||||||
                hash,
 | 
					 | 
				
			||||||
                signer,
 | 
					 | 
				
			||||||
                signature
 | 
					 | 
				
			||||||
            ).rrevert();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Reads the `SignatureType` from the end of a signature.
 | 
					 | 
				
			||||||
    function _readSignatureType(
 | 
					 | 
				
			||||||
        bytes32 hash,
 | 
					 | 
				
			||||||
        address signer,
 | 
					 | 
				
			||||||
        bytes memory signature
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        private
 | 
					 | 
				
			||||||
        pure
 | 
					 | 
				
			||||||
        returns (SignatureType sigType)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (signature.length == 0) {
 | 
					 | 
				
			||||||
            LibSignatureRichErrors.SignatureValidationError(
 | 
					 | 
				
			||||||
                LibSignatureRichErrors.SignatureValidationErrorCodes.INVALID_LENGTH,
 | 
					 | 
				
			||||||
                hash,
 | 
					 | 
				
			||||||
                signer,
 | 
					 | 
				
			||||||
                signature
 | 
					 | 
				
			||||||
            ).rrevert();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return SignatureType(uint8(signature[signature.length - 1]));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -35,7 +35,6 @@ import "../transformers/IERC20Transformer.sol";
 | 
				
			|||||||
import "../transformers/LibERC20Transformer.sol";
 | 
					import "../transformers/LibERC20Transformer.sol";
 | 
				
			||||||
import "./ITransformERC20Feature.sol";
 | 
					import "./ITransformERC20Feature.sol";
 | 
				
			||||||
import "./IFeature.sol";
 | 
					import "./IFeature.sol";
 | 
				
			||||||
import "./ISignatureValidatorFeature.sol";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// @dev Feature to composably transform between ERC20 tokens.
 | 
					/// @dev Feature to composably transform between ERC20 tokens.
 | 
				
			||||||
@@ -374,35 +373,4 @@ contract TransformERC20Feature is
 | 
				
			|||||||
            ).rrevert();
 | 
					            ).rrevert();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Check if a call data hash is signed by the quote signer.
 | 
					 | 
				
			||||||
    /// @param callDataHash The hash of the callData.
 | 
					 | 
				
			||||||
    /// @param signature The signature provided by `getQuoteSigner()`.
 | 
					 | 
				
			||||||
    /// @return validCallDataHash `callDataHash` if so and `0x0` otherwise.
 | 
					 | 
				
			||||||
    function _getValidCallDataHash(
 | 
					 | 
				
			||||||
        bytes32 callDataHash,
 | 
					 | 
				
			||||||
        bytes memory signature
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        private
 | 
					 | 
				
			||||||
        view
 | 
					 | 
				
			||||||
        returns (bytes32 validCallDataHash)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        address quoteSigner = getQuoteSigner();
 | 
					 | 
				
			||||||
        if (quoteSigner == address(0)) {
 | 
					 | 
				
			||||||
            // If no quote signer is configured, then all calldata hashes are
 | 
					 | 
				
			||||||
            // valid.
 | 
					 | 
				
			||||||
            return callDataHash;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (signature.length == 0) {
 | 
					 | 
				
			||||||
            return bytes32(0);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (ISignatureValidatorFeature(address(this)).isValidHashSignature(
 | 
					 | 
				
			||||||
            callDataHash,
 | 
					 | 
				
			||||||
            quoteSigner,
 | 
					 | 
				
			||||||
            signature
 | 
					 | 
				
			||||||
        )) {
 | 
					 | 
				
			||||||
            return callDataHash;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,6 @@ import "../ZeroEx.sol";
 | 
				
			|||||||
import "../features/IOwnableFeature.sol";
 | 
					import "../features/IOwnableFeature.sol";
 | 
				
			||||||
import "../features/TokenSpenderFeature.sol";
 | 
					import "../features/TokenSpenderFeature.sol";
 | 
				
			||||||
import "../features/TransformERC20Feature.sol";
 | 
					import "../features/TransformERC20Feature.sol";
 | 
				
			||||||
import "../features/SignatureValidatorFeature.sol";
 | 
					 | 
				
			||||||
import "../features/MetaTransactionsFeature.sol";
 | 
					import "../features/MetaTransactionsFeature.sol";
 | 
				
			||||||
import "../features/NativeOrdersFeature.sol";
 | 
					import "../features/NativeOrdersFeature.sol";
 | 
				
			||||||
import "../external/AllowanceTarget.sol";
 | 
					import "../external/AllowanceTarget.sol";
 | 
				
			||||||
@@ -42,7 +41,6 @@ contract FullMigration {
 | 
				
			|||||||
        OwnableFeature ownable;
 | 
					        OwnableFeature ownable;
 | 
				
			||||||
        TokenSpenderFeature tokenSpender;
 | 
					        TokenSpenderFeature tokenSpender;
 | 
				
			||||||
        TransformERC20Feature transformERC20;
 | 
					        TransformERC20Feature transformERC20;
 | 
				
			||||||
        SignatureValidatorFeature signatureValidator;
 | 
					 | 
				
			||||||
        MetaTransactionsFeature metaTransactions;
 | 
					        MetaTransactionsFeature metaTransactions;
 | 
				
			||||||
        NativeOrdersFeature nativeOrders;
 | 
					        NativeOrdersFeature nativeOrders;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -176,17 +174,6 @@ contract FullMigration {
 | 
				
			|||||||
                address(this)
 | 
					                address(this)
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // SignatureValidatorFeature
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // Register the feature.
 | 
					 | 
				
			||||||
            ownable.migrate(
 | 
					 | 
				
			||||||
                address(features.signatureValidator),
 | 
					 | 
				
			||||||
                abi.encodeWithSelector(
 | 
					 | 
				
			||||||
                    SignatureValidatorFeature.migrate.selector
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
                address(this)
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        // MetaTransactionsFeature
 | 
					        // MetaTransactionsFeature
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            // Register the feature.
 | 
					            // Register the feature.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,9 +41,9 @@
 | 
				
			|||||||
        "rollback": "node ./lib/scripts/rollback.js"
 | 
					        "rollback": "node ./lib/scripts/rollback.js"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "config": {
 | 
					    "config": {
 | 
				
			||||||
        "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IAllowanceTarget,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITokenSpenderFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,TokenSpenderFeature,AffiliateFeeTransformer,SignatureValidatorFeature,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector",
 | 
					        "publicInterfaceContracts": "IZeroEx,ZeroEx,FullMigration,InitialMigration,IFlashWallet,IAllowanceTarget,IERC20Transformer,IOwnableFeature,ISimpleFunctionRegistryFeature,ITokenSpenderFeature,ITransformERC20Feature,FillQuoteTransformer,PayTakerTransformer,WethTransformer,OwnableFeature,SimpleFunctionRegistryFeature,TransformERC20Feature,TokenSpenderFeature,AffiliateFeeTransformer,MetaTransactionsFeature,LogMetadataTransformer,BridgeAdapter,LiquidityProviderFeature,ILiquidityProviderFeature,NativeOrdersFeature,INativeOrdersFeature,FeeCollectorController,FeeCollector",
 | 
				
			||||||
        "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
 | 
					        "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
 | 
				
			||||||
        "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|AllowanceTarget|BootstrapFeature|BridgeAdapter|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|IAllowanceTarget|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IExchange|IFeature|IFlashWallet|IGasToken|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|INativeOrdersFeature|IOwnableFeature|ISignatureValidatorFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOrderHash|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibSpenderRichErrors|LibStorage|LibTokenSpenderStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAdapterAddresses|MixinBalancer|MixinBancor|MixinCoFiX|MixinCryptoCom|MixinCurve|MixinDodo|MixinKyber|MixinMStable|MixinMooniswap|MixinOasis|MixinShell|MixinSushiswap|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|NativeOrdersFeature|OwnableFeature|PayTakerTransformer|PermissionlessTransformerDeployer|SignatureValidatorFeature|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestNativeOrdersFeature|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpender|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TokenSpenderFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx|ZeroExOptimized).json"
 | 
					        "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|AllowanceTarget|BootstrapFeature|BridgeAdapter|FeeCollector|FeeCollectorController|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FixinTokenSpender|FlashWallet|FullMigration|IAllowanceTarget|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IExchange|IFeature|IFlashWallet|IGasToken|ILiquidityProvider|ILiquidityProviderFeature|ILiquidityProviderSandbox|IMetaTransactionsFeature|INativeOrdersFeature|IOwnableFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibFeeCollector|LibLiquidityProviderRichErrors|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibNativeOrder|LibNativeOrdersRichErrors|LibNativeOrdersStorage|LibOrderHash|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibSpenderRichErrors|LibStorage|LibTokenSpenderStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LiquidityProviderSandbox|LogMetadataTransformer|MetaTransactionsFeature|MixinAdapterAddresses|MixinBalancer|MixinBancor|MixinCoFiX|MixinCryptoCom|MixinCurve|MixinDodo|MixinKyber|MixinMStable|MixinMooniswap|MixinOasis|MixinShell|MixinSushiswap|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|NativeOrdersFeature|OwnableFeature|PayTakerTransformer|PermissionlessTransformerDeployer|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestDelegateCaller|TestFeeCollectorController|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFixinProtocolFees|TestFixinTokenSpender|TestFullMigration|TestInitialMigration|TestLibNativeOrder|TestLibSignature|TestLiquidityProvider|TestMetaTransactionsNativeOrdersFeature|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestNativeOrdersFeature|TestPermissionlessTransformerDeployerSuicidal|TestPermissionlessTransformerDeployerTransformer|TestRfqOriginRegistration|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpender|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TokenSpenderFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx|ZeroExOptimized).json"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "repository": {
 | 
					    "repository": {
 | 
				
			||||||
        "type": "git",
 | 
					        "type": "git",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,6 @@ import {
 | 
				
			|||||||
    MetaTransactionsFeatureContract,
 | 
					    MetaTransactionsFeatureContract,
 | 
				
			||||||
    NativeOrdersFeatureContract,
 | 
					    NativeOrdersFeatureContract,
 | 
				
			||||||
    OwnableFeatureContract,
 | 
					    OwnableFeatureContract,
 | 
				
			||||||
    SignatureValidatorFeatureContract,
 | 
					 | 
				
			||||||
    SimpleFunctionRegistryFeatureContract,
 | 
					    SimpleFunctionRegistryFeatureContract,
 | 
				
			||||||
    TokenSpenderFeatureContract,
 | 
					    TokenSpenderFeatureContract,
 | 
				
			||||||
    TransformERC20FeatureContract,
 | 
					    TransformERC20FeatureContract,
 | 
				
			||||||
@@ -111,7 +110,6 @@ export async function initialMigrateAsync(
 | 
				
			|||||||
export interface FullFeatures extends BootstrapFeatures {
 | 
					export interface FullFeatures extends BootstrapFeatures {
 | 
				
			||||||
    tokenSpender: string;
 | 
					    tokenSpender: string;
 | 
				
			||||||
    transformERC20: string;
 | 
					    transformERC20: string;
 | 
				
			||||||
    signatureValidator: string;
 | 
					 | 
				
			||||||
    metaTransactions: string;
 | 
					    metaTransactions: string;
 | 
				
			||||||
    nativeOrders: string;
 | 
					    nativeOrders: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -122,7 +120,6 @@ export interface FullFeatures extends BootstrapFeatures {
 | 
				
			|||||||
export interface FullFeatureArtifacts extends BootstrapFeatureArtifacts {
 | 
					export interface FullFeatureArtifacts extends BootstrapFeatureArtifacts {
 | 
				
			||||||
    tokenSpender: SimpleContractArtifact;
 | 
					    tokenSpender: SimpleContractArtifact;
 | 
				
			||||||
    transformERC20: SimpleContractArtifact;
 | 
					    transformERC20: SimpleContractArtifact;
 | 
				
			||||||
    signatureValidator: SimpleContractArtifact;
 | 
					 | 
				
			||||||
    metaTransactions: SimpleContractArtifact;
 | 
					    metaTransactions: SimpleContractArtifact;
 | 
				
			||||||
    nativeOrders: SimpleContractArtifact;
 | 
					    nativeOrders: SimpleContractArtifact;
 | 
				
			||||||
    feeCollectorController: SimpleContractArtifact;
 | 
					    feeCollectorController: SimpleContractArtifact;
 | 
				
			||||||
@@ -158,7 +155,6 @@ const DEFAULT_FULL_FEATURES_DEPLOY_CONFIG = {
 | 
				
			|||||||
const DEFAULT_FULL_FEATURES_ARTIFACTS = {
 | 
					const DEFAULT_FULL_FEATURES_ARTIFACTS = {
 | 
				
			||||||
    tokenSpender: artifacts.TokenSpenderFeature,
 | 
					    tokenSpender: artifacts.TokenSpenderFeature,
 | 
				
			||||||
    transformERC20: artifacts.TransformERC20Feature,
 | 
					    transformERC20: artifacts.TransformERC20Feature,
 | 
				
			||||||
    signatureValidator: artifacts.SignatureValidatorFeature,
 | 
					 | 
				
			||||||
    metaTransactions: artifacts.MetaTransactionsFeature,
 | 
					    metaTransactions: artifacts.MetaTransactionsFeature,
 | 
				
			||||||
    nativeOrders: artifacts.NativeOrdersFeature,
 | 
					    nativeOrders: artifacts.NativeOrdersFeature,
 | 
				
			||||||
    feeCollectorController: artifacts.FeeCollectorController,
 | 
					    feeCollectorController: artifacts.FeeCollectorController,
 | 
				
			||||||
@@ -208,14 +204,6 @@ export async function deployFullFeaturesAsync(
 | 
				
			|||||||
                artifacts,
 | 
					                artifacts,
 | 
				
			||||||
                _config.greedyTokensBloomFilter,
 | 
					                _config.greedyTokensBloomFilter,
 | 
				
			||||||
            )).address,
 | 
					            )).address,
 | 
				
			||||||
        signatureValidator:
 | 
					 | 
				
			||||||
            features.signatureValidator ||
 | 
					 | 
				
			||||||
            (await SignatureValidatorFeatureContract.deployFrom0xArtifactAsync(
 | 
					 | 
				
			||||||
                _featureArtifacts.signatureValidator,
 | 
					 | 
				
			||||||
                provider,
 | 
					 | 
				
			||||||
                txDefaults,
 | 
					 | 
				
			||||||
                artifacts,
 | 
					 | 
				
			||||||
            )).address,
 | 
					 | 
				
			||||||
        metaTransactions:
 | 
					        metaTransactions:
 | 
				
			||||||
            features.metaTransactions ||
 | 
					            features.metaTransactions ||
 | 
				
			||||||
            (await MetaTransactionsFeatureContract.deployFrom0xArtifactAsync(
 | 
					            (await MetaTransactionsFeatureContract.deployFrom0xArtifactAsync(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,6 @@ import * as IMetaTransactionsFeature from '../test/generated-artifacts/IMetaTran
 | 
				
			|||||||
import * as INativeOrdersFeature from '../test/generated-artifacts/INativeOrdersFeature.json';
 | 
					import * as INativeOrdersFeature from '../test/generated-artifacts/INativeOrdersFeature.json';
 | 
				
			||||||
import * as InitialMigration from '../test/generated-artifacts/InitialMigration.json';
 | 
					import * as InitialMigration from '../test/generated-artifacts/InitialMigration.json';
 | 
				
			||||||
import * as IOwnableFeature from '../test/generated-artifacts/IOwnableFeature.json';
 | 
					import * as IOwnableFeature from '../test/generated-artifacts/IOwnableFeature.json';
 | 
				
			||||||
import * as ISignatureValidatorFeature from '../test/generated-artifacts/ISignatureValidatorFeature.json';
 | 
					 | 
				
			||||||
import * as ISimpleFunctionRegistryFeature from '../test/generated-artifacts/ISimpleFunctionRegistryFeature.json';
 | 
					import * as ISimpleFunctionRegistryFeature from '../test/generated-artifacts/ISimpleFunctionRegistryFeature.json';
 | 
				
			||||||
import * as IStaking from '../test/generated-artifacts/IStaking.json';
 | 
					import * as IStaking from '../test/generated-artifacts/IStaking.json';
 | 
				
			||||||
import * as ITestSimpleFunctionRegistryFeature from '../test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json';
 | 
					import * as ITestSimpleFunctionRegistryFeature from '../test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json';
 | 
				
			||||||
@@ -94,7 +93,6 @@ import * as NativeOrdersFeature from '../test/generated-artifacts/NativeOrdersFe
 | 
				
			|||||||
import * as OwnableFeature from '../test/generated-artifacts/OwnableFeature.json';
 | 
					import * as OwnableFeature from '../test/generated-artifacts/OwnableFeature.json';
 | 
				
			||||||
import * as PayTakerTransformer from '../test/generated-artifacts/PayTakerTransformer.json';
 | 
					import * as PayTakerTransformer from '../test/generated-artifacts/PayTakerTransformer.json';
 | 
				
			||||||
import * as PermissionlessTransformerDeployer from '../test/generated-artifacts/PermissionlessTransformerDeployer.json';
 | 
					import * as PermissionlessTransformerDeployer from '../test/generated-artifacts/PermissionlessTransformerDeployer.json';
 | 
				
			||||||
import * as SignatureValidatorFeature from '../test/generated-artifacts/SignatureValidatorFeature.json';
 | 
					 | 
				
			||||||
import * as SimpleFunctionRegistryFeature from '../test/generated-artifacts/SimpleFunctionRegistryFeature.json';
 | 
					import * as SimpleFunctionRegistryFeature from '../test/generated-artifacts/SimpleFunctionRegistryFeature.json';
 | 
				
			||||||
import * as TestBridge from '../test/generated-artifacts/TestBridge.json';
 | 
					import * as TestBridge from '../test/generated-artifacts/TestBridge.json';
 | 
				
			||||||
import * as TestCallTarget from '../test/generated-artifacts/TestCallTarget.json';
 | 
					import * as TestCallTarget from '../test/generated-artifacts/TestCallTarget.json';
 | 
				
			||||||
@@ -172,7 +170,6 @@ export const artifacts = {
 | 
				
			|||||||
    IMetaTransactionsFeature: IMetaTransactionsFeature as ContractArtifact,
 | 
					    IMetaTransactionsFeature: IMetaTransactionsFeature as ContractArtifact,
 | 
				
			||||||
    INativeOrdersFeature: INativeOrdersFeature as ContractArtifact,
 | 
					    INativeOrdersFeature: INativeOrdersFeature as ContractArtifact,
 | 
				
			||||||
    IOwnableFeature: IOwnableFeature as ContractArtifact,
 | 
					    IOwnableFeature: IOwnableFeature as ContractArtifact,
 | 
				
			||||||
    ISignatureValidatorFeature: ISignatureValidatorFeature as ContractArtifact,
 | 
					 | 
				
			||||||
    ISimpleFunctionRegistryFeature: ISimpleFunctionRegistryFeature as ContractArtifact,
 | 
					    ISimpleFunctionRegistryFeature: ISimpleFunctionRegistryFeature as ContractArtifact,
 | 
				
			||||||
    ITokenSpenderFeature: ITokenSpenderFeature as ContractArtifact,
 | 
					    ITokenSpenderFeature: ITokenSpenderFeature as ContractArtifact,
 | 
				
			||||||
    ITransformERC20Feature: ITransformERC20Feature as ContractArtifact,
 | 
					    ITransformERC20Feature: ITransformERC20Feature as ContractArtifact,
 | 
				
			||||||
@@ -181,7 +178,6 @@ export const artifacts = {
 | 
				
			|||||||
    MetaTransactionsFeature: MetaTransactionsFeature as ContractArtifact,
 | 
					    MetaTransactionsFeature: MetaTransactionsFeature as ContractArtifact,
 | 
				
			||||||
    NativeOrdersFeature: NativeOrdersFeature as ContractArtifact,
 | 
					    NativeOrdersFeature: NativeOrdersFeature as ContractArtifact,
 | 
				
			||||||
    OwnableFeature: OwnableFeature as ContractArtifact,
 | 
					    OwnableFeature: OwnableFeature as ContractArtifact,
 | 
				
			||||||
    SignatureValidatorFeature: SignatureValidatorFeature as ContractArtifact,
 | 
					 | 
				
			||||||
    SimpleFunctionRegistryFeature: SimpleFunctionRegistryFeature as ContractArtifact,
 | 
					    SimpleFunctionRegistryFeature: SimpleFunctionRegistryFeature as ContractArtifact,
 | 
				
			||||||
    TokenSpenderFeature: TokenSpenderFeature as ContractArtifact,
 | 
					    TokenSpenderFeature: TokenSpenderFeature as ContractArtifact,
 | 
				
			||||||
    TransformERC20Feature: TransformERC20Feature as ContractArtifact,
 | 
					    TransformERC20Feature: TransformERC20Feature as ContractArtifact,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,231 +0,0 @@
 | 
				
			|||||||
import { blockchainTests, constants, expect, randomAddress, signingUtils } from '@0x/contracts-test-utils';
 | 
					 | 
				
			||||||
import { signatureUtils } from '@0x/order-utils';
 | 
					 | 
				
			||||||
import { SignatureType } from '@0x/types';
 | 
					 | 
				
			||||||
import { hexUtils, ZeroExRevertErrors } from '@0x/utils';
 | 
					 | 
				
			||||||
import * as ethjs from 'ethereumjs-util';
 | 
					 | 
				
			||||||
import * as _ from 'lodash';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { IZeroExContract, SignatureValidatorFeatureContract } from '../../src/wrappers';
 | 
					 | 
				
			||||||
import { abis } from '../utils/abis';
 | 
					 | 
				
			||||||
import { fullMigrateAsync } from '../utils/migration';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const { NULL_BYTES } = constants;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
blockchainTests.resets('SignatureValidator feature', env => {
 | 
					 | 
				
			||||||
    let owner: string;
 | 
					 | 
				
			||||||
    let signers: string[];
 | 
					 | 
				
			||||||
    let zeroEx: IZeroExContract;
 | 
					 | 
				
			||||||
    let feature: SignatureValidatorFeatureContract;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    before(async () => {
 | 
					 | 
				
			||||||
        [owner, ...signers] = await env.getAccountAddressesAsync();
 | 
					 | 
				
			||||||
        zeroEx = await fullMigrateAsync(owner, env.provider, env.txDefaults);
 | 
					 | 
				
			||||||
        feature = new SignatureValidatorFeatureContract(zeroEx.address, env.provider, env.txDefaults, abis);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    describe('validateHashSignature()', () => {
 | 
					 | 
				
			||||||
        it('can validate an eth_sign signature', async () => {
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = _.sampleSize(signers, 1)[0];
 | 
					 | 
				
			||||||
            const signature = await signatureUtils.ecSignHashAsync(env.provider, hash, signer);
 | 
					 | 
				
			||||||
            await feature.validateHashSignature(hash, signer, signature).callAsync();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('rejects a wrong eth_sign signature', async () => {
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = _.sampleSize(signers, 1)[0];
 | 
					 | 
				
			||||||
            const signature = await signatureUtils.ecSignHashAsync(env.provider, hash, signer);
 | 
					 | 
				
			||||||
            const notSigner = randomAddress();
 | 
					 | 
				
			||||||
            const tx = feature.validateHashSignature(hash, notSigner, signature).callAsync();
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(
 | 
					 | 
				
			||||||
                new ZeroExRevertErrors.SignatureValidator.SignatureValidationError(
 | 
					 | 
				
			||||||
                    ZeroExRevertErrors.SignatureValidator.SignatureValidationErrorCodes.WrongSigner,
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    notSigner,
 | 
					 | 
				
			||||||
                    signature,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('rejects an eth_sign if ecrecover() fails', async () => {
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = _.sampleSize(signers, 1)[0];
 | 
					 | 
				
			||||||
            const signature = hexUtils.concat(hexUtils.random(65), SignatureType.EthSign);
 | 
					 | 
				
			||||||
            const tx = feature.validateHashSignature(hash, signer, signature).callAsync();
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(
 | 
					 | 
				
			||||||
                new ZeroExRevertErrors.SignatureValidator.SignatureValidationError(
 | 
					 | 
				
			||||||
                    ZeroExRevertErrors.SignatureValidator.SignatureValidationErrorCodes.WrongSigner,
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    signer,
 | 
					 | 
				
			||||||
                    signature,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('rejects a too short eth_sign signature', async () => {
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = _.sampleSize(signers, 1)[0];
 | 
					 | 
				
			||||||
            const signature = hexUtils.slice(await signatureUtils.ecSignHashAsync(env.provider, hash, signer), 1);
 | 
					 | 
				
			||||||
            const tx = feature.validateHashSignature(hash, signer, signature).callAsync();
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(
 | 
					 | 
				
			||||||
                new ZeroExRevertErrors.SignatureValidator.SignatureValidationError(
 | 
					 | 
				
			||||||
                    ZeroExRevertErrors.SignatureValidator.SignatureValidationErrorCodes.InvalidLength,
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    signer,
 | 
					 | 
				
			||||||
                    signature,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('can validate an eip712 signature', async () => {
 | 
					 | 
				
			||||||
            const privateKey = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = hexUtils.toHex(ethjs.privateToAddress(ethjs.toBuffer(privateKey)));
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signature = hexUtils.toHex(
 | 
					 | 
				
			||||||
                signingUtils.signMessage(ethjs.toBuffer(hash), ethjs.toBuffer(privateKey), SignatureType.EIP712),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            await feature.validateHashSignature(hash, signer, signature).callAsync();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('rejects a wrong eip712 signature', async () => {
 | 
					 | 
				
			||||||
            const privateKey = hexUtils.random();
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signature = hexUtils.toHex(
 | 
					 | 
				
			||||||
                signingUtils.signMessage(ethjs.toBuffer(hash), ethjs.toBuffer(privateKey), SignatureType.EIP712),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            const notSigner = randomAddress();
 | 
					 | 
				
			||||||
            const tx = feature.validateHashSignature(hash, notSigner, signature).callAsync();
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(
 | 
					 | 
				
			||||||
                new ZeroExRevertErrors.SignatureValidator.SignatureValidationError(
 | 
					 | 
				
			||||||
                    ZeroExRevertErrors.SignatureValidator.SignatureValidationErrorCodes.WrongSigner,
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    notSigner,
 | 
					 | 
				
			||||||
                    signature,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('rejects an eip712 if ecrecover() fails', async () => {
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = _.sampleSize(signers, 1)[0];
 | 
					 | 
				
			||||||
            const signature = hexUtils.concat(hexUtils.random(65), SignatureType.EIP712);
 | 
					 | 
				
			||||||
            const tx = feature.validateHashSignature(hash, signer, signature).callAsync();
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(
 | 
					 | 
				
			||||||
                new ZeroExRevertErrors.SignatureValidator.SignatureValidationError(
 | 
					 | 
				
			||||||
                    ZeroExRevertErrors.SignatureValidator.SignatureValidationErrorCodes.WrongSigner,
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    signer,
 | 
					 | 
				
			||||||
                    signature,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('rejects a too short eip712 signature', async () => {
 | 
					 | 
				
			||||||
            const privateKey = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = hexUtils.toHex(ethjs.privateToAddress(ethjs.toBuffer(privateKey)));
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signature = hexUtils.slice(
 | 
					 | 
				
			||||||
                hexUtils.toHex(
 | 
					 | 
				
			||||||
                    signingUtils.signMessage(ethjs.toBuffer(hash), ethjs.toBuffer(privateKey), SignatureType.EIP712),
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
                1,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            const tx = feature.validateHashSignature(hash, signer, signature).callAsync();
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(
 | 
					 | 
				
			||||||
                new ZeroExRevertErrors.SignatureValidator.SignatureValidationError(
 | 
					 | 
				
			||||||
                    ZeroExRevertErrors.SignatureValidator.SignatureValidationErrorCodes.InvalidLength,
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    signer,
 | 
					 | 
				
			||||||
                    signature,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('rejects an INVALID signature type', async () => {
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = _.sampleSize(signers, 1)[0];
 | 
					 | 
				
			||||||
            const signature = hexUtils.concat(
 | 
					 | 
				
			||||||
                hexUtils.slice(await signatureUtils.ecSignHashAsync(env.provider, hash, signer), 0, -1),
 | 
					 | 
				
			||||||
                SignatureType.Invalid,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            const tx = feature.validateHashSignature(hash, signer, signature).callAsync();
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(
 | 
					 | 
				
			||||||
                new ZeroExRevertErrors.SignatureValidator.SignatureValidationError(
 | 
					 | 
				
			||||||
                    ZeroExRevertErrors.SignatureValidator.SignatureValidationErrorCodes.AlwaysInvalid,
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    signer,
 | 
					 | 
				
			||||||
                    signature,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('rejects an ILLEGAL signature type', async () => {
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = _.sampleSize(signers, 1)[0];
 | 
					 | 
				
			||||||
            const signature = hexUtils.concat(
 | 
					 | 
				
			||||||
                hexUtils.slice(await signatureUtils.ecSignHashAsync(env.provider, hash, signer), 0, -1),
 | 
					 | 
				
			||||||
                SignatureType.Illegal,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            const tx = feature.validateHashSignature(hash, signer, signature).callAsync();
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(
 | 
					 | 
				
			||||||
                new ZeroExRevertErrors.SignatureValidator.SignatureValidationError(
 | 
					 | 
				
			||||||
                    ZeroExRevertErrors.SignatureValidator.SignatureValidationErrorCodes.Illegal,
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    signer,
 | 
					 | 
				
			||||||
                    signature,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('rejects an unsupported signature type', async () => {
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = _.sampleSize(signers, 1)[0];
 | 
					 | 
				
			||||||
            const signature = hexUtils.concat(
 | 
					 | 
				
			||||||
                hexUtils.slice(await signatureUtils.ecSignHashAsync(env.provider, hash, signer), 0, -1),
 | 
					 | 
				
			||||||
                SignatureType.Wallet,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            const tx = feature.validateHashSignature(hash, signer, signature).callAsync();
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(
 | 
					 | 
				
			||||||
                new ZeroExRevertErrors.SignatureValidator.SignatureValidationError(
 | 
					 | 
				
			||||||
                    ZeroExRevertErrors.SignatureValidator.SignatureValidationErrorCodes.Unsupported,
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    signer,
 | 
					 | 
				
			||||||
                    signature,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('rejects an empty signature type', async () => {
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = _.sampleSize(signers, 1)[0];
 | 
					 | 
				
			||||||
            const signature = NULL_BYTES;
 | 
					 | 
				
			||||||
            const tx = feature.validateHashSignature(hash, signer, signature).callAsync();
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(
 | 
					 | 
				
			||||||
                new ZeroExRevertErrors.SignatureValidator.SignatureValidationError(
 | 
					 | 
				
			||||||
                    ZeroExRevertErrors.SignatureValidator.SignatureValidationErrorCodes.InvalidLength,
 | 
					 | 
				
			||||||
                    hash,
 | 
					 | 
				
			||||||
                    signer,
 | 
					 | 
				
			||||||
                    signature,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    describe('isValidHashSignature()', () => {
 | 
					 | 
				
			||||||
        it('returns true on valid signature', async () => {
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = _.sampleSize(signers, 1)[0];
 | 
					 | 
				
			||||||
            const signature = await signatureUtils.ecSignHashAsync(env.provider, hash, signer);
 | 
					 | 
				
			||||||
            const r = await feature.isValidHashSignature(hash, signer, signature).callAsync();
 | 
					 | 
				
			||||||
            expect(r).to.eq(true);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('returns false on invalid signature', async () => {
 | 
					 | 
				
			||||||
            const hash = hexUtils.random();
 | 
					 | 
				
			||||||
            const signer = _.sampleSize(signers, 1)[0];
 | 
					 | 
				
			||||||
            const signature = await signatureUtils.ecSignHashAsync(env.provider, hash, signer);
 | 
					 | 
				
			||||||
            const r = await feature.isValidHashSignature(hash, randomAddress(), signature).callAsync();
 | 
					 | 
				
			||||||
            expect(r).to.eq(false);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -12,7 +12,6 @@ import {
 | 
				
			|||||||
    IMetaTransactionsFeatureContract,
 | 
					    IMetaTransactionsFeatureContract,
 | 
				
			||||||
    INativeOrdersFeatureContract,
 | 
					    INativeOrdersFeatureContract,
 | 
				
			||||||
    IOwnableFeatureContract,
 | 
					    IOwnableFeatureContract,
 | 
				
			||||||
    ISignatureValidatorFeatureContract,
 | 
					 | 
				
			||||||
    ITokenSpenderFeatureContract,
 | 
					    ITokenSpenderFeatureContract,
 | 
				
			||||||
    ITransformERC20FeatureContract,
 | 
					    ITransformERC20FeatureContract,
 | 
				
			||||||
    TestFullMigrationContract,
 | 
					    TestFullMigrationContract,
 | 
				
			||||||
@@ -86,22 +85,17 @@ blockchainTests.resets('Full migration', env => {
 | 
				
			|||||||
                'setQuoteSigner',
 | 
					                'setQuoteSigner',
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        SignatureValidator: {
 | 
					 | 
				
			||||||
            contractType: ISignatureValidatorFeatureContract,
 | 
					 | 
				
			||||||
            fns: ['isValidHashSignature', 'validateHashSignature'],
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        MetaTransactions: {
 | 
					        MetaTransactions: {
 | 
				
			||||||
            contractType: IMetaTransactionsFeatureContract,
 | 
					            contractType: IMetaTransactionsFeatureContract,
 | 
				
			||||||
            fns: [
 | 
					            fns: [
 | 
				
			||||||
                'executeMetaTransaction',
 | 
					                'executeMetaTransaction',
 | 
				
			||||||
                'batchExecuteMetaTransactions',
 | 
					                'batchExecuteMetaTransactions',
 | 
				
			||||||
                '_executeMetaTransaction',
 | 
					 | 
				
			||||||
                'getMetaTransactionExecutedBlock',
 | 
					                'getMetaTransactionExecutedBlock',
 | 
				
			||||||
                'getMetaTransactionHashExecutedBlock',
 | 
					                'getMetaTransactionHashExecutedBlock',
 | 
				
			||||||
                'getMetaTransactionHash',
 | 
					                'getMetaTransactionHash',
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        LimitOrdersFeature: {
 | 
					        NativeOrdersFeature: {
 | 
				
			||||||
            contractType: INativeOrdersFeatureContract,
 | 
					            contractType: INativeOrdersFeatureContract,
 | 
				
			||||||
            fns: [
 | 
					            fns: [
 | 
				
			||||||
                'transferProtocolFeesForPools',
 | 
					                'transferProtocolFeesForPools',
 | 
				
			||||||
@@ -124,6 +118,11 @@ blockchainTests.resets('Full migration', env => {
 | 
				
			|||||||
                'getLimitOrderHash',
 | 
					                'getLimitOrderHash',
 | 
				
			||||||
                'getRfqOrderHash',
 | 
					                'getRfqOrderHash',
 | 
				
			||||||
                'getProtocolFeeMultiplier',
 | 
					                'getProtocolFeeMultiplier',
 | 
				
			||||||
 | 
					                'registerAllowedRfqOrigins',
 | 
				
			||||||
 | 
					                'getLimitOrderRelevantState',
 | 
				
			||||||
 | 
					                'getRfqOrderRelevantState',
 | 
				
			||||||
 | 
					                'batchGetLimitOrderRelevantStates',
 | 
				
			||||||
 | 
					                'batchGetRfqOrderRelevantStates',
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,7 +32,6 @@ export * from '../test/generated-wrappers/i_liquidity_provider_sandbox';
 | 
				
			|||||||
export * from '../test/generated-wrappers/i_meta_transactions_feature';
 | 
					export * from '../test/generated-wrappers/i_meta_transactions_feature';
 | 
				
			||||||
export * from '../test/generated-wrappers/i_native_orders_feature';
 | 
					export * from '../test/generated-wrappers/i_native_orders_feature';
 | 
				
			||||||
export * from '../test/generated-wrappers/i_ownable_feature';
 | 
					export * from '../test/generated-wrappers/i_ownable_feature';
 | 
				
			||||||
export * from '../test/generated-wrappers/i_signature_validator_feature';
 | 
					 | 
				
			||||||
export * from '../test/generated-wrappers/i_simple_function_registry_feature';
 | 
					export * from '../test/generated-wrappers/i_simple_function_registry_feature';
 | 
				
			||||||
export * from '../test/generated-wrappers/i_staking';
 | 
					export * from '../test/generated-wrappers/i_staking';
 | 
				
			||||||
export * from '../test/generated-wrappers/i_test_simple_function_registry_feature';
 | 
					export * from '../test/generated-wrappers/i_test_simple_function_registry_feature';
 | 
				
			||||||
@@ -92,7 +91,6 @@ export * from '../test/generated-wrappers/native_orders_feature';
 | 
				
			|||||||
export * from '../test/generated-wrappers/ownable_feature';
 | 
					export * from '../test/generated-wrappers/ownable_feature';
 | 
				
			||||||
export * from '../test/generated-wrappers/pay_taker_transformer';
 | 
					export * from '../test/generated-wrappers/pay_taker_transformer';
 | 
				
			||||||
export * from '../test/generated-wrappers/permissionless_transformer_deployer';
 | 
					export * from '../test/generated-wrappers/permissionless_transformer_deployer';
 | 
				
			||||||
export * from '../test/generated-wrappers/signature_validator_feature';
 | 
					 | 
				
			||||||
export * from '../test/generated-wrappers/simple_function_registry_feature';
 | 
					export * from '../test/generated-wrappers/simple_function_registry_feature';
 | 
				
			||||||
export * from '../test/generated-wrappers/test_bridge';
 | 
					export * from '../test/generated-wrappers/test_bridge';
 | 
				
			||||||
export * from '../test/generated-wrappers/test_call_target';
 | 
					export * from '../test/generated-wrappers/test_call_target';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,7 +61,6 @@
 | 
				
			|||||||
        "test/generated-artifacts/IMetaTransactionsFeature.json",
 | 
					        "test/generated-artifacts/IMetaTransactionsFeature.json",
 | 
				
			||||||
        "test/generated-artifacts/INativeOrdersFeature.json",
 | 
					        "test/generated-artifacts/INativeOrdersFeature.json",
 | 
				
			||||||
        "test/generated-artifacts/IOwnableFeature.json",
 | 
					        "test/generated-artifacts/IOwnableFeature.json",
 | 
				
			||||||
        "test/generated-artifacts/ISignatureValidatorFeature.json",
 | 
					 | 
				
			||||||
        "test/generated-artifacts/ISimpleFunctionRegistryFeature.json",
 | 
					        "test/generated-artifacts/ISimpleFunctionRegistryFeature.json",
 | 
				
			||||||
        "test/generated-artifacts/IStaking.json",
 | 
					        "test/generated-artifacts/IStaking.json",
 | 
				
			||||||
        "test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json",
 | 
					        "test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json",
 | 
				
			||||||
@@ -121,7 +120,6 @@
 | 
				
			|||||||
        "test/generated-artifacts/OwnableFeature.json",
 | 
					        "test/generated-artifacts/OwnableFeature.json",
 | 
				
			||||||
        "test/generated-artifacts/PayTakerTransformer.json",
 | 
					        "test/generated-artifacts/PayTakerTransformer.json",
 | 
				
			||||||
        "test/generated-artifacts/PermissionlessTransformerDeployer.json",
 | 
					        "test/generated-artifacts/PermissionlessTransformerDeployer.json",
 | 
				
			||||||
        "test/generated-artifacts/SignatureValidatorFeature.json",
 | 
					 | 
				
			||||||
        "test/generated-artifacts/SimpleFunctionRegistryFeature.json",
 | 
					        "test/generated-artifacts/SimpleFunctionRegistryFeature.json",
 | 
				
			||||||
        "test/generated-artifacts/TestBridge.json",
 | 
					        "test/generated-artifacts/TestBridge.json",
 | 
				
			||||||
        "test/generated-artifacts/TestCallTarget.json",
 | 
					        "test/generated-artifacts/TestCallTarget.json",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,10 @@
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                "note": "Redeploy LiquidityProviderSandbox",
 | 
					                "note": "Redeploy LiquidityProviderSandbox",
 | 
				
			||||||
                "pr": 107
 | 
					                "pr": 107
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Update ganache snapshot addresses",
 | 
				
			||||||
 | 
					                "pr": 109
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -198,10 +198,10 @@
 | 
				
			|||||||
        "exchangeProxyFlashWallet": "0xb9682a8e7920b431f1d412b8510f0077410c8faa",
 | 
					        "exchangeProxyFlashWallet": "0xb9682a8e7920b431f1d412b8510f0077410c8faa",
 | 
				
			||||||
        "exchangeProxyLiquidityProviderSandbox": "0x0000000000000000000000000000000000000000",
 | 
					        "exchangeProxyLiquidityProviderSandbox": "0x0000000000000000000000000000000000000000",
 | 
				
			||||||
        "transformers": {
 | 
					        "transformers": {
 | 
				
			||||||
            "wethTransformer": "0x3f16ca81691dab9184cb4606c361d73c4fd2510a",
 | 
					            "wethTransformer": "0x7209185959d7227fb77274e1e88151d7c4c368d3",
 | 
				
			||||||
            "payTakerTransformer": "0x99356167edba8fbdc36959e3f5d0c43d1ba9c6db",
 | 
					            "payTakerTransformer": "0x3f16ca81691dab9184cb4606c361d73c4fd2510a",
 | 
				
			||||||
            "affiliateFeeTransformer": "0x45b3a72221e571017c0f0ec42189e11d149d0ace",
 | 
					            "affiliateFeeTransformer": "0x99356167edba8fbdc36959e3f5d0c43d1ba9c6db",
 | 
				
			||||||
            "fillQuoteTransformer": "0xdd66c23e07b4d6925b6089b5fe6fc9e62941afe8"
 | 
					            "fillQuoteTransformer": "0x45b3a72221e571017c0f0ec42189e11d149d0ace"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user