@paraswap/dex-lib 3.8.35 → 3.8.36-usual

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/src/dex/index.ts CHANGED
@@ -88,6 +88,7 @@ import { ConcentratorArusd } from './concentrator-arusd/concentrator-arusd';
88
88
  import { FxProtocolRusd } from './fx-protocol-rusd/fx-protocol-rusd';
89
89
  import { AaveGsm } from './aave-gsm/aave-gsm';
90
90
  import { LitePsm } from './lite-psm/lite-psm';
91
+ import { UsualBond } from './usual-bond/usual-bond';
91
92
  import { StkGHO } from './stkgho/stkgho';
92
93
  import { SkyConverter } from './sky-converter/sky-converter';
93
94
 
@@ -173,6 +174,7 @@ const Dexes = [
173
174
  FxProtocolRusd,
174
175
  AaveGsm,
175
176
  LitePsm,
177
+ UsualBond,
176
178
  StkGHO,
177
179
  SkyConverter,
178
180
  ];
@@ -10,6 +10,11 @@ export const LitePsmConfig: DexConfigMap<DexParams> = {
10
10
  address: '0x6b175474e89094c44da98b954eedeac495271d0f',
11
11
  decimals: 18,
12
12
  },
13
+ usds: {
14
+ address: '0xdc035d45d973e3ec169d2276ddab16f1e407384f',
15
+ decimals: 18,
16
+ },
17
+ usdsPsmAddress: '0xA188EEC8F81263234dA3622A406892F3D630f98c',
13
18
  vatAddress: '0x35d1b3f3d7966a1dfe207aa4514c12a259a0492b',
