@defisaver/positions-sdk 2.0.15-dev.0 → 2.1.1-dev.0

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.
Files changed (125) hide show
  1. package/cjs/aaveV2/index.js +9 -5
  2. package/cjs/aaveV3/index.d.ts +3 -0
  3. package/cjs/aaveV3/index.js +66 -47
  4. package/cjs/aaveV3/merit.d.ts +7 -0
  5. package/cjs/aaveV3/merit.js +95 -0
  6. package/cjs/aaveV3/merkl.d.ts +9 -0
  7. package/cjs/aaveV3/merkl.js +88 -0
  8. package/cjs/compoundV2/index.js +13 -7
  9. package/cjs/compoundV3/index.js +8 -3
  10. package/cjs/config/contracts.d.ts +6510 -1851
  11. package/cjs/config/contracts.js +33 -12
  12. package/cjs/contracts.d.ts +178 -0
  13. package/cjs/eulerV2/index.js +11 -2
  14. package/cjs/fluid/index.js +108 -34
  15. package/cjs/helpers/aaveHelpers/index.js +0 -1
  16. package/cjs/helpers/compoundHelpers/index.d.ts +5 -7
  17. package/cjs/helpers/compoundHelpers/index.js +31 -11
  18. package/cjs/helpers/eulerHelpers/index.d.ts +0 -5
  19. package/cjs/helpers/eulerHelpers/index.js +2 -31
  20. package/cjs/helpers/fluidHelpers/index.js +2 -0
  21. package/cjs/helpers/liquityV2Helpers/index.js +3 -2
  22. package/cjs/liquityV2/index.js +10 -2
  23. package/cjs/llamaLend/index.js +10 -2
  24. package/cjs/morphoBlue/index.js +20 -6
  25. package/cjs/spark/index.js +20 -30
  26. package/cjs/staking/eligibility.d.ts +19 -0
  27. package/cjs/staking/eligibility.js +67 -0
  28. package/cjs/staking/index.d.ts +1 -0
  29. package/cjs/staking/index.js +1 -0
  30. package/cjs/staking/staking.d.ts +1 -7
  31. package/cjs/staking/staking.js +29 -55
  32. package/cjs/types/aave.d.ts +3 -8
  33. package/cjs/types/common.d.ts +18 -4
  34. package/cjs/types/common.js +12 -1
  35. package/cjs/types/euler.d.ts +3 -3
  36. package/cjs/types/fluid.d.ts +3 -5
  37. package/cjs/types/index.d.ts +2 -0
  38. package/cjs/types/index.js +2 -0
  39. package/cjs/types/liquityV2.d.ts +3 -3
  40. package/cjs/types/llamaLend.d.ts +3 -1
  41. package/cjs/types/merit.d.ts +9 -0
  42. package/cjs/types/merit.js +2 -0
  43. package/cjs/types/merkl.d.ts +75 -0
  44. package/cjs/types/merkl.js +14 -0
  45. package/cjs/types/morphoBlue.d.ts +3 -5
  46. package/cjs/types/spark.d.ts +0 -3
  47. package/esm/aaveV2/index.js +9 -5
  48. package/esm/aaveV3/index.d.ts +3 -0
  49. package/esm/aaveV3/index.js +65 -47
  50. package/esm/aaveV3/merit.d.ts +7 -0
  51. package/esm/aaveV3/merit.js +90 -0
  52. package/esm/aaveV3/merkl.d.ts +9 -0
  53. package/esm/aaveV3/merkl.js +82 -0
  54. package/esm/compoundV2/index.js +13 -7
  55. package/esm/compoundV3/index.js +8 -3
  56. package/esm/config/contracts.d.ts +6510 -1851
  57. package/esm/config/contracts.js +33 -12
  58. package/esm/contracts.d.ts +178 -0
  59. package/esm/eulerV2/index.js +11 -2
  60. package/esm/fluid/index.js +109 -35
  61. package/esm/helpers/aaveHelpers/index.js +0 -1
  62. package/esm/helpers/compoundHelpers/index.d.ts +5 -7
  63. package/esm/helpers/compoundHelpers/index.js +34 -14
  64. package/esm/helpers/eulerHelpers/index.d.ts +0 -5
  65. package/esm/helpers/eulerHelpers/index.js +2 -30
  66. package/esm/helpers/fluidHelpers/index.js +2 -0
  67. package/esm/helpers/liquityV2Helpers/index.js +3 -2
  68. package/esm/liquityV2/index.js +11 -3
  69. package/esm/llamaLend/index.js +11 -3
  70. package/esm/morphoBlue/index.js +21 -7
  71. package/esm/spark/index.js +21 -31
  72. package/esm/staking/eligibility.d.ts +19 -0
  73. package/esm/staking/eligibility.js +58 -0
  74. package/esm/staking/index.d.ts +1 -0
  75. package/esm/staking/index.js +1 -0
  76. package/esm/staking/staking.d.ts +1 -7
  77. package/esm/staking/staking.js +28 -53
  78. package/esm/types/aave.d.ts +3 -8
  79. package/esm/types/common.d.ts +18 -4
  80. package/esm/types/common.js +11 -0
  81. package/esm/types/euler.d.ts +3 -3
  82. package/esm/types/fluid.d.ts +3 -5
  83. package/esm/types/index.d.ts +2 -0
  84. package/esm/types/index.js +2 -0
  85. package/esm/types/liquityV2.d.ts +3 -3
  86. package/esm/types/llamaLend.d.ts +3 -1
  87. package/esm/types/merit.d.ts +9 -0
  88. package/esm/types/merit.js +1 -0
  89. package/esm/types/merkl.d.ts +75 -0
  90. package/esm/types/merkl.js +11 -0
  91. package/esm/types/morphoBlue.d.ts +3 -5
  92. package/esm/types/spark.d.ts +0 -3
  93. package/package.json +1 -1
  94. package/src/aaveV2/index.ts +10 -7
  95. package/src/aaveV3/index.ts +77 -49
  96. package/src/aaveV3/merit.ts +94 -0
  97. package/src/aaveV3/merkl.ts +74 -0
  98. package/src/compoundV2/index.ts +13 -9
  99. package/src/compoundV3/index.ts +8 -4
  100. package/src/config/contracts.ts +34 -13
  101. package/src/eulerV2/index.ts +13 -3
  102. package/src/fluid/index.ts +107 -37
  103. package/src/helpers/aaveHelpers/index.ts +0 -1
  104. package/src/helpers/compoundHelpers/index.ts +41 -19
  105. package/src/helpers/eulerHelpers/index.ts +3 -40
  106. package/src/helpers/fluidHelpers/index.ts +2 -0
  107. package/src/helpers/liquityV2Helpers/index.ts +4 -2
  108. package/src/liquityV2/index.ts +13 -3
  109. package/src/llamaLend/index.ts +13 -4
  110. package/src/morphoBlue/index.ts +21 -7
  111. package/src/spark/index.ts +21 -33
  112. package/src/staking/eligibility.ts +61 -0
  113. package/src/staking/index.ts +2 -1
  114. package/src/staking/staking.ts +29 -54
  115. package/src/types/aave.ts +3 -8
  116. package/src/types/common.ts +21 -4
  117. package/src/types/euler.ts +3 -2
  118. package/src/types/fluid.ts +3 -5
  119. package/src/types/index.ts +3 -1
  120. package/src/types/liquityV2.ts +3 -3
  121. package/src/types/llamaLend.ts +3 -1
  122. package/src/types/merit.ts +2 -0
  123. package/src/types/merkl.ts +71 -0
  124. package/src/types/morphoBlue.ts +5 -5
  125. package/src/types/spark.ts +1 -3
