@paraswap/dex-lib 3.0.3-fix-for-rc.0 → 3.0.4

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.
@@ -1010,6 +1010,8 @@ export class BalancerV2
1010
1010
  destAmount,
1011
1011
  data,
1012
1012
  side,
1013
+ this.dexHelper.config.data.augustusAddress!,
1014
+ this.dexHelper.config.data.augustusAddress!,
1013
1015
  );
1014
1016
 
1015
1017
  const payload = this.abiCoder.encodeParameter(
@@ -1049,6 +1051,24 @@ export class BalancerV2
1049
1051
  };
1050
1052
  }
1051
1053
 
1054
+ /*
1055
+ Algorithm to determine balancer (sender, recipient) params:
1056
+
1057
+ if version = 5
1058
+ sender = recipient = augustusV5
1059
+ else (so V6)
1060
+ if direct swap
1061
+ sender = recipient = augustusV6
1062
+ else (so generic swaps)
1063
+ if sell
1064
+ if swap.destToken = priceRoute.destToken <> ETH (need withdraw for eth currently, need fix in future)
1065
+ sender = executor and recipient = augustusV6 (skip 1 extra transfer)
1066
+ else
1067
+ sender = recipient = executor
1068
+ # note: we pass sender=null then the address of the executor is inferred contract side
1069
+ else (so buy)
1070
+ sender = recipient = executor
1071
+ */
1052
1072
  public getBalancerParam(
1053
1073
  srcToken: string,
1054
1074
  destToken: string,
@@ -1056,6 +1076,8 @@ export class BalancerV2
1056
1076
  destAmount: string,
1057
1077
  data: OptimizedBalancerV2Data,
1058
1078
  side: SwapSide,
1079
+ recipient: string,
1080
+ sender: string,
1059
1081
  ): BalancerParam {
1060
1082
  let swapOffset = 0;
1061
1083
  let swaps: BalancerSwap[] = [];
@@ -1115,116 +1137,6 @@ export class BalancerV2
1115
1137
  }
1116
1138
 
