@strkfarm/sdk 1.1.28 → 1.1.31
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/dist/index.browser.global.js +255 -45
- package/dist/index.browser.mjs +255 -45
- package/dist/index.d.ts +32 -4
- package/dist/index.js +263 -51
- package/dist/index.mjs +261 -51
- package/package.json +1 -1
- package/src/strategies/universal-adapters/adapter-utils.ts +2 -0
- package/src/strategies/universal-adapters/common-adapter.ts +6 -6
- package/src/strategies/universal-adapters/vesu-adapter.ts +29 -21
- package/src/strategies/universal-lst-muliplier-strategy.tsx +263 -17
- package/src/strategies/universal-strategy.tsx +13 -2
|
@@ -3,10 +3,10 @@ import { AUMTypes, getContractDetails, UNIVERSAL_ADAPTERS, UNIVERSAL_MANAGE_IDS,
|
|
|
3
3
|
import { PricerBase } from "@/modules/pricerBase";
|
|
4
4
|
import { ContractAddr, Web3Number } from "@/dataTypes";
|
|
5
5
|
import { Global } from "@/global";
|
|
6
|
-
import { ApproveCallParams, CommonAdapter, getVesuSingletonAddress, ManageCall, Swap, VesuAdapter, VesuModifyDelegationCallParams, VesuMultiplyCallParams, VesuPools } from "./universal-adapters";
|
|
7
|
-
import {
|
|
6
|
+
import { ApproveCallParams, AvnuSwapCallParams, CommonAdapter, getVesuSingletonAddress, ManageCall, Swap, VesuAdapter, VesuModifyDelegationCallParams, VesuModifyPositionCallParams, VesuMultiplyCallParams, VesuPools } from "./universal-adapters";
|
|
7
|
+
import { AVNU_EXCHANGE } from "./universal-adapters/adapter-utils";
|
|
8
8
|
import { DepegRiskLevel, LiquidationRiskLevel, SmartContractRiskLevel, TechnicalRiskLevel } from "@/interfaces/risks";
|
|
9
|
-
import { EkuboQuoter, ERC20, LSTAPRService, PricerLST } from "@/modules";
|
|
9
|
+
import { AvnuWrapper, EkuboQuoter, ERC20, LSTAPRService, PricerLST } from "@/modules";
|
|
10
10
|
import { assert, logger } from "@/utils";
|
|
11
11
|
import { SingleTokenInfo } from "./base-strategy";
|
|
12
12
|
import { Call, Contract, uint256 } from "starknet";
|
|
@@ -76,6 +76,209 @@ export class UniversalLstMultiplierStrategy extends UniversalStrategy<UniversalS
|
|
|
76
76
|
return price;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
|
|
80
|
+
async getAvnuSwapMultiplyCall(params: {
|
|
81
|
+
isDeposit: boolean,
|
|
82
|
+
leg1DepositAmount: Web3Number
|
|
83
|
+
}) {
|
|
84
|
+
// TODO use a varibale for 1.02
|
|
85
|
+
return this._getAvnuDepositSwapLegCall({
|
|
86
|
+
...params,
|
|
87
|
+
minHF: 1.02
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private async _getAvnuDepositSwapLegCall(params: {
|
|
92
|
+
isDeposit: boolean,
|
|
93
|
+
leg1DepositAmount: Web3Number,
|
|
94
|
+
minHF: number // e.g. 1.01
|
|
95
|
+
}) {
|
|
96
|
+
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall params: ${JSON.stringify(params)}`);
|
|
97
|
+
assert(params.isDeposit, 'Only deposit is supported in _getAvnuDepositSwapLegCall')
|
|
98
|
+
// add collateral
|
|
99
|
+
// borrow STRK (e.g.)
|
|
100
|
+
// approve and swap strk
|
|
101
|
+
// add collateral again
|
|
102
|
+
|
|
103
|
+
const [vesuAdapter1] = this.getVesuAdapters();
|
|
104
|
+
const legLTV = await vesuAdapter1.getLTVConfig(this.config);
|
|
105
|
+
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall legLTV: ${legLTV}`);
|
|
106
|
+
const existingPositions = await vesuAdapter1.getPositions(this.config);
|
|
107
|
+
const collateralisation = await vesuAdapter1.getCollateralization(this.config);
|
|
108
|
+
const existingCollateralInfo = existingPositions[0];
|
|
109
|
+
const existingDebtInfo = existingPositions[1];
|
|
110
|
+
logger.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
|
|
111
|
+
existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
|
|
112
|
+
|
|
113
|
+
// - Prices as seen by Vesu contracts, ideal for HF math
|
|
114
|
+
// Price 1 is ok as fallback bcz that would relatively price the
|
|
115
|
+
// collateral and debt as equal.
|
|
116
|
+
const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
|
|
117
|
+
const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
|
|
118
|
+
logger.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
const totalCollateral = existingCollateralInfo.amount.plus(params.leg1DepositAmount);
|
|
122
|
+
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalCollateral: ${totalCollateral}`);
|
|
123
|
+
const totalDebtAmount = totalCollateral.multipliedBy(collateralPrice).multipliedBy(legLTV).dividedBy(debtPrice).dividedBy(params.minHF);
|
|
124
|
+
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalDebtAmount: ${totalDebtAmount}`);
|
|
125
|
+
const debtAmount = totalDebtAmount.minus(existingDebtInfo.amount);
|
|
126
|
+
if (debtAmount.lt(0)) {
|
|
127
|
+
// this is to unwind the position to optimal HF.
|
|
128
|
+
const lstDEXPrice = await this.getLSTDexPrice();
|
|
129
|
+
const debtAmountInLST = debtAmount.abs().dividedBy(lstDEXPrice);
|
|
130
|
+
const calls = await this.getVesuMultiplyCall({
|
|
131
|
+
isDeposit: false,
|
|
132
|
+
leg1DepositAmount: debtAmountInLST
|
|
133
|
+
})
|
|
134
|
+
assert(calls.length == 1, 'Expected 1 call for unwind');
|
|
135
|
+
return calls[0];
|
|
136
|
+
}
|
|
137
|
+
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall debtAmount: ${debtAmount}`);
|
|
138
|
+
const STEP0 = UNIVERSAL_MANAGE_IDS.APPROVE_TOKEN1;
|
|
139
|
+
const manage0Info = this.getProofs<ApproveCallParams>(STEP0);
|
|
140
|
+
const manageCall0 = manage0Info.callConstructor({
|
|
141
|
+
amount: params.leg1DepositAmount
|
|
142
|
+
});
|
|
143
|
+
const STEP1 = UNIVERSAL_MANAGE_IDS.VESU_LEG1;
|
|
144
|
+
const manage1Info = this.getProofs<VesuModifyPositionCallParams>(STEP1);
|
|
145
|
+
const manageCall1 = manage1Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
|
|
146
|
+
collateralAmount: params.leg1DepositAmount,
|
|
147
|
+
isAddCollateral: params.isDeposit,
|
|
148
|
+
debtAmount: debtAmount,
|
|
149
|
+
isBorrow: params.isDeposit
|
|
150
|
+
}));
|
|
151
|
+
|
|
152
|
+
const proofIds: string[] = [STEP0, STEP1];
|
|
153
|
+
const manageCalls: ManageCall[] = [manageCall0, manageCall1];
|
|
154
|
+
|
|
155
|
+
// approve and swap to LST using avnu
|
|
156
|
+
// todo add non-zero check
|
|
157
|
+
if (debtAmount.gt(0)) {
|
|
158
|
+
const STEP2 = LST_MULTIPLIER_MANAGE_IDS.AVNU_MULTIPLY_APPROVE_DEPOSIT;
|
|
159
|
+
const manage2Info = this.getProofs<ApproveCallParams>(STEP2);
|
|
160
|
+
const manageCall2 = manage2Info.callConstructor({
|
|
161
|
+
amount: debtAmount
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
const debtTokenInfo = vesuAdapter1.config.debt;
|
|
165
|
+
const lstTokenInfo = this.asset();
|
|
166
|
+
const avnuModule = new AvnuWrapper();
|
|
167
|
+
const quote = await avnuModule.getQuotes(
|
|
168
|
+
debtTokenInfo.address.address,
|
|
169
|
+
lstTokenInfo.address.address,
|
|
170
|
+
debtAmount.toWei(),
|
|
171
|
+
this.metadata.additionalInfo.vaultAllocator.address
|
|
172
|
+
);
|
|
173
|
+
const minAmount = await this._getMinOutputAmountLSTBuy(debtAmount);
|
|
174
|
+
const minAmountWei = (minAmount).toWei();
|
|
175
|
+
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall minAmount: ${minAmount}`);
|
|
176
|
+
const swapInfo = await avnuModule.getSwapInfo(
|
|
177
|
+
quote,
|
|
178
|
+
this.metadata.additionalInfo.vaultAllocator.address,
|
|
179
|
+
0,
|
|
180
|
+
this.address.address,
|
|
181
|
+
minAmountWei
|
|
182
|
+
);
|
|
183
|
+
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall swapInfo: ${JSON.stringify(swapInfo)}`);
|
|
184
|
+
const STEP3 = LST_MULTIPLIER_MANAGE_IDS.AVNU_MULTIPLY_SWAP_DEPOSIT;
|
|
185
|
+
const manage3Info = this.getProofs<AvnuSwapCallParams>(STEP3);
|
|
186
|
+
const manageCall3 = manage3Info.callConstructor({
|
|
187
|
+
props: swapInfo
|
|
188
|
+
});
|
|
189
|
+
proofIds.push(STEP2);
|
|
190
|
+
proofIds.push(STEP3);
|
|
191
|
+
manageCalls.push(manageCall2, manageCall3);
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
// if the created debt, when added is collateral will put the total HF above min, but below (target + 0.05),
|
|
195
|
+
// then lets close the looping cycle by adding this as collateral.
|
|
196
|
+
const newCollateral = minAmount.plus(totalCollateral);
|
|
197
|
+
const newHF = newCollateral.multipliedBy(collateralPrice).multipliedBy(legLTV).dividedBy(totalDebtAmount).dividedBy(debtPrice).toNumber();
|
|
198
|
+
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall newHF: ${newHF}`);
|
|
199
|
+
if (newHF > this.metadata.additionalInfo.minHealthFactor && newHF < this.metadata.additionalInfo.targetHealthFactor + 0.05) {
|
|
200
|
+
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall newHF is above min and below target + 0.05, adding collateral on vesu`);
|
|
201
|
+
// approve and add collateral on vesu (modify position)
|
|
202
|
+
const STEP4 = UNIVERSAL_MANAGE_IDS.APPROVE_TOKEN1;
|
|
203
|
+
const manage4Info = this.getProofs<ApproveCallParams>(STEP4);
|
|
204
|
+
const manageCall4 = manage4Info.callConstructor({
|
|
205
|
+
amount: minAmount
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
const STEP5 = UNIVERSAL_MANAGE_IDS.VESU_LEG1;
|
|
209
|
+
const manage5Info = this.getProofs<VesuModifyPositionCallParams>(STEP5);
|
|
210
|
+
const manageCall5 = manage5Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
|
|
211
|
+
collateralAmount: minAmount,
|
|
212
|
+
isAddCollateral: true,
|
|
213
|
+
debtAmount: Web3Number.fromWei('0', this.asset().decimals),
|
|
214
|
+
isBorrow: params.isDeposit
|
|
215
|
+
}));
|
|
216
|
+
proofIds.push(STEP4, STEP5);
|
|
217
|
+
manageCalls.push(manageCall4, manageCall5);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const manageCall = this.getManageCall(proofIds, manageCalls);
|
|
222
|
+
return manageCall;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// todo unwind or not deposit when the yield is bad.
|
|
226
|
+
|
|
227
|
+
async getLSTMultiplierRebalanceCall(): Promise<{ shouldRebalance: boolean, manageCall: Call | undefined }> {
|
|
228
|
+
const positions = await this.getVaultPositions();
|
|
229
|
+
assert(positions.length == 3, 'Rebalance call is only supported for 3 positions');
|
|
230
|
+
const existingCollateralInfo = positions[0];
|
|
231
|
+
const existingDebtInfo = positions[1];
|
|
232
|
+
const unusedBalance = positions[2];
|
|
233
|
+
const [healthFactor] = await this.getVesuHealthFactors();
|
|
234
|
+
|
|
235
|
+
const [vesuAdapter1] = this.getVesuAdapters();
|
|
236
|
+
const legLTV = await vesuAdapter1.getLTVConfig(this.config);
|
|
237
|
+
const collateralisation = await vesuAdapter1.getCollateralization(this.config);
|
|
238
|
+
logger.debug(`${this.getTag()}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
|
|
239
|
+
existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
|
|
240
|
+
|
|
241
|
+
// - Prices as seen by Vesu contracts, ideal for HF math
|
|
242
|
+
// Price 1 is ok as fallback bcz that would relatively price the
|
|
243
|
+
// collateral and debt as equal.
|
|
244
|
+
const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
|
|
245
|
+
const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
|
|
246
|
+
logger.debug(`${this.getTag()}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
|
|
247
|
+
|
|
248
|
+
const isHFTooLow = healthFactor < this.metadata.additionalInfo.minHealthFactor;
|
|
249
|
+
const isHFTooHigh = healthFactor > this.metadata.additionalInfo.targetHealthFactor + 0.05;
|
|
250
|
+
if (isHFTooLow || isHFTooHigh) {
|
|
251
|
+
// use unused collateral to target more.
|
|
252
|
+
const manageCall = await this._getAvnuDepositSwapLegCall({
|
|
253
|
+
isDeposit: true,
|
|
254
|
+
leg1DepositAmount: unusedBalance.amount,
|
|
255
|
+
minHF: 1.02 // todo, shouldnt use this 1.02 HF, if there isn;t more looping left.
|
|
256
|
+
})
|
|
257
|
+
return { shouldRebalance: true, manageCall };
|
|
258
|
+
} else {
|
|
259
|
+
// do nothing
|
|
260
|
+
return { shouldRebalance: false, manageCall: undefined };
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
//
|
|
265
|
+
private async _getMinOutputAmountLSTBuy(amountInUnderlying: Web3Number) {
|
|
266
|
+
const lstTruePrice = await this.getLSTExchangeRate();
|
|
267
|
+
// during buy, the purchase should always be <= true LST price.
|
|
268
|
+
const minOutputAmount = amountInUnderlying.dividedBy(lstTruePrice);
|
|
269
|
+
return minOutputAmount;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
private async _getMinOutputAmountLSTSell(amountInLST: Web3Number) {
|
|
273
|
+
const lstTruePrice = await this.getLSTExchangeRate();
|
|
274
|
+
// during sell, the purchase should always be > 0.995 * true LST price.
|
|
275
|
+
const minOutputAmount = amountInLST.multipliedBy(lstTruePrice).multipliedBy(0.995);
|
|
276
|
+
return minOutputAmount;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// todo add a function to findout max borrowable amount without fucking yield
|
|
280
|
+
// if the current net yield < LST yield, add a function to calculate how much to unwind.
|
|
281
|
+
|
|
79
282
|
/**
|
|
80
283
|
* Uses vesu's multiple call to create leverage on LST
|
|
81
284
|
* Deposit amount is in LST
|
|
@@ -158,13 +361,42 @@ export class UniversalLstMultiplierStrategy extends UniversalStrategy<UniversalS
|
|
|
158
361
|
async getLSTAPR(_address: ContractAddr): Promise<number> {
|
|
159
362
|
try {
|
|
160
363
|
const vesuAdapter1 = this.getVesuAdapters()[0];
|
|
161
|
-
|
|
364
|
+
const apr = await LSTAPRService.getLSTAPR(vesuAdapter1.config.debt.address);
|
|
365
|
+
if (!apr) {
|
|
366
|
+
throw new Error('Failed to get LST APR');
|
|
367
|
+
}
|
|
368
|
+
return apr;
|
|
162
369
|
} catch (error) {
|
|
163
370
|
logger.warn(`${this.getTag()}: Failed to get LST APR: ${error}`);
|
|
164
371
|
return 0;
|
|
165
372
|
}
|
|
166
373
|
}
|
|
167
374
|
|
|
375
|
+
// todo undo this
|
|
376
|
+
async netAPY(): Promise<{ net: number; splits: { apy: number; id: string; }[]; }> {
|
|
377
|
+
const { net, splits } = await super.netAPY();
|
|
378
|
+
let _net = net;
|
|
379
|
+
if (this.asset().symbol == 'xWBTC') {
|
|
380
|
+
const debtToken = this.getVesuAdapters()[0].config.debt;
|
|
381
|
+
const lstAPY = await this.getLSTAPR(debtToken.address);
|
|
382
|
+
_net = lstAPY * 5;
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
net: _net,
|
|
386
|
+
splits: splits
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
protected async getUnusedBalanceAPY() {
|
|
391
|
+
const unusedBalance = await this.getUnusedBalance();
|
|
392
|
+
const vesuAdapter = this.getVesuAdapters()[0];
|
|
393
|
+
const underlying = vesuAdapter.config.debt;
|
|
394
|
+
const lstAPY = await this.getLSTAPR(underlying.address);
|
|
395
|
+
return {
|
|
396
|
+
apy: lstAPY, weight: unusedBalance.usdValue
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
168
400
|
async getLSTExchangeRate() {
|
|
169
401
|
const [vesuAdapter1] = this.getVesuAdapters();
|
|
170
402
|
const lstTokenInfo = vesuAdapter1.config.collateral;
|
|
@@ -209,7 +441,7 @@ export class UniversalLstMultiplierStrategy extends UniversalStrategy<UniversalS
|
|
|
209
441
|
|
|
210
442
|
// approve token
|
|
211
443
|
if (params.marginAmount.greaterThan(0)) {
|
|
212
|
-
const STEP1_ID =
|
|
444
|
+
const STEP1_ID = LST_MULTIPLIER_MANAGE_IDS.MULTIPLE_APPROVE;
|
|
213
445
|
const manage1Info = this.getProofs<ApproveCallParams>(STEP1_ID);
|
|
214
446
|
const depositAmount = params.marginAmount;
|
|
215
447
|
const manageCall1 = manage1Info.callConstructor({
|
|
@@ -349,9 +581,14 @@ function getDescription(tokenSymbol: string, underlyingSymbol: string) {
|
|
|
349
581
|
}
|
|
350
582
|
|
|
351
583
|
enum LST_MULTIPLIER_MANAGE_IDS {
|
|
584
|
+
MULTIPLE_APPROVE = 'multiple_approve',
|
|
352
585
|
MULTIPLY_VESU = 'multiply_vesu',
|
|
353
586
|
SWITCH_DELEGATION_ON = 'switch_delegation_on',
|
|
354
|
-
SWITCH_DELEGATION_OFF = 'switch_delegation_off'
|
|
587
|
+
SWITCH_DELEGATION_OFF = 'switch_delegation_off',
|
|
588
|
+
AVNU_MULTIPLY_APPROVE_DEPOSIT = 'avnu_multiply_approve_deposit',
|
|
589
|
+
AVNU_MULTIPLY_SWAP_DEPOSIT = 'avnu_multiply_swap_deposit',
|
|
590
|
+
AVNU_MULTIPLY_APPROVE_WITHDRAW = 'avnu_multiply_approve_withdraw',
|
|
591
|
+
AVNU_MULTIPLY_SWAP_WITHDRAW = 'avnu_multiply_swap_withdraw',
|
|
355
592
|
}
|
|
356
593
|
|
|
357
594
|
function getLooperSettings(
|
|
@@ -370,7 +607,7 @@ function getLooperSettings(
|
|
|
370
607
|
collateral: lstToken,
|
|
371
608
|
debt: underlyingToken,
|
|
372
609
|
vaultAllocator: vaultSettings.vaultAllocator,
|
|
373
|
-
id:
|
|
610
|
+
id: UNIVERSAL_MANAGE_IDS.VESU_LEG1
|
|
374
611
|
})
|
|
375
612
|
|
|
376
613
|
const commonAdapter = new CommonAdapter({
|
|
@@ -382,10 +619,10 @@ function getLooperSettings(
|
|
|
382
619
|
})
|
|
383
620
|
|
|
384
621
|
// vesu looping
|
|
385
|
-
const { isV2 } = getVesuSingletonAddress(pool1);
|
|
622
|
+
const { isV2, addr:poolAddr } = getVesuSingletonAddress(pool1);
|
|
386
623
|
const VESU_MULTIPLY = isV2 ? vesuAdapterLST.VESU_MULTIPLY : vesuAdapterLST.VESU_MULTIPLY_V1;
|
|
387
|
-
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, VESU_MULTIPLY,
|
|
388
|
-
vaultSettings.leafAdapters.push(vesuAdapterLST.getMultiplyAdapter.bind(vesuAdapterLST));
|
|
624
|
+
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, VESU_MULTIPLY, LST_MULTIPLIER_MANAGE_IDS.MULTIPLE_APPROVE).bind(commonAdapter));
|
|
625
|
+
vaultSettings.leafAdapters.push(vesuAdapterLST.getMultiplyAdapter(LST_MULTIPLIER_MANAGE_IDS.MULTIPLY_VESU).bind(vesuAdapterLST));
|
|
389
626
|
vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter(LST_MULTIPLIER_MANAGE_IDS.SWITCH_DELEGATION_ON).bind(vesuAdapterLST));
|
|
390
627
|
vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter(LST_MULTIPLIER_MANAGE_IDS.SWITCH_DELEGATION_OFF).bind(vesuAdapterLST));
|
|
391
628
|
|
|
@@ -399,6 +636,15 @@ function getLooperSettings(
|
|
|
399
636
|
adapter: commonAdapter
|
|
400
637
|
}])
|
|
401
638
|
|
|
639
|
+
// avnu multiply
|
|
640
|
+
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(underlyingToken.address, AVNU_EXCHANGE, LST_MULTIPLIER_MANAGE_IDS.AVNU_MULTIPLY_APPROVE_DEPOSIT).bind(commonAdapter));
|
|
641
|
+
vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(underlyingToken.address, lstToken.address, LST_MULTIPLIER_MANAGE_IDS.AVNU_MULTIPLY_SWAP_DEPOSIT, false).bind(commonAdapter));
|
|
642
|
+
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, AVNU_EXCHANGE, LST_MULTIPLIER_MANAGE_IDS.AVNU_MULTIPLY_APPROVE_WITHDRAW).bind(commonAdapter));
|
|
643
|
+
vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(lstToken.address, underlyingToken.address, LST_MULTIPLIER_MANAGE_IDS.AVNU_MULTIPLY_SWAP_WITHDRAW, false).bind(commonAdapter));
|
|
644
|
+
// approve LST to add collateral
|
|
645
|
+
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, poolAddr, UNIVERSAL_MANAGE_IDS.APPROVE_TOKEN1).bind(commonAdapter));
|
|
646
|
+
vaultSettings.leafAdapters.push(vesuAdapterLST.getModifyPosition.bind(vesuAdapterLST));
|
|
647
|
+
|
|
402
648
|
// to bridge liquidity back to vault (used by bring_liquidity)
|
|
403
649
|
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, vaultSettings.vaultAddress, UNIVERSAL_MANAGE_IDS.APPROVE_BRING_LIQUIDITY).bind(commonAdapter));
|
|
404
650
|
vaultSettings.leafAdapters.push(commonAdapter.getBringLiquidityAdapter(UNIVERSAL_MANAGE_IDS.BRING_LIQUIDITY).bind(commonAdapter));
|
|
@@ -408,8 +654,8 @@ function getLooperSettings(
|
|
|
408
654
|
|
|
409
655
|
// avnu swap for claims rewards
|
|
410
656
|
const STRKToken = Global.getDefaultTokens().find(token => token.symbol === 'STRK')!;
|
|
411
|
-
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(STRKToken.address,
|
|
412
|
-
vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(STRKToken.address, lstToken.address, UNIVERSAL_MANAGE_IDS.AVNU_SWAP_REWARDS).bind(commonAdapter));
|
|
657
|
+
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(STRKToken.address, AVNU_EXCHANGE, UNIVERSAL_MANAGE_IDS.APPROVE_SWAP_TOKEN1).bind(commonAdapter));
|
|
658
|
+
vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(STRKToken.address, lstToken.address, UNIVERSAL_MANAGE_IDS.AVNU_SWAP_REWARDS, false).bind(commonAdapter));
|
|
413
659
|
return vaultSettings;
|
|
414
660
|
}
|
|
415
661
|
|
|
@@ -523,11 +769,11 @@ const hyperxsBTC: UniversalStrategySettings = {
|
|
|
523
769
|
}
|
|
524
770
|
|
|
525
771
|
const hyperxLBTC: UniversalStrategySettings = {
|
|
526
|
-
vaultAddress: ContractAddr.from('
|
|
527
|
-
manager: ContractAddr.from('
|
|
528
|
-
vaultAllocator: ContractAddr.from('
|
|
529
|
-
redeemRequestNFT: ContractAddr.from('
|
|
530
|
-
aumOracle: ContractAddr.from('
|
|
772
|
+
vaultAddress: ContractAddr.from('0x64cf24d4883fe569926419a0569ab34497c6956a1a308fa883257f7486d7030'),
|
|
773
|
+
manager: ContractAddr.from('0x203530a4022a99b8f4b406aaf33b0849d43ad7422c1d5cc14ff8c667abec6c0'),
|
|
774
|
+
vaultAllocator: ContractAddr.from('0x7dbc8ccd4eabce6ea6c19e0e5c9ccca3a93bd510303b9e071cbe25fc508546e'),
|
|
775
|
+
redeemRequestNFT: ContractAddr.from('0x5ee66a39af9aef3d0d48982b4a63e8bd2a5bad021916bd87fb0eae3a26800b8'),
|
|
776
|
+
aumOracle: ContractAddr.from('0x23d69e4391fa72d10e625e7575d8bddbb4aff96f04503f83fdde23123bf41d0'),
|
|
531
777
|
leafAdapters: [],
|
|
532
778
|
adapters: [],
|
|
533
779
|
targetHealthFactor: 1.1,
|
|
@@ -9,7 +9,7 @@ import UniversalVaultAbi from '../data/universal-vault.abi.json';
|
|
|
9
9
|
import ManagerAbi from '../data/vault-manager.abi.json';
|
|
10
10
|
import { ApproveCallParams, AvnuSwapCallParams, BaseAdapter, CommonAdapter, FlashloanCallParams, GenerateCallFn, LeafAdapterFn, ManageCall, VesuAdapter, VesuDefiSpringRewardsCallParams, VesuModifyPositionCallParams, VesuPools } from "./universal-adapters";
|
|
11
11
|
import { Global } from "@/global";
|
|
12
|
-
import { AvnuWrapper, ERC20
|
|
12
|
+
import { AvnuWrapper, ERC20 } from "@/modules";
|
|
13
13
|
import { AVNU_MIDDLEWARE, VESU_SINGLETON } from "./universal-adapters/adapter-utils";
|
|
14
14
|
import { VesuHarvests } from "@/modules/harvests";
|
|
15
15
|
|
|
@@ -257,8 +257,13 @@ export class UniversalStrategy<
|
|
|
257
257
|
}]};
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
+
const unusedBalanceAPY = await this.getUnusedBalanceAPY();
|
|
261
|
+
baseAPYs.push(...[unusedBalanceAPY.apy]);
|
|
262
|
+
rewardAPYs.push(0);
|
|
263
|
+
|
|
260
264
|
// Compute APy using weights
|
|
261
265
|
const weights = positions.map((p, index) => p.usdValue * (index % 2 == 0 ? 1 : -1));
|
|
266
|
+
weights.push(unusedBalanceAPY.weight);
|
|
262
267
|
const price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
|
|
263
268
|
const prevAUMUSD = prevAUM.multipliedBy(price.price);
|
|
264
269
|
const baseAPY = this.computeAPY(baseAPYs, weights, prevAUMUSD);
|
|
@@ -272,6 +277,12 @@ export class UniversalStrategy<
|
|
|
272
277
|
}] };
|
|
273
278
|
}
|
|
274
279
|
|
|
280
|
+
protected async getUnusedBalanceAPY() {
|
|
281
|
+
return {
|
|
282
|
+
apy: 0, weight: 0
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
275
286
|
private computeAPY(apys: number[], weights: number[], currentAUM: Web3Number) {
|
|
276
287
|
assert(apys.length === weights.length, "APYs and weights length mismatch");
|
|
277
288
|
const weightedSum = apys.reduce((acc, apy, i) => acc + apy * weights[i], 0);
|
|
@@ -875,7 +886,7 @@ function getLooperSettings(
|
|
|
875
886
|
// avnu swap
|
|
876
887
|
const STRKToken = Global.getDefaultTokens().find(token => token.symbol === 'STRK')!;
|
|
877
888
|
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(STRKToken.address, AVNU_MIDDLEWARE, UNIVERSAL_MANAGE_IDS.APPROVE_SWAP_TOKEN1).bind(commonAdapter));
|
|
878
|
-
vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(STRKToken.address, USDCToken.address, UNIVERSAL_MANAGE_IDS.AVNU_SWAP_REWARDS).bind(commonAdapter));
|
|
889
|
+
vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(STRKToken.address, USDCToken.address, UNIVERSAL_MANAGE_IDS.AVNU_SWAP_REWARDS, true).bind(commonAdapter));
|
|
879
890
|
return vaultSettings;
|
|
880
891
|
}
|
|
881
892
|
|