@paraswap/dex-lib 3.8.21 → 3.8.22-infusion

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.
@@ -0,0 +1,442 @@
1
+ [
2
+ {
3
+ "inputs": [
4
+ { "internalType": "address", "name": "_factory", "type": "address" },
5
+ {
6
+ "internalType": "contract ILockFactory",
7
+ "name": "_lockFactory",
8
+ "type": "address"
9
+ },
10
+ { "internalType": "address", "name": "_weth", "type": "address" }
11
+ ],
12
+ "stateMutability": "nonpayable",
13
+ "type": "constructor"
14
+ },
15
+ {
16
+ "inputs": [
17
+ { "internalType": "address", "name": "target", "type": "address" }
18
+ ],
19
+ "name": "AddressEmptyCode",
20
+ "type": "error"
21
+ },
22
+ {
23
+ "inputs": [
24
+ { "internalType": "address", "name": "account", "type": "address" }
25
+ ],
26
+ "name": "AddressInsufficientBalance",
27
+ "type": "error"
28
+ },
29
+ { "inputs": [], "name": "FailedInnerCall", "type": "error" },
30
+ {
31
+ "inputs": [
32
+ { "internalType": "address", "name": "token", "type": "address" }
33
+ ],
34
+ "name": "SafeERC20FailedOperation",
35
+ "type": "error"
36
+ },
37
+ {
38
+ "inputs": [
39
+ { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" },
40
+ {
41
+ "components": [
42
+ { "internalType": "address", "name": "from", "type": "address" },
43
+ { "internalType": "address", "name": "to", "type": "address" },
44
+ { "internalType": "bool", "name": "stable", "type": "bool" }
45
+ ],
46
+ "internalType": "struct Router.route[]",
47
+ "name": "routes",
48
+ "type": "tuple[]"
49
+ },
50
+ { "internalType": "address", "name": "to", "type": "address" },
51
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" }
52
+ ],
53
+ "name": "UNSAFE_swapExactTokensForTokens",
54
+ "outputs": [
55
+ { "internalType": "uint256[]", "name": "", "type": "uint256[]" }
56
+ ],
57
+ "stateMutability": "nonpayable",
58
+ "type": "function"
59
+ },
60
+ {
61
+ "inputs": [
62
+ { "internalType": "address", "name": "tokenA", "type": "address" },
63
+ { "internalType": "address", "name": "tokenB", "type": "address" },
64
+ {
65
+ "internalType": "uint256",
66
+ "name": "amountADesired",
67
+ "type": "uint256"
68
+ },
69
+ {
70
+ "internalType": "uint256",
71
+ "name": "amountBDesired",
72
+ "type": "uint256"
73
+ },
74
+ { "internalType": "uint256", "name": "amountAMin", "type": "uint256" },
75
+ { "internalType": "uint256", "name": "amountBMin", "type": "uint256" },
76
+ { "internalType": "address", "name": "to", "type": "address" },
77
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" },
78
+ { "internalType": "bool", "name": "stable", "type": "bool" },
79
+ { "internalType": "uint256", "name": "lockerFeesP", "type": "uint256" }
80
+ ],
81
+ "name": "addLiquidity",
82
+ "outputs": [
83
+ { "internalType": "uint256", "name": "amountA", "type": "uint256" },
84
+ { "internalType": "uint256", "name": "amountB", "type": "uint256" },
85
+ { "internalType": "uint256", "name": "liquidity", "type": "uint256" }
86
+ ],
87
+ "stateMutability": "nonpayable",
88
+ "type": "function"
89
+ },
90
+ {
91
+ "inputs": [
92
+ { "internalType": "address", "name": "token", "type": "address" },
93
+ {
94
+ "internalType": "uint256",
95
+ "name": "amountTokenDesired",
96
+ "type": "uint256"
97
+ },
98
+ {
99
+ "internalType": "uint256",
100
+ "name": "amountTokenMin",
101
+ "type": "uint256"
102
+ },
103
+ { "internalType": "uint256", "name": "amountETHMin", "type": "uint256" },
104
+ { "internalType": "address", "name": "to", "type": "address" },
105
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" },
106
+ { "internalType": "bool", "name": "stable", "type": "bool" },
107
+ { "internalType": "uint256", "name": "lockerFeesP", "type": "uint256" }
108
+ ],
109
+ "name": "addLiquidityETH",
110
+ "outputs": [
111
+ { "internalType": "uint256", "name": "amountToken", "type": "uint256" },
112
+ { "internalType": "uint256", "name": "amountETH", "type": "uint256" },
113
+ { "internalType": "uint256", "name": "liquidity", "type": "uint256" }
114
+ ],
115
+ "stateMutability": "payable",
116
+ "type": "function"
117
+ },
118
+ {
119
+ "inputs": [],
120
+ "name": "factory",
121
+ "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
122
+ "stateMutability": "view",
123
+ "type": "function"
124
+ },
125
+ {
126
+ "inputs": [
127
+ { "internalType": "uint256", "name": "amountIn", "type": "uint256" },
128
+ { "internalType": "address", "name": "tokenIn", "type": "address" },
129
+ { "internalType": "address", "name": "tokenOut", "type": "address" }
130
+ ],
131
+ "name": "getAmountOut",
132
+ "outputs": [
133
+ { "internalType": "uint256", "name": "amount", "type": "uint256" },
134
+ { "internalType": "bool", "name": "stable", "type": "bool" }
135
+ ],
136
+ "stateMutability": "view",
137
+ "type": "function"
138
+ },
139
+ {
140
+ "inputs": [
141
+ { "internalType": "uint256", "name": "amountIn", "type": "uint256" },
142
+ {
143
+ "components": [
144
+ { "internalType": "address", "name": "from", "type": "address" },
145
+ { "internalType": "address", "name": "to", "type": "address" },
146
+ { "internalType": "bool", "name": "stable", "type": "bool" }
147
+ ],
148
+ "internalType": "struct Router.route[]",
149
+ "name": "routes",
150
+ "type": "tuple[]"
151
+ }
152
+ ],
153
+ "name": "getAmountsOut",
154
+ "outputs": [
155
+ { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }
156
+ ],
157
+ "stateMutability": "view",
158
+ "type": "function"
159
+ },
160
+ {
161
+ "inputs": [
162
+ { "internalType": "address", "name": "tokenA", "type": "address" },
163
+ { "internalType": "address", "name": "tokenB", "type": "address" },
164
+ { "internalType": "bool", "name": "stable", "type": "bool" }
165
+ ],
166
+ "name": "getReserves",
167
+ "outputs": [
168
+ { "internalType": "uint256", "name": "reserveA", "type": "uint256" },
169
+ { "internalType": "uint256", "name": "reserveB", "type": "uint256" }
170
+ ],
171
+ "stateMutability": "view",
172
+ "type": "function"
173
+ },
174
+ {
175
+ "inputs": [
176
+ { "internalType": "address", "name": "pair", "type": "address" }
177
+ ],
178
+ "name": "isPair",
179
+ "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],
180
+ "stateMutability": "view",
181
+ "type": "function"
182
+ },
183
+ {
184
+ "inputs": [],
185
+ "name": "lockFactory",
186
+ "outputs": [
187
+ { "internalType": "contract ILockFactory", "name": "", "type": "address" }
188
+ ],
189
+ "stateMutability": "view",
190
+ "type": "function"
191
+ },
192
+ {
193
+ "inputs": [
194
+ { "internalType": "address", "name": "tokenA", "type": "address" },
195
+ { "internalType": "address", "name": "tokenB", "type": "address" },
196
+ { "internalType": "bool", "name": "stable", "type": "bool" }
197
+ ],
198
+ "name": "pairFor",
199
+ "outputs": [
200
+ { "internalType": "address", "name": "pair", "type": "address" }
201
+ ],
202
+ "stateMutability": "view",
203
+ "type": "function"
204
+ },
205
+ {
206
+ "inputs": [
207
+ { "internalType": "address", "name": "tokenA", "type": "address" },
208
+ { "internalType": "address", "name": "tokenB", "type": "address" },
209
+ { "internalType": "bool", "name": "stable", "type": "bool" },
210
+ {
211
+ "internalType": "uint256",
212
+ "name": "amountADesired",
213
+ "type": "uint256"
214
+ },
215
+ { "internalType": "uint256", "name": "amountBDesired", "type": "uint256" }
216
+ ],
217
+ "name": "quoteAddLiquidity",
218
+ "outputs": [
219
+ { "internalType": "uint256", "name": "amountA", "type": "uint256" },
220
+ { "internalType": "uint256", "name": "amountB", "type": "uint256" },
221
+ { "internalType": "uint256", "name": "liquidity", "type": "uint256" }
222
+ ],
223
+ "stateMutability": "view",
224
+ "type": "function"
225
+ },
226
+ {
227
+ "inputs": [
228
+ { "internalType": "address", "name": "tokenA", "type": "address" },
229
+ { "internalType": "address", "name": "tokenB", "type": "address" },
230
+ { "internalType": "bool", "name": "stable", "type": "bool" },
231
+ { "internalType": "uint256", "name": "liquidity", "type": "uint256" }
232
+ ],
233
+ "name": "quoteRemoveLiquidity",
234
+ "outputs": [
235
+ { "internalType": "uint256", "name": "amountA", "type": "uint256" },
236
+ { "internalType": "uint256", "name": "amountB", "type": "uint256" }
237
+ ],
238
+ "stateMutability": "view",
239
+ "type": "function"
240
+ },
241
+ {
242
+ "inputs": [
243
+ { "internalType": "address", "name": "tokenA", "type": "address" },
244
+ { "internalType": "address", "name": "tokenB", "type": "address" },
245
+ { "internalType": "bool", "name": "stable", "type": "bool" },
246
+ { "internalType": "uint256", "name": "liquidity", "type": "uint256" },
247
+ { "internalType": "uint256", "name": "amountAMin", "type": "uint256" },
248
+ { "internalType": "uint256", "name": "amountBMin", "type": "uint256" },
249
+ { "internalType": "address", "name": "to", "type": "address" },
250
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" }
251
+ ],
252
+ "name": "removeLiquidity",
253
+ "outputs": [
254
+ { "internalType": "uint256", "name": "amountA", "type": "uint256" },
255
+ { "internalType": "uint256", "name": "amountB", "type": "uint256" }
256
+ ],
257
+ "stateMutability": "nonpayable",
258
+ "type": "function"
259
+ },
260
+ {
261
+ "inputs": [
262
+ { "internalType": "address", "name": "token", "type": "address" },
263
+ { "internalType": "bool", "name": "stable", "type": "bool" },
264
+ { "internalType": "uint256", "name": "liquidity", "type": "uint256" },
265
+ {
266
+ "internalType": "uint256",
267
+ "name": "amountTokenMin",
268
+ "type": "uint256"
269
+ },
270
+ { "internalType": "uint256", "name": "amountETHMin", "type": "uint256" },
271
+ { "internalType": "address", "name": "to", "type": "address" },
272
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" }
273
+ ],
274
+ "name": "removeLiquidityETH",
275
+ "outputs": [
276
+ { "internalType": "uint256", "name": "amountToken", "type": "uint256" },
277
+ { "internalType": "uint256", "name": "amountETH", "type": "uint256" }
278
+ ],
279
+ "stateMutability": "nonpayable",
280
+ "type": "function"
281
+ },
282
+ {
283
+ "inputs": [
284
+ { "internalType": "address", "name": "token", "type": "address" },
285
+ { "internalType": "bool", "name": "stable", "type": "bool" },
286
+ { "internalType": "uint256", "name": "liquidity", "type": "uint256" },
287
+ {
288
+ "internalType": "uint256",
289
+ "name": "amountTokenMin",
290
+ "type": "uint256"
291
+ },
292
+ { "internalType": "uint256", "name": "amountETHMin", "type": "uint256" },
293
+ { "internalType": "address", "name": "to", "type": "address" },
294
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" },
295
+ { "internalType": "bool", "name": "approveMax", "type": "bool" },
296
+ { "internalType": "uint8", "name": "v", "type": "uint8" },
297
+ { "internalType": "bytes32", "name": "r", "type": "bytes32" },
298
+ { "internalType": "bytes32", "name": "s", "type": "bytes32" }
299
+ ],
300
+ "name": "removeLiquidityETHWithPermit",
301
+ "outputs": [
302
+ { "internalType": "uint256", "name": "amountToken", "type": "uint256" },
303
+ { "internalType": "uint256", "name": "amountETH", "type": "uint256" }
304
+ ],
305
+ "stateMutability": "nonpayable",
306
+ "type": "function"
307
+ },
308
+ {
309
+ "inputs": [
310
+ { "internalType": "address", "name": "tokenA", "type": "address" },
311
+ { "internalType": "address", "name": "tokenB", "type": "address" },
312
+ { "internalType": "bool", "name": "stable", "type": "bool" },
313
+ { "internalType": "uint256", "name": "liquidity", "type": "uint256" },
314
+ { "internalType": "uint256", "name": "amountAMin", "type": "uint256" },
315
+ { "internalType": "uint256", "name": "amountBMin", "type": "uint256" },
316
+ { "internalType": "address", "name": "to", "type": "address" },
317
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" },
318
+ { "internalType": "bool", "name": "approveMax", "type": "bool" },
319
+ { "internalType": "uint8", "name": "v", "type": "uint8" },
320
+ { "internalType": "bytes32", "name": "r", "type": "bytes32" },
321
+ { "internalType": "bytes32", "name": "s", "type": "bytes32" }
322
+ ],
323
+ "name": "removeLiquidityWithPermit",
324
+ "outputs": [
325
+ { "internalType": "uint256", "name": "amountA", "type": "uint256" },
326
+ { "internalType": "uint256", "name": "amountB", "type": "uint256" }
327
+ ],
328
+ "stateMutability": "nonpayable",
329
+ "type": "function"
330
+ },
331
+ {
332
+ "inputs": [
333
+ { "internalType": "address", "name": "tokenA", "type": "address" },
334
+ { "internalType": "address", "name": "tokenB", "type": "address" }
335
+ ],
336
+ "name": "sortTokens",
337
+ "outputs": [
338
+ { "internalType": "address", "name": "token0", "type": "address" },
339
+ { "internalType": "address", "name": "token1", "type": "address" }
340
+ ],
341
+ "stateMutability": "pure",
342
+ "type": "function"
343
+ },
344
+ {
345
+ "inputs": [
346
+ { "internalType": "uint256", "name": "amountOutMin", "type": "uint256" },
347
+ {
348
+ "components": [
349
+ { "internalType": "address", "name": "from", "type": "address" },
350
+ { "internalType": "address", "name": "to", "type": "address" },
351
+ { "internalType": "bool", "name": "stable", "type": "bool" }
352
+ ],
353
+ "internalType": "struct Router.route[]",
354
+ "name": "routes",
355
+ "type": "tuple[]"
356
+ },
357
+ { "internalType": "address", "name": "to", "type": "address" },
358
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" }
359
+ ],
360
+ "name": "swapExactETHForTokens",
361
+ "outputs": [
362
+ { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }
363
+ ],
364
+ "stateMutability": "payable",
365
+ "type": "function"
366
+ },
367
+ {
368
+ "inputs": [
369
+ { "internalType": "uint256", "name": "amountIn", "type": "uint256" },
370
+ { "internalType": "uint256", "name": "amountOutMin", "type": "uint256" },
371
+ {
372
+ "components": [
373
+ { "internalType": "address", "name": "from", "type": "address" },
374
+ { "internalType": "address", "name": "to", "type": "address" },
375
+ { "internalType": "bool", "name": "stable", "type": "bool" }
376
+ ],
377
+ "internalType": "struct Router.route[]",
378
+ "name": "routes",
379
+ "type": "tuple[]"
380
+ },
381
+ { "internalType": "address", "name": "to", "type": "address" },
382
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" }
383
+ ],
384
+ "name": "swapExactTokensForETH",
385
+ "outputs": [
386
+ { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }
387
+ ],
388
+ "stateMutability": "nonpayable",
389
+ "type": "function"
390
+ },
391
+ {
392
+ "inputs": [
393
+ { "internalType": "uint256", "name": "amountIn", "type": "uint256" },
394
+ { "internalType": "uint256", "name": "amountOutMin", "type": "uint256" },
395
+ {
396
+ "components": [
397
+ { "internalType": "address", "name": "from", "type": "address" },
398
+ { "internalType": "address", "name": "to", "type": "address" },
399
+ { "internalType": "bool", "name": "stable", "type": "bool" }
400
+ ],
401
+ "internalType": "struct Router.route[]",
402
+ "name": "routes",
403
+ "type": "tuple[]"
404
+ },
405
+ { "internalType": "address", "name": "to", "type": "address" },
406
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" }
407
+ ],
408
+ "name": "swapExactTokensForTokens",
409
+ "outputs": [
410
+ { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }
411
+ ],
412
+ "stateMutability": "nonpayable",
413
+ "type": "function"
414
+ },
415
+ {
416
+ "inputs": [
417
+ { "internalType": "uint256", "name": "amountIn", "type": "uint256" },
418
+ { "internalType": "uint256", "name": "amountOutMin", "type": "uint256" },
419
+ { "internalType": "address", "name": "tokenFrom", "type": "address" },
420
+ { "internalType": "address", "name": "tokenTo", "type": "address" },
421
+ { "internalType": "bool", "name": "stable", "type": "bool" },
422
+ { "internalType": "address", "name": "to", "type": "address" },
423
+ { "internalType": "uint256", "name": "deadline", "type": "uint256" }
424
+ ],
425
+ "name": "swapExactTokensForTokensSimple",
426
+ "outputs": [
427
+ { "internalType": "uint256[]", "name": "amounts", "type": "uint256[]" }
428
+ ],
429
+ "stateMutability": "nonpayable",
430
+ "type": "function"
431
+ },
432
+ {
433
+ "inputs": [],
434
+ "name": "weth",
435
+ "outputs": [
436
+ { "internalType": "contract IWETH", "name": "", "type": "address" }
437
+ ],
438
+ "stateMutability": "view",
439
+ "type": "function"
440
+ },
441
+ { "stateMutability": "payable", "type": "receive" }
442
+ ]
package/src/dex/index.ts CHANGED
@@ -60,6 +60,7 @@ import { GenericRFQ } from './generic-rfq/generic-rfq';
60
60
  import { WstETH } from './wsteth/wsteth';
61
61
  import { Camelot } from './camelot/camelot';
62
62
  import { Hashflow } from './hashflow/hashflow';
63
+ import { Infusion } from './infusion/infusion';
63
64
  import { SolidlyEthereum } from './solidly/solidly-ethereum';
64
65
  import { MaverickV1 } from './maverick-v1/maverick-v1';
65
66
  import { MaverickV2 } from './maverick-v2/maverick-v2';
@@ -148,6 +149,7 @@ const Dexes = [
148
149
  CurveV1StableNg,
149
150
  WstETH,
150
151
  Hashflow,
152
+ Infusion,
151
153
  MaverickV1,
152
154
  MaverickV2,
153
155
  Camelot,
@@ -0,0 +1,27 @@
1
+ import { DexParams } from './types';
2
+ import { DexConfigMap, AdapterMappings } from '../../types';
3
+ import { Network, SwapSide } from '../../constants';
4
+
5
+ export const InfusionConfig: DexConfigMap<DexParams> = {
6
+ Infusion: {
7
+ [Network.BASE]: {
8
+ subgraphURL:
9
+ 'https://api.goldsky.com/api/public/project_clvn0ei0x2qro0130fpihh83o/subgraphs/infusion-subgraph/1.0.0/gn',
10
+ factoryAddress: '0x2D9A3a2bd6400eE28d770c7254cA840c82faf23f',
11
+ router: '0x1E891C9F96DcA29Da8B97bE3403D16135EBe8028',
12
+ initCode:
13
+ '0xc1ac28b1c4ebe53c0cff67bab5878c4eb68759bb1e9f73977cd266b247d149f0',
14
+ // updatable fees on the factory without event
15
+ stableFee: 2,
16
+ volatileFee: 2,
17
+ poolGasCost: 180 * 1000,
18
+ feeCode: 2,
19
+ },
20
+ },
21
+ };
22
+
23
+ export const Adapters: Record<number, AdapterMappings> = {
24
+ [Network.BASE]: {
25
+ [SwapSide.SELL]: [{ name: 'BaseAdapter01', index: 6 }], // velodrome
26
+ },
27
+ };
@@ -0,0 +1,110 @@
1
+ /* eslint-disable no-console */
2
+ import dotenv from 'dotenv';
3
+ dotenv.config();
4
+
5
+ import { testE2E } from '../../../tests/utils-e2e';
6
+ import {
7
+ Tokens,
8
+ Holders,
9
+ NativeTokenSymbols,
10
+ } from '../../../tests/constants-e2e';
11
+ import { Network, ContractMethod, SwapSide } from '../../constants';
12
+ import { StaticJsonRpcProvider } from '@ethersproject/providers';
13
+ import { generateConfig } from '../../config';
14
+
15
+ describe('Infusion E2E', () => {
16
+ describe('Base', () => {
17
+ const network = Network.BASE;
18
+ const tokens = Tokens[network];
19
+ const holders = Holders[network];
20
+ const provider = new StaticJsonRpcProvider(
21
+ generateConfig(network).privateHttpProvider,
22
+ network,
23
+ );
24
+
25
+ describe('Infusion', () => {
26
+ const dexKey = 'Infusion';
27
+
28
+ describe('swapExactAmountIn', () => {
29
+ it('ETH -> USDC', async () => {
30
+ await testE2E(
31
+ tokens.ETH,
32
+ tokens.USDC,
33
+ holders.ETH,
34
+ '3000000000000000000',
35
+ SwapSide.SELL,
36
+ dexKey,
37
+ ContractMethod.swapExactAmountIn,
38
+ network,
39
+ provider,
40
+ );
41
+ });
42
+ it('USDC -> ETH', async () => {
43
+ await testE2E(
44
+ tokens.USDC,
45
+ tokens.ETH,
46
+ holders.USDC,
47
+ '9900000000',
48
+ SwapSide.SELL,
49
+ dexKey,
50
+ ContractMethod.swapExactAmountIn,
51
+ network,
52
+ provider,
53
+ );
54
+ });
55
+ it('WETH -> USDC', async () => {
56
+ await testE2E(
57
+ tokens.WETH,
58
+ tokens.USDC,
59
+ holders.WETH,
60
+ '3000000000000000000',
61
+ SwapSide.SELL,
62
+ dexKey,
63
+ ContractMethod.swapExactAmountIn,
64
+ network,
65
+ provider,
66
+ );
67
+ });
68
+ it('USDC -> WETH', async () => {
69
+ await testE2E(
70
+ tokens.USDC,
71
+ tokens.WETH,
72
+ holders.USDC,
73
+ '3000000',
74
+ SwapSide.SELL,
75
+ dexKey,
76
+ ContractMethod.swapExactAmountIn,
77
+ network,
78
+ provider,
79
+ );
80
+ });
81
+ it('USDbC -> USDC', async () => {
82
+ await testE2E(
83
+ tokens.USDbC,
84
+ tokens.USDC,
85
+ holders.USDbC,
86
+ '9900000000',
87
+ SwapSide.SELL,
88
+ dexKey,
89
+ ContractMethod.swapExactAmountIn,
90
+ network,
91
+ provider,
92
+ );
93
+ });
94
+ it('USDC -> USDbC', async () => {
95
+ await testE2E(
96
+ tokens.USDC,
97
+ tokens.USDbC,
98
+ holders.USDC,
99
+ '9900000000',
100
+ SwapSide.SELL,
101
+ dexKey,
102
+ ContractMethod.swapExactAmountIn,
103
+ network,
104
+ provider,
105
+ );
106
+ });
107
+ });
108
+ });
109
+ });
110
+ });