@strkfarm/sdk 2.0.0-dev.17 → 2.0.0-dev.18
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 +223 -80
- package/dist/index.browser.mjs +149 -6
- package/dist/index.d.ts +15 -0
- package/dist/index.js +149 -6
- package/dist/index.mjs +149 -6
- package/package.json +1 -1
- package/src/strategies/universal-adapters/avnu-adapter.ts +1 -1
- package/src/strategies/universal-adapters/extended-adapter.ts +2 -2
- package/src/strategies/vesu-extended-strategy/utils/constants.ts +1 -5
- package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +184 -33
|
@@ -54,7 +54,7 @@ import {
|
|
|
54
54
|
} from "./utils/helper";
|
|
55
55
|
import { SingleTokenInfo } from "../base-strategy";
|
|
56
56
|
import { Call } from "starknet";
|
|
57
|
-
import { PositionTypeAvnuExtended} from "../universal-strategy";
|
|
57
|
+
import { PositionTypeAvnuExtended } from "../universal-strategy";
|
|
58
58
|
import { TransactionMetadata, TransactionResult } from "./types/transaction-metadata";
|
|
59
59
|
|
|
60
60
|
|
|
@@ -67,6 +67,7 @@ export interface VesuExtendedStrategySettings
|
|
|
67
67
|
minHealthFactor: number;
|
|
68
68
|
aumOracle: ContractAddr;
|
|
69
69
|
minimumWBTCDifferenceForAvnuSwap: number;
|
|
70
|
+
walletAddress: string;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
export class VesuExtendedMultiplierStrategy<
|
|
@@ -182,7 +183,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
182
183
|
}
|
|
183
184
|
|
|
184
185
|
async moveAssetsToVaultAllocator(amount: Web3Number, extendedAdapter: ExtendedAdapter): Promise<{
|
|
185
|
-
calls:Call[],
|
|
186
|
+
calls: Call[],
|
|
186
187
|
status: boolean,
|
|
187
188
|
}> {
|
|
188
189
|
try {
|
|
@@ -234,7 +235,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
234
235
|
const vesuAdapter = await this.getVesuAdapter();
|
|
235
236
|
const extendedAdapter = await this.getExtendedAdapter();
|
|
236
237
|
logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest adapters fetched: vesuAdapter=${!!vesuAdapter}, extendedAdapter=${!!extendedAdapter}, extendedAdapter.client=${!!extendedAdapter?.client}`);
|
|
237
|
-
|
|
238
|
+
|
|
238
239
|
if (!vesuAdapter) {
|
|
239
240
|
logger.error(
|
|
240
241
|
`Vesu adapter not configured in metadata. This is a configuration issue, not a temporary failure.`
|
|
@@ -277,10 +278,10 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
277
278
|
vesuLeverage: 0,
|
|
278
279
|
};
|
|
279
280
|
}
|
|
280
|
-
|
|
281
|
+
|
|
281
282
|
logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest calling getUnusedBalance`);
|
|
282
283
|
const balance = await this.getUnusedBalance();
|
|
283
|
-
|
|
284
|
+
|
|
284
285
|
if (!Number.isFinite(balance.usdValue) || balance.usdValue < 0) {
|
|
285
286
|
logger.error(
|
|
286
287
|
`Invalid balance.usdValue: ${balance.usdValue}. Expected a finite, non-negative number.`
|
|
@@ -297,7 +298,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
297
298
|
}
|
|
298
299
|
logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest balance: ${balance.usdValue}`);
|
|
299
300
|
const usdcBalanceOnExtended = await extendedAdapter.getExtendedDepositAmount();
|
|
300
|
-
|
|
301
|
+
|
|
301
302
|
if (usdcBalanceOnExtended) {
|
|
302
303
|
const availableForWithdrawal = parseFloat(usdcBalanceOnExtended.availableForWithdrawal);
|
|
303
304
|
if (!Number.isFinite(availableForWithdrawal) || availableForWithdrawal < 0) {
|
|
@@ -315,11 +316,11 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
315
316
|
};
|
|
316
317
|
}
|
|
317
318
|
}
|
|
318
|
-
|
|
319
|
+
|
|
319
320
|
/** The LIMIT_BALANCE is the bffer amount to keep in the investing Cycle */
|
|
320
321
|
const amountToInvest = new Web3Number(balance.usdValue, USDC_TOKEN_DECIMALS).plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).multipliedBy(1 - LIMIT_BALANCE);
|
|
321
322
|
|
|
322
|
-
|
|
323
|
+
|
|
323
324
|
const amountToInvestNumber = amountToInvest.toNumber();
|
|
324
325
|
if (!Number.isFinite(amountToInvestNumber)) {
|
|
325
326
|
logger.error(
|
|
@@ -335,7 +336,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
335
336
|
vesuLeverage: 0,
|
|
336
337
|
};
|
|
337
338
|
}
|
|
338
|
-
|
|
339
|
+
|
|
339
340
|
logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvestNumber}`);
|
|
340
341
|
if (amountToInvest.lessThan(LIMIT_BALANCE_VALUE)) {
|
|
341
342
|
return {
|
|
@@ -369,7 +370,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
369
370
|
collateralPrice,
|
|
370
371
|
debtPrice
|
|
371
372
|
} = await this.getAssetPrices();
|
|
372
|
-
|
|
373
|
+
|
|
373
374
|
|
|
374
375
|
if (!Number.isFinite(collateralPrice.price) || collateralPrice.price <= 0) {
|
|
375
376
|
logger.error(
|
|
@@ -399,7 +400,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
399
400
|
vesuLeverage: 0,
|
|
400
401
|
};
|
|
401
402
|
}
|
|
402
|
-
|
|
403
|
+
|
|
403
404
|
const { vesu_amount, extended_amount, extended_leverage, vesu_leverage } =
|
|
404
405
|
await calculateAmountDistribution(
|
|
405
406
|
amountToInvest.toNumber(),
|
|
@@ -482,35 +483,35 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
482
483
|
if (extendedAmount.isNegative() && extendedAmount.abs().greaterThan(extendedAdapter.minimumExtendedMovementAmount)) {
|
|
483
484
|
totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmount.abs());
|
|
484
485
|
}
|
|
485
|
-
|
|
486
|
+
|
|
486
487
|
// Calculate remaining Extended difference (target vs current)
|
|
487
488
|
// If extendedAmount was negative, we've already accounted for that withdrawal
|
|
488
489
|
// So we calculate based on what Extended will be after that withdrawal
|
|
489
490
|
const extendedTargetAmount = extendedAmount.abs(); // Use absolute value as target
|
|
490
491
|
let projectedExtendedBalance = usdcAmountOnExtendedAvailableForWithdrawal;
|
|
491
|
-
|
|
492
|
+
|
|
492
493
|
if (extendedAmount.isNegative()) {
|
|
493
494
|
projectedExtendedBalance = projectedExtendedBalance - extendedAmount.abs().toNumber();
|
|
494
495
|
}
|
|
495
|
-
|
|
496
|
+
|
|
496
497
|
const extendedAmountDifference = extendedTargetAmount.minus(projectedExtendedBalance);
|
|
497
498
|
const extendedAmountDifferenceAbs = extendedAmountDifference.abs();
|
|
498
|
-
|
|
499
|
+
|
|
499
500
|
// Track additional Extended movements
|
|
500
501
|
if (extendedAmountDifference.lessThan(0)) {
|
|
501
502
|
totalExtendedWithdrawal = totalExtendedWithdrawal.plus(extendedAmountDifferenceAbs);
|
|
502
503
|
} else if (extendedAmountDifference.greaterThan(0)) {
|
|
503
504
|
totalExtendedDeposit = totalExtendedDeposit.plus(extendedAmountDifference);
|
|
504
505
|
}
|
|
505
|
-
|
|
506
|
+
|
|
506
507
|
const vesuTargetAmount = vesuAmount.abs();
|
|
507
508
|
const projectedWalletBalance = usdcAmountInWallet
|
|
508
509
|
.plus(totalExtendedWithdrawal)
|
|
509
510
|
.minus(totalExtendedDeposit);
|
|
510
|
-
|
|
511
|
+
|
|
511
512
|
let vesuAmountDifference = vesuTargetAmount.minus(projectedWalletBalance);
|
|
512
513
|
const vesuAmountDifferenceAbs = vesuAmountDifference.abs();
|
|
513
|
-
|
|
514
|
+
|
|
514
515
|
logger.info(`${VesuExtendedMultiplierStrategy.name}::shouldMoveAssets calculated movements - Extended withdrawal: ${totalExtendedWithdrawal.toNumber()}, Extended deposit: ${totalExtendedDeposit.toNumber()}, Extended diff: ${extendedAmountDifference.toNumber()}, Projected wallet: ${projectedWalletBalance.toNumber()}, Vesu diff: ${vesuAmountDifference.toNumber()}`);
|
|
515
516
|
let calls: Call[] = [];
|
|
516
517
|
let transactionResults: TransactionResult[] = [];
|
|
@@ -634,7 +635,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
634
635
|
}
|
|
635
636
|
}
|
|
636
637
|
}
|
|
637
|
-
|
|
638
|
+
|
|
638
639
|
// Handle Vesu adjustments based on calculated difference (already adjusted for Extended movements)
|
|
639
640
|
if (vesuAmountDifferenceAbs.greaterThan(vesuAdapter.minimumVesuMovementAmount)) {
|
|
640
641
|
if (vesuAmountDifference.lessThanOrEqualTo(0)) {
|
|
@@ -672,7 +673,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
672
673
|
}
|
|
673
674
|
}
|
|
674
675
|
}
|
|
675
|
-
|
|
676
|
+
|
|
676
677
|
return transactionResults;
|
|
677
678
|
} catch (err) {
|
|
678
679
|
logger.error(`Failed moving assets to vesu: ${err}`);
|
|
@@ -808,10 +809,10 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
808
809
|
receivedTxnHash: withdrawalFromExtendedTxnHash,
|
|
809
810
|
} =
|
|
810
811
|
await extendedAdapter.withdrawFromExtended(params.amount);
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
812
|
+
/**
|
|
813
|
+
* This logic needs fixing
|
|
814
|
+
*/
|
|
815
|
+
logger.info(`withdrawalFromExtendedStatus: ${withdrawalFromExtendedStatus}, withdrawalFromExtendedTxnHash: ${withdrawalFromExtendedTxnHash}`);
|
|
815
816
|
if (withdrawalFromExtendedStatus && withdrawalFromExtendedTxnHash) {
|
|
816
817
|
/**
|
|
817
818
|
* We need to move assets from my wallet back to vault contract
|
|
@@ -819,10 +820,10 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
819
820
|
const extendedHoldings = await extendedAdapter.getExtendedDepositAmount();
|
|
820
821
|
logger.info(`extendedHoldings after withdrawal ${extendedHoldings?.availableForWithdrawal}`);
|
|
821
822
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
822
|
-
const {calls, status} = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
|
|
823
|
+
const { calls, status } = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
|
|
823
824
|
if (calls.length > 0 && status) {
|
|
824
825
|
return this.createTransactionResult(calls, true, params, "WITHDRAWAL", params.cycleType);
|
|
825
|
-
}else {
|
|
826
|
+
} else {
|
|
826
827
|
/**
|
|
827
828
|
* This is a fallback scenario, where the funds were withdrawn from extended, but didn't get transferred to the wallet
|
|
828
829
|
* We need to return a successful transaction result, but with no calls
|
|
@@ -830,7 +831,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
830
831
|
*/
|
|
831
832
|
return this.createTransactionResult([], true, params, "WITHDRAWAL", params.cycleType);
|
|
832
833
|
}
|
|
833
|
-
}else if(withdrawalFromExtendedStatus && !withdrawalFromExtendedTxnHash){
|
|
834
|
+
} else if (withdrawalFromExtendedStatus && !withdrawalFromExtendedTxnHash) {
|
|
834
835
|
logger.error("withdrawal from extended successful, but funds didn't get transferred to the wallet");
|
|
835
836
|
return this.createTransactionResult([], true, params, "WITHDRAWAL", params.cycleType);
|
|
836
837
|
} else {
|
|
@@ -906,7 +907,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
906
907
|
return this.createTransactionResult([], false, params, "NONE", params.cycleType);
|
|
907
908
|
} catch (err) {
|
|
908
909
|
logger.error(`error moving assets: ${err}`);
|
|
909
|
-
return this.createTransactionResult([], false, params,"NONE", params.cycleType);
|
|
910
|
+
return this.createTransactionResult([], false, params, "NONE", params.cycleType);
|
|
910
911
|
}
|
|
911
912
|
}
|
|
912
913
|
|
|
@@ -938,7 +939,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
938
939
|
const price = ask.plus(bid).dividedBy(2);
|
|
939
940
|
const btcToken = vesuAdapter.config.supportedPositions[0].asset;
|
|
940
941
|
const btcPriceAvnu = await avnuAdapter.getPriceOfToken(btcToken.address.toString());
|
|
941
|
-
|
|
942
|
+
|
|
942
943
|
if (!btcPriceAvnu) {
|
|
943
944
|
logger.error(`error getting btc price avnu: ${btcPriceAvnu}`);
|
|
944
945
|
return false;
|
|
@@ -947,15 +948,15 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
947
948
|
logger.info(`btcPriceAvnu: ${btcPriceAvnu}`);
|
|
948
949
|
const priceDifference = new Web3Number(price.minus(btcPriceAvnu).toFixed(2), 0);
|
|
949
950
|
logger.info(`priceDifference: ${priceDifference}`);
|
|
950
|
-
if(priceDifference.isNegative()){
|
|
951
|
+
if (priceDifference.isNegative()) {
|
|
951
952
|
return false;
|
|
952
953
|
}
|
|
953
|
-
if(positionType === PositionTypeAvnuExtended.OPEN){
|
|
954
|
+
if (positionType === PositionTypeAvnuExtended.OPEN) {
|
|
954
955
|
logger.info(`price difference between avnu and extended for open position: ${priceDifference.toNumber()}, minimumExtendedPriceDifferenceForSwapOpen: ${avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen}`);
|
|
955
956
|
const result = priceDifference.greaterThanOrEqualTo(avnuAdapter.config.minimumExtendedPriceDifferenceForSwapOpen); // 500 for now
|
|
956
957
|
logger.info(`result: ${result}`);
|
|
957
958
|
return result;
|
|
958
|
-
}else{
|
|
959
|
+
} else {
|
|
959
960
|
logger.info(`price difference between avnu and extended for close position: ${priceDifference.toNumber()}, maximumExtendedPriceDifferenceForSwapClosing: ${avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing}`);
|
|
960
961
|
const result = priceDifference.lessThanOrEqualTo(avnuAdapter.config.maximumExtendedPriceDifferenceForSwapClosing); // 1000 for now
|
|
961
962
|
logger.info(`result: ${result}`);
|
|
@@ -1127,7 +1128,7 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
1127
1128
|
}, prevAum: prevAum, splits: [realAUM, estimatedAUMDelta]
|
|
1128
1129
|
};
|
|
1129
1130
|
}
|
|
1130
|
-
|
|
1131
|
+
|
|
1131
1132
|
async processTransactionDataFromSDK(txnData: TransactionResult<any>[]): Promise<{ callsToBeExecutedFinal: Call[], txnMetadata: TransactionMetadata[] } | null> {
|
|
1132
1133
|
try {
|
|
1133
1134
|
const txnsToBeExecuted = txnData.filter(txn => {
|
|
@@ -1160,6 +1161,155 @@ export class VesuExtendedMultiplierStrategy<
|
|
|
1160
1161
|
return null;
|
|
1161
1162
|
}
|
|
1162
1163
|
}
|
|
1164
|
+
|
|
1165
|
+
async getMaxBorrowableAmount(): Promise<Web3Number> {
|
|
1166
|
+
const vesuAdapter = await this.getVesuAdapter();
|
|
1167
|
+
const extendedAdapter = await this.getExtendedAdapter();
|
|
1168
|
+
if (!vesuAdapter || !extendedAdapter) {
|
|
1169
|
+
return new Web3Number(0, 0);
|
|
1170
|
+
}
|
|
1171
|
+
const extendedFundingRate = new Web3Number((await extendedAdapter.getNetAPY()).toFixed(4), 0);
|
|
1172
|
+
const extendedPositions = await extendedAdapter.getAllOpenPositions();
|
|
1173
|
+
if (!extendedPositions || extendedPositions.length === 0) {
|
|
1174
|
+
logger.info(`no extended positions found`);
|
|
1175
|
+
return new Web3Number(0, 0);
|
|
1176
|
+
}
|
|
1177
|
+
const extendePositionSizeUSD = new Web3Number(extendedPositions[0].value || 0, 0);
|
|
1178
|
+
const vesuPositions = await vesuAdapter.getPositions();
|
|
1179
|
+
const vesuSupplyApy = vesuPositions[0].apy.apy;
|
|
1180
|
+
const vesuCollateralSizeUSD = new Web3Number(vesuPositions[0].usdValue.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS);
|
|
1181
|
+
const vesuDebtSizeUSD = new Web3Number(vesuPositions[1].usdValue.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS)
|
|
1182
|
+
const num1 = extendePositionSizeUSD.multipliedBy(extendedFundingRate);
|
|
1183
|
+
const num2 = vesuCollateralSizeUSD.multipliedBy(vesuSupplyApy);
|
|
1184
|
+
const num3 = vesuDebtSizeUSD.abs()
|
|
1185
|
+
const maxBorrowApy = num1.plus(num2).minus(0.1).dividedBy(num3);
|
|
1186
|
+
const vesuMaxBorrowableAmount = await vesuAdapter.vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxBorrowApy.toNumber());
|
|
1187
|
+
return new Web3Number(vesuMaxBorrowableAmount.toFixed(USDC_TOKEN_DECIMALS), USDC_TOKEN_DECIMALS);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
async getVesuHealthFactors(): Promise<number[]> {
|
|
1191
|
+
const vesuAdapter = await this.getVesuAdapter();
|
|
1192
|
+
const extendedAdapter = await this.getExtendedAdapter();
|
|
1193
|
+
if (!vesuAdapter || !extendedAdapter) {
|
|
1194
|
+
return [0, 0];
|
|
1195
|
+
}
|
|
1196
|
+
const vesuPositions = await vesuAdapter.getPositions();
|
|
1197
|
+
const vesuCollateralSizeUSD = new Web3Number(vesuPositions[0].usdValue.toFixed(USDC_TOKEN_DECIMALS), 0);
|
|
1198
|
+
const vesuDebtSizeUSD = new Web3Number(vesuPositions[1].usdValue.toFixed(USDC_TOKEN_DECIMALS), 0);
|
|
1199
|
+
const actualLtv = vesuDebtSizeUSD.dividedBy(vesuCollateralSizeUSD).abs();
|
|
1200
|
+
logger.info(`actualLtv: ${actualLtv.toNumber()}`);
|
|
1201
|
+
const maxLtv = new Web3Number(await vesuAdapter.vesuAdapter.getLTVConfig(this.config), 4);
|
|
1202
|
+
const healthFactor = new Web3Number(maxLtv.dividedBy(actualLtv).toFixed(4), 4);
|
|
1203
|
+
logger.info(`healthFactor: ${healthFactor.toNumber()}`);
|
|
1204
|
+
const extendedBalance = await extendedAdapter.getExtendedDepositAmount();
|
|
1205
|
+
if (!extendedBalance) {
|
|
1206
|
+
return [0, 0];
|
|
1207
|
+
}
|
|
1208
|
+
const extendedLeverage = new Web3Number((Number(extendedBalance.marginRatio) * 100).toFixed(4), 4);
|
|
1209
|
+
logger.info(`extendedLeverage: ${extendedLeverage.toNumber()}`);
|
|
1210
|
+
return [healthFactor.toNumber(), extendedLeverage.toNumber()];
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
async netAPY(): Promise<{ net: number; splits: { apy: number; id: string; }[]; }> {
|
|
1214
|
+
const allPositions: PositionInfo[] = [];
|
|
1215
|
+
for (let adapter of this.metadata.additionalInfo.adapters) {
|
|
1216
|
+
if(adapter.adapter.name !== ExtendedAdapter.name){
|
|
1217
|
+
let positions = await adapter.adapter.getPositions();
|
|
1218
|
+
if(positions.length > 0){
|
|
1219
|
+
allPositions.push(...positions);
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
const extendedAdapter =await this.getExtendedAdapter()
|
|
1224
|
+
if(!extendedAdapter){
|
|
1225
|
+
return {
|
|
1226
|
+
net: 0,
|
|
1227
|
+
splits: []
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
let vesuPositions = allPositions.filter((item) => item.protocol === Protocols.VESU);
|
|
1231
|
+
vesuPositions.map((item) =>{
|
|
1232
|
+
item.apy.apy = item.apy.apy * 0.1;
|
|
1233
|
+
})
|
|
1234
|
+
const extendedPositions = await extendedAdapter.getAllOpenPositions();
|
|
1235
|
+
const usdcToken = Global.getDefaultTokens().find(token => token.symbol === "USDC");
|
|
1236
|
+
if(!extendedPositions || !usdcToken){
|
|
1237
|
+
return {
|
|
1238
|
+
net: 0,
|
|
1239
|
+
splits: []
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
const extendedPosition = extendedPositions[0] || 0;
|
|
1243
|
+
const extendedEquity = (await extendedAdapter.getExtendedDepositAmount())?.equity || 0;
|
|
1244
|
+
const extendedApy = await extendedAdapter.getNetAPY();
|
|
1245
|
+
const totalHoldingsUSDValue = allPositions.reduce((acc, curr) => acc + curr.usdValue, 0) + Number(extendedEquity);
|
|
1246
|
+
console.log(totalHoldingsUSDValue)
|
|
1247
|
+
const extendedPositionSizeMultipliedByApy = Number(extendedPosition.value) * extendedApy;
|
|
1248
|
+
let weightedAPYs = allPositions.reduce((acc, curr) => acc + curr.apy.apy * curr.usdValue, 0) + extendedPositionSizeMultipliedByApy;
|
|
1249
|
+
console.log(weightedAPYs)
|
|
1250
|
+
const netAPY = weightedAPYs / totalHoldingsUSDValue;
|
|
1251
|
+
console.log(netAPY)
|
|
1252
|
+
allPositions.push({
|
|
1253
|
+
tokenInfo: usdcToken,
|
|
1254
|
+
amount: new Web3Number(extendedPosition.size, 0),
|
|
1255
|
+
usdValue: Number(extendedEquity),
|
|
1256
|
+
apy: { apy: extendedApy, type: APYType.BASE },
|
|
1257
|
+
remarks: AUMTypes.FINALISED,
|
|
1258
|
+
protocol: Protocols.EXTENDED
|
|
1259
|
+
})
|
|
1260
|
+
return {
|
|
1261
|
+
net: netAPY,
|
|
1262
|
+
splits: allPositions.map(p => ({apy: p.apy.apy, id: p.remarks ?? ''}))
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
async getWalletHoldings(): Promise<{
|
|
1267
|
+
tokenInfo: TokenInfo,
|
|
1268
|
+
amount: Web3Number,
|
|
1269
|
+
usdValue: number
|
|
1270
|
+
}[]> {
|
|
1271
|
+
const usdceToken = Global.getDefaultTokens().find(token => token.symbol === "USDCe");
|
|
1272
|
+
const wbtcToken = Global.getDefaultTokens().find(token => token.symbol === "WBTC");
|
|
1273
|
+
const usdcToken = Global.getDefaultTokens().find(token => token.symbol === "USDC");
|
|
1274
|
+
if (!usdceToken || !wbtcToken || !usdcToken) {
|
|
1275
|
+
return [];
|
|
1276
|
+
}
|
|
1277
|
+
const walletAddress = this.metadata.additionalInfo.walletAddress;
|
|
1278
|
+
const usdceWalletBalance = await new ERC20(this.config).balanceOf(
|
|
1279
|
+
usdceToken.address,
|
|
1280
|
+
walletAddress,
|
|
1281
|
+
usdceToken.decimals
|
|
1282
|
+
);
|
|
1283
|
+
const usdcWalletBalance = await new ERC20(this.config).balanceOf(
|
|
1284
|
+
usdcToken.address,
|
|
1285
|
+
walletAddress,
|
|
1286
|
+
usdcToken.decimals
|
|
1287
|
+
);
|
|
1288
|
+
const wbtcWalletBalance = await new ERC20(this.config).balanceOf(
|
|
1289
|
+
wbtcToken.address,
|
|
1290
|
+
walletAddress,
|
|
1291
|
+
wbtcToken.decimals
|
|
1292
|
+
);
|
|
1293
|
+
const price = await this.pricer.getPrice(usdceToken.symbol);
|
|
1294
|
+
const wbtcPrice = await this.pricer.getPrice(wbtcToken.symbol);
|
|
1295
|
+
const usdceUsdValue = Number(usdceWalletBalance.toFixed(usdceToken.decimals)) * price.price;
|
|
1296
|
+
const usdcUsdValue = Number(usdcWalletBalance.toFixed(usdcToken.decimals)) * price.price;
|
|
1297
|
+
const wbtcUsdValue = Number(wbtcWalletBalance.toFixed(wbtcToken.decimals)) * wbtcPrice.price;
|
|
1298
|
+
return [{
|
|
1299
|
+
tokenInfo: usdceToken,
|
|
1300
|
+
amount: usdceWalletBalance,
|
|
1301
|
+
usdValue: usdceUsdValue
|
|
1302
|
+
},
|
|
1303
|
+
{
|
|
1304
|
+
tokenInfo: usdcToken,
|
|
1305
|
+
amount: usdcWalletBalance,
|
|
1306
|
+
usdValue: usdcUsdValue
|
|
1307
|
+
}, {
|
|
1308
|
+
tokenInfo: wbtcToken,
|
|
1309
|
+
amount: wbtcWalletBalance,
|
|
1310
|
+
usdValue: wbtcUsdValue
|
|
1311
|
+
}];
|
|
1312
|
+
}
|
|
1163
1313
|
}
|
|
1164
1314
|
|
|
1165
1315
|
function getLooperSettings(
|
|
@@ -1369,6 +1519,7 @@ const re7UsdcPrimeDevansh: VesuExtendedStrategySettings = {
|
|
|
1369
1519
|
),
|
|
1370
1520
|
borrowable_assets: [Global.getDefaultTokens().find(token => token.symbol === "WBTC")!],
|
|
1371
1521
|
minimumWBTCDifferenceForAvnuSwap: MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP,
|
|
1522
|
+
walletAddress: WALLET_ADDRESS,
|
|
1372
1523
|
}
|
|
1373
1524
|
|
|
1374
1525
|
export const VesuExtendedTestStrategies = (extendedBackendUrl: string, extendedApiKey: string, vaultIdExtended: number, minimumExtendedMovementAmount: number, minimumVesuMovementAmount: number, minimumExtendedRetriesDelayForOrderStatus: number, minimumExtendedPriceDifferenceForSwapOpen: number, maximumExtendedPriceDifferenceForSwapClosing: number): IStrategyMetadata<VesuExtendedStrategySettings>[] => {
|