diff --git a/contracts/exchange/compiler.json b/contracts/exchange/compiler.json index 6279dab760..e76c32ca47 100644 --- a/contracts/exchange/compiler.json +++ b/contracts/exchange/compiler.json @@ -39,10 +39,10 @@ "src/interfaces/IValidator.sol", "src/interfaces/IWallet.sol", "src/interfaces/IWrapperFunctions.sol", - "src/libs/LibExchangeRichErrorDecoder.sol", "test/ReentrantERC20Token.sol", "test/TestAssetProxyDispatcher.sol", "test/TestExchangeInternals.sol", + "test/TestLibExchangeRichErrorDecoder.sol", "test/TestRevertReceiver.sol", "test/TestSignatureValidator.sol", "test/TestStaticCallReceiver.sol" diff --git a/contracts/exchange/contracts/src/libs/LibExchangeRichErrorDecoder.sol b/contracts/exchange/contracts/src/libs/LibExchangeRichErrorDecoder.sol index 3adcca2b8e..63c0966cfb 100644 --- a/contracts/exchange/contracts/src/libs/LibExchangeRichErrorDecoder.sol +++ b/contracts/exchange/contracts/src/libs/LibExchangeRichErrorDecoder.sol @@ -25,26 +25,12 @@ import "../mixins/MExchangeRichErrorTypes.sol"; contract LibExchangeRichErrorDecoder is MExchangeRichErrorTypes { - /// @dev Decompose an ABI-encoded StandardError. - /// This is the standard, string revert() error. - /// @param encoded ABI-encoded revert error. - /// @param encoded ABI-encoded revert error. - /// @return message The error message. - function decomposeStandardError(bytes memory encoded) - public - pure - returns (string memory message) - { - _assertSelectorBytes(encoded, STANDARD_ERROR_SELECTOR); - message = _readErrorParameterAsString(encoded, 0); - } - /// @dev Decompose an ABI-encoded SignatureError. /// @param encoded ABI-encoded revert error. /// @return errorCode The error code. /// @return signer The expected signer of the hash. /// @return signature The full signature. - function decomposeSignatureError(bytes memory encoded) + function decodeSignatureError(bytes memory encoded) public pure returns ( @@ -63,15 +49,13 @@ contract LibExchangeRichErrorDecoder is /// @dev Decompose an ABI-encoded SignatureValidatorError. /// @param encoded ABI-encoded revert error. - /// @return errorCode The error code. /// @return signer The expected signer of the hash. /// @return signature The full signature bytes. /// @return errorData The revert data thrown by the validator contract. - function decomposeSignatureValidatorError(bytes memory encoded) + function decodeSignatureValidatorError(bytes memory encoded) public pure returns ( - SignatureErrorCodes errorCode, bytes32 hash, address signer, bytes memory signature, @@ -79,11 +63,10 @@ contract LibExchangeRichErrorDecoder is ) { _assertSelectorBytes(encoded, SIGNATURE_VALIDATOR_ERROR_SELECTOR); - errorCode = SignatureErrorCodes(_readErrorParameterAsUint256(encoded, 0)); - hash = _readErrorParameterAsBytes32(encoded, 1); - signer = _readErrorParameterAsAddress(encoded, 2); - signature = _readErrorParameterAsBytes(encoded, 3); - errorData = _readErrorParameterAsBytes(encoded, 4); + hash = _readErrorParameterAsBytes32(encoded, 0); + signer = _readErrorParameterAsAddress(encoded, 1); + signature = _readErrorParameterAsBytes(encoded, 2); + errorData = _readErrorParameterAsBytes(encoded, 3); } /// @dev Decompose an ABI-encoded SignatureWalletError. @@ -92,11 +75,10 @@ contract LibExchangeRichErrorDecoder is /// @return signer The expected signer of the hash. /// @return signature The full signature bytes. /// @return errorData The revert data thrown by the validator contract. - function decomposeSignatureWalletError(bytes memory encoded) + function decodeSignatureWalletError(bytes memory encoded) public pure returns ( - SignatureErrorCodes errorCode, bytes32 hash, address signer, bytes memory signature, @@ -104,11 +86,10 @@ contract LibExchangeRichErrorDecoder is ) { _assertSelectorBytes(encoded, SIGNATURE_WALLET_ERROR_SELECTOR); - errorCode = SignatureErrorCodes(_readErrorParameterAsUint256(encoded, 0)); - hash = _readErrorParameterAsBytes32(encoded, 1); - signer = _readErrorParameterAsAddress(encoded, 2); - signature = _readErrorParameterAsBytes(encoded, 3); - errorData = _readErrorParameterAsBytes(encoded, 4); + hash = _readErrorParameterAsBytes32(encoded, 0); + signer = _readErrorParameterAsAddress(encoded, 1); + signature = _readErrorParameterAsBytes(encoded, 2); + errorData = _readErrorParameterAsBytes(encoded, 3); } /// @dev Decompose an ABI-encoded SignatureOrderValidatorError. @@ -117,11 +98,10 @@ contract LibExchangeRichErrorDecoder is /// @return signer The expected signer of the hash. /// @return signature The full signature bytes. /// @return errorData The revert data thrown by the validator contract. - function decomposeSignatureOrderValidatorError(bytes memory encoded) + function decodeSignatureOrderValidatorError(bytes memory encoded) public pure returns ( - SignatureErrorCodes errorCode, bytes32 hash, address signer, bytes memory signature, @@ -129,11 +109,10 @@ contract LibExchangeRichErrorDecoder is ) { _assertSelectorBytes(encoded, SIGNATURE_ORDER_VALIDATOR_ERROR_SELECTOR); - errorCode = SignatureErrorCodes(_readErrorParameterAsUint256(encoded, 0)); - hash = _readErrorParameterAsBytes32(encoded, 1); - signer = _readErrorParameterAsAddress(encoded, 2); - signature = _readErrorParameterAsBytes(encoded, 3); - errorData = _readErrorParameterAsBytes(encoded, 4); + hash = _readErrorParameterAsBytes32(encoded, 0); + signer = _readErrorParameterAsAddress(encoded, 1); + signature = _readErrorParameterAsBytes(encoded, 2); + errorData = _readErrorParameterAsBytes(encoded, 3); } /// @dev Decompose an ABI-encoded SignatureWalletOrderValidatorError. @@ -142,11 +121,10 @@ contract LibExchangeRichErrorDecoder is /// @return signer The expected signer of the hash. /// @return signature The full signature bytes. /// @return errorData The revert data thrown by the validator contract. - function decomposeSignatureWalletOrderValidatorError(bytes memory encoded) + function decodeSignatureWalletOrderValidatorError(bytes memory encoded) public pure returns ( - SignatureErrorCodes errorCode, bytes32 hash, address signer, bytes memory signature, @@ -154,18 +132,17 @@ contract LibExchangeRichErrorDecoder is ) { _assertSelectorBytes(encoded, SIGNATURE_WALLET_ORDER_VALIDATOR_ERROR_SELECTOR); - errorCode = SignatureErrorCodes(_readErrorParameterAsUint256(encoded, 0)); - hash = _readErrorParameterAsBytes32(encoded, 1); - signer = _readErrorParameterAsAddress(encoded, 2); - signature = _readErrorParameterAsBytes(encoded, 3); - errorData = _readErrorParameterAsBytes(encoded, 4); + hash = _readErrorParameterAsBytes32(encoded, 0); + signer = _readErrorParameterAsAddress(encoded, 1); + signature = _readErrorParameterAsBytes(encoded, 2); + errorData = _readErrorParameterAsBytes(encoded, 3); } /// @dev Decompose an ABI-encoded OrderStatusError. /// @param encoded ABI-encoded revert error. /// @return orderHash The order hash. /// @return orderStatus The order status. - function decomposeOrderStatusError(bytes memory encoded) + function decodeOrderStatusError(bytes memory encoded) public pure returns ( @@ -181,8 +158,8 @@ contract LibExchangeRichErrorDecoder is /// @dev Decompose an ABI-encoded InvalidSenderError. /// @param encoded ABI-encoded revert error. /// @return orderHash The order hash. - /// @return sender The sender of the order. - function decomposeInvalidSenderError(bytes memory encoded) + /// @return sender The sender. + function decodeInvalidSenderError(bytes memory encoded) public pure returns ( @@ -199,7 +176,7 @@ contract LibExchangeRichErrorDecoder is /// @param encoded ABI-encoded revert error. /// @return orderHash The order hash. /// @return maker The maker of the order. - function decomposeInvalidMakerError(bytes memory encoded) + function decodeInvalidMakerError(bytes memory encoded) public pure returns ( @@ -207,16 +184,33 @@ contract LibExchangeRichErrorDecoder is address maker ) { - _assertSelectorBytes(encoded, INVALID_SENDER_ERROR_SELECTOR); + _assertSelectorBytes(encoded, INVALID_MAKER_ERROR_SELECTOR); orderHash = _readErrorParameterAsBytes32(encoded, 0); maker = _readErrorParameterAsAddress(encoded, 1); } + /// @dev Decompose an ABI-encoded InvalidTaker. + /// @param encoded ABI-encoded revert error. + /// @return orderHash The order hash. + /// @return taker The taker of the order. + function decodeInvalidTakerError(bytes memory encoded) + public + pure + returns ( + bytes32 orderHash, + address taker + ) + { + _assertSelectorBytes(encoded, INVALID_TAKER_ERROR_SELECTOR); + orderHash = _readErrorParameterAsBytes32(encoded, 0); + taker = _readErrorParameterAsAddress(encoded, 1); + } + /// @dev Decompose an ABI-encoded FillError. /// @param encoded ABI-encoded revert error. /// @return errorCode The error code. /// @return orderHash The order hash. - function decomposeFillError(bytes memory encoded) + function decodeFillError(bytes memory encoded) public pure returns ( @@ -229,6 +223,165 @@ contract LibExchangeRichErrorDecoder is orderHash = _readErrorParameterAsBytes32(encoded, 0); } + /// @dev Decompose an ABI-encoded OrderEpochError. + /// @param encoded ABI-encoded revert error. + /// @return maker The order maker. + /// @return sender The sender. + /// @return currentEpoch The current epoch for the maker. + function decodeOrderEpochError(bytes memory encoded) + public + pure + returns ( + address maker, + address sender, + uint256 currentEpoch + ) + { + _assertSelectorBytes(encoded, ORDER_EPOCH_ERROR_SELECTOR); + maker = _readErrorParameterAsAddress(encoded, 0); + sender = _readErrorParameterAsAddress(encoded, 1); + currentEpoch = _readErrorParameterAsUint256(encoded, 2); + } + + /// @dev Decompose an ABI-encoded AssetProxyExistsError. + /// @param encoded ABI-encoded revert error. + /// @return proxyAddress The address of the asset proxy. + function decodeAssetProxyExistsError(bytes memory encoded) + public + pure + returns ( + address assetProxyAddress + ) + { + _assertSelectorBytes(encoded, ASSET_PROXY_EXISTS_ERROR_SELECTOR); + assetProxyAddress = _readErrorParameterAsAddress(encoded, 0); + } + + /// @dev Decompose an ABI-encoded AssetProxyDispatchError. + /// @param encoded ABI-encoded revert error. + /// @return errorCode The error code. + /// @return orderHash Hash of the order being dispatched. + /// @return assetData Asset data of the order being dispatched. + function decodeAssetProxyDispatchError(bytes memory encoded) + public + pure + returns ( + AssetProxyDispatchErrorCodes errorCode, + bytes32 orderHash, + bytes memory assetData + ) + { + _assertSelectorBytes(encoded, ASSET_PROXY_DISPATCH_ERROR_SELECTOR); + errorCode = AssetProxyDispatchErrorCodes(_readErrorParameterAsUint256(encoded, 0)); + orderHash = _readErrorParameterAsBytes32(encoded, 1); + assetData = _readErrorParameterAsBytes(encoded, 2); + } + + /// @dev Decompose an ABI-encoded AssetProxyTransferError. + /// @param encoded ABI-encoded revert error. + /// @return orderHash Hash of the order being dispatched. + /// @return assetData Asset data of the order being dispatched. + /// @return errorData ABI-encoded revert data from the asset proxy. + function decodeAssetProxyTransferError(bytes memory encoded) + public + pure + returns ( + bytes32 orderHash, + bytes memory assetData, + bytes memory errorData + ) + { + _assertSelectorBytes(encoded, ASSET_PROXY_TRANSFER_ERROR_SELECTOR); + orderHash = _readErrorParameterAsBytes32(encoded, 0); + assetData = _readErrorParameterAsBytes(encoded, 1); + errorData = _readErrorParameterAsBytes(encoded, 2); + } + + /// @dev Decompose an ABI-encoded NegativeSpreadError. + /// @param encoded ABI-encoded revert error. + /// @return leftOrderHash Hash of the left order being matched. + /// @return rightOrderHash Hash of the right order being matched. + function decodeNegativeSpreadError(bytes memory encoded) + public + pure + returns ( + bytes32 leftOrderHash, + bytes32 rightOrderHash + ) + { + _assertSelectorBytes(encoded, NEGATIVE_SPREAD_ERROR_SELECTOR); + leftOrderHash = _readErrorParameterAsBytes32(encoded, 0); + rightOrderHash = _readErrorParameterAsBytes32(encoded, 1); + } + + /// @dev Decompose an ABI-encoded TransactionError. + /// @param encoded ABI-encoded revert error. + /// @return errorCode The error code. + /// @return transactionHash Hash of the transaction. + function decodeTransactionError(bytes memory encoded) + public + pure + returns ( + TransactionErrorCodes errorCode, + bytes32 transactionHash + ) + { + _assertSelectorBytes(encoded, TRANSACTION_ERROR_SELECTOR); + errorCode = TransactionErrorCodes(_readErrorParameterAsUint256(encoded, 0)); + transactionHash = _readErrorParameterAsBytes32(encoded, 1); + } + + /// @dev Decompose an ABI-encoded TransactionSignatureError. + /// @param encoded ABI-encoded revert error. + /// @return transactionHash Hash of the transaction. + /// @return signer Signer of the transaction. + /// @return signature Full signature for the transaction. + function decodeTransactionSignatureError(bytes memory encoded) + public + pure + returns ( + bytes32 transactionHash, + address signer, + bytes memory signature + ) + { + _assertSelectorBytes(encoded, TRANSACTION_SIGNATURE_ERROR_SELECTOR); + transactionHash = _readErrorParameterAsBytes32(encoded, 0); + signer = _readErrorParameterAsAddress(encoded, 1); + signature = _readErrorParameterAsBytes(encoded, 2); + } + + /// @dev Decompose an ABI-encoded TransactionExecutionError. + /// @param encoded ABI-encoded revert error. + /// @return transactionHash Hash of the transaction. + /// @return errorData Error thrown by exeucteTransaction(). + function decodeTransactionExecutionError(bytes memory encoded) + public + pure + returns ( + bytes32 transactionHash, + bytes memory errorData + ) + { + _assertSelectorBytes(encoded, TRANSACTION_EXECUTION_ERROR_SELECTOR); + transactionHash = _readErrorParameterAsBytes32(encoded, 0); + errorData = _readErrorParameterAsBytes(encoded, 1); + } + + /// @dev Decompose an ABI-encoded IncompleteFillError. + /// @param encoded ABI-encoded revert error. + /// @return orderHash Hash of the order being filled. + function decodeIncompleteFillError(bytes memory encoded) + public + pure + returns ( + bytes32 orderHash + ) + { + _assertSelectorBytes(encoded, INCOMPLETE_FILL_ERROR_SELECTOR); + orderHash = _readErrorParameterAsBytes32(encoded, 0); + } + /// @dev Revert if the leading 4 bytes of `encoded` is not `selector`. function _assertSelectorBytes(bytes memory encoded, bytes4 selector) private @@ -237,7 +390,7 @@ contract LibExchangeRichErrorDecoder is bytes4 actualSelector = LibBytes.readBytes4(encoded, 0); require( actualSelector == selector, - "INVALID_SELECTOR" + "BAD_SELECTOR" ); } diff --git a/contracts/exchange/contracts/test/TestLibExchangeRichErrorDecoder.sol b/contracts/exchange/contracts/test/TestLibExchangeRichErrorDecoder.sol new file mode 100644 index 0000000000..bbc833978f --- /dev/null +++ b/contracts/exchange/contracts/test/TestLibExchangeRichErrorDecoder.sol @@ -0,0 +1,27 @@ +/* + + Copyright 2018 ZeroEx Intl. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +pragma solidity ^0.5.5; + +import "../src/libs/LibExchangeRichErrorDecoder.sol"; + + +// solhint-disable no-empty-blocks +contract TestLibExchangeRichErrorDecoder is + LibExchangeRichErrorDecoder +{} diff --git a/contracts/exchange/package.json b/contracts/exchange/package.json index 79507d5d93..ab97dc542d 100644 --- a/contracts/exchange/package.json +++ b/contracts/exchange/package.json @@ -34,7 +34,7 @@ "lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol" }, "config": { - "abis": "./generated-artifacts/@(Exchange|ExchangeWrapper|IAssetProxyDispatcher|IExchange|IExchangeCore|IMatchOrders|IOrderValidator|ISignatureValidator|ITransactions|IValidator|IWallet|IWrapperFunctions|ReentrantERC20Token|TestAssetProxyDispatcher|TestExchangeInternals|TestRevertReceiver|TestSignatureValidator|TestStaticCallReceiver|Validator|Wallet|Whitelist).json", + "abis": "./generated-artifacts/@(Exchange|ExchangeWrapper|IAssetProxyDispatcher|IExchange|IExchangeCore|IMatchOrders|IOrderValidator|ISignatureValidator|ITransactions|IValidator|IWallet|IWrapperFunctions|ReentrantERC20Token|TestAssetProxyDispatcher|TestExchangeInternals|TestLibExchangeRichErrorDecoder|TestRevertReceiver|TestSignatureValidator|TestStaticCallReceiver|Validator|Wallet|Whitelist).json", "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually." }, "repository": { diff --git a/contracts/exchange/src/artifacts.ts b/contracts/exchange/src/artifacts.ts index e5d67af895..762aa10e34 100644 --- a/contracts/exchange/src/artifacts.ts +++ b/contracts/exchange/src/artifacts.ts @@ -20,6 +20,7 @@ import * as IWrapperFunctions from '../generated-artifacts/IWrapperFunctions.jso import * as ReentrantERC20Token from '../generated-artifacts/ReentrantERC20Token.json'; import * as TestAssetProxyDispatcher from '../generated-artifacts/TestAssetProxyDispatcher.json'; import * as TestExchangeInternals from '../generated-artifacts/TestExchangeInternals.json'; +import * as TestLibExchangeRichErrorDecoder from '../generated-artifacts/TestLibExchangeRichErrorDecoder.json'; import * as TestRevertReceiver from '../generated-artifacts/TestRevertReceiver.json'; import * as TestSignatureValidator from '../generated-artifacts/TestSignatureValidator.json'; import * as TestStaticCallReceiver from '../generated-artifacts/TestStaticCallReceiver.json'; @@ -48,4 +49,5 @@ export const artifacts = { TestRevertReceiver: TestRevertReceiver as ContractArtifact, TestSignatureValidator: TestSignatureValidator as ContractArtifact, TestStaticCallReceiver: TestStaticCallReceiver as ContractArtifact, + TestLibExchangeRichErrorDecoder: TestLibExchangeRichErrorDecoder as ContractArtifact, }; diff --git a/contracts/exchange/src/wrappers.ts b/contracts/exchange/src/wrappers.ts index 0c97d94931..e53b656240 100644 --- a/contracts/exchange/src/wrappers.ts +++ b/contracts/exchange/src/wrappers.ts @@ -18,6 +18,7 @@ export * from '../generated-wrappers/i_wrapper_functions'; export * from '../generated-wrappers/reentrant_erc20_token'; export * from '../generated-wrappers/test_asset_proxy_dispatcher'; export * from '../generated-wrappers/test_exchange_internals'; +export * from '../generated-wrappers/test_lib_exchange_rich_error_decoder'; export * from '../generated-wrappers/test_revert_receiver'; export * from '../generated-wrappers/test_signature_validator'; export * from '../generated-wrappers/test_static_call_receiver'; diff --git a/contracts/exchange/test/core.ts b/contracts/exchange/test/core.ts index 7917759310..820a31de86 100644 --- a/contracts/exchange/test/core.ts +++ b/contracts/exchange/test/core.ts @@ -220,8 +220,6 @@ describe('Exchange core', () => { }; const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)]; orderFactory = new OrderFactory(privateKey, defaultOrderParams); - - // Grant the reentrant ERC20 token a }); beforeEach(async () => { await blockchainLifecycle.startAsync(); diff --git a/contracts/exchange/test/lib_exchange_rich_error_decoder.ts b/contracts/exchange/test/lib_exchange_rich_error_decoder.ts new file mode 100644 index 0000000000..063590544c --- /dev/null +++ b/contracts/exchange/test/lib_exchange_rich_error_decoder.ts @@ -0,0 +1,127 @@ +import { + addressUtils, + chaiSetup, + OrderStatus, + orderUtils, + provider, + txDefaults, + web3Wrapper, +} from '@0x/contracts-test-utils'; +import { BlockchainLifecycle } from '@0x/dev-utils'; +import { assetDataUtils, ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils'; +import { RevertError } from '@0x/utils'; +import * as chai from 'chai'; +import * as crypto from 'crypto'; +import * as _ from 'lodash'; + +import { + artifacts, + TestLibExchangeRichErrorDecoderContract, +} from '../src'; + +chaiSetup.configure(); +const expect = chai.expect; +const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); + +describe.only('LibExchangeRichErrorDecoder', () => { + let decoder: TestLibExchangeRichErrorDecoderContract; + + before(async () => { + await blockchainLifecycle.startAsync(); + }); + after(async () => { + await blockchainLifecycle.revertAsync(); + }); + before(async () => { + decoder = await TestLibExchangeRichErrorDecoderContract.deployFrom0xArtifactAsync( + artifacts.TestLibExchangeRichErrorDecoder, + provider, + txDefaults, + ); + }); + + function generateRandomBytes(length: number) { + const bytes = crypto.randomBytes(length).toString('hex'); + return `0x${bytes}`; + } + + function createDecodeTest( + revertType: new(...args: any[]) => RevertError, + parameters: any[], + ) { + const revert = new revertType(...parameters); + const encoded = revert.encode(); + const endpointName = `decode${revert.name}`; + const callAsync = (encoded: string) => { + return (decoder as any)[endpointName].callAsync.call( + (decoder as any)[endpointName], + encoded, + ); + }; + describe(`${endpointName}()`, async () => { + it('decodes encoded parameters', async () => { + const results = await callAsync(encoded); + return expect(results).to.deep.equal(parameters); + }); + it('reverts if selector does not match', async () => { + // Replace the selector with null bytes. + const NULL_SELECTOR = '00000000'; + const withBadSelector = `0x${NULL_SELECTOR}${encoded.substr(10)}`; + return expect(callAsync(withBadSelector)).to.revertWith('BAD_SELECTOR'); + }); + }); + }; + + (() => { + const errorCode = ExchangeRevertErrors.SignatureErrorCode.Illegal; + const orderHash = orderUtils.generatePseudoRandomOrderHash(); + const signer = addressUtils.generatePseudoRandomAddress(); + const signature = generateRandomBytes(66); + const errorData = generateRandomBytes(4+32+32+32); + createDecodeTest( + ExchangeRevertErrors.SignatureError, + [ + errorCode, + orderHash, + signer, + signature, + ], + ); + createDecodeTest( + ExchangeRevertErrors.SignatureValidatorError, + [ + orderHash, + signer, + signature, + errorData, + ], + ); + createDecodeTest( + ExchangeRevertErrors.SignatureWalletError, + [ + orderHash, + signer, + signature, + errorData, + ], + ); + createDecodeTest( + ExchangeRevertErrors.SignatureOrderValidatorError, + [ + orderHash, + signer, + signature, + errorData, + ], + ); + createDecodeTest( + ExchangeRevertErrors.SignatureWalletOrderValidatorError, + [ + orderHash, + signer, + signature, + errorData, + ], + ); + })(); +}); diff --git a/contracts/exchange/tsconfig.json b/contracts/exchange/tsconfig.json index 736b507cfb..f33bbe65bd 100644 --- a/contracts/exchange/tsconfig.json +++ b/contracts/exchange/tsconfig.json @@ -18,6 +18,7 @@ "generated-artifacts/ReentrantERC20Token.json", "generated-artifacts/TestAssetProxyDispatcher.json", "generated-artifacts/TestExchangeInternals.json", + "generated-artifacts/TestLibExchangeRichErrorDecoder.json", "generated-artifacts/TestRevertReceiver.json", "generated-artifacts/TestSignatureValidator.json", "generated-artifacts/TestStaticCallReceiver.json",