@paraswap/dex-lib 2.12.15-friendly-local-deadline.0 → 2.12.15

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.
Files changed (79) hide show
  1. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  2. package/.idea/misc.xml +6 -0
  3. package/.idea/modules.xml +8 -0
  4. package/.idea/vcs.xml +6 -0
  5. package/.vscode/launch.json +21 -0
  6. package/build/dex/aave-v3/tokens/arbitrum.json +50 -0
  7. package/build/dex/aave-v3/tokens/avalanche.json +50 -0
  8. package/build/dex/aave-v3/tokens/fantom.json +62 -0
  9. package/build/dex/aave-v3/tokens/mainnet.json +44 -0
  10. package/build/dex/aave-v3/tokens/optimism.json +50 -0
  11. package/build/dex/aave-v3/tokens/polygon.json +98 -0
  12. package/build/dex/balancer-v2/VirtualBoostedPool.d.ts +79 -0
  13. package/build/dex/balancer-v2/VirtualBoostedPool.js +382 -0
  14. package/build/dex/balancer-v2/VirtualBoostedPool.js.map +1 -0
  15. package/build/dex/generic-rfq/e2e-test-config.d.ts +9 -0
  16. package/build/dex/generic-rfq/e2e-test-config.js +33 -0
  17. package/build/dex/generic-rfq/e2e-test-config.js.map +1 -0
  18. package/build/dex/generic-rfq/rate-fetcher.js +2 -0
  19. package/build/dex/generic-rfq/rate-fetcher.js.map +1 -1
  20. package/build/dex/generic-rfq/validators.d.ts +1 -1
  21. package/build/dex/generic-rfq/validators.js +36 -26
  22. package/build/dex/generic-rfq/validators.js.map +1 -1
  23. package/build/dex/maverick-v1/maverick-v1.js +4 -4
  24. package/build/dex/maverick-v1/maverick-v1.js.map +1 -1
  25. package/build/dex/maverick-v1/types.d.ts +3 -2
  26. package/build/dex/maverick-v1/types.js.map +1 -1
  27. package/build/dex/platypus/platypus.js +3 -3
  28. package/build/dex/platypus/platypus.js.map +1 -1
  29. package/build/dex/shell.d.ts +1 -1
  30. package/build/dex/shell.js +1 -1
  31. package/build/dex/shell.js.map +1 -1
  32. package/build/dex/simple-exchange.d.ts +1 -1
  33. package/build/dex/simple-exchange.js +3 -9
  34. package/build/dex/simple-exchange.js.map +1 -1
  35. package/build/dex/test-aave-v3/config.d.ts +4 -0
  36. package/build/dex/test-aave-v3/config.js +15 -0
  37. package/build/dex/test-aave-v3/config.js.map +1 -0
  38. package/build/dex/test-aave-v3/test-aave-v3-pool.d.ts +39 -0
  39. package/build/dex/test-aave-v3/test-aave-v3-pool.js +63 -0
  40. package/build/dex/test-aave-v3/test-aave-v3-pool.js.map +1 -0
  41. package/build/dex/test-aave-v3/test-aave-v3.d.ts +37 -0
  42. package/build/dex/test-aave-v3/test-aave-v3.js +126 -0
  43. package/build/dex/test-aave-v3/test-aave-v3.js.map +1 -0
  44. package/build/dex/test-aave-v3/types.d.ts +6 -0
  45. package/build/dex/test-aave-v3/types.js +3 -0
  46. package/build/dex/test-aave-v3/types.js.map +1 -0
  47. package/build/dex/trader-joe-v2.d.ts +2 -1
  48. package/build/dex/trader-joe-v2.js +3 -3
  49. package/build/dex/trader-joe-v2.js.map +1 -1
  50. package/build/dex/uniswap-v3/types.d.ts +2 -2
  51. package/build/dex/uniswap-v3/uniswap-v3.js +3 -3
  52. package/build/dex/uniswap-v3/uniswap-v3.js.map +1 -1
  53. package/build/dex/uniswap-v3.d.ts +3 -2
  54. package/build/dex/uniswap-v3.js +5 -5
  55. package/build/dex/uniswap-v3.js.map +1 -1
  56. package/build/lib/fetcher/fetcher.js +3 -0
  57. package/build/lib/fetcher/fetcher.js.map +1 -1
  58. package/package.json +1 -1
  59. package/src/dex/generic-rfq/e2e-test-config.ts +37 -0
  60. package/src/dex/generic-rfq/generic-rfq-e2e-arbitrum.test.ts +360 -0
  61. package/src/dex/generic-rfq/generic-rfq-e2e-bsc.test.ts +346 -0
  62. package/src/dex/generic-rfq/generic-rfq-e2e-polygon.test.ts +360 -0
  63. package/src/dex/generic-rfq/generic-rfq-e2e.test.ts +63 -258
  64. package/src/dex/generic-rfq/generic-rfq-local-e2e.test.ts +121 -0
  65. package/src/dex/generic-rfq/rate-fetcher.ts +2 -0
  66. package/src/dex/generic-rfq/validators.test.ts +6 -32
  67. package/src/dex/generic-rfq/validators.ts +57 -32
  68. package/src/dex/maverick-v1/maverick-v1.ts +4 -4
  69. package/src/dex/maverick-v1/types.ts +3 -2
  70. package/src/dex/platypus/platypus.ts +3 -3
  71. package/src/dex/shell.ts +3 -2
  72. package/src/dex/simple-exchange.ts +3 -10
  73. package/src/dex/trader-joe-v2.ts +5 -4
  74. package/src/dex/uniswap-v3/types.ts +2 -2
  75. package/src/dex/uniswap-v3/uniswap-v3.ts +3 -3
  76. package/src/dex/uniswap-v3.ts +8 -7
  77. package/src/lib/fetcher/fetcher.ts +6 -0
  78. package/tests/constants-e2e.ts +2 -0
  79. package/tests/utils-e2e.ts +59 -48
