@gearbox-protocol/sdk 2.1.8 → 2.1.10

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,10 +3,10 @@ export interface StrategyPayload {
3
3
  apy?: number;
4
4
  name: string;
5
5
  lpToken: string;
6
- pools: Array<string>;
6
+ creditManagers: Array<string>;
7
+ baseAssets: Array<string>;
7
8
  unleveragableCollateral: Array<string>;
8
9
  leveragableCollateral: Array<string>;
9
- baseAssets: Array<string>;
10
10
  }
11
11
  interface LiquidationPriceProps {
12
12
  prices: Record<string, bigint>;
@@ -20,18 +20,15 @@ export declare class Strategy {
20
20
  apy: number | undefined;
21
21
  name: string;
22
22
  lpToken: string;
23
- pools: Array<string>;
23
+ baseAssets: Array<string>;
24
24
  unleveragableCollateral: Array<string>;
25
25
  leveragableCollateral: Array<string>;
26
- baseAssets: Array<string>;
26
+ creditManagers: Array<string>;
27
27
  constructor(payload: StrategyPayload);
28
28
  static maxLeverage(lpToken: string, cms: Array<PartialCM>): number;
29
29
  maxAPY(baseAPY: number, maxLeverage: number, borrowAPY: number): number;
30
- overallAPY(apy: number, leverage: number, depositCollateral: string, borrowAPY: number): number;
31
30
  static liquidationPrice({ prices, liquidationThresholds, borrowed, underlyingToken, lpAmount, lpToken, }: LiquidationPriceProps): bigint;
32
- protected farmLev(leverage: number, depositCollateral: string): number;
33
- protected inBaseAssets(depositCollateral: string): boolean;
34
- protected inLeveragableAssets(depositCollateral: string): boolean;
31
+ protected static maxLeverageThreshold(lpToken: string, cms: Array<PartialCM>): readonly [bigint, string];
35
32
  }
36
33
  type PartialCM = Pick<CreditManagerData, "liquidationThresholds" | "address">;
37
34
  export {};
@@ -9,21 +9,21 @@ class Strategy {
9
9
  apy;
10
10
  name;
11
11
  lpToken;
12
- pools;
12
+ baseAssets;
13
13
  unleveragableCollateral;
14
14
  leveragableCollateral;
15
- baseAssets;
15
+ creditManagers;
16
16
  constructor(payload) {
17
17
  this.apy = payload.apy;
18
18
  this.name = payload.name;
19
19
  this.lpToken = payload.lpToken.toLowerCase();
20
- this.pools = payload.pools.map(addr => addr.toLowerCase());
20
+ this.creditManagers = payload.creditManagers.map(addr => addr.toLowerCase());
21
+ this.baseAssets = payload.baseAssets.map(addr => addr.toLowerCase());
21
22
  this.unleveragableCollateral = payload.unleveragableCollateral.map(addr => addr.toLowerCase());
22
23
  this.leveragableCollateral = payload.leveragableCollateral.map(addr => addr.toLowerCase());
23
- this.baseAssets = payload.baseAssets.map(addr => addr.toLowerCase());
24
24
  }
25
25
  static maxLeverage(lpToken, cms) {
26
- const [maxThreshold] = maxLeverageThreshold(lpToken, cms);
26
+ const [maxThreshold] = Strategy.maxLeverageThreshold(lpToken, cms);
27
27
  const maxLeverage = (constants_1.PERCENTAGE_FACTOR * constants_1.LEVERAGE_DECIMALS) /
28
28
  (constants_1.PERCENTAGE_FACTOR - maxThreshold);
29
29
  return Number(maxLeverage - constants_1.LEVERAGE_DECIMALS);
@@ -33,10 +33,6 @@ class Strategy {
33
33
  ((baseAPY - borrowAPY) * (maxLeverage - Number(constants_1.LEVERAGE_DECIMALS))) /
34
34
  Number(constants_1.LEVERAGE_DECIMALS));
35
35
  }
36
- overallAPY(apy, leverage, depositCollateral, borrowAPY) {
37
- const farmLev = this.farmLev(leverage, depositCollateral);
38
- return roi(apy, farmLev, leverage - Number(constants_1.LEVERAGE_DECIMALS), borrowAPY);
39
- }
40
36
  static liquidationPrice({ prices, liquidationThresholds, borrowed, underlyingToken, lpAmount, lpToken, }) {
41
37
  const underlyingTokenAddressLC = underlyingToken.toLowerCase();
42
38
  const underlyingTokenSymbol = token_1.tokenSymbolByAddress[underlyingTokenAddressLC];
@@ -56,36 +52,21 @@ class Strategy {
56
52
  }
57
53
  return 0n;
58
54
  }
59
- farmLev(leverage, depositCollateral) {
60
- return this.inBaseAssets(depositCollateral) ||
61
- this.inLeveragableAssets(depositCollateral)
62
- ? leverage
63
- : leverage - Number(constants_1.LEVERAGE_DECIMALS);
64
- }
65
- inBaseAssets(depositCollateral) {
66
- return this.baseAssets.some(c => c === depositCollateral.toLowerCase());
67
- }
68
- inLeveragableAssets(depositCollateral) {
69
- return this.leveragableCollateral.some(c => c === depositCollateral.toLowerCase());
55
+ static maxLeverageThreshold(lpToken, cms) {
56
+ const lpTokenLC = lpToken.toLowerCase();
57
+ const ltByCM = cms.map(cm => {
58
+ const lt = cm.liquidationThresholds[lpTokenLC] || 0n;
59
+ return [cm.address, lt];
60
+ });
61
+ const sorted = ltByCM.sort(([, ltA], [, ltB]) => {
62
+ if (ltA > ltB)
63
+ return 1;
64
+ if (ltB > ltA)
65
+ return -1;
66
+ return 0;
67
+ });
68
+ const [cm = "", lt = 0n] = sorted[0] || [];
69
+ return [lt, cm];
70
70
  }
71
71
  }
72
72
  exports.Strategy = Strategy;
73
- function roi(apy, farmLev, debtLev, borrowAPY) {
74
- return (apy * farmLev - borrowAPY * debtLev) / Number(constants_1.LEVERAGE_DECIMALS);
75
- }
76
- function maxLeverageThreshold(lpToken, cms) {
77
- const lpTokenLC = lpToken.toLowerCase();
78
- const ltByCM = cms.map(cm => {
79
- const lt = cm.liquidationThresholds[lpTokenLC] || 0n;
80
- return [cm.address, lt];
81
- });
82
- const sorted = ltByCM.sort(([, ltA], [, ltB]) => {
83
- if (ltA > ltB)
84
- return 1;
85
- if (ltB > ltA)
86
- return -1;
87
- return 0;
88
- });
89
- const [cm = "", lt = 0n] = sorted[0] || [];
90
- return [lt, cm];
91
- }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const chai_1 = require("chai");
4
+ const contractsRegister_1 = require("../contracts/contractsRegister");
4
5
  const decimals_1 = require("../tokens/decimals");
5
6
  const token_1 = require("../tokens/token");
6
7
  const formatter_1 = require("../utils/formatter");
@@ -10,7 +11,7 @@ const lidoPayload = {
10
11
  name: "Lido",
11
12
  lpToken: token_1.tokenDataByNetwork.Mainnet.STETH,
12
13
  apy: 38434,
13
- pools: [token_1.tokenDataByNetwork.Mainnet.WETH],
14
+ creditManagers: [contractsRegister_1.creditManagerByNetwork.Mainnet.WETH_V2],
14
15
  unleveragableCollateral: [
15
16
  token_1.tokenDataByNetwork.Mainnet.USDC,
16
17
  token_1.tokenDataByNetwork.Mainnet.DAI,
@@ -43,10 +44,6 @@ describe("Strategy test", () => {
43
44
  const result = lidoStrategy.maxAPY(53203, 10 * Number(constants_1.LEVERAGE_DECIMALS), pools["0x1"].borrowRate);
44
45
  (0, chai_1.expect)(result).to.be.eq(284143);
45
46
  });
46
- it("overallAPY calculation is correct", () => {
47
- const result = lidoStrategy.overallAPY(lidoStrategy.apy || 0, 10 * Number(constants_1.LEVERAGE_DECIMALS), token_1.tokenDataByNetwork.Mainnet.WETH, pools["0x2"].borrowRate);
48
- (0, chai_1.expect)(result).to.be.eq(332716);
49
- });
50
47
  it("liquidationPrice calculation is correct", () => {
51
48
  const result = strategy_1.Strategy.liquidationPrice({
52
49
  liquidationThresholds,
@@ -26,9 +26,12 @@ export declare enum PriceFeedType {
26
26
  ERC4626_VAULT_ORACLE = 16,
27
27
  NETWORK_DEPENDENT = 17
28
28
  }
29
+ export declare const HOUR_1: number;
30
+ export declare const HOUR_24: number;
29
31
  export type PriceFeedData = {
30
32
  type: PriceFeedType.CHAINLINK_ORACLE;
31
33
  address: string;
34
+ stalenessPeriod?: number;
32
35
  } | {
33
36
  type: PriceFeedType.YEARN_ORACLE;
34
37
  token: SupportedToken;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PriceFeedType = void 0;
3
+ exports.HOUR_24 = exports.HOUR_1 = exports.PriceFeedType = void 0;
4
4
  var PriceFeedType;
5
5
  (function (PriceFeedType) {
6
6
  PriceFeedType[PriceFeedType["CHAINLINK_ORACLE"] = 0] = "CHAINLINK_ORACLE";
@@ -22,3 +22,5 @@ var PriceFeedType;
22
22
  PriceFeedType[PriceFeedType["ERC4626_VAULT_ORACLE"] = 16] = "ERC4626_VAULT_ORACLE";
23
23
  PriceFeedType[PriceFeedType["NETWORK_DEPENDENT"] = 17] = "NETWORK_DEPENDENT";
24
24
  })(PriceFeedType = exports.PriceFeedType || (exports.PriceFeedType = {}));
25
+ exports.HOUR_1 = 60 * 60;
26
+ exports.HOUR_24 = 24 * exports.HOUR_1;
@@ -15,7 +15,7 @@ export declare class PathFinder {
15
15
  network: NetworkType;
16
16
  static connectors: Array<SupportedToken>;
17
17
  protected readonly _connectors: Array<string>;
18
- constructor(address: string, provider: Signer | providers.Provider, network?: NetworkType, connectors?: Array<SupportedToken>);
18
+ constructor(address: string, provider: Signer | providers.Provider, network?: NetworkType, connectors?: SupportedToken[]);
19
19
  findAllSwaps(creditAccount: CreditAccountData, swapOperation: SwapOperation, tokenIn: SupportedToken | string, tokenOut: SupportedToken | string, amount: BigNumberish, slippage: number): Promise<Array<PathFinderResult>>;
20
20
  findOneTokenPath(creditAccount: CreditAccountData, tokenIn: SupportedToken | string, tokenOut: SupportedToken | string, amount: BigNumberish, slippage: number): Promise<PathFinderResult>;
21
21
  /**
@@ -41,4 +41,6 @@ export declare class PathFinder {
41
41
  */
42
42
  findBestClosePath(creditAccount: CreditAccountData, slippage: number, noConcurency?: boolean): Promise<PathFinderCloseResult>;
43
43
  static compare(r1: CloseResult, r2: CloseResult, gasPriceRAY: bigint): CloseResult;
44
+ getAvailableConnectors(availableList: Record<string, bigint> | Record<string, true>): string[];
45
+ static getAvailableConnectors(availableList: Record<string, bigint> | Record<string, true>, connectors: string[]): string[];
44
46
  }
@@ -13,19 +13,22 @@ class PathFinder {
13
13
  network;
14
14
  static connectors = ["USDC", "WETH", "DAI"];
15
15
  _connectors;
16
- constructor(address, provider, network = "Mainnet", connectors) {
16
+ constructor(address, provider, network = "Mainnet", connectors = PathFinder.connectors) {
17
17
  this.pathFinder = types_1.IRouter__factory.connect(address, provider);
18
18
  this.network = network;
19
- this._connectors = (connectors || PathFinder.connectors).map(c => token_1.tokenDataByNetwork[this.network][c]);
19
+ this._connectors = connectors
20
+ .map(c => token_1.tokenDataByNetwork[this.network][c]?.toLowerCase())
21
+ .filter(t => !t);
20
22
  }
21
23
  async findAllSwaps(creditAccount, swapOperation, tokenIn, tokenOut, amount, slippage) {
24
+ const connectors = this.getAvailableConnectors(creditAccount.balances);
22
25
  const swapTask = {
23
26
  swapOperation: swapOperation,
24
27
  creditAccount: creditAccount.addr,
25
28
  tokenIn: token_1.tokenDataByNetwork[this.network][tokenIn] || tokenIn,
26
29
  tokenOut: token_1.tokenDataByNetwork[this.network][tokenOut] ||
27
30
  tokenOut,
28
- connectors: this._connectors,
31
+ connectors,
29
32
  amount: amount,
30
33
  slippage,
31
34
  externalSlippage: false,
@@ -47,10 +50,8 @@ class PathFinder {
47
50
  }
48
51
  async findOneTokenPath(creditAccount, tokenIn, tokenOut, amount, slippage) {
49
52
  const tokenInAddr = token_1.tokenDataByNetwork[this.network][tokenIn] || tokenIn;
50
- // if (creditAccount.balances[tokenInAddr.toLowerCase()].lt(amount)) {
51
- // throw new Error(`Not enough balance for token ${tokenIn}`);
52
- // }
53
- const result = await this.pathFinder.callStatic.findOneTokenPath(tokenInAddr, amount, token_1.tokenDataByNetwork[this.network][tokenOut] || tokenOut, creditAccount.addr, this._connectors, slippage, {
53
+ const connectors = this.getAvailableConnectors(creditAccount.balances);
54
+ const result = await this.pathFinder.callStatic.findOneTokenPath(tokenInAddr, amount, token_1.tokenDataByNetwork[this.network][tokenOut] || tokenOut, creditAccount.addr, connectors, slippage, {
54
55
  gasLimit: GAS_PER_BLOCK,
55
56
  });
56
57
  return {
@@ -80,7 +81,8 @@ class PathFinder {
80
81
  token,
81
82
  balance: expectedBalancesAddr[token] || 0,
82
83
  }));
83
- const result = await this.pathFinder.callStatic.findOpenStrategyPath(cm.address, balances, targetAddr, this._connectors, slippage, {
84
+ const connectors = this.getAvailableConnectors(cm.supportedTokens);
85
+ const result = await this.pathFinder.callStatic.findOpenStrategyPath(cm.address, balances, targetAddr, connectors, slippage, {
84
86
  gasLimit: GAS_PER_BLOCK,
85
87
  });
86
88
  const balancesAfter = result[0].reduce((acc, b) => {
@@ -104,16 +106,17 @@ class PathFinder {
104
106
  async findBestClosePath(creditAccount, slippage, noConcurency = false) {
105
107
  const loopsPerTx = Math.floor(GAS_PER_BLOCK / MAX_GAS_PER_ROUTE);
106
108
  const pathOptions = pathOptions_1.PathOptionFactory.generatePathOptions(creditAccount.allBalances, loopsPerTx);
109
+ const connectors = this.getAvailableConnectors(creditAccount.balances);
107
110
  let results = [];
108
111
  if (noConcurency) {
109
112
  for (const po of pathOptions) {
110
- results.push(await this.pathFinder.callStatic.findBestClosePath(creditAccount.addr, this._connectors, slippage, po, loopsPerTx, false, {
113
+ results.push(await this.pathFinder.callStatic.findBestClosePath(creditAccount.addr, connectors, slippage, po, loopsPerTx, false, {
111
114
  gasLimit: GAS_PER_BLOCK,
112
115
  }));
113
116
  }
114
117
  }
115
118
  else {
116
- const requests = pathOptions.map(po => this.pathFinder.callStatic.findBestClosePath(creditAccount.addr, this._connectors, slippage, po, loopsPerTx, false, {
119
+ const requests = pathOptions.map(po => this.pathFinder.callStatic.findBestClosePath(creditAccount.addr, connectors, slippage, po, loopsPerTx, false, {
117
120
  gasLimit: GAS_PER_BLOCK,
118
121
  }));
119
122
  results = await Promise.all(requests);
@@ -137,5 +140,11 @@ class PathFinder {
137
140
  const comparator = ({ amount, gasUsage }, gasPrice) => amount - (gasUsage * gasPrice) / constants_1.RAY;
138
141
  return comparator(r1, gasPriceRAY) > comparator(r2, gasPriceRAY) ? r1 : r2;
139
142
  }
143
+ getAvailableConnectors(availableList) {
144
+ return PathFinder.getAvailableConnectors(availableList, this._connectors);
145
+ }
146
+ static getAvailableConnectors(availableList, connectors) {
147
+ return connectors.filter(t => availableList[t] !== undefined);
148
+ }
140
149
  }
141
150
  exports.PathFinder = PathFinder;
@@ -13,3 +13,4 @@ export type GearboxTokenData = {
13
13
  type: TokenType.GEAR_TOKEN;
14
14
  } & TokenBase;
15
15
  export declare const gearTokens: Record<DieselTokenTypes | GearboxToken, DieselTokenData | GearboxTokenData>;
16
+ export declare const isDieselToken: (t: unknown) => t is DieselTokenTypes;
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.gearTokens = void 0;
3
+ exports.isDieselToken = exports.gearTokens = void 0;
4
4
  const tokenType_1 = require("./tokenType");
5
- exports.gearTokens = {
5
+ const dieselTokens = {
6
6
  // GEARBOX
7
7
  dDAI: {
8
8
  name: "dDAI",
@@ -34,9 +34,14 @@ exports.gearTokens = {
34
34
  symbol: "dFRAX",
35
35
  type: tokenType_1.TokenType.DIESEL_LP_TOKEN,
36
36
  },
37
+ };
38
+ exports.gearTokens = {
39
+ ...dieselTokens,
37
40
  GEAR: {
38
41
  name: "GEAR",
39
42
  symbol: "GEAR",
40
43
  type: tokenType_1.TokenType.GEAR_TOKEN,
41
44
  },
42
45
  };
46
+ const isDieselToken = (t) => typeof t === "string" && !!dieselTokens[t];
47
+ exports.isDieselToken = isDieselToken;
@@ -258,12 +258,9 @@ exports.tokenDataByNetwork = {
258
258
  };
259
259
  exports.tokenSymbolByAddress = mappers_1.TypedObjectUtils.entries(exports.tokenDataByNetwork).reduce((acc, [, tokens]) => ({
260
260
  ...acc,
261
- ...{
262
- ...acc,
263
- ...mappers_1.TypedObjectUtils.fromEntries(mappers_1.TypedObjectUtils.entries(tokens)
264
- .map(([k, v]) => [v.toLowerCase(), k])
265
- .filter(k => !!k)),
266
- },
261
+ ...mappers_1.TypedObjectUtils.fromEntries(mappers_1.TypedObjectUtils.entries(tokens)
262
+ .map(([k, v]) => [v.toLowerCase(), k])
263
+ .filter(k => !!k)),
267
264
  }), {});
268
265
  const isSupportedToken = (t) => typeof t === "string" && !!exports.supportedTokens[t];
269
266
  exports.isSupportedToken = isSupportedToken;
@@ -3,7 +3,7 @@ interface Target {
3
3
  decimals: number | undefined;
4
4
  }
5
5
  export declare class PriceUtils {
6
- static calcTotalPrice: (price: bigint, amount: bigint, decimals?: number) => bigint;
6
+ static calcTotalPrice: (price: bigint, amount: bigint, decimals?: number | undefined) => bigint;
7
7
  static convertByPrice(totalMoney: bigint, { price: targetPrice, decimals: targetDecimals }: Target): bigint;
8
8
  }
9
9
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "2.1.8",
3
+ "version": "2.1.10",
4
4
  "description": "Gearbox SDK",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",