@ring-protocol/universal-router-sdk 0.1.8 → 0.1.24

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,1728 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
+
7
+ var invariant = _interopDefault(require('tiny-invariant'));
8
+ var UniversalRouter = _interopDefault(require('@uniswap/universal-router/artifacts/contracts/UniversalRouter.sol/UniversalRouter.json'));
9
+ var abi = require('@ethersproject/abi');
10
+ var ethers = require('ethers');
11
+ var v3Sdk = require('@ring-protocol/v3-sdk');
12
+ var v4Sdk = require('@ring-protocol/v4-sdk');
13
+ var sdkCore = require('@ring-protocol/sdk-core');
14
+ var utils = require('ethers/lib/utils');
15
+ var fewV2Sdk = require('@ring-protocol/few-v2-sdk');
16
+ var v2Sdk = require('@ring-protocol/v2-sdk');
17
+ var routerSdk = require('@ring-protocol/router-sdk');
18
+ require('jsbi');
19
+ require('bignumber.js');
20
+
21
+ function _arrayLikeToArray(r, a) {
22
+ (null == a || a > r.length) && (a = r.length);
23
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
24
+ return n;
25
+ }
26
+ function _defineProperties(e, r) {
27
+ for (var t = 0; t < r.length; t++) {
28
+ var o = r[t];
29
+ o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
30
+ }
31
+ }
32
+ function _createClass(e, r, t) {
33
+ return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
34
+ writable: !1
35
+ }), e;
36
+ }
37
+ function _createForOfIteratorHelperLoose(r, e) {
38
+ var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
39
+ if (t) return (t = t.call(r)).next.bind(t);
40
+ if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
41
+ t && (r = t);
42
+ var o = 0;
43
+ return function () {
44
+ return o >= r.length ? {
45
+ done: !0
46
+ } : {
47
+ done: !1,
48
+ value: r[o++]
49
+ };
50
+ };
51
+ }
52
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
53
+ }
54
+ function _toPrimitive(t, r) {
55
+ if ("object" != typeof t || !t) return t;
56
+ var e = t[Symbol.toPrimitive];
57
+ if (void 0 !== e) {
58
+ var i = e.call(t, r || "default");
59
+ if ("object" != typeof i) return i;
60
+ throw new TypeError("@@toPrimitive must return a primitive value.");
61
+ }
62
+ return ("string" === r ? String : Number)(t);
63
+ }
64
+ function _toPropertyKey(t) {
65
+ var i = _toPrimitive(t, "string");
66
+ return "symbol" == typeof i ? i : i + "";
67
+ }
68
+ function _unsupportedIterableToArray(r, a) {
69
+ if (r) {
70
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
71
+ var t = {}.toString.call(r).slice(8, -1);
72
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
73
+ }
74
+ }
75
+
76
+ var _COMMAND_DEFINITION;
77
+ (function (CommandType) {
78
+ CommandType[CommandType["V3_SWAP_EXACT_IN"] = 0] = "V3_SWAP_EXACT_IN";
79
+ CommandType[CommandType["V3_SWAP_EXACT_OUT"] = 1] = "V3_SWAP_EXACT_OUT";
80
+ CommandType[CommandType["PERMIT2_TRANSFER_FROM"] = 2] = "PERMIT2_TRANSFER_FROM";
81
+ CommandType[CommandType["PERMIT2_PERMIT_BATCH"] = 3] = "PERMIT2_PERMIT_BATCH";
82
+ CommandType[CommandType["SWEEP"] = 4] = "SWEEP";
83
+ CommandType[CommandType["TRANSFER"] = 5] = "TRANSFER";
84
+ CommandType[CommandType["PAY_PORTION"] = 6] = "PAY_PORTION";
85
+ CommandType[CommandType["V2_SWAP_EXACT_IN"] = 8] = "V2_SWAP_EXACT_IN";
86
+ CommandType[CommandType["V2_SWAP_EXACT_OUT"] = 9] = "V2_SWAP_EXACT_OUT";
87
+ CommandType[CommandType["PERMIT2_PERMIT"] = 10] = "PERMIT2_PERMIT";
88
+ CommandType[CommandType["WRAP_ETH"] = 11] = "WRAP_ETH";
89
+ CommandType[CommandType["UNWRAP_WETH"] = 12] = "UNWRAP_WETH";
90
+ CommandType[CommandType["PERMIT2_TRANSFER_FROM_BATCH"] = 13] = "PERMIT2_TRANSFER_FROM_BATCH";
91
+ CommandType[CommandType["BALANCE_CHECK_ERC20"] = 14] = "BALANCE_CHECK_ERC20";
92
+ CommandType[CommandType["V4_SWAP"] = 16] = "V4_SWAP";
93
+ CommandType[CommandType["V3_POSITION_MANAGER_PERMIT"] = 17] = "V3_POSITION_MANAGER_PERMIT";
94
+ CommandType[CommandType["V3_POSITION_MANAGER_CALL"] = 18] = "V3_POSITION_MANAGER_CALL";
95
+ CommandType[CommandType["V4_INITIALIZE_POOL"] = 19] = "V4_INITIALIZE_POOL";
96
+ CommandType[CommandType["V4_POSITION_MANAGER_CALL"] = 20] = "V4_POSITION_MANAGER_CALL";
97
+ CommandType[CommandType["EXECUTE_SUB_PLAN"] = 33] = "EXECUTE_SUB_PLAN";
98
+ CommandType[CommandType["FEW_V2_SWAP_EXACT_IN"] = 35] = "FEW_V2_SWAP_EXACT_IN";
99
+ CommandType[CommandType["FEW_V2_SWAP_EXACT_OUT"] = 36] = "FEW_V2_SWAP_EXACT_OUT";
100
+ CommandType[CommandType["WRAP_FEW_TOKEN"] = 39] = "WRAP_FEW_TOKEN";
101
+ CommandType[CommandType["UNWRAP_FEW_TOKEN"] = 40] = "UNWRAP_FEW_TOKEN";
102
+ })(exports.CommandType || (exports.CommandType = {}));
103
+ (function (Subparser) {
104
+ Subparser[Subparser["V3PathExactIn"] = 0] = "V3PathExactIn";
105
+ Subparser[Subparser["V3PathExactOut"] = 1] = "V3PathExactOut";
106
+ })(exports.Subparser || (exports.Subparser = {}));
107
+ (function (Parser) {
108
+ Parser[Parser["Abi"] = 0] = "Abi";
109
+ Parser[Parser["V4Actions"] = 1] = "V4Actions";
110
+ Parser[Parser["V3Actions"] = 2] = "V3Actions";
111
+ })(exports.Parser || (exports.Parser = {}));
112
+ var ALLOW_REVERT_FLAG = 0x80;
113
+ var REVERTIBLE_COMMANDS = /*#__PURE__*/new Set([exports.CommandType.EXECUTE_SUB_PLAN]);
114
+ var PERMIT_STRUCT = '((address token,uint160 amount,uint48 expiration,uint48 nonce) details,address spender,uint256 sigDeadline)';
115
+ var PERMIT_BATCH_STRUCT = '((address token,uint160 amount,uint48 expiration,uint48 nonce)[] details,address spender,uint256 sigDeadline)';
116
+ var POOL_KEY_STRUCT = '(address currency0,address currency1,uint24 fee,int24 tickSpacing,address hooks)';
117
+ var PERMIT2_TRANSFER_FROM_STRUCT = '(address from,address to,uint160 amount,address token)';
118
+ var PERMIT2_TRANSFER_FROM_BATCH_STRUCT = PERMIT2_TRANSFER_FROM_STRUCT + '[]';
119
+ var COMMAND_DEFINITION = (_COMMAND_DEFINITION = {}, _COMMAND_DEFINITION[exports.CommandType.EXECUTE_SUB_PLAN] = {
120
+ parser: exports.Parser.Abi,
121
+ params: [{
122
+ name: 'commands',
123
+ type: 'bytes'
124
+ }, {
125
+ name: 'inputs',
126
+ type: 'bytes[]'
127
+ }]
128
+ }, _COMMAND_DEFINITION[exports.CommandType.PERMIT2_PERMIT] = {
129
+ parser: exports.Parser.Abi,
130
+ params: [{
131
+ name: 'permit',
132
+ type: PERMIT_STRUCT
133
+ }, {
134
+ name: 'signature',
135
+ type: 'bytes'
136
+ }]
137
+ }, _COMMAND_DEFINITION[exports.CommandType.PERMIT2_PERMIT_BATCH] = {
138
+ parser: exports.Parser.Abi,
139
+ params: [{
140
+ name: 'permit',
141
+ type: PERMIT_BATCH_STRUCT
142
+ }, {
143
+ name: 'signature',
144
+ type: 'bytes'
145
+ }]
146
+ }, _COMMAND_DEFINITION[exports.CommandType.PERMIT2_TRANSFER_FROM] = {
147
+ parser: exports.Parser.Abi,
148
+ params: [{
149
+ name: 'token',
150
+ type: 'address'
151
+ }, {
152
+ name: 'recipient',
153
+ type: 'address'
154
+ }, {
155
+ name: 'amount',
156
+ type: 'uint160'
157
+ }]
158
+ }, _COMMAND_DEFINITION[exports.CommandType.PERMIT2_TRANSFER_FROM_BATCH] = {
159
+ parser: exports.Parser.Abi,
160
+ params: [{
161
+ name: 'transferFrom',
162
+ type: PERMIT2_TRANSFER_FROM_BATCH_STRUCT
163
+ }]
164
+ }, _COMMAND_DEFINITION[exports.CommandType.V3_SWAP_EXACT_IN] = {
165
+ parser: exports.Parser.Abi,
166
+ params: [{
167
+ name: 'recipient',
168
+ type: 'address'
169
+ }, {
170
+ name: 'amountIn',
171
+ type: 'uint256'
172
+ }, {
173
+ name: 'amountOutMin',
174
+ type: 'uint256'
175
+ }, {
176
+ name: 'path',
177
+ subparser: exports.Subparser.V3PathExactIn,
178
+ type: 'bytes'
179
+ }, {
180
+ name: 'payerIsUser',
181
+ type: 'bool'
182
+ }]
183
+ }, _COMMAND_DEFINITION[exports.CommandType.V3_SWAP_EXACT_OUT] = {
184
+ parser: exports.Parser.Abi,
185
+ params: [{
186
+ name: 'recipient',
187
+ type: 'address'
188
+ }, {
189
+ name: 'amountOut',
190
+ type: 'uint256'
191
+ }, {
192
+ name: 'amountInMax',
193
+ type: 'uint256'
194
+ }, {
195
+ name: 'path',
196
+ subparser: exports.Subparser.V3PathExactOut,
197
+ type: 'bytes'
198
+ }, {
199
+ name: 'payerIsUser',
200
+ type: 'bool'
201
+ }]
202
+ }, _COMMAND_DEFINITION[exports.CommandType.V2_SWAP_EXACT_IN] = {
203
+ parser: exports.Parser.Abi,
204
+ params: [{
205
+ name: 'recipient',
206
+ type: 'address'
207
+ }, {
208
+ name: 'amountIn',
209
+ type: 'uint256'
210
+ }, {
211
+ name: 'amountOutMin',
212
+ type: 'uint256'
213
+ }, {
214
+ name: 'path',
215
+ type: 'address[]'
216
+ }, {
217
+ name: 'payerIsUser',
218
+ type: 'bool'
219
+ }]
220
+ }, _COMMAND_DEFINITION[exports.CommandType.V2_SWAP_EXACT_OUT] = {
221
+ parser: exports.Parser.Abi,
222
+ params: [{
223
+ name: 'recipient',
224
+ type: 'address'
225
+ }, {
226
+ name: 'amountOut',
227
+ type: 'uint256'
228
+ }, {
229
+ name: 'amountInMax',
230
+ type: 'uint256'
231
+ }, {
232
+ name: 'path',
233
+ type: 'address[]'
234
+ }, {
235
+ name: 'payerIsUser',
236
+ type: 'bool'
237
+ }]
238
+ }, _COMMAND_DEFINITION[exports.CommandType.FEW_V2_SWAP_EXACT_IN] = {
239
+ parser: exports.Parser.Abi,
240
+ params: [{
241
+ name: 'recipient',
242
+ type: 'address'
243
+ }, {
244
+ name: 'amountIn',
245
+ type: 'uint256'
246
+ }, {
247
+ name: 'amountOutMin',
248
+ type: 'uint256'
249
+ }, {
250
+ name: 'path',
251
+ type: 'address[]'
252
+ }, {
253
+ name: 'payerIsUser',
254
+ type: 'bool'
255
+ }]
256
+ }, _COMMAND_DEFINITION[exports.CommandType.FEW_V2_SWAP_EXACT_OUT] = {
257
+ parser: exports.Parser.Abi,
258
+ params: [{
259
+ name: 'recipient',
260
+ type: 'address'
261
+ }, {
262
+ name: 'amountOut',
263
+ type: 'uint256'
264
+ }, {
265
+ name: 'amountInMax',
266
+ type: 'uint256'
267
+ }, {
268
+ name: 'path',
269
+ type: 'address[]'
270
+ }, {
271
+ name: 'payerIsUser',
272
+ type: 'bool'
273
+ }]
274
+ }, _COMMAND_DEFINITION[exports.CommandType.V4_SWAP] = {
275
+ parser: exports.Parser.V4Actions
276
+ }, _COMMAND_DEFINITION[exports.CommandType.WRAP_FEW_TOKEN] = {
277
+ parser: exports.Parser.Abi,
278
+ params: [{
279
+ name: 'token',
280
+ type: 'address'
281
+ }, {
282
+ name: 'recipient',
283
+ type: 'address'
284
+ }, {
285
+ name: 'amount',
286
+ type: 'uint256'
287
+ }]
288
+ }, _COMMAND_DEFINITION[exports.CommandType.UNWRAP_FEW_TOKEN] = {
289
+ parser: exports.Parser.Abi,
290
+ params: [{
291
+ name: 'wrappedToken',
292
+ type: 'address'
293
+ }, {
294
+ name: 'recipient',
295
+ type: 'address'
296
+ }, {
297
+ name: 'amountMin',
298
+ type: 'uint256'
299
+ }]
300
+ }, _COMMAND_DEFINITION[exports.CommandType.WRAP_ETH] = {
301
+ parser: exports.Parser.Abi,
302
+ params: [{
303
+ name: 'recipient',
304
+ type: 'address'
305
+ }, {
306
+ name: 'amount',
307
+ type: 'uint256'
308
+ }]
309
+ }, _COMMAND_DEFINITION[exports.CommandType.UNWRAP_WETH] = {
310
+ parser: exports.Parser.Abi,
311
+ params: [{
312
+ name: 'recipient',
313
+ type: 'address'
314
+ }, {
315
+ name: 'amountMin',
316
+ type: 'uint256'
317
+ }]
318
+ }, _COMMAND_DEFINITION[exports.CommandType.SWEEP] = {
319
+ parser: exports.Parser.Abi,
320
+ params: [{
321
+ name: 'token',
322
+ type: 'address'
323
+ }, {
324
+ name: 'recipient',
325
+ type: 'address'
326
+ }, {
327
+ name: 'amountMin',
328
+ type: 'uint256'
329
+ }]
330
+ }, _COMMAND_DEFINITION[exports.CommandType.TRANSFER] = {
331
+ parser: exports.Parser.Abi,
332
+ params: [{
333
+ name: 'token',
334
+ type: 'address'
335
+ }, {
336
+ name: 'recipient',
337
+ type: 'address'
338
+ }, {
339
+ name: 'value',
340
+ type: 'uint256'
341
+ }]
342
+ }, _COMMAND_DEFINITION[exports.CommandType.PAY_PORTION] = {
343
+ parser: exports.Parser.Abi,
344
+ params: [{
345
+ name: 'token',
346
+ type: 'address'
347
+ }, {
348
+ name: 'recipient',
349
+ type: 'address'
350
+ }, {
351
+ name: 'bips',
352
+ type: 'uint256'
353
+ }]
354
+ }, _COMMAND_DEFINITION[exports.CommandType.BALANCE_CHECK_ERC20] = {
355
+ parser: exports.Parser.Abi,
356
+ params: [{
357
+ name: 'owner',
358
+ type: 'address'
359
+ }, {
360
+ name: 'token',
361
+ type: 'address'
362
+ }, {
363
+ name: 'minBalance',
364
+ type: 'uint256'
365
+ }]
366
+ }, _COMMAND_DEFINITION[exports.CommandType.V4_INITIALIZE_POOL] = {
367
+ parser: exports.Parser.Abi,
368
+ params: [{
369
+ name: 'poolKey',
370
+ type: POOL_KEY_STRUCT
371
+ }, {
372
+ name: 'sqrtPriceX96',
373
+ type: 'uint160'
374
+ }]
375
+ }, _COMMAND_DEFINITION[exports.CommandType.V3_POSITION_MANAGER_PERMIT] = {
376
+ parser: exports.Parser.V3Actions
377
+ }, _COMMAND_DEFINITION[exports.CommandType.V3_POSITION_MANAGER_CALL] = {
378
+ parser: exports.Parser.V3Actions
379
+ }, _COMMAND_DEFINITION[exports.CommandType.V4_POSITION_MANAGER_CALL] = {
380
+ parser: exports.Parser.V4Actions
381
+ }, _COMMAND_DEFINITION);
382
+ var RoutePlanner = /*#__PURE__*/function () {
383
+ function RoutePlanner() {
384
+ this.commands = '0x';
385
+ this.inputs = [];
386
+ }
387
+ var _proto = RoutePlanner.prototype;
388
+ _proto.addSubPlan = function addSubPlan(subplan) {
389
+ this.addCommand(exports.CommandType.EXECUTE_SUB_PLAN, [subplan.commands, subplan.inputs], true);
390
+ return this;
391
+ };
392
+ _proto.addCommand = function addCommand(type, parameters, allowRevert) {
393
+ if (allowRevert === void 0) {
394
+ allowRevert = false;
395
+ }
396
+ var command = createCommand(type, parameters);
397
+ this.inputs.push(command.encodedInput);
398
+ if (allowRevert) {
399
+ if (!REVERTIBLE_COMMANDS.has(command.type)) {
400
+ throw new Error("command type: " + command.type + " cannot be allowed to revert");
401
+ }
402
+ command.type = command.type | ALLOW_REVERT_FLAG;
403
+ }
404
+ this.commands = this.commands.concat(command.type.toString(16).padStart(2, '0'));
405
+ return this;
406
+ };
407
+ return RoutePlanner;
408
+ }();
409
+ function createCommand(type, parameters) {
410
+ var commandDef = COMMAND_DEFINITION[type];
411
+ switch (commandDef.parser) {
412
+ case exports.Parser.Abi:
413
+ var encodedInput = utils.defaultAbiCoder.encode(commandDef.params.map(function (abi) {
414
+ return abi.type;
415
+ }), parameters);
416
+ return {
417
+ type: type,
418
+ encodedInput: encodedInput
419
+ };
420
+ case exports.Parser.V4Actions:
421
+ // v4 swap data comes pre-encoded at index 0
422
+ return {
423
+ type: type,
424
+ encodedInput: parameters[0]
425
+ };
426
+ case exports.Parser.V3Actions:
427
+ // v4 swap data comes pre-encoded at index 0
428
+ return {
429
+ type: type,
430
+ encodedInput: parameters[0]
431
+ };
432
+ }
433
+ }
434
+
435
+ function getPathCurrency(currency, pool) {
436
+ if (fewV2Sdk.isFewToken(pool.token0.wrapped) || fewV2Sdk.isFewToken(pool.token1.wrapped)) {
437
+ return currency;
438
+ }
439
+ // return currency if the currency matches a currency of the pool
440
+ if (pool.involvesToken(currency)) {
441
+ return currency;
442
+ // return if currency.wrapped if pool involves wrapped currency
443
+ } else if (pool.involvesToken(currency.wrapped)) {
444
+ return currency.wrapped;
445
+ // return native currency if pool involves native version of wrapped currency (only applies to V4)
446
+ } else if (pool instanceof v4Sdk.Pool && pool.token0.wrapped.equals(currency)) {
447
+ return pool.token0;
448
+ } else if (pool instanceof v4Sdk.Pool && pool.token1.wrapped.equals(currency)) {
449
+ return pool.token1;
450
+ } else {
451
+ throw new Error("Expected currency " + currency.symbol + " to be either " + pool.token0.symbol + " or " + pool.token1.symbol);
452
+ }
453
+ }
454
+
455
+ (function (RouterActionType) {
456
+ RouterActionType["UniswapTrade"] = "UniswapTrade";
457
+ RouterActionType["UnwrapWETH"] = "UnwrapWETH";
458
+ })(exports.RouterActionType || (exports.RouterActionType = {}));
459
+
460
+ var _routerConfigs, _routerConfigs2, _routerConfigs3, _routerConfigs4, _routerConfigs5, _routerConfigs6, _routerConfigs7, _routerConfigs8, _routerConfigs9, _routerConfigs0, _routerConfigs1, _routerConfigs10, _routerConfigs11, _routerConfigs12, _routerConfigs13, _routerConfigs14, _routerConfigs15, _routerConfigs16, _routerConfigs17, _routerConfigs18, _routerConfigs19, _routerConfigs20, _routerConfigs21, _routerConfigs22, _routerConfigs23, _routerConfigs24, _CHAIN_CONFIGS;
461
+ (function (UniversalRouterVersion) {
462
+ UniversalRouterVersion["V1_2"] = "1.2";
463
+ UniversalRouterVersion["V2_0"] = "2.0";
464
+ })(exports.UniversalRouterVersion || (exports.UniversalRouterVersion = {}));
465
+ var WETH_NOT_SUPPORTED_ON_CHAIN = '0x0000000000000000000000000000000000000000';
466
+ // Todo: Change `CHAIN_CONFIGS` to pull the UR address with v4
467
+ var CHAIN_CONFIGS = (_CHAIN_CONFIGS = {}, _CHAIN_CONFIGS[1] = {
468
+ weth: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
469
+ routerConfigs: (_routerConfigs = {}, _routerConfigs[exports.UniversalRouterVersion.V1_2] = {
470
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
471
+ creationBlock: 17143817
472
+ }, _routerConfigs[exports.UniversalRouterVersion.V2_0] = {
473
+ address: '0x66a9893cc07d91d95644aedd05d03f95e1dba8af',
474
+ creationBlock: 1737658355
475
+ }, _routerConfigs)
476
+ }, _CHAIN_CONFIGS[5] = {
477
+ weth: '0xb4fbf271143f4fbf7b91a5ded31805e42b2208d6',
478
+ routerConfigs: (_routerConfigs2 = {}, _routerConfigs2[exports.UniversalRouterVersion.V1_2] = {
479
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
480
+ creationBlock: 8940568
481
+ }, _routerConfigs2[exports.UniversalRouterVersion.V2_0] = {
482
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
483
+ creationBlock: 8940568
484
+ }, _routerConfigs2)
485
+ }, _CHAIN_CONFIGS[11155111] = {
486
+ weth: '0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14',
487
+ routerConfigs: (_routerConfigs3 = {}, _routerConfigs3[exports.UniversalRouterVersion.V1_2] = {
488
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
489
+ creationBlock: 3543575
490
+ }, _routerConfigs3[exports.UniversalRouterVersion.V2_0] = {
491
+ address: '0x3a9d48ab9751398bbfa63ad67599bb04e4bdf98b',
492
+ creationBlock: 7259601
493
+ }, _routerConfigs3)
494
+ }, _CHAIN_CONFIGS[137] = {
495
+ weth: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
496
+ routerConfigs: (_routerConfigs4 = {}, _routerConfigs4[exports.UniversalRouterVersion.V1_2] = {
497
+ address: '0xec7BE89e9d109e7e3Fec59c222CF297125FEFda2',
498
+ creationBlock: 52210153
499
+ }, _routerConfigs4[exports.UniversalRouterVersion.V2_0] = {
500
+ address: '0x1095692a6237d83c6a72f3f5efedb9a670c49223',
501
+ creationBlock: 1737492197
502
+ }, _routerConfigs4)
503
+ }, _CHAIN_CONFIGS[80001] = {
504
+ weth: '0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889',
505
+ routerConfigs: (_routerConfigs5 = {}, _routerConfigs5[exports.UniversalRouterVersion.V1_2] = {
506
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
507
+ creationBlock: 35176052
508
+ }, _routerConfigs5[exports.UniversalRouterVersion.V2_0] = {
509
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
510
+ creationBlock: 35176052
511
+ }, _routerConfigs5)
512
+ }, _CHAIN_CONFIGS[10] = {
513
+ weth: '0x4200000000000000000000000000000000000006',
514
+ routerConfigs: (_routerConfigs6 = {}, _routerConfigs6[exports.UniversalRouterVersion.V1_2] = {
515
+ address: '0xCb1355ff08Ab38bBCE60111F1bb2B784bE25D7e8',
516
+ creationBlock: 114702266
517
+ }, _routerConfigs6[exports.UniversalRouterVersion.V2_0] = {
518
+ address: '0x851116d9223fabed8e56c0e6b8ad0c31d98b3507',
519
+ creationBlock: 1737494278
520
+ }, _routerConfigs6)
521
+ }, _CHAIN_CONFIGS[420] = {
522
+ weth: '0x4200000000000000000000000000000000000006',
523
+ routerConfigs: (_routerConfigs7 = {}, _routerConfigs7[exports.UniversalRouterVersion.V1_2] = {
524
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
525
+ creationBlock: 8887728
526
+ }, _routerConfigs7[exports.UniversalRouterVersion.V2_0] = {
527
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
528
+ creationBlock: 8887728
529
+ }, _routerConfigs7)
530
+ }, _CHAIN_CONFIGS[42161] = {
531
+ weth: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
532
+ routerConfigs: (_routerConfigs8 = {}, _routerConfigs8[exports.UniversalRouterVersion.V1_2] = {
533
+ address: '0x5E325eDA8064b456f4781070C0738d849c824258',
534
+ creationBlock: 169472836
535
+ }, _routerConfigs8[exports.UniversalRouterVersion.V2_0] = {
536
+ address: '0xa51afafe0263b40edaef0df8781ea9aa03e381a3',
537
+ creationBlock: 1737487458
538
+ }, _routerConfigs8)
539
+ }, _CHAIN_CONFIGS[421613] = {
540
+ weth: '0xe39Ab88f8A4777030A534146A9Ca3B52bd5D43A3',
541
+ routerConfigs: (_routerConfigs9 = {}, _routerConfigs9[exports.UniversalRouterVersion.V1_2] = {
542
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
543
+ creationBlock: 18815277
544
+ }, _routerConfigs9[exports.UniversalRouterVersion.V2_0] = {
545
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
546
+ creationBlock: 18815277
547
+ }, _routerConfigs9)
548
+ }, _CHAIN_CONFIGS[42220] = {
549
+ weth: WETH_NOT_SUPPORTED_ON_CHAIN,
550
+ routerConfigs: (_routerConfigs0 = {}, _routerConfigs0[exports.UniversalRouterVersion.V1_2] = {
551
+ address: '0x643770e279d5d0733f21d6dc03a8efbabf3255b4',
552
+ creationBlock: 21407637
553
+ }, _routerConfigs0[exports.UniversalRouterVersion.V2_0] = {
554
+ address: '0x643770e279d5d0733f21d6dc03a8efbabf3255b4',
555
+ creationBlock: 21407637
556
+ }, _routerConfigs0)
557
+ }, _CHAIN_CONFIGS[44787] = {
558
+ weth: WETH_NOT_SUPPORTED_ON_CHAIN,
559
+ routerConfigs: (_routerConfigs1 = {}, _routerConfigs1[exports.UniversalRouterVersion.V1_2] = {
560
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
561
+ creationBlock: 17566658
562
+ }, _routerConfigs1[exports.UniversalRouterVersion.V2_0] = {
563
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
564
+ creationBlock: 17566658
565
+ }, _routerConfigs1)
566
+ }, _CHAIN_CONFIGS[56] = {
567
+ weth: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',
568
+ routerConfigs: (_routerConfigs10 = {}, _routerConfigs10[exports.UniversalRouterVersion.V1_2] = {
569
+ address: '0x4Dae2f939ACf50408e13d58534Ff8c2776d45265',
570
+ creationBlock: 35160263
571
+ }, _routerConfigs10[exports.UniversalRouterVersion.V2_0] = {
572
+ address: '0x1906c1d672b88cd1b9ac7593301ca990f94eae07',
573
+ creationBlock: 1737493275
574
+ }, _routerConfigs10)
575
+ }, _CHAIN_CONFIGS[43114] = {
576
+ weth: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7',
577
+ routerConfigs: (_routerConfigs11 = {}, _routerConfigs11[exports.UniversalRouterVersion.V1_2] = {
578
+ address: '0x4Dae2f939ACf50408e13d58534Ff8c2776d45265',
579
+ creationBlock: 40237257
580
+ }, _routerConfigs11[exports.UniversalRouterVersion.V2_0] = {
581
+ address: '0x94b75331ae8d42c1b61065089b7d48fe14aa73b7',
582
+ creationBlock: 1737558236
583
+ }, _routerConfigs11)
584
+ }, _CHAIN_CONFIGS[84531] = {
585
+ weth: '0x4200000000000000000000000000000000000006',
586
+ routerConfigs: (_routerConfigs12 = {}, _routerConfigs12[exports.UniversalRouterVersion.V1_2] = {
587
+ address: '0xd0872d928672ae2ff74bdb2f5130ac12229cafaf',
588
+ creationBlock: 6915289
589
+ }, _routerConfigs12[exports.UniversalRouterVersion.V2_0] = {
590
+ address: '0xd0872d928672ae2ff74bdb2f5130ac12229cafaf',
591
+ creationBlock: 6915289
592
+ }, _routerConfigs12)
593
+ }, _CHAIN_CONFIGS[8453] = {
594
+ weth: '0x4200000000000000000000000000000000000006',
595
+ routerConfigs: (_routerConfigs13 = {}, _routerConfigs13[exports.UniversalRouterVersion.V1_2] = {
596
+ address: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
597
+ creationBlock: 9107268
598
+ }, _routerConfigs13[exports.UniversalRouterVersion.V2_0] = {
599
+ address: '0x6ff5693b99212da76ad316178a184ab56d299b43',
600
+ creationBlock: 1737491485
601
+ }, _routerConfigs13)
602
+ }, _CHAIN_CONFIGS[81457] = {
603
+ weth: '0x4300000000000000000000000000000000000004',
604
+ routerConfigs: (_routerConfigs14 = {}, _routerConfigs14[exports.UniversalRouterVersion.V1_2] = {
605
+ address: '0x643770E279d5D0733F21d6DC03A8efbABf3255B4',
606
+ creationBlock: 1116444
607
+ }, _routerConfigs14[exports.UniversalRouterVersion.V2_0] = {
608
+ address: '0xeabbcb3e8e415306207ef514f660a3f820025be3',
609
+ creationBlock: 1737564586
610
+ }, _routerConfigs14)
611
+ }, _CHAIN_CONFIGS[7777777] = {
612
+ weth: '0x4200000000000000000000000000000000000006',
613
+ routerConfigs: (_routerConfigs15 = {}, _routerConfigs15[exports.UniversalRouterVersion.V1_2] = {
614
+ address: '0x2986d9721A49838ab4297b695858aF7F17f38014',
615
+ creationBlock: 11832155
616
+ }, _routerConfigs15[exports.UniversalRouterVersion.V2_0] = {
617
+ address: '0x3315ef7ca28db74abadc6c44570efdf06b04b020',
618
+ creationBlock: 1737562927
619
+ }, _routerConfigs15)
620
+ }, _CHAIN_CONFIGS[324] = {
621
+ weth: '0x5aea5775959fbc2557cc8789bc1bf90a239d9a91',
622
+ routerConfigs: (_routerConfigs16 = {}, _routerConfigs16[exports.UniversalRouterVersion.V1_2] = {
623
+ address: '0x28731BCC616B5f51dD52CF2e4dF0E78dD1136C06',
624
+ creationBlock: 12640979
625
+ }, _routerConfigs16[exports.UniversalRouterVersion.V2_0] = {
626
+ address: '0x28731BCC616B5f51dD52CF2e4dF0E78dD1136C06',
627
+ creationBlock: 12640979
628
+ }, _routerConfigs16)
629
+ }, _CHAIN_CONFIGS[480] = {
630
+ weth: '0x4200000000000000000000000000000000000006',
631
+ routerConfigs: (_routerConfigs17 = {}, _routerConfigs17[exports.UniversalRouterVersion.V1_2] = {
632
+ address: '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
633
+ creationBlock: 4063979
634
+ }, _routerConfigs17[exports.UniversalRouterVersion.V2_0] = {
635
+ address: '0x8ac7bee993bb44dab564ea4bc9ea67bf9eb5e743',
636
+ creationBlock: 1737559557
637
+ }, _routerConfigs17)
638
+ }, _CHAIN_CONFIGS[1301] = {
639
+ weth: '0x4200000000000000000000000000000000000006',
640
+ routerConfigs: (_routerConfigs18 = {}, _routerConfigs18[exports.UniversalRouterVersion.V1_2] = {
641
+ address: '0x8909Dc15e40173Ff4699343b6eB8132c65e18eC6',
642
+ creationBlock: 1241811
643
+ }, _routerConfigs18[exports.UniversalRouterVersion.V2_0] = {
644
+ address: '0xf70536b3bcc1bd1a972dc186a2cf84cc6da6be5d',
645
+ creationBlock: 7100543
646
+ }, _routerConfigs18)
647
+ }, _CHAIN_CONFIGS[130] = {
648
+ weth: '0x4200000000000000000000000000000000000006',
649
+ routerConfigs: (_routerConfigs19 = {}, _routerConfigs19[exports.UniversalRouterVersion.V1_2] = {
650
+ address: '0x4D73A4411CA1c660035e4AECC8270E5DdDEC8C17',
651
+ creationBlock: 23678
652
+ }, _routerConfigs19[exports.UniversalRouterVersion.V2_0] = {
653
+ address: '0xef740bf23acae26f6492b10de645d6b98dc8eaf3',
654
+ creationBlock: 1737568156
655
+ }, _routerConfigs19)
656
+ }, _CHAIN_CONFIGS[10143] = {
657
+ weth: '0x760AfE86e5de5fa0Ee542fc7B7B713e1c5425701',
658
+ routerConfigs: (_routerConfigs20 = {}, _routerConfigs20[exports.UniversalRouterVersion.V1_2] = {
659
+ address: '0x3ae6d8a282d67893e17aa70ebffb33ee5aa65893',
660
+ creationBlock: 23678
661
+ }, _routerConfigs20[exports.UniversalRouterVersion.V2_0] = {
662
+ address: '0x3ae6d8a282d67893e17aa70ebffb33ee5aa65893',
663
+ creationBlock: 23678
664
+ }, _routerConfigs20)
665
+ }, _CHAIN_CONFIGS[84532] = {
666
+ weth: '0x4200000000000000000000000000000000000006',
667
+ routerConfigs: (_routerConfigs21 = {}, _routerConfigs21[exports.UniversalRouterVersion.V1_2] = {
668
+ address: '0x492e6456d9528771018deb9e87ef7750ef184104',
669
+ creationBlock: 20216585
670
+ }, _routerConfigs21[exports.UniversalRouterVersion.V2_0] = {
671
+ address: '0x492e6456d9528771018deb9e87ef7750ef184104',
672
+ creationBlock: 20216585
673
+ }, _routerConfigs21)
674
+ }, _CHAIN_CONFIGS[1868] = {
675
+ weth: '0x4200000000000000000000000000000000000006',
676
+ routerConfigs: (_routerConfigs22 = {}, _routerConfigs22[exports.UniversalRouterVersion.V1_2] = {
677
+ address: '0x0e2850543f69f678257266e0907ff9a58b3f13de',
678
+ creationBlock: 3254782
679
+ }, _routerConfigs22[exports.UniversalRouterVersion.V2_0] = {
680
+ address: '0x0e2850543f69f678257266e0907ff9a58b3f13de',
681
+ creationBlock: 3254782
682
+ }, _routerConfigs22)
683
+ }, _CHAIN_CONFIGS[143] = {
684
+ weth: '0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A',
685
+ routerConfigs: (_routerConfigs23 = {}, _routerConfigs23[exports.UniversalRouterVersion.V1_2] = {
686
+ address: '0x0d97dc33264bfc1c226207428a79b26757fb9dc3',
687
+ creationBlock: 29255937
688
+ }, _routerConfigs23[exports.UniversalRouterVersion.V2_0] = {
689
+ address: '0x0d97dc33264bfc1c226207428a79b26757fb9dc3',
690
+ creationBlock: 29255937
691
+ }, _routerConfigs23)
692
+ }, _CHAIN_CONFIGS[999] = {
693
+ weth: '0x5555555555555555555555555555555555555555',
694
+ routerConfigs: (_routerConfigs24 = {}, _routerConfigs24[exports.UniversalRouterVersion.V1_2] = {
695
+ address: '0x7d3D28dee339C17452A4d6b53C71b2557278B530',
696
+ creationBlock: 9273064
697
+ }, _routerConfigs24[exports.UniversalRouterVersion.V2_0] = {
698
+ address: '0x7d3D28dee339C17452A4d6b53C71b2557278B530',
699
+ creationBlock: 9273064
700
+ }, _routerConfigs24)
701
+ }, _CHAIN_CONFIGS);
702
+ var UNIVERSAL_ROUTER_ADDRESS = function UNIVERSAL_ROUTER_ADDRESS(version, chainId) {
703
+ if (!(chainId in CHAIN_CONFIGS)) throw new Error("Universal Router not deployed on chain " + chainId);
704
+ return CHAIN_CONFIGS[chainId].routerConfigs[version].address;
705
+ };
706
+ var UNIVERSAL_ROUTER_CREATION_BLOCK = function UNIVERSAL_ROUTER_CREATION_BLOCK(version, chainId) {
707
+ if (!(chainId in CHAIN_CONFIGS)) throw new Error("Universal Router not deployed on chain " + chainId);
708
+ return CHAIN_CONFIGS[chainId].routerConfigs[version].creationBlock;
709
+ };
710
+ var WETH_ADDRESS = function WETH_ADDRESS(chainId) {
711
+ if (!(chainId in CHAIN_CONFIGS)) throw new Error("Universal Router not deployed on chain " + chainId);
712
+ if (CHAIN_CONFIGS[chainId].weth == WETH_NOT_SUPPORTED_ON_CHAIN) throw new Error("Chain " + chainId + " does not have WETH");
713
+ return CHAIN_CONFIGS[chainId].weth;
714
+ };
715
+ var CONTRACT_BALANCE = /*#__PURE__*/ethers.BigNumber.from(2).pow(255);
716
+ var ETH_ADDRESS = '0x0000000000000000000000000000000000000000';
717
+ var E_ETH_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
718
+ var SENDER_AS_RECIPIENT = '0x0000000000000000000000000000000000000001';
719
+ var ROUTER_AS_RECIPIENT = '0x0000000000000000000000000000000000000002';
720
+
721
+ function getCurrencyAddress(currency) {
722
+ return currency.isNative ? ETH_ADDRESS : currency.wrapped.address;
723
+ }
724
+
725
+ function encodeFeeBips(fee) {
726
+ return v3Sdk.toHex(fee.multiply(10000).quotient);
727
+ }
728
+
729
+ var _FEW_WRAPPED_NATIVE_C;
730
+ var FEW_WRAPPED_NATIVE_CURRENCY = (_FEW_WRAPPED_NATIVE_C = {}, _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.HYPER_MAINNET] = /*#__PURE__*/new sdkCore.Token(999, '0x9e1148bC3665a9f7C35F313d89c0432c34928AEf', 18, 'fwWHYPE', 'Few Wrapped Wrapped Hyper'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.MAINNET] = /*#__PURE__*/new sdkCore.Token(1, '0xa250CC729Bb3323e7933022a67B52200fE354767', 18, 'fwWETH', 'Few Wrapped Wrapped Ether'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.BASE] = /*#__PURE__*/new sdkCore.Token(8453, '0xd38e4149df30AfFFEE13d771f3Ec9277c72333E4', 18, 'fwWETH', 'Few Wrapped Wrapped Ether'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.ARBITRUM_ONE] = /*#__PURE__*/new sdkCore.Token(42161, '0x76CDff74222533Efa4BAa713BC3d14df81A460F7', 18, 'fwWETH', 'Few Wrapped Wrapped Ether'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.ARBITRUM_SEPOLIA] = /*#__PURE__*/new sdkCore.Token(421614, '0x1fc632A9A9c99ae7C406f8565cd709b52BA0ed47', 18, 'fwWETH', 'Few Wrapped Wrapped Ether'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.UNICHAIN] = /*#__PURE__*/new sdkCore.Token(130, '0x05e6c1B4Da05c41c86c35Ce42a8a222C1a450167', 18, 'fwWETH', 'Few Wrapped Wrapped Ether'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.UNICHAIN_SEPOLIA] = /*#__PURE__*/new sdkCore.Token(1301, '0x1fc632A9A9c99ae7C406f8565cd709b52BA0ed47',
731
+ //TODO: replace to mainnet
732
+ 18, 'fwWETH', 'Few Wrapped Wrapped Ether'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.GOERLI] = /*#__PURE__*/new sdkCore.Token(5, '0x6b7e07C37a157d01D71012c36644907Ab5a7694e', 18, 'fwWETH', 'Few Wrapped Wrapped Ether'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.BLAST] = /*#__PURE__*/new sdkCore.Token(81457, '0x66714DB8F3397c767d0A602458B5b4E3C0FE7dd1', 18, 'fwWETH', 'Few Wrapped Wrapped Ether'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.SEPOLIA] = /*#__PURE__*/new sdkCore.Token(11155111, '0x98b902eF4f9fEB2F6982ceEB4E98761294854D61', 18, 'fwWETH', 'Few Wrapped Wrapped Ether'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.BLAST_SEPOLIA] = /*#__PURE__*/new sdkCore.Token(sdkCore.ChainId.BLAST_SEPOLIA, '0x798dE0520497E28E8eBfF0DF1d791c2E942eA881', 18, 'fwWETH', 'Few Wrapped Wrapped Ether'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.STORY_ODYSSEY] = /*#__PURE__*/new sdkCore.Token(sdkCore.ChainId.STORY_ODYSSEY, '0xA67013F71AF4f21563BAf8C1d156F1Dc7ab681C6', 18, 'fwWIP', 'Few Wrapped Wrapped IP'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.STORY_MAINNET] = /*#__PURE__*/new sdkCore.Token(sdkCore.ChainId.STORY_MAINNET, '0x088dE218b725975E6285995C25Ce3706BAe0f4Ec', 18, 'fwWIP', 'Few Wrapped Wrapped IP'), _FEW_WRAPPED_NATIVE_C[sdkCore.ChainId.BNB] = /*#__PURE__*/new sdkCore.Token(56, '0x7f0172b75d3823D8aF04feE3A3f6a14aBD68EFE1', 18, 'fwWBNB', 'Few Wrapped Wrapped BNB'), _FEW_WRAPPED_NATIVE_C);
733
+
734
+ var REFUND_ETH_PRICE_IMPACT_THRESHOLD = /*#__PURE__*/new sdkCore.Percent(50, 100);
735
+ // Wrapper for uniswap router-sdk trade entity to encode swaps for Universal Router
736
+ // also translates trade objects from previous (v2, v3) SDKs
737
+ var UniswapTrade = /*#__PURE__*/function () {
738
+ function UniswapTrade(trade, options) {
739
+ this.trade = trade;
740
+ this.options = options;
741
+ this.tradeType = exports.RouterActionType.UniswapTrade;
742
+ if (!!options.fee && !!options.flatFee) throw new Error('Only one fee option permitted');
743
+ if (this.inputRequiresWrap || this.inputRequiresUnwrap || this.options.useRouterBalance) {
744
+ this.payerIsUser = false;
745
+ } else {
746
+ this.payerIsUser = true;
747
+ }
748
+ }
749
+ var _proto = UniswapTrade.prototype;
750
+ _proto.encode = function encode(planner, _config) {
751
+ var _this$options$recipie;
752
+ // If the input currency is the native currency, we need to wrap it with the router as the recipient
753
+ if (this.inputRequiresWrap) {
754
+ // TODO: optimize if only one v2 pool we can directly send this to the pool
755
+ planner.addCommand(exports.CommandType.WRAP_ETH, [ROUTER_AS_RECIPIENT, this.trade.maximumAmountIn(this.options.slippageTolerance).quotient.toString()]);
756
+ } else if (this.inputRequiresUnwrap) {
757
+ // send wrapped token to router to unwrap
758
+ planner.addCommand(exports.CommandType.PERMIT2_TRANSFER_FROM, [this.trade.inputAmount.currency.address, ROUTER_AS_RECIPIENT, this.trade.maximumAmountIn(this.options.slippageTolerance).quotient.toString()]);
759
+ planner.addCommand(exports.CommandType.UNWRAP_WETH, [ROUTER_AS_RECIPIENT, 0]);
760
+ }
761
+ // The overall recipient at the end of the trade, SENDER_AS_RECIPIENT uses the msg.sender
762
+ this.options.recipient = (_this$options$recipie = this.options.recipient) != null ? _this$options$recipie : SENDER_AS_RECIPIENT;
763
+ // flag for whether we want to perform slippage check on aggregate output of multiple routes
764
+ // 1. when there are >2 exact input trades. this is only a heuristic,
765
+ // as it's still more gas-expensive even in this case, but has benefits
766
+ // in that the reversion probability is lower
767
+ var performAggregatedSlippageCheck = this.trade.tradeType === sdkCore.TradeType.EXACT_INPUT && this.trade.routes.length > 2;
768
+ var routerMustCustody = performAggregatedSlippageCheck || this.outputRequiresTransition || hasFeeOption(this.options);
769
+ for (var _iterator = _createForOfIteratorHelperLoose(this.trade.swaps), _step; !(_step = _iterator()).done;) {
770
+ var swap = _step.value;
771
+ switch (swap.route.protocol) {
772
+ case routerSdk.Protocol.FEWV2:
773
+ addRingV2Swap(planner, swap, this.trade.tradeType, this.options, this.payerIsUser, routerMustCustody);
774
+ break;
775
+ case routerSdk.Protocol.V2:
776
+ addV2Swap(planner, swap, this.trade.tradeType, this.options, this.payerIsUser, routerMustCustody);
777
+ break;
778
+ case routerSdk.Protocol.V3:
779
+ addV3Swap(planner, swap, this.trade.tradeType, this.options, this.payerIsUser, routerMustCustody);
780
+ break;
781
+ case routerSdk.Protocol.V4:
782
+ addV4Swap(this.trade.swaps, planner, swap, this.trade.tradeType, this.options, this.payerIsUser, routerMustCustody);
783
+ break;
784
+ case routerSdk.Protocol.MIXED:
785
+ addMixedSwap(this.trade.swaps, planner, swap, this.trade.tradeType, this.options, this.payerIsUser, routerMustCustody);
786
+ break;
787
+ default:
788
+ throw new Error('UNSUPPORTED_TRADE_PROTOCOL');
789
+ }
790
+ }
791
+ var minimumAmountOut = ethers.BigNumber.from(this.trade.minimumAmountOut(this.options.slippageTolerance).quotient.toString());
792
+ // The router custodies for 3 reasons: to unwrap, to take a fee, and/or to do a slippage check
793
+ if (routerMustCustody) {
794
+ var pools = this.trade.swaps[0].route.pools;
795
+ var pathOutputCurrencyAddress = getCurrencyAddress(getPathCurrency(this.trade.outputAmount.currency, pools[pools.length - 1]));
796
+ // If there is a fee, that percentage is sent to the fee recipient
797
+ // In the case where ETH is the output currency, the fee is taken in WETH (for gas reasons)
798
+ if (!!this.options.fee) {
799
+ var feeBips = encodeFeeBips(this.options.fee.fee);
800
+ planner.addCommand(exports.CommandType.PAY_PORTION, [pathOutputCurrencyAddress, this.options.fee.recipient, feeBips]);
801
+ // If the trade is exact output, and a fee was taken, we must adjust the amount out to be the amount after the fee
802
+ // Otherwise we continue as expected with the trade's normal expected output
803
+ if (this.trade.tradeType === sdkCore.TradeType.EXACT_OUTPUT) {
804
+ minimumAmountOut = minimumAmountOut.sub(minimumAmountOut.mul(feeBips).div(10000));
805
+ }
806
+ }
807
+ // If there is a flat fee, that absolute amount is sent to the fee recipient
808
+ // In the case where ETH is the output currency, the fee is taken in WETH (for gas reasons)
809
+ if (!!this.options.flatFee) {
810
+ var feeAmount = this.options.flatFee.amount;
811
+ if (minimumAmountOut.lt(feeAmount)) throw new Error('Flat fee amount greater than minimumAmountOut');
812
+ planner.addCommand(exports.CommandType.TRANSFER, [pathOutputCurrencyAddress, this.options.flatFee.recipient, feeAmount]);
813
+ // If the trade is exact output, and a fee was taken, we must adjust the amount out to be the amount after the fee
814
+ // Otherwise we continue as expected with the trade's normal expected output
815
+ if (this.trade.tradeType === sdkCore.TradeType.EXACT_OUTPUT) {
816
+ minimumAmountOut = minimumAmountOut.sub(feeAmount);
817
+ }
818
+ }
819
+ // The remaining tokens that need to be sent to the user after the fee is taken will be caught
820
+ // by this if-else clause.
821
+ if (this.outputRequiresUnwrap) {
822
+ planner.addCommand(exports.CommandType.UNWRAP_WETH, [this.options.recipient, '0']);
823
+ planner.addCommand(exports.CommandType.SWEEP, [getCurrencyAddress(this.trade.outputAmount.currency), SENDER_AS_RECIPIENT, '0']);
824
+ } else if (this.outputRequiresWrap) {
825
+ planner.addCommand(exports.CommandType.WRAP_ETH, [this.options.recipient, CONTRACT_BALANCE]);
826
+ } else {
827
+ if (this.hasFewV2) {
828
+ planner.addCommand(exports.CommandType.SWEEP, [getCurrencyAddress(this.trade.outputAmount.currency), this.options.recipient, '0']);
829
+ } else {
830
+ planner.addCommand(exports.CommandType.SWEEP, [getCurrencyAddress(this.trade.outputAmount.currency), this.options.recipient, minimumAmountOut]);
831
+ }
832
+ }
833
+ }
834
+ var fwWETH = FEW_WRAPPED_NATIVE_CURRENCY[this.trade.inputAmount.currency.wrapped.chainId];
835
+ // for exactOutput swaps with native input or that perform an inputToken transition (wrap or unwrap)
836
+ // we need to send back the change to the user
837
+ if (this.trade.tradeType === sdkCore.TradeType.EXACT_OUTPUT || riskOfPartialFill(this.trade)) {
838
+ if (this.inputRequiresWrap) {
839
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [fwWETH.address, ROUTER_AS_RECIPIENT, '0']);
840
+ planner.addCommand(exports.CommandType.UNWRAP_WETH, [this.options.recipient, 0]);
841
+ planner.addCommand(exports.CommandType.SWEEP, [ETH_ADDRESS, this.options.recipient, 0]);
842
+ } else if (this.inputRequiresUnwrap) {
843
+ planner.addCommand(exports.CommandType.WRAP_ETH, [this.options.recipient, CONTRACT_BALANCE]);
844
+ } else if (this.trade.inputAmount.currency.isNative) {
845
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [fwWETH.address, ROUTER_AS_RECIPIENT, '0']);
846
+ planner.addCommand(exports.CommandType.UNWRAP_WETH, [SENDER_AS_RECIPIENT, 0]);
847
+ // must refund extra native currency sent along for native v4 trades (no input transition)
848
+ planner.addCommand(exports.CommandType.SWEEP, [ETH_ADDRESS, this.options.recipient, 0]);
849
+ }
850
+ planner.addCommand(exports.CommandType.SWEEP, [this.trade.inputAmount.currency.wrapped.address, SENDER_AS_RECIPIENT, '0']);
851
+ planner.addCommand(exports.CommandType.SWEEP, [this.trade.outputAmount.currency.wrapped.address, SENDER_AS_RECIPIENT, '0']);
852
+ }
853
+ if (this.options.safeMode) planner.addCommand(exports.CommandType.SWEEP, [ETH_ADDRESS, this.options.recipient, 0]);
854
+ };
855
+ return _createClass(UniswapTrade, [{
856
+ key: "isAllV4",
857
+ get: function get() {
858
+ var result = true;
859
+ for (var _iterator2 = _createForOfIteratorHelperLoose(this.trade.swaps), _step2; !(_step2 = _iterator2()).done;) {
860
+ var swap = _step2.value;
861
+ result = result && swap.route.protocol == routerSdk.Protocol.V4;
862
+ }
863
+ return result;
864
+ }
865
+ }, {
866
+ key: "hasFewV2",
867
+ get: function get() {
868
+ var result = false;
869
+ for (var _iterator3 = _createForOfIteratorHelperLoose(this.trade.swaps), _step3; !(_step3 = _iterator3()).done;) {
870
+ var swap = _step3.value;
871
+ result = result || swap.route.protocol == routerSdk.Protocol.FEWV2;
872
+ }
873
+ return result;
874
+ }
875
+ // this.trade.swaps is an array of swaps / trades.
876
+ // we are iterating over one swap (trade) at a time so length is 1
877
+ // route is either v2, v3, v4, or mixed
878
+ // pathInput and pathOutput are the currencies of the input and output of the route
879
+ // this.trade.inputAmount is the input currency of the trade (could be different from pathInput)
880
+ // this.trade.outputAmount is the output currency of the trade (could be different from pathOutput)
881
+ // each route can have multiple pools
882
+ }, {
883
+ key: "inputRequiresWrap",
884
+ get: function get() {
885
+ var swap = this.trade.swaps[0];
886
+ var route = swap.route;
887
+ var firstPool = route.pools[0];
888
+ if (firstPool instanceof v4Sdk.Pool) {
889
+ // If first pool is a v4 pool and input currency is native and the path input currency in the route is not native, we need to wrap.
890
+ return this.trade.inputAmount.currency.isNative && !this.trade.swaps[0].route.pathInput.isNative;
891
+ }
892
+ // If first pool is not a v4 pool and input currency is native, we need to wrap
893
+ return this.trade.inputAmount.currency.isNative;
894
+ }
895
+ }, {
896
+ key: "inputRequiresUnwrap",
897
+ get: function get() {
898
+ var swap = this.trade.swaps[0];
899
+ var route = swap.route;
900
+ var firstPool = route.pools[0];
901
+ if (firstPool instanceof v4Sdk.Pool) {
902
+ // If the first pool is a v4 pool and input currency is not native and the path input currency is native, we need to unwrap
903
+ return !this.trade.inputAmount.currency.isNative && this.trade.swaps[0].route.pathInput.isNative;
904
+ }
905
+ // If the first pool is not a v4 pool, we don't need to unwrap.
906
+ return false;
907
+ }
908
+ }, {
909
+ key: "outputRequiresWrap",
910
+ get: function get() {
911
+ var swap = this.trade.swaps[0];
912
+ var lastRoute = swap.route;
913
+ var lastPool = lastRoute.pools[lastRoute.pools.length - 1];
914
+ // if last pool is v4:
915
+ if (lastPool instanceof v4Sdk.Pool) {
916
+ // If output currency is not native but path currency output is native, we need to wrap
917
+ return !this.trade.outputAmount.currency.isNative && lastRoute.pathOutput.isNative;
918
+ }
919
+ // if last pool is not v4:
920
+ // we do not need to wrap because v2 and v3 pools already require wrapped tokens
921
+ return false;
922
+ }
923
+ }, {
924
+ key: "outputRequiresUnwrap",
925
+ get: function get() {
926
+ var swap = this.trade.swaps[0];
927
+ var lastRoute = swap.route;
928
+ var lastPool = lastRoute.pools[lastRoute.pools.length - 1];
929
+ // if last pool is v4:
930
+ if (lastPool instanceof v4Sdk.Pool) {
931
+ // If output currency is native and path currency output is not native, we need to unwrap
932
+ return this.trade.outputAmount.currency.isNative && !this.trade.swaps[0].route.pathOutput.isNative;
933
+ }
934
+ // else: if path output currency is native, we need to unwrap because v2 and v3 pools already require wrapped tokens
935
+ return this.trade.outputAmount.currency.isNative;
936
+ }
937
+ }, {
938
+ key: "outputRequiresTransition",
939
+ get: function get() {
940
+ return this.outputRequiresWrap || this.outputRequiresUnwrap;
941
+ }
942
+ }]);
943
+ }();
944
+ // encode a ring v2 swap
945
+ function addRingV2Swap(planner, _ref, tradeType, options, payerIsUser, routerMustCustody) {
946
+ var route = _ref.route,
947
+ inputAmount = _ref.inputAmount,
948
+ outputAmount = _ref.outputAmount;
949
+ var trade = new fewV2Sdk.Trade(route, tradeType == sdkCore.TradeType.EXACT_INPUT ? inputAmount : outputAmount, tradeType);
950
+ var pathInput = route.path[0];
951
+ var pathOutput = route.path[route.path.length - 1];
952
+ if (!trade.inputAmount.currency.isNative) {
953
+ // send wrapped token to router to unwrap
954
+ planner.addCommand(exports.CommandType.PERMIT2_TRANSFER_FROM, [trade.inputAmount.currency.address, ROUTER_AS_RECIPIENT, trade.maximumAmountIn(options.slippageTolerance).quotient.toString()]);
955
+ }
956
+ planner.addCommand(exports.CommandType.WRAP_FEW_TOKEN, [trade.inputAmount.currency.wrapped.address, ROUTER_AS_RECIPIENT, trade.inputAmount.quotient.toString()]);
957
+ payerIsUser = false;
958
+ routerMustCustody = true; // TOTO, check again
959
+ if (tradeType == sdkCore.TradeType.EXACT_INPUT) {
960
+ planner.addCommand(exports.CommandType.FEW_V2_SWAP_EXACT_IN, [
961
+ // if native, we have to unwrap so keep in the router for now
962
+ routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient, trade.maximumAmountIn(options.slippageTolerance).quotient.toString(),
963
+ // if router will custody funds, we do aggregated slippage check from router
964
+ routerMustCustody ? 0 : trade.minimumAmountOut(options.slippageTolerance).quotient.toString(), route.path.map(function (token) {
965
+ return token.wrapped.address;
966
+ }), payerIsUser]);
967
+ } else if (tradeType == sdkCore.TradeType.EXACT_OUTPUT) {
968
+ planner.addCommand(exports.CommandType.FEW_V2_SWAP_EXACT_OUT, [routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient, trade.minimumAmountOut(options.slippageTolerance).quotient.toString(), trade.maximumAmountIn(options.slippageTolerance).quotient.toString(), route.path.map(function (token) {
969
+ return token.wrapped.address;
970
+ }), payerIsUser]);
971
+ }
972
+ var fewOutputToken = fewV2Sdk.getFewTokenFromOriginalToken(trade.outputAmount.currency.wrapped, trade.outputAmount.currency.chainId);
973
+ var fwWETH = FEW_WRAPPED_NATIVE_CURRENCY[trade.inputAmount.currency.wrapped.chainId];
974
+ if (outputAmount.currency.isNative) {
975
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [fwWETH.address, ROUTER_AS_RECIPIENT, trade.minimumAmountOut(options.slippageTolerance).quotient.toString()]);
976
+ } else {
977
+ if (fewV2Sdk.isFewToken(route.pathInput.wrapped) && fewV2Sdk.isFewToken(route.pathOutput.wrapped)) {
978
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [fewOutputToken.address, SENDER_AS_RECIPIENT, trade.minimumAmountOut(options.slippageTolerance).quotient.toString()]);
979
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [pathInput.wrapped.address, SENDER_AS_RECIPIENT, '0']);
980
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [pathOutput.wrapped.address, SENDER_AS_RECIPIENT, '0']);
981
+ }
982
+ }
983
+ }
984
+ // encode a uniswap v2 swap
985
+ function addV2Swap(planner, _ref2, tradeType, options, payerIsUser, routerMustCustody) {
986
+ var route = _ref2.route,
987
+ inputAmount = _ref2.inputAmount,
988
+ outputAmount = _ref2.outputAmount;
989
+ var trade = new v2Sdk.Trade(route, tradeType == sdkCore.TradeType.EXACT_INPUT ? inputAmount : outputAmount, tradeType);
990
+ var pathInput = route.path[0];
991
+ var pathOutput = route.path[route.path.length - 1];
992
+ if (fewV2Sdk.isFewToken(route.pathInput.wrapped) && fewV2Sdk.isFewToken(route.pathOutput.wrapped)) {
993
+ if (!trade.inputAmount.currency.isNative) {
994
+ // send wrapped token to router to unwrap
995
+ planner.addCommand(exports.CommandType.PERMIT2_TRANSFER_FROM, [trade.inputAmount.currency.address, ROUTER_AS_RECIPIENT, trade.maximumAmountIn(options.slippageTolerance).quotient.toString()]);
996
+ }
997
+ planner.addCommand(exports.CommandType.WRAP_FEW_TOKEN, [trade.inputAmount.currency.wrapped.address, ROUTER_AS_RECIPIENT, trade.inputAmount.currency.isNative ? CONTRACT_BALANCE : trade.inputAmount.quotient.toString()]);
998
+ payerIsUser = false;
999
+ routerMustCustody = true; // TOTO, check again
1000
+ if (tradeType == sdkCore.TradeType.EXACT_INPUT) {
1001
+ planner.addCommand(exports.CommandType.V2_SWAP_EXACT_IN, [
1002
+ // if native, we have to unwrap so keep in the router for now
1003
+ routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient, trade.maximumAmountIn(options.slippageTolerance).quotient.toString(),
1004
+ // if router will custody funds, we do aggregated slippage check from router
1005
+ routerMustCustody ? 0 : trade.minimumAmountOut(options.slippageTolerance).quotient.toString(), route.path.map(function (token) {
1006
+ return token.wrapped.address;
1007
+ }), payerIsUser]);
1008
+ } else if (tradeType == sdkCore.TradeType.EXACT_OUTPUT) {
1009
+ planner.addCommand(exports.CommandType.V2_SWAP_EXACT_OUT, [routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient, trade.minimumAmountOut(options.slippageTolerance).quotient.toString(), trade.maximumAmountIn(options.slippageTolerance).quotient.toString(), route.path.map(function (token) {
1010
+ return token.wrapped.address;
1011
+ }), payerIsUser]);
1012
+ }
1013
+ var fewOutputToken = fewV2Sdk.getFewTokenFromOriginalToken(trade.outputAmount.currency.wrapped, trade.outputAmount.currency.chainId);
1014
+ if (fewV2Sdk.isFewToken(pathInput.wrapped) && fewV2Sdk.isFewToken(pathOutput.wrapped)) {
1015
+ if (outputAmount.currency.isNative) {
1016
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [fewOutputToken.address, ROUTER_AS_RECIPIENT, trade.minimumAmountOut(options.slippageTolerance).quotient.toString()]);
1017
+ } else {
1018
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [fewOutputToken.address, SENDER_AS_RECIPIENT, trade.minimumAmountOut(options.slippageTolerance).quotient.toString()]);
1019
+ }
1020
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [pathInput.wrapped.address, SENDER_AS_RECIPIENT, '0']);
1021
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [pathOutput.wrapped.address, SENDER_AS_RECIPIENT, '0']);
1022
+ }
1023
+ } else {
1024
+ if (tradeType == sdkCore.TradeType.EXACT_INPUT) {
1025
+ planner.addCommand(exports.CommandType.V2_SWAP_EXACT_IN, [
1026
+ // if native, we have to unwrap so keep in the router for now
1027
+ routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient, trade.maximumAmountIn(options.slippageTolerance).quotient.toString(),
1028
+ // if router will custody funds, we do aggregated slippage check from router
1029
+ routerMustCustody ? 0 : trade.minimumAmountOut(options.slippageTolerance).quotient.toString(), route.path.map(function (token) {
1030
+ return token.wrapped.address;
1031
+ }), payerIsUser]);
1032
+ } else if (tradeType == sdkCore.TradeType.EXACT_OUTPUT) {
1033
+ planner.addCommand(exports.CommandType.V2_SWAP_EXACT_OUT, [routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient, trade.minimumAmountOut(options.slippageTolerance).quotient.toString(), trade.maximumAmountIn(options.slippageTolerance).quotient.toString(), route.path.map(function (token) {
1034
+ return token.wrapped.address;
1035
+ }), payerIsUser]);
1036
+ }
1037
+ }
1038
+ }
1039
+ // encode a uniswap v3 swap
1040
+ function addV3Swap(planner, _ref3, tradeType, options, payerIsUser, routerMustCustody) {
1041
+ var route = _ref3.route,
1042
+ inputAmount = _ref3.inputAmount,
1043
+ outputAmount = _ref3.outputAmount;
1044
+ var trade = v3Sdk.Trade.createUncheckedTrade({
1045
+ route: route,
1046
+ inputAmount: inputAmount,
1047
+ outputAmount: outputAmount,
1048
+ tradeType: tradeType
1049
+ });
1050
+ var pathInput = route.path[0];
1051
+ var pathOutput = route.path[route.path.length - 1];
1052
+ // const fwWETH = FEW_WRAPPED_NATIVE_CURRENCY[trade.inputAmount.currency.wrapped.chainId]
1053
+ if (fewV2Sdk.isFewToken(route.pathInput.wrapped) && fewV2Sdk.isFewToken(route.pathOutput.wrapped)) {
1054
+ if (!trade.inputAmount.currency.isNative) {
1055
+ // send wrapped token to router to unwrap
1056
+ planner.addCommand(exports.CommandType.PERMIT2_TRANSFER_FROM, [trade.inputAmount.currency.address, ROUTER_AS_RECIPIENT, trade.maximumAmountIn(options.slippageTolerance).quotient.toString()]);
1057
+ }
1058
+ planner.addCommand(exports.CommandType.WRAP_FEW_TOKEN, [trade.inputAmount.currency.wrapped.address, ROUTER_AS_RECIPIENT, trade.inputAmount.currency.isNative ? CONTRACT_BALANCE : trade.inputAmount.quotient.toString()]);
1059
+ payerIsUser = false;
1060
+ routerMustCustody = true; // TOTO, check again
1061
+ var fewCurrencyIn = fewV2Sdk.getFewTokenFromOriginalToken(route.input.wrapped, route.input.chainId);
1062
+ var fewCurrencyOut = fewV2Sdk.getFewTokenFromOriginalToken(route.output.wrapped, route.output.chainId);
1063
+ var v3Route = route;
1064
+ var newV3Route = new v3Sdk.Route(v3Route.pools, fewCurrencyIn, fewCurrencyOut);
1065
+ var path = v3Sdk.encodeRouteToPath(newV3Route, trade.tradeType === sdkCore.TradeType.EXACT_OUTPUT);
1066
+ if (tradeType == sdkCore.TradeType.EXACT_INPUT) {
1067
+ planner.addCommand(exports.CommandType.V3_SWAP_EXACT_IN, [routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient, trade.maximumAmountIn(options.slippageTolerance).quotient.toString(), routerMustCustody ? 0 : trade.minimumAmountOut(options.slippageTolerance).quotient.toString(), path, payerIsUser]);
1068
+ } else if (tradeType == sdkCore.TradeType.EXACT_OUTPUT) {
1069
+ planner.addCommand(exports.CommandType.V3_SWAP_EXACT_OUT, [routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient, trade.minimumAmountOut(options.slippageTolerance).quotient.toString(), trade.maximumAmountIn(options.slippageTolerance).quotient.toString(), path, payerIsUser]);
1070
+ }
1071
+ var fewInputToken = fewV2Sdk.getFewTokenFromOriginalToken(trade.inputAmount.currency.wrapped, trade.inputAmount.currency.chainId);
1072
+ var fewOutputToken = fewV2Sdk.getFewTokenFromOriginalToken(trade.outputAmount.currency.wrapped, trade.outputAmount.currency.chainId);
1073
+ if (fewV2Sdk.isFewToken(pathInput.wrapped) && fewV2Sdk.isFewToken(pathOutput.wrapped)) {
1074
+ if (outputAmount.currency.isNative) {
1075
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [fewOutputToken.address, ROUTER_AS_RECIPIENT, '0']);
1076
+ } else if (trade.inputAmount.currency.isNative) {
1077
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [fewInputToken.address, ROUTER_AS_RECIPIENT, '0']);
1078
+ planner.addCommand(exports.CommandType.UNWRAP_WETH, [SENDER_AS_RECIPIENT, '0']);
1079
+ } else {
1080
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [fewOutputToken.address, SENDER_AS_RECIPIENT, '0']);
1081
+ }
1082
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [pathInput.wrapped.address, SENDER_AS_RECIPIENT, '0']);
1083
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [pathOutput.wrapped.address, SENDER_AS_RECIPIENT, '0']);
1084
+ }
1085
+ } else {
1086
+ var _path = v3Sdk.encodeRouteToPath(route, trade.tradeType === sdkCore.TradeType.EXACT_OUTPUT);
1087
+ if (tradeType == sdkCore.TradeType.EXACT_INPUT) {
1088
+ planner.addCommand(exports.CommandType.V3_SWAP_EXACT_IN, [routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient, trade.maximumAmountIn(options.slippageTolerance).quotient.toString(), routerMustCustody ? 0 : trade.minimumAmountOut(options.slippageTolerance).quotient.toString(), _path, payerIsUser]);
1089
+ } else if (tradeType == sdkCore.TradeType.EXACT_OUTPUT) {
1090
+ planner.addCommand(exports.CommandType.V3_SWAP_EXACT_OUT, [routerMustCustody ? ROUTER_AS_RECIPIENT : options.recipient, trade.minimumAmountOut(options.slippageTolerance).quotient.toString(), trade.maximumAmountIn(options.slippageTolerance).quotient.toString(), _path, payerIsUser]);
1091
+ }
1092
+ }
1093
+ }
1094
+ function addV4Swap(swaps, planner, _ref4, tradeType, options, payerIsUser, routerMustCustody) {
1095
+ var inputAmount = _ref4.inputAmount,
1096
+ outputAmount = _ref4.outputAmount,
1097
+ route = _ref4.route;
1098
+ // create a deep copy of pools since v4Planner encoding tampers with array
1099
+ var fewCurrencyIn = fewV2Sdk.getFewTokenFromOriginalToken(inputAmount.currency.wrapped, inputAmount.currency.chainId);
1100
+ var fewCurrencyOut = fewV2Sdk.getFewTokenFromOriginalToken(outputAmount.currency.wrapped, outputAmount.currency.chainId);
1101
+ var firstSwap = swaps[0];
1102
+ var lastSwap = swaps[swaps.length - 1];
1103
+ var pathInput = route.path[0];
1104
+ var pathOutput = route.path[route.path.length - 1];
1105
+ var pools = route.pools.map(function (p) {
1106
+ return p;
1107
+ });
1108
+ var v4Route = new v4Sdk.Route(pools, inputAmount.currency, outputAmount.currency);
1109
+ if (fewV2Sdk.isFewToken(route.pools[0].token0.wrapped) && fewV2Sdk.isFewToken(route.pools[0].token1.wrapped)) {
1110
+ var _options$recipient;
1111
+ var fewV4Route = new v4Sdk.Route(pools, fewCurrencyIn, fewCurrencyOut);
1112
+ var fewTrade = v4Sdk.Trade.createUncheckedTrade({
1113
+ route: fewV4Route,
1114
+ inputAmount: inputAmount,
1115
+ outputAmount: outputAmount,
1116
+ tradeType: tradeType
1117
+ });
1118
+ if (!fewTrade.inputAmount.currency.isNative) {
1119
+ // send wrapped token to router to unwrap
1120
+ planner.addCommand(exports.CommandType.PERMIT2_TRANSFER_FROM, [fewTrade.inputAmount.currency.address, ROUTER_AS_RECIPIENT, fewTrade.maximumAmountIn(options.slippageTolerance).quotient.toString()]);
1121
+ }
1122
+ if (fewTrade.inputAmount.currency.isNative) {
1123
+ planner.addCommand(exports.CommandType.WRAP_ETH, [ROUTER_AS_RECIPIENT, fewTrade.inputAmount.quotient.toString()]);
1124
+ }
1125
+ planner.addCommand(exports.CommandType.WRAP_FEW_TOKEN, [fewTrade.inputAmount.currency.wrapped.address, ROUTER_AS_RECIPIENT, fewTrade.inputAmount.currency.isNative ? CONTRACT_BALANCE : fewTrade.inputAmount.quotient.toString()]);
1126
+ payerIsUser = false;
1127
+ routerMustCustody = true; // TOTO, check again
1128
+ var slippageToleranceOnSwap = routerMustCustody && tradeType == sdkCore.TradeType.EXACT_INPUT ? undefined : options.slippageTolerance;
1129
+ var v4Planner = new v4Sdk.V4Planner();
1130
+ v4Planner.addTrade(fewTrade, slippageToleranceOnSwap);
1131
+ v4Planner.addSettle(fewTrade.route.pathInput, payerIsUser);
1132
+ v4Planner.addTake(fewTrade.route.pathOutput, routerMustCustody ? ROUTER_AS_RECIPIENT : (_options$recipient = options.recipient) != null ? _options$recipient : SENDER_AS_RECIPIENT);
1133
+ planner.addCommand(exports.CommandType.V4_SWAP, [v4Planner.finalize()]);
1134
+ var fewOutputToken = fewV2Sdk.getFewTokenFromOriginalToken(fewTrade.outputAmount.currency.wrapped, fewTrade.outputAmount.currency.chainId);
1135
+ if (fewV2Sdk.isFewToken(pathInput.wrapped) && fewV2Sdk.isFewToken(pathOutput.wrapped)) {
1136
+ if (outputAmount.currency.isNative) {
1137
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [fewOutputToken.address, ROUTER_AS_RECIPIENT, fewTrade.minimumAmountOut(options.slippageTolerance).quotient.toString()]);
1138
+ planner.addCommand(exports.CommandType.UNWRAP_WETH, [SENDER_AS_RECIPIENT, 0]);
1139
+ } else {
1140
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [fewOutputToken.address, SENDER_AS_RECIPIENT, fewTrade.minimumAmountOut(options.slippageTolerance).quotient.toString()]);
1141
+ }
1142
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [pathInput.wrapped.address, SENDER_AS_RECIPIENT, '0']);
1143
+ planner.addCommand(exports.CommandType.UNWRAP_FEW_TOKEN, [pathOutput.wrapped.address, SENDER_AS_RECIPIENT, '0']);
1144
+ }
1145
+ } else {
1146
+ var _options$recipient2;
1147
+ var trade = v4Sdk.Trade.createUncheckedTrade({
1148
+ route: v4Route,
1149
+ inputAmount: inputAmount,
1150
+ outputAmount: outputAmount,
1151
+ tradeType: tradeType
1152
+ });
1153
+ var _slippageToleranceOnSwap = routerMustCustody && tradeType == sdkCore.TradeType.EXACT_INPUT ? undefined : options.slippageTolerance;
1154
+ var _v4Planner = new v4Sdk.V4Planner();
1155
+ _v4Planner.addTrade(trade, _slippageToleranceOnSwap);
1156
+ _v4Planner.addSettle(trade.route.pathInput, payerIsUser);
1157
+ _v4Planner.addTake(trade.route.pathOutput, routerMustCustody ? ROUTER_AS_RECIPIENT : (_options$recipient2 = options.recipient) != null ? _options$recipient2 : SENDER_AS_RECIPIENT);
1158
+ if (firstSwap.route.protocol !== routerSdk.Protocol.V4 && lastSwap.route.protocol === routerSdk.Protocol.V4 && trade.route.pathInput.isNative) {
1159
+ planner.addCommand(exports.CommandType.UNWRAP_WETH, [ROUTER_AS_RECIPIENT, 0]);
1160
+ }
1161
+ planner.addCommand(exports.CommandType.V4_SWAP, [_v4Planner.finalize()]);
1162
+ }
1163
+ }
1164
+ // encode a mixed route swap, i.e. including both v2 and v3 pools
1165
+ function addMixedSwap(swaps, planner, swap, tradeType, options, payerIsUser, routerMustCustody) {
1166
+ var _options$recipient3;
1167
+ var route = swap.route;
1168
+ var inputAmount = swap.inputAmount;
1169
+ var outputAmount = swap.outputAmount;
1170
+ var tradeRecipient = routerMustCustody ? ROUTER_AS_RECIPIENT : (_options$recipient3 = options.recipient) != null ? _options$recipient3 : SENDER_AS_RECIPIENT;
1171
+ // single hop, so it can be reduced to plain swap logic for one protocol version
1172
+ if (route.pools.length === 1) {
1173
+ if (route.pools[0] instanceof v4Sdk.Pool) {
1174
+ return addV4Swap(swaps, planner, swap, tradeType, options, payerIsUser, routerMustCustody);
1175
+ } else if (route.pools[0] instanceof v3Sdk.Pool) {
1176
+ return addV3Swap(planner, swap, tradeType, options, payerIsUser, routerMustCustody);
1177
+ } else if (route.pools[0] instanceof v2Sdk.Pair) {
1178
+ return addV2Swap(planner, swap, tradeType, options, payerIsUser, routerMustCustody);
1179
+ } else {
1180
+ throw new Error('Invalid route type');
1181
+ }
1182
+ }
1183
+ var trade = routerSdk.MixedRouteTrade.createUncheckedTrade({
1184
+ route: route,
1185
+ inputAmount: inputAmount,
1186
+ outputAmount: outputAmount,
1187
+ tradeType: tradeType
1188
+ });
1189
+ var amountIn = trade.maximumAmountIn(options.slippageTolerance, inputAmount).quotient.toString();
1190
+ var amountOut = routerMustCustody ? 0 : trade.minimumAmountOut(options.slippageTolerance, outputAmount).quotient.toString();
1191
+ // logic from
1192
+ // https://github.com/Uniswap/router-sdk/blob/d8eed164e6c79519983844ca8b6a3fc24ebcb8f8/src/swapRouter.ts#L276
1193
+ var sections = routerSdk.partitionMixedRouteByProtocol(route);
1194
+ var isLastSectionInRoute = function isLastSectionInRoute(i) {
1195
+ return i === sections.length - 1;
1196
+ };
1197
+ var inputToken = route.pathInput;
1198
+ for (var i = 0; i < sections.length; i++) {
1199
+ var section = sections[i];
1200
+ var routePool = section[0];
1201
+ var outputToken = routerSdk.getOutputOfPools(section, inputToken);
1202
+ var subRoute = new routerSdk.MixedRoute(new routerSdk.MixedRouteSDK([].concat(section), inputToken, outputToken));
1203
+ var nextInputToken = void 0;
1204
+ var swapRecipient = void 0;
1205
+ if (isLastSectionInRoute(i)) {
1206
+ nextInputToken = outputToken;
1207
+ swapRecipient = tradeRecipient;
1208
+ } else {
1209
+ var nextPool = sections[i + 1][0];
1210
+ nextInputToken = getPathCurrency(outputToken, nextPool);
1211
+ var v2PoolIsSwapRecipient = nextPool instanceof v2Sdk.Pair && outputToken.equals(nextInputToken);
1212
+ swapRecipient = v2PoolIsSwapRecipient ? nextPool.liquidityToken.address : ROUTER_AS_RECIPIENT;
1213
+ }
1214
+ if (routePool instanceof v4Sdk.Pool) {
1215
+ var v4Planner = new v4Sdk.V4Planner();
1216
+ var v4SubRoute = new v4Sdk.Route(section, subRoute.input, subRoute.output);
1217
+ v4Planner.addSettle(inputToken, payerIsUser && i === 0, i == 0 ? amountIn : CONTRACT_BALANCE);
1218
+ v4Planner.addAction(v4Sdk.Actions.SWAP_EXACT_IN, [{
1219
+ currencyIn: inputToken.isNative ? ETH_ADDRESS : inputToken.address,
1220
+ path: v4Sdk.encodeRouteToPath(v4SubRoute),
1221
+ amountIn: 0,
1222
+ amountOutMinimum: !isLastSectionInRoute(i) ? 0 : amountOut
1223
+ }]);
1224
+ v4Planner.addTake(outputToken, swapRecipient);
1225
+ planner.addCommand(exports.CommandType.V4_SWAP, [v4Planner.finalize()]);
1226
+ } else if (routePool instanceof v3Sdk.Pool) {
1227
+ planner.addCommand(exports.CommandType.V3_SWAP_EXACT_IN, [swapRecipient, i == 0 ? amountIn : CONTRACT_BALANCE, !isLastSectionInRoute(i) ? 0 : amountOut, routerSdk.encodeMixedRouteToPath(subRoute), payerIsUser && i === 0]);
1228
+ } else if (routePool instanceof v2Sdk.Pair) {
1229
+ planner.addCommand(exports.CommandType.V2_SWAP_EXACT_IN, [swapRecipient, i === 0 ? amountIn : CONTRACT_BALANCE, !isLastSectionInRoute(i) ? 0 : amountOut, subRoute.path.map(function (token) {
1230
+ return token.wrapped.address;
1231
+ }), payerIsUser && i === 0]);
1232
+ } else {
1233
+ throw new Error('Unexpected Pool Type');
1234
+ }
1235
+ // perform a token transition (wrap/unwrap if necessary)
1236
+ if (!isLastSectionInRoute(i)) {
1237
+ if (outputToken.isNative && !nextInputToken.isNative) {
1238
+ planner.addCommand(exports.CommandType.WRAP_ETH, [ROUTER_AS_RECIPIENT, CONTRACT_BALANCE]);
1239
+ } else if (!outputToken.isNative && nextInputToken.isNative) {
1240
+ planner.addCommand(exports.CommandType.UNWRAP_WETH, [ROUTER_AS_RECIPIENT, 0]);
1241
+ }
1242
+ }
1243
+ inputToken = nextInputToken;
1244
+ }
1245
+ }
1246
+ // if price impact is very high, there's a chance of hitting max/min prices resulting in a partial fill of the swap
1247
+ function riskOfPartialFill(trade) {
1248
+ return trade.priceImpact.greaterThan(REFUND_ETH_PRICE_IMPACT_THRESHOLD);
1249
+ }
1250
+ function hasFeeOption(swapOptions) {
1251
+ return !!swapOptions.fee || !!swapOptions.flatFee;
1252
+ }
1253
+
1254
+ var SIGNATURE_LENGTH = 65;
1255
+ var EIP_2098_SIGNATURE_LENGTH = 64;
1256
+ function encodePermit(planner, permit2) {
1257
+ var signature = permit2.signature;
1258
+ var length = ethers.ethers.utils.arrayify(permit2.signature).length;
1259
+ // signature data provided for EIP-1271 may have length different from ECDSA signature
1260
+ if (length === SIGNATURE_LENGTH || length === EIP_2098_SIGNATURE_LENGTH) {
1261
+ // sanitizes signature to cover edge cases of malformed EIP-2098 sigs and v used as recovery id
1262
+ signature = ethers.ethers.utils.joinSignature(ethers.ethers.utils.splitSignature(permit2.signature));
1263
+ }
1264
+ planner.addCommand(exports.CommandType.PERMIT2_PERMIT, [permit2, signature]);
1265
+ }
1266
+ function encodeV3PositionPermit(planner, permit, tokenId) {
1267
+ var calldata = v3Sdk.NonfungiblePositionManager.INTERFACE.encodeFunctionData('permit', [sdkCore.validateAndParseAddress(permit.spender), tokenId, permit.deadline, permit.v, permit.r, permit.s]);
1268
+ planner.addCommand(exports.CommandType.V3_POSITION_MANAGER_PERMIT, [calldata]);
1269
+ }
1270
+ // Handles the encoding of commands needed to gather input tokens for a trade
1271
+ // Approval: The router approving another address to take tokens.
1272
+ // note: Only seaport and sudoswap support this action. Approvals are left open.
1273
+ // Permit: A Permit2 signature-based Permit to allow the router to access a user's tokens
1274
+ // Transfer: A Permit2 TransferFrom of tokens from a user to either the router or another address
1275
+ function encodeInputTokenOptions(planner, options) {
1276
+ // first ensure that all tokens provided for encoding are the same
1277
+ if (!!options.permit2TransferFrom && !!options.permit2Permit) !(options.permit2TransferFrom.token === options.permit2Permit.details.token) ? invariant(false, "inconsistent token") : void 0;
1278
+ // if this order has a options.permit2Permit, encode it
1279
+ if (!!options.permit2Permit) {
1280
+ encodePermit(planner, options.permit2Permit);
1281
+ }
1282
+ if (!!options.permit2TransferFrom) {
1283
+ planner.addCommand(exports.CommandType.PERMIT2_TRANSFER_FROM, [options.permit2TransferFrom.token, options.permit2TransferFrom.recipient ? options.permit2TransferFrom.recipient : ROUTER_AS_RECIPIENT, options.permit2TransferFrom.amount]);
1284
+ }
1285
+ }
1286
+
1287
+ function isMint(options) {
1288
+ return Object.keys(options).some(function (k) {
1289
+ return k === 'recipient';
1290
+ });
1291
+ }
1292
+ var SwapRouter = /*#__PURE__*/function () {
1293
+ function SwapRouter() {}
1294
+ SwapRouter.swapCallParameters = function swapCallParameters(trades, options) {
1295
+ // TODO: use permit if signature included in swapOptions
1296
+ var planner = new RoutePlanner();
1297
+ var trade = new UniswapTrade(trades, options);
1298
+ var inputCurrency = trade.trade.inputAmount.currency;
1299
+ !!(inputCurrency.isNative && !!options.inputTokenPermit) ? invariant(false, 'NATIVE_INPUT_PERMIT') : void 0;
1300
+ if (options.inputTokenPermit) {
1301
+ encodePermit(planner, options.inputTokenPermit);
1302
+ }
1303
+ var nativeCurrencyValue = inputCurrency.isNative ? ethers.BigNumber.from(trade.trade.maximumAmountIn(options.slippageTolerance).quotient.toString()) : ethers.BigNumber.from(0);
1304
+ trade.encode(planner, {
1305
+ allowRevert: false
1306
+ });
1307
+ return SwapRouter.encodePlan(planner, nativeCurrencyValue, {
1308
+ deadline: options.deadlineOrPreviousBlockhash ? ethers.BigNumber.from(options.deadlineOrPreviousBlockhash) : undefined
1309
+ });
1310
+ }
1311
+ /**
1312
+ * Builds the call parameters for a migration from a V3 position to a V4 position.
1313
+ * Some requirements of the parameters:
1314
+ * - v3RemoveLiquidityOptions.collectOptions.recipient must equal v4PositionManager
1315
+ * - v3RemoveLiquidityOptions.liquidityPercentage must be 100%
1316
+ * - input pool and output pool must have the same tokens
1317
+ * - V3 NFT must be approved, or valid inputV3NFTPermit must be provided with UR as spender
1318
+ */;
1319
+ SwapRouter.migrateV3ToV4CallParameters = function migrateV3ToV4CallParameters(options, positionManagerOverride) {
1320
+ var v4Pool = options.outputPosition.pool;
1321
+ var v3Token0 = options.inputPosition.pool.token0;
1322
+ var v3Token1 = options.inputPosition.pool.token1;
1323
+ var v4PositionManagerAddress = positionManagerOverride != null ? positionManagerOverride : sdkCore.CHAIN_TO_ADDRESSES_MAP[v4Pool.chainId].v4PositionManagerAddress;
1324
+ // owner of the v3 nft must be the receiver of the v4 nft
1325
+ // validate the parameters
1326
+ if (v4Pool.currency0.isNative) {
1327
+ !(v4Pool.currency0.wrapped.equals(v3Token0) && v4Pool.currency1.equals(v3Token1) || v4Pool.currency0.wrapped.equals(v3Token1) && v4Pool.currency1.equals(v3Token0)) ? invariant(false, 'TOKEN_MISMATCH') : void 0;
1328
+ } else {
1329
+ !(v3Token0 === v4Pool.token0) ? invariant(false, 'TOKEN0_MISMATCH') : void 0;
1330
+ !(v3Token1 === v4Pool.token1) ? invariant(false, 'TOKEN1_MISMATCH') : void 0;
1331
+ }
1332
+ !options.v3RemoveLiquidityOptions.liquidityPercentage.equalTo(new sdkCore.Percent(100, 100)) ? invariant(false, 'FULL_REMOVAL_REQUIRED') : void 0;
1333
+ !(options.v3RemoveLiquidityOptions.burnToken == true) ? invariant(false, 'BURN_TOKEN_REQUIRED') : void 0;
1334
+ !(options.v3RemoveLiquidityOptions.collectOptions.recipient === v4PositionManagerAddress) ? invariant(false, 'RECIPIENT_NOT_POSITION_MANAGER') : void 0;
1335
+ !isMint(options.v4AddLiquidityOptions) ? invariant(false, 'MINT_REQUIRED') : void 0;
1336
+ !options.v4AddLiquidityOptions.migrate ? invariant(false, 'MIGRATE_REQUIRED') : void 0;
1337
+ var planner = new RoutePlanner();
1338
+ // to prevent reentrancy by the pool hook, we initialize the v4 pool before moving funds
1339
+ if (options.v4AddLiquidityOptions.createPool) {
1340
+ var poolKey = v4Sdk.Pool.getPoolKey(v4Pool.currency0, v4Pool.currency1, v4Pool.fee, v4Pool.tickSpacing, v4Pool.hooks);
1341
+ planner.addCommand(exports.CommandType.V4_INITIALIZE_POOL, [poolKey, v4Pool.sqrtRatioX96.toString()]);
1342
+ // remove createPool setting, so that it doesnt get encoded again later
1343
+ delete options.v4AddLiquidityOptions.createPool;
1344
+ }
1345
+ // add position permit to the universal router planner
1346
+ if (options.v3RemoveLiquidityOptions.permit) {
1347
+ // permit spender should be UR
1348
+ var universalRouterAddress = UNIVERSAL_ROUTER_ADDRESS(exports.UniversalRouterVersion.V2_0, options.inputPosition.pool.chainId);
1349
+ !(universalRouterAddress == options.v3RemoveLiquidityOptions.permit.spender) ? invariant(false, 'INVALID_SPENDER') : void 0;
1350
+ // don't need to transfer it because v3posm uses isApprovedOrOwner()
1351
+ encodeV3PositionPermit(planner, options.v3RemoveLiquidityOptions.permit, options.v3RemoveLiquidityOptions.tokenId);
1352
+ // remove permit so that multicall doesnt add it again
1353
+ delete options.v3RemoveLiquidityOptions.permit;
1354
+ }
1355
+ // encode v3 withdraw
1356
+ var v3RemoveParams = v3Sdk.NonfungiblePositionManager.removeCallParameters(options.inputPosition, options.v3RemoveLiquidityOptions);
1357
+ var v3Calls = v3Sdk.Multicall.decodeMulticall(v3RemoveParams.calldata);
1358
+ for (var _iterator = _createForOfIteratorHelperLoose(v3Calls), _step; !(_step = _iterator()).done;) {
1359
+ var v3Call = _step.value;
1360
+ // slice selector - 0x + 4 bytes = 10 characters
1361
+ var _selector = v3Call.slice(0, 10);
1362
+ !(_selector == v3Sdk.NonfungiblePositionManager.INTERFACE.getSighash('collect') || _selector == v3Sdk.NonfungiblePositionManager.INTERFACE.getSighash('decreaseLiquidity') || _selector == v3Sdk.NonfungiblePositionManager.INTERFACE.getSighash('burn')) ? invariant(false, 'INVALID_V3_CALL: ' + _selector) : void 0;
1363
+ planner.addCommand(exports.CommandType.V3_POSITION_MANAGER_CALL, [v3Call]);
1364
+ }
1365
+ // encode v4 mint
1366
+ var v4AddParams = v4Sdk.V4PositionManager.addCallParameters(options.outputPosition, options.v4AddLiquidityOptions);
1367
+ // only modifyLiquidities can be called by the UniversalRouter
1368
+ var selector = v4AddParams.calldata.slice(0, 10);
1369
+ !(selector == v4Sdk.V4PositionManager.INTERFACE.getSighash('modifyLiquidities')) ? invariant(false, 'INVALID_V4_CALL: ' + selector) : void 0;
1370
+ planner.addCommand(exports.CommandType.V4_POSITION_MANAGER_CALL, [v4AddParams.calldata]);
1371
+ return SwapRouter.encodePlan(planner, ethers.BigNumber.from(0), {
1372
+ deadline: ethers.BigNumber.from(options.v4AddLiquidityOptions.deadline)
1373
+ });
1374
+ }
1375
+ /**
1376
+ * Encodes a planned route into a method name and parameters for the Router contract.
1377
+ * @param planner the planned route
1378
+ * @param nativeCurrencyValue the native currency value of the planned route
1379
+ * @param config the router config
1380
+ */;
1381
+ SwapRouter.encodePlan = function encodePlan(planner, nativeCurrencyValue, config) {
1382
+ if (config === void 0) {
1383
+ config = {};
1384
+ }
1385
+ var commands = planner.commands,
1386
+ inputs = planner.inputs;
1387
+ var functionSignature = !!config.deadline ? 'execute(bytes,bytes[],uint256)' : 'execute(bytes,bytes[])';
1388
+ var parameters = !!config.deadline ? [commands, inputs, config.deadline] : [commands, inputs];
1389
+ var calldata = SwapRouter.INTERFACE.encodeFunctionData(functionSignature, parameters);
1390
+ return {
1391
+ calldata: calldata,
1392
+ value: nativeCurrencyValue.toHexString()
1393
+ };
1394
+ };
1395
+ return SwapRouter;
1396
+ }();
1397
+ SwapRouter.INTERFACE = /*#__PURE__*/new abi.Interface(UniversalRouter.abi);
1398
+
1399
+ var UnwrapWETH = /*#__PURE__*/function () {
1400
+ function UnwrapWETH(amount, chainId, permit2) {
1401
+ this.tradeType = exports.RouterActionType.UnwrapWETH;
1402
+ this.wethAddress = WETH_ADDRESS(chainId);
1403
+ this.amount = amount;
1404
+ if (!!permit2) {
1405
+ !(permit2.details.token.toLowerCase() === this.wethAddress.toLowerCase()) ? invariant(false, "must be permitting WETH address: " + this.wethAddress) : void 0;
1406
+ !(permit2.details.amount >= amount) ? invariant(false, "Did not permit enough WETH for unwrapWETH transaction") : void 0;
1407
+ this.permit2Data = permit2;
1408
+ }
1409
+ }
1410
+ var _proto = UnwrapWETH.prototype;
1411
+ _proto.encode = function encode(planner, _) {
1412
+ encodeInputTokenOptions(planner, {
1413
+ permit2Permit: this.permit2Data,
1414
+ permit2TransferFrom: {
1415
+ token: this.wethAddress,
1416
+ amount: this.amount.toString()
1417
+ }
1418
+ });
1419
+ planner.addCommand(exports.CommandType.UNWRAP_WETH, [ROUTER_AS_RECIPIENT, this.amount]);
1420
+ };
1421
+ return UnwrapWETH;
1422
+ }();
1423
+
1424
+ (function (PoolType) {
1425
+ PoolType["V2Pool"] = "v2-pool";
1426
+ PoolType["V3Pool"] = "v3-pool";
1427
+ PoolType["V4Pool"] = "v4-pool";
1428
+ })(exports.PoolType || (exports.PoolType = {}));
1429
+ var isNativeCurrency = function isNativeCurrency(address) {
1430
+ return address.toLowerCase() === ETH_ADDRESS.toLowerCase() || address.toLowerCase() === E_ETH_ADDRESS.toLowerCase();
1431
+ };
1432
+ // Helper class to convert routing-specific quote entities to RouterTrade entities
1433
+ // the returned RouterTrade can then be used to build the UniswapTrade entity in this package
1434
+ var RouterTradeAdapter = /*#__PURE__*/function () {
1435
+ function RouterTradeAdapter() {}
1436
+ // Generate a RouterTrade using fields from a classic quote response
1437
+ RouterTradeAdapter.fromClassicQuote = function fromClassicQuote(quote) {
1438
+ var route = quote.route,
1439
+ tokenIn = quote.tokenIn,
1440
+ tokenOut = quote.tokenOut;
1441
+ if (!route) throw new Error('Expected route to be present');
1442
+ if (!route.length) throw new Error('Expected there to be at least one route');
1443
+ if (route.some(function (r) {
1444
+ return !r.length;
1445
+ })) throw new Error('Expected all routes to have at least one pool');
1446
+ var firstRoute = route[0];
1447
+ var tokenInData = firstRoute[0].tokenIn;
1448
+ var tokenOutData = firstRoute[firstRoute.length - 1].tokenOut;
1449
+ if (!tokenInData || !tokenOutData) throw new Error('Expected both tokenIn and tokenOut to be present');
1450
+ if (tokenInData.chainId !== tokenOutData.chainId) throw new Error('Expected tokenIn and tokenOut to be have same chainId');
1451
+ var parsedCurrencyIn = RouterTradeAdapter.toCurrency(isNativeCurrency(tokenIn), tokenInData);
1452
+ var parsedCurrencyOut = RouterTradeAdapter.toCurrency(isNativeCurrency(tokenOut), tokenOutData);
1453
+ var typedRoutes = route.map(function (subRoute) {
1454
+ var rawAmountIn = subRoute[0].amountIn;
1455
+ var rawAmountOut = subRoute[subRoute.length - 1].amountOut;
1456
+ if (!rawAmountIn || !rawAmountOut) {
1457
+ throw new Error('Expected both raw amountIn and raw amountOut to be present');
1458
+ }
1459
+ var inputAmount = sdkCore.CurrencyAmount.fromRawAmount(parsedCurrencyIn, rawAmountIn);
1460
+ var outputAmount = sdkCore.CurrencyAmount.fromRawAmount(parsedCurrencyOut, rawAmountOut);
1461
+ var isOnlyV2 = RouterTradeAdapter.isVersionedRoute(exports.PoolType.V2Pool, subRoute);
1462
+ var isOnlyV3 = RouterTradeAdapter.isVersionedRoute(exports.PoolType.V3Pool, subRoute);
1463
+ var isOnlyV4 = RouterTradeAdapter.isVersionedRoute(exports.PoolType.V4Pool, subRoute);
1464
+ return {
1465
+ routev4: isOnlyV4 ? new v4Sdk.Route(subRoute.map(RouterTradeAdapter.toV4Pool), parsedCurrencyIn, parsedCurrencyOut) : null,
1466
+ routev3: isOnlyV3 ? new v3Sdk.Route(subRoute.map(RouterTradeAdapter.toV3Pool), parsedCurrencyIn, parsedCurrencyOut) : null,
1467
+ routev2: isOnlyV2 ? new v2Sdk.Route(subRoute.map(RouterTradeAdapter.toPair), parsedCurrencyIn, parsedCurrencyOut) : null,
1468
+ mixedRoute: !isOnlyV4 && !isOnlyV3 && !isOnlyV2 ? new routerSdk.MixedRouteSDK(subRoute.map(RouterTradeAdapter.toPoolOrPair), parsedCurrencyIn, parsedCurrencyOut) : null,
1469
+ inputAmount: inputAmount,
1470
+ outputAmount: outputAmount
1471
+ };
1472
+ });
1473
+ return new routerSdk.Trade({
1474
+ v2Routes: typedRoutes.filter(function (route) {
1475
+ return route.routev2;
1476
+ }).map(function (route) {
1477
+ return {
1478
+ routev2: route.routev2,
1479
+ inputAmount: route.inputAmount,
1480
+ outputAmount: route.outputAmount
1481
+ };
1482
+ }),
1483
+ v3Routes: typedRoutes.filter(function (route) {
1484
+ return route.routev3;
1485
+ }).map(function (route) {
1486
+ return {
1487
+ routev3: route.routev3,
1488
+ inputAmount: route.inputAmount,
1489
+ outputAmount: route.outputAmount
1490
+ };
1491
+ }),
1492
+ v4Routes: typedRoutes.filter(function (route) {
1493
+ return route.routev4;
1494
+ }).map(function (route) {
1495
+ return {
1496
+ routev4: route.routev4,
1497
+ inputAmount: route.inputAmount,
1498
+ outputAmount: route.outputAmount
1499
+ };
1500
+ }),
1501
+ mixedRoutes: typedRoutes.filter(function (route) {
1502
+ return route.mixedRoute;
1503
+ }).map(function (route) {
1504
+ return {
1505
+ mixedRoute: route.mixedRoute,
1506
+ inputAmount: route.inputAmount,
1507
+ outputAmount: route.outputAmount
1508
+ };
1509
+ }),
1510
+ tradeType: quote.tradeType
1511
+ });
1512
+ };
1513
+ RouterTradeAdapter.toCurrency = function toCurrency(isNative, token) {
1514
+ if (isNative) {
1515
+ return sdkCore.Ether.onChain(token.chainId);
1516
+ }
1517
+ return this.toToken(token);
1518
+ };
1519
+ RouterTradeAdapter.toToken = function toToken(token) {
1520
+ var chainId = token.chainId,
1521
+ address = token.address,
1522
+ decimals = token.decimals,
1523
+ symbol = token.symbol,
1524
+ buyFeeBps = token.buyFeeBps,
1525
+ sellFeeBps = token.sellFeeBps;
1526
+ return new sdkCore.Token(chainId, address, parseInt(decimals.toString()), symbol, /* name */undefined, false, buyFeeBps ? ethers.BigNumber.from(buyFeeBps) : undefined, sellFeeBps ? ethers.BigNumber.from(sellFeeBps) : undefined);
1527
+ };
1528
+ RouterTradeAdapter.toV3Pool = function toV3Pool(_ref) {
1529
+ var fee = _ref.fee,
1530
+ sqrtRatioX96 = _ref.sqrtRatioX96,
1531
+ liquidity = _ref.liquidity,
1532
+ tickCurrent = _ref.tickCurrent,
1533
+ tokenIn = _ref.tokenIn,
1534
+ tokenOut = _ref.tokenOut;
1535
+ return new v3Sdk.Pool(RouterTradeAdapter.toToken(tokenIn), RouterTradeAdapter.toToken(tokenOut), parseInt(fee), sqrtRatioX96, liquidity, parseInt(tickCurrent));
1536
+ };
1537
+ RouterTradeAdapter.toV4Pool = function toV4Pool(pool) {
1538
+ var parsedCurrencyIn = RouterTradeAdapter.toCurrency(isNativeCurrency(pool.tokenIn.address), pool.tokenIn);
1539
+ var parsedCurrencyOut = RouterTradeAdapter.toCurrency(isNativeCurrency(pool.tokenOut.address), pool.tokenOut);
1540
+ return new v4Sdk.Pool(parsedCurrencyIn, parsedCurrencyOut, parseInt(pool.fee), parseInt(pool.tickSpacing), pool.hooks, pool.sqrtRatioX96, pool.liquidity, parseInt(pool.tickCurrent));
1541
+ };
1542
+ RouterTradeAdapter.isVersionedRoute = function isVersionedRoute(type, route) {
1543
+ return route.every(function (pool) {
1544
+ return pool.type === type;
1545
+ });
1546
+ };
1547
+ return RouterTradeAdapter;
1548
+ }();
1549
+ RouterTradeAdapter.toPoolOrPair = function (pool) {
1550
+ switch (pool.type) {
1551
+ case exports.PoolType.V4Pool:
1552
+ return RouterTradeAdapter.toV4Pool(pool);
1553
+ case exports.PoolType.V3Pool:
1554
+ return RouterTradeAdapter.toV3Pool(pool);
1555
+ case exports.PoolType.V2Pool:
1556
+ return RouterTradeAdapter.toPair(pool);
1557
+ default:
1558
+ throw new Error('Invalid pool type');
1559
+ }
1560
+ };
1561
+ RouterTradeAdapter.toPair = function (_ref2) {
1562
+ var reserve0 = _ref2.reserve0,
1563
+ reserve1 = _ref2.reserve1;
1564
+ return new v2Sdk.Pair(sdkCore.CurrencyAmount.fromRawAmount(RouterTradeAdapter.toToken(reserve0.token), reserve0.quotient), sdkCore.CurrencyAmount.fromRawAmount(RouterTradeAdapter.toToken(reserve1.token), reserve1.quotient));
1565
+ };
1566
+
1567
+ // Parses UniversalRouter V2 commands
1568
+ var CommandParser = /*#__PURE__*/function () {
1569
+ function CommandParser() {}
1570
+ CommandParser.parseCalldata = function parseCalldata(calldata) {
1571
+ var genericParser = new GenericCommandParser(COMMAND_DEFINITION);
1572
+ var txDescription = CommandParser.INTERFACE.parseTransaction({
1573
+ data: calldata
1574
+ });
1575
+ var _txDescription$args = txDescription.args,
1576
+ commands = _txDescription$args.commands,
1577
+ inputs = _txDescription$args.inputs;
1578
+ return genericParser.parse(commands, inputs);
1579
+ };
1580
+ return CommandParser;
1581
+ }();
1582
+ CommandParser.INTERFACE = /*#__PURE__*/new abi.Interface(UniversalRouter.abi);
1583
+ // Parses commands based on given command definition
1584
+ var GenericCommandParser = /*#__PURE__*/function () {
1585
+ function GenericCommandParser(commandDefinition) {
1586
+ this.commandDefinition = commandDefinition;
1587
+ }
1588
+ var _proto = GenericCommandParser.prototype;
1589
+ _proto.parse = function parse(commands, inputs) {
1590
+ var _this = this;
1591
+ var commandTypes = GenericCommandParser.getCommands(commands);
1592
+ return {
1593
+ commands: commandTypes.map(function (commandType, i) {
1594
+ var commandDef = _this.commandDefinition[commandType];
1595
+ if (commandDef.parser === exports.Parser.V4Actions) {
1596
+ var _V4BaseActionsParser$ = v4Sdk.V4BaseActionsParser.parseCalldata(inputs[i]),
1597
+ actions = _V4BaseActionsParser$.actions;
1598
+ return {
1599
+ commandName: exports.CommandType[commandType],
1600
+ commandType: commandType,
1601
+ params: v4RouterCallToParams(actions)
1602
+ };
1603
+ } else if (commandDef.parser === exports.Parser.Abi) {
1604
+ var abiDef = commandDef.params;
1605
+ var rawParams = ethers.ethers.utils.defaultAbiCoder.decode(abiDef.map(function (command) {
1606
+ return command.type;
1607
+ }), inputs[i]);
1608
+ var params = rawParams.map(function (param, j) {
1609
+ switch (abiDef[j].subparser) {
1610
+ case exports.Subparser.V3PathExactIn:
1611
+ return {
1612
+ name: abiDef[j].name,
1613
+ value: parseV3PathExactIn(param)
1614
+ };
1615
+ case exports.Subparser.V3PathExactOut:
1616
+ return {
1617
+ name: abiDef[j].name,
1618
+ value: parseV3PathExactOut(param)
1619
+ };
1620
+ default:
1621
+ return {
1622
+ name: abiDef[j].name,
1623
+ value: param
1624
+ };
1625
+ }
1626
+ });
1627
+ return {
1628
+ commandName: exports.CommandType[commandType],
1629
+ commandType: commandType,
1630
+ params: params
1631
+ };
1632
+ } else if (commandDef.parser === exports.Parser.V3Actions) {
1633
+ // TODO: implement better parsing here
1634
+ return {
1635
+ commandName: exports.CommandType[commandType],
1636
+ commandType: commandType,
1637
+ params: inputs.map(function (input) {
1638
+ return {
1639
+ name: 'command',
1640
+ value: input
1641
+ };
1642
+ })
1643
+ };
1644
+ } else {
1645
+ throw new Error("Unsupported parser: " + commandDef);
1646
+ }
1647
+ })
1648
+ };
1649
+ }
1650
+ // parse command types from bytes string
1651
+ ;
1652
+ GenericCommandParser.getCommands = function getCommands(commands) {
1653
+ var commandTypes = [];
1654
+ for (var i = 2; i < commands.length; i += 2) {
1655
+ var _byte = commands.substring(i, i + 2);
1656
+ commandTypes.push(parseInt(_byte, 16));
1657
+ }
1658
+ return commandTypes;
1659
+ };
1660
+ return GenericCommandParser;
1661
+ }();
1662
+ function parseV3PathExactIn(path) {
1663
+ var strippedPath = path.replace('0x', '');
1664
+ var tokenIn = ethers.ethers.utils.getAddress(strippedPath.substring(0, 40));
1665
+ var loc = 40;
1666
+ var res = [];
1667
+ while (loc < strippedPath.length) {
1668
+ var feeAndTokenOut = strippedPath.substring(loc, loc + 46);
1669
+ var fee = parseInt(feeAndTokenOut.substring(0, 6), 16);
1670
+ var tokenOut = ethers.ethers.utils.getAddress(feeAndTokenOut.substring(6, 46));
1671
+ res.push({
1672
+ tokenIn: tokenIn,
1673
+ tokenOut: tokenOut,
1674
+ fee: fee
1675
+ });
1676
+ tokenIn = tokenOut;
1677
+ loc += 46;
1678
+ }
1679
+ return res;
1680
+ }
1681
+ function parseV3PathExactOut(path) {
1682
+ var strippedPath = path.replace('0x', '');
1683
+ var tokenIn = ethers.ethers.utils.getAddress(strippedPath.substring(strippedPath.length - 40));
1684
+ var loc = strippedPath.length - 86; // 86 = (20 addr + 3 fee + 20 addr) * 2 (for hex characters)
1685
+ var res = [];
1686
+ while (loc >= 0) {
1687
+ var feeAndTokenOut = strippedPath.substring(loc, loc + 46);
1688
+ var tokenOut = ethers.ethers.utils.getAddress(feeAndTokenOut.substring(0, 40));
1689
+ var fee = parseInt(feeAndTokenOut.substring(40, 46), 16);
1690
+ res.push({
1691
+ tokenIn: tokenIn,
1692
+ tokenOut: tokenOut,
1693
+ fee: fee
1694
+ });
1695
+ tokenIn = tokenOut;
1696
+ loc -= 46;
1697
+ }
1698
+ return res;
1699
+ }
1700
+ function v4RouterCallToParams(actions) {
1701
+ return actions.map(function (action) {
1702
+ return {
1703
+ name: action.actionName,
1704
+ value: action.params.map(function (param) {
1705
+ return {
1706
+ name: param.name,
1707
+ value: param.value
1708
+ };
1709
+ })
1710
+ };
1711
+ });
1712
+ }
1713
+
1714
+ exports.COMMAND_DEFINITION = COMMAND_DEFINITION;
1715
+ exports.CommandParser = CommandParser;
1716
+ exports.FEW_WRAPPED_NATIVE_CURRENCY = FEW_WRAPPED_NATIVE_CURRENCY;
1717
+ exports.GenericCommandParser = GenericCommandParser;
1718
+ exports.ROUTER_AS_RECIPIENT = ROUTER_AS_RECIPIENT;
1719
+ exports.RoutePlanner = RoutePlanner;
1720
+ exports.RouterTradeAdapter = RouterTradeAdapter;
1721
+ exports.SwapRouter = SwapRouter;
1722
+ exports.UNIVERSAL_ROUTER_ADDRESS = UNIVERSAL_ROUTER_ADDRESS;
1723
+ exports.UNIVERSAL_ROUTER_CREATION_BLOCK = UNIVERSAL_ROUTER_CREATION_BLOCK;
1724
+ exports.UniswapTrade = UniswapTrade;
1725
+ exports.UnwrapWETH = UnwrapWETH;
1726
+ exports.WETH_ADDRESS = WETH_ADDRESS;
1727
+ exports.isNativeCurrency = isNativeCurrency;
1728
+ //# sourceMappingURL=universal-router-sdk.cjs.development.js.map