@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.js
CHANGED
|
@@ -78,6 +78,7 @@ __export(index_exports, {
|
|
|
78
78
|
PositionTypeAvnuExtended: () => PositionTypeAvnuExtended,
|
|
79
79
|
Pragma: () => Pragma,
|
|
80
80
|
Pricer: () => Pricer,
|
|
81
|
+
PricerAvnuApi: () => PricerAvnuApi,
|
|
81
82
|
PricerBase: () => PricerBase,
|
|
82
83
|
PricerFromApi: () => PricerFromApi,
|
|
83
84
|
PricerLST: () => PricerLST2,
|
|
@@ -832,20 +833,20 @@ var defaultTokens = [
|
|
|
832
833
|
decimals: 18,
|
|
833
834
|
coingeckId: void 0,
|
|
834
835
|
displayDecimals: 6,
|
|
835
|
-
priceCheckAmount: 1e-4
|
|
836
|
+
priceCheckAmount: 1e-4,
|
|
836
837
|
// 112000 * 0.0001 = $11.2
|
|
838
|
+
dontPrice: true
|
|
837
839
|
},
|
|
838
840
|
{
|
|
839
841
|
name: "mRe7YIELD",
|
|
840
842
|
symbol: "mRe7YIELD",
|
|
841
843
|
logo: "https://midas.app/assets/mre7-BcOOHm7i.svg",
|
|
842
|
-
address: ContractAddr.from(
|
|
843
|
-
"0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"
|
|
844
|
-
),
|
|
844
|
+
address: ContractAddr.from("0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"),
|
|
845
845
|
decimals: 18,
|
|
846
846
|
coingeckId: void 0,
|
|
847
847
|
displayDecimals: 2,
|
|
848
|
-
priceCheckAmount: 100
|
|
848
|
+
priceCheckAmount: 100,
|
|
849
|
+
dontPrice: true
|
|
849
850
|
},
|
|
850
851
|
{
|
|
851
852
|
name: "fyWBTC",
|
|
@@ -855,8 +856,9 @@ var defaultTokens = [
|
|
|
855
856
|
decimals: 8,
|
|
856
857
|
coingeckId: void 0,
|
|
857
858
|
displayDecimals: 6,
|
|
858
|
-
priceCheckAmount: 1e-3
|
|
859
|
+
priceCheckAmount: 1e-3,
|
|
859
860
|
// 112000 * 0.0001 = $110.2
|
|
861
|
+
dontPrice: true
|
|
860
862
|
},
|
|
861
863
|
{
|
|
862
864
|
name: "fyETH",
|
|
@@ -866,7 +868,8 @@ var defaultTokens = [
|
|
|
866
868
|
decimals: 18,
|
|
867
869
|
coingeckId: void 0,
|
|
868
870
|
displayDecimals: 4,
|
|
869
|
-
priceCheckAmount: 0.1
|
|
871
|
+
priceCheckAmount: 0.1,
|
|
872
|
+
dontPrice: true
|
|
870
873
|
},
|
|
871
874
|
{
|
|
872
875
|
name: "fyUSDC",
|
|
@@ -876,7 +879,8 @@ var defaultTokens = [
|
|
|
876
879
|
decimals: 6,
|
|
877
880
|
coingeckId: void 0,
|
|
878
881
|
displayDecimals: 2,
|
|
879
|
-
priceCheckAmount: 100
|
|
882
|
+
priceCheckAmount: 100,
|
|
883
|
+
dontPrice: true
|
|
880
884
|
},
|
|
881
885
|
{
|
|
882
886
|
name: "strkBTC",
|
|
@@ -3894,7 +3898,7 @@ var TokenMarketData = class {
|
|
|
3894
3898
|
};
|
|
3895
3899
|
|
|
3896
3900
|
// src/modules/pricer.ts
|
|
3897
|
-
var
|
|
3901
|
+
var import_axios4 = __toESM(require("axios"));
|
|
3898
3902
|
|
|
3899
3903
|
// src/modules/pricerBase.ts
|
|
3900
3904
|
var PricerBase = class {
|
|
@@ -3998,7 +4002,96 @@ var AvnuWrapper = class _AvnuWrapper {
|
|
|
3998
4002
|
}
|
|
3999
4003
|
};
|
|
4000
4004
|
|
|
4005
|
+
// src/modules/pricer-avnu-api.ts
|
|
4006
|
+
var import_axios3 = __toESM(require("axios"));
|
|
4007
|
+
var AVNU_TOKENS_API = "https://starknet.impulse.avnu.fi/v3/tokens";
|
|
4008
|
+
var PricerAvnuApi = class extends PricerBase {
|
|
4009
|
+
constructor(config, tokens2) {
|
|
4010
|
+
super(config, tokens2);
|
|
4011
|
+
this.prices = {};
|
|
4012
|
+
this.refreshInterval = 15e3;
|
|
4013
|
+
this.staleTime = 5 * 60 * 1e3;
|
|
4014
|
+
this.pollTimer = null;
|
|
4015
|
+
this.loading = false;
|
|
4016
|
+
}
|
|
4017
|
+
start() {
|
|
4018
|
+
this._loadPrices();
|
|
4019
|
+
this.pollTimer = setInterval(() => {
|
|
4020
|
+
this._loadPrices();
|
|
4021
|
+
}, this.refreshInterval);
|
|
4022
|
+
}
|
|
4023
|
+
stop() {
|
|
4024
|
+
if (this.pollTimer) {
|
|
4025
|
+
clearInterval(this.pollTimer);
|
|
4026
|
+
this.pollTimer = null;
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
isStale(timestamp) {
|
|
4030
|
+
return Date.now() - timestamp.getTime() > this.staleTime;
|
|
4031
|
+
}
|
|
4032
|
+
hasPrice(tokenSymbol) {
|
|
4033
|
+
const info = this.prices[tokenSymbol];
|
|
4034
|
+
return !!info && !this.isStale(info.timestamp);
|
|
4035
|
+
}
|
|
4036
|
+
async getPrice(tokenSymbol) {
|
|
4037
|
+
const info = this.prices[tokenSymbol];
|
|
4038
|
+
if (!info) {
|
|
4039
|
+
throw new Error(`AvnuApi: price of ${tokenSymbol} not found`);
|
|
4040
|
+
}
|
|
4041
|
+
if (this.isStale(info.timestamp)) {
|
|
4042
|
+
throw new Error(`AvnuApi: price of ${tokenSymbol} is stale`);
|
|
4043
|
+
}
|
|
4044
|
+
return info;
|
|
4045
|
+
}
|
|
4046
|
+
async _loadPrices() {
|
|
4047
|
+
if (this.loading) {
|
|
4048
|
+
return;
|
|
4049
|
+
}
|
|
4050
|
+
this.loading = true;
|
|
4051
|
+
const timestamp = /* @__PURE__ */ new Date();
|
|
4052
|
+
try {
|
|
4053
|
+
const result = await import_axios3.default.get(AVNU_TOKENS_API);
|
|
4054
|
+
const priceByAddress = /* @__PURE__ */ new Map();
|
|
4055
|
+
for (const entry of result.data) {
|
|
4056
|
+
const usd = entry.starknet?.usd;
|
|
4057
|
+
if (usd != null && usd > 0) {
|
|
4058
|
+
priceByAddress.set(ContractAddr.standardise(entry.address), usd);
|
|
4059
|
+
}
|
|
4060
|
+
}
|
|
4061
|
+
for (const token of this.tokens) {
|
|
4062
|
+
if (token.symbol === "USDT" || token.symbol === "USDC") {
|
|
4063
|
+
this.prices[token.symbol] = { price: 1, timestamp };
|
|
4064
|
+
continue;
|
|
4065
|
+
}
|
|
4066
|
+
const targetToken = token.priceProxySymbol ? this.tokens.find((t) => t.symbol === token.priceProxySymbol) : token;
|
|
4067
|
+
if (!targetToken) {
|
|
4068
|
+
continue;
|
|
4069
|
+
}
|
|
4070
|
+
const addr = targetToken.address.address;
|
|
4071
|
+
const price = priceByAddress.get(addr);
|
|
4072
|
+
if (price != null) {
|
|
4073
|
+
this.prices[token.symbol] = { price, timestamp };
|
|
4074
|
+
logger.verbose(
|
|
4075
|
+
`AvnuApi: ${token.symbol} -> $${price}`
|
|
4076
|
+
);
|
|
4077
|
+
}
|
|
4078
|
+
}
|
|
4079
|
+
} catch (error) {
|
|
4080
|
+
logger.warn(`AvnuApi: failed to fetch tokens: ${error?.message ?? error}`);
|
|
4081
|
+
} finally {
|
|
4082
|
+
this.loading = false;
|
|
4083
|
+
}
|
|
4084
|
+
}
|
|
4085
|
+
};
|
|
4086
|
+
|
|
4001
4087
|
// src/modules/pricer.ts
|
|
4088
|
+
var PRICE_METHOD_PRIORITY = [
|
|
4089
|
+
"AvnuApi",
|
|
4090
|
+
"Coinbase",
|
|
4091
|
+
"Coinmarketcap",
|
|
4092
|
+
"Ekubo",
|
|
4093
|
+
"Avnu"
|
|
4094
|
+
];
|
|
4002
4095
|
var Pricer = class extends PricerBase {
|
|
4003
4096
|
// e.g. ETH/USDC
|
|
4004
4097
|
constructor(config, tokens2, refreshInterval = 3e4, staleTime = 6e4) {
|
|
@@ -4017,6 +4110,7 @@ var Pricer = class extends PricerBase {
|
|
|
4017
4110
|
this.EKUBO_API = "https://prod-api-quoter.ekubo.org/23448594291968334/{{AMOUNT}}/{{TOKEN_ADDRESS}}/0x033068F6539f8e6e6b131e6B2B814e6c34A5224bC66947c47DaB9dFeE93b35fb";
|
|
4018
4111
|
this.refreshInterval = refreshInterval;
|
|
4019
4112
|
this.staleTime = staleTime;
|
|
4113
|
+
this.avnuApiPricer = new PricerAvnuApi(config, tokens2);
|
|
4020
4114
|
}
|
|
4021
4115
|
isReady() {
|
|
4022
4116
|
const allPricesExist = Object.keys(this.prices).length === this.tokens.length;
|
|
@@ -4046,6 +4140,7 @@ var Pricer = class extends PricerBase {
|
|
|
4046
4140
|
});
|
|
4047
4141
|
}
|
|
4048
4142
|
start() {
|
|
4143
|
+
this.avnuApiPricer.start();
|
|
4049
4144
|
this._loadPrices();
|
|
4050
4145
|
setInterval(() => {
|
|
4051
4146
|
this._loadPrices();
|
|
@@ -4070,6 +4165,9 @@ var Pricer = class extends PricerBase {
|
|
|
4070
4165
|
let retry = 0;
|
|
4071
4166
|
while (retry < MAX_RETRIES) {
|
|
4072
4167
|
try {
|
|
4168
|
+
if (token.dontPrice) {
|
|
4169
|
+
return;
|
|
4170
|
+
}
|
|
4073
4171
|
if (token.symbol === "USDT" || token.symbol === "USDC") {
|
|
4074
4172
|
this.prices[token.symbol] = {
|
|
4075
4173
|
price: 1,
|
|
@@ -4112,60 +4210,61 @@ var Pricer = class extends PricerBase {
|
|
|
4112
4210
|
});
|
|
4113
4211
|
if (this.isReady() && this.config.heartbeatUrl) {
|
|
4114
4212
|
console.log(`sending beat`);
|
|
4115
|
-
|
|
4213
|
+
import_axios4.default.get(this.config.heartbeatUrl).catch((err) => {
|
|
4116
4214
|
console.error("Pricer: Heartbeat err", err);
|
|
4117
4215
|
});
|
|
4118
4216
|
}
|
|
4119
4217
|
}
|
|
4120
|
-
async _getPrice(token
|
|
4121
|
-
const
|
|
4122
|
-
|
|
4123
|
-
|
|
4218
|
+
async _getPrice(token) {
|
|
4219
|
+
const pinned = this.methodToUse[token.symbol];
|
|
4220
|
+
if (pinned) {
|
|
4221
|
+
logger.verbose(`Fetching price of ${token.symbol} using pinned ${pinned}`);
|
|
4222
|
+
try {
|
|
4223
|
+
return await this._tryPriceMethod(token, pinned);
|
|
4224
|
+
} catch (error) {
|
|
4225
|
+
console.warn(`${pinned}: pinned price failed [${token.symbol}]: `, error.message);
|
|
4226
|
+
delete this.methodToUse[token.symbol];
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
for (const method of PRICE_METHOD_PRIORITY) {
|
|
4230
|
+
logger.verbose(`Fetching price of ${token.symbol} using ${method}`);
|
|
4231
|
+
try {
|
|
4232
|
+
const result = await this._tryPriceMethod(token, method);
|
|
4233
|
+
this.methodToUse[token.symbol] = method;
|
|
4234
|
+
return result;
|
|
4235
|
+
} catch (error) {
|
|
4236
|
+
console.warn(`${method}: price err [${token.symbol}]: `, error.message);
|
|
4237
|
+
}
|
|
4238
|
+
}
|
|
4239
|
+
throw new FatalError(`Price not found for ${token.symbol}`);
|
|
4240
|
+
}
|
|
4241
|
+
async _tryPriceMethod(token, method) {
|
|
4242
|
+
switch (method) {
|
|
4243
|
+
case "AvnuApi":
|
|
4244
|
+
return await this._getPriceAvnuApi(token);
|
|
4124
4245
|
case "Coinbase":
|
|
4125
|
-
|
|
4126
|
-
// const result = await this._getPriceCoinbase(token);
|
|
4127
|
-
// this.methodToUse[token.symbol] = 'Coinbase';
|
|
4128
|
-
// return result;
|
|
4129
|
-
// } catch (error: any) {
|
|
4130
|
-
// console.warn(`Coinbase: price err: message [${token.symbol}]: `, error.message);
|
|
4131
|
-
// // do nothing, try next
|
|
4132
|
-
// }
|
|
4246
|
+
return await this._getPriceCoinbase(token);
|
|
4133
4247
|
case "Coinmarketcap":
|
|
4134
|
-
|
|
4135
|
-
const result = await this._getPriceCoinMarketCap(token);
|
|
4136
|
-
this.methodToUse[token.symbol] = "Coinmarketcap";
|
|
4137
|
-
return result;
|
|
4138
|
-
} catch (error) {
|
|
4139
|
-
console.warn(`CoinMarketCap: price err [${token.symbol}]: `, Object.keys(error));
|
|
4140
|
-
console.warn(`CoinMarketCap: price err [${token.symbol}]: `, error.message);
|
|
4141
|
-
}
|
|
4248
|
+
return await this._getPriceCoinMarketCap(token);
|
|
4142
4249
|
case "Ekubo":
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
} catch (error) {
|
|
4148
|
-
console.warn(`Ekubo: price err [${token.symbol}]: `, error.message);
|
|
4149
|
-
console.warn(`Ekubo: price err [${token.symbol}]: `, Object.keys(error));
|
|
4150
|
-
}
|
|
4250
|
+
return await this._getPriceEkubo(
|
|
4251
|
+
token,
|
|
4252
|
+
new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals)
|
|
4253
|
+
);
|
|
4151
4254
|
case "Avnu":
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
} catch (error) {
|
|
4157
|
-
console.warn(`Avnu: price err [${token.symbol}]: `, error.message);
|
|
4158
|
-
console.warn(`Avnu: price err [${token.symbol}]: `, Object.keys(error));
|
|
4159
|
-
}
|
|
4160
|
-
}
|
|
4161
|
-
if (defaultMethod == "all") {
|
|
4162
|
-
return await this._getPrice(token, "Coinbase");
|
|
4255
|
+
return await this._getAvnuPrice(
|
|
4256
|
+
token,
|
|
4257
|
+
new Web3Number(token.priceCheckAmount ? token.priceCheckAmount : 1, token.decimals)
|
|
4258
|
+
);
|
|
4163
4259
|
}
|
|
4164
|
-
|
|
4260
|
+
}
|
|
4261
|
+
async _getPriceAvnuApi(token) {
|
|
4262
|
+
const priceInfo = await this.avnuApiPricer.getPrice(token.symbol);
|
|
4263
|
+
return priceInfo.price;
|
|
4165
4264
|
}
|
|
4166
4265
|
async _getPriceCoinbase(token) {
|
|
4167
4266
|
const url = this.PRICE_API.replace("{{PRICER_KEY}}", `${token.symbol}-USD`);
|
|
4168
|
-
const result = await
|
|
4267
|
+
const result = await import_axios4.default.get(url);
|
|
4169
4268
|
const data = result.data;
|
|
4170
4269
|
return Number(data.data.amount);
|
|
4171
4270
|
}
|
|
@@ -4191,7 +4290,7 @@ var Pricer = class extends PricerBase {
|
|
|
4191
4290
|
async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
|
|
4192
4291
|
logger.verbose(`Getting price of ${token.symbol} using Ekubo, amountIn: ${amountIn.toWei()}`);
|
|
4193
4292
|
const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei());
|
|
4194
|
-
const result = await
|
|
4293
|
+
const result = await import_axios4.default.get(url);
|
|
4195
4294
|
const data = result.data;
|
|
4196
4295
|
const multiplier = 1 / amountIn.toNumber();
|
|
4197
4296
|
const outputUSDC = Number(Web3Number.fromWei(data.total_calculated, 6).toFixed(6)) * multiplier;
|
|
@@ -4337,7 +4436,7 @@ var Pragma = class extends PricerBase {
|
|
|
4337
4436
|
};
|
|
4338
4437
|
|
|
4339
4438
|
// src/modules/zkLend.ts
|
|
4340
|
-
var
|
|
4439
|
+
var import_axios5 = __toESM(require("axios"));
|
|
4341
4440
|
|
|
4342
4441
|
// src/dataTypes/bignumber.browser.ts
|
|
4343
4442
|
var import_starknet11 = require("starknet");
|
|
@@ -4396,7 +4495,7 @@ var _ZkLend = class _ZkLend extends ILending {
|
|
|
4396
4495
|
async init() {
|
|
4397
4496
|
try {
|
|
4398
4497
|
logger.verbose(`Initialising ${this.metadata.name}`);
|
|
4399
|
-
const result = await
|
|
4498
|
+
const result = await import_axios5.default.get(_ZkLend.POOLS_URL);
|
|
4400
4499
|
const data = result.data;
|
|
4401
4500
|
const savedTokens = await Global.getTokens();
|
|
4402
4501
|
data.forEach((pool) => {
|
|
@@ -4488,7 +4587,7 @@ var _ZkLend = class _ZkLend extends ILending {
|
|
|
4488
4587
|
*/
|
|
4489
4588
|
async getPositions(user) {
|
|
4490
4589
|
const url = this.POSITION_URL.replace("{{USER_ADDR}}", user.address);
|
|
4491
|
-
const result = await
|
|
4590
|
+
const result = await import_axios5.default.get(url);
|
|
4492
4591
|
const data = result.data;
|
|
4493
4592
|
const lendingPosition = [];
|
|
4494
4593
|
logger.verbose(`${this.metadata.name}:: Positions: ${JSON.stringify(data)}`);
|
|
@@ -4521,7 +4620,7 @@ _ZkLend.POOLS_URL = "https://app.zklend.com/api/pools";
|
|
|
4521
4620
|
var ZkLend = _ZkLend;
|
|
4522
4621
|
|
|
4523
4622
|
// src/modules/pricer-from-api.ts
|
|
4524
|
-
var
|
|
4623
|
+
var import_axios6 = __toESM(require("axios"));
|
|
4525
4624
|
|
|
4526
4625
|
// src/modules/apollo-client-config.ts
|
|
4527
4626
|
var import_client = require("@apollo/client");
|
|
@@ -4908,7 +5007,7 @@ var PricerFromApi = class extends PricerBase {
|
|
|
4908
5007
|
const MAX_RETRIES = 5;
|
|
4909
5008
|
for (retry = 1; retry < MAX_RETRIES + 1; retry++) {
|
|
4910
5009
|
try {
|
|
4911
|
-
const priceInfo = await
|
|
5010
|
+
const priceInfo = await import_axios6.default.get(
|
|
4912
5011
|
`https://api.coinbase.com/v2/prices/${tokenSymbol}-USDT/spot`
|
|
4913
5012
|
);
|
|
4914
5013
|
if (!priceInfo) {
|
|
@@ -6219,7 +6318,7 @@ var ERC20 = class {
|
|
|
6219
6318
|
};
|
|
6220
6319
|
|
|
6221
6320
|
// src/modules/ekubo-quoter.ts
|
|
6222
|
-
var
|
|
6321
|
+
var import_axios7 = __toESM(require("axios"));
|
|
6223
6322
|
var import_starknet14 = require("starknet");
|
|
6224
6323
|
var import_starknet15 = require("starknet");
|
|
6225
6324
|
var EkuboQuoter = class _EkuboQuoter {
|
|
@@ -6232,7 +6331,7 @@ var EkuboQuoter = class _EkuboQuoter {
|
|
|
6232
6331
|
try {
|
|
6233
6332
|
const url = this.ENDPOINT.replace("{{AMOUNT}}", amount.toWei()).replace("{{TOKEN_FROM_ADDRESS}}", fromToken).replace("{{TOKEN_TO_ADDRESS}}", toToken);
|
|
6234
6333
|
logger.verbose(`EkuboQuoter::_callQuoterApi url: ${url}`);
|
|
6235
|
-
const quote = await
|
|
6334
|
+
const quote = await import_axios7.default.get(url);
|
|
6236
6335
|
return quote.data;
|
|
6237
6336
|
} catch (error) {
|
|
6238
6337
|
logger.error(`EkuboQuoter::_callQuoterApi error: ${error.message}`);
|
|
@@ -8243,9 +8342,9 @@ var BaseStrategy = class extends CacheClass {
|
|
|
8243
8342
|
};
|
|
8244
8343
|
|
|
8245
8344
|
// src/node/headless.browser.ts
|
|
8246
|
-
var
|
|
8345
|
+
var import_axios8 = __toESM(require("axios"));
|
|
8247
8346
|
async function getAPIUsingHeadlessBrowser(url) {
|
|
8248
|
-
const res = await
|
|
8347
|
+
const res = await import_axios8.default.get(url);
|
|
8249
8348
|
return res.data;
|
|
8250
8349
|
}
|
|
8251
8350
|
|
|
@@ -19750,6 +19849,9 @@ var xSTRKSTRK = {
|
|
|
19750
19849
|
},
|
|
19751
19850
|
apyMethodology: "APY based on 30-day historical performance, including fees and rewards.",
|
|
19752
19851
|
realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
|
|
19852
|
+
feeBps: {
|
|
19853
|
+
performanceFeeBps: 1e3
|
|
19854
|
+
},
|
|
19753
19855
|
additionalInfo: {
|
|
19754
19856
|
newBounds: {
|
|
19755
19857
|
lower: -1,
|
|
@@ -30476,6 +30578,9 @@ var YoloVaultStrategies = yoloVaultsConfig.map((yoloConfig) => {
|
|
|
30476
30578
|
notARisks: getNoRiskTags(yoloRiskFactors)
|
|
30477
30579
|
},
|
|
30478
30580
|
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.",
|
|
30581
|
+
feeBps: {
|
|
30582
|
+
performanceFeeBps: 1e3
|
|
30583
|
+
},
|
|
30479
30584
|
additionalInfo: {
|
|
30480
30585
|
mainToken: yoloConfig.mainToken,
|
|
30481
30586
|
secondaryToken: yoloConfig.secondaryToken,
|
|
@@ -33256,7 +33361,7 @@ var TokenTransferAdapter = class _TokenTransferAdapter extends BaseAdapter {
|
|
|
33256
33361
|
|
|
33257
33362
|
// src/strategies/universal-adapters/avnu-adapter.ts
|
|
33258
33363
|
var import_starknet32 = require("starknet");
|
|
33259
|
-
var
|
|
33364
|
+
var import_axios9 = __toESM(require("axios"));
|
|
33260
33365
|
var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
|
|
33261
33366
|
constructor(config) {
|
|
33262
33367
|
super(config, _AvnuAdapter.name, Protocols.AVNU);
|
|
@@ -33463,7 +33568,7 @@ var AvnuAdapter = class _AvnuAdapter extends BaseAdapter {
|
|
|
33463
33568
|
async fetchQuoteWithRetry(params, retries = 5) {
|
|
33464
33569
|
for (let attempt = 0; attempt < retries; attempt++) {
|
|
33465
33570
|
try {
|
|
33466
|
-
const response = await
|
|
33571
|
+
const response = await import_axios9.default.get(this.config.baseUrl, { params });
|
|
33467
33572
|
if (response.data && response.data.length > 0) {
|
|
33468
33573
|
return response;
|
|
33469
33574
|
}
|
|
@@ -36997,6 +37102,29 @@ var SVKStrategy = class extends BaseStrategy {
|
|
|
36997
37102
|
]);
|
|
36998
37103
|
return [call];
|
|
36999
37104
|
}
|
|
37105
|
+
async getUserTVL(user, blockIdentifier = "latest") {
|
|
37106
|
+
const shares = await this.contract.call("balanceOf", [user.address], { blockIdentifier });
|
|
37107
|
+
const assets = await this.contract.call(
|
|
37108
|
+
"convert_to_assets",
|
|
37109
|
+
[import_starknet34.uint256.bnToUint256(shares)],
|
|
37110
|
+
{ blockIdentifier }
|
|
37111
|
+
);
|
|
37112
|
+
const amount = Web3Number.fromWei(
|
|
37113
|
+
assets.toString(),
|
|
37114
|
+
this.metadata.depositTokens[0].decimals
|
|
37115
|
+
);
|
|
37116
|
+
const blockNumber = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : void 0;
|
|
37117
|
+
const price = await this.pricer.getPrice(
|
|
37118
|
+
this.metadata.depositTokens[0].symbol,
|
|
37119
|
+
blockNumber
|
|
37120
|
+
);
|
|
37121
|
+
const usdValue = Number(amount.toFixed(6)) * price.price;
|
|
37122
|
+
return {
|
|
37123
|
+
tokenInfo: this.asset(),
|
|
37124
|
+
amount,
|
|
37125
|
+
usdValue
|
|
37126
|
+
};
|
|
37127
|
+
}
|
|
37000
37128
|
/**
|
|
37001
37129
|
* Returns the unused balance in the vault allocator.
|
|
37002
37130
|
* Note: This function is common for any SVK strategy.
|
|
@@ -37188,6 +37316,100 @@ var SVKStrategy = class extends BaseStrategy {
|
|
|
37188
37316
|
usdValue
|
|
37189
37317
|
};
|
|
37190
37318
|
}
|
|
37319
|
+
async getUserRealizedAPY(blockIdentifier = "latest", sinceBlocks = 6e5) {
|
|
37320
|
+
logger.verbose(
|
|
37321
|
+
`${this.getTag()}: getUserRealizedAPY => starting with blockIdentifier=${blockIdentifier}, sinceBlocks=${sinceBlocks}`
|
|
37322
|
+
);
|
|
37323
|
+
const blockNow = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : (await this.config.provider.getBlockLatestAccepted()).block_number;
|
|
37324
|
+
const blockNowTime = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
|
|
37325
|
+
const blockBefore = Math.max(
|
|
37326
|
+
blockNow - sinceBlocks,
|
|
37327
|
+
this.metadata.launchBlock
|
|
37328
|
+
);
|
|
37329
|
+
const assetsNowRaw = await this.contract.call("total_assets", [], {
|
|
37330
|
+
blockIdentifier
|
|
37331
|
+
});
|
|
37332
|
+
const amountNow = Web3Number.fromWei(
|
|
37333
|
+
assetsNowRaw.toString(),
|
|
37334
|
+
this.metadata.depositTokens[0].decimals
|
|
37335
|
+
);
|
|
37336
|
+
const supplyNowRaw = await this.contract.call("total_supply", [], {
|
|
37337
|
+
blockIdentifier
|
|
37338
|
+
});
|
|
37339
|
+
const supplyNow = Web3Number.fromWei(supplyNowRaw.toString(), 18);
|
|
37340
|
+
const assetsBeforeRaw = await this.contract.call(
|
|
37341
|
+
"total_assets",
|
|
37342
|
+
[],
|
|
37343
|
+
{ blockIdentifier: blockBefore }
|
|
37344
|
+
);
|
|
37345
|
+
const amountBefore = Web3Number.fromWei(
|
|
37346
|
+
assetsBeforeRaw.toString(),
|
|
37347
|
+
this.metadata.depositTokens[0].decimals
|
|
37348
|
+
);
|
|
37349
|
+
const supplyBeforeRaw = await this.contract.call(
|
|
37350
|
+
"total_supply",
|
|
37351
|
+
[],
|
|
37352
|
+
{ blockIdentifier: blockBefore }
|
|
37353
|
+
);
|
|
37354
|
+
const supplyBefore = Web3Number.fromWei(supplyBeforeRaw.toString(), 18);
|
|
37355
|
+
const blockBeforeInfo = await this.config.provider.getBlockWithTxs(
|
|
37356
|
+
blockBefore
|
|
37357
|
+
);
|
|
37358
|
+
const assetsPerShareNow = amountNow.multipliedBy(1e18).dividedBy(supplyNow.toString());
|
|
37359
|
+
const assetsPerShareBf = amountBefore.multipliedBy(1e18).dividedBy(supplyBefore.toString());
|
|
37360
|
+
const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
|
|
37361
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsNow: ${amountNow.toString()}`);
|
|
37362
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsBefore: ${amountBefore.toString()}`);
|
|
37363
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareNow: ${assetsPerShareNow.toString()}`);
|
|
37364
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareBf: ${assetsPerShareBf.toString()}`);
|
|
37365
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply before: ${supplyBefore.toString()}`);
|
|
37366
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply now: ${supplyNow.toString()}`);
|
|
37367
|
+
logger.verbose(`${this.getTag()} [getUserRealizedAPY] Time diff in seconds: ${timeDiffSeconds}`);
|
|
37368
|
+
const apyForGivenBlocks = Number(
|
|
37369
|
+
assetsPerShareNow.minus(assetsPerShareBf).multipliedBy(1e4).dividedBy(assetsPerShareBf)
|
|
37370
|
+
) / 1e4;
|
|
37371
|
+
return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
|
|
37372
|
+
}
|
|
37373
|
+
async getUserPositionCards(input) {
|
|
37374
|
+
const { user, investmentFlows = [] } = input;
|
|
37375
|
+
const [userTVL] = await Promise.all([
|
|
37376
|
+
this.getUserTVL(user)
|
|
37377
|
+
]);
|
|
37378
|
+
const cards = [
|
|
37379
|
+
{
|
|
37380
|
+
title: "Your Holdings",
|
|
37381
|
+
tooltip: "Your Holdings",
|
|
37382
|
+
value: this.formatTokenAmountForCard(userTVL.amount, userTVL.tokenInfo),
|
|
37383
|
+
subValue: `\u2248 ${this.formatUSDForCard(userTVL.usdValue)}`,
|
|
37384
|
+
subValueColor: "positive"
|
|
37385
|
+
}
|
|
37386
|
+
];
|
|
37387
|
+
let lifetimeAmount = userTVL.amount.multipliedBy(0);
|
|
37388
|
+
let lifetimeTokenInfo = userTVL.tokenInfo;
|
|
37389
|
+
let lifetimeUsdValue = 0;
|
|
37390
|
+
if (investmentFlows.length > 0) {
|
|
37391
|
+
try {
|
|
37392
|
+
const earningsResult = this.getLifetimeEarnings(userTVL, investmentFlows);
|
|
37393
|
+
lifetimeAmount = earningsResult.lifetimeEarnings;
|
|
37394
|
+
lifetimeTokenInfo = earningsResult.tokenInfo.tokenInfo;
|
|
37395
|
+
const userAmount = userTVL.amount.toNumber();
|
|
37396
|
+
if (Number.isFinite(userAmount) && userAmount > 0) {
|
|
37397
|
+
const pricePerToken = userTVL.usdValue / userAmount;
|
|
37398
|
+
lifetimeUsdValue = lifetimeAmount.toNumber() * pricePerToken;
|
|
37399
|
+
}
|
|
37400
|
+
} catch (error) {
|
|
37401
|
+
logger.warn(`${this.getTag()}::getUserPositionCards lifetime earnings fallback`, error);
|
|
37402
|
+
}
|
|
37403
|
+
}
|
|
37404
|
+
cards.push({
|
|
37405
|
+
title: "Lifetime Earnings",
|
|
37406
|
+
tooltip: "Lifetime Earnings",
|
|
37407
|
+
value: this.formatTokenAmountForCard(lifetimeAmount, lifetimeTokenInfo),
|
|
37408
|
+
subValue: `\u2248 ${this.formatUSDForCard(lifetimeUsdValue)}`,
|
|
37409
|
+
subValueColor: this.getSubValueColorFromSignedNumber(lifetimeUsdValue)
|
|
37410
|
+
});
|
|
37411
|
+
return cards;
|
|
37412
|
+
}
|
|
37191
37413
|
async getPrevAUM() {
|
|
37192
37414
|
const currentAUM = await this.contract.call("aum", []);
|
|
37193
37415
|
const prevAum = Web3Number.fromWei(currentAUM.toString(), this.asset().decimals);
|
|
@@ -37301,29 +37523,6 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
|
|
|
37301
37523
|
]);
|
|
37302
37524
|
return [call];
|
|
37303
37525
|
}
|
|
37304
|
-
async getUserTVL(user, blockIdentifier = "latest") {
|
|
37305
|
-
const shares = await this.contract.call("balanceOf", [user.address], { blockIdentifier });
|
|
37306
|
-
const assets = await this.contract.call(
|
|
37307
|
-
"convert_to_assets",
|
|
37308
|
-
[import_starknet35.uint256.bnToUint256(shares)],
|
|
37309
|
-
{ blockIdentifier }
|
|
37310
|
-
);
|
|
37311
|
-
const amount = Web3Number.fromWei(
|
|
37312
|
-
assets.toString(),
|
|
37313
|
-
this.metadata.depositTokens[0].decimals
|
|
37314
|
-
);
|
|
37315
|
-
const blockNumber = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : void 0;
|
|
37316
|
-
let price = await this.pricer.getPrice(
|
|
37317
|
-
this.metadata.depositTokens[0].symbol,
|
|
37318
|
-
blockNumber
|
|
37319
|
-
);
|
|
37320
|
-
const usdValue = Number(amount.toFixed(6)) * price.price;
|
|
37321
|
-
return {
|
|
37322
|
-
tokenInfo: this.asset(),
|
|
37323
|
-
amount,
|
|
37324
|
-
usdValue
|
|
37325
|
-
};
|
|
37326
|
-
}
|
|
37327
37526
|
async getVesuAPYs() {
|
|
37328
37527
|
const vesuAdapters = this.getVesuAdapters();
|
|
37329
37528
|
const allVesuPools = await VesuAdapter.getVesuPools();
|
|
@@ -37364,13 +37563,16 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
|
|
|
37364
37563
|
*/
|
|
37365
37564
|
async netAPY() {
|
|
37366
37565
|
if (this.metadata.isPreview) {
|
|
37367
|
-
return {
|
|
37368
|
-
|
|
37369
|
-
|
|
37370
|
-
|
|
37371
|
-
|
|
37372
|
-
|
|
37373
|
-
|
|
37566
|
+
return {
|
|
37567
|
+
net: 0,
|
|
37568
|
+
splits: [{
|
|
37569
|
+
apy: 0,
|
|
37570
|
+
id: "base"
|
|
37571
|
+
}, {
|
|
37572
|
+
apy: 0,
|
|
37573
|
+
id: "defispring"
|
|
37574
|
+
}]
|
|
37575
|
+
};
|
|
37374
37576
|
}
|
|
37375
37577
|
const { positions, baseAPYs, rewardAPYs } = await this.getVesuAPYs();
|
|
37376
37578
|
const unusedBalanceAPY = await this.getUnusedBalanceAPY();
|
|
@@ -37385,25 +37587,31 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
|
|
|
37385
37587
|
}
|
|
37386
37588
|
async returnNetAPY(baseAPYs, rewardAPYs, weights, prevAUMUSD) {
|
|
37387
37589
|
if (weights.every((p) => p == 0)) {
|
|
37388
|
-
return {
|
|
37389
|
-
|
|
37390
|
-
|
|
37391
|
-
|
|
37392
|
-
|
|
37393
|
-
|
|
37394
|
-
|
|
37590
|
+
return {
|
|
37591
|
+
net: 0,
|
|
37592
|
+
splits: [{
|
|
37593
|
+
apy: 0,
|
|
37594
|
+
id: "base"
|
|
37595
|
+
}, {
|
|
37596
|
+
apy: 0,
|
|
37597
|
+
id: "defispring"
|
|
37598
|
+
}]
|
|
37599
|
+
};
|
|
37395
37600
|
}
|
|
37396
37601
|
const baseAPY = this.computeAPY(baseAPYs, weights, prevAUMUSD);
|
|
37397
37602
|
const rewardAPY = this.computeAPY(rewardAPYs, weights, prevAUMUSD);
|
|
37398
37603
|
const netAPY = baseAPY + rewardAPY;
|
|
37399
37604
|
logger.verbose(`${this.metadata.name}::netAPY: net: ${netAPY}, baseAPY: ${baseAPY}, rewardAPY: ${rewardAPY}`);
|
|
37400
|
-
return {
|
|
37401
|
-
|
|
37402
|
-
|
|
37403
|
-
|
|
37404
|
-
|
|
37405
|
-
|
|
37406
|
-
|
|
37605
|
+
return {
|
|
37606
|
+
net: netAPY,
|
|
37607
|
+
splits: [{
|
|
37608
|
+
apy: baseAPY,
|
|
37609
|
+
id: "base"
|
|
37610
|
+
}, {
|
|
37611
|
+
apy: rewardAPY,
|
|
37612
|
+
id: "defispring"
|
|
37613
|
+
}]
|
|
37614
|
+
};
|
|
37407
37615
|
}
|
|
37408
37616
|
async getUnusedBalanceAPY() {
|
|
37409
37617
|
return {
|
|
@@ -37417,104 +37625,6 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
|
|
|
37417
37625
|
logger.verbose(`${this.getTag()} computeAPY: apys: ${JSON.stringify(apys)}, weights: ${JSON.stringify(weights)}, weightedSum: ${weightedSum}, currentAUM: ${currentAUM}`);
|
|
37418
37626
|
return weightedSum / currentAUM.toNumber();
|
|
37419
37627
|
}
|
|
37420
|
-
/**
|
|
37421
|
-
* Calculates user realized APY based on trueSharesBasedAPY method.
|
|
37422
|
-
* Returns the APY as a number.
|
|
37423
|
-
*/
|
|
37424
|
-
async getUserRealizedAPY(blockIdentifier = "latest", sinceBlocks = 6e5) {
|
|
37425
|
-
logger.verbose(
|
|
37426
|
-
`${this.getTag()}: getUserRealizedAPY => starting with blockIdentifier=${blockIdentifier}, sinceBlocks=${sinceBlocks}`
|
|
37427
|
-
);
|
|
37428
|
-
let blockNow = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? Number(blockIdentifier) : (await this.config.provider.getBlockLatestAccepted()).block_number;
|
|
37429
|
-
const blockNowTime = typeof blockIdentifier === "number" || typeof blockIdentifier === "bigint" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
|
|
37430
|
-
const blockBefore = Math.max(
|
|
37431
|
-
blockNow - sinceBlocks,
|
|
37432
|
-
this.metadata.launchBlock
|
|
37433
|
-
);
|
|
37434
|
-
const assetsNowRaw = await this.contract.call("total_assets", [], {
|
|
37435
|
-
blockIdentifier
|
|
37436
|
-
});
|
|
37437
|
-
const amountNow = Web3Number.fromWei(
|
|
37438
|
-
assetsNowRaw.toString(),
|
|
37439
|
-
this.metadata.depositTokens[0].decimals
|
|
37440
|
-
);
|
|
37441
|
-
const supplyNowRaw = await this.contract.call("total_supply", [], {
|
|
37442
|
-
blockIdentifier
|
|
37443
|
-
});
|
|
37444
|
-
const supplyNow = Web3Number.fromWei(supplyNowRaw.toString(), 18);
|
|
37445
|
-
const assetsBeforeRaw = await this.contract.call(
|
|
37446
|
-
"total_assets",
|
|
37447
|
-
[],
|
|
37448
|
-
{ blockIdentifier: blockBefore }
|
|
37449
|
-
);
|
|
37450
|
-
const amountBefore = Web3Number.fromWei(
|
|
37451
|
-
assetsBeforeRaw.toString(),
|
|
37452
|
-
this.metadata.depositTokens[0].decimals
|
|
37453
|
-
);
|
|
37454
|
-
const supplyBeforeRaw = await this.contract.call(
|
|
37455
|
-
"total_supply",
|
|
37456
|
-
[],
|
|
37457
|
-
{ blockIdentifier: blockBefore }
|
|
37458
|
-
);
|
|
37459
|
-
const supplyBefore = Web3Number.fromWei(supplyBeforeRaw.toString(), 18);
|
|
37460
|
-
const blockBeforeInfo = await this.config.provider.getBlockWithTxs(
|
|
37461
|
-
blockBefore
|
|
37462
|
-
);
|
|
37463
|
-
const assetsPerShareNow = amountNow.multipliedBy(1e18).dividedBy(supplyNow.toString());
|
|
37464
|
-
const assetsPerShareBf = amountBefore.multipliedBy(1e18).dividedBy(supplyBefore.toString());
|
|
37465
|
-
const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
|
|
37466
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsNow: ${amountNow.toString()}`);
|
|
37467
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsBefore: ${amountBefore.toString()}`);
|
|
37468
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareNow: ${assetsPerShareNow.toString()}`);
|
|
37469
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] assetsPerShareBf: ${assetsPerShareBf.toString()}`);
|
|
37470
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply before: ${supplyBefore.toString()}`);
|
|
37471
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] Supply now: ${supplyNow.toString()}`);
|
|
37472
|
-
logger.verbose(`${this.getTag()} [getUserRealizedAPY] Time diff in seconds: ${timeDiffSeconds}`);
|
|
37473
|
-
const apyForGivenBlocks = Number(
|
|
37474
|
-
assetsPerShareNow.minus(assetsPerShareBf).multipliedBy(1e4).dividedBy(assetsPerShareBf)
|
|
37475
|
-
) / 1e4;
|
|
37476
|
-
return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
|
|
37477
|
-
}
|
|
37478
|
-
async getUserPositionCards(input) {
|
|
37479
|
-
const { user, investmentFlows = [] } = input;
|
|
37480
|
-
const [userTVL] = await Promise.all([
|
|
37481
|
-
this.getUserTVL(user)
|
|
37482
|
-
]);
|
|
37483
|
-
const cards = [
|
|
37484
|
-
{
|
|
37485
|
-
title: "Your Holdings",
|
|
37486
|
-
tooltip: "Your Holdings",
|
|
37487
|
-
value: this.formatTokenAmountForCard(userTVL.amount, userTVL.tokenInfo),
|
|
37488
|
-
subValue: `\u2248 ${this.formatUSDForCard(userTVL.usdValue)}`,
|
|
37489
|
-
subValueColor: "positive"
|
|
37490
|
-
}
|
|
37491
|
-
];
|
|
37492
|
-
let lifetimeAmount = userTVL.amount.multipliedBy(0);
|
|
37493
|
-
let lifetimeTokenInfo = userTVL.tokenInfo;
|
|
37494
|
-
let lifetimeUsdValue = 0;
|
|
37495
|
-
if (investmentFlows.length > 0) {
|
|
37496
|
-
try {
|
|
37497
|
-
const earningsResult = this.getLifetimeEarnings(userTVL, investmentFlows);
|
|
37498
|
-
lifetimeAmount = earningsResult.lifetimeEarnings;
|
|
37499
|
-
lifetimeTokenInfo = earningsResult.tokenInfo.tokenInfo;
|
|
37500
|
-
const userAmount = userTVL.amount.toNumber();
|
|
37501
|
-
if (Number.isFinite(userAmount) && userAmount > 0) {
|
|
37502
|
-
const pricePerToken = userTVL.usdValue / userAmount;
|
|
37503
|
-
lifetimeUsdValue = lifetimeAmount.toNumber() * pricePerToken;
|
|
37504
|
-
}
|
|
37505
|
-
} catch (error) {
|
|
37506
|
-
logger.warn(`${this.getTag()}::getUserPositionCards lifetime earnings fallback`, error);
|
|
37507
|
-
}
|
|
37508
|
-
}
|
|
37509
|
-
cards.push({
|
|
37510
|
-
title: "Lifetime Earnings",
|
|
37511
|
-
tooltip: "Lifetime Earnings",
|
|
37512
|
-
value: this.formatTokenAmountForCard(lifetimeAmount, lifetimeTokenInfo),
|
|
37513
|
-
subValue: `\u2248 ${this.formatUSDForCard(lifetimeUsdValue)}`,
|
|
37514
|
-
subValueColor: this.getSubValueColorFromSignedNumber(lifetimeUsdValue)
|
|
37515
|
-
});
|
|
37516
|
-
return cards;
|
|
37517
|
-
}
|
|
37518
37628
|
/**
|
|
37519
37629
|
* Calculates the total TVL of the strategy.
|
|
37520
37630
|
* @returns Object containing the total amount in token units and USD value
|
|
@@ -37591,13 +37701,17 @@ var UniversalStrategy = class _UniversalStrategy extends SVKStrategy {
|
|
|
37591
37701
|
};
|
|
37592
37702
|
const aumToken = vesuAum.plus(balance.amount);
|
|
37593
37703
|
if (aumToken.isZero()) {
|
|
37594
|
-
return {
|
|
37595
|
-
|
|
37596
|
-
|
|
37597
|
-
|
|
37598
|
-
|
|
37599
|
-
|
|
37600
|
-
|
|
37704
|
+
return {
|
|
37705
|
+
net,
|
|
37706
|
+
splits: [{
|
|
37707
|
+
aum: zeroAmt,
|
|
37708
|
+
id: "finalised" /* FINALISED */
|
|
37709
|
+
}, {
|
|
37710
|
+
aum: zeroAmt,
|
|
37711
|
+
id: "defispring" /* DEFISPRING */
|
|
37712
|
+
}],
|
|
37713
|
+
prevAum
|
|
37714
|
+
};
|
|
37601
37715
|
}
|
|
37602
37716
|
logger.verbose(`${this.getTag()} Actual AUM: ${aumToken}`);
|
|
37603
37717
|
const rewardAssets = await this.getRewardsAUM(prevAum);
|
|
@@ -38250,6 +38364,9 @@ var createUniversalStrategy = (params) => {
|
|
|
38250
38364
|
auditUrl: AUDIT_URL3,
|
|
38251
38365
|
protocols: [Protocols.VESU],
|
|
38252
38366
|
realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
|
|
38367
|
+
feeBps: {
|
|
38368
|
+
performanceFeeBps: 1e3
|
|
38369
|
+
},
|
|
38253
38370
|
curator: UnwrapLabsCurator,
|
|
38254
38371
|
settings: createUniversalSettings(params.tokenSymbol, params.maxTVLDecimals),
|
|
38255
38372
|
contractDetails: getContractDetails(params.vaultSettings),
|
|
@@ -38891,11 +39008,15 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
38891
39008
|
remarks: "defispring" /* DEFISPRING */,
|
|
38892
39009
|
protocol: Protocols.NONE
|
|
38893
39010
|
};
|
|
38894
|
-
return {
|
|
38895
|
-
|
|
38896
|
-
|
|
38897
|
-
|
|
38898
|
-
|
|
39011
|
+
return {
|
|
39012
|
+
net: {
|
|
39013
|
+
tokenInfo: underlying,
|
|
39014
|
+
amount: netAUM,
|
|
39015
|
+
usdValue: netAUM.toNumber() * assetPrice.price
|
|
39016
|
+
},
|
|
39017
|
+
prevAum,
|
|
39018
|
+
splits: [realAUM, estimatedAUMDelta]
|
|
39019
|
+
};
|
|
38899
39020
|
}
|
|
38900
39021
|
async getTVLUnrealized() {
|
|
38901
39022
|
return await this.getAUM(true);
|
|
@@ -38913,6 +39034,62 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
38913
39034
|
tokenInfo: this.asset()
|
|
38914
39035
|
};
|
|
38915
39036
|
}
|
|
39037
|
+
async getUserPositionCards(input) {
|
|
39038
|
+
const cards = await super.getUserPositionCards(input);
|
|
39039
|
+
try {
|
|
39040
|
+
const [unrealizedResult, userTVL, realizedApyRaw] = await Promise.all([
|
|
39041
|
+
this.getUserUnrealizedGains(input.user),
|
|
39042
|
+
this.getUserTVL(input.user),
|
|
39043
|
+
this.getUserRealizedAPY().catch(() => null)
|
|
39044
|
+
]);
|
|
39045
|
+
const amount = unrealizedResult.unrealizedGains;
|
|
39046
|
+
let usdValue = 0;
|
|
39047
|
+
const userAmount = userTVL.amount.toNumber();
|
|
39048
|
+
if (Number.isFinite(userAmount) && userAmount > 0) {
|
|
39049
|
+
usdValue = userTVL.usdValue / userAmount * amount.toNumber();
|
|
39050
|
+
}
|
|
39051
|
+
cards.push({
|
|
39052
|
+
title: "Unrealized Gains",
|
|
39053
|
+
tooltip: "Unrealized gains based on current market prices vs Endur prices. If you withdraw now, you will forgo these gains.",
|
|
39054
|
+
value: this.formatTokenAmountForCard(amount, unrealizedResult.tokenInfo),
|
|
39055
|
+
subValue: `\u2248 ${this.formatUSDForCard(usdValue)}`,
|
|
39056
|
+
subValueColor: this.getSubValueColorFromSignedNumber(usdValue)
|
|
39057
|
+
});
|
|
39058
|
+
const realizedApy = typeof realizedApyRaw === "number" ? this.formatPercentForCard(realizedApyRaw) : "N/A";
|
|
39059
|
+
cards.push({
|
|
39060
|
+
title: "Realized APY",
|
|
39061
|
+
tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
|
|
39062
|
+
value: realizedApy
|
|
39063
|
+
});
|
|
39064
|
+
} catch (error) {
|
|
39065
|
+
logger.warn(`${this.getTag()}::getUserPositionCards unrealized gains fallback`, error);
|
|
39066
|
+
cards.push({
|
|
39067
|
+
title: "Unrealized Gains",
|
|
39068
|
+
tooltip: "Unrealized gains based on current market prices vs Endur prices. If you withdraw now, you will forgo these gains.",
|
|
39069
|
+
value: this.formatTokenAmountForCard(
|
|
39070
|
+
Web3Number.fromWei("0", this.asset().decimals),
|
|
39071
|
+
this.asset()
|
|
39072
|
+
),
|
|
39073
|
+
subValue: `\u2248 ${this.formatUSDForCard(0)}`,
|
|
39074
|
+
subValueColor: "default"
|
|
39075
|
+
});
|
|
39076
|
+
cards.push({
|
|
39077
|
+
title: "Realized APY",
|
|
39078
|
+
tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
|
|
39079
|
+
value: "N/A"
|
|
39080
|
+
});
|
|
39081
|
+
}
|
|
39082
|
+
if (this.asset().symbol === "xSTRK") {
|
|
39083
|
+
const index = cards.findIndex((card) => card.title === "Lifetime Earnings");
|
|
39084
|
+
if (index >= 0) {
|
|
39085
|
+
cards[index] = {
|
|
39086
|
+
...cards[index],
|
|
39087
|
+
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."
|
|
39088
|
+
};
|
|
39089
|
+
}
|
|
39090
|
+
}
|
|
39091
|
+
return cards;
|
|
39092
|
+
}
|
|
38916
39093
|
};
|
|
38917
39094
|
function VaultDescription(lstSymbol, underlyingSymbol) {
|
|
38918
39095
|
const containerStyle = {
|
|
@@ -39320,6 +39497,9 @@ function getStrategySettings(lstSymbol, underlyingSymbol, settings, isPreview =
|
|
|
39320
39497
|
isPreview,
|
|
39321
39498
|
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.",
|
|
39322
39499
|
realizedApyMethodology: "The realizedAPY is based on past 14 days performance by the vault",
|
|
39500
|
+
feeBps: {
|
|
39501
|
+
performanceFeeBps: 1e3
|
|
39502
|
+
},
|
|
39323
39503
|
tags: lstSymbol.includes("BTC") ? ["BTC" /* BTC */, "Maxx" /* LEVERED */] : ["Maxx" /* LEVERED */],
|
|
39324
39504
|
security: HYPER_LST_SECURITY,
|
|
39325
39505
|
redemptionInfo: HYPER_LST_REDEMPTION_INFO,
|
|
@@ -39533,6 +39713,23 @@ var BoostedxSTRKCarryStrategy = class _BoostedxSTRKCarryStrategy extends SVKStra
|
|
|
39533
39713
|
usdValue
|
|
39534
39714
|
};
|
|
39535
39715
|
}
|
|
39716
|
+
async getUserPositionCards(input) {
|
|
39717
|
+
const cards = await super.getUserPositionCards(input);
|
|
39718
|
+
const realizedApyRaw = await this.getUserRealizedAPY().catch((error) => {
|
|
39719
|
+
logger.warn(
|
|
39720
|
+
`${this.getTag()}::getUserPositionCards realized APY fallback`,
|
|
39721
|
+
error
|
|
39722
|
+
);
|
|
39723
|
+
return null;
|
|
39724
|
+
});
|
|
39725
|
+
const realizedApy = typeof realizedApyRaw === "number" ? this.formatPercentForCard(realizedApyRaw) : "N/A";
|
|
39726
|
+
cards.push({
|
|
39727
|
+
title: "Realized APY",
|
|
39728
|
+
tooltip: this.metadata.realizedApyMethodology || "Realized APY is based on past 14 days performance",
|
|
39729
|
+
value: realizedApy
|
|
39730
|
+
});
|
|
39731
|
+
return cards;
|
|
39732
|
+
}
|
|
39536
39733
|
async getAUM() {
|
|
39537
39734
|
const underlying = this.asset();
|
|
39538
39735
|
const depositTokenPrice = await this.pricer.getPrice(underlying.symbol);
|
|
@@ -40122,15 +40319,15 @@ function getBoostedCarryFAQs(depositSymbol, debtSymbol, lstSymbol) {
|
|
|
40122
40319
|
question: "Which protocols are used?",
|
|
40123
40320
|
answer: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
|
|
40124
40321
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Vesu" }),
|
|
40125
|
-
" for collateral and borrowing,
|
|
40126
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Avnu" }),
|
|
40322
|
+
" for collateral and borrowing,",
|
|
40127
40323
|
" ",
|
|
40128
|
-
|
|
40324
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Avnu" }),
|
|
40325
|
+
" for swaps, ",
|
|
40129
40326
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Endur" }),
|
|
40130
|
-
" for
|
|
40131
|
-
lstSymbol,
|
|
40132
|
-
", and the Troves",
|
|
40327
|
+
" for",
|
|
40133
40328
|
" ",
|
|
40329
|
+
lstSymbol,
|
|
40330
|
+
", and the Troves ",
|
|
40134
40331
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("strong", { children: [
|
|
40135
40332
|
"Hyper-",
|
|
40136
40333
|
lstSymbol
|
|
@@ -40218,6 +40415,9 @@ function getStrategySettings2(settings, meta) {
|
|
|
40218
40415
|
]
|
|
40219
40416
|
},
|
|
40220
40417
|
contractDetails: getContractDetails(settings),
|
|
40418
|
+
feeBps: {
|
|
40419
|
+
performanceFeeBps: 1500
|
|
40420
|
+
},
|
|
40221
40421
|
faqs: getBoostedCarryFAQs(
|
|
40222
40422
|
depositToken.symbol,
|
|
40223
40423
|
debtToken.symbol,
|
|
@@ -40538,7 +40738,7 @@ function createStrategy(type, config, pricer, metadata) {
|
|
|
40538
40738
|
}
|
|
40539
40739
|
|
|
40540
40740
|
// src/modules/pricer-lst.ts
|
|
40541
|
-
var
|
|
40741
|
+
var import_axios10 = __toESM(require("axios"));
|
|
40542
40742
|
var PricerLST2 = class extends Pricer {
|
|
40543
40743
|
// e.g. xSTRK/STRK
|
|
40544
40744
|
constructor(config, tokenMaps) {
|
|
@@ -40574,7 +40774,7 @@ var PricerLST2 = class extends Pricer {
|
|
|
40574
40774
|
async _getPriceEkubo(token, amountIn = new Web3Number(1, token.decimals), retry = 0) {
|
|
40575
40775
|
const underlying = this.getUnderlying(token);
|
|
40576
40776
|
const url = this.EKUBO_API.replace("{{TOKEN_ADDRESS}}", token.address.toString()).replace("{{AMOUNT}}", amountIn.toWei()).replace("{{UNDERLYING_ADDRESS}}", underlying.address.toString());
|
|
40577
|
-
const result = await
|
|
40777
|
+
const result = await import_axios10.default.get(url);
|
|
40578
40778
|
const data = result.data;
|
|
40579
40779
|
const multiplier = 1 / amountIn.toNumber();
|
|
40580
40780
|
const outputUnderlying = Number(Web3Number.fromWei(data.total_calculated, underlying.decimals).toFixed(6)) * multiplier;
|
|
@@ -40726,6 +40926,7 @@ var PricerRedis = class extends Pricer {
|
|
|
40726
40926
|
async startWithRedis(redisUrl) {
|
|
40727
40927
|
await this.initRedis(redisUrl);
|
|
40728
40928
|
logger.info(`Starting Pricer with Redis`);
|
|
40929
|
+
this.avnuApiPricer.start();
|
|
40729
40930
|
this._loadPrices(this._setRedisPrices.bind(this));
|
|
40730
40931
|
setInterval(() => {
|
|
40731
40932
|
this._loadPrices(this._setRedisPrices.bind(this));
|
|
@@ -41173,6 +41374,7 @@ var deployer_default = Deployer;
|
|
|
41173
41374
|
PositionTypeAvnuExtended,
|
|
41174
41375
|
Pragma,
|
|
41175
41376
|
Pricer,
|
|
41377
|
+
PricerAvnuApi,
|
|
41176
41378
|
PricerBase,
|
|
41177
41379
|
PricerFromApi,
|
|
41178
41380
|
PricerLST,
|