@@ -1,5 +1,4 @@
1
1
  import { EthAddress, MMAssetData, MMPositionData, MMUsedAsset, NetworkNumber } from './common';
2
- import { IncentiveData } from './aave';
3
2
  export declare enum SparkVersions {
4
3
  SparkV1 = "v1default"
5
4
  }
@@ -48,8 +47,6 @@ export interface SparkAssetData extends MMAssetData {
48
47
  eModeCategory: number;
49
48
  eModeCategoryData: SparkEModeCategoryData;
50
49
  liquidationRatio: string;
51
- supplyIncentives?: IncentiveData[];
52
- borrowIncentives?: IncentiveData[];
53
50
  }
54
51
  export interface SparkAssetsData {
55
52
  [token: string]: SparkAssetData;
@@ -9,6 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import Dec from 'decimal.js';
11
11
  import { assetAmountInEth, getAssetInfo } from '@defisaver/tokens';
12
+ import { IncentiveKind, } from '../types/common';
12
13
  import { calculateNetApy, getStakingApy } from '../staking';
13
14
  import { ethToWeth, wethToEth, wethToEthByAddress } from '../services/utils';
14
15
  import { AaveLoanInfoV2ContractViem, createViemContractFromConfigFunc } from '../contracts';
@@ -56,15 +57,18 @@ export const _getAaveV2MarketsData = (provider, network, selectedMarket) => __aw
56
57
  totalBorrow: assetAmountInEth(market.totalBorrow.toString(), selectedMarket.assets[i]),
57
58
  totalBorrowVar: assetAmountInEth(market.totalBorrowVar.toString(), selectedMarket.assets[i]),
58
59
  priceInEth: new Dec(market.price.toString()).div(1e18).toString(),
59
- incentiveSupplyToken: 'AAVE',
60
- incentiveBorrowToken: 'AAVE',
61
- incentiveSupplyApy: '0',
60
+ supplyIncentives: [],
61
+ borrowIncentives: [],
62
62
  price: new Dec(market.price.toString()).div(1e18).mul(ethPrice).toString(),
63
63
  }));