@@ -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.debug('FirmRate Request:', payload);
406
407
  const { data } = await this.dexHelper.httpRequest.request<unknown>(
407
408
  payload,
408
409
  );
410
+ this.logger.debug('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 pricesInvalidBidsNotSortedDesc = {
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('Blacklist test', () => {
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 pricesValidatorWithoutSorting = joi
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: 'sortedArray',
70
- base: pricesValidatorWithoutSorting,
69
+ type: 'validatedPrices',
70
+ base: joi.object({
71
+ bids: pricesValidator,
72
+ asks: pricesValidator,
73
+ }),
71
74
  rules: {
72
- asc: {
73
- validate: (values: string[], helpers: CustomHelpers) => {
74
- const prices = values.map(numbers => new BigNumber(numbers[0]));
75
- const isAscOrder = prices.every(
76
- (x, i) => i === 0 || x.gte(prices[i - 1]),
77
- );
78
- return isAscOrder
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: `array is not asc sorted ${JSON.stringify(values)}`,
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 pricesArrayValidator = joi.extend(ext);
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.object().pattern(joi.string().min(1), priceValidator),
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
@@ -291,7 +291,7 @@ export class MaverickV1
291
291
  data: MaverickV1Data,
292
292
  side: SwapSide,
293
293
  ): AdapterExchangeParam {
294
- const { pool } = data;
294
+ const { deadline, pool } = data;
295
295
  const payload = this.abiCoder.encodeParameter(
296
296
  {
297
297
  ParentStruct: {
@@ -301,7 +301,7 @@ export class MaverickV1
301
301
  },
302
302
  {
303
303
  pool,
304
- deadline: this.getLocalDeadlineAsFriendlyPlaceholder(), // FIXME: more gas efficient to pass block.timestamp in adapter
304
+ deadline: deadline || this.getDeadline(),
305
305
  },
306
306
  );
307
307
 
@@ -329,7 +329,7 @@ export class MaverickV1
329
329
  side === SwapSide.SELL
330
330
  ? {
331
331
  recipient: this.augustusAddress,
332
- deadline: this.getLocalDeadlineAsFriendlyPlaceholder(),
332
+ deadline: this.getDeadline(),
333
333
  amountIn: srcAmount,
334
334
  amountOutMinimum: destAmount,
335
335
  tokenIn: srcToken,
@@ -339,7 +339,7 @@ export class MaverickV1
339
339
  }
340
340
  : {
341
341
  recipient: this.augustusAddress,
342
- deadline: this.getLocalDeadlineAsFriendlyPlaceholder(),
342
+ deadline: this.getDeadline(),
343
343
  amountOut: destAmount,
344
344
  amountInMaximum: srcAmount,
345
345
  tokenIn: srcToken,
@@ -45,6 +45,7 @@ export type MaverickV1Data = {
45
45
  tokenA: Address;
46
46
  tokenB: Address;
47
47
  exchange: Address;
48
+ deadline?: number;
48
49
  };
49
50
 
50
51
  export enum MaverickV1Functions {
@@ -57,7 +58,7 @@ export type MaverickV1SellParam = {
57
58
  tokenOut: Address;
58
59
  pool: Address;
59
60
  recipient: Address;
60
- deadline: string;
61
+ deadline: number;
61
62
  amountIn: NumberAsString;
62
63
  amountOutMinimum: NumberAsString;
63
64
  sqrtPriceLimitD18: NumberAsString;
@@ -68,7 +69,7 @@ export type MaverickV1BuyParam = {
68
69
  tokenOut: Address;
69
70
  pool: Address;
70
71
  recipient: Address;
71
- deadline: string;
72
+ deadline: number;
72
73
  amountOut: NumberAsString;
73
74
  amountInMaximum: NumberAsString;
74
75
  sqrtPriceLimitD18: NumberAsString;
@@ -461,7 +461,7 @@ export class Platypus extends SimpleExchange implements IDex<PlatypusData> {
461
461
  destToken,
462
462
  1,
463
463
  this.augustusAddress,
464
- this.getLocalDeadlineAsFriendlyPlaceholder(),
464
+ this.getDeadline(),
465
465
  ])
466
466
  : isETHAddress(destToken)
467
467
  ? Platypus.avaxPoolInterface.encodeFunctionData('swapToETH', [
@@ -469,7 +469,7 @@ export class Platypus extends SimpleExchange implements IDex<PlatypusData> {
469
469
  srcAmount,
470
470
  1,
471
471
  this.augustusAddress,
472
- this.getLocalDeadlineAsFriendlyPlaceholder(),
472
+ this.getDeadline(),
473
473
  ])
474
474
  : Platypus.poolInterface.encodeFunctionData('swap', [
475
475
  srcToken,
@@ -477,7 +477,7 @@ export class Platypus extends SimpleExchange implements IDex<PlatypusData> {
477
477
  srcAmount,
478
478
  1,
479
479
  this.augustusAddress,
480
- this.getLocalDeadlineAsFriendlyPlaceholder(),
480
+ this.getDeadline(),
481
481
  ]),
482
482
  data.pool,
483
483
  );
package/src/dex/shell.ts CHANGED
@@ -4,6 +4,7 @@ import { AdapterExchangeParam, Address, SimpleExchangeParam } from '../types';
4
4
  import { IDexTxBuilder } from './idex';
5
5
  import { SimpleExchange } from './simple-exchange';
6
6
  import ShellABI from '../abi/Shell.json';
7
+ import Web3 from 'web3';
7
8
  import { IDexHelper } from '../dex-helper';
8
9
 
9
10
  export type ShellData = {
@@ -15,7 +16,7 @@ type ShellParam = [
15
16
  _target: string,
16
17
  _originAmount: string,
17
18
  _minTargetAmount: string,
18
- _deadline: string,
19
+ _deadline?: number,
19
20
  ];
20
21
  enum ShellFunctions {
21
22
  originSwap = 'originSwap',
@@ -62,7 +63,7 @@ export class Shell
62
63
  destToken,
63
64
  srcAmount,
64
65
  destAmount,
65
- this.getLocalDeadlineAsFriendlyPlaceholder(),
66
+ data.deadline || this.getDeadline(),
66
67
  ];
67
68
  const swapData = this.exchangeRouterInterface.encodeFunctionData(
68
69
  swapFunction,
@@ -123,14 +123,7 @@ export class SimpleExchange {
123
123
  };
124
124
  }
125
125
 
126
- /*
127
- * Context: Augustus routers have all a deadline protection logic implemented globally.
128
- * But some integrations (router, pools,...) require passing a deadline generally as uint256.
129
- * While this problem can be solved in adapters easily by passing block.timestamp (or block.timestamp +1 for some marginal cases),
130
- * In the context of direct calls like simpleSwap we have to generate this value offchain.
131
- * One can naively pick type(uint).max but that would impose a higher gas cost on the calldata.
132
- * Here we decide to go with a high enough default so that the local deadline rarely supersedes the global router deadline.
133
- */
134
- getLocalDeadlineAsFriendlyPlaceholder = () =>
135
- String(Math.floor(new Date().getTime() / 1000) + 7 * 24 * 60 * 60);
126
+ getDeadline() {
127
+ return Math.floor(new Date().getTime() / 1000) + 60 * 60;
128
+ }
136
129
  }
@@ -29,7 +29,7 @@ type TraderJoeV2RouterBuyParams = [
29
29
  _pairBinSteps: NumberAsString[],
30
30
  _tokenPath: Address[],
31
31
  to: Address,
32
- _deadline: string,
32
+ _deadline: number,
33
33
  ];
34
34
 
35
35
  type TraderJoeV2RouterParam =
@@ -37,6 +37,7 @@ type TraderJoeV2RouterParam =
37
37
  | TraderJoeV2RouterBuyParams;
38
38
 
39
39
  export type TraderJoeV2Data = {
40
+ deadline?: number;
40
41
  tokenIn: string; // redundant
41
42
  tokenOut: string; // redundant
42
43
  binStep: string;
@@ -86,7 +87,7 @@ export class TraderJoeV2
86
87
  {
87
88
  _pairBinSteps: [data.binStep],
88
89
  _tokenPath: [data.tokenIn, data.tokenOut], // FIXME: redundant, shoot & read from contract
89
- _deadline: this.getLocalDeadlineAsFriendlyPlaceholder(), // FIXME: more gas efficient to pass block.timestamp in adapter
90
+ _deadline: data.deadline || this.getDeadline(),
90
91
  },
91
92
  );
92
93
 
@@ -118,7 +119,7 @@ export class TraderJoeV2
118
119
  [data.binStep],
119
120
  [srcToken, destToken],
120
121
  this.augustusAddress,
121
- this.getLocalDeadlineAsFriendlyPlaceholder(),
122
+ data.deadline || this.getDeadline(),
122
123
  ]
123
124
  : [
124
125
  destAmount,
@@ -126,7 +127,7 @@ export class TraderJoeV2
126
127
  [data.binStep],
127
128
  [srcToken, destToken],
128
129
  this.augustusAddress,
129
- this.getLocalDeadlineAsFriendlyPlaceholder(),
130
+ data.deadline || this.getDeadline(),
130
131
  ];
131
132
  const swapData = this.exchangeRouterInterface.encodeFunctionData(
132
133
  swapFunction,
@@ -72,7 +72,7 @@ export type DexParams = {
72
72
  export type UniswapV3SellParam = {
73
73
  path: string;
74
74
  recipient: Address;
75
- deadline: string;
75
+ deadline: number;
76
76
  amountIn: NumberAsString;
77
77
  amountOutMinimum: NumberAsString;
78
78
  };
@@ -80,7 +80,7 @@ export type UniswapV3SellParam = {
80
80
  export type UniswapV3BuyParam = {
81
81
  path: string;
82
82
  recipient: Address;
83
- deadline: string;
83
+ deadline: number;
84
84
  amountOut: NumberAsString;
85
85
  amountInMaximum: NumberAsString;
86
86
  };
@@ -686,7 +686,7 @@ export class UniswapV3
686
686
  },
687
687
  {
688
688
  path,
689
- deadline: this.getLocalDeadlineAsFriendlyPlaceholder(), // FIXME: more gas efficient to pass block.timestamp in adapter
689
+ deadline: this.getDeadline(),
690
690
  },
691
691
  );
692
692
 
@@ -740,14 +740,14 @@ export class UniswapV3
740
740
  side === SwapSide.SELL
741
741
  ? {
742
742
  recipient: this.augustusAddress,
743
- deadline: this.getLocalDeadlineAsFriendlyPlaceholder(),
743
+ deadline: this.getDeadline(),
744
744
  amountIn: srcAmount,
745
745
  amountOutMinimum: destAmount,
746
746
  path,
747
747
  }
748
748
  : {
749
749
  recipient: this.augustusAddress,
750
- deadline: this.getLocalDeadlineAsFriendlyPlaceholder(),
750
+ deadline: this.getDeadline(),
751
751
  amountOut: destAmount,
752
752
  amountInMaximum: srcAmount,
753
753
  path,
@@ -17,6 +17,7 @@ const UNISWAP_V3_ROUTER_ADDRESSES: { [network: number]: Address } = {
17
17
 
18
18
  export type UniswapV3Data = {
19
19
  // ExactInputSingleParams
20
+ deadline?: number;
20
21
  path: {
21
22
  tokenIn: Address;
22
23
  tokenOut: Address;
@@ -27,7 +28,7 @@ export type UniswapV3Data = {
27
28
  type UniswapV3SellParam = {
28
29
  path: string;
29
30
  recipient: Address;
30
- deadline: string;
31
+ deadline: number;
31
32
  amountIn: NumberAsString;
32
33
  amountOutMinimum: NumberAsString;
33
34
  };
@@ -35,7 +36,7 @@ type UniswapV3SellParam = {
35
36
  type UniswapV3BuyParam = {
36
37
  path: string;
37
38
  recipient: Address;
38
- deadline: string;
39
+ deadline: number;
39
40
  amountOut: NumberAsString;
40
41
  amountInMaximum: NumberAsString;
41
42
  };
@@ -111,7 +112,7 @@ export class UniswapV3
111
112
  data: UniswapV3Data,
112
113
  side: SwapSide,
113
114
  ): AdapterExchangeParam {
114
- const { path: rawPath } = data;
115
+ const { deadline, path: rawPath } = data;
115
116
  const path = this.encodePath(rawPath, side);
116
117
  const payload = this.abiCoder.encodeParameter(
117
118
  {
@@ -122,14 +123,14 @@ export class UniswapV3
122
123
  },
123
124
  {
124
125
  path,
125
- deadline: this.getLocalDeadlineAsFriendlyPlaceholder(), // FIXME: more gas efficient to pass block.timestamp in adapter
126
+ deadline: deadline || this.getDeadline(),
126
127
  },
127
128
  );
128
129
 
129
130
  return {
130
131
  targetExchange: this.routerAddress,
131
132
  payload,
132
- networkFee: '0',
133
+ networkFee: '0', // warning
133
134
  };
134
135
  }
135
136
 
@@ -150,14 +151,14 @@ export class UniswapV3
150
151
  side === SwapSide.SELL
151
152
  ? {
152
153
  recipient: this.augustusAddress,
153
- deadline: this.getLocalDeadlineAsFriendlyPlaceholder(),
154
+ deadline: data.deadline || this.getDeadline(),
154
155
  amountIn: srcAmount,
155
156
  amountOutMinimum: destAmount,
156
157
  path,
157
158
  }
158
159
  : {
159
160
  recipient: this.augustusAddress,
160
- deadline: this.getLocalDeadlineAsFriendlyPlaceholder(),
161
+ deadline: data.deadline || this.getDeadline(),
161
162
  amountOut: destAmount,
162
163
  amountInMaximum: srcAmount,
163
164
  path,
@@ -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.debug(
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]}`,
@@ -46,6 +46,8 @@ export const Tokens: {
46
46
  USDT: {
47
47
  address: '0xdac17f958d2ee523a2206206994597c13d831ec7',
48
48
  decimals: 6,
49
+ addBalance: balancesFn,
50
+ addAllowance: allowedFn,
49
51
  },
50
52
  STETH: {
51
53
  address: '0xae7ab96520de3a18e5e111b5eaab095312d7fe84',