@strkfarm/sdk 2.0.0-dev.40 → 2.0.0-dev.41
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 +407 -208
- package/dist/index.browser.mjs +425 -225
- package/dist/index.d.ts +38 -14
- package/dist/index.js +427 -225
- package/dist/index.mjs +426 -225
- package/package.json +4 -5
- package/src/global.ts +36 -34
- package/src/interfaces/common.tsx +6 -0
- package/src/modules/index.ts +1 -0
- package/src/modules/pricer-avnu-api.ts +114 -0
- package/src/modules/pricer.ts +63 -45
- package/src/node/pricer-redis.ts +1 -0
- package/src/strategies/ekubo-cl-vault.tsx +3 -0
- package/src/strategies/svk-strategy.ts +159 -2
- package/src/strategies/token-boosted-xstrk-carry-strategy.tsx +46 -9
- package/src/strategies/universal-lst-muliplier-strategy.tsx +90 -19
- package/src/strategies/universal-strategy.tsx +216 -372
- package/src/strategies/yoloVault.ts +3 -0
package/dist/index.browser.mjs
CHANGED
|
@@ -474,20 +474,20 @@ var defaultTokens = [
|
|
|
474
474
|
decimals: 18,
|
|
475
475
|
coingeckId: void 0,
|
|
476
476
|
displayDecimals: 6,
|
|
477
|
-
priceCheckAmount: 1e-4
|
|
477
|
+
priceCheckAmount: 1e-4,
|
|
478
478
|
// 112000 * 0.0001 = $11.2
|
|
479
|
+
dontPrice: true
|
|
479
480
|
},
|
|
480
481
|
{
|
|
481
482
|
name: "mRe7YIELD",
|
|
482
483
|
symbol: "mRe7YIELD",
|
|
483
484
|
logo: "https://midas.app/assets/mre7-BcOOHm7i.svg",
|
|
484
|
-
address: ContractAddr.from(
|
|
485
|
-
"0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"
|
|
486
|
-
),
|
|
485
|
+
address: ContractAddr.from("0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"),
|
|
487
486
|
decimals: 18,
|
|
488
487
|
coingeckId: void 0,
|
|
489
488
|
displayDecimals: 2,
|
|
490
|
-
priceCheckAmount: 100
|
|
489
|
+
priceCheckAmount: 100,
|
|
490
|
+
dontPrice: true
|
|
491
491
|
},
|
|
492
492
|
{
|
|
493
493
|
name: "fyWBTC",
|
|
@@ -497,8 +497,9 @@ var defaultTokens = [
|
|
|
497
497
|
decimals: 8,
|
|
498
498
|
coingeckId: void 0,
|
|
499
499
|
displayDecimals: 6,
|
|
500
|
-
priceCheckAmount: 1e-3
|
|
500
|
+
priceCheckAmount: 1e-3,
|
|
501
501
|
// 112000 * 0.0001 = $110.2
|
|
502
|
+
dontPrice: true
|
|
502
503
|
},
|
|
503
504
|
{
|
|
504
505
|
name: "fyETH",
|
|
@@ -508,7 +509,8 @@ var defaultTokens = [
|
|
|
508
509
|
decimals: 18,
|
|
509
510
|
coingeckId: void 0,
|
|
510
511
|
displayDecimals: 4,
|
|
511
|
-
priceCheckAmount: 0.1
|
|
512
|
+
priceCheckAmount: 0.1,
|
|
513
|
+
dontPrice: true
|
|
512
514
|
},
|
|
513
515
|
{
|
|
514
516
|
name: "fyUSDC",
|
|
@@ -518,7 +520,8 @@ var defaultTokens = [
|
|
|
518
520
|
decimals: 6,
|
|
519
521
|
coingeckId: void 0,
|
|
520
522
|
displayDecimals: 2,
|
|
521
|
-
priceCheckAmount: 100
|
|
523
|
+
priceCheckAmount: 100,
|
|
524
|
+
dontPrice: true
|
|
522
525
|
},
|
|
523
526
|
{
|
|
524
527
|
name: "strkBTC",
|
|
@@ -3526,7 +3529,7 @@ var TokenMarketData = class {
|
|
|
3526
3529
|
};
|
|
3527
3530
|
|
|
3528
3531
|
// src/modules/pricer.ts
|
|
3529
|
-
import
|
|
3532
|
+
import axios4 from "axios";
|
|
3530
3533
|
|
|
3531
3534
|
// src/modules/pricerBase.ts
|
|
3532
3535
|
var PricerBase = class {
|
|
@@ -3630,7 +3633,96 @@ var AvnuWrapper = class _AvnuWrapper {
|
|
|
3630
3633
|
}
|
|
3631
3634
|
};
|
|
3632
3635
|
|
|
3636
|
+
// src/modules/pricer-avnu-api.ts
|
|
3637
|
+
import axios3 from "axios";
|
|
3638
|
+
var AVNU_TOKENS_API = "https://starknet.impulse.avnu.fi/v3/tokens";
|
|
3639
|
+
var PricerAvnuApi = class extends PricerBase {
|
|
3640
|
+
constructor(config, tokens2) {
|
|
3641
|
+
super(config, tokens2);
|
|
3642
|
+
this.prices = {};
|
|
3643
|
+
this.refreshInterval = 15e3;
|
|
3644
|
+
this.staleTime = 5 * 60 * 1e3;
|
|
3645
|
+
this.pollTimer = null;
|
|
3646
|
+
this.loading = false;
|
|
3647
|
+
}
|
|
3648
|
+
start() {
|
|
3649
|
+
this._loadPrices();
|
|
3650
|
+
this.pollTimer = setInterval(() => {
|
|
3651
|
+
this._loadPrices();
|
|
3652
|
+
}, this.refreshInterval);
|
|
3653
|
+
}
|
|
3654
|
+
stop() {
|
|
3655
|
+
if (this.pollTimer) {
|
|
3656
|
+
clearInterval(this.pollTimer);
|
|
3657
|
+
this.pollTimer = null;
|
|
3658
|
+
}
|
|
3659
|
+
}
|
|
3660
|
+
isStale(timestamp) {
|
|
3661
|
+
return Date.now() - timestamp.getTime() > this.staleTime;
|
|
3662
|
+
}
|
|
3663
|
+
hasPrice(tokenSymbol) {
|
|
3664
|
+
const info = this.prices[tokenSymbol];
|
|
3665
|
+
return !!info && !this.isStale(info.timestamp);
|
|
3666
|
+
}
|
|
3667
|
+
async getPrice(tokenSymbol) {
|
|
3668
|
+
const info = this.prices[tokenSymbol];
|
|
3669
|
+
if (!info) {
|
|
3670
|
+
throw new Error(`AvnuApi: price of ${tokenSymbol} not found`);
|
|
3671
|
+
}
|
|
3672
|
+
if (this.isStale(info.timestamp)) {
|
|
3673
|
+
throw new Error(`AvnuApi: price of ${tokenSymbol} is stale`);
|
|
3674
|
+
}
|
|
3675
|
+
return info;
|
|
3676
|
+
}
|
|
3677
|
+
async _loadPrices() {
|
|
3678
|
+
if (this.loading) {
|
|
3679
|
+
return;
|
|
3680
|
+
}
|
|
3681
|
+
this.loading = true;
|
|
3682
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
3683
|
+
try {
|
|
3684
|
+
const result = await axios3.get(AVNU_TOKENS_API);
|
|
3685
|
+
const priceByAddress = /* @__PURE__ */ new Map();
|
|
3686
|
+
for (const entry of result.data) {
|
|
3687
|
+
const usd = entry.starknet?.usd;
|
|
3688
|
+
if (usd != null && usd > 0) {
|
|
3689
|
+
priceByAddress.set(ContractAddr.standardise(entry.address), usd);
|
|
3690
|
+
}
|
|
3691
|
+
}
|
|
3692
|
+
for (const token of this.tokens) {
|
|
3693
|
+
if (token.symbol === "USDT" || token.symbol === "USDC") {
|
|
3694
|
+
this.prices[token.symbol] = { price: 1, timestamp };
|
|
3695
|
+
continue;
|
|
3696
|
+
}
|
|
3697
|
+
const targetToken = token.priceProxySymbol ? this.tokens.find((t) => t.symbol === token.priceProxySymbol) : token;
|
|
3698
|
+
if (!targetToken) {
|
|
3699
|
+
continue;
|
|
3700
|
+
}
|
|
3701
|
+
const addr = targetToken.address.address;
|
|
3702
|
+
const price = priceByAddress.get(addr);
|
|
3703
|
+
if (price != null) {
|
|
3704
|
+
this.prices[token.symbol] = { price, timestamp };
|
|
3705
|
+
logger.verbose(
|
|
3706
|
+
`AvnuApi: ${token.symbol} -> $${price}`
|
|
3707
|
+
);
|
|
3708
|
+
}
|
|
3709
|
+
}
|
|
3710
|
+
} catch (error) {
|
|
3711
|
+
logger.warn(`AvnuApi: failed to fetch tokens: ${error?.message ?? error}`);
|
|
3712
|
+
} finally {
|
|
3713
|
+
this.loading = false;
|
|
3714
|
+
}
|
|
3715
|
+
}
|
|
3716
|
+
};
|
|
3717
|
+
|
|
3633
3718
|
// src/modules/pricer.ts
|
|
3719
|
+
var PRICE_METHOD_PRIORITY = [
|
|
3720
|
+
"AvnuApi",
|
|
3721
|
+
"Coinbase",
|
|
3722
|
+
"Coinmarketcap",
|
|
3723
|
+
"Ekubo",
|
|
3724
|
+
"Avnu"
|
|
3725
|
+
];
|
|
3634
3726
|
var Pricer = class extends PricerBase {
|
|
3635
3727
|
// e.g. ETH/USDC
|
|
3636
3728
|
constructor(config, tokens2, refreshInterval = 3e4, staleTime = 6e4) {
|
|
@@ -3649,6 +3741,7 @@ var Pricer = class extends PricerBase {
|
|
|
3649
3741
|
this.EKUBO_API = "https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
|
|
3650
3742
|
this.refreshInterval = refreshInterval;
|
|
3651
3743
|
this.staleTime = staleTime;
|
|
3744
|
+
this.avnuApiPricer = new PricerAvnuApi(config, tokens2);
|
|
3652
3745
|
}
|
|
3653
3746
|
isReady() {
|
|
3654
3747
|
const allPricesExist = Object.keys(this.prices).length === this.tokens.length;
|
|
@@ -3678,6 +3771,7 @@ var Pricer = class extends PricerBase {
|
|
|
3678
3771
|
});
|
|
3679
3772
|
}
|
|
3680
3773
|
start() {
|
|
3774
|
+
this.avnuApiPricer.start();
|
|
3681
3775
|
this._loadPrices();
|
|
3682
3776
|
setInterval(() => {
|
|
3683
3777
|
this._loadPrices();
|
|
@@ -3702,6 +3796,9 @@ var Pricer = class extends PricerBase {
|
|
|
3702
3796
|
let retry = 0;
|
|
3703
3797
|
while (retry < MAX_RETRIES) {
|
|
3704
3798
|
try {
|
|
3799
|
+
if (token.dontPrice) {
|
|
3800
|
+
return;
|
|
3801
|
+
}
|
|
3705
3802
|
if (token.symbol === "USDT" || token.symbol === "USDC") {
|
|
3706
3803
|
this.prices[token.symbol] = {
|
|
3707
3804
|
price: 1,
|
|
@@ -3744,60 +3841,61 @@ var Pricer = class extends PricerBase {
|
|
|
3744
3841
|
});
|
|
3745
3842
|
if (this.isReady() && this.config.heartbeatUrl) {
|
|
3746
3843
|
console.log(`sending beat`);
|
|
3747
|
-
|
|
3844
|
+
axios4.get(this.config.heartbeatUrl).catch((err) => {
|
|
3748
3845
|
console.error("Pricer: Heartbeat err", err);
|
|
3749
3846
|
});
|
|
3750
3847
|
}
|
|
3751
3848
|
}
|
|
3752
|
-
async _getPrice(token
|
|
3753
|
-
const
|
|
3754
|
-
|
|
3755
|
-
|
|
3849
|
+
async _getPrice(token) {
|
|
3850
|
+
const pinned = this.methodToUse[token.symbol];
|
|
3851
|
+
if (pinned) {
|
|
3852
|
+
logger.verbose(`Fetching price of ${token.symbol} using pinned ${pinned}`);
|
|
3853
|
+
try {
|
|
3854
|
+
return await this._tryPriceMethod(token, pinned);
|
|
3855
|
+
} catch (error) {
|
|
3856
|
+
console.warn(`${pinned}: pinned price failed [${token.symbol}]: `, error.message);
|
|
3857
|
+
delete this.methodToUse[token.symbol];
|
|
3858
|
+
}
|
|
3859
|
+
}
|
|
3860
|
+
for (const method of PRICE_METHOD_PRIORITY) {
|
|
3861
|
+
logger.verbose(`Fetching price of ${token.symbol} using ${method}`);
|
|
3862
|
+
try {
|
|
3863
|
+
const result = await this._tryPriceMethod(token, method);
|
|
3864
|
+
this.methodToUse[token.symbol] = method;
|
|
3865
|
+
return result;
|
|
3866
|
+
} catch (error) {
|
|
3867
|
+
console.warn(`${method}: price err [${token.symbol}]: `, error.message);
|
|
3868
|
+
}
|
|
3869
|
+
}
|
|
3870
|
+
throw new FatalError(`Price not found for ${token.symbol}`);
|
|
3871
|
+
}
|
|
3872
|
+
async _tryPriceMethod(token, method) {
|
|
3873
|
+
switch (method) {
|
|
3874
|
+
case "AvnuApi":
|
|
3875
|
+
return await this._getPriceAvnuApi(token);
|
|
3756
3876
|
case "Coinbase":
|
|
3757
|
-
|
|
3758
|
-
// const result = await this._getPriceCoinbase(token);
|
|
3759
|
-
// this.methodToUse[token.symbol] = 'Coinbase';
|
|
3760
|
-
// return result;
|
|
3761
|
-
// } catch (error: any) {
|
|
3762
|
-
// console.warn(`Coinbase: price err: message [${token.symbol}]: `, error.message);
|
|
3763
|
-
// // do nothing, try next
|
|
3764
|
-
// }
|
|
3877
|
+
return await this._getPriceCoinbase(token);
|
|
3765
3878
|
case "Coinmarketcap":
|
|
3766
|
-
|
|
3767
|
-
const result = await this._getPriceCoinMarketCap(token);
|
|
3768
|
-
this.methodToUse[token.symbol] = "Coinmarketcap";
|
|
3769
|
-
return result;
|
|
3770
|
-
} catch (error) {
|
|
3771
|
-
console.warn(`CoinMarketCap: price err [${token.symbol}]: `, Object.keys(error));
|
|
3772
|
-
console.warn(`CoinMarketCap: price err [${token.symbol}]: `, error.message);
|
|
3773
|
-
}
|
|
3879
|
+
return await this._getPriceCoinMarketCap(token);
|
|
3774
3880
|
case "Ekubo":
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
} catch (error) {
|
|
3780
|
-
console.warn(`Ekubo: price err [${token.symbol}]: `, error.message);
|
|
3781
|
-
console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error));
|
|
3782
|
-
}
|
|
3881
|
+
return await this._getPriceEkubo(
|
|
3882
|
+
token,
|
|
3883
|
+
new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals)
|
|
3884
|
+
);
|
|
3783
3885
|
case "Avnu":
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
} catch (error) {
|
|
3789
|
-
console.warn(`Avnu: price err [${token.symbol}]: `, error.message);
|
|
3790
|
-
console.warn(`Avnu: price err [${token.symbol}]: `, Object.keys(error));
|
|
3791
|
-
}
|
|
3792
|
-
}
|
|
3793
|
-
if (defaultMethod == "all") {
|
|
3794
|
-
return await this._getPrice(token, "Coinbase");
|
|
3886
|
+
return await this._getAvnuPrice(
|
|
3887
|
+
token,
|
|
3888
|
+
new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals)
|
|
3889
|
+
);
|
|
3795
3890
|
}
|
|
3796
|
-
|
|
3891
|
+
}
|
|
3892
|
+
async _getPriceAvnuApi(token) {
|
|
3893
|
+
const priceInfo = await this.avnuApiPricer.getPrice(token.symbol);
|
|
3894
|
+
return priceInfo.price;
|
|
3797
3895
|
}
|
|
3798
3896
|
async _getPriceCoinbase(token) {
|
|
3799
3897
|
const url = this.PRICE_API.replace("{{PRICER_KEY}}", `${token.symbol}-USD`);
|
|
3800
|
-
const result = await
|
|
3898
|
+
const result = await axios4.get(url);
|
|
3801
3899
|
const data = result.data;
|
|
3802
3900
|
return Number(data.data.amount);
|
|
3803
3901
|
}
|
|
@@ -3823,7 +3921,7 @@ var Pricer = class extends PricerBase {
|
|
|
3823
3921
|
async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
|
|
3824
3922
|
logger.verbose(`Getting price of ${token.symbol} using Ekubo, amountIn: ${amountIn.toWei()}`);
|
|
3825
3923
|
const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei());
|
|
3826
|
-
const result = await
|
|
3924
|
+
const result = await axios4.get(url);
|
|
3827
3925
|
const data = result.data;
|
|
3828
3926
|
const multiplier = 1 / amountIn.toNumber();
|
|
3829
3927
|
const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6)) * multiplier;
|
|
@@ -3969,7 +4067,7 @@ var Pragma = class extends PricerBase {
|
|
|
3969
4067
|
};
|
|
3970
4068
|
|
|
3971
4069
|
// src/modules/zkLend.ts
|
|
3972
|
-
import
|
|
4070
|
+
import axios5 from "axios";
|
|
3973
4071
|
|
|
3974
4072
|
// src/interfaces/lending.ts
|
|
3975
4073
|
var MarginType = /* @__PURE__ */ ((MarginType2) => {
|
|
@@ -4013,7 +4111,7 @@ var _ZkLend = class _ZkLend extends ILending {
|
|
|
4013
4111
|
async init() {
|
|
4014
4112
|
try {
|
|
4015
4113
|
logger.verbose(`Initialising ${this.metadata.name}`);
|
|
4016
|
-
const result = await
|
|
4114
|
+
const result = await axios5.get(_ZkLend.POOLS_URL);
|
|
4017
4115
|
const data = result.data;
|
|
4018
4116
|
const savedTokens = await Global.getTokens();
|
|
4019
4117
|
data.forEach((pool) => {
|
|
@@ -4105,7 +4203,7 @@ var _ZkLend = class _ZkLend extends ILending {
|
|
|
4105
4203
|
*/
|
|
4106
4204
|
async getPositions(user) {
|
|
4107
4205
|
const url = this.POSITION_URL.replace("{{USER_ADDR}}", user.address);
|
|
4108
|
-
const result = await
|
|
4206
|
+
const result = await axios5.get(url);
|
|
4109
4207
|
const data = result.data;
|
|
4110
4208
|
const lendingPosition = [];
|
|
4111
4209
|
logger.verbose(`${this.metadata.name}:: Positions: ${JSON.stringify(data)}`);
|
|
@@ -4138,7 +4236,7 @@ _ZkLend.POOLS_URL = "https://app.zklend.com/api/pools";
|
|
|
4138
4236
|
var ZkLend = _ZkLend;
|
|
4139
4237
|
|
|
4140
4238
|
// src/modules/pricer-from-api.ts
|
|
4141
|
-
import
|
|
4239
|
+
import axios6 from "axios";
|
|
4142
4240
|
|
|
4143
4241
|
// src/modules/apollo-client-config.ts
|
|
4144
4242
|
import { ApolloClient, InMemoryCache } from "@apollo/client";
|
|
@@ -4525,7 +4623,7 @@ var PricerFromApi = class extends PricerBase {
|
|
|
4525
4623
|
const MAX_RETRIES = 5;
|
|
4526
4624
|
for (retry = 1; retry < MAX_RETRIES + 1; retry++) {
|
|
4527
4625
|
try {
|
|
4528
|
-
const priceInfo = await
|
|
4626
|
+
const priceInfo = await axios6.get(
|
|
4529
4627
|
`https://api.coinbase.com/v2/prices/${tokenSymbol}-USDT/spot`
|
|
4530
4628
|
);
|
|
4531
4629
|
if (!priceInfo) {
|
|
@@ -5836,7 +5934,7 @@ var ERC20 = class {
|
|
|
5836
5934
|
};
|
|
5837
5935
|
|
|
5838
5936
|
// src/modules/ekubo-quoter.ts
|
|
5839
|
-
import
|
|
5937
|
+
import axios7 from "axios";
|
|
5840
5938
|
import { uint256 as uint2567 } from "starknet";
|
|
5841
5939
|
import { Contract as Contract5 } from "starknet";
|
|
5842
5940
|
var EkuboQuoter = class _EkuboQuoter {
|
|
@@ -5849,7 +5947,7 @@ var EkuboQuoter = class _EkuboQuoter {
|
|
|
5849
5947
|
try {
|
|
5850
5948
|
const url = this.ENDPOINT.replace("{{AMOUNT}}", amount.toWei()).replace("{{TOKEN_FROM_ADDRESS}}", fromToken).replace("{{TOKEN_TO_ADDRESS}}", toToken);
|
|
5851
5949
|
logger.verbose(`EkuboQuoter::_callQuoterApi url: ${url}`);
|
|
5852
|
-
const quote = await
|
|
5950
|
+
const quote = await axios7.get(url);
|
|
5853
5951
|
return quote.data;
|
|
5854
5952
|
} catch (error) {
|
|
5855
5953
|
logger.error(`EkuboQuoter::_callQuoterApi error: ${error.message}`);
|
|
@@ -5972,7 +6070,7 @@ var EkuboQuoter = class _EkuboQuoter {
|
|
|
5972
6070
|
};
|
|
5973
6071
|
|
|
5974
6072
|
// src/modules/pricer-lst.ts
|
|
5975
|
-
import
|
|
6073
|
+
import axios8 from "axios";
|
|
5976
6074
|
var PricerLST = class extends Pricer {
|
|
5977
6075
|
// e.g. xSTRK/STRK
|
|
5978
6076
|
constructor(config, tokenMaps) {
|
|
@@ -6008,7 +6106,7 @@ var PricerLST = class extends Pricer {
|
|
|
6008
6106
|
async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
|
|
6009
6107
|
const underlying = this.getUnderlying(token);
|
|
6010
6108
|
const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei()).replace("{{UNDERLYING_ADDRESS}}", underlying.address.toString());
|
|
6011
|
-
const result = await
|
|
6109
|
+
const result = await axios8.get(url);
|
|
6012
6110
|
const data = result.data;
|
|
6013
6111
|
const multiplier = 1 / amountIn.toNumber();
|
|
6014
6112
|
const outputUnderlying = Number(Web3Number.fromWei(data.total_calculated, underlying.decimals).toFixed(6)) * multiplier;
|
|
@@ -7910,9 +8008,9 @@ var BaseStrategy = class extends CacheClass {
|
|
|
7910
8008
|
};
|
|
7911
8009
|
|
|
7912
8010
|
// src/node/headless.browser.ts
|
|
7913
|
-
import
|
|
8011
|
+
import axios9 from "axios";
|
|
7914
8012
|
async function getAPIUsingHeadlessBrowser(url) {
|
|
7915
|
-
const res = await
|
|
8013
|
+
const res = await axios9.get(url);
|
|
7916
8014
|
return res.data;
|
|
7917
8015
|
}
|
|
7918
8016
|
|
|
@@ -19421,6 +19519,9 @@ var xSTRKSTRK = {
|
|
|
19421
19519
|
},
|
|
19422
19520
|
apyMethodology: "APY based on 30-day historical performance, including fees and rewards.",
|
|
19423
19521
|
realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
|
|
19522
|
+
feeBps: {
|
|
19523
|
+
performanceFeeBps: 1e3
|
|
19524
|
+
},
|
|
19424
19525
|
additionalInfo: {
|
|
19425
19526
|
newBounds: {
|
|
19426
19527
|
lower: -1,
|
|
@@ -30147,6 +30248,9 @@ var YoloVaultStrategies = yoloVaultsConfig.map((yoloConfig) => {
|
|
|
30147
30248
|
notARisks: getNoRiskTags(yoloRiskFactors)
|
|
30148
30249
|
},
|
|
30149
30250
|
apyMethodology: "Not a primary yield strategy. Funds earn yield when idle, but the main return comes from BTC price appreciation and your conviction to hold. This vault simply helps you accumulate more BTC.",
|
|
30251
|
+
feeBps: {
|
|
30252
|
+
performanceFeeBps: 1e3
|
|
30253
|
+
},
|
|
30150
30254
|
additionalInfo: {
|
|
30151
30255
|
mainToken: yoloConfig.mainToken,
|
|
30152
30256
|
secondaryToken: yoloConfig.secondaryToken,
|
|
@@ -32927,7 +33031,7 @@ var TokenTransferAdapter = class _TokenTransferAdapter extends BaseAdapter {
|
|
|
32927
33031
|
|
|
32928
33032
|
// src/strategies/universal-adapters/avnu-adapter.ts
|
|
32929
33033
|
import { hash as hash9, uint256 as uint25619 } from "starknet";
|
|
32930
|
-
import
|
|
33034
|
+
import axios10 from "axios";
|
|
32931
33035
|
var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
|
|
32932
33036
|
constructor(config) {
|
|
32933
33037
|
super(config, _AvnuAdapter.name, Protocols.AVNU);
|
|
@@ -33134,7 +33238,7 @@ var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
|
|
|
33134
33238
|
async fetchQuoteWithRetry(params, retries = 5) {
|
|
33135
33239
|
for (let attempt = 0; attempt < retries; attempt++) {
|
|
33136
33240
|
try {
|
|
33137
|
-
const response = await
|
|
33241
|
+
const response = await axios10.get(this.config.baseUrl, { params });
|
|
33138
33242
|
if (response.data && response.data.length > 0) {
|
|
33139
33243
|
return response;
|
|
33140
33244
|
}
|
|
@@ -36668,6 +36772,29 @@ var SVKStrategy = class extends BaseStrategy {
|
|
|
36668
36772
|
]);
|
|
36669
36773
|
return [call];
|
|
36670
36774
|
}
|
|
36775
|
+
async getUserTVL(user, blockIdentifier = "latest") {
|
|
36776
|
+
const shares = await this.contract.call("balanceOf", [user.address], { blockIdentifier });
|
|
36777
|
+
const assets = await this.contract.call(
|
|
36778
|
+
"convert_to_assets",
|
|
36779
|
+
[uint25621.bnToUint256(shares)],
|
|
36780
|
+
{ blockIdentifier }
|
|
36781
|
+
);
|
|
36782
|
+
const amount = Web3Number.fromWei(
|
|
36783
|
+
assets.toString(),
|
|
36784
|
+
this.metadata.depositTokens[0].decimals
|
|
36785
|
+
);
|
|
36786
|
+
const blockNumber = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : void 0;
|
|
36787
|
+
const price = await this.pricer.getPrice(
|
|
36788
|
+
this.metadata.depositTokens[0].symbol,
|
|
36789
|
+
blockNumber
|
|
36790
|
+
);
|
|
36791
|
+
const usdValue = Number(amount.toFixed(6)) * price.price;
|
|
36792
|
+
return {
|
|
36793
|
+
tokenInfo: this.asset(),
|
|
36794
|
+
amount,
|
|
36795
|
+
usdValue
|
|
36796
|
+
};
|
|
36797
|
+
}
|
|
36671
36798
|
/**
|
|
36672
36799
|
* Returns the unused balance in the vault allocator.
|
|
36673
36800
|
* Note: This function is common for any SVK strategy.
|
|
@@ -36859,6 +36986,100 @@ var SVKStrategy = class extends BaseStrategy {
|
|
|
36859
36986
|
usdValue
|
|
36860
36987
|
};
|
|
36861
36988
|
}
|
|
36989
|
+
async getUserRealizedAPY(blockIdentifier = "latest", sinceBlocks = 6e5) {
|
|
36990
|
+
logger.verbose(
|
|
36991
|
+
`${this.getTag()}: getUserRealizedAPY => starting with blockIdentifier=${blockIdentifier}, sinceBlocks=${sinceBlocks}`
|
|
36992
|
+
);
|
|
36993
|
+
const blockNow = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : (await this.config.provider.getBlockLatestAccepted()).block_number;
|
|
36994
|
+
const blockNowTime = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
|
|
36995
|
+
const blockBefore = Math.max(
|
|
36996
|
+
blockNow - sinceBlocks,
|
|
36997
|
+
this.metadata.launchBlock
|
|
36998
|
+
);
|
|
36999
|
+
const assetsNowRaw = await this.contract.call("total_assets", [], {
|
|
37000
|
+
blockIdentifier
|
|
37001
|
+
});
|
|
37002
|
+
const amountNow = Web3Number.fromWei(
|
|
37003
|
+
assetsNowRaw.toString(),
|
|
37004
|
+
this.metadata.depositTokens[0].decimals
|
|
37005
|
+
);
|
|
37006
|
+
const supplyNowRaw = await this.contract.call("total_supply", [], {
|
|
37007
|
+
blockIdentifier
|
|
37008
|
+
});
|
|
37009
|
+
const supplyNow = Web3Number.fromWei(supplyNowRaw.toString(), 18);
|
|
37010
|
+
const assetsBeforeRaw = await this.contract.call(
|
|
37011
|
+
"total_assets",
|
|
37012
|
+
[],
|
|
37013
|
+
{ blockIdentifier: blockBefore }
|
|
37014
|
+
);
|
|
37015
|
+
const amountBefore = Web3Number.fromWei(
|
|
37016
|
+
assetsBeforeRaw.toString(),
|
|
37017
|
+
this.metadata.depositTokens[0].decimals
|
|
37018
|
+
);
|
|
37019
|
+
const supplyBeforeRaw = await this.contract.call(
|
|
37020
|
+
"total_supply",
|
|
37021
|
+
[],
|
|
37022
|
+
{ blockIdentifier: blockBefore }
|
|
37023
|
+
);
|
|
37024
|
+
const supplyBefore = Web3Number.fromWei(supplyBeforeRaw.toString(), 18);
|
|
37025
|
+
const blockBeforeInfo = await this.config.provider.getBlockWithTxs(
|
|
37026
|
+
blockBefore
|
|
37027
|
+
);
|
|
37028
|
+
const assetsPerShareNow = amountNow.multipliedBy(1e18).dividedBy(supplyNow.toString());
|
|
37029
|
+
const assetsPerShareBf = amountBefore.multipliedBy(1e18).dividedBy(supplyBefore.toString());
|
|
37030
|
+
const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
|
|
37031
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsNow: ${amountNow.toString()}`);
|
|
37032
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsBefore: ${amountBefore.toString()}`);
|
|
37033
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareNow: ${assetsPerShareNow.toString()}`);
|
|
37034
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareBf: ${assetsPerShareBf.toString()}`);
|
|
37035
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply before: ${supplyBefore.toString()}`);
|
|
37036
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply now: ${supplyNow.toString()}`);
|
|
37037
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] Time diff in seconds: ${timeDiffSeconds}`);
|
|
37038
|
+
const apyForGivenBlocks = Number(
|
|
37039
|
+
assetsPerShareNow.minus(assetsPerShareBf).multipliedBy(1e4).dividedBy(assetsPerShareBf)
|
|
37040
|
+
) / 1e4;
|
|
37041
|
+
return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
|
|
37042
|
+
}
|
|
37043
|
+
async getUserPositionCards(input) {
|
|
37044
|
+
const { user, investmentFlows = [] } = input;
|
|
37045
|
+
const [userTVL] = await Promise.all([
|
|
37046
|
+
this.getUserTVL(user)
|
|
37047
|
+
]);
|
|
37048
|
+
const cards = [
|
|
37049
|
+
{
|
|
37050
|
+
title: "Your Holdings",
|
|
37051
|
+
tooltip: "Your Holdings",
|
|
37052
|
+
value: this.formatTokenAmountForCard(userTVL.amount, userTVL.tokenInfo),
|
|
37053
|
+
subValue: `\u2248 ${this.formatUSDForCard(userTVL.usdValue)}`,
|
|
37054
|
+
subValueColor: "positive"
|
|
37055
|
+
}
|
|
37056
|
+
];
|
|
37057
|
+
let lifetimeAmount = userTVL.amount.multipliedBy(0);
|
|
37058
|
+
let lifetimeTokenInfo = userTVL.tokenInfo;
|
|
37059
|
+
let lifetimeUsdValue = 0;
|
|
37060
|
+
if (investmentFlows.length > 0) {
|
|
37061
|
+
try {
|
|
37062
|
+
const earningsResult = this.getLifetimeEarnings(userTVL, investmentFlows);
|
|
37063
|
+
lifetimeAmount = earningsResult.lifetimeEarnings;
|
|
37064
|
+
lifetimeTokenInfo = earningsResult.tokenInfo.tokenInfo;
|
|
37065
|
+
const userAmount = userTVL.amount.toNumber();
|
|
37066
|
+
if (Number.isFinite(userAmount) && userAmount > 0) {
|
|
37067
|
+
const pricePerToken = userTVL.usdValue / userAmount;
|
|
37068
|
+
lifetimeUsdValue = lifetimeAmount.toNumber() * pricePerToken;
|
|
37069
|
+
}
|
|
37070
|
+
} catch (error) {
|
|
37071
|
+
logger.warn(`${this.getTag()}::getUserPositionCards lifetime earnings fallback`, error);
|
|
37072
|
+
}
|
|
37073
|
+
}
|
|
37074
|
+
cards.push({
|
|
37075
|
+
title: "Lifetime Earnings",
|
|
37076
|
+
tooltip: "Lifetime Earnings",
|
|
37077
|
+
value: this.formatTokenAmountForCard(lifetimeAmount, lifetimeTokenInfo),
|
|
37078
|
+
subValue: `\u2248 ${this.formatUSDForCard(lifetimeUsdValue)}`,
|
|
37079
|
+
subValueColor: this.getSubValueColorFromSignedNumber(lifetimeUsdValue)
|
|
37080
|
+
});
|
|
37081
|
+
return cards;
|
|
37082
|
+
}
|
|
36862
37083
|
async getPrevAUM() {
|
|
36863
37084
|
const currentAUM = await this.contract.call("aum", []);
|
|
36864
37085
|
const prevAum = Web3Number.fromWei(currentAUM.toString(), this.asset().decimals);
|
|
@@ -36972,29 +37193,6 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
|
|
|
36972
37193
|
]);
|
|
36973
37194
|
return [call];
|
|
36974
37195
|
}
|
|
36975
|
-
async getUserTVL(user, blockIdentifier = "latest") {
|
|
36976
|
-
const shares = await this.contract.call("balanceOf", [user.address], { blockIdentifier });
|
|
36977
|
-
const assets = await this.contract.call(
|
|
36978
|
-
"convert_to_assets",
|
|
36979
|
-
[uint25622.bnToUint256(shares)],
|
|
36980
|
-
{ blockIdentifier }
|
|
36981
|
-
);
|
|
36982
|
-
const amount = Web3Number.fromWei(
|
|
36983
|
-
assets.toString(),
|
|
36984
|
-
this.metadata.depositTokens[0].decimals
|
|
36985
|
-
);
|
|
36986
|
-
const blockNumber = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : void 0;
|
|
36987
|
-
let price = await this.pricer.getPrice(
|
|
36988
|
-
this.metadata.depositTokens[0].symbol,
|
|
36989
|
-
blockNumber
|
|
36990
|
-
);
|
|
36991
|
-
const usdValue = Number(amount.toFixed(6)) * price.price;
|
|
36992
|
-
return {
|
|
36993
|
-
tokenInfo: this.asset(),
|
|
36994
|
-
amount,
|
|
36995
|
-
usdValue
|
|
36996
|
-
};
|
|
36997
|
-
}
|
|
36998
37196
|
async getVesuAPYs() {
|
|
36999
37197
|
const vesuAdapters = this.getVesuAdapters();
|
|
37000
37198
|
const allVesuPools = await VesuAdapter.getVesuPools();
|
|
@@ -37035,13 +37233,16 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
|
|
|
37035
37233
|
*/
|
|
37036
37234
|
async netAPY() {
|
|
37037
37235
|
if (this.metadata.isPreview) {
|
|
37038
|
-
return {
|
|
37039
|
-
|
|
37040
|
-
|
|
37041
|
-
|
|
37042
|
-
|
|
37043
|
-
|
|
37044
|
-
|
|
37236
|
+
return {
|
|
37237
|
+
net: 0,
|
|
37238
|
+
splits: [{
|
|
37239
|
+
apy: 0,
|
|
37240
|
+
id: "base"
|
|
37241
|
+
}, {
|
|
37242
|
+
apy: 0,
|
|
37243
|
+
id: "defispring"
|
|
37244
|
+
}]
|
|
37245
|
+
};
|
|
37045
37246
|
}
|
|
37046
37247
|
const { positions, baseAPYs, rewardAPYs } = await this.getVesuAPYs();
|
|
37047
37248
|
const unusedBalanceAPY = await this.getUnusedBalanceAPY();
|
|
@@ -37056,25 +37257,31 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
|
|
|
37056
37257
|
}
|
|
37057
37258
|
async returnNetAPY(baseAPYs, rewardAPYs, weights, prevAUMUSD) {
|
|
37058
37259
|
if (weights.every((p) => p == 0)) {
|
|
37059
|
-
return {
|
|
37060
|
-
|
|
37061
|
-
|
|
37062
|
-
|
|
37063
|
-
|
|
37064
|
-
|
|
37065
|
-
|
|
37260
|
+
return {
|
|
37261
|
+
net: 0,
|
|
37262
|
+
splits: [{
|
|
37263
|
+
apy: 0,
|
|
37264
|
+
id: "base"
|
|
37265
|
+
}, {
|
|
37266
|
+
apy: 0,
|
|
37267
|
+
id: "defispring"
|
|
37268
|
+
}]
|
|
37269
|
+
};
|
|
37066
37270
|
}
|
|
37067
37271
|
const baseAPY = this.computeAPY(baseAPYs, weights, prevAUMUSD);
|
|
37068
37272
|
const rewardAPY = this.computeAPY(rewardAPYs, weights, prevAUMUSD);
|
|
37069
37273
|
const netAPY = baseAPY + rewardAPY;
|
|
37070
37274
|
logger.verbose(`${this.metadata.name}::netAPY: net: ${netAPY}, baseAPY: ${baseAPY}, rewardAPY: ${rewardAPY}`);
|
|
37071
|
-
return {
|
|
37072
|
-
|
|
37073
|
-
|
|
37074
|
-
|
|
37075
|
-
|
|
37076
|
-
|
|
37077
|
-
|
|
37275
|
+
return {
|
|
37276
|
+
net: netAPY,
|
|
37277
|
+
splits: [{
|
|
37278
|
+
apy: baseAPY,
|
|
37279
|
+
id: "base"
|
|
37280
|
+
}, {
|
|
37281
|
+
apy: rewardAPY,
|
|
37282
|
+
id: "defispring"
|
|
37283
|
+
}]
|
|
37284
|
+
};
|
|
37078
37285
|
}
|
|
37079
37286
|
async getUnusedBalanceAPY() {
|
|
37080
37287
|
return {
|
|
@@ -37088,104 +37295,6 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
|
|
|
37088
37295
|
logger.verbose(`${this.getTag()} computeAPY: apys: ${JSON.stringify(apys)}, weights: ${JSON.stringify(weights)}, weightedSum: ${weightedSum}, currentAUM: ${currentAUM}`);
|
|
37089
37296
|
return weightedSum / currentAUM.toNumber();
|
|
37090
37297
|
}
|
|
37091
|
-
/**
|
|
37092
|
-
* Calculates user realized APY based on trueSharesBasedAPY method.
|
|
37093
|
-
* Returns the APY as a number.
|
|
37094
|
-
*/
|
|
37095
|
-
async getUserRealizedAPY(blockIdentifier = "latest", sinceBlocks = 6e5) {
|
|
37096
|
-
logger.verbose(
|
|
37097
|
-
`${this.getTag()}: getUserRealizedAPY => starting with blockIdentifier=${blockIdentifier}, sinceBlocks=${sinceBlocks}`
|
|
37098
|
-
);
|
|
37099
|
-
let blockNow = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : (await this.config.provider.getBlockLatestAccepted()).block_number;
|
|
37100
|
-
const blockNowTime = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
|
|
37101
|
-
const blockBefore = Math.max(
|
|
37102
|
-
blockNow - sinceBlocks,
|
|
37103
|
-
this.metadata.launchBlock
|
|
37104
|
-
);
|
|
37105
|
-
const assetsNowRaw = await this.contract.call("total_assets", [], {
|
|
37106
|
-
blockIdentifier
|
|
37107
|
-
});
|
|
37108
|
-
const amountNow = Web3Number.fromWei(
|
|
37109
|
-
assetsNowRaw.toString(),
|
|
37110
|
-
this.metadata.depositTokens[0].decimals
|
|
37111
|
-
);
|
|
37112
|
-
const supplyNowRaw = await this.contract.call("total_supply", [], {
|
|
37113
|
-
blockIdentifier
|
|
37114
|
-
});
|
|
37115
|
-
const supplyNow = Web3Number.fromWei(supplyNowRaw.toString(), 18);
|
|
37116
|
-
const assetsBeforeRaw = await this.contract.call(
|
|
37117
|
-
"total_assets",
|
|
37118
|
-
[],
|
|
37119
|
-
{ blockIdentifier: blockBefore }
|
|
37120
|
-
);
|
|
37121
|
-
const amountBefore = Web3Number.fromWei(
|
|
37122
|
-
assetsBeforeRaw.toString(),
|
|
37123
|
-
this.metadata.depositTokens[0].decimals
|
|
37124
|
-
);
|
|
37125
|
-
const supplyBeforeRaw = await this.contract.call(
|
|
37126
|
-
"total_supply",
|
|
37127
|
-
[],
|
|
37128
|
-
{ blockIdentifier: blockBefore }
|
|
37129
|
-
);
|
|
37130
|
-
const supplyBefore = Web3Number.fromWei(supplyBeforeRaw.toString(), 18);
|
|
37131
|
-
const blockBeforeInfo = await this.config.provider.getBlockWithTxs(
|
|
37132
|
-
blockBefore
|
|
37133
|
-
);
|
|
37134
|
-
const assetsPerShareNow = amountNow.multipliedBy(1e18).dividedBy(supplyNow.toString());
|
|
37135
|
-
const assetsPerShareBf = amountBefore.multipliedBy(1e18).dividedBy(supplyBefore.toString());
|
|
37136
|
-
const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
|
|
37137
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsNow: ${amountNow.toString()}`);
|
|
37138
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsBefore: ${amountBefore.toString()}`);
|
|
37139
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareNow: ${assetsPerShareNow.toString()}`);
|
|
37140
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareBf: ${assetsPerShareBf.toString()}`);
|
|
37141
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply before: ${supplyBefore.toString()}`);
|
|
37142
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply now: ${supplyNow.toString()}`);
|
|
37143
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] Time diff in seconds: ${timeDiffSeconds}`);
|
|
37144
|
-
const apyForGivenBlocks = Number(
|
|
37145
|
-
assetsPerShareNow.minus(assetsPerShareBf).multipliedBy(1e4).dividedBy(assetsPerShareBf)
|
|
37146
|
-
) / 1e4;
|
|
37147
|
-
return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
|
|
37148
|
-
}
|
|
37149
|
-
async getUserPositionCards(input) {
|
|
37150
|
-
const { user, investmentFlows = [] } = input;
|
|
37151
|
-
const [userTVL] = await Promise.all([
|
|
37152
|
-
this.getUserTVL(user)
|
|
37153
|
-
]);
|
|
37154
|
-
const cards = [
|
|
37155
|
-
{
|
|
37156
|
-
title: "Your Holdings",
|
|
37157
|
-
tooltip: "Your Holdings",
|
|
37158
|
-
value: this.formatTokenAmountForCard(userTVL.amount, userTVL.tokenInfo),
|
|
37159
|
-
subValue: `\u2248 ${this.formatUSDForCard(userTVL.usdValue)}`,
|
|
37160
|
-
subValueColor: "positive"
|
|
37161
|
-
}
|
|
37162
|
-
];
|
|
37163
|
-
let lifetimeAmount = userTVL.amount.multipliedBy(0);
|
|
37164
|
-
let lifetimeTokenInfo = userTVL.tokenInfo;
|
|
37165
|
-
let lifetimeUsdValue = 0;
|
|
37166
|
-
if (investmentFlows.length > 0) {
|
|
37167
|
-
try {
|
|
37168
|
-
const earningsResult = this.getLifetimeEarnings(userTVL, investmentFlows);
|
|
37169
|
-
lifetimeAmount = earningsResult.lifetimeEarnings;
|
|
37170
|
-
lifetimeTokenInfo = earningsResult.tokenInfo.tokenInfo;
|
|
37171
|
-
const userAmount = userTVL.amount.toNumber();
|
|
37172
|
-
if (Number.isFinite(userAmount) && userAmount > 0) {
|
|
37173
|
-
const pricePerToken = userTVL.usdValue / userAmount;
|
|
37174
|
-
lifetimeUsdValue = lifetimeAmount.toNumber() * pricePerToken;
|
|
37175
|
-
}
|
|
37176
|
-
} catch (error) {
|
|
37177
|
-
logger.warn(`${this.getTag()}::getUserPositionCards lifetime earnings fallback`, error);
|
|
37178
|
-
}
|
|
37179
|
-
}
|
|
37180
|
-
cards.push({
|
|
37181
|
-
title: "Lifetime Earnings",
|
|
37182
|
-
tooltip: "Lifetime Earnings",
|
|
37183
|
-
value: this.formatTokenAmountForCard(lifetimeAmount, lifetimeTokenInfo),
|
|
37184
|
-
subValue: `\u2248 ${this.formatUSDForCard(lifetimeUsdValue)}`,
|
|
37185
|
-
subValueColor: this.getSubValueColorFromSignedNumber(lifetimeUsdValue)
|
|
37186
|
-
});
|
|
37187
|
-
return cards;
|
|
37188
|
-
}
|
|
37189
37298
|
/**
|
|
37190
37299
|
* Calculates the total TVL of the strategy.
|
|
37191
37300
|
* @returns Object containing the total amount in token units and USD value
|
|
@@ -37262,13 +37371,17 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
|
|
|
37262
37371
|
};
|
|
37263
37372
|
const aumToken = vesuAum.plus(balance.amount);
|
|
37264
37373
|
if (aumToken.isZero()) {
|
|
37265
|
-
return {
|
|
37266
|
-
|
|
37267
|
-
|
|
37268
|
-
|
|
37269
|
-
|
|
37270
|
-
|
|
37271
|
-
|
|
37374
|
+
return {
|
|
37375
|
+
net,
|
|
37376
|
+
splits: [{
|
|
37377
|
+
aum: zeroAmt,
|
|
37378
|
+
id: "finalised" /* FINALISED */
|
|
37379
|
+
}, {
|
|
37380
|
+
aum: zeroAmt,
|
|
37381
|
+
id: "defispring" /* DEFISPRING */
|
|
37382
|
+
}],
|
|
37383
|
+
prevAum
|
|
37384
|
+
};
|
|
37272
37385
|
}
|
|
37273
37386
|
logger.verbose(`${this.getTag()} Actual AUM: ${aumToken}`);
|
|
37274
37387
|
const rewardAssets = await this.getRewardsAUM(prevAum);
|
|
@@ -37921,6 +38034,9 @@ var createUniversalStrategy = (params) => {
|
|
|
37921
38034
|
auditUrl: AUDIT_URL3,
|
|
37922
38035
|
protocols: [Protocols.VESU],
|
|
37923
38036
|
realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
|
|
38037
|
+
feeBps: {
|
|
38038
|
+
performanceFeeBps: 1e3
|
|
38039
|
+
},
|
|
37924
38040
|
curator: UnwrapLabsCurator,
|
|
37925
38041
|
settings: createUniversalSettings(params.tokenSymbol, params.maxTVLDecimals),
|
|
37926
38042
|
contractDetails: getContractDetails(params.vaultSettings),
|
|
@@ -38562,11 +38678,15 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
38562
38678
|
remarks: "defispring" /* DEFISPRING */,
|
|
38563
38679
|
protocol: Protocols.NONE
|
|
38564
38680
|
};
|
|
38565
|
-
return {
|
|
38566
|
-
|
|
38567
|
-
|
|
38568
|
-
|
|
38569
|
-
|
|
38681
|
+
return {
|
|
38682
|
+
net: {
|
|
38683
|
+
tokenInfo: underlying,
|
|
38684
|
+
amount: netAUM,
|
|
38685
|
+
usdValue: netAUM.toNumber() * assetPrice.price
|
|
38686
|
+
},
|
|
38687
|
+
prevAum,
|
|
38688
|
+
splits: [realAUM, estimatedAUMDelta]
|
|
38689
|
+
};
|
|
38570
38690
|
}
|
|
38571
38691
|
async getTVLUnrealized() {
|
|
38572
38692
|
return await this.getAUM(true);
|
|
@@ -38584,6 +38704,62 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
38584
38704
|
tokenInfo: this.asset()
|
|
38585
38705
|
};
|
|
38586
38706
|
}
|
|
38707
|
+
async getUserPositionCards(input) {
|
|
38708
|
+
const cards = await super.getUserPositionCards(input);
|
|
38709
|
+
try {
|
|
38710
|
+
const [unrealizedResult, userTVL, realizedApyRaw] = await Promise.all([
|
|
38711
|
+
this.getUserUnrealizedGains(input.user),
|
|
38712
|
+
this.getUserTVL(input.user),
|
|
38713
|
+
this.getUserRealizedAPY().catch(() => null)
|
|
38714
|
+
]);
|
|
38715
|
+
const amount = unrealizedResult.unrealizedGains;
|
|
38716
|
+
let usdValue = 0;
|
|
38717
|
+
const userAmount = userTVL.amount.toNumber();
|
|
38718
|
+
if (Number.isFinite(userAmount) && userAmount > 0) {
|
|
38719
|
+
usdValue = userTVL.usdValue / userAmount * amount.toNumber();
|
|
38720
|
+
}
|
|
38721
|
+
cards.push({
|
|
38722
|
+
title: "Unrealized Gains",
|
|
38723
|
+
tooltip: "Unrealized gains based on current market prices vs Endur prices. If you withdraw now, you will forgo these gains.",
|
|
38724
|
+
value: this.formatTokenAmountForCard(amount, unrealizedResult.tokenInfo),
|
|
38725
|
+
subValue: `\u2248 ${this.formatUSDForCard(usdValue)}`,
|
|
38726
|
+
subValueColor: this.getSubValueColorFromSignedNumber(usdValue)
|
|
38727
|
+
});
|
|
38728
|
+
const realizedApy = typeof realizedApyRaw === "number" ? this.formatPercentForCard(realizedApyRaw) : "N/A";
|
|
38729
|
+
cards.push({
|
|
38730
|
+
title: "Realized APY",
|
|
38731
|
+
tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
|
|
38732
|
+
value: realizedApy
|
|
38733
|
+
});
|
|
38734
|
+
} catch (error) {
|
|
38735
|
+
logger.warn(`${this.getTag()}::getUserPositionCards unrealized gains fallback`, error);
|
|
38736
|
+
cards.push({
|
|
38737
|
+
title: "Unrealized Gains",
|
|
38738
|
+
tooltip: "Unrealized gains based on current market prices vs Endur prices. If you withdraw now, you will forgo these gains.",
|
|
38739
|
+
value: this.formatTokenAmountForCard(
|
|
38740
|
+
Web3Number.fromWei("0", this.asset().decimals),
|
|
38741
|
+
this.asset()
|
|
38742
|
+
),
|
|
38743
|
+
subValue: `\u2248 ${this.formatUSDForCard(0)}`,
|
|
38744
|
+
subValueColor: "default"
|
|
38745
|
+
});
|
|
38746
|
+
cards.push({
|
|
38747
|
+
title: "Realized APY",
|
|
38748
|
+
tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
|
|
38749
|
+
value: "N/A"
|
|
38750
|
+
});
|
|
38751
|
+
}
|
|
38752
|
+
if (this.asset().symbol === "xSTRK") {
|
|
38753
|
+
const index = cards.findIndex((card) => card.title === "Lifetime Earnings");
|
|
38754
|
+
if (index >= 0) {
|
|
38755
|
+
cards[index] = {
|
|
38756
|
+
...cards[index],
|
|
38757
|
+
tooltip: "Lifetime earnings of the vault. Due to migration of xSTRK Sensei to this vault, any migrated funds are also seen as lifetime earnings. Team is working to fix this soon."
|
|
38758
|
+
};
|
|
38759
|
+
}
|
|
38760
|
+
}
|
|
38761
|
+
return cards;
|
|
38762
|
+
}
|
|
38587
38763
|
};
|
|
38588
38764
|
function VaultDescription(lstSymbol, underlyingSymbol) {
|
|
38589
38765
|
const containerStyle = {
|
|
@@ -38991,6 +39167,9 @@ function getStrategySettings(lstSymbol, underlyingSymbol, settings, isPreview =
|
|
|
38991
39167
|
isPreview,
|
|
38992
39168
|
apyMethodology: "Current annualized APY in terms of base asset of the LST. There is no additional fee taken by Troves on LST APY. We charge a 10% performance fee on the additional gain which is already accounted in the APY shown.",
|
|
38993
39169
|
realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
|
|
39170
|
+
feeBps: {
|
|
39171
|
+
performanceFeeBps: 1e3
|
|
39172
|
+
},
|
|
38994
39173
|
tags: lstSymbol.includes("BTC") ? ["BTC" /* BTC */, "Maxx" /* LEVERED */] : ["Maxx" /* LEVERED */],
|
|
38995
39174
|
security: HYPER_LST_SECURITY,
|
|
38996
39175
|
redemptionInfo: HYPER_LST_REDEMPTION_INFO,
|
|
@@ -39204,6 +39383,23 @@ var BoostedxSTRKCarryStrategy = class _BoostedxSTRKCarryStrategy extends SVKStra
|
|
|
39204
39383
|
usdValue
|
|
39205
39384
|
};
|
|
39206
39385
|
}
|
|
39386
|
+
async getUserPositionCards(input) {
|
|
39387
|
+
const cards = await super.getUserPositionCards(input);
|
|
39388
|
+
const realizedApyRaw = await this.getUserRealizedAPY().catch((error) => {
|
|
39389
|
+
logger.warn(
|
|
39390
|
+
`${this.getTag()}::getUserPositionCards realized APY fallback`,
|
|
39391
|
+
error
|
|
39392
|
+
);
|
|
39393
|
+
return null;
|
|
39394
|
+
});
|
|
39395
|
+
const realizedApy = typeof realizedApyRaw === "number" ? this.formatPercentForCard(realizedApyRaw) : "N/A";
|
|
39396
|
+
cards.push({
|
|
39397
|
+
title: "Realized APY",
|
|
39398
|
+
tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
|
|
39399
|
+
value: realizedApy
|
|
39400
|
+
});
|
|
39401
|
+
return cards;
|
|
39402
|
+
}
|
|
39207
39403
|
async getAUM() {
|
|
39208
39404
|
const underlying = this.asset();
|
|
39209
39405
|
const depositTokenPrice = await this.pricer.getPrice(underlying.symbol);
|
|
@@ -39793,15 +39989,15 @@ function getBoostedCarryFAQs(depositSymbol, debtSymbol, lstSymbol) {
|
|
|
39793
39989
|
question: "Which protocols are used?",
|
|
39794
39990
|
answer: /* @__PURE__ */ jsxs5("span", { children: [
|
|
39795
39991
|
/* @__PURE__ */ jsx6("strong", { children: "Vesu" }),
|
|
39796
|
-
" for collateral and borrowing,
|
|
39797
|
-
/* @__PURE__ */ jsx6("strong", { children: "Avnu" }),
|
|
39992
|
+
" for collateral and borrowing,",
|
|
39798
39993
|
" ",
|
|
39799
|
-
"
|
|
39994
|
+
/* @__PURE__ */ jsx6("strong", { children: "Avnu" }),
|
|
39995
|
+
" for swaps, ",
|
|
39800
39996
|
/* @__PURE__ */ jsx6("strong", { children: "Endur" }),
|
|
39801
|
-
" for
|
|
39802
|
-
lstSymbol,
|
|
39803
|
-
", and the Troves",
|
|
39997
|
+
" for",
|
|
39804
39998
|
" ",
|
|
39999
|
+
lstSymbol,
|
|
40000
|
+
", and the Troves ",
|
|
39805
40001
|
/* @__PURE__ */ jsxs5("strong", { children: [
|
|
39806
40002
|
"Hyper-",
|
|
39807
40003
|
lstSymbol
|
|
@@ -39889,6 +40085,9 @@ function getStrategySettings2(settings, meta) {
|
|
|
39889
40085
|
]
|
|
39890
40086
|
},
|
|
39891
40087
|
contractDetails: getContractDetails(settings),
|
|
40088
|
+
feeBps: {
|
|
40089
|
+
performanceFeeBps: 1500
|
|
40090
|
+
},
|
|
39892
40091
|
faqs: getBoostedCarryFAQs(
|
|
39893
40092
|
depositToken.symbol,
|
|
39894
40093
|
debtToken.symbol,
|
|
@@ -40254,6 +40453,7 @@ export {
|
|
|
40254
40453
|
PositionTypeAvnuExtended,
|
|
40255
40454
|
Pragma,
|
|
40256
40455
|
Pricer,
|
|
40456
|
+
PricerAvnuApi,
|
|
40257
40457
|
PricerBase,
|
|
40258
40458
|
PricerFromApi,
|
|
40259
40459
|
PricerLST,
|