1117
1139
  const funds = {
1118
- sender: this.augustusAddress,
1119
- recipient: this.augustusAddress,
1120
- fromInternalBalance: false,
1121
- toInternalBalance: false,
1122
- };
1123
-
1124
- const params: BalancerParam = [
1125
- side === SwapSide.SELL ? SwapTypes.SwapExactIn : SwapTypes.SwapExactOut,
1126
- side === SwapSide.SELL ? swaps : swaps.reverse(),
1127
- assets,
1128
- funds,
1129
- limits,
1130
- MAX_UINT,
1131
- ];
1132
-
1133
- return params;
1134
- }
1135
-
1136
- public getBalancerParamV6(
1137
- srcToken: Address,
1138
- destToken: Address,
1139
- srcAmount: string,
1140
- destAmount: string,
1141
- data: OptimizedBalancerV2Data,
1142
- side: SwapSide,
1143
- recipient: Address,
1144
- sender: Address,
1145
- isDirect?: boolean,
1146
- ): BalancerParam {
1147
- let swapOffset = 0;
1148
- let swaps: BalancerSwap[] = [];
1149
- let assets: string[] = [];
1150
- let limits: string[] = [];
1151
-
1152
- const isDirectSwap = !!isDirect;
1153
-
1154
- for (const swapData of data.swaps) {
1155
- const pool = this.poolIdMap[swapData.poolId];
1156
- const hasEth = [srcToken.toLowerCase(), destToken.toLowerCase()].includes(
1157
- ETHER_ADDRESS.toLowerCase(),
1158
- );
1159
- const _srcToken = this.dexHelper.config.wrapETH({
1160
- address: srcToken,
1161
- decimals: 18,
1162
- }).address;
1163
- const _destToken = this.dexHelper.config.wrapETH({
1164
- address: destToken,
1165
- decimals: 18,
1166
- }).address;
1167
-
1168
- let path = poolGetPathForTokenInOut(
1169
- _srcToken,
1170
- _destToken,
1171
- pool,
1172
- this.poolAddressMap,
1173
- side,
1174
- );
1175
-
1176
- if (side === SwapSide.BUY) {
1177
- path = path.reverse();
1178
- }
1179
-
1180
- let _swaps = path.map((hop, index) => ({
1181
- poolId: hop.pool.id,
1182
- assetInIndex: swapOffset + index,
1183
- assetOutIndex: swapOffset + index + 1,
1184
- amount:
1185
- (side === SwapSide.SELL && index === 0) ||
1186
- (side === SwapSide.BUY && index === path.length - 1)
1187
- ? swapData.amount
1188
- : '0',
1189
- userData: '0x',
1190
- }));
1191
-
1192
- swapOffset += path.length + 1;
1193
-
1194
- // BalancerV2 Uses Address(0) as ETH
1195
- let _assets = [_srcToken, ...path.map(hop => hop.tokenOut.address)].map(
1196
- t => (hasEth && this.dexHelper.config.isWETH(t) ? NULL_ADDRESS : t),
1197
- );
1198
-
1199
- if (isDirectSwap && side === SwapSide.BUY) {
1200
- _assets = _assets.reverse();
1201
- _swaps = _swaps.map(swap => ({
1202
- ...swap,
1203
- assetInIndex: _assets.length - swap.assetInIndex - 1,
1204
- assetOutIndex: _assets.length - swap.assetOutIndex - 1,
1205
- }));
1206
- }
1207
-
1208
- let _limits: string[];
1209
- if (isDirectSwap) {
1210
- _limits = this.createSwapArray(
1211
- _assets.length,
1212
- side === SwapSide.SELL ? 0 : 1,
1213
- srcAmount,
1214
- destAmount,
1215
- );
1216
- } else {
1217
- _limits = _assets.map(_ => MAX_INT);
1218
- }
1219
-
1220
- swaps = swaps.concat(_swaps);
1221
- assets = assets.concat(_assets);
1222
- limits = limits.concat(_limits);
1223
- }
1224
-
1225
- const funds = {
1226
- // for Direct: Both sender and recipient is AugustusV6
1227
- // for Generic, `sender`: BUY -> pass Executor3, for SELL -> pass NULL_ADDRESS (it's gonna be determined in the contract)
1228
1140
  sender,
1229
1141
  recipient,
1230
1142
  fromInternalBalance: false,
@@ -1243,23 +1155,6 @@ export class BalancerV2
1243
1155
  return params;
1244
1156
  }
1245
1157
 
1246
- private createSwapArray(
1247
- lengthOfAssets: number,
1248
- swapKind: 0 | 1,
1249
- fromAmount: string,
1250
- toAmount: string,
1251
- ): string[] {
1252
- let swapArray = new Array(lengthOfAssets).fill('0');
1253
-
1254
- // Assign values based on swapKind
1255
- swapArray[0] =
1256
- swapKind === 0 ? fromAmount : BigNumber.from(toAmount).mul(-1).toString();
1257
- swapArray[lengthOfAssets - 1] =
1258
- swapKind === 0 ? BigNumber.from(toAmount).mul(-1).toString() : fromAmount;
1259
-
1260
- return swapArray;
1261
- }
1262
-
1263
1158
  static getDirectFunctionName(): string[] {
1264
1159
  return [DirectMethods.directSell, DirectMethods.directBuy];
1265
1160
  }
@@ -1354,6 +1249,8 @@ export class BalancerV2
1354
1249
  destAmount,
1355
1250
  data,
1356
1251
  side,
1252
+ this.dexHelper.config.data.augustusAddress!,
1253
+ this.dexHelper.config.data.augustusAddress!,
1357
1254
  );
1358
1255
 
1359
1256
  const swapParams: BalancerV2DirectParam = [
@@ -1416,7 +1313,7 @@ export class BalancerV2
1416
1313
  hexZeroPad(hexlify(blockNumber), 16),
1417
1314
  ]);
1418
1315
 
