In @0x/contracts-exchange: Add tests for LibExchangeRichErrorDecoder.

This commit is contained in:
Lawrence Forman 2019-04-23 17:46:47 -04:00 committed by Amir Bandeali
parent a2846faa61
commit fdb6bee65f
9 changed files with 364 additions and 55 deletions

View File

@ -39,10 +39,10 @@
"src/interfaces/IValidator.sol", "src/interfaces/IValidator.sol",
"src/interfaces/IWallet.sol", "src/interfaces/IWallet.sol",
"src/interfaces/IWrapperFunctions.sol", "src/interfaces/IWrapperFunctions.sol",
"src/libs/LibExchangeRichErrorDecoder.sol",
"test/ReentrantERC20Token.sol", "test/ReentrantERC20Token.sol",
"test/TestAssetProxyDispatcher.sol", "test/TestAssetProxyDispatcher.sol",
"test/TestExchangeInternals.sol", "test/TestExchangeInternals.sol",
"test/TestLibExchangeRichErrorDecoder.sol",
"test/TestRevertReceiver.sol", "test/TestRevertReceiver.sol",
"test/TestSignatureValidator.sol", "test/TestSignatureValidator.sol",
"test/TestStaticCallReceiver.sol" "test/TestStaticCallReceiver.sol"

View File

