From 72a74e7c66e27da02dd9f4ce604ad057c740c304 Mon Sep 17 00:00:00 2001 From: Lawrence Forman Date: Tue, 12 Jan 2021 13:53:50 -0500 Subject: [PATCH] Panettone cleanup (#109) * `@0x/contracts-zero-ex`: Updates for panettone release * `@0x/contract-addresses`: Update ganache snapshot addresses Co-authored-by: Lawrence Forman --- contracts/zero-ex/CHANGELOG.json | 4 + contracts/zero-ex/contracts/src/IZeroEx.sol | 2 - .../src/features/IMetaTransactionsFeature.sol | 15 - .../features/ISignatureValidatorFeature.sol | 64 ---- .../src/features/MetaTransactionsFeature.sol | 28 -- .../features/SignatureValidatorFeature.sol | 275 ------------------ .../src/features/TransformERC20Feature.sol | 32 -- .../src/migrations/FullMigration.sol | 13 - contracts/zero-ex/package.json | 4 +- contracts/zero-ex/src/migration.ts | 12 - contracts/zero-ex/test/artifacts.ts | 4 - .../test/features/signature_validator_test.ts | 231 --------------- contracts/zero-ex/test/full_migration_test.ts | 13 +- contracts/zero-ex/test/wrappers.ts | 2 - contracts/zero-ex/tsconfig.json | 2 - packages/contract-addresses/CHANGELOG.json | 4 + packages/contract-addresses/addresses.json | 8 +- 17 files changed, 20 insertions(+), 693 deletions(-) delete mode 100644 contracts/zero-ex/contracts/src/features/ISignatureValidatorFeature.sol delete mode 100644 contracts/zero-ex/contracts/src/features/SignatureValidatorFeature.sol delete mode 100644 contracts/zero-ex/test/features/signature_validator_test.ts diff --git a/contracts/zero-ex/CHANGELOG.json b/contracts/zero-ex/CHANGELOG.json index 9289f1ecaa..c8d8b52fa6 100644 --- a/contracts/zero-ex/CHANGELOG.json +++ b/contracts/zero-ex/CHANGELOG.json @@ -5,6 +5,10 @@ { "note": "Use consistent returndatasize checks in UniswapFeature", "pr": 96 + }, + { + "note": "Remove `MetaTransactionsFeature._executeMetaTransaction()` and `SignatureValidatorFeature`", + "pr": 109 } ] }, diff --git a/contracts/zero-ex/contracts/src/IZeroEx.sol b/contracts/zero-ex/contracts/src/IZeroEx.sol index 5107ab611b..b2f3062c70 100644 --- a/contracts/zero-ex/contracts/src/IZeroEx.sol +++ b/contracts/zero-ex/contracts/src/IZeroEx.sol @@ -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, diff --git a/contracts/zero-ex/contracts/src/features/IMetaTransactionsFeature.sol b/contracts/zero-ex/contracts/src/features/IMetaTransactionsFeature.sol index ac96b98f79..8dff7acce1 100644 --- a/contracts/zero-ex/contracts/src/features/IMetaTransactionsFeature.sol +++ b/contracts/zero-ex/contracts/src/features/IMetaTransactionsFeature.sol @@ -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. diff --git a/contracts/zero-ex/contracts/src/features/ISignatureValidatorFeature.sol b/contracts/zero-ex/contracts/src/features/ISignatureValidatorFeature.sol deleted file mode 100644 index 4dd8e75650..0000000000 --- a/contracts/zero-ex/contracts/src/features/ISignatureValidatorFeature.sol +++ /dev/null @@ -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); -} diff --git a/contracts/zero-ex/contracts/src/features/MetaTransactionsFeature.sol b/contracts/zero-ex/contracts/src/features/MetaTransactionsFeature.sol index f42a0b3e06..937b535324 100644 --- a/contracts/zero-ex/contracts/src/features/MetaTransactionsFeature.sol +++ b/contracts/zero-ex/contracts/src/features/MetaTransactionsFeature.sol @@ -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. diff --git a/contracts/zero-ex/contracts/src/features/SignatureValidatorFeature.sol b/contracts/zero-ex/contracts/src/features/SignatureValidatorFeature.sol deleted file mode 100644 index b07044c494..0000000000 --- a/contracts/zero-ex/contracts/src/features/SignatureValidatorFeature.sol +++ /dev/null @@ -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])); - } -} diff --git a/contracts/zero-ex/contracts/src/features/TransformERC20Feature.sol b/contracts/zero-ex/contracts/src/features/TransformERC20Feature.sol index 900f8283fa..05eb3c3f7d 100644 --- a/contracts/zero-ex/contracts/src/features/TransformERC20Feature.sol +++ b/contracts/zero-ex/contracts/src/features/TransformERC20Feature.sol @@ -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; - } - } } diff --git a/contracts/zero-ex/contracts/src/migrations/FullMigration.sol b/contracts/zero-ex/contracts/src/migrations/FullMigration.sol index f0a90932c7..5d8db5c436 100644 --- a/contracts/zero-ex/contracts/src/migrations/FullMigration.sol +++ b/contracts/zero-ex/contracts/src/migrations/FullMigration.sol @@ -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. diff --git a/contracts/zero-ex/package.json b/contracts/zero-ex/package.json index 4849368cda..6fc0c7579d 100644 --- a/contracts/zero-ex/package.json +++ b/contracts/zero-ex/package.json @@ -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", diff --git a/contracts/zero-ex/src/migration.ts b/contracts/zero-ex/src/migration.ts index 6843d89a98..30e73bc19d 100644 --- a/contracts/zero-ex/src/migration.ts +++ b/contracts/zero-ex/src/migration.ts @@ -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( diff --git a/contracts/zero-ex/test/artifacts.ts b/contracts/zero-ex/test/artifacts.ts index 0f1135ee56..fc487e54d1 100644 --- a/contracts/zero-ex/test/artifacts.ts +++ b/contracts/zero-ex/test/artifacts.ts @@ -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, diff --git a/contracts/zero-ex/test/features/signature_validator_test.ts b/contracts/zero-ex/test/features/signature_validator_test.ts deleted file mode 100644 index 2ea0b7e636..0000000000 --- a/contracts/zero-ex/test/features/signature_validator_test.ts +++ /dev/null @@ -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); - }); - }); -}); diff --git a/contracts/zero-ex/test/full_migration_test.ts b/contracts/zero-ex/test/full_migration_test.ts index 0c32bd72b8..2ab5506c73 100644 --- a/contracts/zero-ex/test/full_migration_test.ts +++ b/contracts/zero-ex/test/full_migration_test.ts @@ -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', ], }, }; diff --git a/contracts/zero-ex/test/wrappers.ts b/contracts/zero-ex/test/wrappers.ts index a103fc3cb0..e94809d01f 100644 --- a/contracts/zero-ex/test/wrappers.ts +++ b/contracts/zero-ex/test/wrappers.ts @@ -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'; diff --git a/contracts/zero-ex/tsconfig.json b/contracts/zero-ex/tsconfig.json index cc639c138b..cc51f79b90 100644 --- a/contracts/zero-ex/tsconfig.json +++ b/contracts/zero-ex/tsconfig.json @@ -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", diff --git a/packages/contract-addresses/CHANGELOG.json b/packages/contract-addresses/CHANGELOG.json index 3949102fee..2f7558b6be 100644 --- a/packages/contract-addresses/CHANGELOG.json +++ b/packages/contract-addresses/CHANGELOG.json @@ -5,6 +5,10 @@ { "note": "Redeploy LiquidityProviderSandbox", "pr": 107 + }, + { + "note": "Update ganache snapshot addresses", + "pr": 109 } ] }, diff --git a/packages/contract-addresses/addresses.json b/packages/contract-addresses/addresses.json index 203ab454fc..e84de0ca77 100644 --- a/packages/contract-addresses/addresses.json +++ b/packages/contract-addresses/addresses.json @@ -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" } } }