64
64
  const stEthMarket = markets.find(({ symbol }) => symbol === 'stETH');
65
65
  if (stEthMarket) {
66
- stEthMarket.incentiveSupplyApy = yield getStakingApy('stETH');
67
- stEthMarket.incentiveSupplyToken = 'stETH';
66
+ stEthMarket.supplyIncentives.push({
67
+ apy: yield getStakingApy('stETH'),
68
+ token: 'stETH',
69
+ incentiveKind: IncentiveKind.Staking,
70
+ description: 'Native stETH yield.',
71
+ });
68
72
  }
69
73
  const payload = {};
70
74
  // Sort by market size
@@ -1,6 +1,8 @@
1
1
  import { Client } from 'viem';
2
2
  import { AaveMarketInfo, AaveV3MarketData, AaveV3PositionData, AaveV3UsedAssets, EModeCategoryDataMapping } from '../types/aave';
3
3
  import { Blockish, EthAddress, EthereumProvider, NetworkNumber, PositionBalances } from '../types/common';
4
+ import { getMeritCampaigns } from './merit';
5
+ import { getMerkleCampaigns } from './merkl';
4
6
  export declare const aaveV3EmodeCategoriesMapping: (extractedState: any, usedAssets: AaveV3UsedAssets) => {
5
7
  [key: number]: EModeCategoryDataMapping;
6
8
  };
@@ -32,3 +34,4 @@ export declare const getAaveV3AccountBalances: (provider: EthereumProvider, netw
32
34
  export declare const _getAaveV3AccountData: (provider: Client, network: NetworkNumber, address: EthAddress, extractedState: any, blockNumber?: "latest" | number) => Promise<AaveV3PositionData>;
33
35
  export declare const getAaveV3AccountData: (provider: EthereumProvider, network: NetworkNumber, address: EthAddress, extractedState: any, blockNumber?: "latest" | number) => Promise<AaveV3PositionData>;
34
36
  export declare const getAaveV3FullPositionData: (provider: EthereumProvider, network: NetworkNumber, address: EthAddress, market: AaveMarketInfo) => Promise<AaveV3PositionData>;
37
+ export { getMeritCampaigns, getMerkleCampaigns, };
@@ -15,8 +15,10 @@ import { AAVE_V3 } from '../markets/aave';
15
15
  import { aprToApy, calculateBorrowingAssetLimit } from '../moneymarket';
16
16
  import { ethToWeth, isEnabledOnBitmap, isLayer2Network, wethToEth, wethToEthByAddress, } from '../services/utils';
17
17
  import { getStakingApy, STAKING_ASSETS } from '../staking';
18
- import { NetworkNumber, } from '../types/common';
18
+ import { IncentiveKind, NetworkNumber, } from '../types/common';
19
19
  import { getViemProvider, setViemBlockNumber } from '../services/viem';
20
+ import { getMeritCampaigns } from './merit';
21
+ import { getAaveUnderlyingSymbol, getMerkleCampaigns } from './merkl';
20
22
  export const aaveV3EmodeCategoriesMapping = (extractedState, usedAssets) => {
21
23
  const { eModeCategoriesData } = extractedState;
22
24
  const usedAssetsValues = Object.values(usedAssets);
@@ -51,11 +53,13 @@ export function _getAaveV3MarketData(provider_1, network_1, market_1) {
51
53
  const marketAddress = market.providerAddress;
52
54
  const networksWithIncentives = [NetworkNumber.Eth, NetworkNumber.Arb, NetworkNumber.Opt, NetworkNumber.Linea];
53
55
  // eslint-disable-next-line prefer-const
54
- let [loanInfo, eModesInfo, isBorrowAllowed, rewardInfo] = yield Promise.all([
56
+ let [loanInfo, eModesInfo, isBorrowAllowed, rewardInfo, merkleRewardsMap, meritRewardsMap] = yield Promise.all([
55
57
  loanInfoContract.read.getFullTokensInfo([marketAddress, _addresses], setViemBlockNumber(blockNumber)),
56
58
  loanInfoContract.read.getAllEmodes([marketAddress], setViemBlockNumber(blockNumber)),
57
59
  loanInfoContract.read.isBorrowAllowed([marketAddress], setViemBlockNumber(blockNumber)), // Used on L2s check for PriceOracleSentinel (mainnet will always return true)
58
60
  networksWithIncentives.includes(network) ? aaveIncentivesContract.read.getReservesIncentivesData([marketAddress], setViemBlockNumber(blockNumber)) : null,
61
+ getMerkleCampaigns(network),
62
+ getMeritCampaigns(network, market.value),
59
63
  ]);
60
64
  isBorrowAllowed = isLayer2Network(network) ? isBorrowAllowed : true;
61
65
  const eModeCategoriesData = {};
@@ -137,47 +141,74 @@ export function _getAaveV3MarketData(provider_1, network_1, market_1) {
137
141
  isolationModeBorrowingEnabled: tokenMarket.isolationModeBorrowingEnabled,
138
142
  isFlashLoanEnabled: tokenMarket.isFlashLoanEnabled,
139
143
  aTokenAddress: tokenMarket.aTokenAddress,
144
+ vTokenAddress: tokenMarket.debtTokenAddress,
145
+ supplyIncentives: [],
146
+ borrowIncentives: [],
140
147
  });
141
148
  })));
