@gearbox-protocol/sdk 3.0.0-next.127 → 3.0.0-next.129

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.
@@ -168,7 +168,7 @@ function calculateConvexAPY(props) {
168
168
  return finished ? 0n : extraAPY;
169
169
  });
170
170
  const extraAPYTotal = extraAPRs.reduce((acc, apy) => acc + apy, 0n);
171
- const baseApy = props.curveAPY?.[crvToken].base || 0;
171
+ const baseApy = props.curveAPY?.[crvToken]?.base || 0;
172
172
  const apyTotal = crvAPY + cvxAPY + extraAPYTotal;
173
173
  const apyTotalInPercent = apyTotal * sdk_gov_1.PERCENTAGE_DECIMALS * sdk_gov_1.PERCENTAGE_FACTOR;
174
174
  const r = baseApy + Math.round(Number((apyTotalInPercent * 10n) / sdk_gov_1.WAD) / 10);
@@ -1,3 +1,4 @@
1
+ import { NetworkType, PartialRecord } from "@gearbox-protocol/sdk-gov";
1
2
  import { CurveLPToken } from "@gearbox-protocol/sdk-gov/lib/tokens/curveLP";
2
3
  import { GearboxToken } from "@gearbox-protocol/sdk-gov/lib/tokens/gear";
