This repository has been archived by the owner on Jul 9, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 467
/
Copy pathlib_exchange_rich_error_decoder.ts
152 lines (136 loc) · 6.66 KB
/
lib_exchange_rich_error_decoder.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import { blockchainTests, constants, expect, OrderStatus, orderUtils, randomAddress } from '@0x/contracts-test-utils';
import { generatePseudoRandomSalt } from '@0x/order-utils';
import { BigNumber, ExchangeRevertErrors, hexUtils, RevertError } from '@0x/utils';
import * as _ from 'lodash';
import { artifacts } from './artifacts';
import { TestLibExchangeRichErrorDecoderContract } from './wrappers';
blockchainTests.resets('LibExchangeRichErrorDecoder', ({ provider, txDefaults }) => {
const ASSET_PROXY_ID_LENGTH = 4;
const SIGNATURE_LENGTH = 66;
const ASSET_DATA_LENGTH = 36;
const ERROR_DATA_LENGTH = 100;
const { WORD_LENGTH } = constants;
let decoder: TestLibExchangeRichErrorDecoderContract;
before(async () => {
decoder = await TestLibExchangeRichErrorDecoderContract.deployFrom0xArtifactAsync(
artifacts.TestLibExchangeRichErrorDecoder,
provider,
txDefaults,
{},
);
});
function createDecodeTest(revertType: new (...args: any[]) => RevertError, parameters: any[]): void {
const revert = new revertType(...parameters);
const encoded = revert.encode();
// Exploit the fact that `RevertError` types have the same names as their
// Solidity counterparts.
const endpointName = `decode${revert.name}`;
const callAsync = (_encoded: string) => {
const wrapperFunctions = (decoder as any)[endpointName](_encoded);
return wrapperFunctions.callAsync.bind(wrapperFunctions).call((decoder as any)[endpointName]);
};
describe(`${endpointName}()`, async () => {
it('decodes encoded parameters', async () => {
let results = await callAsync(encoded);
if (!_.isArray(results)) {
results = [results];
}
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 = randomAddress();
const validator = randomAddress();
const data = hexUtils.random(ERROR_DATA_LENGTH);
const signature = hexUtils.random(SIGNATURE_LENGTH);
const errorData = hexUtils.random(ERROR_DATA_LENGTH);
createDecodeTest(ExchangeRevertErrors.SignatureError, [errorCode, orderHash, signer, signature]);
createDecodeTest(ExchangeRevertErrors.SignatureValidatorNotApprovedError, [signer, validator]);
createDecodeTest(ExchangeRevertErrors.EIP1271SignatureError, [validator, data, signature, errorData]);
createDecodeTest(ExchangeRevertErrors.SignatureWalletError, [orderHash, signer, signature, errorData]);
})();
(() => {
const orderHash = orderUtils.generatePseudoRandomOrderHash();
const orderStatus = OrderStatus.FullyFilled;
createDecodeTest(ExchangeRevertErrors.OrderStatusError, [orderHash, orderStatus]);
})();
(() => {
const orderHash = orderUtils.generatePseudoRandomOrderHash();
const address = randomAddress();
createDecodeTest(ExchangeRevertErrors.ExchangeInvalidContextError, [
ExchangeRevertErrors.ExchangeContextErrorCodes.InvalidMaker,
orderHash,
address,
]);
createDecodeTest(ExchangeRevertErrors.ExchangeInvalidContextError, [
ExchangeRevertErrors.ExchangeContextErrorCodes.InvalidTaker,
orderHash,
address,
]);
createDecodeTest(ExchangeRevertErrors.ExchangeInvalidContextError, [
ExchangeRevertErrors.ExchangeContextErrorCodes.InvalidSender,
orderHash,
address,
]);
})();
(() => {
const errorCode = ExchangeRevertErrors.FillErrorCode.TakerOverpay;
const orderHash = orderUtils.generatePseudoRandomOrderHash();
createDecodeTest(ExchangeRevertErrors.FillError, [errorCode, orderHash]);
})();
(() => {
const maker = randomAddress();
const sender = randomAddress();
const currentEpoch = generatePseudoRandomSalt();
createDecodeTest(ExchangeRevertErrors.OrderEpochError, [maker, sender, currentEpoch]);
})();
(() => {
const assetProxyAddress = randomAddress();
createDecodeTest(ExchangeRevertErrors.AssetProxyExistsError, [
hexUtils.random(ASSET_PROXY_ID_LENGTH),
assetProxyAddress,
]);
})();
(() => {
const errorCode = ExchangeRevertErrors.AssetProxyDispatchErrorCode.UnknownAssetProxy;
const orderHash = orderUtils.generatePseudoRandomOrderHash();
const assetData = hexUtils.random(ASSET_DATA_LENGTH);
createDecodeTest(ExchangeRevertErrors.AssetProxyDispatchError, [errorCode, orderHash, assetData]);
})();
(() => {
const orderHash = orderUtils.generatePseudoRandomOrderHash();
const assetData = hexUtils.random(ASSET_DATA_LENGTH);
const errorData = hexUtils.random(ERROR_DATA_LENGTH);
createDecodeTest(ExchangeRevertErrors.AssetProxyTransferError, [orderHash, assetData, errorData]);
})();
(() => {
const leftOrderHash = orderUtils.generatePseudoRandomOrderHash();
const rightOrderHash = orderUtils.generatePseudoRandomOrderHash();
createDecodeTest(ExchangeRevertErrors.NegativeSpreadError, [leftOrderHash, rightOrderHash]);
})();
(() => {
const errorCode = ExchangeRevertErrors.TransactionErrorCode.AlreadyExecuted;
const transactionHash = orderUtils.generatePseudoRandomOrderHash();
createDecodeTest(ExchangeRevertErrors.TransactionError, [errorCode, transactionHash]);
})();
(() => {
const transactionHash = orderUtils.generatePseudoRandomOrderHash();
const errorData = hexUtils.random(ERROR_DATA_LENGTH);
createDecodeTest(ExchangeRevertErrors.TransactionExecutionError, [transactionHash, errorData]);
})();
(() => {
const errorCode = ExchangeRevertErrors.IncompleteFillErrorCode.IncompleteMarketSellOrders;
const expectedAmount = new BigNumber(hexUtils.random(WORD_LENGTH));
const actualAmount = new BigNumber(hexUtils.random(WORD_LENGTH));
createDecodeTest(ExchangeRevertErrors.IncompleteFillError, [errorCode, expectedAmount, actualAmount]);
})();
});