142
149
  // Get incentives data
143
- yield Promise.all(assetsData.map((_market) => __awaiter(this, void 0, void 0, function* () {
150
+ yield Promise.all(assetsData.map((_market, index) => __awaiter(this, void 0, void 0, function* () {
151
+ var _a, _b;
144
152
  /* eslint-disable no-param-reassign */
145
153
  // @ts-ignore
146
154
  const rewardForMarket = rewardInfo === null || rewardInfo === void 0 ? void 0 : rewardInfo[_market.underlyingTokenAddress];
147
155
  const isStakingAsset = STAKING_ASSETS.includes(_market.symbol);
148
156
  if (isStakingAsset) {
149
- _market.incentiveSupplyApy = yield getStakingApy(_market.symbol);
150
- _market.incentiveSupplyToken = _market.symbol;
151
- if (!_market.supplyIncentives) {
152
- _market.supplyIncentives = [];
153
- }
157
+ const yieldApy = yield getStakingApy(_market.symbol);
154
158
  _market.supplyIncentives.push({
155
- apy: _market.incentiveSupplyApy || '0',
159
+ apy: yieldApy,
156
160
  token: _market.symbol,
157
- incentiveKind: 'staking',
161
+ incentiveKind: IncentiveKind.Staking,
162
+ description: `Native ${_market.symbol} yield.`,
158
163
  });
159
- }
160
- if (_market.canBeBorrowed && _market.incentiveSupplyApy) {
161
- _market.incentiveBorrowApy = _market.incentiveSupplyApy;
162
- _market.incentiveBorrowToken = _market.incentiveSupplyToken;
163
- if (!_market.borrowIncentives) {
164
- _market.borrowIncentives = [];
164
+ if (_market.canBeBorrowed) {
165
+ // when borrowing assets whose value increases over time
166
+ _market.borrowIncentives.push({
167
+ apy: new Dec(yieldApy).mul(-1).toString(),
168
+ token: _market.symbol,
169
+ incentiveKind: IncentiveKind.Reward,
170
+ description: `Due to the native yield of ${_market.symbol}, the value of the debt would increase over time.`,
171
+ });
165
172
  }
173
+ }
174
+ const aTokenAddress = _market.aTokenAddress.toLowerCase(); // DEV: Should aTokenAddress be in AaveV3AssetData type?
175
+ if ((_a = merkleRewardsMap[aTokenAddress]) === null || _a === void 0 ? void 0 : _a.supply) {
176
+ const { apy, rewardTokenSymbol, description, identifier, } = merkleRewardsMap[aTokenAddress].supply;
177
+ _market.supplyIncentives.push({
178
+ apy,
179
+ token: rewardTokenSymbol,
180
+ incentiveKind: IncentiveKind.Reward,
181
+ description,
182
+ eligibilityId: identifier,
183
+ });
184
+ }
185
+ const vTokenAddress = _market.vTokenAddress.toLowerCase(); // DEV: Should vTokenAddress be in AaveV3AssetData type?
186
+ if ((_b = merkleRewardsMap[vTokenAddress]) === null || _b === void 0 ? void 0 : _b.borrow) {
187
+ const { apy, rewardTokenSymbol, description, identifier, } = merkleRewardsMap[vTokenAddress].borrow;
166
188
  _market.borrowIncentives.push({
167
- apy: _market.incentiveBorrowApy,
168
- token: _market.incentiveBorrowToken,
169
- incentiveKind: 'reward',
189
+ apy,
190
+ token: rewardTokenSymbol,
191
+ incentiveKind: IncentiveKind.Reward,
192
+ description,
193
+ eligibilityId: identifier,
170
194
  });
171
195
  }
172
- if (_market.symbol === 'USDe') {
173
- const merklApy = yield getStakingApy(_market.symbol);
174
- if (!_market.supplyIncentives) {
175
- _market.supplyIncentives = [];
176
- }
196
+ if (meritRewardsMap.supply[_market.symbol]) {
197
+ const { apy, rewardTokenSymbol, description } = meritRewardsMap.supply[_market.symbol];
177
198
  _market.supplyIncentives.push({
178
- apy: merklApy || '0',
179
- token: _market.symbol,
180
- incentiveKind: 'reward',
199
+ apy,
200
+ token: rewardTokenSymbol,
201
+ incentiveKind: IncentiveKind.Reward,
202
+ description,
203
+ });
204
+ }
205
+ if (meritRewardsMap.borrow[_market.symbol]) {
206
+ const { apy, rewardTokenSymbol, description } = meritRewardsMap.borrow[_market.symbol];
207
+ _market.borrowIncentives.push({
208
+ apy,
209
+ token: rewardTokenSymbol,
210
+ incentiveKind: IncentiveKind.Reward,
211
+ description,
181
212
  });
182
213
  }
183
214
  if (!rewardForMarket)
@@ -187,10 +218,7 @@ export function _getAaveV3MarketData(provider_1, network_1, market_1) {
187
218
  if (supplyRewardData) {
188
219
  if (+(supplyRewardData.emissionEndTimestamp.toString()) * 1000 < Date.now())
189
220
  return;
190
- _market.incentiveSupplyToken = supplyRewardData.rewardTokenSymbol;
191
221
  // reward token is aave asset
192
- if (supplyRewardData.rewardTokenSymbol.startsWith('a') && supplyRewardData.rewardTokenSymbol.includes(_market.symbol))
193
- _market.incentiveSupplyToken = _market.symbol;
194
222
  const supplyEmissionPerSecond = supplyRewardData.emissionPerSecond;
195
223
  const supplyRewardPrice = new Dec(supplyRewardData.rewardPriceFeed).div(Math.pow(10, +supplyRewardData.priceFeedDecimals))
196
224
  .toString();
@@ -200,15 +228,11 @@ export function _getAaveV3MarketData(provider_1, network_1, market_1) {
200
228
  .div(_market.price)
201
229
  .div(_market.totalSupply)
202
230
  .toString();
203
- _market.incentiveSupplyApy = new Dec(_market.incentiveSupplyApy || '0').add(rewardApy)
204
- .toString();
205
- if (!_market.supplyIncentives) {
206
- _market.supplyIncentives = [];
207
- }
208
231
  _market.supplyIncentives.push({
209
- token: supplyRewardData.rewardTokenSymbol,
232
+ token: getAaveUnderlyingSymbol(supplyRewardData.rewardTokenSymbol),
210
233
  apy: rewardApy,
211
- incentiveKind: 'reward',
234
+ incentiveKind: IncentiveKind.Reward,
235
+ description: 'Eligible for protocol-level incentives.',
212
236
  });
213
237
  }
214
238
  });
@@ -217,9 +241,6 @@ export function _getAaveV3MarketData(provider_1, network_1, market_1) {
217
241
  if (borrowRewardData) {
218
242
  if (+(borrowRewardData.emissionEndTimestamp.toString()) * 1000 < Date.now())
219
243
  return;
220
- _market.incentiveBorrowToken = borrowRewardData.rewardTokenSymbol;
221
- if (borrowRewardData.rewardTokenSymbol.startsWith('a') && borrowRewardData.rewardTokenSymbol.includes(_market.symbol))
222
- _market.incentiveBorrowToken = _market.symbol;
223
244
  const supplyEmissionPerSecond = borrowRewardData.emissionPerSecond;
224
245
  const supplyRewardPrice = new Dec(borrowRewardData.rewardPriceFeed).div(Math.pow(10, +borrowRewardData.priceFeedDecimals))
225
246
  .toString();
@@ -229,15 +250,11 @@ export function _getAaveV3MarketData(provider_1, network_1, market_1) {
229
250
  .div(_market.price)
230
251
  .div(_market.totalBorrowVar)
231
252
  .toString();
232
- _market.incentiveBorrowApy = new Dec(_market.incentiveBorrowApy || '0').add(rewardApy)
233
- .toString();
234
- if (!_market.borrowIncentives) {
235
- _market.borrowIncentives = [];
236
- }
237
253
  _market.borrowIncentives.push({
238
- token: borrowRewardData.rewardTokenSymbol,
254
+ token: getAaveUnderlyingSymbol(borrowRewardData.rewardTokenSymbol),
239
255
  apy: rewardApy,
240
- incentiveKind: 'reward',
256
+ incentiveKind: IncentiveKind.Reward,
257
+ description: 'Eligible for protocol-level incentives.',
241
258
  });
242
259
  }
243
260
  });
@@ -403,3 +420,4 @@ export const getAaveV3FullPositionData = (provider, network, address, market) =>
403
420
  const positionData = yield getAaveV3AccountData(provider, network, address, { assetsData: marketData.assetsData, selectedMarket: market, eModeCategoriesData: marketData.eModeCategoriesData });
404
421
  return positionData;
405
422
  });
423
+ export { getMeritCampaigns, getMerkleCampaigns, };
@@ -0,0 +1,7 @@
1
+ import { NetworkNumber } from '../types/common';
2
+ import { AaveVersions, MeritTokenRewardMap } from '../types';
3
+ /**
4
+ * Fetches merit rewards data from Aave API
5
+ */
6
+ export declare const fetchMeritRewardsData: () => Promise<Record<string, number | null>>;
7
+ export declare const getMeritCampaigns: (chainId: NetworkNumber, market: AaveVersions) => Promise<MeritTokenRewardMap>;
@@ -0,0 +1,90 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { DEFAULT_TIMEOUT } from '../services/utils';
11
+ import { NetworkNumber } from '../types/common';
12
+ import { aprToApy } from '../moneymarket';
13
+ import { AaveVersions } from '../types';
14
+ /**
15
+ * Maps API keys to reward data & actions - hardcoded and needs to be maintained actively.
16
+ * Mapping based on Aave interface implementation: https://github.com/aave/interface/blob/main/src/hooks/useMeritIncentives.ts
17
+ * Active campaigns found here: https://apps.aavechan.com/merit
18
+ */
19
+ const MERIT_DATA_MAP = {
20
+ [NetworkNumber.Eth]: {
21
+ [AaveVersions.AaveV3]: {
22
+ 'ethereum-supply-ethx': { rewardTokenSymbol: 'SD', action: 'supply', supplyTokens: ['ETHx'] },
23
+ 'ethereum-supply-rlusd': { rewardTokenSymbol: 'aEthRLUSD', action: 'supply', supplyTokens: ['RLUSD'] },
24
+ // Campaign disabled here as it's present on Merkl API:
25
+ // 'ethereum-borrow-eurc': { rewardTokenSymbol: 'aEthEURC', action: 'borrow', borrowTokens: ['EURC'] },
26
+ },
27
+ [AaveVersions.AaveV3Lido]: {},
28
+ [AaveVersions.AaveV3Etherfi]: {},
29
+ },
30
+ [NetworkNumber.Arb]: {
31
+ [AaveVersions.AaveV3]: {},
32
+ },
33
+ [NetworkNumber.Opt]: {
34
+ [AaveVersions.AaveV3]: {},
35
+ },
36
+ [NetworkNumber.Base]: {
37
+ [AaveVersions.AaveV3]: {
38
+ 'base-borrow-usdc': { rewardTokenSymbol: 'USDC', action: 'borrow', borrowTokens: ['USDC'] },
39
+ 'base-borrow-gho': { rewardTokenSymbol: 'GHO', action: 'borrow', borrowTokens: ['GHO'] },
40
+ 'base-borrow-eurc': { rewardTokenSymbol: 'EURC', action: 'borrow', borrowTokens: ['EURC'] },
41
+ },
42
+ },
43
+ [NetworkNumber.Linea]: {
44
+ [AaveVersions.AaveV3]: {},
45
+ },
46
+ };
47
+ /**
48
+ * Fetches merit rewards data from Aave API
49
+ */
50
+ export const fetchMeritRewardsData = () => __awaiter(void 0, void 0, void 0, function* () {
51
+ try {
52
+ const response = yield fetch('https://apps.aavechan.com/api/merit/aprs', {
53
+ signal: AbortSignal.timeout(DEFAULT_TIMEOUT),
54
+ });
55
+ const data = yield response.json();
56
+ return data.currentAPR.actionsAPR;
57
+ }
58
+ catch (error) {
59
+ console.error('Failed to fetch merit rewards data:', error);
60
+ return {};
61
+ }
62
+ });
63
+ export const getMeritCampaigns = (chainId, market) => __awaiter(void 0, void 0, void 0, function* () {
64
+ var _a;
65
+ const meritData = yield fetchMeritRewardsData();
66
+ const relevantCampaigns = {
67
+ supply: {},
68
+ borrow: {},
69
+ };
70
+ Object.entries(((_a = MERIT_DATA_MAP[chainId]) === null || _a === void 0 ? void 0 : _a[market]) || {})
71
+ .filter(([key, rewardData]) => !!meritData[key])
72
+ .forEach(([key, rewardData]) => {
73
+ var _a, _b;
74
+ const apr = meritData[key];
75
+ if (!apr)
76
+ return;
77
+ const reward = {
78
+ rewardTokenSymbol: rewardData.rewardTokenSymbol,
79
+ apy: aprToApy(apr).toString(),
80
+ description: `Eligible for Merit rewards in ${rewardData.rewardTokenSymbol}. ${rewardData.message ? `\n${rewardData.message}` : ''}`,
81
+ };
82
+ (_a = rewardData.supplyTokens) === null || _a === void 0 ? void 0 : _a.forEach(token => {
83
+ relevantCampaigns.supply[token] = reward;
84
+ });
85
+ (_b = rewardData.borrowTokens) === null || _b === void 0 ? void 0 : _b.forEach(token => {
86
+ relevantCampaigns.borrow[token] = reward;
87
+ });
88
+ });
89
+ return relevantCampaigns;
90
+ });
@@ -0,0 +1,9 @@
1
+ import { MerkleRewardMap } from '../types';
2
+ import { NetworkNumber } from '../types/common';
3
+ export declare const getAaveUnderlyingSymbol: (_symbol?: string) => any;
4
+ /**
5
+ * aEthLidoUSDC -> aUSDC
6
+ * USDC -> USDC
7
+ */
8
+ export declare const formatAaveAsset: (_symbol: string) => string;
9
+ export declare const getMerkleCampaigns: (chainId: NetworkNumber) => Promise<MerkleRewardMap>;
@@ -0,0 +1,82 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { aprToApy } from '../moneymarket';
11
+ import { DEFAULT_TIMEOUT, wethToEth } from '../services/utils';
12
+ import { OpportunityAction, OpportunityStatus, } from '../types';
13
+ export const getAaveUnderlyingSymbol = (_symbol = '') => {
14
+ let symbol = _symbol
15
+ .replace(/^aEthLido/, '')
16
+ .replace(/^aEthEtherFi/, '')
17
+ .replace(/^aEth/, '')
18
+ .replace(/^aArb/, '')
19
+ .replace(/^aOpt/, '')
20
+ .replace(/^aBas/, '')
21
+ .replace(/^aLin/, '');
22
+ if (symbol.startsWith('a'))
23
+ symbol = symbol.slice(1);
24
+ return wethToEth(symbol);
25
+ };
26
+ /**
27
+ * aEthLidoUSDC -> aUSDC
28
+ * USDC -> USDC
29
+ */
30
+ export const formatAaveAsset = (_symbol) => {
31
+ if (_symbol.startsWith('a')) {
32
+ return `a${getAaveUnderlyingSymbol(_symbol)}`;
33
+ }
34
+ return _symbol;
35
+ };
36
+ export const getMerkleCampaigns = (chainId) => __awaiter(void 0, void 0, void 0, function* () {
37
+ try {
38
+ const res = yield fetch('https://api.merkl.xyz/v4/opportunities?mainProtocolId=aave', {
39
+ signal: AbortSignal.timeout(DEFAULT_TIMEOUT),
40
+ });
41
+ if (!res.ok)
42
+ throw new Error('Failed to fetch Merkle campaigns');
43
+ const opportunities = yield res.json();
44
+ const relevantOpportunities = opportunities
45
+ .filter((o) => o.chainId === chainId)
46
+ .filter((o) => o.status === OpportunityStatus.LIVE);
47
+ return relevantOpportunities.reduce((acc, opportunity) => {
48
+ var _a, _b;
49
+ const rewardToken = opportunity.rewardsRecord.breakdowns[0].token;
50
+ const description = `Eligible for ${formatAaveAsset(rewardToken.symbol)} rewards through Merkl. ${opportunity.description ? `\n${opportunity.description}` : ''}`;
51
+ if (opportunity.action === OpportunityAction.LEND && opportunity.explorerAddress) {
52
+ const supplyAToken = (_a = opportunity.explorerAddress) === null || _a === void 0 ? void 0 : _a.toLowerCase();
53
+ if (!acc[supplyAToken])
54
+ acc[supplyAToken] = {};
55
+ acc[supplyAToken].supply = {
56
+ apy: aprToApy(opportunity.apr),
57
+ // rewardToken: rewardToken.address,
58
+ rewardTokenSymbol: rewardToken.symbol,
59
+ description,
60
+ identifier: opportunity.identifier,
61
+ };
62
+ }
63
+ if (opportunity.action === OpportunityAction.BORROW && opportunity.explorerAddress) {
64
+ const borrowAToken = (_b = opportunity.explorerAddress) === null || _b === void 0 ? void 0 : _b.toLowerCase();
65
+ if (!acc[borrowAToken])
66
+ acc[borrowAToken] = {};
67
+ acc[borrowAToken].borrow = {
68
+ apy: aprToApy(opportunity.apr),
69
+ // rewardToken: rewardToken.address,
70
+ rewardTokenSymbol: rewardToken.symbol,
71
+ description,
72
+ identifier: opportunity.identifier,
73
+ };
74
+ }
75
+ return acc;
76
+ }, {});
77
+ }
78
+ catch (e) {
79
+ console.error('Failed to fetch Merkle campaigns', e);
80
+ return {};
81
+ }
82
+ });
@@ -12,6 +12,7 @@ import Dec from 'decimal.js';
12
12
  import { BLOCKS_IN_A_YEAR } from '../constants';
13
13
  import { aprToApy } from '../moneymarket';
14
14
  import { compareAddresses, handleWbtcLegacy, wethToEth } from '../services/utils';
15
+ import { IncentiveKind, } from '../types/common';
15
16
  import { CompoundLoanInfoContractViem, ComptrollerContractViem } from '../contracts';
16
17
  import { compoundV2CollateralAssets } from '../markets';
17
18
  import { getCompoundV2AggregatedData } from '../helpers/compoundHelpers';
@@ -33,9 +34,6 @@ export const _getCompoundV2MarketsData = (provider, network) => __awaiter(void 0
33
34
  const compBorrowSpeeds = market.compBorrowSpeeds.toString();
34
35
  const assetPrice = market.price.toString();
35
36
  const pricePrecisionDiff = 18 - getAssetInfo(getAssetInfoByAddress(cAddresses[i]).underlyingAsset).decimals;
36
- // compSupplySpeeds/compBorrowSpeeds is per block per market (borrow & supply are separate markets)
37
- const incentiveSupplyApy = aprToApy((100 * BLOCKS_IN_A_YEAR * +compSupplySpeeds * +compPrice) / +assetPrice / +totalSupply).toString();
38
- const incentiveBorrowApy = aprToApy((100 * BLOCKS_IN_A_YEAR * +compBorrowSpeeds * +compPrice) / +assetPrice / +totalBorrow).toString();
39
37
  if (cAddresses[i].toLowerCase() === '0xc11b1268c1a384e55c48c2391d8d480264a3a7f4'.toLowerCase()) {
40
38
  symbol = 'WBTC Legacy';
41
39
  isWbtcLegacy = true;
@@ -45,10 +43,18 @@ export const _getCompoundV2MarketsData = (provider, network) => __awaiter(void 0
45
43
  underlyingTokenAddress: market.underlyingTokenAddress,
46
44
  supplyRate: aprToApy(new Dec(BLOCKS_IN_A_YEAR).times(market.supplyRate.toString()).div(1e16).toString()).toString(),
47
45
  borrowRate: aprToApy(new Dec(BLOCKS_IN_A_YEAR).times(market.borrowRate.toString()).div(1e16).toString()).toString(),
48
- incentiveSupplyToken: 'COMP',
49
- incentiveBorrowToken: 'COMP',
50
- incentiveSupplyApy,
51
- incentiveBorrowApy,
46
+ supplyIncentives: [{
47
+ token: 'COMP',
48
+ apy: aprToApy((100 * BLOCKS_IN_A_YEAR * +compSupplySpeeds * +compPrice) / +assetPrice / +totalSupply).toString(),
49
+ incentiveKind: IncentiveKind.Reward,
50
+ description: 'Eligible for protocol-level COMP incentives.',
51
+ }],
52
+ borrowIncentives: [{
53
+ token: 'COMP',
54
+ apy: aprToApy((100 * BLOCKS_IN_A_YEAR * +compBorrowSpeeds * +compPrice) / +assetPrice / +totalBorrow).toString(),
55
+ incentiveKind: IncentiveKind.Reward,
56
+ description: 'Eligible for protocol-level COMP incentives.',
57
+ }],
52
58
  collateralFactor: new Dec(market.collateralFactor.toString()).div(1e18).toString(),
53
59
  marketLiquidity: assetAmountInEth(market.marketLiquidity.toString(), handleWbtcLegacy(symbol)),
54
60
  utilization: new Dec(market.totalBorrow.toString()).div(totalSupply).times(100).toString(),
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import Dec from 'decimal.js';
11
11
  import { assetAmountInEth, getAssetInfo, getAssetInfoByAddress, } from '@defisaver/tokens';
12
12
  import { CompV3ViewContractViem } from '../contracts';
13
+ import { IncentiveKind, } from '../types/common';
13
14
  import { getStakingApy, STAKING_ASSETS, } from '../staking';
14
15
  import { ethToWeth, wethToEth } from '../services/utils';
15
16
  import { ZERO_ADDRESS } from '../constants';
@@ -43,13 +44,17 @@ export const _getCompoundV3MarketsData = (provider, network, selectedMarket, def
43
44
  .map((coll) => formatMarketData(coll, network, baseAssetPrice));
44
45
  for (const coll of colls) {
45
46
  if (STAKING_ASSETS.includes(coll.symbol)) {
46
- coll.incentiveSupplyApy = yield getStakingApy(coll.symbol);
47
- coll.incentiveSupplyToken = coll.symbol;
47
+ coll.supplyIncentives.push({
48
+ apy: yield getStakingApy(coll.symbol),
49
+ token: coll.symbol,
50
+ incentiveKind: IncentiveKind.Staking,
51
+ description: `Native ${coll.symbol} yield.`,
52
+ });
48
53
  }
49
54
  }
50
55
  const base = formatBaseData(baseTokenInfo, network, baseAssetPrice);
51
56
  const payload = {};
52
- const baseObj = Object.assign(Object.assign({}, base), getIncentiveApys(base, compPrice));
57
+ const baseObj = Object.assign(Object.assign({}, base), (yield getIncentiveApys(base, compPrice)));
53
58
  const allAssets = [baseObj, ...colls];
54
59
  allAssets
55
60
  .sort((a, b) => {