3
4
  interface CurvePoolData {
@@ -50,7 +51,13 @@ interface CurveAPY {
50
51
  crv: number;
51
52
  gauge: Array<[string, number]>;
52
53
  }
53
- export type CurveAPYResult = Record<CurveAPYTokens, CurveAPY>;
54
- export declare function getCurveAPY(): Promise<CurveAPYResult>;
54
+ export type CurveAPYResult = PartialRecord<CurveAPYTokens, CurveAPY>;
55
+ export declare function getCurveAPY(network: NetworkType): Promise<{
56
+ curveAPY: CurveAPYResult;
57
+ gearAPY: CurveAPY;
58
+ } | {
59
+ curveAPY?: undefined;
60
+ gearAPY?: undefined;
61
+ }>;
55
62
  export declare function getCurveGearPool(): Promise<CurvePoolData | undefined>;
56
63
  export {};
@@ -6,76 +6,66 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getCurveGearPool = exports.getCurveAPY = void 0;
7
7
  const sdk_gov_1 = require("@gearbox-protocol/sdk-gov");
8
8
  const axios_1 = __importDefault(require("axios"));
9
- const APY_DICTIONARY = {
10
- "3Crv": "0",
11
- FRAX3CRV: "34",
12
- gusd3CRV: "19",
13
- LUSD3CRV: "33",
14
- crvPlain3andSUSD: "15",
15
- steCRV: "14",
16
- crvFRAX: "44",
17
- GEAR: "factory-crypto-192",
18
- OHMFRAXBP: "factory-crypto-158",
19
- MIM_3LP3CRV: "40",
20
- crvCRVETH: "crypto-3",
21
- crvCVXETH: "crypto-4",
22
- crvUSDTWBTCWETH: "factory-tricrypto-1",
23
- LDOETH: "factory-crypto-204",
24
- crvUSDUSDC: "factory-crvusd-0",
25
- crvUSDUSDT: "factory-crvusd-1",
26
- crvUSDFRAX: "factory-crvusd-4",
27
- crvUSDETHCRV: "factory-tricrypto-4",
28
- rETH_f: "factory-crypto-210",
29
- wstETHCRV: "unknown",
30
- "2CRV": "unknown",
31
- "3c-crvUSD": "unknown",
32
- crvUSDC: "unknown",
33
- crvUSDT: "unknown",
34
- crvUSDC_e: "unknown",
35
- "3CRV": "unknown", // 0xEfDE221f306152971D8e9f181bFe998447975810
9
+ const GEAR_POOL = "0x5Be6C45e2d074fAa20700C49aDA3E88a1cc0025d".toLowerCase();
10
+ const CURVE_CHAINS = {
11
+ Arbitrum: "arbitrum",
12
+ Mainnet: "ethereum",
13
+ Optimism: "optimism",
36
14
  };
37
- // const CRYPTO = "https://api.curve.fi/api/getPools/ethereum/crypto";
38
- // const FACTORY = "https://api.curve.fi/api/getPools/ethereum/factory";
39
- const CURVE_APY_URL = "https://www.convexfinance.com/api/curve-apys";
40
- const CURVE_MAIN_URL = "https://api.curve.fi/api/getPools/ethereum/main";
41
- const CURVE_FACTORY_CRYPTO_URL = "https://api.curve.fi/api/getPools/ethereum/factory-crypto";
42
- const CURVE_CRYPTO_URL = "https://api.curve.fi/api/getPools/ethereum/crypto";
43
- const CURVE_FACTORY_TRICRYPTO_URL = "https://api.curve.fi/api/getPools/ethereum/factory-tricrypto";
44
- const CURVE_FACTORY_CRVUSD_URL = "https://api.curve.fi/api/getPools/ethereum/factory-crvusd";
45
- async function getCurveAPY() {
15
+ // const CRYPTO = "https://api.curve.fi/api/getPools/${CURVE_CHAINS[n]}/crypto";
16
+ // const FACTORY = "https://api.curve.fi/api/getPools/${CURVE_CHAINS[n]}/factory";
17
+ // const CURVE_APY_URL = "https://www.convexfinance.com/api/curve-apys";
18
+ const getVolumesURL = (n) => `https://api.curve.fi/api/getVolumes/${CURVE_CHAINS[n]}`;
19
+ const getMainURL = (n) => `https://api.curve.fi/api/getPools/${CURVE_CHAINS[n]}/main`;
20
+ const getFactoryCryptoURL = (n) => `https://api.curve.fi/api/getPools/${CURVE_CHAINS[n]}/factory-crypto`;
21
+ const getCryptoURL = (n) => `https://api.curve.fi/api/getPools/${CURVE_CHAINS[n]}/crypto`;
22
+ const getFactoryTriCryptoURL = (n) => `https://api.curve.fi/api/getPools/${CURVE_CHAINS[n]}/factory-tricrypto`;
23
+ const getFactoryCrvUsdURL = (n) => `https://api.curve.fi/api/getPools/${CURVE_CHAINS[n]}/factory-crvusd`;
24
+ const getFactoryStableNgURL = (n) => `https://api.curve.fi/api/getPools/${CURVE_CHAINS[n]}/factory-stable-ng`;
25
+ async function getCurveAPY(network) {
46
26
  try {
47
- const [{ data: apyData }, ...restData] = await Promise.all([
48
- axios_1.default.get(CURVE_APY_URL),
49
- axios_1.default.get(CURVE_MAIN_URL),
50
- axios_1.default.get(CURVE_FACTORY_CRYPTO_URL),
51
- axios_1.default.get(CURVE_CRYPTO_URL),
52
- axios_1.default.get(CURVE_FACTORY_TRICRYPTO_URL),
53
- axios_1.default.get(CURVE_FACTORY_CRVUSD_URL),
54
- ]);
55
- const { apys } = apyData || {};
56
- const poolDataByID = Object.fromEntries(restData
57
- .map(resp => {
58
- const { poolData = [] } = resp?.data?.data || {};
59
- return poolData.map(p => [p.id, p]);
27
+ const currentTokens = sdk_gov_1.tokenDataByNetwork[network];
28
+ const { mainnetVolumes, mainnetFactoryPools, volumes, pools } = await getCurvePools(network);
29
+ const volumeByAddress = Object.fromEntries(volumes.data.data.pools.map(v => [v.address.toLowerCase(), v]));
30
+ const poolDataByAddress = Object.fromEntries(pools
31
+ .map(poolCategory => {
32
+ const { poolData = [] } = poolCategory?.data?.data || {};
33
+ return poolData.map((p) => [
34
+ p.lpTokenAddress.toLowerCase(),
35
+ p,
36
+ ]);
60
37
  })
61
38
  .flat(1));
62
- const curveAPY = sdk_gov_1.TypedObjectUtils.entries(APY_DICTIONARY).reduce((acc, [curveSymbol, poolId]) => {
63
- const { baseApy, crvApy } = apys[poolId] || {};
64
- const pool = poolDataByID[poolId];
65
- const { gaugeRewards = [] } = pool || {};
66
- const extraRewards = gaugeRewards.map(({ apy = 0, symbol }) => [
39
+ const curveAPY = sdk_gov_1.TypedObjectUtils.entries(sdk_gov_1.curveTokens).reduce((acc, [curveSymbol]) => {
40
+ const address = (currentTokens?.[curveSymbol] || "").toLowerCase();
41
+ const pool = poolDataByAddress[address];
42
+ const volume = volumeByAddress[(pool?.address || "").toLowerCase()];
43
+ const baseAPY = volume?.latestDailyApyPcent || 0;
44
+ const maxCrv = Math.max(...(pool?.gaugeCrvApy || []), 0);
45
+ const extraRewards = (pool?.gaugeRewards || []).map(({ apy = 0, symbol }) => [
67
46
  symbol.toLowerCase(),
68
47
  curveAPYToBn(apy),
69
48
  ]);
70
- const maxCrv = pool?.gaugeCrvApy?.length > 0 ? Math.max(...pool.gaugeCrvApy) : crvApy;
71
49
  acc[curveSymbol] = {
72
- base: curveAPYToBn(baseApy || 0),
73
- crv: curveAPYToBn(maxCrv || 0),
50
+ base: curveAPYToBn(baseAPY),
51
+ crv: curveAPYToBn(maxCrv),
74
52
  gauge: extraRewards,
75
53
  };
76
54
  return acc;
77
55
  }, {});
78
- return curveAPY;
56
+ const poolFactoryByAddress = Object.fromEntries((mainnetFactoryPools?.data?.data?.poolData || []).map((p) => [p.lpTokenAddress.toLowerCase(), p]));
57
+ const mainnetVolumeByAddress = Object.fromEntries(mainnetVolumes.data.data.pools.map(v => [v.address.toLowerCase(), v]));
58
+ const gearPool = poolFactoryByAddress[GEAR_POOL];
59
+ const gearVolume = mainnetVolumeByAddress[(gearPool?.address || "").toLowerCase()];
60
+ const gearAPY = {
61
+ base: curveAPYToBn(gearVolume?.latestDailyApyPcent || 0),
62
+ crv: curveAPYToBn(Math.max(...(gearPool?.gaugeCrvApy || []), 0)),
63
+ gauge: (gearPool?.gaugeRewards || []).map(({ apy = 0, symbol }) => [
64
+ symbol.toLowerCase(),
65
+ curveAPYToBn(apy),
66
+ ]),
67
+ };
68
+ return { curveAPY, gearAPY };
79
69
  }
80
70
  catch (e) {
81
71
  console.error(e);
@@ -83,20 +73,66 @@ async function getCurveAPY() {
83
73
  }
84
74
  }
85
75
  exports.getCurveAPY = getCurveAPY;
76
+ async function getCurvePools(network) {
77
+ switch (network) {
78
+ case "Mainnet": {
79
+ const [volumes, mainnetFactoryPools, ...pools] = await Promise.all([
80
+ axios_1.default.get(getVolumesURL(network)),
81
+ axios_1.default.get(getFactoryCryptoURL(network)),
82
+ axios_1.default.get(getMainURL(network)),
83
+ axios_1.default.get(getCryptoURL(network)),
84
+ axios_1.default.get(getFactoryTriCryptoURL(network)),
85
+ axios_1.default.get(getFactoryCrvUsdURL(network)),
86
+ ]);
87
+ return {
88
+ mainnetVolumes: volumes,
89
+ mainnetFactoryPools,
90
+ volumes,
91
+ pools: [mainnetFactoryPools, ...pools],
92
+ };
93
+ }
94
+ case "Arbitrum": {
95
+ const [mainnetVolumes, mainnetFactoryPools, volumes, ...pools] = await Promise.all([
96
+ axios_1.default.get(getVolumesURL("Mainnet")),
97
+ axios_1.default.get(getFactoryCryptoURL("Mainnet")),
98
+ axios_1.default.get(getVolumesURL(network)),
99
+ axios_1.default.get(getMainURL(network)),
100
+ axios_1.default.get(getFactoryStableNgURL(network)),
101
+ ]);
102
+ return {
103
+ mainnetVolumes,
104
+ mainnetFactoryPools,
105
+ volumes,
106
+ pools,
107
+ };
108
+ }
109
+ case "Optimism": {
110
+ const [mainnetVolumes, mainnetFactoryPools, volumes, ...pools] = await Promise.all([
111
+ axios_1.default.get(getVolumesURL("Mainnet")),
112
+ axios_1.default.get(getFactoryCryptoURL("Mainnet")),
113
+ axios_1.default.get(getVolumesURL(network)),
114
+ axios_1.default.get(getMainURL(network)),
115
+ axios_1.default.get(getFactoryStableNgURL(network)),
116
+ ]);
117
+ return {
118
+ mainnetVolumes,
119
+ mainnetFactoryPools,
120
+ volumes,
121
+ pools,
122
+ };
123
+ }
124
+ default:
125
+ throw new Error("Unknown network");
126
+ }
127
+ }
86
128
  function curveAPYToBn(baseApy) {
87
129
  return Math.round(baseApy * Number(sdk_gov_1.PERCENTAGE_FACTOR));
88
130
  }
89
131
  async function getCurveGearPool() {
90
- const data = await Promise.all([
91
- axios_1.default.get(CURVE_FACTORY_CRYPTO_URL),
92
- ]);
93
- const poolDataByID = Object.fromEntries(data
94
- .map(resp => {
95
- const { poolData = [] } = resp?.data?.data || {};
96
- return poolData.map(p => [p.id, p]);
97
- })
98
- .flat(1));
99
- const gearPool = poolDataByID[APY_DICTIONARY.GEAR];
132
+ const resp = await axios_1.default.get(getFactoryCryptoURL("Mainnet"));
133
+ const { poolData = [] } = resp?.data?.data || {};
134
+ const poolDataByAddress = Object.fromEntries(poolData.map(p => [p.lpTokenAddress.toLowerCase(), p]));
135
+ const gearPool = poolDataByAddress[GEAR_POOL];
100
136
  return gearPool;
101
137
  }
102
138
  exports.getCurveGearPool = getCurveGearPool;
@@ -10,7 +10,10 @@ const LAMA_URL = "https://charts-server.fly.dev/api/defillama?ids=";
10
10
  async function getDefiLamaAPY(networkType) {
11
11
  try {
12
12
  const currentNormal = NORMAL_TO_LAMA[networkType];
13
- const res = await axios_1.default.get(`${LAMA_URL}${Object.values(currentNormal).join(",")}`);
13
+ const idList = Object.values(currentNormal);
14
+ if (idList.length === 0)
15
+ return {};
16
+ const res = await axios_1.default.get(`${LAMA_URL}${idList.join(",")}`);
14
17
  const itemsRecord = res.data.data.reduce((acc, item) => {
15
18
  acc[item.pool] = item;
16
19
  return acc;
@@ -34,7 +37,7 @@ const NORMAL_TO_LAMA = {
34
37
  osETH: "4d01599c-69ae-41a3-bae1-5fab896f04c8",
35
38
  auraB_rETH_STABLE_vault: "a4b5b995-99e7-4b8f-916d-8940b5627d70",
36
39
  },
37
- Optimism: { rETH: "d4b3c522-6127-4b89-bedf-83641cdcd2eb" },
40
+ Optimism: {},
38
41
  Arbitrum: {},
39
42
  };
40
43
  // const CONVEX_TO_LAMA: Record<
@@ -1,3 +1,3 @@
1
- import { NetworkType, YearnLPToken } from "@gearbox-protocol/sdk-gov";
2
- export type YearnAPYResult = Record<YearnLPToken, number>;
1
+ import { NetworkType, PartialRecord, YearnLPToken } from "@gearbox-protocol/sdk-gov";
2
+ export type YearnAPYResult = PartialRecord<YearnLPToken, number>;
3
3
  export declare function getYearnAPY(network: NetworkType): Promise<YearnAPYResult>;
@@ -10,13 +10,14 @@ const getUrl = (chainId) => `https://ydaemon.yearn.finance/vaults/all?chainids=$
10
10
  async function getYearnAPY(network) {
11
11
  try {
12
12
  const chainId = sdk_gov_1.CHAINS[network];
13
+ const currentTokens = sdk_gov_1.tokenDataByNetwork[network];
13
14
  const { data } = await axios_1.default.get(getUrl(chainId));
14
15
  const dataByAddress = data.reduce((acc, d) => {
15
16
  acc[d.address.toLowerCase()] = d;
16
17
  return acc;
17
18
  }, {});
18
19
  const yearnAPY = sdk_gov_1.TypedObjectUtils.entries(sdk_gov_1.yearnTokens).reduce((acc, [yearnSymbol]) => {
19
- const address = (sdk_gov_1.tokenDataByNetwork[network]?.[yearnSymbol] || "").toLowerCase();
20
+ const address = (currentTokens?.[yearnSymbol] || "").toLowerCase();
20
21
  const data = dataByAddress[address];
21
22
  const { apr: apy } = data || {};
22
23
  const { netAPR } = apy || {};
@@ -40,6 +40,7 @@ export interface CalcQuotaUpdateProps {
40
40
  initialQuotas: Record<string, Pick<CaTokenBalance, "quota">>;
41
41
  liquidationThresholds: Record<string, bigint>;
42
42
  assetsAfterUpdate: Record<string, AssetWithAmountInTarget>;
43
+ maxDebt: bigint;
43
44
  allowedToSpend: Record<string, {}>;
44
45
  allowedToObtain: Record<string, {}>;
45
46
  quotaReserve: bigint;
@@ -120,7 +121,8 @@ export declare class CreditAccountData {
120
121
  static calcHealthFactor({ assets, quotas, quotasInfo, liquidationThresholds, underlyingToken, debt, prices, }: CalcHealthFactorProps): number;
121
122
  static calcRecommendedQuota({ amount, debt, lt, quotaReserve, }: CalcRecommendedQuotaProps): bigint;
122
123
  static calcDefaultQuota({ amount, lt, quotaReserve }: CalcDefaultQuotaProps): bigint;
123
- static calcQuotaUpdate({ quotas, initialQuotas, assetsAfterUpdate, liquidationThresholds, allowedToSpend, allowedToObtain, quotaReserve, }: CalcQuotaUpdateProps): CalcQuotaUpdateReturnType;
124
+ static calcQuotaUpdate(props: CalcQuotaUpdateProps): CalcQuotaUpdateReturnType;
125
+ private static getSingleQuotaChange;
124
126
  static calcQuotaBorrowRate({ quotas, quotaRates }: CalcQuotaBorrowRateProps): bigint;
125
127
  static calcRelativeBaseBorrowRate({ debt, baseRateWithFee, assetAmountInUnderlying, totalValue, }: CalcRelativeBaseBorrowRateProps): bigint;
126
128
  static liquidationPrice({ liquidationThresholds, debt, underlyingToken, targetToken, assets, }: LiquidationPriceProps): bigint;
@@ -239,56 +239,81 @@ class CreditAccountData {
239
239
  sdk_gov_1.PERCENTAGE_FACTOR;
240
240
  return recommendedQuota;
241
241
  }
242
- static calcQuotaUpdate({ quotas, initialQuotas, assetsAfterUpdate, liquidationThresholds, allowedToSpend, allowedToObtain, quotaReserve, }) {
243
- const r = Object.values(quotas).reduce((acc, cmQuota) => {
242
+ static calcQuotaUpdate(props) {
243
+ const { quotas, initialQuotas, maxDebt, allowedToSpend, allowedToObtain } = props;
244
+ const quotaDecrease = Object.keys(allowedToSpend).reduce((acc, token) => {
245
+ const ch = CreditAccountData.getSingleQuotaChange(token, 0n, props);
246
+ if (ch)
247
+ acc[ch.token] = ch;
248
+ return acc;
249
+ }, {});
250
+ const quotaCap = maxDebt * 2n;
251
+ const quotaBought = Object.values(initialQuotas).reduce((sum, q) => sum + (q?.quota || 0n), 0n);
252
+ const quotaReduced = Object.values(quotaDecrease).reduce((sum, q) => sum + (q.balance || 0n), 0n);
253
+ const maxQuotaIncrease = math_1.BigIntMath.max(quotaCap - (quotaBought + quotaReduced), 0n);
254
+ const quotaIncrease = Object.keys(allowedToObtain).reduce((acc, token) => {
255
+ const ch = CreditAccountData.getSingleQuotaChange(token, maxQuotaIncrease, props);
256
+ if (ch)
257
+ acc[ch.token] = ch;
258
+ return acc;
259
+ }, {});
260
+ const quotaChange = {
261
+ ...quotaDecrease,
262
+ ...quotaIncrease,
263
+ };
264
+ const desiredQuota = Object.values(quotas).reduce((acc, cmQuota) => {
244
265
  const { token, isActive } = cmQuota;
245
266
  const { quota: initialQuota = 0n } = initialQuotas[token] || {};
246
267
  if (!isActive) {
247
- acc.desiredQuota[token] = {
268
+ acc[token] = {
248
269
  balance: initialQuota,
249
270
  token,
250
271
  };
251
- return acc;
252
- }
253
- // min(debt,assetAmountInUnderlying*LT)*(1+buffer)
254
- const after = assetsAfterUpdate[token];
255
- const { amountInTarget = 0n } = after || {};
256
- const lt = liquidationThresholds[token] || 0n;
257
- const desiredQuota = this.calcDefaultQuota({
258
- lt,
259
- quotaReserve,
260
- amount: amountInTarget,
261
- });
262
- const quotaChange = desiredQuota - initialQuota;
263
- const correctIncrease = after && allowedToObtain[token] && quotaChange > 0;
264
- const correctDecrease = after && allowedToSpend[token] && quotaChange < 0;
265
- if (correctIncrease || correctDecrease) {
266
- acc.desiredQuota[token] = {
267
- balance: desiredQuota,
268
- token,
269
- };
270
272
  }
271
273
  else {
272
- acc.desiredQuota[token] = {
273
- balance: initialQuota,
274
+ const change = quotaChange[token]?.balance || 0n;
275
+ const quotaAfter = initialQuota + change;
276
+ acc[token] = {
277
+ balance: quotaAfter,
274
278
  token,
275
279
  };
276
280
  }
277
- if (correctIncrease) {
278
- acc.quotaIncrease.push({
279
- balance: quotaChange,
280
- token,
281
- });
282
- }
283
- if (correctDecrease) {
284
- acc.quotaDecrease.push({
285
- balance: quotaChange,
286
- token,
287
- });
288
- }
289
281
  return acc;
290
- }, { desiredQuota: {}, quotaIncrease: [], quotaDecrease: [] });
291
- return r;
282
+ }, {});
283
+ return {
284
+ desiredQuota,
285
+ quotaDecrease: Object.values(quotaDecrease),
286
+ quotaIncrease: Object.values(quotaIncrease),
287
+ };
288
+ }
289
+ static getSingleQuotaChange(token, maxQuotaIncrease, props) {
290
+ const { isActive = false } = props.quotas[token] || {};
291
+ const { quota: initialQuota = 0n } = props.initialQuotas[token] || {};
292
+ if (!isActive) {
293
+ return undefined;
294
+ }
295
+ // min(debt,assetAmountInUnderlying*LT)*(1+buffer)
296
+ const assetAfter = props.assetsAfterUpdate[token];
297
+ const { amountInTarget = 0n } = assetAfter || {};
298
+ const lt = props.liquidationThresholds[token] || 0n;
299
+ const defaultQuota = this.calcDefaultQuota({
300
+ lt,
301
+ quotaReserve: props.quotaReserve,
302
+ amount: amountInTarget,
303
+ });
304
+ const unsafeQuotaChange = defaultQuota - initialQuota;
305
+ const quotaChange = unsafeQuotaChange > 0
306
+ ? math_1.BigIntMath.min(maxQuotaIncrease, unsafeQuotaChange)
307
+ : unsafeQuotaChange;
308
+ const correctIncrease = assetAfter && props.allowedToObtain[token] && quotaChange > 0;
309
+ const correctDecrease = assetAfter && props.allowedToSpend[token] && quotaChange < 0;
310
+ if (correctIncrease || correctDecrease) {
311
+ return {
312
+ balance: quotaChange,
313
+ token,
314
+ };
315
+ }
316
+ return undefined;
292
317
  }
293
318
  static calcQuotaBorrowRate({ quotas, quotaRates }) {
294
319
  const totalRateBalance = Object.values(quotas).reduce((acc, { token, balance }) => {
@@ -422,9 +422,11 @@ const DEFAULT_LT = {
422
422
  [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: sdk_gov_1.PERCENTAGE_FACTOR,
423
423
  [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: sdk_gov_1.PERCENTAGE_FACTOR,
424
424
  };
425
+ const HUGE_MAX_DEBT = 20n;
425
426
  describe("CreditAccount calcQuotaUpdate test", () => {
426
427
  it("open account should buy quota", () => {
427
428
  const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
429
+ maxDebt: HUGE_MAX_DEBT,
428
430
  quotaReserve: QUOTA_RESERVE,
429
431
  quotas: cmQuotas,
430
432
  initialQuotas: {},
@@ -475,6 +477,7 @@ describe("CreditAccount calcQuotaUpdate test", () => {
475
477
  });
476
478
  it("add collateral should buy quota", () => {
477
479
  const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
480
+ maxDebt: HUGE_MAX_DEBT,
478
481
  quotaReserve: QUOTA_RESERVE,
479
482
  quotas: cmQuotas,
480
483
  initialQuotas: caQuota,
@@ -515,6 +518,7 @@ describe("CreditAccount calcQuotaUpdate test", () => {
515
518
  });
516
519
  it("add collateral should add additional quota", () => {
517
520
  const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
521
+ maxDebt: HUGE_MAX_DEBT,
518
522
  quotaReserve: QUOTA_RESERVE,
519
523
  quotas: cmQuotas,
520
524
  initialQuotas: caQuota,
@@ -555,6 +559,7 @@ describe("CreditAccount calcQuotaUpdate test", () => {
555
559
  });
556
560
  it("add collateral shouldn't add additional quota", () => {
557
561
  const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
562
+ maxDebt: HUGE_MAX_DEBT,
558
563
  quotaReserve: QUOTA_RESERVE,
559
564
  quotas: cmQuotas,
560
565
  initialQuotas: caQuota,
@@ -590,6 +595,7 @@ describe("CreditAccount calcQuotaUpdate test", () => {
590
595
  });
591
596
  it("swap should buy quota", () => {
592
597
  const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
598
+ maxDebt: HUGE_MAX_DEBT,
593
599
  quotaReserve: QUOTA_RESERVE,
594
600
  quotas: cmQuotas,
595
601
  initialQuotas: caQuota,
@@ -635,8 +641,9 @@ describe("CreditAccount calcQuotaUpdate test", () => {
635
641
  },
636
642
  });
637
643
  });
638
- it("swap should add additional quota", () => {
644
+ it("swap should buy additional quota", () => {
639
645
  const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
646
+ maxDebt: HUGE_MAX_DEBT,
640
647
  quotaReserve: QUOTA_RESERVE,
641
648
  quotas: cmQuotas,
642
649
  initialQuotas: caQuota,
@@ -687,8 +694,9 @@ describe("CreditAccount calcQuotaUpdate test", () => {
687
694
  },
688
695
  });
689
696
  });
690
- it("swap shouldn't add additional quota", () => {
697
+ it("swap shouldn't buy additional quota", () => {
691
698
  const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
699
+ maxDebt: HUGE_MAX_DEBT,
692
700
  quotaReserve: QUOTA_RESERVE,
693
701
  quotas: cmQuotas,
694
702
  initialQuotas: caQuota,
@@ -734,6 +742,7 @@ describe("CreditAccount calcQuotaUpdate test", () => {
734
742
  });
735
743
  it("shouldn't change quota if disallowed", () => {
736
744
  const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
745
+ maxDebt: HUGE_MAX_DEBT,
737
746
  quotaReserve: QUOTA_RESERVE,
738
747
  quotas: cmQuotas,
739
748
  initialQuotas: caQuota,
@@ -772,6 +781,7 @@ describe("CreditAccount calcQuotaUpdate test", () => {
772
781
  });
773
782
  it("shouldn't change quota if it is disabled", () => {
774
783
  const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
784
+ maxDebt: HUGE_MAX_DEBT,
775
785
  quotaReserve: QUOTA_RESERVE,
776
786
  quotas: {
777
787
  [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
@@ -827,6 +837,7 @@ describe("CreditAccount calcQuotaUpdate test", () => {
827
837
  });
828
838
  it("swap shouldn't buy quota if no lt", () => {
829
839
  const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
840
+ maxDebt: HUGE_MAX_DEBT,
830
841
  quotaReserve: QUOTA_RESERVE,
831
842
  quotas: cmQuotas,
832
843
  initialQuotas: {
@@ -874,6 +885,7 @@ describe("CreditAccount calcQuotaUpdate test", () => {
874
885
  });
875
886
  it("swap should buy quota with respect to lt", () => {
876
887
  const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
888
+ maxDebt: HUGE_MAX_DEBT,
877
889
  quotaReserve: QUOTA_RESERVE,
878
890
  quotas: cmQuotas,
879
891
  initialQuotas: {
@@ -927,6 +939,7 @@ describe("CreditAccount calcQuotaUpdate test", () => {
927
939
  });
928
940
  it("swap shouldn't buy quota with respect to lt", () => {
929
941
  const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
942
+ maxDebt: HUGE_MAX_DEBT,
930
943
  quotaReserve: QUOTA_RESERVE,
931
944
  quotas: cmQuotas,
932
945
  initialQuotas: {
@@ -973,6 +986,175 @@ describe("CreditAccount calcQuotaUpdate test", () => {
973
986
  },
974
987
  });
975
988
  });
989
+ it("swap should buy additional quota after limit was increased", () => {
990
+ const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
991
+ maxDebt: 10n,
992
+ quotaReserve: QUOTA_RESERVE,
993
+ quotas: cmQuotas,
994
+ initialQuotas: {
995
+ ...caQuota,
996
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
997
+ quota: 10n,
998
+ },
999
+ },
1000
+ assetsAfterUpdate: {
1001
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
1002
+ amountInTarget: 20n,
1003
+ balance: 0n,
1004
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
1005
+ },
1006
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
1007
+ amountInTarget: 0n,
1008
+ balance: 0n,
1009
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
1010
+ },
1011
+ },
1012
+ allowedToObtain: {
1013
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {},
1014
+ },
1015
+ allowedToSpend: {
1016
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {},
1017
+ },
1018
+ liquidationThresholds: DEFAULT_LT,
1019
+ });
1020
+ (0, chai_1.expect)(result.quotaIncrease).to.be.deep.eq([
1021
+ {
1022
+ balance: 10n,
1023
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
1024
+ },
1025
+ ]);
1026
+ (0, chai_1.expect)(result.quotaDecrease).to.be.deep.eq([
1027
+ {
1028
+ balance: -10n,
1029
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
1030
+ },
1031
+ ]);
1032
+ (0, chai_1.expect)(result.desiredQuota).to.be.deep.eq({
1033
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
1034
+ balance: 20n,
1035
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
1036
+ },
1037
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
1038
+ balance: 0n,
1039
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
1040
+ },
1041
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
1042
+ balance: 0n,
1043
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.STETH,
1044
+ },
1045
+ });
1046
+ });
1047
+ it("swap should buy additional quota with respect to debt limit", () => {
1048
+ const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
1049
+ maxDebt: 9n,
1050
+ quotaReserve: QUOTA_RESERVE,
1051
+ quotas: cmQuotas,
1052
+ initialQuotas: {
1053
+ ...caQuota,
1054
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
1055
+ quota: 10n,
1056
+ },
1057
+ },
1058
+ assetsAfterUpdate: {
1059
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
1060
+ amountInTarget: 20n,
1061
+ balance: 0n,
1062
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
1063
+ },
1064
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
1065
+ amountInTarget: 0n,
1066
+ balance: 0n,
1067
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
1068
+ },
1069
+ },
1070
+ allowedToObtain: {
1071
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {},
1072
+ },
1073
+ allowedToSpend: {
1074
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {},
1075
+ },
1076
+ liquidationThresholds: DEFAULT_LT,
1077
+ });
1078
+ (0, chai_1.expect)(result.quotaIncrease).to.be.deep.eq([
1079
+ {
1080
+ balance: 8n,
1081
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
1082
+ },
1083
+ ]);
1084
+ (0, chai_1.expect)(result.quotaDecrease).to.be.deep.eq([
1085
+ {
1086
+ balance: -10n,
1087
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
1088
+ },
1089
+ ]);
1090
+ (0, chai_1.expect)(result.desiredQuota).to.be.deep.eq({
1091
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
1092
+ balance: 18n,
1093
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
1094
+ },
1095
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
1096
+ balance: 0n,
1097
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
1098
+ },
1099
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
1100
+ balance: 0n,
1101
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.STETH,
1102
+ },
1103
+ });
1104
+ });
1105
+ it("swap shouldn't buy additional quota if debt limit more then current quota", () => {
1106
+ const result = creditAccount_1.CreditAccountData.calcQuotaUpdate({
1107
+ maxDebt: 5n,
1108
+ quotaReserve: QUOTA_RESERVE,
1109
+ quotas: cmQuotas,
1110
+ initialQuotas: {
1111
+ ...caQuota,
1112
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
1113
+ quota: 10n,
1114
+ },
1115
+ },
1116
+ assetsAfterUpdate: {
1117
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
1118
+ amountInTarget: 20n,
1119
+ balance: 0n,
1120
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
1121
+ },
1122
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
1123
+ amountInTarget: 0n,
1124
+ balance: 0n,
1125
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
1126
+ },
1127
+ },
1128
+ allowedToObtain: {
1129
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {},
1130
+ },
1131
+ allowedToSpend: {
1132
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {},
1133
+ },
1134
+ liquidationThresholds: DEFAULT_LT,
1135
+ });
1136
+ (0, chai_1.expect)(result.quotaIncrease).to.be.deep.eq([]);
1137
+ (0, chai_1.expect)(result.quotaDecrease).to.be.deep.eq([
1138
+ {
1139
+ balance: -10n,
1140
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
1141
+ },
1142
+ ]);
1143
+ (0, chai_1.expect)(result.desiredQuota).to.be.deep.eq({
1144
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.DAI]: {
1145
+ balance: 10n,
1146
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.DAI,
1147
+ },
1148
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.WETH]: {
1149
+ balance: 0n,
1150
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.WETH,
1151
+ },
1152
+ [sdk_gov_1.tokenDataByNetwork.Mainnet.STETH]: {
1153
+ balance: 0n,
1154
+ token: sdk_gov_1.tokenDataByNetwork.Mainnet.STETH,
1155
+ },
1156
+ });
1157
+ });
976
1158
  });
977
1159
  describe("CreditAccount calcAvgQuotaBorrowRate test", () => {
978
1160
  it("should calculate quota rate (same amounts, different rates)", () => {
@@ -1,6 +1,7 @@
1
1
  export declare const TESTNET_CHAINS: {
2
2
  readonly Mainnet: 7878;
3
3
  readonly Optimism: 7879;
4
+ readonly Arbitrum: 7880;
4
5
  };
5
6
  type ChartsPriceSource = "chainlink" | "spot";
6
7
  interface Options {
@@ -5,6 +5,7 @@ const sdk_gov_1 = require("@gearbox-protocol/sdk-gov");
5
5
  exports.TESTNET_CHAINS = {
6
6
  Mainnet: 7878,
7
7
  Optimism: 7879,
8
+ Arbitrum: 7880,
8
9
  };
9
10
  const CHARTS_BACKEND_ADDRESSES = {
10
11
  [sdk_gov_1.CHAINS.Mainnet]: "https://charts-server.fly.dev",
@@ -12,6 +13,7 @@ const CHARTS_BACKEND_ADDRESSES = {
12
13
  [exports.TESTNET_CHAINS.Mainnet]: "https://testnet.gearbox.foundation",
13
14
  // !& test server for optimism
14
15
  [exports.TESTNET_CHAINS.Optimism]: "https://testnet.gearbox.foundation",
16
+ [exports.TESTNET_CHAINS.Arbitrum]: "https://testnet.gearbox.foundation",
15
17
  };
16
18
  class ChartsApi {
17
19
  static getUrl = (url, chainId, options, priceSource) => [
@@ -10,8 +10,6 @@ const types_1 = require("../types");
10
10
  class RewardConvex {
11
11
  static poolInterface = types_1.IBaseRewardPool__factory.createInterface();
12
12
  static async findRewards(ca, cm, network, provider) {
13
- if (network !== "Mainnet")
14
- return [];
15
13
  const { auraCalls, auraDistribution, convexCalls, convexDistribution } = RewardConvex.prepareMultiCalls(ca.addr, cm, network);
16
14
  const auraTotal = auraCalls.flat(1);
17
15
  const convexTotal = convexCalls.flat(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "3.0.0-next.127",
3
+ "version": "3.0.0-next.129",
4
4
  "description": "Gearbox SDK",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",