1419
- const balancerParams = this.getBalancerParamV6(
1316
+ const balancerParams = this.getBalancerParam(
1420
1317
  srcToken,
1421
1318
  destToken,
1422
1319
  fromAmount,
@@ -1425,7 +1322,6 @@ export class BalancerV2
1425
1322
  side,
1426
1323
  this.dexHelper.config.data.augustusV6Address!,
1427
1324
  this.dexHelper.config.data.augustusV6Address!,
1428
- true,
1429
1325
  );
1430
1326
 
1431
1327
  const swapParams: BalancerV2DirectParamV6 = [
@@ -1496,6 +1392,8 @@ export class BalancerV2
1496
1392
  destAmount,
1497
1393
  data,
1498
1394
  side,
1395
+ this.dexHelper.config.data.augustusAddress!,
1396
+ this.dexHelper.config.data.augustusAddress!,
1499
1397
  );
1500
1398
 
1501
1399
  const swapData = this.eventPools.vaultInterface.encodeFunctionData(
@@ -1523,7 +1421,7 @@ export class BalancerV2
1523
1421
  side: SwapSide,
1524
1422
  context: Context,
1525
1423
  ): DexExchangeParam {
1526
- const params = this.getBalancerParamV6(
1424
+ const params = this.getBalancerParam(
1527
1425
  srcToken,
1528
1426
  destToken,
1529
1427
  srcAmount,
@@ -94,6 +94,7 @@ export class CurveV2
94
94
  exchangeRouterInterface: Interface;
95
95
  genericFactoryZapIface: Interface;
96
96
  minConversionRate = '1';
97
+ // TODO: it's wrong, cause some pools can have eth and others can have weth
97
98
  needWrapNative = true;
98
99
  logger: Logger;
99
100
 
@@ -1,4 +1,4 @@
1
- import { NumberAsString, SwapSide } from '@paraswap/core';
1
+ import { NumberAsString, ParaSwapVersion, SwapSide } from '@paraswap/core';
2
2
  import { Address } from '../../types';
3
3
 
4
4
  export type WethData = null;
@@ -29,5 +29,6 @@ export interface IWethDepositorWithdrawer {
29
29
  srcAmount: NumberAsString,
30
30
  destAmount: NumberAsString,
31
31
  side: SwapSide,
32
+ version: ParaSwapVersion,
32
33
  ): DepositWithdrawReturn;
33
34
  }
@@ -25,7 +25,7 @@ import {
25
25
  import { SimpleExchange } from '../simple-exchange';
26
26
  import { Adapters, WethConfig } from './config';
27
27
  import { BI_POWS } from '../../bigint-constants';
28
- import { NumberAsString } from '@paraswap/core';
28
+ import { NumberAsString, ParaSwapVersion } from '@paraswap/core';
29
29
 
30
30
  export class Weth
31
31
  extends SimpleExchange
@@ -184,6 +184,7 @@ export class Weth
184
184
  srcAmount: string,
185
185
  destAmount: string,
186
186
  side: SwapSide,
187
+ version: ParaSwapVersion,
187
188
  ): DepositWithdrawReturn {
188
189
  const wethToken = this.address;
189
190
 
@@ -206,13 +207,18 @@ export class Weth
206
207
  }
207
208
 
208
209
  if (needWithdraw || destAmount !== '0') {
209
- const opType = WethFunctions.withdraw;
210
- const withdrawWethData = this.erc20Interface.encodeFunctionData(opType, [
211
- destAmount,
212
- ]);
210
+ const withdrawWethData =
211
+ version === ParaSwapVersion.V5
212
+ ? this.simpleSwapHelper.encodeFunctionData(
213
+ WethFunctions.withdrawAllWETH,
214
+ [wethToken],
215
+ )
216
+ : this.erc20Interface.encodeFunctionData(WethFunctions.withdraw, [
217
+ destAmount,
218
+ ]);
213
219
 
214
220
  withdraw = {
215
- callee: this.augustusAddress,
221
+ callee: this.augustusAddress, // FXME CALLEE NOT USED IN V6
216
222
  calldata: withdrawWethData,
217
223
  value: '0',
218
224
  };
@@ -176,7 +176,7 @@ export class Executor02BytecodeBuilder extends ExecutorBytecodeBuilder {
176
176
  const needCheckEthBalance = isEthDest && !needWrapNative;
177
177
 
178
178
  const needCheckSrcTokenBalanceOf =
179
- (needUnwrap && !applyVerticalBranching && !isLastSwap) ||
179
+ (needUnwrap && !applyVerticalBranching) ||
180
180
  (isHorizontalSequence && !applyVerticalBranching && !isLastSwap);
181
181
 
182
182
  let dexFlag: Flag;
@@ -719,7 +719,9 @@ export class Executor02BytecodeBuilder extends ExecutorBytecodeBuilder {
719
719
  if (
720
720
  !exchangeParams[exchangeParamIndex].dexFuncHasRecipient &&
721
721
  isETHAddress(swap.destToken) &&
722
- isLast
722
+ isLast &&
723
+ // don't need to send eth without unwrapping, handling unwrap and sendEth in the end of root branch
724
+ !this.doesRouteNeedsRootUnwrapEth(priceRoute, exchangeParams)
723
725
  ) {
724
726
  const finalSpecialFlagCalldata = this.buildFinalSpecialFlagCalldata();
725
727
  swapExchangeCallData = hexConcat([
@@ -1168,13 +1170,13 @@ export class Executor02BytecodeBuilder extends ExecutorBytecodeBuilder {
1168
1170
 
1169
1171
  const res = priceRoute.bestRoute.some((route, routeIndex) => {
1170
1172
  const lastSwap = route.swaps[route.swaps.length - 1];
1171
- const eachDexOnSwapNeedsWrapNative = this.anyDexOnSwapNeedsWrapNative(
1173
+ const anyDexOnSwapNeedsWrapNative = this.anyDexOnSwapNeedsWrapNative(
1172
1174
  priceRoute,
1173
1175
  lastSwap,
1174
1176
  exchangeParams,
1175
1177
  );
1176
1178
 
1177
- return eachDexOnSwapNeedsWrapNative;
1179
+ return anyDexOnSwapNeedsWrapNative;
1178
1180
  });
1179
1181
 
1180
1182
  return res;
@@ -1067,12 +1067,7 @@ describe('Executor02ByteCodeBuilder e2e tests', () => {
1067
1067
  });
1068
1068
 
1069
1069
  describe('lzUSDC -> FTM -> SPIRIT', () => {
1070
- const dexKeys = [
1071
- 'Morphex',
1072
- 'SpiritSwap',
1073
- 'SpiritSwapV2',
1074
- 'BeetsFi',
1075
- ];
1070
+ const dexKeys = ['Morphex', 'SpiritSwap', 'SpiritSwapV2', 'BeetsFi'];
1076
1071
 
1077
1072
  const tokenASymbol: string = 'lzUSDC';
1078
1073
  const tokenBSymbol: string = 'SPIRIT';
@@ -1437,7 +1432,7 @@ describe('Executor02ByteCodeBuilder e2e tests', () => {
1437
1432
  false,
1438
1433
  );
1439
1434
  });
1440
- })
1435
+ });
1441
1436
  });
1442
1437
  });
1443
1438
 
@@ -32,6 +32,7 @@ import ERC20ABI from './abi/erc20.json';
32
32
  import { ExecutorDetector } from './executor/ExecutorDetector';
33
33
  import { ExecutorBytecodeBuilder } from './executor/ExecutorBytecodeBuilder';
34
34
  import { IDexTxBuilder } from './dex/idex';
35
+ import { ParaSwapVersion } from '@paraswap/core';
35
36
 
36
37
  const {
37
38
  utils: { hexlify, hexConcat, hexZeroPad },
@@ -92,6 +93,7 @@ export class GenericSwapTransactionBuilder {
92
93
  srcAmountWeth.toString(),
93
94
  destAmountWeth.toString(),
94
95
  side,
96
+ ParaSwapVersion.V6,
95
97
  );
96
98
  }
97
99
 
@@ -19,6 +19,7 @@ import {
19
19
  encodeFeePercentForReferrer,
20
20
  encodePartnerAddressForFeeLogic,
21
21
  } from './payload-encoder';
22
+ import { ParaSwapVersion } from '@paraswap/core';
22
23
 
23
24
  type SimpleSwapParam = [ConstractSimpleData];
24
25
 
@@ -244,6 +245,7 @@ export abstract class SimpleRouterBase<RouterParam>
244
245
  srcAmountWeth.toString(),
245
246
  destAmountWeth.toString(),
246
247
  this.side,
248
+ ParaSwapVersion.V5,
247
249
  );
248
250
  }
249
251
  }
@@ -1 +1,87 @@
1
- { "priceRoute" : { "blockNumber" : 19433584, "network" : 1, "srcToken" : "0xae7ab96520de3a18e5e111b5eaab095312d7fe84", "srcDecimals" : 18, "srcAmount" : "864303161674786484853", "destToken" : "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "destDecimals" : 18, "destAmount" : "863477638047664488829", "bestRoute" : [ { "percent" : 18, "swaps" : [ { "srcToken" : "0xae7ab96520de3a18e5e111b5eaab095312d7fe84", "srcDecimals" : 18, "destToken" : "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "destDecimals" : 18, "swapExchanges" : [ { "exchange" : "CurveV1", "srcAmount" : "155574569101461567274", "destAmount" : "155426142829423771521", "percent" : 100, "poolAddresses" : [ "0xdc24316b9ae028f1497c275eb9192a3ea0f67022" ], "data" : { "exchange" : "0xdc24316b9ae028f1497c275eb9192a3ea0f67022", "i" : 1, "j" : 0, "underlyingSwap" : false, "deadline" : 0, "gasUSD" : "50.718266" } } ] } ] }, { "percent" : 82, "swaps" : [ { "srcToken" : "0xae7ab96520de3a18e5e111b5eaab095312d7fe84", "srcDecimals" : 18, "destToken" : "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0", "destDecimals" : 18, "swapExchanges" : [ { "exchange" : "wstETH", "srcAmount" : "708728592573324917579", "destAmount" : "610809583801027512819", "percent" : 100, "poolAddresses" : [ "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0" ], "data" : { "gasUSD" : "15.215480" } } ] }, { "srcToken" : "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0", "srcDecimals" : 18, "destToken" : "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "destDecimals" : 18, "swapExchanges" : [ { "exchange" : "UniswapV3", "srcAmount" : "566098322266792298881", "destAmount" : "656241721408829891190", "percent" : 92.68, "poolAddresses" : [ "0x109830a1aaad605bbf02a9dfa7b0b92ec2fb7daa" ], "data" : { "path" : [ { "tokenIn" : "0x7f39c581f595b53c5cb19bd0b3f8da6c935e2ca0", "tokenOut" : "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "fee" : "100", "currentFee" : "100" } ], "gasUSD" : "33.727647" } }, { "exchange" : "SolidlyV3", "srcAmount" : "44711261534235213938", "destAmount" : "51809773809410826118", "percent" : 7.32, "poolAddresses" : [ "0x4370e48e610d2e02d3d091a9d79c8eb9a54c5b1c" ], "data" : { "zeroForOne" : true, "poolAddress" : "0x4370e48e610d2e02d3d091a9d79c8eb9a54c5b1c", "gasUSD" : "15.215480" } } ] } ] } ], "gasCostUSD" : "137.167551", "gasCost" : "540900", "side" : "SELL", "tokenTransferProxy" : "0x216b4b4ba9f3e719726886d34a177484278bfcae", "contractAddress" : "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", "contractMethod" : "megaSwap", "partnerFee" : 0.28, "srcUSD" : "3392761.5599330571", "destUSD" : "3368776.0521803359", "partner" : "ledger2", "maxImpactReached" : false, "hmac" : "ad89afc898d3ab06ec3141992db9c12089749711" }, "minMaxAmount" : "859160249857426166384", "userAddress" : "0x0F0231B43Ee64d53DcAe20b89783ee78a48bBC24", "partnerAddress" : "0x558247e365be655f9144e1a0140D793984372Ef3", "partnerFeePercent" : "28", "takeSurplus" : false, "maxPriorityFeePerGas" : "90000000", "maxFeePerGas" : "80300000000", "deadline" : "1710445007", "uuid" : "a2cbe4f1-79ed-40b6-a95d-581e30eed150", "beneficiary" : "0x0000000000000000000000000000000000000000", "onlyParams" : false, "ignoreChecks" : false, "userIP" : "220.255.55.139", "buildFailed" : false }
1
+ {
2
+ "userIP": "78.201.144.55",
3
+ "priceRoute": {
4
+ "blockNumber": 54765382,
5
+ "network": 137,
6
+ "srcToken": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
7
+ "srcDecimals": 18,
8
+ "srcAmount": "1933698735959307184",
9
+ "destToken": "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063",
10
+ "destDecimals": 18,
11
+ "destAmount": "2019182231196365472",
12
+ "bestRoute": [
13
+ {
14
+ "percent": 100,
15
+ "swaps": [
16
+ {
17
+ "srcToken": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
18
+ "srcDecimals": 18,
19
+ "destToken": "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063",
20
+ "destDecimals": 18,
21
+ "swapExchanges": [
22
+ {
23
+ "exchange": "BalancerV2",
24
+ "srcAmount": "1915328597967693765",
25
+ "destAmount": "2019182231196365472",
26
+ "percent": 100,
27
+ "poolAddresses": [
28
+ "0x5e6989c0e2b6600ab585d56bf05479d5450a60c8"
29
+ ],
30
+ "data": {
31
+ "swaps": [
32
+ {
33
+ "poolId": "0x5e6989c0e2b6600ab585d56bf05479d5450a60c8000100000000000000000055",
34
+ "amount": "2019182231196365472"
35
+ }
36
+ ],
37
+ "gasUSD": "0.007820"
38
+ }
39
+ }
40
+ ]
41
+ }
42
+ ]
43
+ }
44
+ ],
45
+ "gasCostUSD": "0.008971",
46
+ "gasCost": "168620",
47
+ "others": [
48
+ {
49
+ "exchange": "BalancerV2",
50
+ "srcAmount": "1933698735959307184",
51
+ "destAmount": "2019182231196365472",
52
+ "unit": "946590620724131563",
53
+ "data": {
54
+ "poolId": "0x5e6989c0e2b6600ab585d56bf05479d5450a60c8000100000000000000000055",
55
+ "gasUSD": "0.012694"
56
+ }
57
+ }
58
+ ],
59
+ "side": "BUY",
60
+ "version": "6",
61
+ "contractAddress": "0x00000000FdAC7708D0D360BDDc1bc7d097F47439",
62
+ "tokenTransferProxy": "0x00000000FdAC7708D0D360BDDc1bc7d097F47439",
63
+ "contractMethod": "swapExactAmountOutOnBalancerV2",
64
+ "partnerFee": 0.95,
65
+ "srcUSD": "2.0379096282",
66
+ "destUSD": "2.0182130237",
67
+ "partner": "ledger2",
68
+ "maxImpactReached": false,
69
+ "hmac": "7f034cb72d31209d2fb9467296042781d0c70b2c"
70
+ },
71
+ "minMaxAmount": "1943367229639103719",
72
+ "userAddress": "0x5AC840Fb4738C36467aC673E87aaFa26C9397dcd",
73
+ "txOrigin": "0x5AC840Fb4738C36467aC673E87aaFa26C9397dcd",
74
+ "beneficiary": "0x0000000000000000000000000000000000000000",
75
+ "partnerAddress": "0x558247e365be655f9144e1a0140D793984372Ef3",
76
+ "partnerFeePercent": "95",
77
+ "takeSurplus": false,
78
+ "gasPrice": "52000000000",
79
+ "onlyParams": false,
80
+ "ignoreChecks": false,
81
+ "ignoreAllowance": false,
82
+ "ignoreGasEstimate": false,
83
+ "signCalldata": false,
84
+ "ignoreImpactCheck": false,
85
+ "partner": "ledger2",
86
+ "isCapSurplus": true
87
+ }