@defisaver/positions-sdk 2.0.0 → 2.0.4
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/.mocharc.json +4 -4
- package/.nvmrc +1 -1
- package/README.md +64 -64
- package/cjs/fluid/index.js +2 -1
- package/cjs/helpers/compoundHelpers/index.js +2 -2
- package/cjs/helpers/morphoBlueHelpers/index.js +156 -139
- package/cjs/markets/aave/marketAssets.js +1 -1
- package/cjs/services/utils.d.ts +1 -0
- package/cjs/services/utils.js +2 -1
- package/cjs/staking/staking.js +43 -23
- package/cjs/types/compound.d.ts +2 -0
- package/esm/fluid/index.js +3 -2
- package/esm/helpers/compoundHelpers/index.js +2 -2
- package/esm/helpers/morphoBlueHelpers/index.js +157 -140
- package/esm/markets/aave/marketAssets.js +1 -1
- package/esm/services/utils.d.ts +1 -0
- package/esm/services/utils.js +1 -0
- package/esm/staking/staking.js +43 -23
- package/esm/types/compound.d.ts +2 -0
- package/package.json +47 -47
- package/src/aaveV2/index.ts +236 -236
- package/src/aaveV3/index.ts +489 -489
- package/src/compoundV2/index.ts +240 -240
- package/src/compoundV3/index.ts +270 -270
- package/src/config/contracts.ts +1082 -1082
- package/src/constants/index.ts +6 -6
- package/src/contracts.ts +107 -107
- package/src/curveUsd/index.ts +250 -250
- package/src/eulerV2/index.ts +314 -314
- package/src/exchange/index.ts +25 -25
- package/src/fluid/index.ts +1568 -1564
- package/src/helpers/aaveHelpers/index.ts +170 -170
- package/src/helpers/compoundHelpers/index.ts +261 -250
- package/src/helpers/curveUsdHelpers/index.ts +40 -40
- package/src/helpers/eulerHelpers/index.ts +259 -259
- package/src/helpers/fluidHelpers/index.ts +324 -324
- package/src/helpers/index.ts +10 -10
- package/src/helpers/liquityV2Helpers/index.ts +80 -80
- package/src/helpers/llamaLendHelpers/index.ts +53 -53
- package/src/helpers/makerHelpers/index.ts +52 -52
- package/src/helpers/morphoBlueHelpers/index.ts +390 -375
- package/src/helpers/sparkHelpers/index.ts +155 -155
- package/src/index.ts +45 -45
- package/src/liquity/index.ts +104 -104
- package/src/liquityV2/index.ts +408 -408
- package/src/llamaLend/index.ts +296 -296
- package/src/maker/index.ts +223 -223
- package/src/markets/aave/index.ts +116 -116
- package/src/markets/aave/marketAssets.ts +44 -44
- package/src/markets/compound/index.ts +216 -216
- package/src/markets/compound/marketsAssets.ts +83 -83
- package/src/markets/curveUsd/index.ts +69 -69
- package/src/markets/euler/index.ts +26 -26
- package/src/markets/fluid/index.ts +2456 -2456
- package/src/markets/index.ts +25 -25
- package/src/markets/liquityV2/index.ts +102 -102
- package/src/markets/llamaLend/contractAddresses.ts +141 -141
- package/src/markets/llamaLend/index.ts +235 -235
- package/src/markets/morphoBlue/index.ts +895 -895
- package/src/markets/spark/index.ts +29 -29
- package/src/markets/spark/marketAssets.ts +10 -10
- package/src/moneymarket/moneymarketCommonService.ts +80 -80
- package/src/morphoBlue/index.ts +222 -222
- package/src/portfolio/index.ts +285 -285
- package/src/services/priceService.ts +159 -159
- package/src/services/utils.ts +64 -62
- package/src/services/viem.ts +30 -30
- package/src/setup.ts +8 -8
- package/src/spark/index.ts +456 -456
- package/src/staking/staking.ts +192 -173
- package/src/types/aave.ts +194 -194
- package/src/types/common.ts +87 -87
- package/src/types/compound.ts +136 -134
- package/src/types/curveUsd.ts +121 -121
- package/src/types/euler.ts +174 -174
- package/src/types/fluid.ts +450 -450
- package/src/types/index.ts +11 -11
- package/src/types/liquity.ts +30 -30
- package/src/types/liquityV2.ts +126 -126
- package/src/types/llamaLend.ts +157 -157
- package/src/types/maker.ts +63 -63
- package/src/types/morphoBlue.ts +194 -194
- package/src/types/portfolio.ts +60 -60
- package/src/types/spark.ts +137 -137
package/.mocharc.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{
|
|
2
|
-
"require": "ts-node/register",
|
|
3
|
-
"extension": ["ts"]
|
|
4
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"require": "ts-node/register",
|
|
3
|
+
"extension": ["ts"]
|
|
4
|
+
}
|
package/.nvmrc
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v20.17.0
|
|
1
|
+
v20.17.0
|
package/README.md
CHANGED
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
# DeFi Saver Positions SDK
|
|
2
|
-
|
|
3
|
-
Supported protocols:
|
|
4
|
-
- [Maker](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/maker)
|
|
5
|
-
- [Spark](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/spark)
|
|
6
|
-
- [CrvUSD](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/curveUsd)
|
|
7
|
-
- [Aave V2](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/aaveV2)
|
|
8
|
-
- [Aave V3](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/aaveV3)
|
|
9
|
-
- [Compound V2](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/compoundV2)
|
|
10
|
-
- [Compound V3](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/compoundV3)
|
|
11
|
-
- [Liquity](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/liquity)
|
|
12
|
-
|
|
13
|
-
## Setup
|
|
14
|
-
Supported Node version is v10.
|
|
15
|
-
|
|
16
|
-
- run `npm install` (first time)
|
|
17
|
-
- run `npm run build`
|
|
18
|
-
|
|
19
|
-
`build` command will generate contracts and build ejs and esm folders
|
|
20
|
-
|
|
21
|
-
## How to use
|
|
22
|
-
[All available imports](https://github.com/defisaver/defisaver-positions-sdk/blob/main/src/index.ts)
|
|
23
|
-
|
|
24
|
-
This is a Compound V3 example, and every other protocol is similar
|
|
25
|
-
```js
|
|
26
|
-
import { compoundV3 } from '@defisaver/positions-sdk';
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// every protocol has market data and user data getters
|
|
30
|
-
const {
|
|
31
|
-
getCompoundV3MarketsData,
|
|
32
|
-
getCompoundV3AccountData,
|
|
33
|
-
} = compoundV3;
|
|
34
|
-
|
|
35
|
-
const provider = 'Your RPC provider';
|
|
36
|
-
|
|
37
|
-
const user = '0x123...';
|
|
38
|
-
|
|
39
|
-
const { assetsData } = await getCompoundV3MarketsData(
|
|
40
|
-
provider, // rpc for the network you are using (note: can be tenderly or any other testnet rpc)
|
|
41
|
-
1, // network
|
|
42
|
-
selectedMarket, // market object like in /src/markets/compound/index.ts
|
|
43
|
-
provider, // this must be mainnet rpc - used for getting prices onchain and calculating apys
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
const userData = await getCompoundV3AccountData(
|
|
47
|
-
provider,
|
|
48
|
-
1, // network
|
|
49
|
-
userAddress, // EOA or DSProxy
|
|
50
|
-
'', // proxy address of the user, or just empty string if checking for EOA
|
|
51
|
-
{
|
|
52
|
-
selectedMarket, // market object as in /src/markets/compound/index.ts
|
|
53
|
-
assetsData,
|
|
54
|
-
}
|
|
55
|
-
);
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
More examples found [here](https://github.com/defisaver/defisaver-positions-sdk/tree/main/tests)
|
|
59
|
-
|
|
60
|
-
## Testing
|
|
61
|
-
|
|
62
|
-
`npm run test` - Run all tests
|
|
63
|
-
|
|
64
|
-
`npm run test-single --name=your_test_name` - Run single test for specified name e.g. for MyTest.js test name is MyTest
|
|
1
|
+
# DeFi Saver Positions SDK
|
|
2
|
+
|
|
3
|
+
Supported protocols:
|
|
4
|
+
- [Maker](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/maker)
|
|
5
|
+
- [Spark](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/spark)
|
|
6
|
+
- [CrvUSD](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/curveUsd)
|
|
7
|
+
- [Aave V2](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/aaveV2)
|
|
8
|
+
- [Aave V3](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/aaveV3)
|
|
9
|
+
- [Compound V2](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/compoundV2)
|
|
10
|
+
- [Compound V3](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/compoundV3)
|
|
11
|
+
- [Liquity](https://github.com/defisaver/defisaver-positions-sdk/tree/main/src/liquity)
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
14
|
+
Supported Node version is v10.
|
|
15
|
+
|
|
16
|
+
- run `npm install` (first time)
|
|
17
|
+
- run `npm run build`
|
|
18
|
+
|
|
19
|
+
`build` command will generate contracts and build ejs and esm folders
|
|
20
|
+
|
|
21
|
+
## How to use
|
|
22
|
+
[All available imports](https://github.com/defisaver/defisaver-positions-sdk/blob/main/src/index.ts)
|
|
23
|
+
|
|
24
|
+
This is a Compound V3 example, and every other protocol is similar
|
|
25
|
+
```js
|
|
26
|
+
import { compoundV3 } from '@defisaver/positions-sdk';
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
// every protocol has market data and user data getters
|
|
30
|
+
const {
|
|
31
|
+
getCompoundV3MarketsData,
|
|
32
|
+
getCompoundV3AccountData,
|
|
33
|
+
} = compoundV3;
|
|
34
|
+
|
|
35
|
+
const provider = 'Your RPC provider';
|
|
36
|
+
|
|
37
|
+
const user = '0x123...';
|
|
38
|
+
|
|
39
|
+
const { assetsData } = await getCompoundV3MarketsData(
|
|
40
|
+
provider, // rpc for the network you are using (note: can be tenderly or any other testnet rpc)
|
|
41
|
+
1, // network
|
|
42
|
+
selectedMarket, // market object like in /src/markets/compound/index.ts
|
|
43
|
+
provider, // this must be mainnet rpc - used for getting prices onchain and calculating apys
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
const userData = await getCompoundV3AccountData(
|
|
47
|
+
provider,
|
|
48
|
+
1, // network
|
|
49
|
+
userAddress, // EOA or DSProxy
|
|
50
|
+
'', // proxy address of the user, or just empty string if checking for EOA
|
|
51
|
+
{
|
|
52
|
+
selectedMarket, // market object as in /src/markets/compound/index.ts
|
|
53
|
+
assetsData,
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
More examples found [here](https://github.com/defisaver/defisaver-positions-sdk/tree/main/tests)
|
|
59
|
+
|
|
60
|
+
## Testing
|
|
61
|
+
|
|
62
|
+
`npm run test` - Run all tests
|
|
63
|
+
|
|
64
|
+
`npm run test-single --name=your_test_name` - Run single test for specified name e.g. for MyTest.js test name is MyTest
|
package/cjs/fluid/index.js
CHANGED
|
@@ -199,9 +199,10 @@ const getAdditionalMarketRateForDex = (token1PerShare, token0PerShare, incentive
|
|
|
199
199
|
const getTradingApy = (poolAddress) => __awaiter(void 0, void 0, void 0, function* () {
|
|
200
200
|
let res;
|
|
201
201
|
try {
|
|
202
|
-
res = yield fetch(`https://api.fluid.instadapp.io/v2/1/dexes/${poolAddress}/apy`, { signal: AbortSignal.timeout(
|
|
202
|
+
res = yield fetch(`https://api.fluid.instadapp.io/v2/1/dexes/${poolAddress}/apy`, { signal: AbortSignal.timeout(utils_1.DEFAULT_TIMEOUT) });
|
|
203
203
|
}
|
|
204
204
|
catch (e) {
|
|
205
|
+
console.error('External API Failure: Fluid Trading Apy');
|
|
205
206
|
return '0';
|
|
206
207
|
}
|
|
207
208
|
if (!res.ok) {
|
|
@@ -38,7 +38,7 @@ const formatMarketData = (data, network, baseAssetPrice) => {
|
|
|
38
38
|
const assetInfo = (0, tokens_1.getAssetInfoByAddress)(data.tokenAddr, network);
|
|
39
39
|
const isWETH = assetInfo.symbol === 'WETH';
|
|
40
40
|
const price = (0, utils_1.getEthAmountForDecimals)(data.price, 8);
|
|
41
|
-
return (Object.assign(Object.assign({}, data), { priceInBaseAsset: (0, utils_1.getEthAmountForDecimals)(data.price, 8), price: new decimal_js_1.default(price).mul(baseAssetPrice).toString(), collateralFactor: (0, utils_1.getEthAmountForDecimals)(data.borrowCollateralFactor, 18), liquidationRatio: (0, utils_1.getEthAmountForDecimals)(data.liquidateCollateralFactor, 18), supplyCap: (0, utils_1.getEthAmountForDecimals)(data.supplyCap, assetInfo.decimals), totalSupply: (0, utils_1.getEthAmountForDecimals)(data.totalSupply, assetInfo.decimals), symbol: isWETH ? 'ETH' : assetInfo.symbol, supplyRate: '0', borrowRate: '0', canBeBorrowed: false, canBeSupplied: true }));
|
|
41
|
+
return (Object.assign(Object.assign({}, data), { borrowCollateralFactor: data.borrowCollateralFactor.toString(), liquidateCollateralFactor: data.liquidateCollateralFactor.toString(), liquidationFactor: data.liquidationFactor.toString(), supplyReserved: data.supplyReserved.toString(), priceInBaseAsset: (0, utils_1.getEthAmountForDecimals)(data.price, 8), price: new decimal_js_1.default(price).mul(baseAssetPrice).toString(), collateralFactor: (0, utils_1.getEthAmountForDecimals)(data.borrowCollateralFactor, 18), liquidationRatio: (0, utils_1.getEthAmountForDecimals)(data.liquidateCollateralFactor, 18), supplyCap: (0, utils_1.getEthAmountForDecimals)(data.supplyCap, assetInfo.decimals), totalSupply: (0, utils_1.getEthAmountForDecimals)(data.totalSupply, assetInfo.decimals), symbol: isWETH ? 'ETH' : assetInfo.symbol, supplyRate: '0', borrowRate: '0', canBeBorrowed: false, canBeSupplied: true }));
|
|
42
42
|
};
|
|
43
43
|
exports.formatMarketData = formatMarketData;
|
|
44
44
|
// TODO: maybe not hardcode decimals
|
|
@@ -46,7 +46,7 @@ const formatBaseData = (data, network, baseAssetPrice) => {
|
|
|
46
46
|
const assetInfo = (0, tokens_1.getAssetInfoByAddress)(data.tokenAddr, network);
|
|
47
47
|
const totalSupply = (0, utils_1.getEthAmountForDecimals)(new decimal_js_1.default(data.totalSupply).mul(data.supplyIndex).toString(), 15 + assetInfo.decimals);
|
|
48
48
|
const totalBorrow = (0, utils_1.getEthAmountForDecimals)(new decimal_js_1.default(data.totalBorrow).mul(data.borrowIndex).toString(), 15 + assetInfo.decimals);
|
|
49
|
-
return (Object.assign(Object.assign({}, data), { supplyRate: (0, moneymarket_1.aprToApy)(new decimal_js_1.default(data.supplyRate).div(1e18).mul(constants_1.SECONDS_PER_YEAR).mul(100)
|
|
49
|
+
return (Object.assign(Object.assign({}, data), { baseBorrowMin: data.baseBorrowMin.toString(), baseTrackingBorrowRewardsSpeed: data.baseTrackingBorrowRewardsSpeed.toString(), baseTrackingSupplyRewardsSpeed: data.baseTrackingSupplyRewardsSpeed.toString(), borrowIndex: data.borrowIndex.toString(), supplyIndex: data.supplyIndex.toString(), trackingBorrowIndex: data.trackingBorrowIndex.toString(), trackingSupplyIndex: data.trackingSupplyIndex.toString(), supplyRate: (0, moneymarket_1.aprToApy)(new decimal_js_1.default(data.supplyRate).div(1e18).mul(constants_1.SECONDS_PER_YEAR).mul(100)
|
|
50
50
|
.toString()), borrowRate: (0, moneymarket_1.aprToApy)(new decimal_js_1.default(data.borrowRate).div(1e18).mul(constants_1.SECONDS_PER_YEAR).mul(100)
|
|
51
51
|
.toString()), utilization: (0, utils_1.getEthAmountForDecimals)(data.utilization, 16), // utilization is totalSupply/totalBorrow in 1e18, but we need % so when we mul with 100 it's 16 decimals
|
|
52
52
|
totalSupply,
|
|
@@ -128,73 +128,73 @@ const getApyAfterValuesEstimation = (selectedMarket, actions, provider, network)
|
|
|
128
128
|
});
|
|
129
129
|
exports.getApyAfterValuesEstimation = getApyAfterValuesEstimation;
|
|
130
130
|
const API_URL = 'https://blue-api.morpho.org/graphql';
|
|
131
|
-
const MARKET_QUERY = `
|
|
132
|
-
query MarketByUniqueKey($uniqueKey: String!, $chainId: Int!) {
|
|
133
|
-
marketByUniqueKey(uniqueKey: $uniqueKey, chainId: $chainId) {
|
|
134
|
-
reallocatableLiquidityAssets
|
|
135
|
-
targetBorrowUtilization
|
|
136
|
-
loanAsset {
|
|
137
|
-
address
|
|
138
|
-
decimals
|
|
139
|
-
priceUsd
|
|
140
|
-
}
|
|
141
|
-
state {
|
|
142
|
-
liquidityAssets
|
|
143
|
-
borrowAssets
|
|
144
|
-
supplyAssets
|
|
145
|
-
}
|
|
146
|
-
publicAllocatorSharedLiquidity {
|
|
147
|
-
assets
|
|
148
|
-
vault {
|
|
149
|
-
address
|
|
150
|
-
name
|
|
151
|
-
}
|
|
152
|
-
allocationMarket {
|
|
153
|
-
uniqueKey
|
|
154
|
-
loanAsset {
|
|
155
|
-
address
|
|
156
|
-
}
|
|
157
|
-
collateralAsset {
|
|
158
|
-
address
|
|
159
|
-
}
|
|
160
|
-
irmAddress
|
|
161
|
-
oracle {
|
|
162
|
-
address
|
|
163
|
-
}
|
|
164
|
-
lltv
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
loanAsset {
|
|
168
|
-
address
|
|
169
|
-
}
|
|
170
|
-
collateralAsset {
|
|
171
|
-
address
|
|
172
|
-
}
|
|
173
|
-
oracle {
|
|
174
|
-
address
|
|
175
|
-
}
|
|
176
|
-
irmAddress
|
|
177
|
-
lltv
|
|
178
|
-
}
|
|
179
|
-
}
|
|
131
|
+
const MARKET_QUERY = `
|
|
132
|
+
query MarketByUniqueKey($uniqueKey: String!, $chainId: Int!) {
|
|
133
|
+
marketByUniqueKey(uniqueKey: $uniqueKey, chainId: $chainId) {
|
|
134
|
+
reallocatableLiquidityAssets
|
|
135
|
+
targetBorrowUtilization
|
|
136
|
+
loanAsset {
|
|
137
|
+
address
|
|
138
|
+
decimals
|
|
139
|
+
priceUsd
|
|
140
|
+
}
|
|
141
|
+
state {
|
|
142
|
+
liquidityAssets
|
|
143
|
+
borrowAssets
|
|
144
|
+
supplyAssets
|
|
145
|
+
}
|
|
146
|
+
publicAllocatorSharedLiquidity {
|
|
147
|
+
assets
|
|
148
|
+
vault {
|
|
149
|
+
address
|
|
150
|
+
name
|
|
151
|
+
}
|
|
152
|
+
allocationMarket {
|
|
153
|
+
uniqueKey
|
|
154
|
+
loanAsset {
|
|
155
|
+
address
|
|
156
|
+
}
|
|
157
|
+
collateralAsset {
|
|
158
|
+
address
|
|
159
|
+
}
|
|
160
|
+
irmAddress
|
|
161
|
+
oracle {
|
|
162
|
+
address
|
|
163
|
+
}
|
|
164
|
+
lltv
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
loanAsset {
|
|
168
|
+
address
|
|
169
|
+
}
|
|
170
|
+
collateralAsset {
|
|
171
|
+
address
|
|
172
|
+
}
|
|
173
|
+
oracle {
|
|
174
|
+
address
|
|
175
|
+
}
|
|
176
|
+
irmAddress
|
|
177
|
+
lltv
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
180
|
`;
|
|
181
|
-
const REWARDS_QUERY = `
|
|
182
|
-
query MarketByUniqueKey($uniqueKey: String!, $chainId: Int!) {
|
|
183
|
-
marketByUniqueKey(uniqueKey: $uniqueKey, chainId: $chainId) {
|
|
184
|
-
uniqueKey
|
|
185
|
-
state {
|
|
186
|
-
rewards {
|
|
187
|
-
amountPerSuppliedToken
|
|
188
|
-
supplyApr
|
|
189
|
-
amountPerBorrowedToken
|
|
190
|
-
borrowApr
|
|
191
|
-
asset {
|
|
192
|
-
address
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
181
|
+
const REWARDS_QUERY = `
|
|
182
|
+
query MarketByUniqueKey($uniqueKey: String!, $chainId: Int!) {
|
|
183
|
+
marketByUniqueKey(uniqueKey: $uniqueKey, chainId: $chainId) {
|
|
184
|
+
uniqueKey
|
|
185
|
+
state {
|
|
186
|
+
rewards {
|
|
187
|
+
amountPerSuppliedToken
|
|
188
|
+
supplyApr
|
|
189
|
+
amountPerBorrowedToken
|
|
190
|
+
borrowApr
|
|
191
|
+
asset {
|
|
192
|
+
address
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
198
|
`;
|
|
199
199
|
/**
|
|
200
200
|
* Get reallocatable liquidity to a given market and target borrow utilization
|
|
@@ -204,19 +204,29 @@ const REWARDS_QUERY = `
|
|
|
204
204
|
*/
|
|
205
205
|
const getReallocatableLiquidity = (marketId_1, ...args_1) => __awaiter(void 0, [marketId_1, ...args_1], void 0, function* (marketId, network = common_1.NetworkNumber.Eth) {
|
|
206
206
|
var _a;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
207
|
+
try {
|
|
208
|
+
const response = yield fetch(API_URL, {
|
|
209
|
+
method: 'POST',
|
|
210
|
+
headers: { 'Content-Type': 'application/json' },
|
|
211
|
+
body: JSON.stringify({
|
|
212
|
+
query: MARKET_QUERY,
|
|
213
|
+
variables: { uniqueKey: marketId, chainId: network },
|
|
214
|
+
}),
|
|
215
|
+
signal: AbortSignal.timeout(utils_1.DEFAULT_TIMEOUT),
|
|
216
|
+
});
|
|
217
|
+
const data = yield response.json();
|
|
218
|
+
const marketData = (_a = data === null || data === void 0 ? void 0 : data.data) === null || _a === void 0 ? void 0 : _a.marketByUniqueKey;
|
|
219
|
+
if (!marketData)
|
|
220
|
+
throw new Error('Market data not found');
|
|
221
|
+
return {
|
|
222
|
+
reallocatableLiquidity: marketData.reallocatableLiquidityAssets,
|
|
223
|
+
targetBorrowUtilization: marketData.targetBorrowUtilization,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
console.error('External API Failure: Morpho blue reallocatable liquidity', error);
|
|
228
|
+
throw new Error('Failed to fetch reallocatable liquidity');
|
|
229
|
+
}
|
|
220
230
|
});
|
|
221
231
|
exports.getReallocatableLiquidity = getReallocatableLiquidity;
|
|
222
232
|
/**
|
|
@@ -257,71 +267,78 @@ exports.getLiquidityToAllocate = getLiquidityToAllocate;
|
|
|
257
267
|
*/
|
|
258
268
|
const getReallocation = (market_1, assetsData_1, amountToBorrow_1, ...args_1) => __awaiter(void 0, [market_1, assetsData_1, amountToBorrow_1, ...args_1], void 0, function* (market, assetsData, amountToBorrow, network = common_1.NetworkNumber.Eth) {
|
|
259
269
|
var _a, _b, _c;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
const vaultAllocations = marketData.publicAllocatorSharedLiquidity.filter((item) => (0, utils_1.compareAddresses)(item.vault.address, vaultAddress));
|
|
295
|
-
for (const item of vaultAllocations) {
|
|
270
|
+
try {
|
|
271
|
+
const { marketId, loanToken } = market;
|
|
272
|
+
const response = yield fetch(API_URL, {
|
|
273
|
+
method: 'POST',
|
|
274
|
+
headers: { 'Content-Type': 'application/json' },
|
|
275
|
+
body: JSON.stringify({
|
|
276
|
+
query: MARKET_QUERY,
|
|
277
|
+
variables: { uniqueKey: marketId, chainId: network },
|
|
278
|
+
}),
|
|
279
|
+
signal: AbortSignal.timeout(utils_1.DEFAULT_TIMEOUT),
|
|
280
|
+
});
|
|
281
|
+
const data = yield response.json();
|
|
282
|
+
const marketData = (_a = data === null || data === void 0 ? void 0 : data.data) === null || _a === void 0 ? void 0 : _a.marketByUniqueKey;
|
|
283
|
+
if (!marketData)
|
|
284
|
+
throw new Error('Market data not found');
|
|
285
|
+
const loanAssetInfo = (0, tokens_1.getAssetInfoByAddress)(loanToken, network);
|
|
286
|
+
const { totalBorrow, totalSupply } = assetsData[loanAssetInfo.symbol] || { totalBorrow: '0', totalSupply: '0' };
|
|
287
|
+
const totalBorrowWei = (0, tokens_1.assetAmountInWei)(totalBorrow, loanAssetInfo.symbol);
|
|
288
|
+
const totalSupplyWei = (0, tokens_1.assetAmountInWei)(totalSupply, loanAssetInfo.symbol);
|
|
289
|
+
const newTotalBorrowAssets = new decimal_js_1.default(totalBorrowWei).add(amountToBorrow).toString();
|
|
290
|
+
const newUtil = new decimal_js_1.default(newTotalBorrowAssets).div(totalSupplyWei).toString();
|
|
291
|
+
const newUtilScaled = new decimal_js_1.default(newUtil).mul(1e18).toString();
|
|
292
|
+
if (new decimal_js_1.default(newUtilScaled).lt(marketData.targetBorrowUtilization))
|
|
293
|
+
return { vaults: [], withdrawals: [] };
|
|
294
|
+
const liquidityToAllocate = (0, exports.getLiquidityToAllocate)(amountToBorrow, totalBorrowWei, totalSupplyWei, marketData.targetBorrowUtilization, marketData.reallocatableLiquidityAssets);
|
|
295
|
+
const vaultTotalAssets = marketData.publicAllocatorSharedLiquidity.reduce((acc, item) => {
|
|
296
|
+
const vaultAddress = item.vault.address;
|
|
297
|
+
acc[vaultAddress] = new decimal_js_1.default(acc[vaultAddress] || '0').add(item.assets).toString();
|
|
298
|
+
return acc;
|
|
299
|
+
}, {});
|
|
300
|
+
const sortedVaults = Object.entries(vaultTotalAssets).sort(([, a], [, b]) => new decimal_js_1.default(b || '0').sub(a || '0').toNumber());
|
|
301
|
+
const withdrawalsPerVault = {};
|
|
302
|
+
let totalReallocated = '0';
|
|
303
|
+
for (const [vaultAddress] of sortedVaults) {
|
|
296
304
|
if (new decimal_js_1.default(totalReallocated).gte(liquidityToAllocate))
|
|
297
305
|
break;
|
|
298
|
-
const
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
306
|
+
const vaultAllocations = marketData.publicAllocatorSharedLiquidity.filter((item) => (0, utils_1.compareAddresses)(item.vault.address, vaultAddress));
|
|
307
|
+
for (const item of vaultAllocations) {
|
|
308
|
+
if (new decimal_js_1.default(totalReallocated).gte(liquidityToAllocate))
|
|
309
|
+
break;
|
|
310
|
+
const itemAmount = item.assets;
|
|
311
|
+
const leftToAllocate = new decimal_js_1.default(liquidityToAllocate).sub(totalReallocated).toString();
|
|
312
|
+
const amountToTake = new decimal_js_1.default(itemAmount).lt(leftToAllocate) ? itemAmount : leftToAllocate;
|
|
313
|
+
totalReallocated = new decimal_js_1.default(totalReallocated).add(amountToTake).toString();
|
|
314
|
+
const withdrawal = [
|
|
315
|
+
[
|
|
316
|
+
item.allocationMarket.loanAsset.address,
|
|
317
|
+
(_b = item.allocationMarket.collateralAsset) === null || _b === void 0 ? void 0 : _b.address,
|
|
318
|
+
(_c = item.allocationMarket.oracle) === null || _c === void 0 ? void 0 : _c.address,
|
|
319
|
+
item.allocationMarket.irmAddress,
|
|
320
|
+
item.allocationMarket.lltv,
|
|
321
|
+
],
|
|
322
|
+
amountToTake.toString(),
|
|
323
|
+
item.allocationMarket.uniqueKey,
|
|
324
|
+
];
|
|
325
|
+
if (!withdrawalsPerVault[vaultAddress]) {
|
|
326
|
+
withdrawalsPerVault[vaultAddress] = [];
|
|
327
|
+
}
|
|
328
|
+
withdrawalsPerVault[vaultAddress].push(withdrawal);
|
|
315
329
|
}
|
|
316
|
-
withdrawalsPerVault[vaultAddress].push(withdrawal);
|
|
317
330
|
}
|
|
331
|
+
const vaults = Object.keys(withdrawalsPerVault);
|
|
332
|
+
const withdrawals = vaults.map((vaultAddress) => withdrawalsPerVault[vaultAddress].sort((a, b) => a[2].localeCompare(b[2])).map(w => [w[0], w[1]]));
|
|
333
|
+
return {
|
|
334
|
+
vaults,
|
|
335
|
+
withdrawals,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
console.error('External API Failure: Morpho blue reallocation', error);
|
|
340
|
+
throw new Error('Failed to fetch reallocation data');
|
|
318
341
|
}
|
|
319
|
-
const vaults = Object.keys(withdrawalsPerVault);
|
|
320
|
-
const withdrawals = vaults.map((vaultAddress) => withdrawalsPerVault[vaultAddress].sort((a, b) => a[2].localeCompare(b[2])).map(w => [w[0], w[1]]));
|
|
321
|
-
return {
|
|
322
|
-
vaults,
|
|
323
|
-
withdrawals,
|
|
324
|
-
};
|
|
325
342
|
});
|
|
326
343
|
exports.getReallocation = getReallocation;
|
|
327
344
|
const getRewardsForMarket = (marketId_1, ...args_1) => __awaiter(void 0, [marketId_1, ...args_1], void 0, function* (marketId, network = common_1.NetworkNumber.Eth) {
|
|
@@ -10,7 +10,7 @@ exports.aaveV1AssetsDefaultMarket = [
|
|
|
10
10
|
exports.aaveV2AssetsDefaultMarket = ['USDT', 'WBTC', 'ETH', 'YFI', 'ZRX', 'UNI', 'AAVE', 'BAT', 'BUSD', 'DAI', 'ENJ', 'KNCL', 'LINK', 'MANA', 'MKR', 'REN', 'SNX', 'SUSD', 'TUSD', 'USDC', 'CRV', 'GUSD', 'BAL', 'xSUSHI', 'RENFIL', 'RAI', 'AMPL', 'USDP', 'DPI', 'FRAX', 'FEI', 'stETH', 'ENS', 'UST', 'CVX', '1INCH', 'LUSD'];
|
|
11
11
|
exports.aaveV3AssetsDefaultMarketEth = [
|
|
12
12
|
'ETH', 'wstETH', 'WBTC', 'USDC', 'DAI', 'LINK', 'AAVE', 'cbETH', 'USDT', 'rETH', 'LUSD', 'CRV', 'MKR', 'SNX', 'BAL', 'UNI', 'LDO', 'ENS', '1INCH', 'FRAX', 'GHO', 'RPL', 'sDAI', 'STG', 'KNC', 'FXS', 'crvUSD', 'PYUSD', 'weETH', 'osETH', 'USDe', 'ETHx', 'sUSDe', 'tBTC', 'cbBTC', 'USDS', 'rsETH', 'LBTC', 'eBTC', 'RLUSD', 'PT eUSDe May', 'PT sUSDe July', 'USDtb',
|
|
13
|
-
'eUSDe', 'PT USDe July', 'PT eUSDe Aug', 'EURC', 'FBTC', 'PT sUSDe Sep', 'PT USDe Sep',
|
|
13
|
+
'eUSDe', 'PT USDe July', 'PT eUSDe Aug', 'EURC', 'FBTC', 'PT sUSDe Sep', 'PT USDe Sep', 'tETH', 'ezETH',
|
|
14
14
|
];
|
|
15
15
|
exports.aaveV3AssetsDefaultMarketOpt = [
|
|
16
16
|
'DAI', 'USDC.e', 'USDT', 'SUSD', 'AAVE', 'LINK', 'WBTC', 'ETH', 'OP', 'wstETH', 'LUSD', 'MAI', 'rETH', 'USDC',
|
package/cjs/services/utils.d.ts
CHANGED
|
@@ -24,3 +24,4 @@ export declare const isEnabledOnBitmap: (bitmap: number, assetId: number) => big
|
|
|
24
24
|
export declare const MAXUINT: string;
|
|
25
25
|
export declare const isMaxuint: (amount: string) => boolean;
|
|
26
26
|
export declare const isMainnetNetwork: (network: NetworkNumber) => network is NetworkNumber.Eth;
|
|
27
|
+
export declare const DEFAULT_TIMEOUT = 2000;
|
package/cjs/services/utils.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.isMainnetNetwork = exports.isMaxuint = exports.MAXUINT = exports.isEnabledOnBitmap = exports.mapRange = exports.bytesToString = exports.ethToWethByAddress = exports.wethToEthByAddress = exports.handleWbtcLegacy = exports.getEthAmountForDecimals = exports.getWeiAmountForDecimals = exports.compareAddresses = exports.isAddress = exports.ADDRESS_REGEX = exports.getAbiItem = exports.wstEthToStEth = exports.stEthToWstEth = exports.wethToEth = exports.ethToWeth = exports.addToArrayIf = exports.addToObjectIf = exports.isLayer2Network = void 0;
|
|
6
|
+
exports.DEFAULT_TIMEOUT = exports.isMainnetNetwork = exports.isMaxuint = exports.MAXUINT = exports.isEnabledOnBitmap = exports.mapRange = exports.bytesToString = exports.ethToWethByAddress = exports.wethToEthByAddress = exports.handleWbtcLegacy = exports.getEthAmountForDecimals = exports.getWeiAmountForDecimals = exports.compareAddresses = exports.isAddress = exports.ADDRESS_REGEX = exports.getAbiItem = exports.wstEthToStEth = exports.stEthToWstEth = exports.wethToEth = exports.ethToWeth = exports.addToArrayIf = exports.addToObjectIf = exports.isLayer2Network = void 0;
|
|
7
7
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
8
8
|
const tokens_1 = require("@defisaver/tokens");
|
|
9
9
|
const common_1 = require("../types/common");
|
|
@@ -63,3 +63,4 @@ const isMaxuint = (amount) => (0, exports.compareAddresses)(exports.MAXUINT, amo
|
|
|
63
63
|
exports.isMaxuint = isMaxuint;
|
|
64
64
|
const isMainnetNetwork = (network) => network === common_1.NetworkNumber.Eth;
|
|
65
65
|
exports.isMainnetNetwork = isMainnetNetwork;
|
|
66
|
+
exports.DEFAULT_TIMEOUT = 2000; // 2 seconds
|
package/cjs/staking/staking.js
CHANGED
|
@@ -16,36 +16,56 @@ exports.calculateNetApy = exports.isEligibleForEthenaUSDeRewards = exports.calcu
|
|
|
16
16
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
17
17
|
const memoizee_1 = __importDefault(require("memoizee"));
|
|
18
18
|
const constants_1 = require("../constants");
|
|
19
|
+
const utils_1 = require("../services/utils");
|
|
19
20
|
const getSsrApy = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
try {
|
|
22
|
+
const res = yield fetch('https://fe.defisaver.com/api/sky/data', { signal: AbortSignal.timeout(utils_1.DEFAULT_TIMEOUT) });
|
|
23
|
+
const data = yield res.json();
|
|
24
|
+
return new decimal_js_1.default(data.data.skyData[0].sky_savings_rate_apy).mul(100).toString();
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
console.error('External API Failure: Failed to fetch SSR APY from external API', e);
|
|
28
|
+
return '0';
|
|
29
|
+
}
|
|
23
30
|
});
|
|
24
31
|
const getSuperOETHApy = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
body: JSON.stringify({
|
|
31
|
-
query: '\n query OTokenApy($chainId: Int!, $token: String!) {\n oTokenApies(\n limit: 1\n orderBy: timestamp_DESC\n where: {chainId_eq: $chainId, otoken_containsInsensitive: $token}\n ) {\n apy7DayAvg\n apy14DayAvg\n apy30DayAvg\n apr\n apy\n }\n}\n ',
|
|
32
|
-
variables: {
|
|
33
|
-
token: '0xdbfefd2e8460a6ee4955a68582f85708baea60a3',
|
|
34
|
-
chainId: 8453,
|
|
32
|
+
try {
|
|
33
|
+
const res = yield fetch('https://origin.squids.live/origin-squid/graphql', {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
headers: {
|
|
36
|
+
'Content-Type': 'application/json',
|
|
35
37
|
},
|
|
36
|
-
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
body: JSON.stringify({
|
|
39
|
+
query: '\n query OTokenApy($chainId: Int!, $token: String!) {\n oTokenApies(\n limit: 1\n orderBy: timestamp_DESC\n where: {chainId_eq: $chainId, otoken_containsInsensitive: $token}\n ) {\n apy7DayAvg\n apy14DayAvg\n apy30DayAvg\n apr\n apy\n }\n}\n ',
|
|
40
|
+
variables: {
|
|
41
|
+
token: '0xdbfefd2e8460a6ee4955a68582f85708baea60a3',
|
|
42
|
+
chainId: 8453,
|
|
43
|
+
},
|
|
44
|
+
}),
|
|
45
|
+
signal: AbortSignal.timeout(utils_1.DEFAULT_TIMEOUT),
|
|
46
|
+
});
|
|
47
|
+
const data = yield res.json();
|
|
48
|
+
return new decimal_js_1.default(data.data.oTokenApies[0].apy).mul(100).toString();
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
console.error('External API Failure: Failed to fetch Super OETH APY from external API', e);
|
|
52
|
+
return '0';
|
|
53
|
+
}
|
|
40
54
|
});
|
|
41
55
|
const getApyFromDfsApi = (asset) => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
56
|
+
try {
|
|
57
|
+
const res = yield fetch(`https://fe.defisaver.com/api/staking/apy?asset=${asset}`, { signal: AbortSignal.timeout(utils_1.DEFAULT_TIMEOUT) });
|
|
58
|
+
if (!res.ok)
|
|
59
|
+
throw new Error(`Failed to fetch APY for ${asset}`);
|
|
60
|
+
const data = yield res.json();
|
|
61
|
+
return String(data.apy);
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
console.error(`External API Failure: Failed to fetch APY for ${asset} from DFS API`, e);
|
|
65
|
+
return '0';
|
|
66
|
+
}
|
|
47
67
|
});
|
|
48
|
-
exports.STAKING_ASSETS = ['cbETH', 'wstETH', 'cbETH', 'rETH', 'sDAI', 'weETH', 'sUSDe', 'osETH', 'ezETH', 'ETHx', 'rsETH', 'pufETH', 'wrsETH', 'wsuperOETHb', 'sUSDS', '
|
|
68
|
+
exports.STAKING_ASSETS = ['cbETH', 'wstETH', 'cbETH', 'rETH', 'sDAI', 'weETH', 'sUSDe', 'osETH', 'ezETH', 'ETHx', 'rsETH', 'pufETH', 'wrsETH', 'wsuperOETHb', 'sUSDS', 'tETH', 'PT sUSDe Sep', 'PT USDe Sep'];
|
|
49
69
|
exports.getStakingApy = (0, memoizee_1.default)((asset) => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
70
|
try {
|
|
51
71
|
if (asset === 'stETH' || asset === 'wstETH')
|
package/cjs/types/compound.d.ts
CHANGED
|
@@ -50,7 +50,9 @@ export interface CompoundV2AssetData extends CompoundAssetData {
|
|
|
50
50
|
export interface CompoundV3AssetData extends CompoundAssetData {
|
|
51
51
|
borrowCollateralFactor: string;
|
|
52
52
|
liquidateCollateralFactor: string;
|
|
53
|
+
liquidationFactor: string;
|
|
53
54
|
minDebt: string;
|
|
55
|
+
supplyReserved: string;
|
|
54
56
|
liquidationRatio: string;
|
|
55
57
|
supplyCap: string;
|
|
56
58
|
priceInBaseAsset: string;
|