@uniswap/universal-router-sdk 1.5.6 → 1.5.8

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.
@@ -3,8 +3,14 @@ import { Trade as RouterTrade, SwapOptions as RouterSwapOptions } from '@uniswap
3
3
  import { Permit2Permit } from '../../utils/inputTokens';
4
4
  import { Currency, TradeType } from '@uniswap/sdk-core';
5
5
  import { Command, RouterTradeType, TradeConfig } from '../Command';
6
+ import { BigNumberish } from 'ethers';
7
+ export declare type FlatFeeOptions = {
8
+ amount: BigNumberish;
9
+ recipient: string;
10
+ };
6
11
  export declare type SwapOptions = Omit<RouterSwapOptions, 'inputTokenPermit'> & {
7
12
  inputTokenPermit?: Permit2Permit;
13
+ flatFee?: FlatFeeOptions;
8
14
  };
9
15
  export declare class UniswapTrade implements Command {
10
16
  trade: RouterTrade<Currency, Currency, TradeType>;
@@ -3,5 +3,6 @@ export declare const FORGE_ROUTER_ADDRESS = "0xe808c1cfeebb6cb36b537b82fa7c9eef3
3
3
  export declare const FORGE_PERMIT2_ADDRESS = "0x4a873bdd49f7f9cc0a5458416a12973fab208f8d";
4
4
  export declare const FORGE_SENDER_ADDRESS = "0xcf03dd0a894ef79cb5b601a43c4b25e3ae4c67ed";
5
5
  export declare const TEST_RECIPIENT_ADDRESS = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
6
+ export declare const TEST_FEE_RECIPIENT_ADDRESS = "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
6
7
  export declare const PERMIT2_ADDRESS: string;
7
8
  export declare const ROUTER_ADDRESS: string;
@@ -8,12 +8,13 @@ var invariant = _interopDefault(require('tiny-invariant'));
8
8
  var UniversalRouter_json = require('@uniswap/universal-router/artifacts/contracts/UniversalRouter.sol/UniversalRouter.json');
9
9
  var abi$7 = require('@ethersproject/abi');
10
10
  var ethers = require('ethers');
11
- var JSBI = _interopDefault(require('jsbi'));
12
11
  var utils = require('ethers/lib/utils');
13
12
  var v2Sdk = require('@uniswap/v2-sdk');
14
13
  var v3Sdk = require('@uniswap/v3-sdk');
15
14
  var routerSdk = require('@uniswap/router-sdk');
16
15
  var sdkCore = require('@uniswap/sdk-core');
16
+ require('jsbi');
17
+ require('bignumber.js');
17
18
 
18
19
  function _extends() {
19
20
  _extends = Object.assign ? Object.assign.bind() : function (target) {
@@ -199,53 +200,53 @@ var CHAIN_CONFIGS = (_CHAIN_CONFIGS = {}, _CHAIN_CONFIGS[1] = {
199
200
  weth: '0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14',
200
201
  creationBlock: 3543575
201
202
  }, _CHAIN_CONFIGS[137] = {
202
- router: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
203
+ router: '0x643770E279d5D0733F21d6DC03A8efbABf3255B4',
203
204
  weth: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
204
- creationBlock: 42294741
205
+ creationBlock: 46866777
205
206
  }, _CHAIN_CONFIGS[80001] = {
206
207
  router: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
207
208
  weth: '0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889',
208
209
  creationBlock: 35176052
209
210
  }, _CHAIN_CONFIGS[10] = {
210
- router: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
211
+ router: '0xeC8B0F7Ffe3ae75d7FfAb09429e3675bb63503e4',
211
212
  weth: '0x4200000000000000000000000000000000000006',
212
- creationBlock: 96333990
213
+ creationBlock: 108825869
213
214
  }, _CHAIN_CONFIGS[420] = {
214
215
  router: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
215
216
  weth: '0x4200000000000000000000000000000000000006',
216
217
  creationBlock: 8887728
217
218
  }, _CHAIN_CONFIGS[42161] = {
218
- router: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
219
+ router: '0xeC8B0F7Ffe3ae75d7FfAb09429e3675bb63503e4',
219
220
  weth: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
220
- creationBlock: 87206402
221
+ creationBlock: 125861718
221
222
  }, _CHAIN_CONFIGS[421613] = {
222
223
  router: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
223
224
  weth: '0xe39Ab88f8A4777030A534146A9Ca3B52bd5D43A3',
224
225
  creationBlock: 18815277
225
226
  }, _CHAIN_CONFIGS[42220] = {
226
- router: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
227
+ router: '0x88a3ED7F21A3fCF6adb86b6F878C5B7a02D20e9b',
227
228
  weth: WETH_NOT_SUPPORTED_ON_CHAIN,
228
- creationBlock: 19106929
229
+ creationBlock: 21116361
229
230
  }, _CHAIN_CONFIGS[44787] = {
230
231
  router: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
231
232
  weth: WETH_NOT_SUPPORTED_ON_CHAIN,
232
233
  creationBlock: 17566658
233
234
  }, _CHAIN_CONFIGS[56] = {
234
- router: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
235
+ router: '0xeC8B0F7Ffe3ae75d7FfAb09429e3675bb63503e4',
235
236
  weth: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',
236
- creationBlock: 27915533
237
+ creationBlock: 31254967
237
238
  }, _CHAIN_CONFIGS[43114] = {
238
- router: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD',
239
+ router: '0x82635AF6146972cD6601161c4472ffe97237D292',
239
240
  weth: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7',
240
- creationBlock: 31583684
241
+ creationBlock: 34491144
241
242
  }, _CHAIN_CONFIGS[84531] = {
242
243
  router: '0xd0872d928672ae2ff74bdb2f5130ac12229cafaf',
243
244
  weth: '0x4200000000000000000000000000000000000006',
244
245
  creationBlock: 6915289
245
246
  }, _CHAIN_CONFIGS[8453] = {
246
- router: '0x198EF79F1F515F02dFE9e3115eD9fC07183f02fC',
247
+ router: '0xeC8B0F7Ffe3ae75d7FfAb09429e3675bb63503e4',
247
248
  weth: '0x4200000000000000000000000000000000000006',
248
- creationBlock: 1452376
249
+ creationBlock: 3229053
249
250
  }, _CHAIN_CONFIGS);
250
251
  var UNIVERSAL_ROUTER_ADDRESS = function UNIVERSAL_ROUTER_ADDRESS(chainId) {
251
252
  if (!(chainId in CHAIN_CONFIGS)) throw new Error("Universal Router not deployed on chain " + chainId);
@@ -269,7 +270,11 @@ var ROUTER_AS_RECIPIENT = '0x0000000000000000000000000000000000000002';
269
270
  var OPENSEA_CONDUIT_SPENDER_ID = 0;
270
271
  var SUDOSWAP_SPENDER_ID = 1;
271
272
 
272
- var REFUND_ETH_PRICE_IMPACT_THRESHOLD = /*#__PURE__*/new sdkCore.Percent( /*#__PURE__*/JSBI.BigInt(50), /*#__PURE__*/JSBI.BigInt(100));
273
+ function encodeFeeBips(fee) {
274
+ return v3Sdk.toHex(fee.multiply(10000).quotient);
275
+ }
276
+
277
+ var REFUND_ETH_PRICE_IMPACT_THRESHOLD = /*#__PURE__*/new sdkCore.Percent(50, 100);
273
278
  // Wrapper for uniswap router-sdk trade entity to encode swaps for Universal Router
274
279
  // also translates trade objects from previous (v2, v3) SDKs
275
280
  var UniswapTrade = /*#__PURE__*/function () {
@@ -277,17 +282,20 @@ var UniswapTrade = /*#__PURE__*/function () {
277
282
  this.trade = trade;
278
283
  this.options = options;
279
284
  this.tradeType = exports.RouterTradeType.UniswapTrade;
285
+ if (!!options.fee && !!options.flatFee) throw new Error('Only one fee option permitted');
280
286
  }
281
287
  var _proto = UniswapTrade.prototype;
282
288
  _proto.encode = function encode(planner, _config) {
283
289
  var _this$options$recipie;
284
290
  var payerIsUser = true;
291
+ // If the input currency is the native currency, we need to wrap it with the router as the recipient
285
292
  if (this.trade.inputAmount.currency.isNative) {
286
293
  // TODO: optimize if only one v2 pool we can directly send this to the pool
287
294
  planner.addCommand(CommandType.WRAP_ETH, [ROUTER_AS_RECIPIENT, this.trade.maximumAmountIn(this.options.slippageTolerance).quotient.toString()]);
288
295
  // since WETH is now owned by the router, the router pays for inputs
289
296
  payerIsUser = false;
290
297
  }
298
+ // The overall recipient at the end of the trade, SENDER_AS_RECIPIENT uses the msg.sender
291
299
  this.options.recipient = (_this$options$recipie = this.options.recipient) != null ? _this$options$recipie : SENDER_AS_RECIPIENT;
292
300
  // flag for whether we want to perform slippage check on aggregate output of multiple routes
293
301
  // 1. when there are >2 exact input trades. this is only a heuristic,
@@ -296,7 +304,7 @@ var UniswapTrade = /*#__PURE__*/function () {
296
304
  var performAggregatedSlippageCheck = this.trade.tradeType === sdkCore.TradeType.EXACT_INPUT && this.trade.routes.length > 2;
297
305
  var outputIsNative = this.trade.outputAmount.currency.isNative;
298
306
  var inputIsNative = this.trade.inputAmount.currency.isNative;
299
- var routerMustCustody = performAggregatedSlippageCheck || outputIsNative;
307
+ var routerMustCustody = performAggregatedSlippageCheck || outputIsNative || hasFeeOption(this.options);
300
308
  for (var _iterator = _createForOfIteratorHelperLoose(this.trade.swaps), _step; !(_step = _iterator()).done;) {
301
309
  var swap = _step.value;
302
310
  switch (swap.route.protocol) {
@@ -313,11 +321,38 @@ var UniswapTrade = /*#__PURE__*/function () {
313
321
  throw new Error('UNSUPPORTED_TRADE_PROTOCOL');
314
322
  }
315
323
  }
324
+ var minimumAmountOut = ethers.BigNumber.from(this.trade.minimumAmountOut(this.options.slippageTolerance).quotient.toString());
325
+ // The router custodies for 3 reasons: to unwrap, to take a fee, and/or to do a slippage check
316
326
  if (routerMustCustody) {
327
+ // If there is a fee, that percentage is sent to the fee recipient
328
+ // In the case where ETH is the output currency, the fee is taken in WETH (for gas reasons)
329
+ if (!!this.options.fee) {
330
+ var feeBips = encodeFeeBips(this.options.fee.fee);
331
+ planner.addCommand(CommandType.PAY_PORTION, [this.trade.outputAmount.currency.wrapped.address, this.options.fee.recipient, feeBips]);
332
+ // If the trade is exact output, and a fee was taken, we must adjust the amount out to be the amount after the fee
333
+ // Otherwise we continue as expected with the trade's normal expected output
334
+ if (this.trade.tradeType === sdkCore.TradeType.EXACT_OUTPUT) {
335
+ minimumAmountOut = minimumAmountOut.sub(minimumAmountOut.mul(feeBips).div(10000));
336
+ }
337
+ }
338
+ // If there is a flat fee, that absolute amount is sent to the fee recipient
339
+ // In the case where ETH is the output currency, the fee is taken in WETH (for gas reasons)
340
+ if (!!this.options.flatFee) {
341
+ var feeAmount = this.options.flatFee.amount;
342
+ if (minimumAmountOut.lt(feeAmount)) throw new Error('Flat fee amount greater than minimumAmountOut');
343
+ planner.addCommand(CommandType.TRANSFER, [this.trade.outputAmount.currency.wrapped.address, this.options.flatFee.recipient, feeAmount]);
344
+ // If the trade is exact output, and a fee was taken, we must adjust the amount out to be the amount after the fee
345
+ // Otherwise we continue as expected with the trade's normal expected output
346
+ if (this.trade.tradeType === sdkCore.TradeType.EXACT_OUTPUT) {
347
+ minimumAmountOut = minimumAmountOut.sub(feeAmount);
348
+ }
349
+ }
350
+ // The remaining tokens that need to be sent to the user after the fee is taken will be caught
351
+ // by this if-else clause.
317
352
  if (outputIsNative) {
318
- planner.addCommand(CommandType.UNWRAP_WETH, [this.options.recipient, this.trade.minimumAmountOut(this.options.slippageTolerance).quotient.toString()]);
353
+ planner.addCommand(CommandType.UNWRAP_WETH, [this.options.recipient, minimumAmountOut]);
319
354
  } else {
320
- planner.addCommand(CommandType.SWEEP, [this.trade.outputAmount.currency.wrapped.address, this.options.recipient, this.trade.minimumAmountOut(this.options.slippageTolerance).quotient.toString()]);
355
+ planner.addCommand(CommandType.SWEEP, [this.trade.outputAmount.currency.wrapped.address, this.options.recipient, minimumAmountOut]);
321
356
  }
322
357
  }
323
358
  if (inputIsNative && (this.trade.tradeType === sdkCore.TradeType.EXACT_OUTPUT || riskOfPartialFill(this.trade))) {
@@ -426,6 +461,9 @@ function addMixedSwap(planner, swap, tradeType, options, payerIsUser, routerMust
426
461
  function riskOfPartialFill(trade) {
427
462
  return trade.priceImpact.greaterThan(REFUND_ETH_PRICE_IMPACT_THRESHOLD);
428
463
  }
464
+ function hasFeeOption(swapOptions) {
465
+ return !!swapOptions.fee || !!swapOptions.flatFee;
466
+ }
429
467
 
430
468
  var SIGNATURE_LENGTH = 65;
431
469
  var EIP_2098_SIGNATURE_LENGTH = 64;