@ -25,26 +25,12 @@ import "../mixins/MExchangeRichErrorTypes.sol";
contract LibExchangeRichErrorDecoder is contract LibExchangeRichErrorDecoder is
MExchangeRichErrorTypes 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. /// @dev Decompose an ABI-encoded SignatureError.
/// @param encoded ABI-encoded revert error. /// @param encoded ABI-encoded revert error.
/// @return errorCode The error code. /// @return errorCode The error code.
/// @return signer The expected signer of the hash. /// @return signer The expected signer of the hash.
/// @return signature The full signature. /// @return signature The full signature.
function decomposeSignatureError(bytes memory encoded) function decodeSignatureError(bytes memory encoded)
public public
pure pure
returns ( returns (
@ -63,15 +49,13 @@ contract LibExchangeRichErrorDecoder is
/// @dev Decompose an ABI-encoded SignatureValidatorError. /// @dev Decompose an ABI-encoded SignatureValidatorError.
/// @param encoded ABI-encoded revert error. /// @param encoded ABI-encoded revert error.
/// @return errorCode The error code.
/// @return signer The expected signer of the hash. /// @return signer The expected signer of the hash.
/// @return signature The full signature bytes. /// @return signature The full signature bytes.
/// @return errorData The revert data thrown by the validator contract. /// @return errorData The revert data thrown by the validator contract.
function decomposeSignatureValidatorError(bytes memory encoded) function decodeSignatureValidatorError(bytes memory encoded)
public public
pure pure
returns ( returns (
SignatureErrorCodes errorCode,
bytes32 hash, bytes32 hash,
address signer, address signer,
bytes memory signature, bytes memory signature,
@ -79,11 +63,10 @@ contract LibExchangeRichErrorDecoder is
) )
{ {
_assertSelectorBytes(encoded, SIGNATURE_VALIDATOR_ERROR_SELECTOR); _assertSelectorBytes(encoded, SIGNATURE_VALIDATOR_ERROR_SELECTOR);
errorCode = SignatureErrorCodes(_readErrorParameterAsUint256(encoded, 0)); hash = _readErrorParameterAsBytes32(encoded, 0);
hash = _readErrorParameterAsBytes32(encoded, 1); signer = _readErrorParameterAsAddress(encoded, 1);
signer = _readErrorParameterAsAddress(encoded, 2); signature = _readErrorParameterAsBytes(encoded, 2);
signature = _readErrorParameterAsBytes(encoded, 3); errorData = _readErrorParameterAsBytes(encoded, 3);
errorData = _readErrorParameterAsBytes(encoded, 4);
} }
/// @dev Decompose an ABI-encoded SignatureWalletError. /// @dev Decompose an ABI-encoded SignatureWalletError.
@ -92,11 +75,10 @@ contract LibExchangeRichErrorDecoder is
/// @return signer The expected signer of the hash. /// @return signer The expected signer of the hash.
/// @return signature The full signature bytes. /// @return signature The full signature bytes.
/// @return errorData The revert data thrown by the validator contract. /// @return errorData The revert data thrown by the validator contract.
function decomposeSignatureWalletError(bytes memory encoded) function decodeSignatureWalletError(bytes memory encoded)
public public
pure pure
returns ( returns (
SignatureErrorCodes errorCode,
bytes32 hash, bytes32 hash,
address signer, address signer,
bytes memory signature, bytes memory signature,
@ -104,11 +86,10 @@ contract LibExchangeRichErrorDecoder is
) )
{ {
_assertSelectorBytes(encoded, SIGNATURE_WALLET_ERROR_SELECTOR); _assertSelectorBytes(encoded, SIGNATURE_WALLET_ERROR_SELECTOR);
errorCode = SignatureErrorCodes(_readErrorParameterAsUint256(encoded, 0)); hash = _readErrorParameterAsBytes32(encoded, 0);
hash = _readErrorParameterAsBytes32(encoded, 1); signer = _readErrorParameterAsAddress(encoded, 1);
signer = _readErrorParameterAsAddress(encoded, 2); signature = _readErrorParameterAsBytes(encoded, 2);
signature = _readErrorParameterAsBytes(encoded, 3); errorData = _readErrorParameterAsBytes(encoded, 3);
errorData = _readErrorParameterAsBytes(encoded, 4);
} }
/// @dev Decompose an ABI-encoded SignatureOrderValidatorError. /// @dev Decompose an ABI-encoded SignatureOrderValidatorError.
@ -117,11 +98,10 @@ contract LibExchangeRichErrorDecoder is
/// @return signer The expected signer of the hash. /// @return signer The expected signer of the hash.
/// @return signature The full signature bytes. /// @return signature The full signature bytes.
/// @return errorData The revert data thrown by the validator contract. /// @return errorData The revert data thrown by the validator contract.
function decomposeSignatureOrderValidatorError(bytes memory encoded) function decodeSignatureOrderValidatorError(bytes memory encoded)
public public
pure pure
returns ( returns (
SignatureErrorCodes errorCode,
bytes32 hash, bytes32 hash,
address signer, address signer,
bytes memory signature, bytes memory signature,
@ -129,11 +109,10 @@ contract LibExchangeRichErrorDecoder is
) )
{ {
_assertSelectorBytes(encoded, SIGNATURE_ORDER_VALIDATOR_ERROR_SELECTOR); _assertSelectorBytes(encoded, SIGNATURE_ORDER_VALIDATOR_ERROR_SELECTOR);
errorCode = SignatureErrorCodes(_readErrorParameterAsUint256(encoded, 0)); hash = _readErrorParameterAsBytes32(encoded, 0);
hash = _readErrorParameterAsBytes32(encoded, 1); signer = _readErrorParameterAsAddress(encoded, 1);
signer = _readErrorParameterAsAddress(encoded, 2); signature = _readErrorParameterAsBytes(encoded, 2);
signature = _readErrorParameterAsBytes(encoded, 3); errorData = _readErrorParameterAsBytes(encoded, 3);
errorData = _readErrorParameterAsBytes(encoded, 4);
} }
/// @dev Decompose an ABI-encoded SignatureWalletOrderValidatorError. /// @dev Decompose an ABI-encoded SignatureWalletOrderValidatorError.
@ -142,11 +121,10 @@ contract LibExchangeRichErrorDecoder is
/// @return signer The expected signer of the hash. /// @return signer The expected signer of the hash.
/// @return signature The full signature bytes. /// @return signature The full signature bytes.
/// @return errorData The revert data thrown by the validator contract. /// @return errorData The revert data thrown by the validator contract.
function decomposeSignatureWalletOrderValidatorError(bytes memory encoded) function decodeSignatureWalletOrderValidatorError(bytes memory encoded)
public public
pure pure
returns ( returns (
SignatureErrorCodes errorCode,
bytes32 hash, bytes32 hash,
address signer, address signer,
bytes memory signature, bytes memory signature,
@ -154,18 +132,17 @@ contract LibExchangeRichErrorDecoder is
) )
{ {
_assertSelectorBytes(encoded, SIGNATURE_WALLET_ORDER_VALIDATOR_ERROR_SELECTOR); _assertSelectorBytes(encoded, SIGNATURE_WALLET_ORDER_VALIDATOR_ERROR_SELECTOR);
errorCode = SignatureErrorCodes(_readErrorParameterAsUint256(encoded, 0)); hash = _readErrorParameterAsBytes32(encoded, 0);
hash = _readErrorParameterAsBytes32(encoded, 1); signer = _readErrorParameterAsAddress(encoded, 1);
signer = _readErrorParameterAsAddress(encoded, 2); signature = _readErrorParameterAsBytes(encoded, 2);
signature = _readErrorParameterAsBytes(encoded, 3); errorData = _readErrorParameterAsBytes(encoded, 3);
errorData = _readErrorParameterAsBytes(encoded, 4);
} }
/// @dev Decompose an ABI-encoded OrderStatusError. /// @dev Decompose an ABI-encoded OrderStatusError.
/// @param encoded ABI-encoded revert error. /// @param encoded ABI-encoded revert error.
/// @return orderHash The order hash. /// @return orderHash The order hash.
/// @return orderStatus The order status. /// @return orderStatus The order status.
function decomposeOrderStatusError(bytes memory encoded) function decodeOrderStatusError(bytes memory encoded)
public public
pure pure
returns ( returns (
@ -181,8 +158,8 @@ contract LibExchangeRichErrorDecoder is
/// @dev Decompose an ABI-encoded InvalidSenderError. /// @dev Decompose an ABI-encoded InvalidSenderError.
/// @param encoded ABI-encoded revert error. /// @param encoded ABI-encoded revert error.
/// @return orderHash The order hash. /// @return orderHash The order hash.
/// @return sender The sender of the order. /// @return sender The sender.
function decomposeInvalidSenderError(bytes memory encoded) function decodeInvalidSenderError(bytes memory encoded)
public public
pure pure
returns ( returns (
@ -199,7 +176,7 @@ contract LibExchangeRichErrorDecoder is
/// @param encoded ABI-encoded revert error. /// @param encoded ABI-encoded revert error.
/// @return orderHash The order hash. /// @return orderHash The order hash.
/// @return maker The maker of the order. /// @return maker The maker of the order.
function decomposeInvalidMakerError(bytes memory encoded) function decodeInvalidMakerError(bytes memory encoded)
public public
pure pure
returns ( returns (
@ -207,16 +184,33 @@ contract LibExchangeRichErrorDecoder is
address maker address maker
) )
{ {
_assertSelectorBytes(encoded, INVALID_SENDER_ERROR_SELECTOR); _assertSelectorBytes(encoded, INVALID_MAKER_ERROR_SELECTOR);
orderHash = _readErrorParameterAsBytes32(encoded, 0); orderHash = _readErrorParameterAsBytes32(encoded, 0);
maker = _readErrorParameterAsAddress(encoded, 1); 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. /// @dev Decompose an ABI-encoded FillError.
/// @param encoded ABI-encoded revert error. /// @param encoded ABI-encoded revert error.
/// @return errorCode The error code. /// @return errorCode The error code.
/// @return orderHash The order hash. /// @return orderHash The order hash.
function decomposeFillError(bytes memory encoded) function decodeFillError(bytes memory encoded)
public public
pure pure
returns ( returns (
@ -229,6 +223,165 @@ contract LibExchangeRichErrorDecoder is
orderHash = _readErrorParameterAsBytes32(encoded, 0); 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`. /// @dev Revert if the leading 4 bytes of `encoded` is not `selector`.
function _assertSelectorBytes(bytes memory encoded, bytes4 selector) function _assertSelectorBytes(bytes memory encoded, bytes4 selector)
private private
@ -237,7 +390,7 @@ contract LibExchangeRichErrorDecoder is
bytes4 actualSelector = LibBytes.readBytes4(encoded, 0); bytes4 actualSelector = LibBytes.readBytes4(encoded, 0);
require( require(
actualSelector == selector, actualSelector == selector,
"INVALID_SELECTOR" "BAD_SELECTOR"
); );
} }

View File

@ -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
{}

View File

@ -34,7 +34,7 @@
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol" "lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol"
}, },
"config": { "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." "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
}, },
"repository": { "repository": {

View File

@ -20,6 +20,7 @@ import * as IWrapperFunctions from '../generated-artifacts/IWrapperFunctions.jso
import * as ReentrantERC20Token from '../generated-artifacts/ReentrantERC20Token.json'; import * as ReentrantERC20Token from '../generated-artifacts/ReentrantERC20Token.json';
import * as TestAssetProxyDispatcher from '../generated-artifacts/TestAssetProxyDispatcher.json'; import * as TestAssetProxyDispatcher from '../generated-artifacts/TestAssetProxyDispatcher.json';
import * as TestExchangeInternals from '../generated-artifacts/TestExchangeInternals.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 TestRevertReceiver from '../generated-artifacts/TestRevertReceiver.json';
import * as TestSignatureValidator from '../generated-artifacts/TestSignatureValidator.json'; import * as TestSignatureValidator from '../generated-artifacts/TestSignatureValidator.json';
import * as TestStaticCallReceiver from '../generated-artifacts/TestStaticCallReceiver.json'; import * as TestStaticCallReceiver from '../generated-artifacts/TestStaticCallReceiver.json';
@ -48,4 +49,5 @@ export const artifacts = {
TestRevertReceiver: TestRevertReceiver as ContractArtifact, TestRevertReceiver: TestRevertReceiver as ContractArtifact,
TestSignatureValidator: TestSignatureValidator as ContractArtifact, TestSignatureValidator: TestSignatureValidator as ContractArtifact,
TestStaticCallReceiver: TestStaticCallReceiver as ContractArtifact, TestStaticCallReceiver: TestStaticCallReceiver as ContractArtifact,
TestLibExchangeRichErrorDecoder: TestLibExchangeRichErrorDecoder as ContractArtifact,
}; };

View File

@ -18,6 +18,7 @@ export * from '../generated-wrappers/i_wrapper_functions';
export * from '../generated-wrappers/reentrant_erc20_token'; export * from '../generated-wrappers/reentrant_erc20_token';
export * from '../generated-wrappers/test_asset_proxy_dispatcher'; export * from '../generated-wrappers/test_asset_proxy_dispatcher';
export * from '../generated-wrappers/test_exchange_internals'; 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_revert_receiver';
export * from '../generated-wrappers/test_signature_validator'; export * from '../generated-wrappers/test_signature_validator';
export * from '../generated-wrappers/test_static_call_receiver'; export * from '../generated-wrappers/test_static_call_receiver';

View File

@ -220,8 +220,6 @@ describe('Exchange core', () => {
}; };
const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)]; const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
orderFactory = new OrderFactory(privateKey, defaultOrderParams); orderFactory = new OrderFactory(privateKey, defaultOrderParams);
// Grant the reentrant ERC20 token a
}); });
beforeEach(async () => { beforeEach(async () => {
await blockchainLifecycle.startAsync(); await blockchainLifecycle.startAsync();

View File

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

View File

@ -18,6 +18,7 @@
"generated-artifacts/ReentrantERC20Token.json", "generated-artifacts/ReentrantERC20Token.json",
"generated-artifacts/TestAssetProxyDispatcher.json", "generated-artifacts/TestAssetProxyDispatcher.json",
"generated-artifacts/TestExchangeInternals.json", "generated-artifacts/TestExchangeInternals.json",
"generated-artifacts/TestLibExchangeRichErrorDecoder.json",
"generated-artifacts/TestRevertReceiver.json", "generated-artifacts/TestRevertReceiver.json",
"generated-artifacts/TestSignatureValidator.json", "generated-artifacts/TestSignatureValidator.json",
"generated-artifacts/TestStaticCallReceiver.json", "generated-artifacts/TestStaticCallReceiver.json",