@defisaver/positions-sdk 0.0.166 → 0.0.168
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.
- package/.vscode/launch.json +17 -0
- package/.vscode/settings.json +22 -0
- package/cjs/aaveV2/index.js +1 -1
- package/cjs/aaveV3/index.js +71 -41
- package/cjs/compoundV2/index.js +10 -10
- package/cjs/morphoAaveV2/index.js +1 -1
- package/cjs/spark/index.js +63 -29
- package/cjs/staking/staking.d.ts +4 -4
- package/cjs/staking/staking.js +19 -16
- package/cjs/types/aave.d.ts +6 -0
- package/cjs/types/spark.d.ts +3 -0
- package/esm/aaveV2/index.js +2 -2
- package/esm/aaveV3/index.js +71 -41
- package/esm/compoundV2/index.js +1 -1
- package/esm/morphoAaveV2/index.js +2 -2
- package/esm/spark/index.js +63 -29
- package/esm/staking/staking.d.ts +4 -4
- package/esm/staking/staking.js +15 -12
- package/esm/types/aave.d.ts +6 -0
- package/esm/types/spark.d.ts +3 -0
- package/package.json +1 -1
- package/src/aaveV2/index.ts +2 -2
- package/src/aaveV3/index.ts +69 -35
- package/src/compoundV2/index.ts +2 -2
- package/src/morphoAaveV2/index.ts +2 -2
- package/src/spark/index.ts +64 -27
- package/src/staking/staking.ts +15 -13
- package/src/types/aave.ts +7 -0
- package/src/types/spark.ts +4 -1
package/src/spark/index.ts
CHANGED
|
@@ -151,6 +151,14 @@ export const getSparkMarketsData = async (web3: Web3, network: NetworkNumber, se
|
|
|
151
151
|
if (STAKING_ASSETS.includes(market.symbol)) {
|
|
152
152
|
market.incentiveSupplyApy = await getStakingApy(market.symbol, mainnetWeb3);
|
|
153
153
|
market.incentiveSupplyToken = market.symbol;
|
|
154
|
+
if (!market.supplyIncentives) {
|
|
155
|
+
market.supplyIncentives = [];
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
market.supplyIncentives.push({
|
|
159
|
+
apy: market.incentiveSupplyApy || '0',
|
|
160
|
+
token: market.symbol,
|
|
161
|
+
});
|
|
154
162
|
}
|
|
155
163
|
|
|
156
164
|
if (market.symbol === 'sDAI') {
|
|
@@ -159,37 +167,66 @@ export const getSparkMarketsData = async (web3: Web3, network: NetworkNumber, se
|
|
|
159
167
|
}
|
|
160
168
|
|
|
161
169
|
if (market.canBeBorrowed && market.incentiveSupplyApy) {
|
|
162
|
-
market.incentiveBorrowApy =
|
|
170
|
+
market.incentiveBorrowApy = market.incentiveSupplyApy;
|
|
163
171
|
market.incentiveBorrowToken = market.incentiveSupplyToken;
|
|
172
|
+
if (!market.borrowIncentives) {
|
|
173
|
+
market.borrowIncentives = [];
|
|
174
|
+
}
|
|
175
|
+
market.borrowIncentives.push({
|
|
176
|
+
apy: market.incentiveBorrowApy,
|
|
177
|
+
token: market.incentiveBorrowToken!!,
|
|
178
|
+
});
|
|
164
179
|
}
|
|
165
180
|
|
|
166
181
|
if (!rewardForMarket) return;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
182
|
+
(rewardForMarket.aIncentiveData.rewardsTokenInformation as any[]).forEach(supplyRewardData => {
|
|
183
|
+
if (supplyRewardData) {
|
|
184
|
+
if (supplyRewardData.emissionEndTimestamp * 1000 < Date.now()) return;
|
|
185
|
+
market.incentiveSupplyToken = supplyRewardData.rewardTokenSymbol;
|
|
186
|
+
const supplyEmissionPerSecond = supplyRewardData.emissionPerSecond;
|
|
187
|
+
const supplyRewardPrice = new Dec(supplyRewardData.rewardPriceFeed).div(10 ** supplyRewardData.priceFeedDecimals)
|
|
188
|
+
.toString();
|
|
189
|
+
const rewardApy = new Dec(supplyEmissionPerSecond).div((10 ** supplyRewardData.rewardTokenDecimals) / 100)
|
|
190
|
+
.mul(365 * 24 * 3600)
|
|
191
|
+
.mul(supplyRewardPrice)
|
|
192
|
+
.div(market.price)
|
|
193
|
+
.div(market.totalSupply)
|
|
194
|
+
.toString();
|
|
195
|
+
market.incentiveSupplyApy = new Dec(market.incentiveSupplyApy || '0').add(rewardApy).toString();
|
|
196
|
+
|
|
197
|
+
if (!market.supplyIncentives) {
|
|
198
|
+
market.supplyIncentives = [];
|
|
199
|
+
}
|
|
200
|
+
market.supplyIncentives.push({
|
|
201
|
+
token: supplyRewardData.rewardTokenSymbol,
|
|
202
|
+
apy: rewardApy,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
(rewardForMarket.vIncentiveData.rewardsTokenInformation as any[]).forEach(borrowRewardData => {
|
|
207
|
+
if (borrowRewardData) {
|
|
208
|
+
if (borrowRewardData.emissionEndTimestamp * 1000 < Date.now()) return;
|
|
209
|
+
market.incentiveBorrowToken = borrowRewardData.rewardTokenSymbol;
|
|
210
|
+
const supplyEmissionPerSecond = borrowRewardData.emissionPerSecond;
|
|
211
|
+
const supplyRewardPrice = new Dec(borrowRewardData.rewardPriceFeed).div(10 ** borrowRewardData.priceFeedDecimals)
|
|
212
|
+
.toString();
|
|
213
|
+
const rewardApy = new Dec(supplyEmissionPerSecond).div((10 ** borrowRewardData.rewardTokenDecimals) / 100)
|
|
214
|
+
.mul(365 * 24 * 3600)
|
|
215
|
+
.mul(supplyRewardPrice)
|
|
216
|
+
.div(market.price)
|
|
217
|
+
.div(market.totalBorrowVar)
|
|
218
|
+
.toString();
|
|
219
|
+
market.incentiveBorrowApy = new Dec(market.incentiveBorrowApy || '0').add(rewardApy).toString();
|
|
220
|
+
|
|
221
|
+
if (!market.borrowIncentives) {
|
|
222
|
+
market.borrowIncentives = [];
|
|
223
|
+
}
|
|
224
|
+
market.borrowIncentives.push({
|
|
225
|
+
token: borrowRewardData.rewardTokenSymbol,
|
|
226
|
+
apy: rewardApy,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
});
|
|
193
230
|
/* eslint-enable no-param-reassign */
|
|
194
231
|
}));
|
|
195
232
|
|
package/src/staking/staking.ts
CHANGED
|
@@ -7,9 +7,10 @@ import { MMAssetsData, MMUsedAssets, NetworkNumber } from '../types/common';
|
|
|
7
7
|
import { ContractEventLog } from '../types/contracts/generated/types';
|
|
8
8
|
import { BLOCKS_IN_A_YEAR, SECONDS_PER_YEAR, AVG_BLOCK_TIME } from '../constants';
|
|
9
9
|
import { multicall } from '../multicall';
|
|
10
|
+
import { aprToApy } from '../moneymarket';
|
|
10
11
|
|
|
11
12
|
|
|
12
|
-
export const
|
|
13
|
+
export const getStETHApy = async (web3: Web3, fromBlock = 17900000, blockNumber: 'latest' | number = 'latest') => {
|
|
13
14
|
try {
|
|
14
15
|
const tokenRebasedEvents: ContractEventLog<{ [key: string]: any }>[] = await LidoContract(web3, NetworkNumber.Eth).getPastEvents('TokenRebased', { fromBlock, toBlock: blockNumber });
|
|
15
16
|
tokenRebasedEvents.sort((a, b) => b.blockNumber - a.blockNumber); // sort from highest to lowest block number
|
|
@@ -21,17 +22,16 @@ export const getStETHApr = async (web3: Web3, fromBlock = 17900000, blockNumber:
|
|
|
21
22
|
.div(event.timeElapsed.toString()).mul(100)
|
|
22
23
|
.toNumber();
|
|
23
24
|
});
|
|
24
|
-
return aprs.reduce((a, b) => a + b, 0) / aprs.length;
|
|
25
|
+
return aprToApy(aprs.reduce((a, b) => a + b, 0) / aprs.length);
|
|
25
26
|
} catch (e) {
|
|
26
27
|
console.warn('Failed to fetch stETH APY from events, falling back to Lido API');
|
|
27
28
|
const res = await fetch('https://eth-api.lido.fi/v1/protocol/steth/apr/sma');
|
|
28
29
|
const data = await res.json();
|
|
29
|
-
return data.data.smaApr;
|
|
30
|
+
return aprToApy(data.data.smaApr);
|
|
30
31
|
}
|
|
31
32
|
};
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
export const getCbETHApr = async (web3: Web3, blockNumber: 'latest' | number = 'latest') => {
|
|
34
|
+
export const getCbETHApy = async (web3: Web3, blockNumber: 'latest' | number = 'latest') => {
|
|
35
35
|
let currentBlock = blockNumber;
|
|
36
36
|
if (blockNumber === 'latest') currentBlock = await web3.eth.getBlockNumber();
|
|
37
37
|
const blockDiff = 6 * 24 * 60 * 60 / AVG_BLOCK_TIME;
|
|
@@ -45,11 +45,11 @@ export const getCbETHApr = async (web3: Web3, blockNumber: 'latest' | number = '
|
|
|
45
45
|
.mul(BLOCKS_IN_A_YEAR / blockDiff)
|
|
46
46
|
.mul(100)
|
|
47
47
|
.toString();
|
|
48
|
-
return apr;
|
|
48
|
+
return aprToApy(apr);
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
export const
|
|
52
|
+
export const getREthApy = async (web3: Web3, blockNumber: 'latest' | number = 'latest') => {
|
|
53
53
|
let currentBlock = blockNumber;
|
|
54
54
|
if (blockNumber === 'latest') currentBlock = await web3.eth.getBlockNumber();
|
|
55
55
|
const blockDiff = 8 * 24 * 60 * 60 / AVG_BLOCK_TIME;
|
|
@@ -64,7 +64,7 @@ export const getREthApr = async (web3: Web3, blockNumber: 'latest' | number = 'l
|
|
|
64
64
|
.mul(100)
|
|
65
65
|
.toString();
|
|
66
66
|
|
|
67
|
-
return apr;
|
|
67
|
+
return aprToApy(apr);
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
export const getDsrApy = async (web3: Web3, blockNumber: 'latest' | number = 'latest') => {
|
|
@@ -84,7 +84,6 @@ export const getSsrApy = async () => {
|
|
|
84
84
|
};
|
|
85
85
|
|
|
86
86
|
const getSuperOETHApy = async () => {
|
|
87
|
-
console.log('getSuperOETHApy');
|
|
88
87
|
const res = await fetch('https://origin.squids.live/origin-squid/graphql', {
|
|
89
88
|
method: 'POST',
|
|
90
89
|
headers: {
|
|
@@ -106,17 +105,20 @@ const getSuperOETHApy = async () => {
|
|
|
106
105
|
const getApyFromDfsApi = async (asset: string) => {
|
|
107
106
|
const res = await fetch(`https://app.defisaver.com/api/staking/apy?asset=${asset}`);
|
|
108
107
|
const data = await res.json();
|
|
108
|
+
// if our server returns apr, transform it into apy
|
|
109
|
+
if (['weETH'].includes(asset)) {
|
|
110
|
+
return aprToApy(data.apy);
|
|
111
|
+
}
|
|
109
112
|
return data.apy;
|
|
110
113
|
};
|
|
111
114
|
|
|
112
115
|
export const STAKING_ASSETS = ['cbETH', 'wstETH', 'cbETH', 'rETH', 'sDAI', 'weETH', 'sUSDe', 'osETH', 'ezETH', 'ETHx', 'rsETH', 'pufETH', 'wrsETH', 'wsuperOETHb', 'sUSDS'];
|
|
113
116
|
|
|
114
117
|
export const getStakingApy = (asset: string, web3: Web3, blockNumber: 'latest' | number = 'latest', fromBlock: number | undefined = undefined) => {
|
|
115
|
-
console.log('getStakingApy', asset, blockNumber, fromBlock);
|
|
116
118
|
try {
|
|
117
|
-
if (asset === 'stETH' || asset === 'wstETH') return
|
|
118
|
-
if (asset === 'cbETH') return
|
|
119
|
-
if (asset === 'rETH') return
|
|
119
|
+
if (asset === 'stETH' || asset === 'wstETH') return getStETHApy(web3, fromBlock, blockNumber);
|
|
120
|
+
if (asset === 'cbETH') return getCbETHApy(web3, blockNumber);
|
|
121
|
+
if (asset === 'rETH') return getREthApy(web3, blockNumber);
|
|
120
122
|
if (asset === 'sDAI') return getDsrApy(web3);
|
|
121
123
|
if (asset === 'sUSDe') return getApyFromDfsApi('sUSDe');
|
|
122
124
|
if (asset === 'weETH') return getApyFromDfsApi('weETH');
|
package/src/types/aave.ts
CHANGED
|
@@ -84,6 +84,11 @@ export interface AaveV2AssetData extends AaveAssetData {
|
|
|
84
84
|
export interface MorphoAaveV2AssetData extends AaveV2AssetData {
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
export interface IncentiveData {
|
|
88
|
+
token: string,
|
|
89
|
+
apy: string,
|
|
90
|
+
}
|
|
91
|
+
|
|
87
92
|
export interface AaveV3AssetData extends AaveAssetData {
|
|
88
93
|
isIsolated: boolean,
|
|
89
94
|
isSiloed: boolean,
|
|
@@ -99,6 +104,8 @@ export interface AaveV3AssetData extends AaveAssetData {
|
|
|
99
104
|
isPaused: boolean,
|
|
100
105
|
isFlashLoanEnabled: boolean,
|
|
101
106
|
assetId: string | null,
|
|
107
|
+
supplyIncentives?: IncentiveData[];
|
|
108
|
+
borrowIncentives?: IncentiveData[];
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
export type EModeCategoriesData = Record<number, EModeCategoryData>;
|
package/src/types/spark.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MMAssetData, MMPositionData, MMUsedAsset, NetworkNumber,
|
|
3
3
|
} from './common';
|
|
4
|
+
import { IncentiveData } from './aave';
|
|
4
5
|
|
|
5
6
|
export enum SparkVersions {
|
|
6
7
|
SparkV1 = 'v1default',
|
|
@@ -55,6 +56,8 @@ export interface SparkAssetData extends MMAssetData {
|
|
|
55
56
|
eModeCategory: number,
|
|
56
57
|
eModeCategoryData: SparkEModeCategoryData,
|
|
57
58
|
liquidationRatio: string,
|
|
59
|
+
supplyIncentives?: IncentiveData[];
|
|
60
|
+
borrowIncentives?: IncentiveData[];
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
export interface SparkAssetsData {
|
|
@@ -125,4 +128,4 @@ export interface SparkPositionData extends MMPositionData {
|
|
|
125
128
|
isInIsolationMode: boolean,
|
|
126
129
|
isInSiloedMode: boolean,
|
|
127
130
|
eModeCategories: { [key: number]: SparkEModeCategoryDataMapping },
|
|
128
|
-
}
|
|
131
|
+
}
|