@paraswap/dex-lib 2.14.1 → 2.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.vscode/launch.json +21 -0
- package/build/dex/aave-v3/tokens/arbitrum.json +50 -0
- package/build/dex/aave-v3/tokens/avalanche.json +50 -0
- package/build/dex/aave-v3/tokens/fantom.json +62 -0
- package/build/dex/aave-v3/tokens/mainnet.json +44 -0
- package/build/dex/aave-v3/tokens/optimism.json +50 -0
- package/build/dex/aave-v3/tokens/polygon.json +98 -0
- package/build/dex/balancer-v2/VirtualBoostedPool.d.ts +79 -0
- package/build/dex/balancer-v2/VirtualBoostedPool.js +382 -0
- package/build/dex/balancer-v2/VirtualBoostedPool.js.map +1 -0
- package/build/dex/generic-rfq/e2e-test-config.d.ts +9 -0
- package/build/dex/generic-rfq/e2e-test-config.js +33 -0
- package/build/dex/generic-rfq/e2e-test-config.js.map +1 -0
- package/build/dex/generic-rfq/rate-fetcher.js +2 -0
- package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
- package/build/dex/generic-rfq/validators.d.ts +1 -1
- package/build/dex/generic-rfq/validators.js +36 -26
- package/build/dex/generic-rfq/validators.js.map +1 -1
- package/build/dex/test-aave-v3/config.d.ts +4 -0
- package/build/dex/test-aave-v3/config.js +15 -0
- package/build/dex/test-aave-v3/config.js.map +1 -0
- package/build/dex/test-aave-v3/test-aave-v3-pool.d.ts +39 -0
- package/build/dex/test-aave-v3/test-aave-v3-pool.js +63 -0
- package/build/dex/test-aave-v3/test-aave-v3-pool.js.map +1 -0
- package/build/dex/test-aave-v3/test-aave-v3.d.ts +37 -0
- package/build/dex/test-aave-v3/test-aave-v3.js +126 -0
- package/build/dex/test-aave-v3/test-aave-v3.js.map +1 -0
- package/build/dex/test-aave-v3/types.d.ts +6 -0
- package/build/dex/test-aave-v3/types.js +3 -0
- package/build/dex/test-aave-v3/types.js.map +1 -0
- package/build/lib/fetcher/fetcher.js +3 -0
- package/build/lib/fetcher/fetcher.js.map +1 -1
- package/package.json +1 -1
- package/src/dex/generic-rfq/e2e-test-config.ts +37 -0
- package/src/dex/generic-rfq/generic-rfq-e2e.test.ts +63 -258
- package/src/dex/generic-rfq/generic-rfq-local-e2e.test.ts +121 -0
- package/src/dex/generic-rfq/rate-fetcher.ts +2 -0
- package/src/dex/generic-rfq/validators.test.ts +6 -32
- package/src/dex/generic-rfq/validators.ts +57 -32
- package/src/lib/fetcher/fetcher.ts +6 -0
- package/tests/constants-e2e.ts +2 -0
- package/tests/utils-e2e.ts +59 -48
|
@@ -6,8 +6,8 @@ import { Network, ContractMethod, SwapSide, MAX_UINT } from '../../constants';
|
|
|
6
6
|
import { generateConfig } from '../../config';
|
|
7
7
|
import { newTestE2E, getEnv } from '../../../tests/utils-e2e';
|
|
8
8
|
import { SmartTokens, GENERIC_ADDR1 } from '../../../tests/constants-e2e';
|
|
9
|
-
import { startTestServer } from './example-api.test';
|
|
10
9
|
import { RFQConfig } from './types';
|
|
10
|
+
import { testConfig } from './e2e-test-config';
|
|
11
11
|
|
|
12
12
|
const PK_KEY = process.env.TEST_PK_KEY;
|
|
13
13
|
|
|
@@ -19,113 +19,13 @@ const testAccount = new ethers.Wallet(PK_KEY!);
|
|
|
19
19
|
|
|
20
20
|
jest.setTimeout(1000 * 60 * 3);
|
|
21
21
|
|
|
22
|
-
describe('GenericRFQ E2E Mainnet', () => {
|
|
23
|
-
let stopServer: undefined | Function = undefined;
|
|
24
|
-
|
|
25
|
-
beforeAll(() => {
|
|
26
|
-
stopServer = startTestServer(testAccount);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const network = Network.MAINNET;
|
|
30
|
-
const smartTokens = SmartTokens[network];
|
|
31
|
-
|
|
32
|
-
const srcToken = smartTokens.WETH;
|
|
33
|
-
const destToken = smartTokens.DAI;
|
|
34
|
-
|
|
35
|
-
const config = generateConfig(network);
|
|
36
|
-
|
|
37
|
-
describe('GenericRFQ', () => {
|
|
38
|
-
const dexKey = 'DummyParaSwapPool';
|
|
39
|
-
|
|
40
|
-
srcToken.addBalance(testAccount.address, MAX_UINT);
|
|
41
|
-
srcToken.addAllowance(
|
|
42
|
-
testAccount.address,
|
|
43
|
-
config.augustusRFQAddress,
|
|
44
|
-
MAX_UINT,
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
destToken.addBalance(testAccount.address, MAX_UINT);
|
|
48
|
-
destToken.addAllowance(
|
|
49
|
-
testAccount.address,
|
|
50
|
-
config.augustusRFQAddress,
|
|
51
|
-
MAX_UINT,
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
describe('Simpleswap', () => {
|
|
55
|
-
it('SELL WETH -> DAI', async () => {
|
|
56
|
-
await newTestE2E({
|
|
57
|
-
config,
|
|
58
|
-
srcToken,
|
|
59
|
-
destToken,
|
|
60
|
-
senderAddress: GENERIC_ADDR1,
|
|
61
|
-
thirdPartyAddress: testAccount.address,
|
|
62
|
-
_amount: '1000000000000000000',
|
|
63
|
-
swapSide: SwapSide.SELL,
|
|
64
|
-
dexKey: dexKey,
|
|
65
|
-
contractMethod: ContractMethod.simpleSwap,
|
|
66
|
-
network: network,
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('SELL DAI -> WETH', async () => {
|
|
71
|
-
await newTestE2E({
|
|
72
|
-
config,
|
|
73
|
-
destToken,
|
|
74
|
-
srcToken,
|
|
75
|
-
senderAddress: GENERIC_ADDR1,
|
|
76
|
-
thirdPartyAddress: testAccount.address,
|
|
77
|
-
_amount: '1000000000000000000',
|
|
78
|
-
swapSide: SwapSide.SELL,
|
|
79
|
-
dexKey: dexKey,
|
|
80
|
-
contractMethod: ContractMethod.simpleSwap,
|
|
81
|
-
network: network,
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('BUY WETH -> DAI', async () => {
|
|
86
|
-
await newTestE2E({
|
|
87
|
-
config,
|
|
88
|
-
srcToken,
|
|
89
|
-
destToken,
|
|
90
|
-
senderAddress: GENERIC_ADDR1,
|
|
91
|
-
thirdPartyAddress: testAccount.address,
|
|
92
|
-
_amount: '1000000000000000000',
|
|
93
|
-
swapSide: SwapSide.BUY,
|
|
94
|
-
dexKey: dexKey,
|
|
95
|
-
contractMethod: ContractMethod.simpleBuy,
|
|
96
|
-
network: network,
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('BUY DAI -> WETH', async () => {
|
|
101
|
-
await newTestE2E({
|
|
102
|
-
config,
|
|
103
|
-
destToken,
|
|
104
|
-
srcToken,
|
|
105
|
-
senderAddress: GENERIC_ADDR1,
|
|
106
|
-
thirdPartyAddress: testAccount.address,
|
|
107
|
-
_amount: '1000000000000000000',
|
|
108
|
-
swapSide: SwapSide.BUY,
|
|
109
|
-
dexKey: dexKey,
|
|
110
|
-
contractMethod: ContractMethod.simpleBuy,
|
|
111
|
-
network: network,
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
afterAll(() => {
|
|
118
|
-
if (stopServer) {
|
|
119
|
-
stopServer();
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
|
|
124
22
|
const buildConfigForGenericRFQ = (): RFQConfig => {
|
|
125
23
|
const url = getEnv('GENERIC_RFQ_URL');
|
|
126
24
|
|
|
127
25
|
const secret = {
|
|
128
|
-
secretKey:
|
|
26
|
+
secretKey: Buffer.from(getEnv('GENERIC_RFQ_SECRET_KEY'), 'base64').toString(
|
|
27
|
+
'binary',
|
|
28
|
+
),
|
|
129
29
|
accessKey: getEnv('GENERIC_RFQ_ACCESS_KEY'),
|
|
130
30
|
domain: 'paraswap',
|
|
131
31
|
};
|
|
@@ -179,160 +79,65 @@ const buildConfigForGenericRFQ = (): RFQConfig => {
|
|
|
179
79
|
};
|
|
180
80
|
};
|
|
181
81
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
destToken.addBalance(testAccount.address, MAX_UINT);
|
|
240
|
-
destToken.addAllowance(
|
|
241
|
-
testAccount.address,
|
|
242
|
-
config.augustusRFQAddress,
|
|
243
|
-
MAX_UINT,
|
|
244
|
-
);
|
|
245
|
-
|
|
246
|
-
describe('Simpleswap', () => {
|
|
247
|
-
it('BUY WBTC -> USDC', async () => {
|
|
248
|
-
await newTestE2E({
|
|
249
|
-
config,
|
|
250
|
-
srcToken,
|
|
251
|
-
destToken,
|
|
252
|
-
senderAddress: GENERIC_ADDR1,
|
|
253
|
-
thirdPartyAddress: testAccount.address,
|
|
254
|
-
_amount: '1000000',
|
|
255
|
-
swapSide: SwapSide.BUY,
|
|
256
|
-
dexKey: dexKey,
|
|
257
|
-
contractMethod: ContractMethod.simpleBuy,
|
|
258
|
-
network: network,
|
|
259
|
-
sleepMs: 5000,
|
|
260
|
-
});
|
|
261
|
-
});
|
|
262
|
-
});
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
describe('GenericRFQ B/Q SELL', () => {
|
|
266
|
-
const srcToken = smartTokens.USDC;
|
|
267
|
-
const destToken = smartTokens.WBTC;
|
|
268
|
-
|
|
269
|
-
srcToken.addBalance(testAccount.address, MAX_UINT);
|
|
270
|
-
srcToken.addAllowance(
|
|
271
|
-
testAccount.address,
|
|
272
|
-
config.augustusRFQAddress,
|
|
273
|
-
MAX_UINT,
|
|
274
|
-
);
|
|
275
|
-
|
|
276
|
-
destToken.addBalance(testAccount.address, MAX_UINT);
|
|
277
|
-
destToken.addAllowance(
|
|
278
|
-
testAccount.address,
|
|
279
|
-
config.augustusRFQAddress,
|
|
280
|
-
MAX_UINT,
|
|
281
|
-
);
|
|
282
|
-
|
|
283
|
-
describe('Simpleswap', () => {
|
|
284
|
-
it('SELL USDC -> WBTC', async () => {
|
|
285
|
-
await newTestE2E({
|
|
286
|
-
config,
|
|
287
|
-
srcToken,
|
|
288
|
-
destToken,
|
|
289
|
-
senderAddress: GENERIC_ADDR1,
|
|
290
|
-
thirdPartyAddress: testAccount.address,
|
|
291
|
-
_amount: '1000000',
|
|
292
|
-
swapSide: SwapSide.SELL,
|
|
293
|
-
dexKey: dexKey,
|
|
294
|
-
contractMethod: ContractMethod.simpleSwap,
|
|
295
|
-
network: network,
|
|
296
|
-
sleepMs: 5000,
|
|
297
|
-
});
|
|
298
|
-
});
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
describe('GenericRFQ Q/B SELL', () => {
|
|
303
|
-
const srcToken = smartTokens.WBTC;
|
|
304
|
-
const destToken = smartTokens.USDC;
|
|
305
|
-
|
|
306
|
-
srcToken.addBalance(testAccount.address, MAX_UINT);
|
|
307
|
-
srcToken.addAllowance(
|
|
308
|
-
testAccount.address,
|
|
309
|
-
config.augustusRFQAddress,
|
|
310
|
-
MAX_UINT,
|
|
311
|
-
);
|
|
312
|
-
|
|
313
|
-
destToken.addBalance(testAccount.address, MAX_UINT);
|
|
314
|
-
destToken.addAllowance(
|
|
315
|
-
testAccount.address,
|
|
316
|
-
config.augustusRFQAddress,
|
|
317
|
-
MAX_UINT,
|
|
318
|
-
);
|
|
319
|
-
|
|
320
|
-
describe('Simpleswap', () => {
|
|
321
|
-
it('SELL WBTC -> USDC', async () => {
|
|
322
|
-
await newTestE2E({
|
|
323
|
-
config,
|
|
324
|
-
srcToken,
|
|
325
|
-
destToken,
|
|
326
|
-
senderAddress: GENERIC_ADDR1,
|
|
327
|
-
thirdPartyAddress: testAccount.address,
|
|
328
|
-
_amount: '10000',
|
|
329
|
-
swapSide: SwapSide.SELL,
|
|
330
|
-
dexKey: dexKey,
|
|
331
|
-
contractMethod: ContractMethod.simpleSwap,
|
|
332
|
-
network: network,
|
|
333
|
-
sleepMs: 5000,
|
|
82
|
+
const SKIP_TENDERLY = !!getEnv('GENERIC_RFQ_SKIP_TENDERLY', true);
|
|
83
|
+
const dexKey = 'YOUR_NAME';
|
|
84
|
+
|
|
85
|
+
describe(`GenericRFQ ${dexKey} E2E`, () => {
|
|
86
|
+
for (const [_network, testCases] of Object.entries(testConfig)) {
|
|
87
|
+
const network = parseInt(_network, 10);
|
|
88
|
+
const smartTokens = SmartTokens[network];
|
|
89
|
+
const config = generateConfig(network);
|
|
90
|
+
|
|
91
|
+
config.rfqConfigs[dexKey] = buildConfigForGenericRFQ();
|
|
92
|
+
describe(`${Network[network]}`, () => {
|
|
93
|
+
for (const testCase of testCases) {
|
|
94
|
+
if (!smartTokens.hasOwnProperty(testCase.srcToken)) {
|
|
95
|
+
throw new Error(`Please add "addBalance" and "addAllowance" functions for ${testCase.srcToken} on ${Network[network]} (in constants-e2e.ts).`);
|
|
96
|
+
}
|
|
97
|
+
if (!smartTokens.hasOwnProperty(testCase.destToken)){
|
|
98
|
+
throw new Error(`Please add "addBalance" and "addAllowance" functions for ${testCase.destToken} on ${Network[network]} (in constants-e2e.ts).`);
|
|
99
|
+
}
|
|
100
|
+
const srcToken = smartTokens[testCase.srcToken];
|
|
101
|
+
const destToken = smartTokens[testCase.destToken];
|
|
102
|
+
|
|
103
|
+
if (!SKIP_TENDERLY) {
|
|
104
|
+
srcToken.addBalance(testAccount.address, MAX_UINT);
|
|
105
|
+
srcToken.addAllowance(
|
|
106
|
+
testAccount.address,
|
|
107
|
+
config.augustusRFQAddress,
|
|
108
|
+
MAX_UINT,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
destToken.addBalance(testAccount.address, MAX_UINT);
|
|
112
|
+
destToken.addAllowance(
|
|
113
|
+
testAccount.address,
|
|
114
|
+
config.augustusRFQAddress,
|
|
115
|
+
MAX_UINT,
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
const contractMethod =
|
|
119
|
+
testCase.swapSide === SwapSide.BUY
|
|
120
|
+
? ContractMethod.simpleBuy
|
|
121
|
+
: ContractMethod.simpleSwap;
|
|
122
|
+
describe(`${contractMethod}`, () => {
|
|
123
|
+
it(`${testCase.swapSide} ${testCase.srcToken} -> ${testCase.destToken}`, async () => {
|
|
124
|
+
await newTestE2E({
|
|
125
|
+
config,
|
|
126
|
+
srcToken,
|
|
127
|
+
destToken,
|
|
128
|
+
senderAddress: GENERIC_ADDR1,
|
|
129
|
+
thirdPartyAddress: testAccount.address,
|
|
130
|
+
_amount: testCase.amount,
|
|
131
|
+
swapSide: testCase.swapSide as SwapSide,
|
|
132
|
+
dexKey: dexKey,
|
|
133
|
+
contractMethod,
|
|
134
|
+
network,
|
|
135
|
+
sleepMs: 5000,
|
|
136
|
+
skipTenderly: SKIP_TENDERLY,
|
|
137
|
+
});
|
|
138
|
+
});
|
|
334
139
|
});
|
|
335
|
-
}
|
|
140
|
+
}
|
|
336
141
|
});
|
|
337
|
-
}
|
|
142
|
+
}
|
|
338
143
|
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import dotenv from 'dotenv';
|
|
2
|
+
dotenv.config();
|
|
3
|
+
|
|
4
|
+
import { ethers } from 'ethers';
|
|
5
|
+
import { Network, ContractMethod, SwapSide, MAX_UINT } from '../../constants';
|
|
6
|
+
import { generateConfig } from '../../config';
|
|
7
|
+
import { newTestE2E } from '../../../tests/utils-e2e';
|
|
8
|
+
import { SmartTokens, GENERIC_ADDR1 } from '../../../tests/constants-e2e';
|
|
9
|
+
import { startTestServer } from './example-api.test';
|
|
10
|
+
|
|
11
|
+
const PK_KEY = process.env.TEST_PK_KEY;
|
|
12
|
+
|
|
13
|
+
if (!PK_KEY) {
|
|
14
|
+
throw new Error('Missing TEST_PK_KEY');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const testAccount = new ethers.Wallet(PK_KEY!);
|
|
18
|
+
|
|
19
|
+
jest.setTimeout(1000 * 60 * 3);
|
|
20
|
+
|
|
21
|
+
describe('GenericRFQ E2E Mainnet', () => {
|
|
22
|
+
let stopServer: undefined | Function = undefined;
|
|
23
|
+
|
|
24
|
+
beforeAll(() => {
|
|
25
|
+
stopServer = startTestServer(testAccount);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const network = Network.MAINNET;
|
|
29
|
+
const smartTokens = SmartTokens[network];
|
|
30
|
+
|
|
31
|
+
const srcToken = smartTokens.WETH;
|
|
32
|
+
const destToken = smartTokens.DAI;
|
|
33
|
+
|
|
34
|
+
const config = generateConfig(network);
|
|
35
|
+
|
|
36
|
+
describe('GenericRFQ', () => {
|
|
37
|
+
const dexKey = 'DummyParaSwapPool';
|
|
38
|
+
|
|
39
|
+
srcToken.addBalance(testAccount.address, MAX_UINT);
|
|
40
|
+
srcToken.addAllowance(
|
|
41
|
+
testAccount.address,
|
|
42
|
+
config.augustusRFQAddress,
|
|
43
|
+
MAX_UINT,
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
destToken.addBalance(testAccount.address, MAX_UINT);
|
|
47
|
+
destToken.addAllowance(
|
|
48
|
+
testAccount.address,
|
|
49
|
+
config.augustusRFQAddress,
|
|
50
|
+
MAX_UINT,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
describe('Simpleswap', () => {
|
|
54
|
+
it('SELL WETH -> DAI', async () => {
|
|
55
|
+
await newTestE2E({
|
|
56
|
+
config,
|
|
57
|
+
srcToken,
|
|
58
|
+
destToken,
|
|
59
|
+
senderAddress: GENERIC_ADDR1,
|
|
60
|
+
thirdPartyAddress: testAccount.address,
|
|
61
|
+
_amount: '1000000000000000000',
|
|
62
|
+
swapSide: SwapSide.SELL,
|
|
63
|
+
dexKey: dexKey,
|
|
64
|
+
contractMethod: ContractMethod.simpleSwap,
|
|
65
|
+
network: network,
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('SELL DAI -> WETH', async () => {
|
|
70
|
+
await newTestE2E({
|
|
71
|
+
config,
|
|
72
|
+
destToken,
|
|
73
|
+
srcToken,
|
|
74
|
+
senderAddress: GENERIC_ADDR1,
|
|
75
|
+
thirdPartyAddress: testAccount.address,
|
|
76
|
+
_amount: '1000000000000000000',
|
|
77
|
+
swapSide: SwapSide.SELL,
|
|
78
|
+
dexKey: dexKey,
|
|
79
|
+
contractMethod: ContractMethod.simpleSwap,
|
|
80
|
+
network: network,
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('BUY WETH -> DAI', async () => {
|
|
85
|
+
await newTestE2E({
|
|
86
|
+
config,
|
|
87
|
+
srcToken,
|
|
88
|
+
destToken,
|
|
89
|
+
senderAddress: GENERIC_ADDR1,
|
|
90
|
+
thirdPartyAddress: testAccount.address,
|
|
91
|
+
_amount: '1000000000000000000',
|
|
92
|
+
swapSide: SwapSide.BUY,
|
|
93
|
+
dexKey: dexKey,
|
|
94
|
+
contractMethod: ContractMethod.simpleBuy,
|
|
95
|
+
network: network,
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('BUY DAI -> WETH', async () => {
|
|
100
|
+
await newTestE2E({
|
|
101
|
+
config,
|
|
102
|
+
destToken,
|
|
103
|
+
srcToken,
|
|
104
|
+
senderAddress: GENERIC_ADDR1,
|
|
105
|
+
thirdPartyAddress: testAccount.address,
|
|
106
|
+
_amount: '1000000000000000000',
|
|
107
|
+
swapSide: SwapSide.BUY,
|
|
108
|
+
dexKey: dexKey,
|
|
109
|
+
contractMethod: ContractMethod.simpleBuy,
|
|
110
|
+
network: network,
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
afterAll(() => {
|
|
117
|
+
if (stopServer) {
|
|
118
|
+
stopServer();
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
});
|
|
@@ -403,9 +403,11 @@ export class RateFetcher {
|
|
|
403
403
|
delete payload.secret;
|
|
404
404
|
}
|
|
405
405
|
|
|
406
|
+
this.logger.info('FirmRate Request:', payload);
|
|
406
407
|
const { data } = await this.dexHelper.httpRequest.request<unknown>(
|
|
407
408
|
payload,
|
|
408
409
|
);
|
|
410
|
+
this.logger.info('FirmRate Response: ', data);
|
|
409
411
|
|
|
410
412
|
const firmRateResp = validateAndCast<RFQFirmRateResponse>(
|
|
411
413
|
data,
|
|
@@ -112,10 +112,11 @@ describe('GenericRFQ Validator test', () => {
|
|
|
112
112
|
},
|
|
113
113
|
};
|
|
114
114
|
|
|
115
|
-
const
|
|
115
|
+
const pricesNegativeSpread = {
|
|
116
116
|
prices: {
|
|
117
117
|
'WETH/DAI': {
|
|
118
118
|
bids: [
|
|
119
|
+
['1337.425240000000000000', '1.166200000000000000'],
|
|
119
120
|
['1333.024812000000000000', '1.166200000000000000'],
|
|
120
121
|
['1333.425240000000000000', '1.166200000000000000'],
|
|
121
122
|
['1332.624384000000000000', '1.166200000000000000'],
|
|
@@ -135,29 +136,6 @@ describe('GenericRFQ Validator test', () => {
|
|
|
135
136
|
},
|
|
136
137
|
};
|
|
137
138
|
|
|
138
|
-
const pricesInvalidAskNotSortedAsc = {
|
|
139
|
-
prices: {
|
|
140
|
-
'WETH/DAI': {
|
|
141
|
-
bids: [
|
|
142
|
-
['1333.425240000000000000', '1.166200000000000000'],
|
|
143
|
-
['1333.024812000000000000', '1.166200000000000000'],
|
|
144
|
-
['1332.624384000000000000', '1.166200000000000000'],
|
|
145
|
-
['1332.223956000000000000', '1.166200000000000000'],
|
|
146
|
-
['1331.823528000000000000', '1.166200000000000000'],
|
|
147
|
-
['1331.423100000000000000', '1.169000000000000000'],
|
|
148
|
-
],
|
|
149
|
-
asks: [
|
|
150
|
-
['1337.146033000000000000', '1.166200000000000000'],
|
|
151
|
-
['1336.745410000000000000', '1.166200000000000000'],
|
|
152
|
-
['1337.546656000000000000', '1.166200000000000000'],
|
|
153
|
-
['1337.947279000000000000', '1.166200000000000000'],
|
|
154
|
-
['1338.347902000000000000', '1.166200000000000000'],
|
|
155
|
-
['1338.748525000000000000', '1.169000000000000000'],
|
|
156
|
-
],
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
};
|
|
160
|
-
|
|
161
139
|
const noPrices = {
|
|
162
140
|
prices: {
|
|
163
141
|
'WETH/DAI': {},
|
|
@@ -200,12 +178,6 @@ describe('GenericRFQ Validator test', () => {
|
|
|
200
178
|
|
|
201
179
|
it('Price test', () => {
|
|
202
180
|
expect(() => validateAndCast(prices, pricesResponse)).not.toThrowError();
|
|
203
|
-
expect(() =>
|
|
204
|
-
validateAndCast(pricesInvalidBidsNotSortedDesc, pricesResponse),
|
|
205
|
-
).toThrowError();
|
|
206
|
-
expect(() =>
|
|
207
|
-
validateAndCast(pricesInvalidAskNotSortedAsc, pricesResponse),
|
|
208
|
-
).toThrowError();
|
|
209
181
|
expect(() =>
|
|
210
182
|
validateAndCast(noPrices, pricesResponse),
|
|
211
183
|
).not.toThrowError();
|
|
@@ -218,6 +190,9 @@ describe('GenericRFQ Validator test', () => {
|
|
|
218
190
|
expect(() =>
|
|
219
191
|
validateAndCast(onlyAsks, pricesResponse),
|
|
220
192
|
).not.toThrowError();
|
|
193
|
+
expect(() =>
|
|
194
|
+
validateAndCast(pricesNegativeSpread, pricesResponse),
|
|
195
|
+
).toThrowError('the maximum bid is higher than minimum ask');
|
|
221
196
|
});
|
|
222
197
|
});
|
|
223
198
|
|
|
@@ -261,11 +236,10 @@ describe('GenericRFQ Validator test', () => {
|
|
|
261
236
|
},
|
|
262
237
|
};
|
|
263
238
|
|
|
264
|
-
it('
|
|
239
|
+
it('Order test', () => {
|
|
265
240
|
expect(() =>
|
|
266
241
|
validateAndCast(order, firmRateResponseValidator),
|
|
267
242
|
).not.toThrowError();
|
|
268
|
-
// expect(() => validateAndCast(invalidBlacklist, blacklistResponseValidator)).toThrowError();
|
|
269
243
|
});
|
|
270
244
|
});
|
|
271
245
|
});
|
|
@@ -56,7 +56,7 @@ const stringNumberValidator = (
|
|
|
56
56
|
return value;
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
const
|
|
59
|
+
const pricesValidator = joi
|
|
60
60
|
.array()
|
|
61
61
|
.items(
|
|
62
62
|
joi
|
|
@@ -66,47 +66,58 @@ const pricesValidatorWithoutSorting = joi
|
|
|
66
66
|
);
|
|
67
67
|
|
|
68
68
|
const ext: joi.Extension = {
|
|
69
|
-
type: '
|
|
70
|
-
base:
|
|
69
|
+
type: 'validatedPrices',
|
|
70
|
+
base: joi.object({
|
|
71
|
+
bids: pricesValidator,
|
|
72
|
+
asks: pricesValidator,
|
|
73
|
+
}),
|
|
71
74
|
rules: {
|
|
72
|
-
|
|
73
|
-
validate: (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
bidsLowerThanAsks: {
|
|
76
|
+
validate: (
|
|
77
|
+
values: { bids: string[]; asks: string[] },
|
|
78
|
+
helpers: CustomHelpers,
|
|
79
|
+
) => {
|
|
80
|
+
if (
|
|
81
|
+
!values.bids ||
|
|
82
|
+
!values.asks ||
|
|
83
|
+
values.bids.length === 0 ||
|
|
84
|
+
values.asks.length === 0
|
|
85
|
+
) {
|
|
86
|
+
return values;
|
|
87
|
+
}
|
|
88
|
+
const maxBid = values.bids
|
|
89
|
+
.map(numbers => new BigNumber(numbers[0]))
|
|
90
|
+
.reduce(
|
|
91
|
+
(previousValue, currentValue) =>
|
|
92
|
+
currentValue.gte(previousValue) ? currentValue : previousValue,
|
|
93
|
+
new BigNumber(0),
|
|
94
|
+
);
|
|
95
|
+
const minAsk = values.asks
|
|
96
|
+
.map(numbers => new BigNumber(numbers[0]))
|
|
97
|
+
.reduce(
|
|
98
|
+
(previousValue, currentValue) =>
|
|
99
|
+
currentValue.lte(previousValue) ? currentValue : previousValue,
|
|
100
|
+
new BigNumber('123456789012345678901234567890'),
|
|
101
|
+
);
|
|
102
|
+
return maxBid < minAsk
|
|
79
103
|
? values
|
|
80
104
|
: helpers.message({
|
|
81
|
-
custom:
|
|
82
|
-
});
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
desc: {
|
|
86
|
-
validate: (values: string[][], helpers: CustomHelpers) => {
|
|
87
|
-
const prices = values.map(numbers => new BigNumber(numbers[0]));
|
|
88
|
-
const isAscOrder = prices.every(
|
|
89
|
-
(x, i) => i === 0 || x.lte(prices[i - 1]),
|
|
90
|
-
);
|
|
91
|
-
return isAscOrder
|
|
92
|
-
? values
|
|
93
|
-
: helpers.message({
|
|
94
|
-
custom: `array is not desc sorted ${JSON.stringify(values)}`,
|
|
105
|
+
custom: 'the maximum bid is higher than minimum ask',
|
|
95
106
|
});
|
|
96
107
|
},
|
|
97
108
|
},
|
|
98
109
|
},
|
|
99
110
|
};
|
|
100
111
|
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
export const priceValidator = joi.object({
|
|
104
|
-
bids: pricesArrayValidator.sortedArray().desc(),
|
|
105
|
-
asks: pricesArrayValidator.sortedArray().asc(),
|
|
106
|
-
});
|
|
112
|
+
export const priceValidator = joi.extend(ext);
|
|
107
113
|
|
|
108
114
|
export const pricesResponse = joi.object({
|
|
109
|
-
prices: joi
|
|
115
|
+
prices: joi
|
|
116
|
+
.object()
|
|
117
|
+
.pattern(
|
|
118
|
+
joi.string().min(1),
|
|
119
|
+
priceValidator.validatedPrices().bidsLowerThanAsks(),
|
|
120
|
+
),
|
|
110
121
|
});
|
|
111
122
|
|
|
112
123
|
export const validateAndCast = <T>(
|
|
@@ -171,12 +182,26 @@ const stringStartWithHex0x = (
|
|
|
171
182
|
return value;
|
|
172
183
|
};
|
|
173
184
|
|
|
185
|
+
const mustBeAugustusSwapper = (
|
|
186
|
+
value: string,
|
|
187
|
+
helpers: CustomHelpers,
|
|
188
|
+
): string | ErrorReport => {
|
|
189
|
+
const allowedTakers = [
|
|
190
|
+
'0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57'.toLowerCase(),
|
|
191
|
+
];
|
|
192
|
+
return allowedTakers.includes(value.toLowerCase())
|
|
193
|
+
? value
|
|
194
|
+
: helpers.message({
|
|
195
|
+
custom: `"order.taker" must be any of ${JSON.stringify(allowedTakers)}`,
|
|
196
|
+
});
|
|
197
|
+
};
|
|
198
|
+
|
|
174
199
|
export const orderWithSignatureValidator = joi
|
|
175
200
|
.object({
|
|
176
201
|
nonceAndMeta: joi.string().custom(stringPositiveBigIntValidator),
|
|
177
202
|
expiry: joi.number().min(0),
|
|
178
203
|
maker: addressSchema.required(),
|
|
179
|
-
taker: addressSchema.required(),
|
|
204
|
+
taker: addressSchema.required().custom(mustBeAugustusSwapper),
|
|
180
205
|
makerAsset: addressSchema.required(),
|
|
181
206
|
takerAsset: addressSchema.required(),
|
|
182
207
|
makerAmount: joi
|
|
@@ -76,6 +76,12 @@ export default class Fetcher<T> {
|
|
|
76
76
|
.map((_, i) => i)
|
|
77
77
|
.filter(i => results[i] instanceof Error);
|
|
78
78
|
|
|
79
|
+
results.map(result => {
|
|
80
|
+
this.logger.info(
|
|
81
|
+
'Results Data:',
|
|
82
|
+
JSON.stringify((result as any).data, null, 4).substring(0, 500),
|
|
83
|
+
);
|
|
84
|
+
});
|
|
79
85
|
failures.forEach(i => {
|
|
80
86
|
this.logger.warn(
|
|
81
87
|
`failed polling ${this.requests[i].info.requestOptions.url} ${results[i]}`,
|