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:
Lawrence Forman 2021-01-12 13:53:50 -05:00 committed by GitHub
parent e8ae64673f
commit 72a74e7c66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 20 additions and 693 deletions

View File

@ -5,6 +5,10 @@
{
"note": "Use consistent returndatasize checks in UniswapFeature",
"pr": 96
},
{
"note": "Remove `MetaTransactionsFeature._executeMetaTransaction()` and `SignatureValidatorFeature`",
"pr": 109
}
]
},

View File

@ -23,7 +23,6 @@ pragma experimental ABIEncoderV2;
import "./features/IOwnableFeature.sol";
import "./features/ISimpleFunctionRegistryFeature.sol";
import "./features/ITokenSpenderFeature.sol";
import "./features/ISignatureValidatorFeature.sol";
import "./features/ITransformERC20Feature.sol";
import "./features/IMetaTransactionsFeature.sol";
import "./features/IUniswapFeature.sol";
@ -36,7 +35,6 @@ interface IZeroEx is
IOwnableFeature,
ISimpleFunctionRegistryFeature,
ITokenSpenderFeature,
ISignatureValidatorFeature,
ITransformERC20Feature,
IMetaTransactionsFeature,
IUniswapFeature,

View File

@ -86,21 +86,6 @@ interface IMetaTransactionsFeature {
payable
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.
/// @param mtx The meta-transaction.
/// @return blockNumber The block height when the meta-transactioin was executed.

View File

@ -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);
}

View File

@ -33,7 +33,6 @@ import "../storage/LibMetaTransactionsStorage.sol";
import "./IMetaTransactionsFeature.sol";
import "./ITransformERC20Feature.sol";
import "./libs/LibSignature.sol";
import "./ISignatureValidatorFeature.sol";
import "./IFeature.sol";
import "./INativeOrdersFeature.sol";
@ -124,7 +123,6 @@ contract MetaTransactionsFeature is
{
_registerFeatureFunction(this.executeMetaTransaction.selector);
_registerFeatureFunction(this.batchExecuteMetaTransactions.selector);
_registerFeatureFunction(this._executeMetaTransaction.selector);
_registerFeatureFunction(this.getMetaTransactionExecutedBlock.selector);
_registerFeatureFunction(this.getMetaTransactionHashExecutedBlock.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.
/// @param mtx The meta-transaction.
/// @return blockNumber The block height when the meta-transactioin was executed.

View File

@ -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]));
}
}

View File

@ -35,7 +35,6 @@ import "../transformers/IERC20Transformer.sol";
import "../transformers/LibERC20Transformer.sol";
import "./ITransformERC20Feature.sol";
import "./IFeature.sol";
import "./ISignatureValidatorFeature.sol";
/// @dev Feature to composably transform between ERC20 tokens.
@ -374,35 +373,4 @@ contract TransformERC20Feature is
).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;
}
}
}

View File