14
19
  pools: [
15
20
  {
@@ -17,7 +22,6 @@ export const LitePsmConfig: DexConfigMap<DexParams> = {
17
22
  address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
18
23
  decimals: 6,
19
24
  },
20
- gemJoinAddress: '0xf6e72db5454dd049d0788e411b06cfaf16853042', // Same as psmAddress. LitePsm does not have an external gem join.
21
25
  pocketAddress: '0x37305b1cd40574e4c5ce33f8e8306be057fd7341',
22
26
  psmAddress: '0xf6e72db5454dd049d0788e411b06cfaf16853042',
23
27
  identifier:
@@ -10,7 +10,7 @@ import { generateConfig } from '../../config';
10
10
  describe('LitePsm E2E', () => {
11
11
  const dexKey = 'LitePsm';
12
12
 
13
- describe('LitePsm MAINNET_V6', () => {
13
+ describe('LitePsm DAI', () => {
14
14
  const network = Network.MAINNET;
15
15
  const tokens = Tokens[network];
16
16
  const holders = Holders[network];
@@ -76,4 +76,71 @@ describe('LitePsm E2E', () => {
76
76
  }),
77
77
  );
78
78
  });
79
+
80
+ describe('LitePsm USDS', () => {
81
+ const network = Network.MAINNET;
82
+ const tokens = Tokens[network];
83
+ const holders = Holders[network];
84
+ const provider = new StaticJsonRpcProvider(
85
+ generateConfig(network).privateHttpProvider,
86
+ network,
87
+ );
88
+
89
+ const tokenASymbol: string = 'USDC';
90
+ const tokenBSymbol: string = 'USDS';
91
+
92
+ const tokenAAmount: string = '10000000';
93
+ const tokenBAmount: string = '10000000000000000';
94
+
95
+ const sideToContractMethods = new Map([
96
+ [
97
+ SwapSide.SELL,
98
+ [
99
+ ContractMethod.swapExactAmountIn,
100
+ ContractMethod.swapExactAmountInOutOnMakerPSM,
101
+ ],
102
+ ],
103
+ [
104
+ SwapSide.BUY,
105
+ [
106
+ ContractMethod.swapExactAmountOut,
107
+ ContractMethod.swapExactAmountInOutOnMakerPSM,
108
+ ],
109
+ ],
110
+ ]);
111
+
112
+ sideToContractMethods.forEach((contractMethods, side) =>
113
+ contractMethods.forEach((contractMethod: ContractMethod) => {
114
+ describe(`${contractMethod}`, () => {
115
+ it(`${side}:${tokenASymbol} -> ${tokenBSymbol}`, async () => {
116
+ await testE2E(
117
+ tokens[tokenASymbol],
118
+ tokens[tokenBSymbol],
119
+ holders[tokenASymbol],
120
+ side === SwapSide.SELL ? tokenAAmount : tokenBAmount,
121
+ side,
122
+ dexKey,
123
+ contractMethod,
124
+ network,
125
+ provider,
126
+ );
127
+ });
128
+
129
+ it(`${side}:${tokenBSymbol} -> ${tokenASymbol}`, async () => {
130
+ await testE2E(
131
+ tokens[tokenBSymbol],
132
+ tokens[tokenASymbol],
133
+ holders[tokenBSymbol],
134
+ side === SwapSide.SELL ? tokenBAmount : tokenAAmount,
135
+ side,
136
+ dexKey,
137
+ contractMethod,
138
+ network,
139
+ provider,
140
+ );
141
+ });
142
+ });
143
+ }),
144
+ );
145
+ });
79
146
  });
@@ -4,9 +4,7 @@ import {
4
4
  Address,
5
5
  ExchangePrices,
6
6
  PoolPrices,
7
- Log,
8
7
  AdapterExchangeParam,
9
- SimpleExchangeParam,
10
8
  PoolLiquidity,
11
9
  Logger,
12
10
  NumberAsString,
@@ -32,7 +30,8 @@ import {
32
30
  } from './types';
33
31
  import { SimpleExchange } from '../simple-exchange';
34
32
  import { LitePsmConfig } from './config';
35
- import PsmABI from '../../abi/lite-psm/psm.json';
33
+ import DaiPsmABI from '../../abi/lite-psm/psm.json';
34
+ import UsdsPsmABI from '../../abi/lite-psm/usdsPsm.json';
36
35
  import { BI_POWS } from '../../bigint-constants';
37
36
  import { SpecialDex } from '../../executor/types';
38
37
  import { hexConcat, hexZeroPad, hexlify } from '@ethersproject/bytes';
@@ -45,7 +44,8 @@ import { BigNumber } from 'ethers';
45
44
  import { LitePsmEventPool, getOnChainState } from './lite-psm-event-pool';
46
45
  import { extractReturnAmountPosition } from '../../executor/utils';
47
46
 
48
- const psmInterface = new Interface(PsmABI);
47
+ const daiPsmInterface = new Interface(DaiPsmABI);
48
+ const usdsPsmInterface = new Interface(UsdsPsmABI);
49
49
  const WAD = BI_POWS[18];
50
50
 
51
51
  const ceilDiv = (a: bigint, b: bigint) => (a + b - 1n) / b;
@@ -70,6 +70,8 @@ export class LitePsm
70
70
  dexKey: string,
71
71
  protected dexHelper: IDexHelper,
72
72
  protected dai: Token = LitePsmConfig[dexKey][network].dai,
73
+ protected usds: Token = LitePsmConfig[dexKey][network].usds,
74
+ protected usdsPsm: Address = LitePsmConfig[dexKey][network].usdsPsmAddress,
73
75
  protected vatAddress: Address = LitePsmConfig[dexKey][network].vatAddress,
74
76
  protected poolConfigs: PoolConfig[] = LitePsmConfig[dexKey][network].pools,
75
77
  ) {
@@ -123,6 +125,8 @@ export class LitePsm
123
125
  return (
124
126
  (srcAddress === this.dai.address && this.eventPools[destAddress]) ||
125
127
  (destAddress === this.dai.address && this.eventPools[srcAddress]) ||
128
+ (srcAddress === this.usds.address && this.eventPools[destAddress]) ||
129
+ (destAddress === this.usds.address && this.eventPools[srcAddress]) ||
126
130
  null
127
131
  );
128
132
  }
@@ -153,7 +157,7 @@ export class LitePsm
153
157
  }
154
158
 
155
159
  computePrices(
156
- isSrcDai: boolean,
160
+ isDestGem: boolean,
157
161
  to18ConversionFactor: bigint,
158
162
  side: SwapSide,
159
163
  amounts: bigint[],
@@ -168,7 +172,7 @@ export class LitePsm
168
172
 
169
173
  return amounts.map(a => {
170
174
  if (side === SwapSide.SELL) {
171
- if (isSrcDai) {
175
+ if (isDestGem) {
172
176
  const gemAmt18 = (a * WAD) / (WAD + poolState.tout);
173
177
  if (buyGemCheck(gemAmt18)) return gemAmt18 / to18ConversionFactor;
174
178
  } else {
@@ -177,7 +181,7 @@ export class LitePsm
177
181
  return gemAmt18 - (gemAmt18 * poolState.tin) / WAD;
178
182
  }
179
183
  } else {
180
- if (isSrcDai) {
184
+ if (isDestGem) {
181
185
  const gemAmt18 = to18ConversionFactor * a;
182
186
  if (buyGemCheck(gemAmt18))
183
187
  return gemAmt18 + (gemAmt18 * poolState.tout) / WAD;
@@ -214,33 +218,39 @@ export class LitePsm
214
218
  (side === SwapSide.SELL ? srcToken : destToken).decimals,
215
219
  );
216
220
 
217
- const isSrcDai = srcToken.address.toLowerCase() === this.dai.address;
218
- const gem = isSrcDai ? destToken : srcToken;
221
+ const srcLower = srcToken.address.toLowerCase();
222
+ const isSrcDai = srcLower === this.dai.address;
223
+ const isDaiSwap =
224
+ isSrcDai || destToken.address.toLowerCase() === this.dai.address;
225
+
226
+ const isDestGem = isSrcDai || srcLower === this.usds.address;
227
+
228
+ const gem = isDestGem ? destToken : srcToken;
219
229
  const toll =
220
- (side === SwapSide.SELL && isSrcDai) ||
221
- (side === SwapSide.BUY && !isSrcDai)
230
+ (side === SwapSide.SELL && isDestGem) ||
231
+ (side === SwapSide.BUY && !isDestGem)
222
232
  ? poolState.tout
223
233
  : poolState.tin;
224
234
 
225
235
  const [unit, ...prices] = this.computePrices(
226
- isSrcDai,
236
+ isDestGem,
227
237
  eventPool.to18ConversionFactor,
228
238
  side,
229
239
  [unitVolume, ...amounts],
230
240
  poolState,
231
241
  );
232
242
 
243
+ const psm = isDaiSwap ? eventPool.poolConfig.psmAddress : this.usdsPsm;
233
244
  return [
234
245
  {
235
246
  prices,
236
247
  unit,
237
248
  data: {
238
249
  toll: toll.toString(),
239
- psmAddress: eventPool.poolConfig.psmAddress,
240
- gemJoinAddress: eventPool.poolConfig.gemJoinAddress,
250
+ psmAddress: psm,
241
251
  gemDecimals: gem.decimals,
242
252
  },
243
- poolAddresses: [eventPool.poolConfig.psmAddress],
253
+ poolAddresses: [psm],
244
254
  exchange: this.dexKey,
245
255
  gasCost: 50000,
246
256
  poolIdentifier,
@@ -270,10 +280,12 @@ export class LitePsm
270
280
  data: LitePsmData,
271
281
  side: SwapSide,
272
282
  ): { isGemSell: boolean; gemAmount: string } {
273
- const isSrcDai = srcToken.toLowerCase() === this.dai.address;
283
+ const isDestGem =
284
+ srcToken.toLowerCase() === this.dai.address ||
285
+ srcToken.toLowerCase() === this.usds.address;
274
286
  const to18ConversionFactor = getBigIntPow(18 - data.gemDecimals);
275
287
  if (side === SwapSide.SELL) {
276
- if (isSrcDai) {
288
+ if (isDestGem) {
277
289
  const gemAmt18 = (BigInt(srcAmount) * WAD) / (WAD + BigInt(data.toll));
278
290
  return {
279
291
  isGemSell: false,
@@ -283,7 +295,7 @@ export class LitePsm
283
295
  return { isGemSell: true, gemAmount: srcAmount };
284
296
  }
285
297
  } else {
286
- if (isSrcDai) {
298
+ if (isDestGem) {
287
299
  return { isGemSell: false, gemAmount: destAmount };
288
300
  } else {
289
301
  const gemAmt = ceilDiv(
@@ -338,9 +350,7 @@ export class LitePsm
338
350
  isApproved = await this.dexHelper.augustusApprovals.hasApproval(
339
351
  options.executionContractAddress,
340
352
  srcToken.address,
341
- srcToken.address.toLowerCase() === this.dai.address.toLowerCase()
342
- ? optimalSwapExchange.data.psmAddress
343
- : optimalSwapExchange.data.gemJoinAddress,
353
+ optimalSwapExchange.data.psmAddress,
344
354
  );
345
355
  }
346
356
 
@@ -370,10 +380,16 @@ export class LitePsm
370
380
  side,
371
381
  );
372
382
 
373
- let exchangeData = psmInterface.encodeFunctionData(
374
- isGemSell ? 'sellGem' : 'buyGem',
375
- [recipient, gemAmount],
376
- );
383
+ const isDaiSwap =
384
+ destToken.toLowerCase() === this.dai.address ||
385
+ srcToken.toLowerCase() === this.dai.address;
386
+
387
+ let exchangeData = (
388
+ isDaiSwap ? daiPsmInterface : usdsPsmInterface
389
+ ).encodeFunctionData(isGemSell ? 'sellGem' : 'buyGem', [
390
+ recipient,
391
+ gemAmount,
392
+ ]);
377
393
 
378
394
  // append toll and to18ConversionFactor & set specialDexFlag = SWAP_ON_MAKER_PSM to
379
395
  // - `buyGem` on Ex1 & Ex2
@@ -397,10 +413,14 @@ export class LitePsm
397
413
  exchangeData,
398
414
  targetExchange: data.psmAddress,
399
415
  specialDexFlag,
400
- spender: isGemSell ? data.gemJoinAddress : data.psmAddress,
416
+ spender: data.psmAddress, // psm is the join for both dai and usds
401
417
  returnAmountPos:
402
418
  side === SwapSide.SELL && isGemSell
403
- ? extractReturnAmountPosition(psmInterface, 'sellGem', 'daiOutWad')
419
+ ? extractReturnAmountPosition(
420
+ isDaiSwap ? daiPsmInterface : usdsPsmInterface,
421
+ 'sellGem',
422
+ isDaiSwap ? 'daiOutWad' : 'usdsOutWad',
423
+ )
404
424
  : undefined,
405
425
  };
406
426
  }
@@ -453,7 +473,7 @@ export class LitePsm
453
473
  data.toll,
454
474
  to18ConversionFactor.toString(),
455
475
  data.psmAddress,
456
- data.gemJoinAddress,
476
+ data.psmAddress,
457
477
  metadata,
458
478
  beneficiaryDirectionApproveFlag.toString(),
459
479
  ];
@@ -492,9 +512,10 @@ export class LitePsm
492
512
  );
493
513
  };
494
514
 
495
- const isDai = _tokenAddress === this.dai.address;
515
+ const isDaiOrUsds =
516
+ _tokenAddress === this.dai.address || _tokenAddress === this.usds.address;
496
517
 
497
- const validPoolConfigs = isDai
518
+ const validPoolConfigs = isDaiOrUsds
498
519
  ? this.poolConfigs
499
520
  : this.eventPools[_tokenAddress]
500
521
  ? [this.eventPools[_tokenAddress].poolConfig]
@@ -513,7 +534,7 @@ export class LitePsm
513
534
  exchange: this.dexKey,
514
535
  address: p.psmAddress,
515
536
  liquidityUSD: minLiq(poolStates[i], p.gem.decimals),
516
- connectorTokens: [isDai ? p.gem : this.dai],
537
+ connectorTokens: isDaiOrUsds ? [p.gem] : [this.dai, this.usds],
517
538
  }));
518
539
  }
519
540
  }
@@ -10,7 +10,6 @@ export type PoolState = {
10
10
 
11
11
  export type LitePsmData = {
12
12
  psmAddress: Address;
13
- gemJoinAddress: Address;
14
13
  gemDecimals: number;
15
14
  toll: string;
16
15
  isApproved?: boolean;
@@ -18,7 +17,6 @@ export type LitePsmData = {
18
17
 
19
18
  export type PoolConfig = {
20
19
  gem: Token;
21
- gemJoinAddress: Address; // dai liquidity
22
20
  pocketAddress: Address; // gem liquidity
23
21
  psmAddress: Address;
24
22
  identifier: string; // bytes32 of pool identifier (Eg. bytes32("PSM-USDC-A"))
@@ -26,6 +24,8 @@ export type PoolConfig = {
26
24
 
27
25
  export type DexParams = {
28
26
  dai: Token;
27
+ usds: Token;
28
+ usdsPsmAddress: Address;
29
29
  vatAddress: Address;
30
30
  pools: PoolConfig[];
31
31
  };
@@ -38,6 +38,7 @@ export type LitePsmParams = [
38
38
  toll: NumberAsString,
39
39
  to18ConversionFactor: NumberAsString,
40
40
  exchange: Address,
41
+ // psm (exchange) is the join for both dai and usds
41
42
  gemJoinAddress: Address,
42
43
  metadata: string,
43
44
  beneficiaryDirectionApproveFlag: NumberAsString,
@@ -0,0 +1,12 @@
1
+ import { DexParams } from './types';
2
+ import { DexConfigMap } from '../../types';
3
+ import { Network } from '../../constants';
4
+
5
+ export const UsualBondConfig: DexConfigMap<DexParams> = {
6
+ UsualBond: {
7
+ [Network.MAINNET]: {
8
+ usd0Address: '0x73A15FeD60Bf67631dC6cd7Bc5B6e8da8190aCF5',
9
+ usd0ppAddress: '0x35D8949372D46B7a3D5A56006AE77B215fc69bC0',
10
+ },
11
+ },
12
+ };
@@ -0,0 +1,10 @@
1
+ import { Address } from '../../types';
2
+
3
+ export type PoolState = {};
4
+
5
+ export type UsualBondData = {};
6
+
7
+ export type DexParams = {
8
+ usd0Address: Address;
9
+ usd0ppAddress: Address;
10
+ };
@@ -0,0 +1,81 @@
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
+ function testForNetwork(
16
+ network: Network,
17
+ dexKey: string,
18
+ tokenASymbol: string,
19
+ tokenBSymbol: string,
20
+ tokenAAmount: string,
21
+ tokenBAmount: string,
22
+ ) {
23
+ const provider = new StaticJsonRpcProvider(
24
+ generateConfig(network).privateHttpProvider,
25
+ network,
26
+ );
27
+ const tokens = Tokens[network];
28
+ const holders = Holders[network];
29
+
30
+ const sideToContractMethods = new Map([
31
+ [SwapSide.SELL, [ContractMethod.swapExactAmountIn]],
32
+ [SwapSide.BUY, [ContractMethod.swapExactAmountOut]],
33
+ ]);
34
+
35
+ describe(`${network}`, () => {
36
+ sideToContractMethods.forEach((contractMethods, side) =>
37
+ describe(`${side}`, () => {
38
+ contractMethods.forEach((contractMethod: ContractMethod) => {
39
+ describe(`${contractMethod}`, () => {
40
+ it(`${tokenASymbol} -> ${tokenBSymbol}`, async () => {
41
+ await testE2E(
42
+ tokens[tokenASymbol],
43
+ tokens[tokenBSymbol],
44
+ holders[tokenASymbol],
45
+ side === SwapSide.SELL ? tokenAAmount : tokenBAmount,
46
+ side,
47
+ dexKey,
48
+ contractMethod,
49
+ network,
50
+ provider,
51
+ );
52
+ });
53
+ });
54
+ });
55
+ }),
56
+ );
57
+ });
58
+ }
59
+
60
+ describe('UsualBond E2E', () => {
61
+ const dexKey = 'UsualBond';
62
+
63
+ describe('Mainnet', () => {
64
+ const network = Network.MAINNET;
65
+
66
+ const tokenASymbol: string = 'USD0';
67
+ const tokenBSymbol: string = 'USD0++';
68
+
69
+ const tokenAAmount: string = '100000';
70
+ const tokenBAmount: string = '100000';
71
+
72
+ testForNetwork(
73
+ network,
74
+ dexKey,
75
+ tokenASymbol,
76
+ tokenBSymbol,
77
+ tokenAAmount,
78
+ tokenBAmount,
79
+ );
80
+ });
81
+ });
@@ -0,0 +1,106 @@
1
+ /* eslint-disable no-console */
2
+ import dotenv from 'dotenv';
3
+ dotenv.config();
4
+
5
+ import { Interface } from '@ethersproject/abi';
6
+ import { DummyDexHelper } from '../../dex-helper/index';
7
+ import { Network, SwapSide } from '../../constants';
8
+ import { BI_POWS } from '../../bigint-constants';
9
+ import { UsualBond } from './usual-bond';
10
+ import { checkPoolPrices, checkConstantPoolPrices } from '../../../tests/utils';
11
+ import { Tokens } from '../../../tests/constants-e2e';
12
+
13
+ async function testPricingOnNetwork(
14
+ usualBond: UsualBond,
15
+ network: Network,
16
+ dexKey: string,
17
+ blockNumber: number,
18
+ srcTokenAddress: string,
19
+ destTokenAddress: string,
20
+ side: SwapSide,
21
+ amounts: bigint[],
22
+ funcNameToCheck: string,
23
+ ) {
24
+ const networkTokens = Tokens[network];
25
+
26
+ console.log(amounts);
27
+
28
+ const pools = await usualBond.getPoolIdentifiers(
29
+ networkTokens['USD0'],
30
+ networkTokens['USD0++'],
31
+ side,
32
+ blockNumber,
33
+ );
34
+ console.log(`${'USD0'} <> ${'USD0++'} Pool Identifiers: `, pools);
35
+
36
+ expect(pools.length).toBeGreaterThan(0);
37
+
38
+ const poolPrices = await usualBond.getPricesVolume(
39
+ networkTokens['USD0'],
40
+ networkTokens['USD0++'],
41
+ amounts,
42
+ side,
43
+ blockNumber,
44
+ pools,
45
+ );
46
+ console.log(`${'USD0'} <> ${'USD0++'} Pool Prices: `, poolPrices);
47
+
48
+ expect(poolPrices).not.toBeNull();
49
+ if (usualBond.hasConstantPriceLargeAmounts) {
50
+ checkConstantPoolPrices(poolPrices!, amounts, dexKey);
51
+ } else {
52
+ checkPoolPrices(poolPrices!, amounts, side, dexKey);
53
+ }
54
+
55
+ // Check if onchain pricing equals to calculated ones
56
+ checkPoolPrices(poolPrices!, amounts, side, dexKey);
57
+ }
58
+
59
+ describe('UsualBond', function () {
60
+ const dexKey = 'UsualBond';
61
+ let blockNumber: number;
62
+ let usualBond: UsualBond;
63
+
64
+ describe('Mainnet', () => {
65
+ const network = Network.MAINNET;
66
+ const dexHelper = new DummyDexHelper(network);
67
+
68
+ // Don't forget to update relevant tokens in constant-e2e.ts
69
+
70
+ const amountsForSell = [
71
+ 0n,
72
+ 1n * BI_POWS[18],
73
+ 2n * BI_POWS[18],
74
+ 3n * BI_POWS[18],
75
+ 4n * BI_POWS[18],
76
+ 5n * BI_POWS[18],
77
+ 6n * BI_POWS[18],
78
+ 7n * BI_POWS[18],
79
+ 8n * BI_POWS[18],
80
+ 9n * BI_POWS[18],
81
+ 10n * BI_POWS[18],
82
+ ];
83
+
84
+ beforeAll(async () => {
85
+ blockNumber = await dexHelper.web3Provider.eth.getBlockNumber();
86
+ usualBond = new UsualBond(network, dexKey, dexHelper);
87
+ if (usualBond.initializePricing) {
88
+ await usualBond.initializePricing(blockNumber);
89
+ }
90
+ });
91
+
92
+ it('getPoolIdentifiers and getPricesVolume SELL', async function () {
93
+ await testPricingOnNetwork(
94
+ usualBond,
95
+ network,
96
+ dexKey,
97
+ blockNumber,
98
+ 'USD0',
99
+ 'USD0++',
100
+ SwapSide.SELL,
101
+ amountsForSell,
102
+ '',
103
+ );
104
+ });
105
+ });
106
+ });