@strkfarm/sdk 1.0.37 → 1.0.38
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/cli.js +236 -112
- package/dist/cli.mjs +241 -113
- package/dist/index.browser.global.js +869 -312
- package/dist/index.browser.mjs +870 -309
- package/dist/index.d.ts +9 -4
- package/dist/index.js +865 -308
- package/dist/index.mjs +870 -309
- package/package.json +1 -1
- package/src/interfaces/common.ts +111 -98
- package/src/strategies/ekubo-cl-vault.tsx +1434 -923
- package/src/strategies/vesu-rebalance.tsx +937 -610
|
@@ -38226,7 +38226,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
38226
38226
|
};
|
|
38227
38227
|
var getNoRiskTags = (risks) => {
|
|
38228
38228
|
const noRisks1 = risks.filter((risk) => risk.value === 0).map((risk) => risk.type);
|
|
38229
|
-
const noRisks2 = Object.values(RiskType).filter(
|
|
38229
|
+
const noRisks2 = Object.values(RiskType).filter(
|
|
38230
|
+
(risk) => !risks.map((risk2) => risk2.type).includes(risk)
|
|
38231
|
+
);
|
|
38230
38232
|
const mergedUnique = [.../* @__PURE__ */ new Set([...noRisks1, ...noRisks2])];
|
|
38231
38233
|
return mergedUnique.map((risk) => `No ${risk}`);
|
|
38232
38234
|
};
|
|
@@ -48912,6 +48914,7 @@ var strkfarm_risk_engine = (() => {
|
|
|
48912
48914
|
};
|
|
48913
48915
|
|
|
48914
48916
|
// src/strategies/vesu-rebalance.tsx
|
|
48917
|
+
var import_jsx_runtime = __toESM(require_jsx_runtime());
|
|
48915
48918
|
var VesuRebalance = class _VesuRebalance extends BaseStrategy {
|
|
48916
48919
|
// 10000 bps = 100%
|
|
48917
48920
|
/**
|
|
@@ -48925,10 +48928,17 @@ var strkfarm_risk_engine = (() => {
|
|
|
48925
48928
|
super(config2);
|
|
48926
48929
|
this.BASE_WEIGHT = 1e4;
|
|
48927
48930
|
this.pricer = pricer;
|
|
48928
|
-
assert3(
|
|
48931
|
+
assert3(
|
|
48932
|
+
metadata.depositTokens.length === 1,
|
|
48933
|
+
"VesuRebalance only supports 1 deposit token"
|
|
48934
|
+
);
|
|
48929
48935
|
this.metadata = metadata;
|
|
48930
48936
|
this.address = metadata.address;
|
|
48931
|
-
this.contract = new Contract(
|
|
48937
|
+
this.contract = new Contract(
|
|
48938
|
+
vesu_rebalance_abi_default,
|
|
48939
|
+
this.address.address,
|
|
48940
|
+
this.config.provider
|
|
48941
|
+
);
|
|
48932
48942
|
}
|
|
48933
48943
|
/**
|
|
48934
48944
|
* Creates a deposit call to the strategy contract.
|
|
@@ -48937,10 +48947,23 @@ var strkfarm_risk_engine = (() => {
|
|
|
48937
48947
|
* @returns Populated contract call for deposit
|
|
48938
48948
|
*/
|
|
48939
48949
|
async depositCall(amountInfo, receiver) {
|
|
48940
|
-
assert3(
|
|
48941
|
-
|
|
48942
|
-
|
|
48943
|
-
|
|
48950
|
+
assert3(
|
|
48951
|
+
amountInfo.tokenInfo.address.eq(this.asset().address),
|
|
48952
|
+
"Deposit token mismatch"
|
|
48953
|
+
);
|
|
48954
|
+
const assetContract = new Contract(
|
|
48955
|
+
vesu_rebalance_abi_default,
|
|
48956
|
+
this.asset().address.address,
|
|
48957
|
+
this.config.provider
|
|
48958
|
+
);
|
|
48959
|
+
const call1 = assetContract.populate("approve", [
|
|
48960
|
+
this.address.address,
|
|
48961
|
+
uint256_exports.bnToUint256(amountInfo.amount.toWei())
|
|
48962
|
+
]);
|
|
48963
|
+
const call2 = this.contract.populate("deposit", [
|
|
48964
|
+
uint256_exports.bnToUint256(amountInfo.amount.toWei()),
|
|
48965
|
+
receiver.address
|
|
48966
|
+
]);
|
|
48944
48967
|
return [call1, call2];
|
|
48945
48968
|
}
|
|
48946
48969
|
/**
|
|
@@ -48951,7 +48974,13 @@ var strkfarm_risk_engine = (() => {
|
|
|
48951
48974
|
* @returns Populated contract call for withdrawal
|
|
48952
48975
|
*/
|
|
48953
48976
|
async withdrawCall(amountInfo, receiver, owner) {
|
|
48954
|
-
return [
|
|
48977
|
+
return [
|
|
48978
|
+
this.contract.populate("withdraw", [
|
|
48979
|
+
uint256_exports.bnToUint256(amountInfo.amount.toWei()),
|
|
48980
|
+
receiver.address,
|
|
48981
|
+
owner.address
|
|
48982
|
+
])
|
|
48983
|
+
];
|
|
48955
48984
|
}
|
|
48956
48985
|
/**
|
|
48957
48986
|
* Returns the underlying asset token of the strategy.
|
|
@@ -48974,9 +49003,16 @@ var strkfarm_risk_engine = (() => {
|
|
|
48974
49003
|
*/
|
|
48975
49004
|
async getUserTVL(user) {
|
|
48976
49005
|
const shares = await this.contract.balanceOf(user.address);
|
|
48977
|
-
const assets = await this.contract.convert_to_assets(
|
|
48978
|
-
|
|
48979
|
-
|
|
49006
|
+
const assets = await this.contract.convert_to_assets(
|
|
49007
|
+
uint256_exports.bnToUint256(shares)
|
|
49008
|
+
);
|
|
49009
|
+
const amount = Web3Number.fromWei(
|
|
49010
|
+
assets.toString(),
|
|
49011
|
+
this.metadata.depositTokens[0].decimals
|
|
49012
|
+
);
|
|
49013
|
+
let price = await this.pricer.getPrice(
|
|
49014
|
+
this.metadata.depositTokens[0].symbol
|
|
49015
|
+
);
|
|
48980
49016
|
const usdValue = Number(amount.toFixed(6)) * price.price;
|
|
48981
49017
|
return {
|
|
48982
49018
|
tokenInfo: this.asset(),
|
|
@@ -48990,8 +49026,13 @@ var strkfarm_risk_engine = (() => {
|
|
|
48990
49026
|
*/
|
|
48991
49027
|
async getTVL() {
|
|
48992
49028
|
const assets = await this.contract.total_assets();
|
|
48993
|
-
const amount = Web3Number.fromWei(
|
|
48994
|
-
|
|
49029
|
+
const amount = Web3Number.fromWei(
|
|
49030
|
+
assets.toString(),
|
|
49031
|
+
this.metadata.depositTokens[0].decimals
|
|
49032
|
+
);
|
|
49033
|
+
let price = await this.pricer.getPrice(
|
|
49034
|
+
this.metadata.depositTokens[0].symbol
|
|
49035
|
+
);
|
|
48995
49036
|
const usdValue = Number(amount.toFixed(6)) * price.price;
|
|
48996
49037
|
return {
|
|
48997
49038
|
tokenInfo: this.asset(),
|
|
@@ -49017,51 +49058,104 @@ var strkfarm_risk_engine = (() => {
|
|
|
49017
49058
|
return pools;
|
|
49018
49059
|
}
|
|
49019
49060
|
async getPoolInfo(p, pools, vesuPositions, totalAssets, isErrorPositionsAPI, isErrorPoolsAPI) {
|
|
49020
|
-
const vesuPosition = vesuPositions.find(
|
|
49061
|
+
const vesuPosition = vesuPositions.find(
|
|
49062
|
+
(d) => d.pool.id.toString() === num_exports.getDecimalString(p.pool_id.address.toString())
|
|
49063
|
+
);
|
|
49021
49064
|
const _pool = pools.find((d) => {
|
|
49022
|
-
logger.verbose(
|
|
49065
|
+
logger.verbose(
|
|
49066
|
+
`pool check: ${d.id == num_exports.getDecimalString(p.pool_id.address.toString())}, id: ${d.id}, pool_id: ${num_exports.getDecimalString(
|
|
49067
|
+
p.pool_id.address.toString()
|
|
49068
|
+
)}`
|
|
49069
|
+
);
|
|
49023
49070
|
return d.id == num_exports.getDecimalString(p.pool_id.address.toString());
|
|
49024
49071
|
});
|
|
49025
49072
|
logger.verbose(`pool: ${JSON.stringify(_pool)}`);
|
|
49026
49073
|
logger.verbose(typeof _pool);
|
|
49027
49074
|
logger.verbose(`name: ${_pool?.name}`);
|
|
49028
49075
|
const name = _pool?.name;
|
|
49029
|
-
logger.verbose(
|
|
49030
|
-
|
|
49076
|
+
logger.verbose(
|
|
49077
|
+
`name2: ${name}, ${!name ? true : false}, ${name?.length}, ${typeof name}`
|
|
49078
|
+
);
|
|
49079
|
+
const assetInfo = _pool?.assets.find(
|
|
49080
|
+
(d) => this.asset().address.eqString(d.address)
|
|
49081
|
+
);
|
|
49031
49082
|
if (!name) {
|
|
49032
49083
|
logger.verbose(`Pool not found`);
|
|
49033
49084
|
throw new Error(`Pool name ${p.pool_id.address.toString()} not found`);
|
|
49034
49085
|
}
|
|
49035
49086
|
if (!assetInfo) {
|
|
49036
|
-
throw new Error(
|
|
49087
|
+
throw new Error(
|
|
49088
|
+
`Asset ${this.asset().address.toString()} not found in pool ${p.pool_id.address.toString()}`
|
|
49089
|
+
);
|
|
49037
49090
|
}
|
|
49038
|
-
let vTokenContract = new Contract(
|
|
49091
|
+
let vTokenContract = new Contract(
|
|
49092
|
+
vesu_rebalance_abi_default,
|
|
49093
|
+
p.v_token.address,
|
|
49094
|
+
this.config.provider
|
|
49095
|
+
);
|
|
49039
49096
|
const bal = await vTokenContract.balanceOf(this.address.address);
|
|
49040
|
-
const assets = await vTokenContract.convert_to_assets(
|
|
49097
|
+
const assets = await vTokenContract.convert_to_assets(
|
|
49098
|
+
uint256_exports.bnToUint256(bal.toString())
|
|
49099
|
+
);
|
|
49041
49100
|
logger.verbose(`Collateral: ${JSON.stringify(vesuPosition?.collateral)}`);
|
|
49042
49101
|
logger.verbose(`supplyApy: ${JSON.stringify(assetInfo?.stats.supplyApy)}`);
|
|
49043
|
-
logger.verbose(
|
|
49044
|
-
|
|
49045
|
-
|
|
49102
|
+
logger.verbose(
|
|
49103
|
+
`defiSpringSupplyApr: ${JSON.stringify(
|
|
49104
|
+
assetInfo?.stats.defiSpringSupplyApr
|
|
49105
|
+
)}`
|
|
49106
|
+
);
|
|
49107
|
+
logger.verbose(
|
|
49108
|
+
`currentUtilization: ${JSON.stringify(
|
|
49109
|
+
assetInfo?.stats.currentUtilization
|
|
49110
|
+
)}`
|
|
49111
|
+
);
|
|
49112
|
+
logger.verbose(
|
|
49113
|
+
`maxUtilization: ${JSON.stringify(assetInfo?.config.maxUtilization)}`
|
|
49114
|
+
);
|
|
49046
49115
|
const item = {
|
|
49047
49116
|
pool_id: p.pool_id,
|
|
49048
49117
|
pool_name: _pool?.name,
|
|
49049
49118
|
max_weight: p.max_weight,
|
|
49050
|
-
current_weight: isErrorPositionsAPI || !vesuPosition ? 0 : Number(
|
|
49119
|
+
current_weight: isErrorPositionsAPI || !vesuPosition ? 0 : Number(
|
|
49120
|
+
Web3Number.fromWei(vesuPosition.collateral.value, this.decimals()).dividedBy(totalAssets.toString()).toFixed(6)
|
|
49121
|
+
),
|
|
49051
49122
|
v_token: p.v_token,
|
|
49052
49123
|
amount: Web3Number.fromWei(assets.toString(), this.decimals()),
|
|
49053
|
-
usdValue: isErrorPositionsAPI || !vesuPosition ? Web3Number.fromWei("0", this.decimals()) : Web3Number.fromWei(
|
|
49124
|
+
usdValue: isErrorPositionsAPI || !vesuPosition ? Web3Number.fromWei("0", this.decimals()) : Web3Number.fromWei(
|
|
49125
|
+
vesuPosition.collateral.usdPrice.value,
|
|
49126
|
+
vesuPosition.collateral.usdPrice.decimals
|
|
49127
|
+
),
|
|
49054
49128
|
APY: isErrorPoolsAPI || !assetInfo ? {
|
|
49055
49129
|
baseApy: 0,
|
|
49056
49130
|
defiSpringApy: 0,
|
|
49057
49131
|
netApy: 0
|
|
49058
49132
|
} : {
|
|
49059
|
-
baseApy: Number(
|
|
49060
|
-
|
|
49133
|
+
baseApy: Number(
|
|
49134
|
+
Web3Number.fromWei(
|
|
49135
|
+
assetInfo.stats.supplyApy.value,
|
|
49136
|
+
assetInfo.stats.supplyApy.decimals
|
|
49137
|
+
).toFixed(6)
|
|
49138
|
+
),
|
|
49139
|
+
defiSpringApy: assetInfo.stats.defiSpringSupplyApr ? Number(
|
|
49140
|
+
Web3Number.fromWei(
|
|
49141
|
+
assetInfo.stats.defiSpringSupplyApr.value,
|
|
49142
|
+
assetInfo.stats.defiSpringSupplyApr.decimals
|
|
49143
|
+
).toFixed(6)
|
|
49144
|
+
) : 0,
|
|
49061
49145
|
netApy: 0
|
|
49062
49146
|
},
|
|
49063
|
-
currentUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(
|
|
49064
|
-
|
|
49147
|
+
currentUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(
|
|
49148
|
+
Web3Number.fromWei(
|
|
49149
|
+
assetInfo.stats.currentUtilization.value,
|
|
49150
|
+
assetInfo.stats.currentUtilization.decimals
|
|
49151
|
+
).toFixed(6)
|
|
49152
|
+
),
|
|
49153
|
+
maxUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(
|
|
49154
|
+
Web3Number.fromWei(
|
|
49155
|
+
assetInfo.config.maxUtilization.value,
|
|
49156
|
+
assetInfo.config.maxUtilization.decimals
|
|
49157
|
+
).toFixed(6)
|
|
49158
|
+
)
|
|
49065
49159
|
};
|
|
49066
49160
|
item.APY.netApy = item.APY.baseApy + item.APY.defiSpringApy;
|
|
49067
49161
|
return item;
|
|
@@ -49071,7 +49165,7 @@ var strkfarm_risk_engine = (() => {
|
|
|
49071
49165
|
* 1. Contract's allowed pools
|
|
49072
49166
|
* 2. Vesu positions API for current positions
|
|
49073
49167
|
* 3. Vesu pools API for APY and utilization data
|
|
49074
|
-
*
|
|
49168
|
+
*
|
|
49075
49169
|
* @returns {Promise<{
|
|
49076
49170
|
* data: Array<PoolInfoFull>,
|
|
49077
49171
|
* isErrorPositionsAPI: boolean
|
|
@@ -49088,15 +49182,29 @@ var strkfarm_risk_engine = (() => {
|
|
|
49088
49182
|
let isErrorPositionsAPI = false;
|
|
49089
49183
|
let vesuPositions = [];
|
|
49090
49184
|
try {
|
|
49091
|
-
const data2 = await getAPIUsingHeadlessBrowser(
|
|
49185
|
+
const data2 = await getAPIUsingHeadlessBrowser(
|
|
49186
|
+
`https://api.vesu.xyz/positions?walletAddress=${this.address.address}`
|
|
49187
|
+
);
|
|
49092
49188
|
vesuPositions = data2.data;
|
|
49093
49189
|
} catch (e) {
|
|
49094
|
-
console.error(
|
|
49190
|
+
console.error(
|
|
49191
|
+
`${_VesuRebalance.name}: Error fetching positions for ${this.address.address}`,
|
|
49192
|
+
e
|
|
49193
|
+
);
|
|
49095
49194
|
isErrorPositionsAPI = true;
|
|
49096
49195
|
}
|
|
49097
49196
|
let { pools, isErrorPoolsAPI } = await this.getVesuPools();
|
|
49098
49197
|
const totalAssets = (await this.getTVL()).amount;
|
|
49099
|
-
const info = allowedPools.map(
|
|
49198
|
+
const info = allowedPools.map(
|
|
49199
|
+
(p) => this.getPoolInfo(
|
|
49200
|
+
p,
|
|
49201
|
+
pools,
|
|
49202
|
+
vesuPositions,
|
|
49203
|
+
totalAssets,
|
|
49204
|
+
isErrorPositionsAPI,
|
|
49205
|
+
isErrorPoolsAPI
|
|
49206
|
+
)
|
|
49207
|
+
);
|
|
49100
49208
|
const data = await Promise.all(info);
|
|
49101
49209
|
return {
|
|
49102
49210
|
data,
|
|
@@ -49109,18 +49217,25 @@ var strkfarm_risk_engine = (() => {
|
|
|
49109
49217
|
let isErrorPoolsAPI = false;
|
|
49110
49218
|
let pools = [];
|
|
49111
49219
|
try {
|
|
49112
|
-
const data = await getAPIUsingHeadlessBrowser(
|
|
49220
|
+
const data = await getAPIUsingHeadlessBrowser(
|
|
49221
|
+
"https://api.vesu.xyz/pools"
|
|
49222
|
+
);
|
|
49113
49223
|
pools = data.data;
|
|
49114
49224
|
for (const pool of vesu_pools_default.data) {
|
|
49115
49225
|
const found = pools.find((d) => d.id === pool.id);
|
|
49116
49226
|
if (!found) {
|
|
49117
49227
|
logger.verbose(`VesuRebalance: pools: ${JSON.stringify(pools)}`);
|
|
49118
|
-
logger.verbose(
|
|
49228
|
+
logger.verbose(
|
|
49229
|
+
`VesuRebalance: Pool ${pool.id} not found in Vesu API, using hardcoded data`
|
|
49230
|
+
);
|
|
49119
49231
|
throw new Error("pool not found [sanity check]");
|
|
49120
49232
|
}
|
|
49121
49233
|
}
|
|
49122
49234
|
} catch (e) {
|
|
49123
|
-
logger.error(
|
|
49235
|
+
logger.error(
|
|
49236
|
+
`${_VesuRebalance.name}: Error fetching pools for ${this.address.address}, retry ${retry}`,
|
|
49237
|
+
e
|
|
49238
|
+
);
|
|
49124
49239
|
isErrorPoolsAPI = true;
|
|
49125
49240
|
if (retry < 10) {
|
|
49126
49241
|
await new Promise((resolve) => setTimeout(resolve, 5e3 * (retry + 1)));
|
|
@@ -49158,8 +49273,8 @@ var strkfarm_risk_engine = (() => {
|
|
|
49158
49273
|
* 3. For each pool that needs more funds:
|
|
49159
49274
|
* - Takes funds from lowest APY pools that are over their target
|
|
49160
49275
|
* 4. Validates that total assets remain constant
|
|
49161
|
-
*
|
|
49162
|
-
* @returns {Promise<{
|
|
49276
|
+
*
|
|
49277
|
+
* @returns {Promise<{
|
|
49163
49278
|
* changes: Change[],
|
|
49164
49279
|
* finalPools: PoolInfoFull[],
|
|
49165
49280
|
* isAnyPoolOverMaxWeight: boolean
|
|
@@ -49175,27 +49290,38 @@ var strkfarm_risk_engine = (() => {
|
|
|
49175
49290
|
_pools = _pools2;
|
|
49176
49291
|
}
|
|
49177
49292
|
const feeDeductions = await this.getFee(_pools);
|
|
49178
|
-
logger.verbose(
|
|
49293
|
+
logger.verbose(
|
|
49294
|
+
`VesuRebalance: feeDeductions: ${JSON.stringify(feeDeductions)}`
|
|
49295
|
+
);
|
|
49179
49296
|
const pools = _pools.map((p) => {
|
|
49180
49297
|
const fee = feeDeductions.find((f) => p.v_token.eq(f.vToken))?.fee || Web3Number.fromWei("0", this.decimals());
|
|
49181
|
-
logger.verbose(
|
|
49298
|
+
logger.verbose(
|
|
49299
|
+
`FeeAdjustment: ${p.pool_id} => ${fee.toString()}, amt: ${p.amount.toString()}`
|
|
49300
|
+
);
|
|
49182
49301
|
return {
|
|
49183
49302
|
...p,
|
|
49184
49303
|
amount: p.amount.minus(fee)
|
|
49185
49304
|
};
|
|
49186
49305
|
});
|
|
49187
49306
|
let totalAssets = (await this.getTVL()).amount;
|
|
49188
|
-
if (totalAssets.eq(0))
|
|
49189
|
-
|
|
49190
|
-
|
|
49191
|
-
|
|
49307
|
+
if (totalAssets.eq(0))
|
|
49308
|
+
return {
|
|
49309
|
+
changes: [],
|
|
49310
|
+
finalPools: []
|
|
49311
|
+
};
|
|
49192
49312
|
feeDeductions.forEach((f) => {
|
|
49193
49313
|
totalAssets = totalAssets.minus(f.fee);
|
|
49194
49314
|
});
|
|
49195
|
-
const sumPools = pools.reduce(
|
|
49315
|
+
const sumPools = pools.reduce(
|
|
49316
|
+
(acc, curr) => acc.plus(curr.amount.toString()),
|
|
49317
|
+
Web3Number.fromWei("0", this.decimals())
|
|
49318
|
+
);
|
|
49196
49319
|
logger.verbose(`Sum of pools: ${sumPools.toString()}`);
|
|
49197
49320
|
logger.verbose(`Total assets: ${totalAssets.toString()}`);
|
|
49198
|
-
assert3(
|
|
49321
|
+
assert3(
|
|
49322
|
+
sumPools.lte(totalAssets.multipliedBy(1.00001).toString()),
|
|
49323
|
+
"Sum of pools.amount must be less than or equal to totalAssets"
|
|
49324
|
+
);
|
|
49199
49325
|
const sortedPools = [...pools].sort((a, b) => b.APY.netApy - a.APY.netApy);
|
|
49200
49326
|
const targetAmounts = {};
|
|
49201
49327
|
let remainingAssets = totalAssets;
|
|
@@ -49217,7 +49343,10 @@ var strkfarm_risk_engine = (() => {
|
|
|
49217
49343
|
assert3(remainingAssets.lt(1e-5), "Remaining assets must be 0");
|
|
49218
49344
|
const changes = sortedPools.map((pool) => {
|
|
49219
49345
|
const target = targetAmounts[pool.pool_id.address.toString()] || Web3Number.fromWei("0", this.decimals());
|
|
49220
|
-
const change = Web3Number.fromWei(
|
|
49346
|
+
const change = Web3Number.fromWei(
|
|
49347
|
+
target.minus(pool.amount.toString()).toWei(),
|
|
49348
|
+
this.decimals()
|
|
49349
|
+
);
|
|
49221
49350
|
return {
|
|
49222
49351
|
pool_id: pool.pool_id,
|
|
49223
49352
|
changeAmt: change,
|
|
@@ -49226,14 +49355,21 @@ var strkfarm_risk_engine = (() => {
|
|
|
49226
49355
|
};
|
|
49227
49356
|
});
|
|
49228
49357
|
logger.verbose(`Changes: ${JSON.stringify(changes)}`);
|
|
49229
|
-
const sumChanges = changes.reduce(
|
|
49230
|
-
|
|
49358
|
+
const sumChanges = changes.reduce(
|
|
49359
|
+
(sum, c) => sum.plus(c.changeAmt.toString()),
|
|
49360
|
+
Web3Number.fromWei("0", this.decimals())
|
|
49361
|
+
);
|
|
49362
|
+
const sumFinal = changes.reduce(
|
|
49363
|
+
(sum, c) => sum.plus(c.finalAmt.toString()),
|
|
49364
|
+
Web3Number.fromWei("0", this.decimals())
|
|
49365
|
+
);
|
|
49231
49366
|
const hasChanges = changes.some((c) => !c.changeAmt.eq(0));
|
|
49232
49367
|
logger.verbose(`Sum of changes: ${sumChanges.toString()}`);
|
|
49233
49368
|
if (!sumChanges.eq(0)) throw new Error("Sum of changes must be zero");
|
|
49234
49369
|
logger.verbose(`Sum of final: ${sumFinal.toString()}`);
|
|
49235
49370
|
logger.verbose(`Total assets: ${totalAssets.toString()}`);
|
|
49236
|
-
if (!sumFinal.eq(totalAssets.toString()))
|
|
49371
|
+
if (!sumFinal.eq(totalAssets.toString()))
|
|
49372
|
+
throw new Error("Sum of final amounts must equal total assets");
|
|
49237
49373
|
if (!hasChanges) throw new Error("No changes required");
|
|
49238
49374
|
const finalPools = pools.map((p) => {
|
|
49239
49375
|
const target = targetAmounts[p.pool_id.address.toString()] || Web3Number.fromWei("0", this.decimals());
|
|
@@ -49261,9 +49397,13 @@ var strkfarm_risk_engine = (() => {
|
|
|
49261
49397
|
if (p.changeAmt.eq(0)) return null;
|
|
49262
49398
|
actions.push({
|
|
49263
49399
|
pool_id: p.pool_id.address,
|
|
49264
|
-
feature: new CairoCustomEnum(
|
|
49400
|
+
feature: new CairoCustomEnum(
|
|
49401
|
+
p.isDeposit ? { DEPOSIT: {} } : { WITHDRAW: {} }
|
|
49402
|
+
),
|
|
49265
49403
|
token: this.asset().address.address,
|
|
49266
|
-
amount: uint256_exports.bnToUint256(
|
|
49404
|
+
amount: uint256_exports.bnToUint256(
|
|
49405
|
+
p.changeAmt.multipliedBy(p.isDeposit ? 1 : -1).toWei()
|
|
49406
|
+
)
|
|
49267
49407
|
});
|
|
49268
49408
|
});
|
|
49269
49409
|
if (actions.length === 0) return null;
|
|
@@ -49276,18 +49416,29 @@ var strkfarm_risk_engine = (() => {
|
|
|
49276
49416
|
const netYield = await this.netAPYGivenPools(pools);
|
|
49277
49417
|
const baseFlow = {
|
|
49278
49418
|
title: "Your Deposit",
|
|
49279
|
-
subItems: [
|
|
49419
|
+
subItems: [
|
|
49420
|
+
{ key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` },
|
|
49421
|
+
{
|
|
49422
|
+
key: `Performance Fee`,
|
|
49423
|
+
value: `${(this.metadata.additionalInfo.feeBps / 100).toFixed(2)}%`
|
|
49424
|
+
}
|
|
49425
|
+
],
|
|
49280
49426
|
linkedFlows: [],
|
|
49281
49427
|
style: { backgroundColor: "#6e53dc" /* Purple */.valueOf() }
|
|
49282
49428
|
};
|
|
49283
49429
|
let _pools = [...pools];
|
|
49284
|
-
_pools = _pools.sort(
|
|
49430
|
+
_pools = _pools.sort(
|
|
49431
|
+
(a, b) => Number(b.amount.toString()) - Number(a.amount.toString())
|
|
49432
|
+
);
|
|
49285
49433
|
_pools.forEach((p) => {
|
|
49286
49434
|
const flow = {
|
|
49287
49435
|
title: `Pool name: ${p.pool_name}`,
|
|
49288
49436
|
subItems: [
|
|
49289
49437
|
{ key: `APY`, value: `${(p.APY.netApy * 100).toFixed(2)}%` },
|
|
49290
|
-
{
|
|
49438
|
+
{
|
|
49439
|
+
key: "Weight",
|
|
49440
|
+
value: `${(p.current_weight * 100).toFixed(2)} / ${(p.max_weight * 100).toFixed(2)}%`
|
|
49441
|
+
}
|
|
49291
49442
|
],
|
|
49292
49443
|
linkedFlows: [],
|
|
49293
49444
|
style: p.amount.greaterThan(0) ? { backgroundColor: "#35484f" /* Blue */.valueOf() } : { color: "gray" }
|
|
@@ -49319,7 +49470,12 @@ var strkfarm_risk_engine = (() => {
|
|
|
49319
49470
|
harvest.actualReward.toWei(),
|
|
49320
49471
|
this.address.address
|
|
49321
49472
|
);
|
|
49322
|
-
swapInfo = await avnu.getSwapInfo(
|
|
49473
|
+
swapInfo = await avnu.getSwapInfo(
|
|
49474
|
+
quote,
|
|
49475
|
+
this.address.address,
|
|
49476
|
+
0,
|
|
49477
|
+
this.address.address
|
|
49478
|
+
);
|
|
49323
49479
|
}
|
|
49324
49480
|
return [
|
|
49325
49481
|
this.contract.populate("harvest", [
|
|
@@ -49340,16 +49496,27 @@ var strkfarm_risk_engine = (() => {
|
|
|
49340
49496
|
* @returns {Promise<Array<{ vToken: ContractAddr, fee: Web3Number }>>} Array of fees deducted in different vTokens
|
|
49341
49497
|
*/
|
|
49342
49498
|
async getFee(allowedPools) {
|
|
49343
|
-
const assets = Web3Number.fromWei(
|
|
49344
|
-
|
|
49345
|
-
|
|
49499
|
+
const assets = Web3Number.fromWei(
|
|
49500
|
+
(await this.contract.total_assets()).toString(),
|
|
49501
|
+
this.asset().decimals
|
|
49502
|
+
);
|
|
49503
|
+
const totalSupply = Web3Number.fromWei(
|
|
49504
|
+
(await this.contract.total_supply()).toString(),
|
|
49505
|
+
this.asset().decimals
|
|
49506
|
+
);
|
|
49507
|
+
const prevIndex = Web3Number.fromWei(
|
|
49508
|
+
(await this.contract.get_previous_index()).toString(),
|
|
49509
|
+
18
|
|
49510
|
+
);
|
|
49346
49511
|
const currIndex = new Web3Number(1, 18).multipliedBy(assets).dividedBy(totalSupply);
|
|
49347
49512
|
logger.verbose(`Previous index: ${prevIndex.toString()}`);
|
|
49348
49513
|
logger.verbose(`Assets: ${assets.toString()}`);
|
|
49349
49514
|
logger.verbose(`Total supply: ${totalSupply.toString()}`);
|
|
49350
49515
|
logger.verbose(`Current index: ${currIndex.toNumber()}`);
|
|
49351
49516
|
if (currIndex.lt(prevIndex)) {
|
|
49352
|
-
logger.verbose(
|
|
49517
|
+
logger.verbose(
|
|
49518
|
+
`getFee::Current index is less than previous index, no fees to be deducted`
|
|
49519
|
+
);
|
|
49353
49520
|
return [];
|
|
49354
49521
|
}
|
|
49355
49522
|
const indexDiff = currIndex.minus(prevIndex);
|
|
@@ -49362,7 +49529,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
49362
49529
|
return [];
|
|
49363
49530
|
}
|
|
49364
49531
|
const fees = [];
|
|
49365
|
-
let remainingFee = fee.plus(
|
|
49532
|
+
let remainingFee = fee.plus(
|
|
49533
|
+
Web3Number.fromWei("100", this.asset().decimals)
|
|
49534
|
+
);
|
|
49366
49535
|
for (const pool of allowedPools) {
|
|
49367
49536
|
const vToken = pool.v_token;
|
|
49368
49537
|
const balance = pool.amount;
|
|
@@ -49371,7 +49540,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
49371
49540
|
break;
|
|
49372
49541
|
} else {
|
|
49373
49542
|
fees.push({ vToken, fee: Web3Number.fromWei(balance.toString(), 18) });
|
|
49374
|
-
remainingFee = remainingFee.minus(
|
|
49543
|
+
remainingFee = remainingFee.minus(
|
|
49544
|
+
Web3Number.fromWei(balance.toString(), 18)
|
|
49545
|
+
);
|
|
49375
49546
|
}
|
|
49376
49547
|
}
|
|
49377
49548
|
logger.verbose(`Fees: ${JSON.stringify(fees)}`);
|
|
@@ -49379,98 +49550,168 @@ var strkfarm_risk_engine = (() => {
|
|
|
49379
49550
|
}
|
|
49380
49551
|
};
|
|
49381
49552
|
var _description = "Automatically diversify {{TOKEN}} holdings into different Vesu pools while reducing risk and maximizing yield. Defi spring STRK Rewards are auto-compounded as well.";
|
|
49382
|
-
var _protocol = {
|
|
49553
|
+
var _protocol = {
|
|
49554
|
+
name: "Vesu",
|
|
49555
|
+
logo: "https://static-assets-8zct.onrender.com/integrations/vesu/logo.png"
|
|
49556
|
+
};
|
|
49383
49557
|
var _riskFactor = [
|
|
49384
49558
|
{ type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 0.5, weight: 25 },
|
|
49385
49559
|
{ type: "Counterparty Risk" /* COUNTERPARTY_RISK */, value: 1, weight: 50 },
|
|
49386
49560
|
{ type: "Oracle Risk" /* ORACLE_RISK */, value: 0.5, weight: 25 }
|
|
49387
49561
|
];
|
|
49388
49562
|
var AUDIT_URL = "https://assets.strkfarm.com/strkfarm/audit_report_vesu_and_ekubo_strats.pdf";
|
|
49389
|
-
var
|
|
49390
|
-
|
|
49391
|
-
|
|
49392
|
-
|
|
49393
|
-
|
|
49394
|
-
|
|
49395
|
-
|
|
49396
|
-
|
|
49397
|
-
|
|
49398
|
-
|
|
49399
|
-
|
|
49400
|
-
|
|
49401
|
-
|
|
49402
|
-
|
|
49403
|
-
|
|
49404
|
-
|
|
49405
|
-
}
|
|
49406
|
-
|
|
49407
|
-
|
|
49408
|
-
|
|
49409
|
-
|
|
49410
|
-
|
|
49411
|
-
|
|
49412
|
-
|
|
49413
|
-
|
|
49414
|
-
|
|
49415
|
-
|
|
49416
|
-
|
|
49417
|
-
|
|
49418
|
-
|
|
49419
|
-
|
|
49420
|
-
|
|
49421
|
-
|
|
49563
|
+
var faqs = [
|
|
49564
|
+
{
|
|
49565
|
+
question: "What is the Vesu Rebalancing Strategy?",
|
|
49566
|
+
answer: "The Vesu Rebalancing Strategy is an automated investment strategy that diversifies your holdings across multiple Vesu pools. It optimizes yield by rebalancing assets based on pool performance while adhering to risk constraints."
|
|
49567
|
+
},
|
|
49568
|
+
{
|
|
49569
|
+
question: "Will I earn Vesu points?",
|
|
49570
|
+
answer: "Yes, of course! You will earn Vesu points for your deposits."
|
|
49571
|
+
},
|
|
49572
|
+
{
|
|
49573
|
+
question: "How does the strategy optimize yield?",
|
|
49574
|
+
answer: "The strategy calculates the weighted average APY across all pools and reallocates assets to maximize returns. It prioritizes high-performing pools while ensuring compliance with maximum weight constraints."
|
|
49575
|
+
},
|
|
49576
|
+
{
|
|
49577
|
+
question: "What are the risks associated with this strategy?",
|
|
49578
|
+
answer: "The strategy involves usual DeFi risks such as smart contract vulnerabilities, counterparty risks, and oracle inaccuracies. However, we try our best to reduce these risks through audits and careful pool selection."
|
|
49579
|
+
},
|
|
49580
|
+
{
|
|
49581
|
+
question: "How are fees calculated and deducted?",
|
|
49582
|
+
answer: "Fees are calculated based on the performance of the strategy and deducted proportionally from the total assets. We charge a 10% performance fee and is already accounted in the APY shown."
|
|
49583
|
+
},
|
|
49584
|
+
{
|
|
49585
|
+
question: "What happens if a pool exceeds its maximum weight?",
|
|
49586
|
+
answer: "If a pool exceeds its maximum weight, the strategy rebalances by withdrawing excess funds and reallocating them to other pools with available capacity."
|
|
49587
|
+
},
|
|
49588
|
+
{
|
|
49589
|
+
question: "Can I withdraw my assets at any time?",
|
|
49590
|
+
answer: "Yes, you can withdraw your assets at any time. In rare circumstances, if debt utilisation is high for certain pools on Vesu, it may not be possible to withdraw until markets restore balance."
|
|
49591
|
+
},
|
|
49592
|
+
{
|
|
49593
|
+
question: "What happens to my Defi Spring STRK rewards?",
|
|
49594
|
+
answer: "STRK rewards are automatically harvested and reinvested into the strategy every week to maximize compounding returns."
|
|
49595
|
+
},
|
|
49596
|
+
{
|
|
49597
|
+
question: "Is the strategy audited?",
|
|
49598
|
+
answer: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
49599
|
+
"Yes, the strategy has been audited. You can review the audit report in our docs ",
|
|
49600
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: "https://docs.strkfarm.com/p/strategies/vesu-fusion-rebalancing-vaults#technical-details", style: { textDecoration: "underline", marginLeft: "5px" }, children: "Here" }),
|
|
49601
|
+
"."
|
|
49602
|
+
] })
|
|
49422
49603
|
}
|
|
49423
|
-
|
|
49424
|
-
|
|
49425
|
-
|
|
49426
|
-
|
|
49427
|
-
|
|
49428
|
-
|
|
49429
|
-
|
|
49430
|
-
|
|
49431
|
-
|
|
49432
|
-
|
|
49433
|
-
|
|
49434
|
-
|
|
49435
|
-
|
|
49436
|
-
|
|
49437
|
-
|
|
49438
|
-
|
|
49604
|
+
];
|
|
49605
|
+
var VesuRebalanceStrategies = [
|
|
49606
|
+
{
|
|
49607
|
+
name: "Vesu Fusion STRK",
|
|
49608
|
+
description: _description.replace("{{TOKEN}}", "STRK"),
|
|
49609
|
+
address: ContractAddr.from(
|
|
49610
|
+
"0x7fb5bcb8525954a60fde4e8fb8220477696ce7117ef264775a1770e23571929"
|
|
49611
|
+
),
|
|
49612
|
+
type: "ERC4626",
|
|
49613
|
+
depositTokens: [
|
|
49614
|
+
Global.getDefaultTokens().find((t) => t.symbol === "STRK")
|
|
49615
|
+
],
|
|
49616
|
+
protocols: [_protocol],
|
|
49617
|
+
auditUrl: AUDIT_URL,
|
|
49618
|
+
maxTVL: Web3Number.fromWei("0", 18),
|
|
49619
|
+
risk: {
|
|
49620
|
+
riskFactor: _riskFactor,
|
|
49621
|
+
netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
|
|
49622
|
+
notARisks: getNoRiskTags(_riskFactor)
|
|
49623
|
+
},
|
|
49624
|
+
additionalInfo: {
|
|
49625
|
+
feeBps: 1e3
|
|
49626
|
+
},
|
|
49627
|
+
faqs
|
|
49628
|
+
},
|
|
49629
|
+
{
|
|
49630
|
+
name: "Vesu Fusion ETH",
|
|
49631
|
+
description: _description.replace("{{TOKEN}}", "ETH"),
|
|
49632
|
+
address: ContractAddr.from(
|
|
49633
|
+
"0x5eaf5ee75231cecf79921ff8ded4b5ffe96be718bcb3daf206690ad1a9ad0ca"
|
|
49634
|
+
),
|
|
49635
|
+
type: "ERC4626",
|
|
49636
|
+
auditUrl: AUDIT_URL,
|
|
49637
|
+
depositTokens: [
|
|
49638
|
+
Global.getDefaultTokens().find((t) => t.symbol === "ETH")
|
|
49639
|
+
],
|
|
49640
|
+
protocols: [_protocol],
|
|
49641
|
+
maxTVL: Web3Number.fromWei("0", 18),
|
|
49642
|
+
risk: {
|
|
49643
|
+
riskFactor: _riskFactor,
|
|
49644
|
+
netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
|
|
49645
|
+
notARisks: getNoRiskTags(_riskFactor)
|
|
49646
|
+
},
|
|
49647
|
+
additionalInfo: {
|
|
49648
|
+
feeBps: 1e3
|
|
49649
|
+
},
|
|
49650
|
+
faqs
|
|
49651
|
+
},
|
|
49652
|
+
{
|
|
49653
|
+
name: "Vesu Fusion USDC",
|
|
49654
|
+
description: _description.replace("{{TOKEN}}", "USDC"),
|
|
49655
|
+
address: ContractAddr.from(
|
|
49656
|
+
"0xa858c97e9454f407d1bd7c57472fc8d8d8449a777c822b41d18e387816f29c"
|
|
49657
|
+
),
|
|
49658
|
+
type: "ERC4626",
|
|
49659
|
+
auditUrl: AUDIT_URL,
|
|
49660
|
+
depositTokens: [
|
|
49661
|
+
Global.getDefaultTokens().find((t) => t.symbol === "USDC")
|
|
49662
|
+
],
|
|
49663
|
+
protocols: [_protocol],
|
|
49664
|
+
maxTVL: Web3Number.fromWei("0", 6),
|
|
49665
|
+
risk: {
|
|
49666
|
+
riskFactor: _riskFactor,
|
|
49667
|
+
netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
|
|
49668
|
+
notARisks: getNoRiskTags(_riskFactor)
|
|
49669
|
+
},
|
|
49670
|
+
additionalInfo: {
|
|
49671
|
+
feeBps: 1e3
|
|
49672
|
+
},
|
|
49673
|
+
faqs
|
|
49674
|
+
},
|
|
49675
|
+
{
|
|
49676
|
+
name: "Vesu Fusion USDT",
|
|
49677
|
+
description: _description.replace("{{TOKEN}}", "USDT"),
|
|
49678
|
+
address: ContractAddr.from(
|
|
49679
|
+
"0x115e94e722cfc4c77a2f15c4aefb0928c1c0029e5a57570df24c650cb7cec2c"
|
|
49680
|
+
),
|
|
49681
|
+
type: "ERC4626",
|
|
49682
|
+
depositTokens: [
|
|
49683
|
+
Global.getDefaultTokens().find((t) => t.symbol === "USDT")
|
|
49684
|
+
],
|
|
49685
|
+
auditUrl: AUDIT_URL,
|
|
49686
|
+
protocols: [_protocol],
|
|
49687
|
+
maxTVL: Web3Number.fromWei("0", 6),
|
|
49688
|
+
risk: {
|
|
49689
|
+
riskFactor: _riskFactor,
|
|
49690
|
+
netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
|
|
49691
|
+
notARisks: getNoRiskTags(_riskFactor)
|
|
49692
|
+
},
|
|
49693
|
+
additionalInfo: {
|
|
49694
|
+
feeBps: 1e3
|
|
49695
|
+
},
|
|
49696
|
+
faqs
|
|
49697
|
+
// }, {
|
|
49698
|
+
// name: 'Vesu Fusion WBTC',
|
|
49699
|
+
// description: _description.replace('{{TOKEN}}', 'WBTC'),
|
|
49700
|
+
// address: ContractAddr.from('0x778007f8136a5b827325d21613803e796bda4d676fbe1e34aeab0b2a2ec027f'),
|
|
49701
|
+
// type: 'ERC4626',
|
|
49702
|
+
// depositTokens: [Global.getDefaultTokens().find(t => t.symbol === 'WBTC')!],
|
|
49703
|
+
// auditUrl: AUDIT_URL,
|
|
49704
|
+
// protocols: [_protocol],
|
|
49705
|
+
// maxTVL: Web3Number.fromWei('0', 8),
|
|
49706
|
+
// risk: {
|
|
49707
|
+
// riskFactor: _riskFactor,
|
|
49708
|
+
// netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
|
|
49709
|
+
// },
|
|
49710
|
+
// additionalInfo: {
|
|
49711
|
+
// feeBps: 1000,
|
|
49712
|
+
// },
|
|
49439
49713
|
}
|
|
49440
|
-
|
|
49441
|
-
name: "Vesu Fusion USDT",
|
|
49442
|
-
description: _description.replace("{{TOKEN}}", "USDT"),
|
|
49443
|
-
address: ContractAddr.from("0x115e94e722cfc4c77a2f15c4aefb0928c1c0029e5a57570df24c650cb7cec2c"),
|
|
49444
|
-
type: "ERC4626",
|
|
49445
|
-
depositTokens: [Global.getDefaultTokens().find((t) => t.symbol === "USDT")],
|
|
49446
|
-
auditUrl: AUDIT_URL,
|
|
49447
|
-
protocols: [_protocol],
|
|
49448
|
-
maxTVL: Web3Number.fromWei("0", 6),
|
|
49449
|
-
risk: {
|
|
49450
|
-
riskFactor: _riskFactor,
|
|
49451
|
-
netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
|
|
49452
|
-
notARisks: getNoRiskTags(_riskFactor)
|
|
49453
|
-
},
|
|
49454
|
-
additionalInfo: {
|
|
49455
|
-
feeBps: 1e3
|
|
49456
|
-
}
|
|
49457
|
-
// }, {
|
|
49458
|
-
// name: 'Vesu Fusion WBTC',
|
|
49459
|
-
// description: _description.replace('{{TOKEN}}', 'WBTC'),
|
|
49460
|
-
// address: ContractAddr.from('0x778007f8136a5b827325d21613803e796bda4d676fbe1e34aeab0b2a2ec027f'),
|
|
49461
|
-
// type: 'ERC4626',
|
|
49462
|
-
// depositTokens: [Global.getDefaultTokens().find(t => t.symbol === 'WBTC')!],
|
|
49463
|
-
// auditUrl: AUDIT_URL,
|
|
49464
|
-
// protocols: [_protocol],
|
|
49465
|
-
// maxTVL: Web3Number.fromWei('0', 8),
|
|
49466
|
-
// risk: {
|
|
49467
|
-
// riskFactor: _riskFactor,
|
|
49468
|
-
// netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
|
|
49469
|
-
// },
|
|
49470
|
-
// additionalInfo: {
|
|
49471
|
-
// feeBps: 1000,
|
|
49472
|
-
// },
|
|
49473
|
-
}];
|
|
49714
|
+
];
|
|
49474
49715
|
|
|
49475
49716
|
// src/data/cl-vault.abi.json
|
|
49476
49717
|
var cl_vault_abi_default = [
|
|
@@ -54372,7 +54613,7 @@ var strkfarm_risk_engine = (() => {
|
|
|
54372
54613
|
];
|
|
54373
54614
|
|
|
54374
54615
|
// src/strategies/ekubo-cl-vault.tsx
|
|
54375
|
-
var
|
|
54616
|
+
var import_jsx_runtime2 = __toESM(require_jsx_runtime());
|
|
54376
54617
|
var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
54377
54618
|
/**
|
|
54378
54619
|
* Creates a new VesuRebalance strategy instance.
|
|
@@ -54385,15 +54626,34 @@ var strkfarm_risk_engine = (() => {
|
|
|
54385
54626
|
super(config2);
|
|
54386
54627
|
this.BASE_WEIGHT = 1e4;
|
|
54387
54628
|
this.pricer = pricer;
|
|
54388
|
-
assert3(
|
|
54629
|
+
assert3(
|
|
54630
|
+
metadata.depositTokens.length === 2,
|
|
54631
|
+
"EkuboCL only supports 2 deposit token"
|
|
54632
|
+
);
|
|
54389
54633
|
this.metadata = metadata;
|
|
54390
54634
|
this.address = metadata.address;
|
|
54391
|
-
this.contract = new Contract(
|
|
54392
|
-
|
|
54635
|
+
this.contract = new Contract(
|
|
54636
|
+
cl_vault_abi_default,
|
|
54637
|
+
this.address.address,
|
|
54638
|
+
this.config.provider
|
|
54639
|
+
);
|
|
54640
|
+
this.lstContract = new Contract(
|
|
54641
|
+
erc4626_abi_default,
|
|
54642
|
+
this.metadata.additionalInfo.lstContract.address,
|
|
54643
|
+
this.config.provider
|
|
54644
|
+
);
|
|
54393
54645
|
const EKUBO_POSITION = "0x02e0af29598b407c8716b17f6d2795eca1b471413fa03fb145a5e33722184067";
|
|
54394
|
-
this.ekuboPositionsContract = new Contract(
|
|
54646
|
+
this.ekuboPositionsContract = new Contract(
|
|
54647
|
+
ekubo_positions_abi_default,
|
|
54648
|
+
EKUBO_POSITION,
|
|
54649
|
+
this.config.provider
|
|
54650
|
+
);
|
|
54395
54651
|
const EKUBO_MATH = "0x04a72e9e166f6c0e9d800af4dc40f6b6fb4404b735d3f528d9250808b2481995";
|
|
54396
|
-
this.ekuboMathContract = new Contract(
|
|
54652
|
+
this.ekuboMathContract = new Contract(
|
|
54653
|
+
ekubo_math_abi_default,
|
|
54654
|
+
EKUBO_MATH,
|
|
54655
|
+
this.config.provider
|
|
54656
|
+
);
|
|
54397
54657
|
this.avnu = new AvnuWrapper();
|
|
54398
54658
|
}
|
|
54399
54659
|
async matchInputAmounts(amountInfo) {
|
|
@@ -54418,25 +54678,52 @@ var strkfarm_risk_engine = (() => {
|
|
|
54418
54678
|
/** Returns minimum amounts give given two amounts based on what can be added for liq */
|
|
54419
54679
|
async getMinDepositAmounts(amountInfo) {
|
|
54420
54680
|
const shares = await this.tokensToShares(amountInfo);
|
|
54421
|
-
const { amount0, amount1 } = await this.contract.call(
|
|
54681
|
+
const { amount0, amount1 } = await this.contract.call(
|
|
54682
|
+
"convert_to_assets",
|
|
54683
|
+
[uint256_exports.bnToUint256(shares.toWei())]
|
|
54684
|
+
);
|
|
54422
54685
|
return {
|
|
54423
54686
|
token0: {
|
|
54424
54687
|
tokenInfo: amountInfo.token0.tokenInfo,
|
|
54425
|
-
amount: Web3Number.fromWei(
|
|
54688
|
+
amount: Web3Number.fromWei(
|
|
54689
|
+
amount0.toString(),
|
|
54690
|
+
amountInfo.token0.tokenInfo.decimals
|
|
54691
|
+
)
|
|
54426
54692
|
},
|
|
54427
54693
|
token1: {
|
|
54428
54694
|
tokenInfo: amountInfo.token1.tokenInfo,
|
|
54429
|
-
amount: Web3Number.fromWei(
|
|
54695
|
+
amount: Web3Number.fromWei(
|
|
54696
|
+
amount1.toString(),
|
|
54697
|
+
amountInfo.token1.tokenInfo.decimals
|
|
54698
|
+
)
|
|
54430
54699
|
}
|
|
54431
54700
|
};
|
|
54432
54701
|
}
|
|
54433
54702
|
async depositCall(amountInfo, receiver) {
|
|
54434
54703
|
const updateAmountInfo = await this.getMinDepositAmounts(amountInfo);
|
|
54435
|
-
const token0Contract = new Contract(
|
|
54436
|
-
|
|
54437
|
-
|
|
54438
|
-
|
|
54439
|
-
|
|
54704
|
+
const token0Contract = new Contract(
|
|
54705
|
+
erc4626_abi_default,
|
|
54706
|
+
amountInfo.token0.tokenInfo.address.address,
|
|
54707
|
+
this.config.provider
|
|
54708
|
+
);
|
|
54709
|
+
const token1Contract = new Contract(
|
|
54710
|
+
erc4626_abi_default,
|
|
54711
|
+
amountInfo.token1.tokenInfo.address.address,
|
|
54712
|
+
this.config.provider
|
|
54713
|
+
);
|
|
54714
|
+
const call1 = token0Contract.populate("approve", [
|
|
54715
|
+
this.address.address,
|
|
54716
|
+
uint256_exports.bnToUint256(updateAmountInfo.token0.amount.toWei())
|
|
54717
|
+
]);
|
|
54718
|
+
const call2 = token1Contract.populate("approve", [
|
|
54719
|
+
this.address.address,
|
|
54720
|
+
uint256_exports.bnToUint256(updateAmountInfo.token1.amount.toWei())
|
|
54721
|
+
]);
|
|
54722
|
+
const call3 = this.contract.populate("deposit", [
|
|
54723
|
+
uint256_exports.bnToUint256(updateAmountInfo.token0.amount.toWei()),
|
|
54724
|
+
uint256_exports.bnToUint256(updateAmountInfo.token1.amount.toWei()),
|
|
54725
|
+
receiver.address
|
|
54726
|
+
]);
|
|
54440
54727
|
const calls = [];
|
|
54441
54728
|
if (updateAmountInfo.token0.amount.greaterThan(0)) calls.push(call1);
|
|
54442
54729
|
if (updateAmountInfo.token1.amount.greaterThan(0)) calls.push(call2);
|
|
@@ -54451,25 +54738,29 @@ var strkfarm_risk_engine = (() => {
|
|
|
54451
54738
|
}
|
|
54452
54739
|
async withdrawCall(amountInfo, receiver, owner) {
|
|
54453
54740
|
const shares = await this.tokensToShares(amountInfo);
|
|
54454
|
-
logger.verbose(
|
|
54455
|
-
|
|
54456
|
-
|
|
54457
|
-
|
|
54458
|
-
|
|
54741
|
+
logger.verbose(
|
|
54742
|
+
`${_EkuboCLVault.name}: withdrawCall: shares=${shares.toString()}`
|
|
54743
|
+
);
|
|
54744
|
+
return [
|
|
54745
|
+
this.contract.populate("withdraw", [
|
|
54746
|
+
uint256_exports.bnToUint256(shares.toWei()),
|
|
54747
|
+
receiver.address
|
|
54748
|
+
])
|
|
54749
|
+
];
|
|
54459
54750
|
}
|
|
54460
54751
|
rebalanceCall(newBounds, swapParams) {
|
|
54461
|
-
return [
|
|
54462
|
-
|
|
54463
|
-
|
|
54464
|
-
|
|
54465
|
-
|
|
54466
|
-
|
|
54467
|
-
|
|
54752
|
+
return [
|
|
54753
|
+
this.contract.populate("rebalance", [
|
|
54754
|
+
{
|
|
54755
|
+
lower: _EkuboCLVault.tickToi129(Number(newBounds.lowerTick)),
|
|
54756
|
+
upper: _EkuboCLVault.tickToi129(Number(newBounds.upperTick))
|
|
54757
|
+
},
|
|
54758
|
+
swapParams
|
|
54759
|
+
])
|
|
54760
|
+
];
|
|
54468
54761
|
}
|
|
54469
54762
|
handleUnusedCall(swapParams) {
|
|
54470
|
-
return [this.contract.populate("handle_unused", [
|
|
54471
|
-
swapParams
|
|
54472
|
-
])];
|
|
54763
|
+
return [this.contract.populate("handle_unused", [swapParams])];
|
|
54473
54764
|
}
|
|
54474
54765
|
handleFeesCall() {
|
|
54475
54766
|
return [this.contract.populate("handle_fees", [])];
|
|
@@ -54485,8 +54776,12 @@ var strkfarm_risk_engine = (() => {
|
|
|
54485
54776
|
let blockNow = typeof blockIdentifier == "number" ? blockIdentifier : (await this.config.provider.getBlockLatestAccepted()).block_number;
|
|
54486
54777
|
const blockNowTime = typeof blockIdentifier == "number" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
|
|
54487
54778
|
const blockBefore = blockNow - sinceBlocks;
|
|
54488
|
-
const adjustedSupplyNow = supplyNow.minus(
|
|
54489
|
-
|
|
54779
|
+
const adjustedSupplyNow = supplyNow.minus(
|
|
54780
|
+
await this.getHarvestRewardShares(blockBefore, blockNow)
|
|
54781
|
+
);
|
|
54782
|
+
let blockBeforeInfo = await this.config.provider.getBlockWithTxs(
|
|
54783
|
+
blockBefore
|
|
54784
|
+
);
|
|
54490
54785
|
const tvlBefore = await this._getTVL(blockBefore);
|
|
54491
54786
|
const supplyBefore = await this.totalSupply(blockBefore);
|
|
54492
54787
|
const priceBefore = await this.getCurrentPrice(blockBefore);
|
|
@@ -54504,7 +54799,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
54504
54799
|
logger.verbose(`Supply before: ${supplyBefore.toString()}`);
|
|
54505
54800
|
logger.verbose(`Supply now: ${adjustedSupplyNow.toString()}`);
|
|
54506
54801
|
logger.verbose(`Time diff in seconds: ${timeDiffSeconds}`);
|
|
54507
|
-
const apyForGivenBlocks = Number(
|
|
54802
|
+
const apyForGivenBlocks = Number(
|
|
54803
|
+
tvlPerShareNow.minus(tvlPerShareBf).multipliedBy(1e4).dividedBy(tvlPerShareBf)
|
|
54804
|
+
) / 1e4;
|
|
54508
54805
|
return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
|
|
54509
54806
|
}
|
|
54510
54807
|
async getHarvestRewardShares(fromBlock, toBlock) {
|
|
@@ -54522,7 +54819,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
54522
54819
|
} else {
|
|
54523
54820
|
shares = shares.plus(Web3Number.fromWei(record.shares.toString(), 18));
|
|
54524
54821
|
}
|
|
54525
|
-
logger.verbose(
|
|
54822
|
+
logger.verbose(
|
|
54823
|
+
`${_EkuboCLVault.name}: getHarvestRewardShares: ${i} => ${shares.toWei()}`
|
|
54824
|
+
);
|
|
54526
54825
|
}
|
|
54527
54826
|
return shares;
|
|
54528
54827
|
}
|
|
@@ -54532,15 +54831,25 @@ var strkfarm_risk_engine = (() => {
|
|
|
54532
54831
|
}
|
|
54533
54832
|
async getUserTVL(user, blockIdentifier = "pending") {
|
|
54534
54833
|
let bal = await this.balanceOf(user, blockIdentifier);
|
|
54535
|
-
const assets = await this.contract.call(
|
|
54536
|
-
|
|
54537
|
-
|
|
54834
|
+
const assets = await this.contract.call(
|
|
54835
|
+
"convert_to_assets",
|
|
54836
|
+
[uint256_exports.bnToUint256(bal.toWei())],
|
|
54837
|
+
{
|
|
54838
|
+
blockIdentifier
|
|
54839
|
+
}
|
|
54840
|
+
);
|
|
54538
54841
|
const poolKey = await this.getPoolKey(blockIdentifier);
|
|
54539
54842
|
this.assertValidDepositTokens(poolKey);
|
|
54540
54843
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
54541
54844
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
54542
|
-
const amount0 = Web3Number.fromWei(
|
|
54543
|
-
|
|
54845
|
+
const amount0 = Web3Number.fromWei(
|
|
54846
|
+
assets.amount0.toString(),
|
|
54847
|
+
token0Info.decimals
|
|
54848
|
+
);
|
|
54849
|
+
const amount1 = Web3Number.fromWei(
|
|
54850
|
+
assets.amount1.toString(),
|
|
54851
|
+
token1Info.decimals
|
|
54852
|
+
);
|
|
54544
54853
|
const P0 = await this.pricer.getPrice(token0Info.symbol);
|
|
54545
54854
|
const P1 = await this.pricer.getPrice(token1Info.symbol);
|
|
54546
54855
|
const token0Usd = Number(amount0.toFixed(13)) * P0.price;
|
|
@@ -54564,7 +54873,11 @@ var strkfarm_risk_engine = (() => {
|
|
|
54564
54873
|
blockIdentifier
|
|
54565
54874
|
});
|
|
54566
54875
|
const bounds = await this.getCurrentBounds(blockIdentifier);
|
|
54567
|
-
const { amount0, amount1 } = await this.getLiquidityToAmounts(
|
|
54876
|
+
const { amount0, amount1 } = await this.getLiquidityToAmounts(
|
|
54877
|
+
Web3Number.fromWei(result.toString(), 18),
|
|
54878
|
+
bounds,
|
|
54879
|
+
blockIdentifier
|
|
54880
|
+
);
|
|
54568
54881
|
return { amount0, amount1 };
|
|
54569
54882
|
}
|
|
54570
54883
|
async totalSupply(blockIdentifier = "pending") {
|
|
@@ -54574,8 +54887,14 @@ var strkfarm_risk_engine = (() => {
|
|
|
54574
54887
|
return Web3Number.fromWei(res.toString(), 18);
|
|
54575
54888
|
}
|
|
54576
54889
|
assertValidDepositTokens(poolKey) {
|
|
54577
|
-
assert3(
|
|
54578
|
-
|
|
54890
|
+
assert3(
|
|
54891
|
+
poolKey.token0.eq(this.metadata.depositTokens[0].address),
|
|
54892
|
+
"Expected token0 in depositTokens[0]"
|
|
54893
|
+
);
|
|
54894
|
+
assert3(
|
|
54895
|
+
poolKey.token1.eq(this.metadata.depositTokens[1].address),
|
|
54896
|
+
"Expected token1 in depositTokens[1]"
|
|
54897
|
+
);
|
|
54579
54898
|
}
|
|
54580
54899
|
async getTVL(blockIdentifier = "pending") {
|
|
54581
54900
|
const { amount0, amount1 } = await this._getTVL(blockIdentifier);
|
|
@@ -54605,26 +54924,35 @@ var strkfarm_risk_engine = (() => {
|
|
|
54605
54924
|
const nftID = await this.getCurrentNFTID();
|
|
54606
54925
|
const poolKey = await this.getPoolKey();
|
|
54607
54926
|
const currentBounds = await this.getCurrentBounds();
|
|
54608
|
-
const result = await this.ekuboPositionsContract.call(
|
|
54609
|
-
|
|
54610
|
-
|
|
54611
|
-
|
|
54612
|
-
|
|
54613
|
-
|
|
54614
|
-
|
|
54615
|
-
|
|
54616
|
-
|
|
54617
|
-
|
|
54618
|
-
|
|
54619
|
-
|
|
54620
|
-
|
|
54621
|
-
|
|
54927
|
+
const result = await this.ekuboPositionsContract.call(
|
|
54928
|
+
"get_token_info",
|
|
54929
|
+
[
|
|
54930
|
+
nftID,
|
|
54931
|
+
{
|
|
54932
|
+
token0: poolKey.token0.address,
|
|
54933
|
+
token1: poolKey.token1.address,
|
|
54934
|
+
fee: poolKey.fee,
|
|
54935
|
+
tick_spacing: poolKey.tick_spacing,
|
|
54936
|
+
extension: poolKey.extension
|
|
54937
|
+
},
|
|
54938
|
+
{
|
|
54939
|
+
lower: _EkuboCLVault.tickToi129(Number(currentBounds.lowerTick)),
|
|
54940
|
+
upper: _EkuboCLVault.tickToi129(Number(currentBounds.upperTick))
|
|
54941
|
+
}
|
|
54942
|
+
]
|
|
54943
|
+
);
|
|
54622
54944
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
54623
54945
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
54624
54946
|
const P0 = await this.pricer.getPrice(token0Info.symbol);
|
|
54625
54947
|
const P1 = await this.pricer.getPrice(token1Info.symbol);
|
|
54626
|
-
const token0Web3 = Web3Number.fromWei(
|
|
54627
|
-
|
|
54948
|
+
const token0Web3 = Web3Number.fromWei(
|
|
54949
|
+
result.fees0.toString(),
|
|
54950
|
+
token0Info.decimals
|
|
54951
|
+
);
|
|
54952
|
+
const token1Web3 = Web3Number.fromWei(
|
|
54953
|
+
result.fees1.toString(),
|
|
54954
|
+
token1Info.decimals
|
|
54955
|
+
);
|
|
54628
54956
|
const token0Usd = Number(token0Web3.toFixed(13)) * P0.price;
|
|
54629
54957
|
const token1Usd = Number(token1Web3.toFixed(13)) * P1.price;
|
|
54630
54958
|
return {
|
|
@@ -54646,7 +54974,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
54646
54974
|
return Number(result.salt.toString());
|
|
54647
54975
|
}
|
|
54648
54976
|
async truePrice() {
|
|
54649
|
-
const result = await this.lstContract.call("convert_to_assets", [
|
|
54977
|
+
const result = await this.lstContract.call("convert_to_assets", [
|
|
54978
|
+
uint256_exports.bnToUint256(BigInt(1e18).toString())
|
|
54979
|
+
]);
|
|
54650
54980
|
const truePrice = Number(BigInt(result.toString()) * BigInt(1e9) / BigInt(1e18)) / 1e9;
|
|
54651
54981
|
return truePrice;
|
|
54652
54982
|
}
|
|
@@ -54655,22 +54985,36 @@ var strkfarm_risk_engine = (() => {
|
|
|
54655
54985
|
return this._getCurrentPrice(poolKey, blockIdentifier);
|
|
54656
54986
|
}
|
|
54657
54987
|
async _getCurrentPrice(poolKey, blockIdentifier = "pending") {
|
|
54658
|
-
const priceInfo = await this.ekuboPositionsContract.call(
|
|
54988
|
+
const priceInfo = await this.ekuboPositionsContract.call(
|
|
54989
|
+
"get_pool_price",
|
|
54990
|
+
[
|
|
54991
|
+
{
|
|
54992
|
+
token0: poolKey.token0.address,
|
|
54993
|
+
token1: poolKey.token1.address,
|
|
54994
|
+
fee: poolKey.fee,
|
|
54995
|
+
tick_spacing: poolKey.tick_spacing,
|
|
54996
|
+
extension: poolKey.extension
|
|
54997
|
+
}
|
|
54998
|
+
],
|
|
54659
54999
|
{
|
|
54660
|
-
|
|
54661
|
-
token1: poolKey.token1.address,
|
|
54662
|
-
fee: poolKey.fee,
|
|
54663
|
-
tick_spacing: poolKey.tick_spacing,
|
|
54664
|
-
extension: poolKey.extension
|
|
55000
|
+
blockIdentifier
|
|
54665
55001
|
}
|
|
54666
|
-
|
|
54667
|
-
|
|
54668
|
-
|
|
54669
|
-
|
|
54670
|
-
console.log(
|
|
55002
|
+
);
|
|
55003
|
+
const sqrtRatio = _EkuboCLVault.div2Power128(
|
|
55004
|
+
BigInt(priceInfo.sqrt_ratio.toString())
|
|
55005
|
+
);
|
|
55006
|
+
console.log(
|
|
55007
|
+
`EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, sqrtRatio: ${sqrtRatio}, ${priceInfo.sqrt_ratio.toString()}`
|
|
55008
|
+
);
|
|
54671
55009
|
const price = sqrtRatio * sqrtRatio;
|
|
54672
|
-
const tick = _EkuboCLVault.priceToTick(
|
|
54673
|
-
|
|
55010
|
+
const tick = _EkuboCLVault.priceToTick(
|
|
55011
|
+
price,
|
|
55012
|
+
true,
|
|
55013
|
+
Number(poolKey.tick_spacing)
|
|
55014
|
+
);
|
|
55015
|
+
console.log(
|
|
55016
|
+
`EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, price: ${price}, tick: ${tick.mag}, ${tick.sign}`
|
|
55017
|
+
);
|
|
54674
55018
|
return {
|
|
54675
55019
|
price,
|
|
54676
55020
|
tick: tick.mag * (tick.sign == 0 ? 1 : -1),
|
|
@@ -54710,7 +55054,10 @@ var strkfarm_risk_engine = (() => {
|
|
|
54710
55054
|
};
|
|
54711
55055
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
54712
55056
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
54713
|
-
assert3(
|
|
55057
|
+
assert3(
|
|
55058
|
+
token0Info.decimals == token1Info.decimals,
|
|
55059
|
+
"Tested only for equal decimals"
|
|
55060
|
+
);
|
|
54714
55061
|
this.poolKey = poolKey;
|
|
54715
55062
|
return poolKey;
|
|
54716
55063
|
}
|
|
@@ -54734,11 +55081,18 @@ var strkfarm_risk_engine = (() => {
|
|
|
54734
55081
|
async _getExpectedAmountsForLiquidity(amount0, amount1, bounds, justUseInputAmount = true) {
|
|
54735
55082
|
assert3(amount0.greaterThan(0) || amount1.greaterThan(0), "Amount is 0");
|
|
54736
55083
|
const sampleLiq = 1e20;
|
|
54737
|
-
const { amount0: sampleAmount0, amount1: sampleAmount1 } = await this.getLiquidityToAmounts(
|
|
54738
|
-
|
|
55084
|
+
const { amount0: sampleAmount0, amount1: sampleAmount1 } = await this.getLiquidityToAmounts(
|
|
55085
|
+
Web3Number.fromWei(sampleLiq.toString(), 18),
|
|
55086
|
+
bounds
|
|
55087
|
+
);
|
|
55088
|
+
logger.verbose(
|
|
55089
|
+
`${_EkuboCLVault.name}: _getExpectedAmountsForLiquidity => sampleAmount0: ${sampleAmount0.toString()}, sampleAmount1: ${sampleAmount1.toString()}`
|
|
55090
|
+
);
|
|
54739
55091
|
assert3(!sampleAmount0.eq(0) || !sampleAmount1.eq(0), "Sample amount is 0");
|
|
54740
55092
|
const price = await (await this.getCurrentPrice()).price;
|
|
54741
|
-
logger.verbose(
|
|
55093
|
+
logger.verbose(
|
|
55094
|
+
`${_EkuboCLVault.name}: _getExpectedAmountsForLiquidity => price: ${price}`
|
|
55095
|
+
);
|
|
54742
55096
|
if (amount1.eq(0) && amount0.greaterThan(0)) {
|
|
54743
55097
|
if (sampleAmount1.eq(0)) {
|
|
54744
55098
|
return {
|
|
@@ -54768,12 +55122,22 @@ var strkfarm_risk_engine = (() => {
|
|
|
54768
55122
|
};
|
|
54769
55123
|
}
|
|
54770
55124
|
}
|
|
54771
|
-
assert3(
|
|
55125
|
+
assert3(
|
|
55126
|
+
sampleAmount0.decimals == sampleAmount1.decimals,
|
|
55127
|
+
"Sample amounts have different decimals"
|
|
55128
|
+
);
|
|
54772
55129
|
const ratioWeb3Number = sampleAmount0.multipliedBy(1e18).dividedBy(sampleAmount1.toString()).dividedBy(1e18);
|
|
54773
55130
|
const ratio = Number(ratioWeb3Number.toFixed(18));
|
|
54774
|
-
logger.verbose(
|
|
55131
|
+
logger.verbose(
|
|
55132
|
+
`${_EkuboCLVault.name}: ${this.metadata.name} => ratio: ${ratio.toString()}`
|
|
55133
|
+
);
|
|
54775
55134
|
if (justUseInputAmount)
|
|
54776
|
-
return this._solveExpectedAmountsEq(
|
|
55135
|
+
return this._solveExpectedAmountsEq(
|
|
55136
|
+
amount0,
|
|
55137
|
+
amount1,
|
|
55138
|
+
ratioWeb3Number,
|
|
55139
|
+
price
|
|
55140
|
+
);
|
|
54777
55141
|
if (amount1.eq(0) && amount0.greaterThan(0)) {
|
|
54778
55142
|
const _amount1 = amount0.dividedBy(ratioWeb3Number);
|
|
54779
55143
|
return {
|
|
@@ -54789,7 +55153,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
54789
55153
|
ratio
|
|
54790
55154
|
};
|
|
54791
55155
|
} else {
|
|
54792
|
-
throw new Error(
|
|
55156
|
+
throw new Error(
|
|
55157
|
+
"Both amounts are non-zero, cannot compute expected amounts"
|
|
55158
|
+
);
|
|
54793
55159
|
}
|
|
54794
55160
|
}
|
|
54795
55161
|
_solveExpectedAmountsEq(availableAmount0, availableAmount1, ratio, price) {
|
|
@@ -54806,34 +55172,65 @@ var strkfarm_risk_engine = (() => {
|
|
|
54806
55172
|
const erc20Mod = new ERC20(this.config);
|
|
54807
55173
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
54808
55174
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
54809
|
-
const token0Bal1 = await erc20Mod.balanceOf(
|
|
54810
|
-
|
|
54811
|
-
|
|
55175
|
+
const token0Bal1 = await erc20Mod.balanceOf(
|
|
55176
|
+
poolKey.token0,
|
|
55177
|
+
this.address.address,
|
|
55178
|
+
token0Info.decimals
|
|
55179
|
+
);
|
|
55180
|
+
const token1Bal1 = await erc20Mod.balanceOf(
|
|
55181
|
+
poolKey.token1,
|
|
55182
|
+
this.address.address,
|
|
55183
|
+
token1Info.decimals
|
|
55184
|
+
);
|
|
55185
|
+
logger.verbose(
|
|
55186
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal1: ${token0Bal1.toString()}, token1Bal1: ${token1Bal1.toString()}`
|
|
55187
|
+
);
|
|
54812
55188
|
const token0Price = await this.pricer.getPrice(token0Info.symbol);
|
|
54813
55189
|
const token1Price = await this.pricer.getPrice(token1Info.symbol);
|
|
54814
55190
|
const token0PriceUsd = token0Price.price * Number(token0Bal1.toFixed(13));
|
|
54815
55191
|
const token1PriceUsd = token1Price.price * Number(token1Bal1.toFixed(13));
|
|
54816
55192
|
if (token0PriceUsd > 1 && token1PriceUsd > 1) {
|
|
54817
|
-
throw new Error(
|
|
55193
|
+
throw new Error(
|
|
55194
|
+
"Both tokens are non-zero and above $1, call handle_fees first"
|
|
55195
|
+
);
|
|
54818
55196
|
}
|
|
54819
55197
|
let token0Bal = token0Bal1;
|
|
54820
55198
|
let token1Bal = token1Bal1;
|
|
54821
55199
|
if (considerRebalance) {
|
|
54822
|
-
logger.verbose(
|
|
55200
|
+
logger.verbose(
|
|
55201
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => considerRebalance: true`
|
|
55202
|
+
);
|
|
54823
55203
|
const tvl = await this.getTVL();
|
|
54824
55204
|
token0Bal = token0Bal.plus(tvl.token0.amount.toString());
|
|
54825
55205
|
token1Bal = token1Bal.plus(tvl.token1.amount.toString());
|
|
54826
55206
|
} else {
|
|
54827
|
-
logger.verbose(
|
|
55207
|
+
logger.verbose(
|
|
55208
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => considerRebalance: false`
|
|
55209
|
+
);
|
|
54828
55210
|
}
|
|
54829
|
-
logger.verbose(
|
|
55211
|
+
logger.verbose(
|
|
55212
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`
|
|
55213
|
+
);
|
|
54830
55214
|
const newBounds = await this.getNewBounds();
|
|
54831
|
-
logger.verbose(
|
|
54832
|
-
|
|
55215
|
+
logger.verbose(
|
|
55216
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newBounds: ${newBounds.lowerTick}, ${newBounds.upperTick}`
|
|
55217
|
+
);
|
|
55218
|
+
return await this.getSwapInfoGivenAmounts(
|
|
55219
|
+
poolKey,
|
|
55220
|
+
token0Bal,
|
|
55221
|
+
token1Bal,
|
|
55222
|
+
newBounds
|
|
55223
|
+
);
|
|
54833
55224
|
}
|
|
54834
55225
|
async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds) {
|
|
54835
|
-
let expectedAmounts = await this._getExpectedAmountsForLiquidity(
|
|
54836
|
-
|
|
55226
|
+
let expectedAmounts = await this._getExpectedAmountsForLiquidity(
|
|
55227
|
+
token0Bal,
|
|
55228
|
+
token1Bal,
|
|
55229
|
+
bounds
|
|
55230
|
+
);
|
|
55231
|
+
logger.verbose(
|
|
55232
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`
|
|
55233
|
+
);
|
|
54837
55234
|
let retry = 0;
|
|
54838
55235
|
const maxRetry = 10;
|
|
54839
55236
|
while (retry < maxRetry) {
|
|
@@ -54850,9 +55247,15 @@ var strkfarm_risk_engine = (() => {
|
|
|
54850
55247
|
const remainingSellAmount = tokenToSell == poolKey.token0 ? expectedAmounts.amount0 : expectedAmounts.amount1;
|
|
54851
55248
|
const tokenToBuyInfo = await Global.getTokenInfoFromAddr(tokenToBuy);
|
|
54852
55249
|
const expectedRatio = expectedAmounts.ratio;
|
|
54853
|
-
logger.verbose(
|
|
54854
|
-
|
|
54855
|
-
|
|
55250
|
+
logger.verbose(
|
|
55251
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => tokenToSell: ${tokenToSell.address}, tokenToBuy: ${tokenToBuy.address}, amountToSell: ${amountToSell.toWei()}`
|
|
55252
|
+
);
|
|
55253
|
+
logger.verbose(
|
|
55254
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => remainingSellAmount: ${remainingSellAmount.toString()}`
|
|
55255
|
+
);
|
|
55256
|
+
logger.verbose(
|
|
55257
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedRatio: ${expectedRatio}`
|
|
55258
|
+
);
|
|
54856
55259
|
if (amountToSell.eq(0)) {
|
|
54857
55260
|
return {
|
|
54858
55261
|
token_from_address: tokenToSell.address,
|
|
@@ -54866,23 +55269,62 @@ var strkfarm_risk_engine = (() => {
|
|
|
54866
55269
|
routes: []
|
|
54867
55270
|
};
|
|
54868
55271
|
}
|
|
54869
|
-
const quote = await this.avnu.getQuotes(
|
|
55272
|
+
const quote = await this.avnu.getQuotes(
|
|
55273
|
+
tokenToSell.address,
|
|
55274
|
+
tokenToBuy.address,
|
|
55275
|
+
amountToSell.toWei(),
|
|
55276
|
+
this.address.address
|
|
55277
|
+
);
|
|
54870
55278
|
if (remainingSellAmount.eq(0)) {
|
|
54871
|
-
const minAmountOut = Web3Number.fromWei(
|
|
54872
|
-
|
|
55279
|
+
const minAmountOut = Web3Number.fromWei(
|
|
55280
|
+
quote.buyAmount.toString(),
|
|
55281
|
+
tokenToBuyInfo.decimals
|
|
55282
|
+
).multipliedBy(0.9999);
|
|
55283
|
+
return await this.avnu.getSwapInfo(
|
|
55284
|
+
quote,
|
|
55285
|
+
this.address.address,
|
|
55286
|
+
0,
|
|
55287
|
+
this.address.address,
|
|
55288
|
+
minAmountOut.toWei()
|
|
55289
|
+
);
|
|
54873
55290
|
}
|
|
54874
|
-
const amountOut = Web3Number.fromWei(
|
|
55291
|
+
const amountOut = Web3Number.fromWei(
|
|
55292
|
+
quote.buyAmount.toString(),
|
|
55293
|
+
tokenToBuyInfo.decimals
|
|
55294
|
+
);
|
|
54875
55295
|
const swapPrice = tokenToSell == poolKey.token0 ? amountOut.dividedBy(amountToSell) : amountToSell.dividedBy(amountOut);
|
|
54876
55296
|
const newRatio = tokenToSell == poolKey.token0 ? remainingSellAmount.dividedBy(token1Bal.plus(amountOut)) : token0Bal.plus(amountOut).dividedBy(remainingSellAmount);
|
|
54877
|
-
logger.verbose(
|
|
54878
|
-
|
|
54879
|
-
|
|
55297
|
+
logger.verbose(
|
|
55298
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => amountOut: ${amountOut.toString()}`
|
|
55299
|
+
);
|
|
55300
|
+
logger.verbose(
|
|
55301
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => swapPrice: ${swapPrice.toString()}`
|
|
55302
|
+
);
|
|
55303
|
+
logger.verbose(
|
|
55304
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newRatio: ${newRatio.toString()}`
|
|
55305
|
+
);
|
|
54880
55306
|
if (Number(newRatio.toString()) > expectedRatio * 1.0000001 || Number(newRatio.toString()) < expectedRatio * 0.9999999) {
|
|
54881
|
-
expectedAmounts = await this._solveExpectedAmountsEq(
|
|
54882
|
-
|
|
55307
|
+
expectedAmounts = await this._solveExpectedAmountsEq(
|
|
55308
|
+
token0Bal,
|
|
55309
|
+
token1Bal,
|
|
55310
|
+
new Web3Number(Number(expectedRatio).toFixed(13), 18),
|
|
55311
|
+
Number(swapPrice.toString())
|
|
55312
|
+
);
|
|
55313
|
+
logger.verbose(
|
|
55314
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`
|
|
55315
|
+
);
|
|
54883
55316
|
} else {
|
|
54884
|
-
const minAmountOut = Web3Number.fromWei(
|
|
54885
|
-
|
|
55317
|
+
const minAmountOut = Web3Number.fromWei(
|
|
55318
|
+
quote.buyAmount.toString(),
|
|
55319
|
+
tokenToBuyInfo.decimals
|
|
55320
|
+
).multipliedBy(0.9999);
|
|
55321
|
+
return await this.avnu.getSwapInfo(
|
|
55322
|
+
quote,
|
|
55323
|
+
this.address.address,
|
|
55324
|
+
0,
|
|
55325
|
+
this.address.address,
|
|
55326
|
+
minAmountOut.toWei()
|
|
55327
|
+
);
|
|
54886
55328
|
}
|
|
54887
55329
|
retry++;
|
|
54888
55330
|
}
|
|
@@ -54891,8 +55333,8 @@ var strkfarm_risk_engine = (() => {
|
|
|
54891
55333
|
/**
|
|
54892
55334
|
* Attempts to rebalance the vault by iteratively adjusting swap amounts if initial attempt fails.
|
|
54893
55335
|
* Uses binary search approach to find optimal swap amount.
|
|
54894
|
-
*
|
|
54895
|
-
* @param newBounds - The new tick bounds to rebalance to
|
|
55336
|
+
*
|
|
55337
|
+
* @param newBounds - The new tick bounds to rebalance to
|
|
54896
55338
|
* @param swapInfo - Initial swap parameters for rebalancing
|
|
54897
55339
|
* @param acc - Account to estimate gas fees with
|
|
54898
55340
|
* @param retry - Current retry attempt number (default 0)
|
|
@@ -54919,7 +55361,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
54919
55361
|
logger.error(`Rebalance failed after ${MAX_RETRIES} retries`);
|
|
54920
55362
|
throw err2;
|
|
54921
55363
|
}
|
|
54922
|
-
logger.error(
|
|
55364
|
+
logger.error(
|
|
55365
|
+
`Rebalance attempt ${retry + 1} failed, adjusting swap amount...`
|
|
55366
|
+
);
|
|
54923
55367
|
const newSwapInfo = { ...swapInfo };
|
|
54924
55368
|
const currentAmount = Web3Number.fromWei(fromAmount.toString(), 18);
|
|
54925
55369
|
logger.verbose(`Current amount: ${currentAmount.toString()}`);
|
|
@@ -55011,23 +55455,39 @@ var strkfarm_risk_engine = (() => {
|
|
|
55011
55455
|
const currentPrice = _currentPrice || await this.getCurrentPrice(blockIdentifier);
|
|
55012
55456
|
const lowerPrice = _EkuboCLVault.tickToPrice(bounds.lowerTick);
|
|
55013
55457
|
const upperPrice = _EkuboCLVault.tickToPrice(bounds.upperTick);
|
|
55014
|
-
logger.verbose(
|
|
55015
|
-
|
|
55016
|
-
|
|
55458
|
+
logger.verbose(
|
|
55459
|
+
`${_EkuboCLVault.name}: getLiquidityToAmounts => currentPrice: ${currentPrice.price}, lowerPrice: ${lowerPrice}, upperPrice: ${upperPrice}`
|
|
55460
|
+
);
|
|
55461
|
+
const result = await this.ekuboMathContract.call(
|
|
55462
|
+
"liquidity_delta_to_amount_delta",
|
|
55463
|
+
[
|
|
55464
|
+
uint256_exports.bnToUint256(currentPrice.sqrtRatio),
|
|
55465
|
+
{
|
|
55466
|
+
mag: liquidity.toWei(),
|
|
55467
|
+
sign: 0
|
|
55468
|
+
},
|
|
55469
|
+
uint256_exports.bnToUint256(
|
|
55470
|
+
_EkuboCLVault.priceToSqrtRatio(lowerPrice).toString()
|
|
55471
|
+
),
|
|
55472
|
+
uint256_exports.bnToUint256(
|
|
55473
|
+
_EkuboCLVault.priceToSqrtRatio(upperPrice).toString()
|
|
55474
|
+
)
|
|
55475
|
+
],
|
|
55017
55476
|
{
|
|
55018
|
-
|
|
55019
|
-
|
|
55020
|
-
|
|
55021
|
-
uint256_exports.bnToUint256(_EkuboCLVault.priceToSqrtRatio(lowerPrice).toString()),
|
|
55022
|
-
uint256_exports.bnToUint256(_EkuboCLVault.priceToSqrtRatio(upperPrice).toString())
|
|
55023
|
-
], {
|
|
55024
|
-
blockIdentifier
|
|
55025
|
-
});
|
|
55477
|
+
blockIdentifier
|
|
55478
|
+
}
|
|
55479
|
+
);
|
|
55026
55480
|
const poolKey = _poolKey || await this.getPoolKey(blockIdentifier);
|
|
55027
55481
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
55028
55482
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
55029
|
-
const amount0 = Web3Number.fromWei(
|
|
55030
|
-
|
|
55483
|
+
const amount0 = Web3Number.fromWei(
|
|
55484
|
+
_EkuboCLVault.i129ToNumber(result.amount0).toString(),
|
|
55485
|
+
token0Info.decimals
|
|
55486
|
+
);
|
|
55487
|
+
const amount1 = Web3Number.fromWei(
|
|
55488
|
+
_EkuboCLVault.i129ToNumber(result.amount1).toString(),
|
|
55489
|
+
token1Info.decimals
|
|
55490
|
+
);
|
|
55031
55491
|
return {
|
|
55032
55492
|
amount0,
|
|
55033
55493
|
amount1
|
|
@@ -55035,7 +55495,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
55035
55495
|
}
|
|
55036
55496
|
async harvest(acc) {
|
|
55037
55497
|
const ekuboHarvests = new EkuboHarvests(this.config);
|
|
55038
|
-
const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(
|
|
55498
|
+
const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(
|
|
55499
|
+
this.address
|
|
55500
|
+
);
|
|
55039
55501
|
const poolKey = await this.getPoolKey();
|
|
55040
55502
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
55041
55503
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
@@ -55045,18 +55507,37 @@ var strkfarm_risk_engine = (() => {
|
|
|
55045
55507
|
const fee = claim.claim.amount.multipliedBy(this.metadata.additionalInfo.feeBps).dividedBy(1e4);
|
|
55046
55508
|
const postFeeAmount = claim.claim.amount.minus(fee);
|
|
55047
55509
|
const isToken1 = claim.token.eq(poolKey.token1);
|
|
55048
|
-
logger.verbose(
|
|
55510
|
+
logger.verbose(
|
|
55511
|
+
`${_EkuboCLVault.name}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`
|
|
55512
|
+
);
|
|
55049
55513
|
const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
|
|
55050
55514
|
const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
|
|
55051
|
-
logger.verbose(
|
|
55052
|
-
|
|
55515
|
+
logger.verbose(
|
|
55516
|
+
`${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
|
|
55517
|
+
);
|
|
55518
|
+
const swapInfo = await this.getSwapInfoGivenAmounts(
|
|
55519
|
+
poolKey,
|
|
55520
|
+
token0Amt,
|
|
55521
|
+
token1Amt,
|
|
55522
|
+
bounds
|
|
55523
|
+
);
|
|
55053
55524
|
swapInfo.token_to_address = token0Info.address.address;
|
|
55054
|
-
logger.verbose(
|
|
55055
|
-
|
|
55525
|
+
logger.verbose(
|
|
55526
|
+
`${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
|
|
55527
|
+
);
|
|
55528
|
+
logger.verbose(
|
|
55529
|
+
`${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
|
|
55530
|
+
);
|
|
55056
55531
|
const harvestEstimateCall = async (swapInfo1) => {
|
|
55057
|
-
const swap1Amount = Web3Number.fromWei(
|
|
55532
|
+
const swap1Amount = Web3Number.fromWei(
|
|
55533
|
+
uint256_exports.uint256ToBN(swapInfo1.token_from_amount).toString(),
|
|
55534
|
+
18
|
|
55535
|
+
);
|
|
55058
55536
|
const remainingAmount = postFeeAmount.minus(swap1Amount);
|
|
55059
|
-
const swapInfo2 = {
|
|
55537
|
+
const swapInfo2 = {
|
|
55538
|
+
...swapInfo,
|
|
55539
|
+
token_from_amount: uint256_exports.bnToUint256(remainingAmount.toWei())
|
|
55540
|
+
};
|
|
55060
55541
|
swapInfo2.token_to_address = token1Info.address.address;
|
|
55061
55542
|
const calldata = [
|
|
55062
55543
|
claim.rewardsContract.address,
|
|
@@ -55069,11 +55550,23 @@ var strkfarm_risk_engine = (() => {
|
|
|
55069
55550
|
swapInfo,
|
|
55070
55551
|
swapInfo2
|
|
55071
55552
|
];
|
|
55072
|
-
logger.verbose(
|
|
55553
|
+
logger.verbose(
|
|
55554
|
+
`${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
|
|
55555
|
+
calldata
|
|
55556
|
+
)}`
|
|
55557
|
+
);
|
|
55073
55558
|
return [this.contract.populate("harvest", calldata)];
|
|
55074
55559
|
};
|
|
55075
|
-
const _callsFinal = await this.rebalanceIter(
|
|
55076
|
-
|
|
55560
|
+
const _callsFinal = await this.rebalanceIter(
|
|
55561
|
+
swapInfo,
|
|
55562
|
+
acc,
|
|
55563
|
+
harvestEstimateCall
|
|
55564
|
+
);
|
|
55565
|
+
logger.verbose(
|
|
55566
|
+
`${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
|
|
55567
|
+
_callsFinal
|
|
55568
|
+
)}`
|
|
55569
|
+
);
|
|
55077
55570
|
calls.push(..._callsFinal);
|
|
55078
55571
|
}
|
|
55079
55572
|
return calls;
|
|
@@ -55083,24 +55576,37 @@ var strkfarm_risk_engine = (() => {
|
|
|
55083
55576
|
const poolKey = await this.getPoolKey();
|
|
55084
55577
|
const linkedFlow = {
|
|
55085
55578
|
title: this.metadata.name,
|
|
55086
|
-
subItems: [
|
|
55579
|
+
subItems: [
|
|
55580
|
+
{
|
|
55581
|
+
key: "Pool",
|
|
55582
|
+
value: `${(_EkuboCLVault.div2Power128(BigInt(poolKey.fee)) * 100).toFixed(2)}%, ${poolKey.tick_spacing} tick spacing`
|
|
55583
|
+
}
|
|
55584
|
+
],
|
|
55087
55585
|
linkedFlows: [],
|
|
55088
55586
|
style: { backgroundColor: "#35484f" /* Blue */.valueOf() }
|
|
55089
55587
|
};
|
|
55090
55588
|
const baseFlow = {
|
|
55091
55589
|
id: "base",
|
|
55092
55590
|
title: "Your Deposit",
|
|
55093
|
-
subItems: [
|
|
55591
|
+
subItems: [
|
|
55592
|
+
{ key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` },
|
|
55593
|
+
{
|
|
55594
|
+
key: `Performance Fee`,
|
|
55595
|
+
value: `${(this.metadata.additionalInfo.feeBps / 100).toFixed(2)}%`
|
|
55596
|
+
}
|
|
55597
|
+
],
|
|
55094
55598
|
linkedFlows: [linkedFlow],
|
|
55095
55599
|
style: { backgroundColor: "#6e53dc" /* Purple */.valueOf() }
|
|
55096
55600
|
};
|
|
55097
55601
|
const rebalanceFlow = {
|
|
55098
55602
|
id: "rebalance",
|
|
55099
55603
|
title: "Automated Rebalance",
|
|
55100
|
-
subItems: [
|
|
55101
|
-
|
|
55102
|
-
|
|
55103
|
-
|
|
55604
|
+
subItems: [
|
|
55605
|
+
{
|
|
55606
|
+
key: "Range selection",
|
|
55607
|
+
value: `${this.metadata.additionalInfo.newBounds.lower * Number(poolKey.tick_spacing)} to ${this.metadata.additionalInfo.newBounds.upper * Number(poolKey.tick_spacing)} ticks`
|
|
55608
|
+
}
|
|
55609
|
+
],
|
|
55104
55610
|
linkedFlows: [linkedFlow],
|
|
55105
55611
|
style: { backgroundColor: "purple" /* Green */.valueOf() }
|
|
55106
55612
|
};
|
|
@@ -55108,43 +55614,94 @@ var strkfarm_risk_engine = (() => {
|
|
|
55108
55614
|
}
|
|
55109
55615
|
};
|
|
55110
55616
|
var _description2 = "Deploys your {{POOL_NAME}} into an Ekubo liquidity pool, automatically rebalancing positions around the current price to optimize yield and reduce the need for manual adjustments. Trading fees and DeFi Spring rewards are automatically compounded back into the strategy. In return, you receive an ERC-20 token representing your share of the strategy. The APY is calculated based on 7-day historical performance.";
|
|
55111
|
-
var _protocol2 = {
|
|
55617
|
+
var _protocol2 = {
|
|
55618
|
+
name: "Ekubo",
|
|
55619
|
+
logo: "https://app.ekubo.org/favicon.ico"
|
|
55620
|
+
};
|
|
55112
55621
|
var _riskFactor2 = [
|
|
55113
55622
|
{ type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 0.5, weight: 25 },
|
|
55114
55623
|
{ type: "Impermanent Loss Risk" /* IMPERMANENT_LOSS */, value: 1, weight: 75 }
|
|
55115
55624
|
];
|
|
55116
55625
|
var AUDIT_URL2 = "https://assets.strkfarm.com/strkfarm/audit_report_vesu_and_ekubo_strats.pdf";
|
|
55117
|
-
var
|
|
55118
|
-
|
|
55119
|
-
|
|
55120
|
-
|
|
55121
|
-
|
|
55122
|
-
|
|
55123
|
-
|
|
55626
|
+
var faqs2 = [
|
|
55627
|
+
{
|
|
55628
|
+
question: "What is the Ekubo CL Vault strategy?",
|
|
55629
|
+
answer: "The Ekubo CL Vault strategy deploys your assets into an Ekubo liquidity pool, automatically rebalancing positions around the current price to optimize yield and reduce manual adjustments."
|
|
55630
|
+
},
|
|
55631
|
+
{
|
|
55632
|
+
question: "How are trading fees and rewards handled?",
|
|
55633
|
+
answer: "Trading fees and DeFi Spring rewards are automatically compounded back into the strategy, increasing your overall returns."
|
|
55634
|
+
},
|
|
55635
|
+
{
|
|
55636
|
+
question: "What happens during withdrawal?",
|
|
55637
|
+
answer: "During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices."
|
|
55638
|
+
},
|
|
55639
|
+
{
|
|
55640
|
+
question: "Is the strategy audited?",
|
|
55641
|
+
answer: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
55642
|
+
"Yes, the strategy has been audited. You can review the audit report in our docs ",
|
|
55643
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { href: "https://docs.strkfarm.com/p/ekubo-cl-vaults#technical-details", style: { textDecoration: "underline", marginLeft: "5px" }, children: "Here" }),
|
|
55644
|
+
"."
|
|
55124
55645
|
] })
|
|
55125
|
-
|
|
55126
|
-
|
|
55127
|
-
|
|
55128
|
-
|
|
55129
|
-
|
|
55130
|
-
|
|
55131
|
-
|
|
55132
|
-
|
|
55133
|
-
|
|
55134
|
-
|
|
55135
|
-
|
|
55136
|
-
|
|
55137
|
-
|
|
55138
|
-
|
|
55139
|
-
|
|
55140
|
-
|
|
55141
|
-
|
|
55142
|
-
|
|
55646
|
+
}
|
|
55647
|
+
];
|
|
55648
|
+
var EkuboCLVaultStrategies = [
|
|
55649
|
+
{
|
|
55650
|
+
name: "Ekubo xSTRK/STRK",
|
|
55651
|
+
description: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
55652
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: _description2.replace("{{POOL_NAME}}", "xSTRK/STRK") }),
|
|
55653
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
55654
|
+
"ul",
|
|
55655
|
+
{
|
|
55656
|
+
style: {
|
|
55657
|
+
marginLeft: "20px",
|
|
55658
|
+
listStyle: "circle",
|
|
55659
|
+
fontSize: "12px"
|
|
55660
|
+
},
|
|
55661
|
+
children: [
|
|
55662
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { style: { marginTop: "10px" }, children: "During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices." }),
|
|
55663
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { style: { marginTop: "10px" }, children: "Sometimes you might see a negative APY \u2014 this is usually not a big deal. It happens when xSTRK's price drops on DEXes, but things typically bounce back within a few days or a week." })
|
|
55664
|
+
]
|
|
55665
|
+
}
|
|
55666
|
+
)
|
|
55667
|
+
] }),
|
|
55668
|
+
address: ContractAddr.from(
|
|
55669
|
+
"0x01f083b98674bc21effee29ef443a00c7b9a500fd92cf30341a3da12c73f2324"
|
|
55670
|
+
),
|
|
55671
|
+
type: "Other",
|
|
55672
|
+
// must be same order as poolKey token0 and token1
|
|
55673
|
+
depositTokens: [
|
|
55674
|
+
Global.getDefaultTokens().find((t) => t.symbol === "xSTRK"),
|
|
55675
|
+
Global.getDefaultTokens().find((t) => t.symbol === "STRK")
|
|
55676
|
+
],
|
|
55677
|
+
protocols: [_protocol2],
|
|
55678
|
+
auditUrl: AUDIT_URL2,
|
|
55679
|
+
maxTVL: Web3Number.fromWei("0", 18),
|
|
55680
|
+
risk: {
|
|
55681
|
+
riskFactor: _riskFactor2,
|
|
55682
|
+
netRisk: _riskFactor2.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor2.reduce((acc, curr) => acc + curr.weight, 0),
|
|
55683
|
+
notARisks: getNoRiskTags(_riskFactor2)
|
|
55143
55684
|
},
|
|
55144
|
-
|
|
55145
|
-
|
|
55685
|
+
apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
|
|
55686
|
+
additionalInfo: {
|
|
55687
|
+
newBounds: {
|
|
55688
|
+
lower: -1,
|
|
55689
|
+
upper: 1
|
|
55690
|
+
},
|
|
55691
|
+
lstContract: ContractAddr.from(
|
|
55692
|
+
"0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a"
|
|
55693
|
+
),
|
|
55694
|
+
feeBps: 1e3
|
|
55695
|
+
},
|
|
55696
|
+
faqs: [
|
|
55697
|
+
...faqs2,
|
|
55698
|
+
{
|
|
55699
|
+
question: "Why might I see a negative APY?",
|
|
55700
|
+
answer: "A negative APY can occur when xSTRK's price drops on DEXes. This is usually temporary and tends to recover within a few days or a week."
|
|
55701
|
+
}
|
|
55702
|
+
]
|
|
55146
55703
|
}
|
|
55147
|
-
|
|
55704
|
+
];
|
|
55148
55705
|
return __toCommonJS(index_browser_exports);
|
|
55149
55706
|
})();
|
|
55150
55707
|
/*! Bundled license information:
|