@ -24,7 +24,6 @@ import "../ZeroEx.sol";
import "../features/IOwnableFeature.sol";
import "../features/TokenSpenderFeature.sol";
import "../features/TransformERC20Feature.sol";
import "../features/SignatureValidatorFeature.sol";
import "../features/MetaTransactionsFeature.sol";
import "../features/NativeOrdersFeature.sol";
import "../external/AllowanceTarget.sol";
@ -42,7 +41,6 @@ contract FullMigration {
OwnableFeature ownable;
TokenSpenderFeature tokenSpender;
TransformERC20Feature transformERC20;
SignatureValidatorFeature signatureValidator;
MetaTransactionsFeature metaTransactions;
NativeOrdersFeature nativeOrders;
}
@ -176,17 +174,6 @@ contract FullMigration {
address(this)
);
}
// SignatureValidatorFeature
{
// Register the feature.
ownable.migrate(
address(features.signatureValidator),
abi.encodeWithSelector(
SignatureValidatorFeature.migrate.selector
),
address(this)
);
}
// MetaTransactionsFeature
{
// Register the feature.

View File

@ -41,9 +41,9 @@
"rollback": "node ./lib/scripts/rollback.js"
},
"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": "./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": {
"type": "git",

View File

@ -14,7 +14,6 @@ import {
MetaTransactionsFeatureContract,
NativeOrdersFeatureContract,
OwnableFeatureContract,
SignatureValidatorFeatureContract,
SimpleFunctionRegistryFeatureContract,
TokenSpenderFeatureContract,
TransformERC20FeatureContract,
@ -111,7 +110,6 @@ export async function initialMigrateAsync(
export interface FullFeatures extends BootstrapFeatures {
tokenSpender: string;
transformERC20: string;
signatureValidator: string;
metaTransactions: string;
nativeOrders: string;
}
@ -122,7 +120,6 @@ export interface FullFeatures extends BootstrapFeatures {
export interface FullFeatureArtifacts extends BootstrapFeatureArtifacts {
tokenSpender: SimpleContractArtifact;
transformERC20: SimpleContractArtifact;
signatureValidator: SimpleContractArtifact;
metaTransactions: SimpleContractArtifact;
nativeOrders: SimpleContractArtifact;
feeCollectorController: SimpleContractArtifact;
@ -158,7 +155,6 @@ const DEFAULT_FULL_FEATURES_DEPLOY_CONFIG = {
const DEFAULT_FULL_FEATURES_ARTIFACTS = {
tokenSpender: artifacts.TokenSpenderFeature,
transformERC20: artifacts.TransformERC20Feature,
signatureValidator: artifacts.SignatureValidatorFeature,
metaTransactions: artifacts.MetaTransactionsFeature,
nativeOrders: artifacts.NativeOrdersFeature,
feeCollectorController: artifacts.FeeCollectorController,
@ -208,14 +204,6 @@ export async function deployFullFeaturesAsync(
artifacts,
_config.greedyTokensBloomFilter,
)).address,
signatureValidator:
features.signatureValidator ||
(await SignatureValidatorFeatureContract.deployFrom0xArtifactAsync(
_featureArtifacts.signatureValidator,
provider,
txDefaults,
artifacts,
)).address,
metaTransactions:
features.metaTransactions ||
(await MetaTransactionsFeatureContract.deployFrom0xArtifactAsync(

View File

@ -35,7 +35,6 @@ import * as IMetaTransactionsFeature from '../test/generated-artifacts/IMetaTran
import * as INativeOrdersFeature from '../test/generated-artifacts/INativeOrdersFeature.json';
import * as InitialMigration from '../test/generated-artifacts/InitialMigration.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 IStaking from '../test/generated-artifacts/IStaking.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 PayTakerTransformer from '../test/generated-artifacts/PayTakerTransformer.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 TestBridge from '../test/generated-artifacts/TestBridge.json';
import * as TestCallTarget from '../test/generated-artifacts/TestCallTarget.json';
@ -172,7 +170,6 @@ export const artifacts = {
IMetaTransactionsFeature: IMetaTransactionsFeature as ContractArtifact,
INativeOrdersFeature: INativeOrdersFeature as ContractArtifact,
IOwnableFeature: IOwnableFeature as ContractArtifact,
ISignatureValidatorFeature: ISignatureValidatorFeature as ContractArtifact,
ISimpleFunctionRegistryFeature: ISimpleFunctionRegistryFeature as ContractArtifact,
ITokenSpenderFeature: ITokenSpenderFeature as ContractArtifact,
ITransformERC20Feature: ITransformERC20Feature as ContractArtifact,
@ -181,7 +178,6 @@ export const artifacts = {
MetaTransactionsFeature: MetaTransactionsFeature as ContractArtifact,
NativeOrdersFeature: NativeOrdersFeature as ContractArtifact,
OwnableFeature: OwnableFeature as ContractArtifact,
SignatureValidatorFeature: SignatureValidatorFeature as ContractArtifact,
SimpleFunctionRegistryFeature: SimpleFunctionRegistryFeature as ContractArtifact,
TokenSpenderFeature: TokenSpenderFeature as ContractArtifact,
TransformERC20Feature: TransformERC20Feature as ContractArtifact,

View File

@ -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);
});
});
});

View File

@ -12,7 +12,6 @@ import {
IMetaTransactionsFeatureContract,
INativeOrdersFeatureContract,
IOwnableFeatureContract,
ISignatureValidatorFeatureContract,
ITokenSpenderFeatureContract,
ITransformERC20FeatureContract,
TestFullMigrationContract,
@ -86,22 +85,17 @@ blockchainTests.resets('Full migration', env => {
'setQuoteSigner',
],
},
SignatureValidator: {
contractType: ISignatureValidatorFeatureContract,
fns: ['isValidHashSignature', 'validateHashSignature'],
},
MetaTransactions: {
contractType: IMetaTransactionsFeatureContract,
fns: [
'executeMetaTransaction',
'batchExecuteMetaTransactions',
'_executeMetaTransaction',
'getMetaTransactionExecutedBlock',
'getMetaTransactionHashExecutedBlock',
'getMetaTransactionHash',
],
},
LimitOrdersFeature: {
NativeOrdersFeature: {
contractType: INativeOrdersFeatureContract,
fns: [
'transferProtocolFeesForPools',
@ -124,6 +118,11 @@ blockchainTests.resets('Full migration', env => {
'getLimitOrderHash',
'getRfqOrderHash',
'getProtocolFeeMultiplier',
'registerAllowedRfqOrigins',
'getLimitOrderRelevantState',
'getRfqOrderRelevantState',
'batchGetLimitOrderRelevantStates',
'batchGetRfqOrderRelevantStates',
],
},
};

View File

@ -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_native_orders_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_staking';
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/pay_taker_transformer';
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/test_bridge';
export * from '../test/generated-wrappers/test_call_target';

View File

@ -61,7 +61,6 @@
"test/generated-artifacts/IMetaTransactionsFeature.json",
"test/generated-artifacts/INativeOrdersFeature.json",
"test/generated-artifacts/IOwnableFeature.json",
"test/generated-artifacts/ISignatureValidatorFeature.json",
"test/generated-artifacts/ISimpleFunctionRegistryFeature.json",
"test/generated-artifacts/IStaking.json",
"test/generated-artifacts/ITestSimpleFunctionRegistryFeature.json",
@ -121,7 +120,6 @@
"test/generated-artifacts/OwnableFeature.json",
"test/generated-artifacts/PayTakerTransformer.json",
"test/generated-artifacts/PermissionlessTransformerDeployer.json",
"test/generated-artifacts/SignatureValidatorFeature.json",
"test/generated-artifacts/SimpleFunctionRegistryFeature.json",
"test/generated-artifacts/TestBridge.json",
"test/generated-artifacts/TestCallTarget.json",

View File

@ -5,6 +5,10 @@
{
"note": "Redeploy LiquidityProviderSandbox",
"pr": 107
},
{
"note": "Update ganache snapshot addresses",
"pr": 109
}
]
},

View File

@ -198,10 +198,10 @@
"exchangeProxyFlashWallet": "0xb9682a8e7920b431f1d412b8510f0077410c8faa",
"exchangeProxyLiquidityProviderSandbox": "0x0000000000000000000000000000000000000000",
"transformers": {
"wethTransformer": "0x3f16ca81691dab9184cb4606c361d73c4fd2510a",
"payTakerTransformer": "0x99356167edba8fbdc36959e3f5d0c43d1ba9c6db",
"affiliateFeeTransformer": "0x45b3a72221e571017c0f0ec42189e11d149d0ace",
"fillQuoteTransformer": "0xdd66c23e07b4d6925b6089b5fe6fc9e62941afe8"
"wethTransformer": "0x7209185959d7227fb77274e1e88151d7c4c368d3",
"payTakerTransformer": "0x3f16ca81691dab9184cb4606c361d73c4fd2510a",
"affiliateFeeTransformer": "0x99356167edba8fbdc36959e3f5d0c43d1ba9c6db",
"fillQuoteTransformer": "0x45b3a72221e571017c0f0ec42189e11d149d0ace"
}
}
}