EP: Add LibSignature library (#21)
				
					
				
			* `@0x/contracts-zero-ex`: Add `LibSignature` library * `@0x/contracts-zero-ex`: Update package.json scripts Co-authored-by: Lawrence Forman <me@merklejerk.com>
This commit is contained in:
		@@ -5,6 +5,10 @@
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                "note": "Add support for collecting protocol fees in ETH or WETH",
 | 
					                "note": "Add support for collecting protocol fees in ETH or WETH",
 | 
				
			||||||
                "pr": 2
 | 
					                "pr": 2
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "note": "Add `LibSignature` library",
 | 
				
			||||||
 | 
					                "pr": 21
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,8 @@ library LibSignatureRichErrors {
 | 
				
			|||||||
        INVALID_LENGTH,
 | 
					        INVALID_LENGTH,
 | 
				
			||||||
        UNSUPPORTED,
 | 
					        UNSUPPORTED,
 | 
				
			||||||
        ILLEGAL,
 | 
					        ILLEGAL,
 | 
				
			||||||
        WRONG_SIGNER
 | 
					        WRONG_SIGNER,
 | 
				
			||||||
 | 
					        BAD_SIGNATURE_DATA
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // solhint-disable func-name-mixedcase
 | 
					    // solhint-disable func-name-mixedcase
 | 
				
			||||||
@@ -49,4 +50,19 @@ library LibSignatureRichErrors {
 | 
				
			|||||||
            signature
 | 
					            signature
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function SignatureValidationError(
 | 
				
			||||||
 | 
					        SignatureValidationErrorCodes code,
 | 
				
			||||||
 | 
					        bytes32 hash
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					        internal
 | 
				
			||||||
 | 
					        pure
 | 
				
			||||||
 | 
					        returns (bytes memory)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return abi.encodeWithSelector(
 | 
				
			||||||
 | 
					            bytes4(keccak256("SignatureValidationError(uint8,bytes32)")),
 | 
				
			||||||
 | 
					            code,
 | 
				
			||||||
 | 
					            hash
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										151
									
								
								contracts/zero-ex/contracts/src/features/libs/LibSignature.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								contracts/zero-ex/contracts/src/features/libs/LibSignature.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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 "../../errors/LibSignatureRichErrors.sol";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @dev A library for validating signatures.
 | 
				
			||||||
 | 
					library LibSignature {
 | 
				
			||||||
 | 
					    using LibRichErrorsV06 for bytes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // '\x19Ethereum Signed Message:\n32\x00\x00\x00\x00' in a word.
 | 
				
			||||||
 | 
					    uint256 private constant ETH_SIGN_HASH_PREFIX =
 | 
				
			||||||
 | 
					        0x19457468657265756d205369676e6564204d6573736167653a0a333200000000;
 | 
				
			||||||
 | 
					    /// @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 Allowed signature types.
 | 
				
			||||||
 | 
					    enum SignatureType {
 | 
				
			||||||
 | 
					        ILLEGAL,
 | 
				
			||||||
 | 
					        INVALID,
 | 
				
			||||||
 | 
					        EIP712,
 | 
				
			||||||
 | 
					        ETHSIGN
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @dev Encoded EC signature.
 | 
				
			||||||
 | 
					    struct Signature {
 | 
				
			||||||
 | 
					        // How to validate the signature.
 | 
				
			||||||
 | 
					        SignatureType signatureType;
 | 
				
			||||||
 | 
					        // EC Signature data.
 | 
				
			||||||
 | 
					        uint8 v;
 | 
				
			||||||
 | 
					        // EC Signature data.
 | 
				
			||||||
 | 
					        bytes32 r;
 | 
				
			||||||
 | 
					        // EC Signature data.
 | 
				
			||||||
 | 
					        bytes32 s;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @dev Retrieve the signer of a signature.
 | 
				
			||||||
 | 
					    ///      Throws if the signature can't be validated.
 | 
				
			||||||
 | 
					    /// @param hash The hash that was signed.
 | 
				
			||||||
 | 
					    /// @param signature The signature.
 | 
				
			||||||
 | 
					    /// @return recovered The recovered signer address.
 | 
				
			||||||
 | 
					    function getSignerOfHash(
 | 
				
			||||||
 | 
					        bytes32 hash,
 | 
				
			||||||
 | 
					        Signature memory signature
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					        internal
 | 
				
			||||||
 | 
					        pure
 | 
				
			||||||
 | 
					        returns (address recovered)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Ensure this is a signature type that can be validated against a hash.
 | 
				
			||||||
 | 
					        _validateHashCompatibleSignature(hash, signature);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (signature.signatureType == SignatureType.EIP712) {
 | 
				
			||||||
 | 
					            // Signed using EIP712
 | 
				
			||||||
 | 
					            recovered = ecrecover(
 | 
				
			||||||
 | 
					                hash,
 | 
				
			||||||
 | 
					                signature.v,
 | 
				
			||||||
 | 
					                signature.r,
 | 
				
			||||||
 | 
					                signature.s
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        } else if (signature.signatureType == SignatureType.ETHSIGN) {
 | 
				
			||||||
 | 
					            // Signed using `eth_sign`
 | 
				
			||||||
 | 
					            // Need to hash `hash` with "\x19Ethereum Signed Message:\n32" prefix
 | 
				
			||||||
 | 
					            // in packed encoding.
 | 
				
			||||||
 | 
					            bytes32 ethSignHash;
 | 
				
			||||||
 | 
					            assembly {
 | 
				
			||||||
 | 
					                // Use scratch space
 | 
				
			||||||
 | 
					                mstore(0, ETH_SIGN_HASH_PREFIX) // length of 28 bytes
 | 
				
			||||||
 | 
					                mstore(28, hash) // length of 32 bytes
 | 
				
			||||||
 | 
					                ethSignHash := keccak256(0, 60)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            recovered = ecrecover(
 | 
				
			||||||
 | 
					                ethSignHash,
 | 
				
			||||||
 | 
					                signature.v,
 | 
				
			||||||
 | 
					                signature.r,
 | 
				
			||||||
 | 
					                signature.s
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // `recovered` can be null if the signature values are out of range.
 | 
				
			||||||
 | 
					        if (recovered == address(0)) {
 | 
				
			||||||
 | 
					            LibSignatureRichErrors.SignatureValidationError(
 | 
				
			||||||
 | 
					                LibSignatureRichErrors.SignatureValidationErrorCodes.BAD_SIGNATURE_DATA,
 | 
				
			||||||
 | 
					                hash
 | 
				
			||||||
 | 
					            ).rrevert();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @dev Validates that a signature is compatible with a hash signee.
 | 
				
			||||||
 | 
					    /// @param hash The hash that was signed.
 | 
				
			||||||
 | 
					    /// @param signature The signature.
 | 
				
			||||||
 | 
					    function _validateHashCompatibleSignature(
 | 
				
			||||||
 | 
					        bytes32 hash,
 | 
				
			||||||
 | 
					        Signature memory signature
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					        private
 | 
				
			||||||
 | 
					        pure
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Ensure the r and s are within malleability limits.
 | 
				
			||||||
 | 
					        if (uint256(signature.r) >= ECDSA_SIGNATURE_R_LIMIT ||
 | 
				
			||||||
 | 
					            uint256(signature.s) >= ECDSA_SIGNATURE_S_LIMIT)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            LibSignatureRichErrors.SignatureValidationError(
 | 
				
			||||||
 | 
					                LibSignatureRichErrors.SignatureValidationErrorCodes.BAD_SIGNATURE_DATA,
 | 
				
			||||||
 | 
					                hash
 | 
				
			||||||
 | 
					            ).rrevert();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Always illegal signature.
 | 
				
			||||||
 | 
					        if (signature.signatureType == SignatureType.ILLEGAL) {
 | 
				
			||||||
 | 
					            LibSignatureRichErrors.SignatureValidationError(
 | 
				
			||||||
 | 
					                LibSignatureRichErrors.SignatureValidationErrorCodes.ILLEGAL,
 | 
				
			||||||
 | 
					                hash
 | 
				
			||||||
 | 
					            ).rrevert();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Always invalid.
 | 
				
			||||||
 | 
					        if (signature.signatureType == SignatureType.INVALID) {
 | 
				
			||||||
 | 
					            LibSignatureRichErrors.SignatureValidationError(
 | 
				
			||||||
 | 
					                LibSignatureRichErrors.SignatureValidationErrorCodes.ALWAYS_INVALID,
 | 
				
			||||||
 | 
					                hash
 | 
				
			||||||
 | 
					            ).rrevert();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Solidity should check that the signature type is within enum range for us
 | 
				
			||||||
 | 
					        // when abi-decoding.
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										34
									
								
								contracts/zero-ex/contracts/test/TestLibSignature.sol
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								contracts/zero-ex/contracts/test/TestLibSignature.sol
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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 "../src/features/libs/LibSignature.sol";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					contract TestLibSignature {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function getSignerOfHash(bytes32 hash, LibSignature.Signature calldata signature)
 | 
				
			||||||
 | 
					        external
 | 
				
			||||||
 | 
					        pure
 | 
				
			||||||
 | 
					        returns (address signer)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return LibSignature.getSignerOfHash(hash, signature);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -10,8 +10,9 @@
 | 
				
			|||||||
        "test": "test"
 | 
					        "test": "test"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "scripts": {
 | 
					    "scripts": {
 | 
				
			||||||
        "build": "yarn pre_build && tsc -b",
 | 
					        "build": "yarn pre_build && yarn build:ts",
 | 
				
			||||||
        "build:ci": "yarn build",
 | 
					        "build:ci": "yarn build",
 | 
				
			||||||
 | 
					        "build:ts": "tsc -b",
 | 
				
			||||||
        "pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
 | 
					        "pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
 | 
				
			||||||
        "test": "yarn run_mocha",
 | 
					        "test": "yarn run_mocha",
 | 
				
			||||||
        "rebuild_and_test": "run-s build test",
 | 
					        "rebuild_and_test": "run-s build test",
 | 
				
			||||||
@@ -41,7 +42,7 @@
 | 
				
			|||||||
    "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",
 | 
					        "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",
 | 
				
			||||||
        "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|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FlashWallet|FullMigration|IAllowanceTarget|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IExchange|IFeature|IFlashWallet|IGasToken|ILiquidityProviderFeature|IMetaTransactionsFeature|IOwnableFeature|ISignatureValidatorFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibLiquidityProviderRichErrors|LibLiquidityProviderStorage|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignatureRichErrors|LibSignedCallData|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibSpenderRichErrors|LibStorage|LibTokenSpender|LibTokenSpenderStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LogMetadataTransformer|MetaTransactionsFeature|MixinAdapterAddresses|MixinBalancer|MixinCurve|MixinDodo|MixinKyber|MixinMStable|MixinMooniswap|MixinOasis|MixinShell|MixinSushiswap|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|OwnableFeature|PayTakerTransformer|SignatureValidatorFeature|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestDelegateCaller|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFullMigration|TestInitialMigration|TestLibTokenSpender|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestProtocolFees|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpender|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TokenSpenderFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx).json"
 | 
					        "abis": "./test/generated-artifacts/@(AffiliateFeeTransformer|AllowanceTarget|BootstrapFeature|BridgeAdapter|FeeCollector|FillQuoteTransformer|FixinCommon|FixinEIP712|FixinProtocolFees|FixinReentrancyGuard|FlashWallet|FullMigration|IAllowanceTarget|IBootstrapFeature|IBridgeAdapter|IERC20Bridge|IERC20Transformer|IExchange|IFeature|IFlashWallet|IGasToken|ILiquidityProviderFeature|IMetaTransactionsFeature|IOwnableFeature|ISignatureValidatorFeature|ISimpleFunctionRegistryFeature|IStaking|ITestSimpleFunctionRegistryFeature|ITokenSpenderFeature|ITransformERC20Feature|IUniswapFeature|IZeroEx|InitialMigration|LibBootstrap|LibCommonRichErrors|LibERC20Transformer|LibLiquidityProviderRichErrors|LibLiquidityProviderStorage|LibMetaTransactionsRichErrors|LibMetaTransactionsStorage|LibMigrate|LibOwnableRichErrors|LibOwnableStorage|LibProxyRichErrors|LibProxyStorage|LibReentrancyGuardStorage|LibSignature|LibSignatureRichErrors|LibSignedCallData|LibSimpleFunctionRegistryRichErrors|LibSimpleFunctionRegistryStorage|LibSpenderRichErrors|LibStorage|LibTokenSpender|LibTokenSpenderStorage|LibTransformERC20RichErrors|LibTransformERC20Storage|LibWalletRichErrors|LiquidityProviderFeature|LogMetadataTransformer|MetaTransactionsFeature|MixinAdapterAddresses|MixinBalancer|MixinCurve|MixinDodo|MixinKyber|MixinMStable|MixinMooniswap|MixinOasis|MixinShell|MixinSushiswap|MixinUniswap|MixinUniswapV2|MixinZeroExBridge|OwnableFeature|PayTakerTransformer|SignatureValidatorFeature|SimpleFunctionRegistryFeature|TestBridge|TestCallTarget|TestDelegateCaller|TestFillQuoteTransformerBridge|TestFillQuoteTransformerExchange|TestFillQuoteTransformerHost|TestFullMigration|TestInitialMigration|TestLibSignature|TestLibTokenSpender|TestMetaTransactionsTransformERC20Feature|TestMigrator|TestMintTokenERC20Transformer|TestMintableERC20Token|TestProtocolFees|TestSimpleFunctionRegistryFeatureImpl1|TestSimpleFunctionRegistryFeatureImpl2|TestStaking|TestTokenSpender|TestTokenSpenderERC20Token|TestTransformERC20|TestTransformerBase|TestTransformerDeployerTransformer|TestTransformerHost|TestWeth|TestWethTransformerHost|TestZeroExFeature|TokenSpenderFeature|TransformERC20Feature|Transformer|TransformerDeployer|UniswapFeature|WethTransformer|ZeroEx).json"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "repository": {
 | 
					    "repository": {
 | 
				
			||||||
        "type": "git",
 | 
					        "type": "git",
 | 
				
			||||||
@@ -76,6 +77,7 @@
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "dependencies": {
 | 
					    "dependencies": {
 | 
				
			||||||
        "@0x/base-contract": "^6.2.11",
 | 
					        "@0x/base-contract": "^6.2.11",
 | 
				
			||||||
 | 
					        "@0x/order-utils": "^10.4.2",
 | 
				
			||||||
        "@0x/subproviders": "^6.1.9",
 | 
					        "@0x/subproviders": "^6.1.9",
 | 
				
			||||||
        "@0x/types": "^3.3.0",
 | 
					        "@0x/types": "^3.3.0",
 | 
				
			||||||
        "@0x/typescript-typings": "^5.1.5",
 | 
					        "@0x/typescript-typings": "^5.1.5",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ export { artifacts } from './artifacts';
 | 
				
			|||||||
export * from './migration';
 | 
					export * from './migration';
 | 
				
			||||||
export * from './nonce_utils';
 | 
					export * from './nonce_utils';
 | 
				
			||||||
export * from './signed_call_data';
 | 
					export * from './signed_call_data';
 | 
				
			||||||
 | 
					export * from './signature_utils';
 | 
				
			||||||
export {
 | 
					export {
 | 
				
			||||||
    AffiliateFeeTransformerContract,
 | 
					    AffiliateFeeTransformerContract,
 | 
				
			||||||
    BridgeAdapterContract,
 | 
					    BridgeAdapterContract,
 | 
				
			||||||
@@ -48,3 +49,6 @@ export {
 | 
				
			|||||||
    WethTransformerContract,
 | 
					    WethTransformerContract,
 | 
				
			||||||
    ZeroExContract,
 | 
					    ZeroExContract,
 | 
				
			||||||
} from './wrappers';
 | 
					} from './wrappers';
 | 
				
			||||||
 | 
					export * from './revert_errors';
 | 
				
			||||||
 | 
					export { EIP712TypedData } from '@0x/types';
 | 
				
			||||||
 | 
					export { SupportedProvider } from '@0x/subproviders';
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								contracts/zero-ex/src/revert_errors.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								contracts/zero-ex/src/revert_errors.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					// TODO(dorothy-zbornak): Move these into `@0x/protocol-utils` whenever that
 | 
				
			||||||
 | 
					// becomes a thing.
 | 
				
			||||||
 | 
					// tslint:disable:max-classes-per-file
 | 
				
			||||||
 | 
					import { RevertError } from '@0x/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export enum SignatureValidationErrorCodes {
 | 
				
			||||||
 | 
					    AlwaysInvalid = 0,
 | 
				
			||||||
 | 
					    InvalidLength = 1,
 | 
				
			||||||
 | 
					    Unsupported = 2,
 | 
				
			||||||
 | 
					    Illegal = 3,
 | 
				
			||||||
 | 
					    WrongSigner = 4,
 | 
				
			||||||
 | 
					    BadSignatureData = 5,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// tslint:disable:max-classes-per-file
 | 
				
			||||||
 | 
					export class SignatureValidationError extends RevertError {
 | 
				
			||||||
 | 
					    constructor(code?: SignatureValidationErrorCodes, hash?: string) {
 | 
				
			||||||
 | 
					        super('SignatureValidationError', 'SignatureValidationError(uint8 code, bytes32 hash)', {
 | 
				
			||||||
 | 
					            code,
 | 
				
			||||||
 | 
					            hash,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const types = [SignatureValidationError];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Register the types we've defined.
 | 
				
			||||||
 | 
					for (const type of types) {
 | 
				
			||||||
 | 
					    RevertError.registerType(type);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										113
									
								
								contracts/zero-ex/src/signature_utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								contracts/zero-ex/src/signature_utils.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
				
			|||||||
 | 
					import { signatureUtils } from '@0x/order-utils';
 | 
				
			||||||
 | 
					import { SupportedProvider } from '@0x/subproviders';
 | 
				
			||||||
 | 
					import { EIP712TypedData } from '@0x/types';
 | 
				
			||||||
 | 
					import { hexUtils, signTypedDataUtils } from '@0x/utils';
 | 
				
			||||||
 | 
					import * as ethjs from 'ethereumjs-util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Valid signature types on the Exchange Proxy.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export enum SignatureType {
 | 
				
			||||||
 | 
					    Illegal = 0,
 | 
				
			||||||
 | 
					    Invalid = 1,
 | 
				
			||||||
 | 
					    EIP712 = 2,
 | 
				
			||||||
 | 
					    EthSign = 3,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Represents a raw EC signature.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export interface ECSignature {
 | 
				
			||||||
 | 
					    v: number;
 | 
				
			||||||
 | 
					    r: string;
 | 
				
			||||||
 | 
					    s: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A complete signature on the Exchange Proxy.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export interface Signature extends ECSignature {
 | 
				
			||||||
 | 
					    signatureType: SignatureType;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Sign a hash with the EthSign signature type on a provider.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export async function ethSignHashFromProviderAsync(
 | 
				
			||||||
 | 
					    signer: string,
 | 
				
			||||||
 | 
					    hash: string,
 | 
				
			||||||
 | 
					    provider: SupportedProvider,
 | 
				
			||||||
 | 
					): Promise<Signature> {
 | 
				
			||||||
 | 
					    const signatureBytes = await signatureUtils.ecSignHashAsync(provider, hash, signer);
 | 
				
			||||||
 | 
					    const parsed = parsePackedSignatureBytes(signatureBytes);
 | 
				
			||||||
 | 
					    assertSignatureType(parsed, SignatureType.EthSign);
 | 
				
			||||||
 | 
					    return parsed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Sign a hash with the EthSign signature type, given a private key.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function ethSignHashWithKey(hash: string, key: string): Signature {
 | 
				
			||||||
 | 
					    const ethHash = hexUtils.toHex(
 | 
				
			||||||
 | 
					        ethjs.sha3(hexUtils.concat(ethjs.toBuffer('\x19Ethereum Signed Message:\n32'), hash)),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        ...ecSignHashWithKey(ethHash, key),
 | 
				
			||||||
 | 
					        signatureType: SignatureType.EthSign,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Sign a typed data object with the EIP712 signature type, given a private key.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function eip712SignTypedDataWithKey(typedData: EIP712TypedData, key: string): Signature {
 | 
				
			||||||
 | 
					    const hash = hexUtils.toHex(signTypedDataUtils.generateTypedDataHash(typedData));
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        ...ecSignHashWithKey(hash, key),
 | 
				
			||||||
 | 
					        signatureType: SignatureType.EIP712,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Sign an EIP712 hash with the EIP712 signature type, given a private key.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function eip712SignHashWithKey(hash: string, key: string): Signature {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        ...ecSignHashWithKey(hash, key),
 | 
				
			||||||
 | 
					        signatureType: SignatureType.EIP712,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Generate the EC signature for a hash given a private key.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function ecSignHashWithKey(hash: string, key: string): ECSignature {
 | 
				
			||||||
 | 
					    const { v, r, s } = ethjs.ecsign(ethjs.toBuffer(hash), ethjs.toBuffer(key));
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        v,
 | 
				
			||||||
 | 
					        r: ethjs.bufferToHex(r),
 | 
				
			||||||
 | 
					        s: ethjs.bufferToHex(s),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function assertSignatureType(signature: Signature, expectedType: SignatureType): void {
 | 
				
			||||||
 | 
					    if (signature.signatureType !== expectedType) {
 | 
				
			||||||
 | 
					        throw new Error(`Expected signature type to be ${expectedType} but received ${signature.signatureType}.`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function parsePackedSignatureBytes(signatureBytes: string): Signature {
 | 
				
			||||||
 | 
					    if (hexUtils.size(signatureBytes) !== 66) {
 | 
				
			||||||
 | 
					        throw new Error(`Expected packed signatureBytes to be 66 bytes long: ${signatureBytes}`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const typeId = parseInt(signatureBytes.slice(-2), 16) as SignatureType;
 | 
				
			||||||
 | 
					    if (!Object.values(SignatureType).includes(typeId)) {
 | 
				
			||||||
 | 
					        throw new Error(`Invalid signatureBytes type ID detected: ${typeId}`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        signatureType: typeId,
 | 
				
			||||||
 | 
					        v: parseInt(signatureBytes.slice(2, 4), 16),
 | 
				
			||||||
 | 
					        r: hexUtils.slice(signatureBytes, 1, 33),
 | 
				
			||||||
 | 
					        s: hexUtils.slice(signatureBytes, 33),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -51,6 +51,7 @@ import * as LibOwnableStorage from '../test/generated-artifacts/LibOwnableStorag
 | 
				
			|||||||
import * as LibProxyRichErrors from '../test/generated-artifacts/LibProxyRichErrors.json';
 | 
					import * as LibProxyRichErrors from '../test/generated-artifacts/LibProxyRichErrors.json';
 | 
				
			||||||
import * as LibProxyStorage from '../test/generated-artifacts/LibProxyStorage.json';
 | 
					import * as LibProxyStorage from '../test/generated-artifacts/LibProxyStorage.json';
 | 
				
			||||||
import * as LibReentrancyGuardStorage from '../test/generated-artifacts/LibReentrancyGuardStorage.json';
 | 
					import * as LibReentrancyGuardStorage from '../test/generated-artifacts/LibReentrancyGuardStorage.json';
 | 
				
			||||||
 | 
					import * as LibSignature from '../test/generated-artifacts/LibSignature.json';
 | 
				
			||||||
import * as LibSignatureRichErrors from '../test/generated-artifacts/LibSignatureRichErrors.json';
 | 
					import * as LibSignatureRichErrors from '../test/generated-artifacts/LibSignatureRichErrors.json';
 | 
				
			||||||
import * as LibSignedCallData from '../test/generated-artifacts/LibSignedCallData.json';
 | 
					import * as LibSignedCallData from '../test/generated-artifacts/LibSignedCallData.json';
 | 
				
			||||||
import * as LibSimpleFunctionRegistryRichErrors from '../test/generated-artifacts/LibSimpleFunctionRegistryRichErrors.json';
 | 
					import * as LibSimpleFunctionRegistryRichErrors from '../test/generated-artifacts/LibSimpleFunctionRegistryRichErrors.json';
 | 
				
			||||||
@@ -90,6 +91,7 @@ import * as TestFillQuoteTransformerExchange from '../test/generated-artifacts/T
 | 
				
			|||||||
import * as TestFillQuoteTransformerHost from '../test/generated-artifacts/TestFillQuoteTransformerHost.json';
 | 
					import * as TestFillQuoteTransformerHost from '../test/generated-artifacts/TestFillQuoteTransformerHost.json';
 | 
				
			||||||
import * as TestFullMigration from '../test/generated-artifacts/TestFullMigration.json';
 | 
					import * as TestFullMigration from '../test/generated-artifacts/TestFullMigration.json';
 | 
				
			||||||
import * as TestInitialMigration from '../test/generated-artifacts/TestInitialMigration.json';
 | 
					import * as TestInitialMigration from '../test/generated-artifacts/TestInitialMigration.json';
 | 
				
			||||||
 | 
					import * as TestLibSignature from '../test/generated-artifacts/TestLibSignature.json';
 | 
				
			||||||
import * as TestLibTokenSpender from '../test/generated-artifacts/TestLibTokenSpender.json';
 | 
					import * as TestLibTokenSpender from '../test/generated-artifacts/TestLibTokenSpender.json';
 | 
				
			||||||
import * as TestMetaTransactionsTransformERC20Feature from '../test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json';
 | 
					import * as TestMetaTransactionsTransformERC20Feature from '../test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json';
 | 
				
			||||||
import * as TestMigrator from '../test/generated-artifacts/TestMigrator.json';
 | 
					import * as TestMigrator from '../test/generated-artifacts/TestMigrator.json';
 | 
				
			||||||
@@ -153,6 +155,7 @@ export const artifacts = {
 | 
				
			|||||||
    TokenSpenderFeature: TokenSpenderFeature as ContractArtifact,
 | 
					    TokenSpenderFeature: TokenSpenderFeature as ContractArtifact,
 | 
				
			||||||
    TransformERC20Feature: TransformERC20Feature as ContractArtifact,
 | 
					    TransformERC20Feature: TransformERC20Feature as ContractArtifact,
 | 
				
			||||||
    UniswapFeature: UniswapFeature as ContractArtifact,
 | 
					    UniswapFeature: UniswapFeature as ContractArtifact,
 | 
				
			||||||
 | 
					    LibSignature: LibSignature as ContractArtifact,
 | 
				
			||||||
    LibSignedCallData: LibSignedCallData as ContractArtifact,
 | 
					    LibSignedCallData: LibSignedCallData as ContractArtifact,
 | 
				
			||||||
    LibTokenSpender: LibTokenSpender as ContractArtifact,
 | 
					    LibTokenSpender: LibTokenSpender as ContractArtifact,
 | 
				
			||||||
    FixinCommon: FixinCommon as ContractArtifact,
 | 
					    FixinCommon: FixinCommon as ContractArtifact,
 | 
				
			||||||
@@ -208,6 +211,7 @@ export const artifacts = {
 | 
				
			|||||||
    TestFillQuoteTransformerHost: TestFillQuoteTransformerHost as ContractArtifact,
 | 
					    TestFillQuoteTransformerHost: TestFillQuoteTransformerHost as ContractArtifact,
 | 
				
			||||||
    TestFullMigration: TestFullMigration as ContractArtifact,
 | 
					    TestFullMigration: TestFullMigration as ContractArtifact,
 | 
				
			||||||
    TestInitialMigration: TestInitialMigration as ContractArtifact,
 | 
					    TestInitialMigration: TestInitialMigration as ContractArtifact,
 | 
				
			||||||
 | 
					    TestLibSignature: TestLibSignature as ContractArtifact,
 | 
				
			||||||
    TestLibTokenSpender: TestLibTokenSpender as ContractArtifact,
 | 
					    TestLibTokenSpender: TestLibTokenSpender as ContractArtifact,
 | 
				
			||||||
    TestMetaTransactionsTransformERC20Feature: TestMetaTransactionsTransformERC20Feature as ContractArtifact,
 | 
					    TestMetaTransactionsTransformERC20Feature: TestMetaTransactionsTransformERC20Feature as ContractArtifact,
 | 
				
			||||||
    TestMigrator: TestMigrator as ContractArtifact,
 | 
					    TestMigrator: TestMigrator as ContractArtifact,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										98
									
								
								contracts/zero-ex/test/lib_signature_test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								contracts/zero-ex/test/lib_signature_test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
				
			|||||||
 | 
					import { blockchainTests, expect } from '@0x/contracts-test-utils';
 | 
				
			||||||
 | 
					import { hexUtils } from '@0x/utils';
 | 
				
			||||||
 | 
					import * as ethjs from 'ethereumjs-util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { SignatureValidationError, SignatureValidationErrorCodes } from '../src/revert_errors';
 | 
				
			||||||
 | 
					import { eip712SignHashWithKey, ethSignHashWithKey, SignatureType } from '../src/signature_utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { artifacts } from './artifacts';
 | 
				
			||||||
 | 
					import { TestLibSignatureContract } from './wrappers';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const EMPTY_REVERT = 'reverted with no data';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					blockchainTests.resets('LibSignature library', env => {
 | 
				
			||||||
 | 
					    let testLib: TestLibSignatureContract;
 | 
				
			||||||
 | 
					    let signerKey: string;
 | 
				
			||||||
 | 
					    let signer: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    before(async () => {
 | 
				
			||||||
 | 
					        signerKey = hexUtils.random();
 | 
				
			||||||
 | 
					        signer = ethjs.bufferToHex(ethjs.privateToAddress(ethjs.toBuffer(signerKey)));
 | 
				
			||||||
 | 
					        testLib = await TestLibSignatureContract.deployFrom0xArtifactAsync(
 | 
				
			||||||
 | 
					            artifacts.TestLibSignature,
 | 
				
			||||||
 | 
					            env.provider,
 | 
				
			||||||
 | 
					            env.txDefaults,
 | 
				
			||||||
 | 
					            artifacts,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('getSignerOfHash()', () => {
 | 
				
			||||||
 | 
					        it('can recover the signer of an EIP712 signature', async () => {
 | 
				
			||||||
 | 
					            const hash = hexUtils.random();
 | 
				
			||||||
 | 
					            const sig = eip712SignHashWithKey(hash, signerKey);
 | 
				
			||||||
 | 
					            const recovered = await testLib.getSignerOfHash(hash, sig).callAsync();
 | 
				
			||||||
 | 
					            expect(recovered).to.eq(signer);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it('can recover the signer of an EthSign signature', async () => {
 | 
				
			||||||
 | 
					            const hash = hexUtils.random();
 | 
				
			||||||
 | 
					            const sig = ethSignHashWithKey(hash, signerKey);
 | 
				
			||||||
 | 
					            const recovered = await testLib.getSignerOfHash(hash, sig).callAsync();
 | 
				
			||||||
 | 
					            expect(recovered).to.eq(signer);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it('throws if the signature type is out of range', async () => {
 | 
				
			||||||
 | 
					            const hash = hexUtils.random();
 | 
				
			||||||
 | 
					            const badType = (Object.values(SignatureType).slice(-1)[0] as number) + 1;
 | 
				
			||||||
 | 
					            const sig = {
 | 
				
			||||||
 | 
					                ...ethSignHashWithKey(hash, signerKey),
 | 
				
			||||||
 | 
					                signatureType: badType,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            return expect(testLib.getSignerOfHash(hash, sig).callAsync()).to.be.rejectedWith(EMPTY_REVERT);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it('throws if the signature data is malformed', async () => {
 | 
				
			||||||
 | 
					            const hash = hexUtils.random();
 | 
				
			||||||
 | 
					            const sig = {
 | 
				
			||||||
 | 
					                ...ethSignHashWithKey(hash, signerKey),
 | 
				
			||||||
 | 
					                v: 1,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            return expect(testLib.getSignerOfHash(hash, sig).callAsync()).to.revertWith(
 | 
				
			||||||
 | 
					                new SignatureValidationError(SignatureValidationErrorCodes.BadSignatureData, hash),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it('throws if an EC value is out of range', async () => {
 | 
				
			||||||
 | 
					            const hash = hexUtils.random();
 | 
				
			||||||
 | 
					            const sig = {
 | 
				
			||||||
 | 
					                ...ethSignHashWithKey(hash, signerKey),
 | 
				
			||||||
 | 
					                r: '0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141',
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            return expect(testLib.getSignerOfHash(hash, sig).callAsync()).to.revertWith(
 | 
				
			||||||
 | 
					                new SignatureValidationError(SignatureValidationErrorCodes.BadSignatureData, hash),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it('throws if the type is Illegal', async () => {
 | 
				
			||||||
 | 
					            const hash = hexUtils.random();
 | 
				
			||||||
 | 
					            const sig = {
 | 
				
			||||||
 | 
					                ...ethSignHashWithKey(hash, signerKey),
 | 
				
			||||||
 | 
					                signatureType: SignatureType.Illegal,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            return expect(testLib.getSignerOfHash(hash, sig).callAsync()).to.revertWith(
 | 
				
			||||||
 | 
					                new SignatureValidationError(SignatureValidationErrorCodes.Illegal, hash),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it('throws if the type is Invalid', async () => {
 | 
				
			||||||
 | 
					            const hash = hexUtils.random();
 | 
				
			||||||
 | 
					            const sig = {
 | 
				
			||||||
 | 
					                ...ethSignHashWithKey(hash, signerKey),
 | 
				
			||||||
 | 
					                signatureType: SignatureType.Invalid,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            return expect(testLib.getSignerOfHash(hash, sig).callAsync()).to.revertWith(
 | 
				
			||||||
 | 
					                new SignatureValidationError(SignatureValidationErrorCodes.AlwaysInvalid, hash),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -49,6 +49,7 @@ export * from '../test/generated-wrappers/lib_ownable_storage';
 | 
				
			|||||||
export * from '../test/generated-wrappers/lib_proxy_rich_errors';
 | 
					export * from '../test/generated-wrappers/lib_proxy_rich_errors';
 | 
				
			||||||
export * from '../test/generated-wrappers/lib_proxy_storage';
 | 
					export * from '../test/generated-wrappers/lib_proxy_storage';
 | 
				
			||||||
export * from '../test/generated-wrappers/lib_reentrancy_guard_storage';
 | 
					export * from '../test/generated-wrappers/lib_reentrancy_guard_storage';
 | 
				
			||||||
 | 
					export * from '../test/generated-wrappers/lib_signature';
 | 
				
			||||||
export * from '../test/generated-wrappers/lib_signature_rich_errors';
 | 
					export * from '../test/generated-wrappers/lib_signature_rich_errors';
 | 
				
			||||||
export * from '../test/generated-wrappers/lib_signed_call_data';
 | 
					export * from '../test/generated-wrappers/lib_signed_call_data';
 | 
				
			||||||
export * from '../test/generated-wrappers/lib_simple_function_registry_rich_errors';
 | 
					export * from '../test/generated-wrappers/lib_simple_function_registry_rich_errors';
 | 
				
			||||||
@@ -88,6 +89,7 @@ export * from '../test/generated-wrappers/test_fill_quote_transformer_exchange';
 | 
				
			|||||||
export * from '../test/generated-wrappers/test_fill_quote_transformer_host';
 | 
					export * from '../test/generated-wrappers/test_fill_quote_transformer_host';
 | 
				
			||||||
export * from '../test/generated-wrappers/test_full_migration';
 | 
					export * from '../test/generated-wrappers/test_full_migration';
 | 
				
			||||||
export * from '../test/generated-wrappers/test_initial_migration';
 | 
					export * from '../test/generated-wrappers/test_initial_migration';
 | 
				
			||||||
 | 
					export * from '../test/generated-wrappers/test_lib_signature';
 | 
				
			||||||
export * from '../test/generated-wrappers/test_lib_token_spender';
 | 
					export * from '../test/generated-wrappers/test_lib_token_spender';
 | 
				
			||||||
export * from '../test/generated-wrappers/test_meta_transactions_transform_erc20_feature';
 | 
					export * from '../test/generated-wrappers/test_meta_transactions_transform_erc20_feature';
 | 
				
			||||||
export * from '../test/generated-wrappers/test_migrator';
 | 
					export * from '../test/generated-wrappers/test_migrator';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,6 +73,7 @@
 | 
				
			|||||||
        "test/generated-artifacts/LibProxyRichErrors.json",
 | 
					        "test/generated-artifacts/LibProxyRichErrors.json",
 | 
				
			||||||
        "test/generated-artifacts/LibProxyStorage.json",
 | 
					        "test/generated-artifacts/LibProxyStorage.json",
 | 
				
			||||||
        "test/generated-artifacts/LibReentrancyGuardStorage.json",
 | 
					        "test/generated-artifacts/LibReentrancyGuardStorage.json",
 | 
				
			||||||
 | 
					        "test/generated-artifacts/LibSignature.json",
 | 
				
			||||||
        "test/generated-artifacts/LibSignatureRichErrors.json",
 | 
					        "test/generated-artifacts/LibSignatureRichErrors.json",
 | 
				
			||||||
        "test/generated-artifacts/LibSignedCallData.json",
 | 
					        "test/generated-artifacts/LibSignedCallData.json",
 | 
				
			||||||
        "test/generated-artifacts/LibSimpleFunctionRegistryRichErrors.json",
 | 
					        "test/generated-artifacts/LibSimpleFunctionRegistryRichErrors.json",
 | 
				
			||||||
@@ -112,6 +113,7 @@
 | 
				
			|||||||
        "test/generated-artifacts/TestFillQuoteTransformerHost.json",
 | 
					        "test/generated-artifacts/TestFillQuoteTransformerHost.json",
 | 
				
			||||||
        "test/generated-artifacts/TestFullMigration.json",
 | 
					        "test/generated-artifacts/TestFullMigration.json",
 | 
				
			||||||
        "test/generated-artifacts/TestInitialMigration.json",
 | 
					        "test/generated-artifacts/TestInitialMigration.json",
 | 
				
			||||||
 | 
					        "test/generated-artifacts/TestLibSignature.json",
 | 
				
			||||||
        "test/generated-artifacts/TestLibTokenSpender.json",
 | 
					        "test/generated-artifacts/TestLibTokenSpender.json",
 | 
				
			||||||
        "test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json",
 | 
					        "test/generated-artifacts/TestMetaTransactionsTransformERC20Feature.json",
 | 
				
			||||||
        "test/generated-artifacts/TestMigrator.json",
 | 
					        "test/generated-artifacts/TestMigrator.json",
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user