@strkfarm/sdk 1.0.37 → 1.0.39
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 +38 -588
- package/dist/cli.mjs +37 -587
- package/dist/index.browser.global.js +962 -329
- package/dist/index.browser.mjs +962 -325
- package/dist/index.d.ts +28 -54
- package/dist/index.js +985 -322
- package/dist/index.mjs +990 -323
- package/package.json +3 -3
- package/src/dataTypes/_bignumber.ts +49 -47
- package/src/global.ts +1 -33
- package/src/interfaces/common.ts +112 -98
- package/src/interfaces/lending.ts +1 -2
- package/src/modules/avnu.ts +1 -1
- package/src/modules/erc20.ts +6 -0
- package/src/modules/harvests.ts +1 -1
- package/src/modules/pragma.ts +1 -1
- package/src/modules/pricer-from-api.ts +3 -3
- package/src/modules/pricer.ts +2 -1
- package/src/modules/zkLend.ts +2 -1
- package/src/node/pricer-redis.ts +2 -1
- package/src/notifs/telegram.ts +1 -1
- package/src/strategies/ekubo-cl-vault.tsx +1503 -920
- package/src/strategies/vesu-rebalance.tsx +943 -611
- package/src/utils/index.ts +2 -0
- package/src/utils/logger.browser.ts +20 -0
- package/src/utils/logger.node.ts +35 -0
- package/src/utils/logger.ts +1 -0
- package/src/utils/store.ts +1 -1
|
@@ -17293,8 +17293,7 @@ var strkfarm_risk_engine = (() => {
|
|
|
17293
17293
|
getMainnetConfig: () => getMainnetConfig,
|
|
17294
17294
|
getNoRiskTags: () => getNoRiskTags,
|
|
17295
17295
|
getRiskColor: () => getRiskColor,
|
|
17296
|
-
getRiskExplaination: () => getRiskExplaination
|
|
17297
|
-
logger: () => logger
|
|
17296
|
+
getRiskExplaination: () => getRiskExplaination
|
|
17298
17297
|
});
|
|
17299
17298
|
|
|
17300
17299
|
// node_modules/.pnpm/axios@1.7.2/node_modules/axios/lib/helpers/bind.js
|
|
@@ -19723,6 +19722,14 @@ var strkfarm_risk_engine = (() => {
|
|
|
19723
19722
|
mergeConfig: mergeConfig2
|
|
19724
19723
|
} = axios_default;
|
|
19725
19724
|
|
|
19725
|
+
// src/utils/logger.browser.ts
|
|
19726
|
+
var logger = {
|
|
19727
|
+
...console,
|
|
19728
|
+
verbose(message) {
|
|
19729
|
+
console.log(`[VERBOSE] ${message}`);
|
|
19730
|
+
}
|
|
19731
|
+
};
|
|
19732
|
+
|
|
19726
19733
|
// src/dataTypes/_bignumber.ts
|
|
19727
19734
|
var import_bignumber = __toESM(require_bignumber());
|
|
19728
19735
|
var _Web3Number = class extends import_bignumber.default {
|
|
@@ -19739,6 +19746,7 @@ var strkfarm_risk_engine = (() => {
|
|
|
19739
19746
|
}
|
|
19740
19747
|
dividedBy(value) {
|
|
19741
19748
|
const _value = this.getStandardString(value);
|
|
19749
|
+
console.log("dividedBy", _value);
|
|
19742
19750
|
return this.construct(this.div(_value).toString(), this.decimals);
|
|
19743
19751
|
}
|
|
19744
19752
|
plus(value) {
|
|
@@ -19752,13 +19760,15 @@ var strkfarm_risk_engine = (() => {
|
|
|
19752
19760
|
construct(value, decimals) {
|
|
19753
19761
|
return new this.constructor(value, decimals);
|
|
19754
19762
|
}
|
|
19755
|
-
toString(
|
|
19756
|
-
return super.
|
|
19763
|
+
toString() {
|
|
19764
|
+
return super.toString();
|
|
19757
19765
|
}
|
|
19758
19766
|
toJSON() {
|
|
19767
|
+
logger.verbose(`converting to json with decimals`);
|
|
19759
19768
|
return this.toString();
|
|
19760
19769
|
}
|
|
19761
19770
|
valueOf() {
|
|
19771
|
+
logger.verbose(`converting to valueOf with decimals`);
|
|
19762
19772
|
return this.toString();
|
|
19763
19773
|
}
|
|
19764
19774
|
maxToFixedDecimals() {
|
|
@@ -36012,12 +36022,6 @@ var strkfarm_risk_engine = (() => {
|
|
|
36012
36022
|
};
|
|
36013
36023
|
|
|
36014
36024
|
// src/global.ts
|
|
36015
|
-
var logger = {
|
|
36016
|
-
...console,
|
|
36017
|
-
verbose(message) {
|
|
36018
|
-
console.log(`[VERBOSE] ${message}`);
|
|
36019
|
-
}
|
|
36020
|
-
};
|
|
36021
36025
|
var FatalError = class extends Error {
|
|
36022
36026
|
constructor(message, err2) {
|
|
36023
36027
|
super(message);
|
|
@@ -36596,7 +36600,7 @@ var strkfarm_risk_engine = (() => {
|
|
|
36596
36600
|
} catch (e) {
|
|
36597
36601
|
logger.warn("getPriceFromMyAPI error", JSON.stringify(e.message || e));
|
|
36598
36602
|
}
|
|
36599
|
-
logger.
|
|
36603
|
+
logger.info("getPrice coinbase", tokenSymbol);
|
|
36600
36604
|
let retry = 0;
|
|
36601
36605
|
const MAX_RETRIES = 5;
|
|
36602
36606
|
for (retry = 1; retry < MAX_RETRIES + 1; retry++) {
|
|
@@ -37774,6 +37778,11 @@ var strkfarm_risk_engine = (() => {
|
|
|
37774
37778
|
const balance = await contract.call("balanceOf", [address.toString()]);
|
|
37775
37779
|
return Web3Number.fromWei(balance.toString(), tokenDecimals);
|
|
37776
37780
|
}
|
|
37781
|
+
async allowance(token, owner, spender, tokenDecimals) {
|
|
37782
|
+
const contract = this.contract(token);
|
|
37783
|
+
const allowance = await contract.call("allowance", [owner.toString(), spender.toString()]);
|
|
37784
|
+
return Web3Number.fromWei(allowance.toString(), tokenDecimals);
|
|
37785
|
+
}
|
|
37777
37786
|
};
|
|
37778
37787
|
|
|
37779
37788
|
// node_modules/.pnpm/ethers@6.13.5/node_modules/ethers/lib.esm/_version.js
|
|
@@ -38226,7 +38235,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
38226
38235
|
};
|
|
38227
38236
|
var getNoRiskTags = (risks) => {
|
|
38228
38237
|
const noRisks1 = risks.filter((risk) => risk.value === 0).map((risk) => risk.type);
|
|
38229
|
-
const noRisks2 = Object.values(RiskType).filter(
|
|
38238
|
+
const noRisks2 = Object.values(RiskType).filter(
|
|
38239
|
+
(risk) => !risks.map((risk2) => risk2.type).includes(risk)
|
|
38240
|
+
);
|
|
38230
38241
|
const mergedUnique = [.../* @__PURE__ */ new Set([...noRisks1, ...noRisks2])];
|
|
38231
38242
|
return mergedUnique.map((risk) => `No ${risk}`);
|
|
38232
38243
|
};
|
|
@@ -48912,6 +48923,7 @@ var strkfarm_risk_engine = (() => {
|
|
|
48912
48923
|
};
|
|
48913
48924
|
|
|
48914
48925
|
// src/strategies/vesu-rebalance.tsx
|
|
48926
|
+
var import_jsx_runtime = __toESM(require_jsx_runtime());
|
|
48915
48927
|
var VesuRebalance = class _VesuRebalance extends BaseStrategy {
|
|
48916
48928
|
// 10000 bps = 100%
|
|
48917
48929
|
/**
|
|
@@ -48925,10 +48937,17 @@ var strkfarm_risk_engine = (() => {
|
|
|
48925
48937
|
super(config2);
|
|
48926
48938
|
this.BASE_WEIGHT = 1e4;
|
|
48927
48939
|
this.pricer = pricer;
|
|
48928
|
-
assert3(
|
|
48940
|
+
assert3(
|
|
48941
|
+
metadata.depositTokens.length === 1,
|
|
48942
|
+
"VesuRebalance only supports 1 deposit token"
|
|
48943
|
+
);
|
|
48929
48944
|
this.metadata = metadata;
|
|
48930
48945
|
this.address = metadata.address;
|
|
48931
|
-
this.contract = new Contract(
|
|
48946
|
+
this.contract = new Contract(
|
|
48947
|
+
vesu_rebalance_abi_default,
|
|
48948
|
+
this.address.address,
|
|
48949
|
+
this.config.provider
|
|
48950
|
+
);
|
|
48932
48951
|
}
|
|
48933
48952
|
/**
|
|
48934
48953
|
* Creates a deposit call to the strategy contract.
|
|
@@ -48937,10 +48956,23 @@ var strkfarm_risk_engine = (() => {
|
|
|
48937
48956
|
* @returns Populated contract call for deposit
|
|
48938
48957
|
*/
|
|
48939
48958
|
async depositCall(amountInfo, receiver) {
|
|
48940
|
-
assert3(
|
|
48941
|
-
|
|
48942
|
-
|
|
48943
|
-
|
|
48959
|
+
assert3(
|
|
48960
|
+
amountInfo.tokenInfo.address.eq(this.asset().address),
|
|
48961
|
+
"Deposit token mismatch"
|
|
48962
|
+
);
|
|
48963
|
+
const assetContract = new Contract(
|
|
48964
|
+
vesu_rebalance_abi_default,
|
|
48965
|
+
this.asset().address.address,
|
|
48966
|
+
this.config.provider
|
|
48967
|
+
);
|
|
48968
|
+
const call1 = assetContract.populate("approve", [
|
|
48969
|
+
this.address.address,
|
|
48970
|
+
uint256_exports.bnToUint256(amountInfo.amount.toWei())
|
|
48971
|
+
]);
|
|
48972
|
+
const call2 = this.contract.populate("deposit", [
|
|
48973
|
+
uint256_exports.bnToUint256(amountInfo.amount.toWei()),
|
|
48974
|
+
receiver.address
|
|
48975
|
+
]);
|
|
48944
48976
|
return [call1, call2];
|
|
48945
48977
|
}
|
|
48946
48978
|
/**
|
|
@@ -48951,7 +48983,13 @@ var strkfarm_risk_engine = (() => {
|
|
|
48951
48983
|
* @returns Populated contract call for withdrawal
|
|
48952
48984
|
*/
|
|
48953
48985
|
async withdrawCall(amountInfo, receiver, owner) {
|
|
48954
|
-
return [
|
|
48986
|
+
return [
|
|
48987
|
+
this.contract.populate("withdraw", [
|
|
48988
|
+
uint256_exports.bnToUint256(amountInfo.amount.toWei()),
|
|
48989
|
+
receiver.address,
|
|
48990
|
+
owner.address
|
|
48991
|
+
])
|
|
48992
|
+
];
|
|
48955
48993
|
}
|
|
48956
48994
|
/**
|
|
48957
48995
|
* Returns the underlying asset token of the strategy.
|
|
@@ -48974,9 +49012,16 @@ var strkfarm_risk_engine = (() => {
|
|
|
48974
49012
|
*/
|
|
48975
49013
|
async getUserTVL(user) {
|
|
48976
49014
|
const shares = await this.contract.balanceOf(user.address);
|
|
48977
|
-
const assets = await this.contract.convert_to_assets(
|
|
48978
|
-
|
|
48979
|
-
|
|
49015
|
+
const assets = await this.contract.convert_to_assets(
|
|
49016
|
+
uint256_exports.bnToUint256(shares)
|
|
49017
|
+
);
|
|
49018
|
+
const amount = Web3Number.fromWei(
|
|
49019
|
+
assets.toString(),
|
|
49020
|
+
this.metadata.depositTokens[0].decimals
|
|
49021
|
+
);
|
|
49022
|
+
let price = await this.pricer.getPrice(
|
|
49023
|
+
this.metadata.depositTokens[0].symbol
|
|
49024
|
+
);
|
|
48980
49025
|
const usdValue = Number(amount.toFixed(6)) * price.price;
|
|
48981
49026
|
return {
|
|
48982
49027
|
tokenInfo: this.asset(),
|
|
@@ -48990,8 +49035,13 @@ var strkfarm_risk_engine = (() => {
|
|
|
48990
49035
|
*/
|
|
48991
49036
|
async getTVL() {
|
|
48992
49037
|
const assets = await this.contract.total_assets();
|
|
48993
|
-
const amount = Web3Number.fromWei(
|
|
48994
|
-
|
|
49038
|
+
const amount = Web3Number.fromWei(
|
|
49039
|
+
assets.toString(),
|
|
49040
|
+
this.metadata.depositTokens[0].decimals
|
|
49041
|
+
);
|
|
49042
|
+
let price = await this.pricer.getPrice(
|
|
49043
|
+
this.metadata.depositTokens[0].symbol
|
|
49044
|
+
);
|
|
48995
49045
|
const usdValue = Number(amount.toFixed(6)) * price.price;
|
|
48996
49046
|
return {
|
|
48997
49047
|
tokenInfo: this.asset(),
|
|
@@ -49017,51 +49067,104 @@ var strkfarm_risk_engine = (() => {
|
|
|
49017
49067
|
return pools;
|
|
49018
49068
|
}
|
|
49019
49069
|
async getPoolInfo(p, pools, vesuPositions, totalAssets, isErrorPositionsAPI, isErrorPoolsAPI) {
|
|
49020
|
-
const vesuPosition = vesuPositions.find(
|
|
49070
|
+
const vesuPosition = vesuPositions.find(
|
|
49071
|
+
(d) => d.pool.id.toString() === num_exports.getDecimalString(p.pool_id.address.toString())
|
|
49072
|
+
);
|
|
49021
49073
|
const _pool = pools.find((d) => {
|
|
49022
|
-
logger.verbose(
|
|
49074
|
+
logger.verbose(
|
|
49075
|
+
`pool check: ${d.id == num_exports.getDecimalString(p.pool_id.address.toString())}, id: ${d.id}, pool_id: ${num_exports.getDecimalString(
|
|
49076
|
+
p.pool_id.address.toString()
|
|
49077
|
+
)}`
|
|
49078
|
+
);
|
|
49023
49079
|
return d.id == num_exports.getDecimalString(p.pool_id.address.toString());
|
|
49024
49080
|
});
|
|
49025
49081
|
logger.verbose(`pool: ${JSON.stringify(_pool)}`);
|
|
49026
49082
|
logger.verbose(typeof _pool);
|
|
49027
49083
|
logger.verbose(`name: ${_pool?.name}`);
|
|
49028
49084
|
const name = _pool?.name;
|
|
49029
|
-
logger.verbose(
|
|
49030
|
-
|
|
49085
|
+
logger.verbose(
|
|
49086
|
+
`name2: ${name}, ${!name ? true : false}, ${name?.length}, ${typeof name}`
|
|
49087
|
+
);
|
|
49088
|
+
const assetInfo = _pool?.assets.find(
|
|
49089
|
+
(d) => this.asset().address.eqString(d.address)
|
|
49090
|
+
);
|
|
49031
49091
|
if (!name) {
|
|
49032
49092
|
logger.verbose(`Pool not found`);
|
|
49033
49093
|
throw new Error(`Pool name ${p.pool_id.address.toString()} not found`);
|
|
49034
49094
|
}
|
|
49035
49095
|
if (!assetInfo) {
|
|
49036
|
-
throw new Error(
|
|
49096
|
+
throw new Error(
|
|
49097
|
+
`Asset ${this.asset().address.toString()} not found in pool ${p.pool_id.address.toString()}`
|
|
49098
|
+
);
|
|
49037
49099
|
}
|
|
49038
|
-
let vTokenContract = new Contract(
|
|
49100
|
+
let vTokenContract = new Contract(
|
|
49101
|
+
vesu_rebalance_abi_default,
|
|
49102
|
+
p.v_token.address,
|
|
49103
|
+
this.config.provider
|
|
49104
|
+
);
|
|
49039
49105
|
const bal = await vTokenContract.balanceOf(this.address.address);
|
|
49040
|
-
const assets = await vTokenContract.convert_to_assets(
|
|
49106
|
+
const assets = await vTokenContract.convert_to_assets(
|
|
49107
|
+
uint256_exports.bnToUint256(bal.toString())
|
|
49108
|
+
);
|
|
49041
49109
|
logger.verbose(`Collateral: ${JSON.stringify(vesuPosition?.collateral)}`);
|
|
49042
49110
|
logger.verbose(`supplyApy: ${JSON.stringify(assetInfo?.stats.supplyApy)}`);
|
|
49043
|
-
logger.verbose(
|
|
49044
|
-
|
|
49045
|
-
|
|
49111
|
+
logger.verbose(
|
|
49112
|
+
`defiSpringSupplyApr: ${JSON.stringify(
|
|
49113
|
+
assetInfo?.stats.defiSpringSupplyApr
|
|
49114
|
+
)}`
|
|
49115
|
+
);
|
|
49116
|
+
logger.verbose(
|
|
49117
|
+
`currentUtilization: ${JSON.stringify(
|
|
49118
|
+
assetInfo?.stats.currentUtilization
|
|
49119
|
+
)}`
|
|
49120
|
+
);
|
|
49121
|
+
logger.verbose(
|
|
49122
|
+
`maxUtilization: ${JSON.stringify(assetInfo?.config.maxUtilization)}`
|
|
49123
|
+
);
|
|
49046
49124
|
const item = {
|
|
49047
49125
|
pool_id: p.pool_id,
|
|
49048
49126
|
pool_name: _pool?.name,
|
|
49049
49127
|
max_weight: p.max_weight,
|
|
49050
|
-
current_weight: isErrorPositionsAPI || !vesuPosition ? 0 : Number(
|
|
49128
|
+
current_weight: isErrorPositionsAPI || !vesuPosition ? 0 : Number(
|
|
49129
|
+
Web3Number.fromWei(vesuPosition.collateral.value, this.decimals()).dividedBy(totalAssets.toString()).toFixed(6)
|
|
49130
|
+
),
|
|
49051
49131
|
v_token: p.v_token,
|
|
49052
49132
|
amount: Web3Number.fromWei(assets.toString(), this.decimals()),
|
|
49053
|
-
usdValue: isErrorPositionsAPI || !vesuPosition ? Web3Number.fromWei("0", this.decimals()) : Web3Number.fromWei(
|
|
49133
|
+
usdValue: isErrorPositionsAPI || !vesuPosition ? Web3Number.fromWei("0", this.decimals()) : Web3Number.fromWei(
|
|
49134
|
+
vesuPosition.collateral.usdPrice.value,
|
|
49135
|
+
vesuPosition.collateral.usdPrice.decimals
|
|
49136
|
+
),
|
|
49054
49137
|
APY: isErrorPoolsAPI || !assetInfo ? {
|
|
49055
49138
|
baseApy: 0,
|
|
49056
49139
|
defiSpringApy: 0,
|
|
49057
49140
|
netApy: 0
|
|
49058
49141
|
} : {
|
|
49059
|
-
baseApy: Number(
|
|
49060
|
-
|
|
49142
|
+
baseApy: Number(
|
|
49143
|
+
Web3Number.fromWei(
|
|
49144
|
+
assetInfo.stats.supplyApy.value,
|
|
49145
|
+
assetInfo.stats.supplyApy.decimals
|
|
49146
|
+
).toFixed(6)
|
|
49147
|
+
),
|
|
49148
|
+
defiSpringApy: assetInfo.stats.defiSpringSupplyApr ? Number(
|
|
49149
|
+
Web3Number.fromWei(
|
|
49150
|
+
assetInfo.stats.defiSpringSupplyApr.value,
|
|
49151
|
+
assetInfo.stats.defiSpringSupplyApr.decimals
|
|
49152
|
+
).toFixed(6)
|
|
49153
|
+
) : 0,
|
|
49061
49154
|
netApy: 0
|
|
49062
49155
|
},
|
|
49063
|
-
currentUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(
|
|
49064
|
-
|
|
49156
|
+
currentUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(
|
|
49157
|
+
Web3Number.fromWei(
|
|
49158
|
+
assetInfo.stats.currentUtilization.value,
|
|
49159
|
+
assetInfo.stats.currentUtilization.decimals
|
|
49160
|
+
).toFixed(6)
|
|
49161
|
+
),
|
|
49162
|
+
maxUtilization: isErrorPoolsAPI || !assetInfo ? 0 : Number(
|
|
49163
|
+
Web3Number.fromWei(
|
|
49164
|
+
assetInfo.config.maxUtilization.value,
|
|
49165
|
+
assetInfo.config.maxUtilization.decimals
|
|
49166
|
+
).toFixed(6)
|
|
49167
|
+
)
|
|
49065
49168
|
};
|
|
49066
49169
|
item.APY.netApy = item.APY.baseApy + item.APY.defiSpringApy;
|
|
49067
49170
|
return item;
|
|
@@ -49071,7 +49174,7 @@ var strkfarm_risk_engine = (() => {
|
|
|
49071
49174
|
* 1. Contract's allowed pools
|
|
49072
49175
|
* 2. Vesu positions API for current positions
|
|
49073
49176
|
* 3. Vesu pools API for APY and utilization data
|
|
49074
|
-
*
|
|
49177
|
+
*
|
|
49075
49178
|
* @returns {Promise<{
|
|
49076
49179
|
* data: Array<PoolInfoFull>,
|
|
49077
49180
|
* isErrorPositionsAPI: boolean
|
|
@@ -49088,15 +49191,29 @@ var strkfarm_risk_engine = (() => {
|
|
|
49088
49191
|
let isErrorPositionsAPI = false;
|
|
49089
49192
|
let vesuPositions = [];
|
|
49090
49193
|
try {
|
|
49091
|
-
const data2 = await getAPIUsingHeadlessBrowser(
|
|
49194
|
+
const data2 = await getAPIUsingHeadlessBrowser(
|
|
49195
|
+
`https://api.vesu.xyz/positions?walletAddress=${this.address.address}`
|
|
49196
|
+
);
|
|
49092
49197
|
vesuPositions = data2.data;
|
|
49093
49198
|
} catch (e) {
|
|
49094
|
-
console.error(
|
|
49199
|
+
console.error(
|
|
49200
|
+
`${_VesuRebalance.name}: Error fetching positions for ${this.address.address}`,
|
|
49201
|
+
e
|
|
49202
|
+
);
|
|
49095
49203
|
isErrorPositionsAPI = true;
|
|
49096
49204
|
}
|
|
49097
49205
|
let { pools, isErrorPoolsAPI } = await this.getVesuPools();
|
|
49098
49206
|
const totalAssets = (await this.getTVL()).amount;
|
|
49099
|
-
const info = allowedPools.map(
|
|
49207
|
+
const info = allowedPools.map(
|
|
49208
|
+
(p) => this.getPoolInfo(
|
|
49209
|
+
p,
|
|
49210
|
+
pools,
|
|
49211
|
+
vesuPositions,
|
|
49212
|
+
totalAssets,
|
|
49213
|
+
isErrorPositionsAPI,
|
|
49214
|
+
isErrorPoolsAPI
|
|
49215
|
+
)
|
|
49216
|
+
);
|
|
49100
49217
|
const data = await Promise.all(info);
|
|
49101
49218
|
return {
|
|
49102
49219
|
data,
|
|
@@ -49109,18 +49226,25 @@ var strkfarm_risk_engine = (() => {
|
|
|
49109
49226
|
let isErrorPoolsAPI = false;
|
|
49110
49227
|
let pools = [];
|
|
49111
49228
|
try {
|
|
49112
|
-
const data = await getAPIUsingHeadlessBrowser(
|
|
49229
|
+
const data = await getAPIUsingHeadlessBrowser(
|
|
49230
|
+
"https://api.vesu.xyz/pools"
|
|
49231
|
+
);
|
|
49113
49232
|
pools = data.data;
|
|
49114
49233
|
for (const pool of vesu_pools_default.data) {
|
|
49115
49234
|
const found = pools.find((d) => d.id === pool.id);
|
|
49116
49235
|
if (!found) {
|
|
49117
49236
|
logger.verbose(`VesuRebalance: pools: ${JSON.stringify(pools)}`);
|
|
49118
|
-
logger.verbose(
|
|
49237
|
+
logger.verbose(
|
|
49238
|
+
`VesuRebalance: Pool ${pool.id} not found in Vesu API, using hardcoded data`
|
|
49239
|
+
);
|
|
49119
49240
|
throw new Error("pool not found [sanity check]");
|
|
49120
49241
|
}
|
|
49121
49242
|
}
|
|
49122
49243
|
} catch (e) {
|
|
49123
|
-
logger.error(
|
|
49244
|
+
logger.error(
|
|
49245
|
+
`${_VesuRebalance.name}: Error fetching pools for ${this.address.address}, retry ${retry}`,
|
|
49246
|
+
e
|
|
49247
|
+
);
|
|
49124
49248
|
isErrorPoolsAPI = true;
|
|
49125
49249
|
if (retry < 10) {
|
|
49126
49250
|
await new Promise((resolve) => setTimeout(resolve, 5e3 * (retry + 1)));
|
|
@@ -49158,8 +49282,8 @@ var strkfarm_risk_engine = (() => {
|
|
|
49158
49282
|
* 3. For each pool that needs more funds:
|
|
49159
49283
|
* - Takes funds from lowest APY pools that are over their target
|
|
49160
49284
|
* 4. Validates that total assets remain constant
|
|
49161
|
-
*
|
|
49162
|
-
* @returns {Promise<{
|
|
49285
|
+
*
|
|
49286
|
+
* @returns {Promise<{
|
|
49163
49287
|
* changes: Change[],
|
|
49164
49288
|
* finalPools: PoolInfoFull[],
|
|
49165
49289
|
* isAnyPoolOverMaxWeight: boolean
|
|
@@ -49175,27 +49299,38 @@ var strkfarm_risk_engine = (() => {
|
|
|
49175
49299
|
_pools = _pools2;
|
|
49176
49300
|
}
|
|
49177
49301
|
const feeDeductions = await this.getFee(_pools);
|
|
49178
|
-
logger.verbose(
|
|
49302
|
+
logger.verbose(
|
|
49303
|
+
`VesuRebalance: feeDeductions: ${JSON.stringify(feeDeductions)}`
|
|
49304
|
+
);
|
|
49179
49305
|
const pools = _pools.map((p) => {
|
|
49180
49306
|
const fee = feeDeductions.find((f) => p.v_token.eq(f.vToken))?.fee || Web3Number.fromWei("0", this.decimals());
|
|
49181
|
-
logger.verbose(
|
|
49307
|
+
logger.verbose(
|
|
49308
|
+
`FeeAdjustment: ${p.pool_id} => ${fee.toString()}, amt: ${p.amount.toString()}`
|
|
49309
|
+
);
|
|
49182
49310
|
return {
|
|
49183
49311
|
...p,
|
|
49184
49312
|
amount: p.amount.minus(fee)
|
|
49185
49313
|
};
|
|
49186
49314
|
});
|
|
49187
49315
|
let totalAssets = (await this.getTVL()).amount;
|
|
49188
|
-
if (totalAssets.eq(0))
|
|
49189
|
-
|
|
49190
|
-
|
|
49191
|
-
|
|
49316
|
+
if (totalAssets.eq(0))
|
|
49317
|
+
return {
|
|
49318
|
+
changes: [],
|
|
49319
|
+
finalPools: []
|
|
49320
|
+
};
|
|
49192
49321
|
feeDeductions.forEach((f) => {
|
|
49193
49322
|
totalAssets = totalAssets.minus(f.fee);
|
|
49194
49323
|
});
|
|
49195
|
-
const sumPools = pools.reduce(
|
|
49324
|
+
const sumPools = pools.reduce(
|
|
49325
|
+
(acc, curr) => acc.plus(curr.amount.toString()),
|
|
49326
|
+
Web3Number.fromWei("0", this.decimals())
|
|
49327
|
+
);
|
|
49196
49328
|
logger.verbose(`Sum of pools: ${sumPools.toString()}`);
|
|
49197
49329
|
logger.verbose(`Total assets: ${totalAssets.toString()}`);
|
|
49198
|
-
assert3(
|
|
49330
|
+
assert3(
|
|
49331
|
+
sumPools.lte(totalAssets.multipliedBy(1.00001).toString()),
|
|
49332
|
+
"Sum of pools.amount must be less than or equal to totalAssets"
|
|
49333
|
+
);
|
|
49199
49334
|
const sortedPools = [...pools].sort((a, b) => b.APY.netApy - a.APY.netApy);
|
|
49200
49335
|
const targetAmounts = {};
|
|
49201
49336
|
let remainingAssets = totalAssets;
|
|
@@ -49217,7 +49352,10 @@ var strkfarm_risk_engine = (() => {
|
|
|
49217
49352
|
assert3(remainingAssets.lt(1e-5), "Remaining assets must be 0");
|
|
49218
49353
|
const changes = sortedPools.map((pool) => {
|
|
49219
49354
|
const target = targetAmounts[pool.pool_id.address.toString()] || Web3Number.fromWei("0", this.decimals());
|
|
49220
|
-
const change = Web3Number.fromWei(
|
|
49355
|
+
const change = Web3Number.fromWei(
|
|
49356
|
+
target.minus(pool.amount.toString()).toWei(),
|
|
49357
|
+
this.decimals()
|
|
49358
|
+
);
|
|
49221
49359
|
return {
|
|
49222
49360
|
pool_id: pool.pool_id,
|
|
49223
49361
|
changeAmt: change,
|
|
@@ -49226,14 +49364,21 @@ var strkfarm_risk_engine = (() => {
|
|
|
49226
49364
|
};
|
|
49227
49365
|
});
|
|
49228
49366
|
logger.verbose(`Changes: ${JSON.stringify(changes)}`);
|
|
49229
|
-
const sumChanges = changes.reduce(
|
|
49230
|
-
|
|
49367
|
+
const sumChanges = changes.reduce(
|
|
49368
|
+
(sum, c) => sum.plus(c.changeAmt.toString()),
|
|
49369
|
+
Web3Number.fromWei("0", this.decimals())
|
|
49370
|
+
);
|
|
49371
|
+
const sumFinal = changes.reduce(
|
|
49372
|
+
(sum, c) => sum.plus(c.finalAmt.toString()),
|
|
49373
|
+
Web3Number.fromWei("0", this.decimals())
|
|
49374
|
+
);
|
|
49231
49375
|
const hasChanges = changes.some((c) => !c.changeAmt.eq(0));
|
|
49232
49376
|
logger.verbose(`Sum of changes: ${sumChanges.toString()}`);
|
|
49233
49377
|
if (!sumChanges.eq(0)) throw new Error("Sum of changes must be zero");
|
|
49234
49378
|
logger.verbose(`Sum of final: ${sumFinal.toString()}`);
|
|
49235
49379
|
logger.verbose(`Total assets: ${totalAssets.toString()}`);
|
|
49236
|
-
if (!sumFinal.eq(totalAssets.toString()))
|
|
49380
|
+
if (!sumFinal.eq(totalAssets.toString()))
|
|
49381
|
+
throw new Error("Sum of final amounts must equal total assets");
|
|
49237
49382
|
if (!hasChanges) throw new Error("No changes required");
|
|
49238
49383
|
const finalPools = pools.map((p) => {
|
|
49239
49384
|
const target = targetAmounts[p.pool_id.address.toString()] || Web3Number.fromWei("0", this.decimals());
|
|
@@ -49261,9 +49406,13 @@ var strkfarm_risk_engine = (() => {
|
|
|
49261
49406
|
if (p.changeAmt.eq(0)) return null;
|
|
49262
49407
|
actions.push({
|
|
49263
49408
|
pool_id: p.pool_id.address,
|
|
49264
|
-
feature: new CairoCustomEnum(
|
|
49409
|
+
feature: new CairoCustomEnum(
|
|
49410
|
+
p.isDeposit ? { DEPOSIT: {} } : { WITHDRAW: {} }
|
|
49411
|
+
),
|
|
49265
49412
|
token: this.asset().address.address,
|
|
49266
|
-
amount: uint256_exports.bnToUint256(
|
|
49413
|
+
amount: uint256_exports.bnToUint256(
|
|
49414
|
+
p.changeAmt.multipliedBy(p.isDeposit ? 1 : -1).toWei()
|
|
49415
|
+
)
|
|
49267
49416
|
});
|
|
49268
49417
|
});
|
|
49269
49418
|
if (actions.length === 0) return null;
|
|
@@ -49276,18 +49425,29 @@ var strkfarm_risk_engine = (() => {
|
|
|
49276
49425
|
const netYield = await this.netAPYGivenPools(pools);
|
|
49277
49426
|
const baseFlow = {
|
|
49278
49427
|
title: "Your Deposit",
|
|
49279
|
-
subItems: [
|
|
49428
|
+
subItems: [
|
|
49429
|
+
{ key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` },
|
|
49430
|
+
{
|
|
49431
|
+
key: `Performance Fee`,
|
|
49432
|
+
value: `${(this.metadata.additionalInfo.feeBps / 100).toFixed(2)}%`
|
|
49433
|
+
}
|
|
49434
|
+
],
|
|
49280
49435
|
linkedFlows: [],
|
|
49281
49436
|
style: { backgroundColor: "#6e53dc" /* Purple */.valueOf() }
|
|
49282
49437
|
};
|
|
49283
49438
|
let _pools = [...pools];
|
|
49284
|
-
_pools = _pools.sort(
|
|
49439
|
+
_pools = _pools.sort(
|
|
49440
|
+
(a, b) => Number(b.amount.toString()) - Number(a.amount.toString())
|
|
49441
|
+
);
|
|
49285
49442
|
_pools.forEach((p) => {
|
|
49286
49443
|
const flow = {
|
|
49287
49444
|
title: `Pool name: ${p.pool_name}`,
|
|
49288
49445
|
subItems: [
|
|
49289
49446
|
{ key: `APY`, value: `${(p.APY.netApy * 100).toFixed(2)}%` },
|
|
49290
|
-
{
|
|
49447
|
+
{
|
|
49448
|
+
key: "Weight",
|
|
49449
|
+
value: `${(p.current_weight * 100).toFixed(2)} / ${(p.max_weight * 100).toFixed(2)}%`
|
|
49450
|
+
}
|
|
49291
49451
|
],
|
|
49292
49452
|
linkedFlows: [],
|
|
49293
49453
|
style: p.amount.greaterThan(0) ? { backgroundColor: "#35484f" /* Blue */.valueOf() } : { color: "gray" }
|
|
@@ -49319,7 +49479,12 @@ var strkfarm_risk_engine = (() => {
|
|
|
49319
49479
|
harvest.actualReward.toWei(),
|
|
49320
49480
|
this.address.address
|
|
49321
49481
|
);
|
|
49322
|
-
swapInfo = await avnu.getSwapInfo(
|
|
49482
|
+
swapInfo = await avnu.getSwapInfo(
|
|
49483
|
+
quote,
|
|
49484
|
+
this.address.address,
|
|
49485
|
+
0,
|
|
49486
|
+
this.address.address
|
|
49487
|
+
);
|
|
49323
49488
|
}
|
|
49324
49489
|
return [
|
|
49325
49490
|
this.contract.populate("harvest", [
|
|
@@ -49340,16 +49505,27 @@ var strkfarm_risk_engine = (() => {
|
|
|
49340
49505
|
* @returns {Promise<Array<{ vToken: ContractAddr, fee: Web3Number }>>} Array of fees deducted in different vTokens
|
|
49341
49506
|
*/
|
|
49342
49507
|
async getFee(allowedPools) {
|
|
49343
|
-
const assets = Web3Number.fromWei(
|
|
49344
|
-
|
|
49345
|
-
|
|
49508
|
+
const assets = Web3Number.fromWei(
|
|
49509
|
+
(await this.contract.total_assets()).toString(),
|
|
49510
|
+
this.asset().decimals
|
|
49511
|
+
);
|
|
49512
|
+
const totalSupply = Web3Number.fromWei(
|
|
49513
|
+
(await this.contract.total_supply()).toString(),
|
|
49514
|
+
this.asset().decimals
|
|
49515
|
+
);
|
|
49516
|
+
const prevIndex = Web3Number.fromWei(
|
|
49517
|
+
(await this.contract.get_previous_index()).toString(),
|
|
49518
|
+
18
|
|
49519
|
+
);
|
|
49346
49520
|
const currIndex = new Web3Number(1, 18).multipliedBy(assets).dividedBy(totalSupply);
|
|
49347
49521
|
logger.verbose(`Previous index: ${prevIndex.toString()}`);
|
|
49348
49522
|
logger.verbose(`Assets: ${assets.toString()}`);
|
|
49349
49523
|
logger.verbose(`Total supply: ${totalSupply.toString()}`);
|
|
49350
49524
|
logger.verbose(`Current index: ${currIndex.toNumber()}`);
|
|
49351
49525
|
if (currIndex.lt(prevIndex)) {
|
|
49352
|
-
logger.verbose(
|
|
49526
|
+
logger.verbose(
|
|
49527
|
+
`getFee::Current index is less than previous index, no fees to be deducted`
|
|
49528
|
+
);
|
|
49353
49529
|
return [];
|
|
49354
49530
|
}
|
|
49355
49531
|
const indexDiff = currIndex.minus(prevIndex);
|
|
@@ -49362,7 +49538,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
49362
49538
|
return [];
|
|
49363
49539
|
}
|
|
49364
49540
|
const fees = [];
|
|
49365
|
-
let remainingFee = fee.plus(
|
|
49541
|
+
let remainingFee = fee.plus(
|
|
49542
|
+
Web3Number.fromWei("100", this.asset().decimals)
|
|
49543
|
+
);
|
|
49366
49544
|
for (const pool of allowedPools) {
|
|
49367
49545
|
const vToken = pool.v_token;
|
|
49368
49546
|
const balance = pool.amount;
|
|
@@ -49371,7 +49549,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
49371
49549
|
break;
|
|
49372
49550
|
} else {
|
|
49373
49551
|
fees.push({ vToken, fee: Web3Number.fromWei(balance.toString(), 18) });
|
|
49374
|
-
remainingFee = remainingFee.minus(
|
|
49552
|
+
remainingFee = remainingFee.minus(
|
|
49553
|
+
Web3Number.fromWei(balance.toString(), 18)
|
|
49554
|
+
);
|
|
49375
49555
|
}
|
|
49376
49556
|
}
|
|
49377
49557
|
logger.verbose(`Fees: ${JSON.stringify(fees)}`);
|
|
@@ -49379,98 +49559,172 @@ var strkfarm_risk_engine = (() => {
|
|
|
49379
49559
|
}
|
|
49380
49560
|
};
|
|
49381
49561
|
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 = {
|
|
49562
|
+
var _protocol = {
|
|
49563
|
+
name: "Vesu",
|
|
49564
|
+
logo: "https://static-assets-8zct.onrender.com/integrations/vesu/logo.png"
|
|
49565
|
+
};
|
|
49383
49566
|
var _riskFactor = [
|
|
49384
49567
|
{ type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 0.5, weight: 25 },
|
|
49385
49568
|
{ type: "Counterparty Risk" /* COUNTERPARTY_RISK */, value: 1, weight: 50 },
|
|
49386
49569
|
{ type: "Oracle Risk" /* ORACLE_RISK */, value: 0.5, weight: 25 }
|
|
49387
49570
|
];
|
|
49388
49571
|
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
|
-
|
|
49572
|
+
var faqs = [
|
|
49573
|
+
{
|
|
49574
|
+
question: "What is the Vesu Rebalancing Strategy?",
|
|
49575
|
+
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."
|
|
49576
|
+
},
|
|
49577
|
+
{
|
|
49578
|
+
question: "Will I earn Vesu points?",
|
|
49579
|
+
answer: "Yes, of course! You will earn Vesu points for your deposits."
|
|
49580
|
+
},
|
|
49581
|
+
{
|
|
49582
|
+
question: "How does the strategy optimize yield?",
|
|
49583
|
+
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."
|
|
49584
|
+
},
|
|
49585
|
+
{
|
|
49586
|
+
question: "What are the risks associated with this strategy?",
|
|
49587
|
+
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."
|
|
49588
|
+
},
|
|
49589
|
+
{
|
|
49590
|
+
question: "How are fees calculated and deducted?",
|
|
49591
|
+
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."
|
|
49592
|
+
},
|
|
49593
|
+
{
|
|
49594
|
+
question: "What happens if a pool exceeds its maximum weight?",
|
|
49595
|
+
answer: "If a pool exceeds its maximum weight, the strategy rebalances by withdrawing excess funds and reallocating them to other pools with available capacity."
|
|
49596
|
+
},
|
|
49597
|
+
{
|
|
49598
|
+
question: "Can I withdraw my assets at any time?",
|
|
49599
|
+
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."
|
|
49600
|
+
},
|
|
49601
|
+
{
|
|
49602
|
+
question: "What happens to my Defi Spring STRK rewards?",
|
|
49603
|
+
answer: "STRK rewards are automatically harvested and reinvested into the strategy every week to maximize compounding returns."
|
|
49604
|
+
},
|
|
49605
|
+
{
|
|
49606
|
+
question: "Is the strategy audited?",
|
|
49607
|
+
answer: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
49608
|
+
"Yes, the strategy has been audited. You can review the audit report in our docs ",
|
|
49609
|
+
/* @__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" }),
|
|
49610
|
+
"."
|
|
49611
|
+
] })
|
|
49422
49612
|
}
|
|
49423
|
-
|
|
49424
|
-
|
|
49425
|
-
|
|
49426
|
-
|
|
49427
|
-
|
|
49428
|
-
|
|
49429
|
-
|
|
49430
|
-
|
|
49431
|
-
|
|
49432
|
-
|
|
49433
|
-
|
|
49434
|
-
|
|
49435
|
-
|
|
49436
|
-
|
|
49437
|
-
|
|
49438
|
-
|
|
49613
|
+
];
|
|
49614
|
+
var VesuRebalanceStrategies = [
|
|
49615
|
+
{
|
|
49616
|
+
name: "Vesu Fusion STRK",
|
|
49617
|
+
description: _description.replace("{{TOKEN}}", "STRK"),
|
|
49618
|
+
address: ContractAddr.from(
|
|
49619
|
+
"0x7fb5bcb8525954a60fde4e8fb8220477696ce7117ef264775a1770e23571929"
|
|
49620
|
+
),
|
|
49621
|
+
launchBlock: 0,
|
|
49622
|
+
type: "ERC4626",
|
|
49623
|
+
depositTokens: [
|
|
49624
|
+
Global.getDefaultTokens().find((t) => t.symbol === "STRK")
|
|
49625
|
+
],
|
|
49626
|
+
protocols: [_protocol],
|
|
49627
|
+
auditUrl: AUDIT_URL,
|
|
49628
|
+
maxTVL: Web3Number.fromWei("0", 18),
|
|
49629
|
+
risk: {
|
|
49630
|
+
riskFactor: _riskFactor,
|
|
49631
|
+
netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
|
|
49632
|
+
notARisks: getNoRiskTags(_riskFactor)
|
|
49633
|
+
},
|
|
49634
|
+
additionalInfo: {
|
|
49635
|
+
feeBps: 1e3
|
|
49636
|
+
},
|
|
49637
|
+
faqs
|
|
49638
|
+
},
|
|
49639
|
+
{
|
|
49640
|
+
name: "Vesu Fusion ETH",
|
|
49641
|
+
description: _description.replace("{{TOKEN}}", "ETH"),
|
|
49642
|
+
address: ContractAddr.from(
|
|
49643
|
+
"0x5eaf5ee75231cecf79921ff8ded4b5ffe96be718bcb3daf206690ad1a9ad0ca"
|
|
49644
|
+
),
|
|
49645
|
+
launchBlock: 0,
|
|
49646
|
+
type: "ERC4626",
|
|
49647
|
+
auditUrl: AUDIT_URL,
|
|
49648
|
+
depositTokens: [
|
|
49649
|
+
Global.getDefaultTokens().find((t) => t.symbol === "ETH")
|
|
49650
|
+
],
|
|
49651
|
+
protocols: [_protocol],
|
|
49652
|
+
maxTVL: Web3Number.fromWei("0", 18),
|
|
49653
|
+
risk: {
|
|
49654
|
+
riskFactor: _riskFactor,
|
|
49655
|
+
netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
|
|
49656
|
+
notARisks: getNoRiskTags(_riskFactor)
|
|
49657
|
+
},
|
|
49658
|
+
additionalInfo: {
|
|
49659
|
+
feeBps: 1e3
|
|
49660
|
+
},
|
|
49661
|
+
faqs
|
|
49662
|
+
},
|
|
49663
|
+
{
|
|
49664
|
+
name: "Vesu Fusion USDC",
|
|
49665
|
+
description: _description.replace("{{TOKEN}}", "USDC"),
|
|
49666
|
+
address: ContractAddr.from(
|
|
49667
|
+
"0xa858c97e9454f407d1bd7c57472fc8d8d8449a777c822b41d18e387816f29c"
|
|
49668
|
+
),
|
|
49669
|
+
launchBlock: 0,
|
|
49670
|
+
type: "ERC4626",
|
|
49671
|
+
auditUrl: AUDIT_URL,
|
|
49672
|
+
depositTokens: [
|
|
49673
|
+
Global.getDefaultTokens().find((t) => t.symbol === "USDC")
|
|
49674
|
+
],
|
|
49675
|
+
protocols: [_protocol],
|
|
49676
|
+
maxTVL: Web3Number.fromWei("0", 6),
|
|
49677
|
+
risk: {
|
|
49678
|
+
riskFactor: _riskFactor,
|
|
49679
|
+
netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
|
|
49680
|
+
notARisks: getNoRiskTags(_riskFactor)
|
|
49681
|
+
},
|
|
49682
|
+
additionalInfo: {
|
|
49683
|
+
feeBps: 1e3
|
|
49684
|
+
},
|
|
49685
|
+
faqs
|
|
49686
|
+
},
|
|
49687
|
+
{
|
|
49688
|
+
name: "Vesu Fusion USDT",
|
|
49689
|
+
description: _description.replace("{{TOKEN}}", "USDT"),
|
|
49690
|
+
address: ContractAddr.from(
|
|
49691
|
+
"0x115e94e722cfc4c77a2f15c4aefb0928c1c0029e5a57570df24c650cb7cec2c"
|
|
49692
|
+
),
|
|
49693
|
+
launchBlock: 0,
|
|
49694
|
+
type: "ERC4626",
|
|
49695
|
+
depositTokens: [
|
|
49696
|
+
Global.getDefaultTokens().find((t) => t.symbol === "USDT")
|
|
49697
|
+
],
|
|
49698
|
+
auditUrl: AUDIT_URL,
|
|
49699
|
+
protocols: [_protocol],
|
|
49700
|
+
maxTVL: Web3Number.fromWei("0", 6),
|
|
49701
|
+
risk: {
|
|
49702
|
+
riskFactor: _riskFactor,
|
|
49703
|
+
netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
|
|
49704
|
+
notARisks: getNoRiskTags(_riskFactor)
|
|
49705
|
+
},
|
|
49706
|
+
additionalInfo: {
|
|
49707
|
+
feeBps: 1e3
|
|
49708
|
+
},
|
|
49709
|
+
faqs
|
|
49710
|
+
// }, {
|
|
49711
|
+
// name: 'Vesu Fusion WBTC',
|
|
49712
|
+
// description: _description.replace('{{TOKEN}}', 'WBTC'),
|
|
49713
|
+
// address: ContractAddr.from('0x778007f8136a5b827325d21613803e796bda4d676fbe1e34aeab0b2a2ec027f'),
|
|
49714
|
+
// type: 'ERC4626',
|
|
49715
|
+
// depositTokens: [Global.getDefaultTokens().find(t => t.symbol === 'WBTC')!],
|
|
49716
|
+
// auditUrl: AUDIT_URL,
|
|
49717
|
+
// protocols: [_protocol],
|
|
49718
|
+
// maxTVL: Web3Number.fromWei('0', 8),
|
|
49719
|
+
// risk: {
|
|
49720
|
+
// riskFactor: _riskFactor,
|
|
49721
|
+
// netRisk: _riskFactor.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor.reduce((acc, curr) => acc + curr.weight, 0),
|
|
49722
|
+
// },
|
|
49723
|
+
// additionalInfo: {
|
|
49724
|
+
// feeBps: 1000,
|
|
49725
|
+
// },
|
|
49439
49726
|
}
|
|
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
|
-
}];
|
|
49727
|
+
];
|
|
49474
49728
|
|
|
49475
49729
|
// src/data/cl-vault.abi.json
|
|
49476
49730
|
var cl_vault_abi_default = [
|
|
@@ -54372,7 +54626,7 @@ var strkfarm_risk_engine = (() => {
|
|
|
54372
54626
|
];
|
|
54373
54627
|
|
|
54374
54628
|
// src/strategies/ekubo-cl-vault.tsx
|
|
54375
|
-
var
|
|
54629
|
+
var import_jsx_runtime2 = __toESM(require_jsx_runtime());
|
|
54376
54630
|
var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
54377
54631
|
/**
|
|
54378
54632
|
* Creates a new VesuRebalance strategy instance.
|
|
@@ -54385,15 +54639,38 @@ var strkfarm_risk_engine = (() => {
|
|
|
54385
54639
|
super(config2);
|
|
54386
54640
|
this.BASE_WEIGHT = 1e4;
|
|
54387
54641
|
this.pricer = pricer;
|
|
54388
|
-
assert3(
|
|
54642
|
+
assert3(
|
|
54643
|
+
metadata.depositTokens.length === 2,
|
|
54644
|
+
"EkuboCL only supports 2 deposit token"
|
|
54645
|
+
);
|
|
54389
54646
|
this.metadata = metadata;
|
|
54390
54647
|
this.address = metadata.address;
|
|
54391
|
-
this.contract = new Contract(
|
|
54392
|
-
|
|
54648
|
+
this.contract = new Contract(
|
|
54649
|
+
cl_vault_abi_default,
|
|
54650
|
+
this.address.address,
|
|
54651
|
+
this.config.provider
|
|
54652
|
+
);
|
|
54653
|
+
if (this.metadata.additionalInfo.lstContract) {
|
|
54654
|
+
this.lstContract = new Contract(
|
|
54655
|
+
erc4626_abi_default,
|
|
54656
|
+
this.metadata.additionalInfo.lstContract.address,
|
|
54657
|
+
this.config.provider
|
|
54658
|
+
);
|
|
54659
|
+
} else {
|
|
54660
|
+
this.lstContract = null;
|
|
54661
|
+
}
|
|
54393
54662
|
const EKUBO_POSITION = "0x02e0af29598b407c8716b17f6d2795eca1b471413fa03fb145a5e33722184067";
|
|
54394
|
-
this.ekuboPositionsContract = new Contract(
|
|
54663
|
+
this.ekuboPositionsContract = new Contract(
|
|
54664
|
+
ekubo_positions_abi_default,
|
|
54665
|
+
EKUBO_POSITION,
|
|
54666
|
+
this.config.provider
|
|
54667
|
+
);
|
|
54395
54668
|
const EKUBO_MATH = "0x04a72e9e166f6c0e9d800af4dc40f6b6fb4404b735d3f528d9250808b2481995";
|
|
54396
|
-
this.ekuboMathContract = new Contract(
|
|
54669
|
+
this.ekuboMathContract = new Contract(
|
|
54670
|
+
ekubo_math_abi_default,
|
|
54671
|
+
EKUBO_MATH,
|
|
54672
|
+
this.config.provider
|
|
54673
|
+
);
|
|
54397
54674
|
this.avnu = new AvnuWrapper();
|
|
54398
54675
|
}
|
|
54399
54676
|
async matchInputAmounts(amountInfo) {
|
|
@@ -54418,25 +54695,52 @@ var strkfarm_risk_engine = (() => {
|
|
|
54418
54695
|
/** Returns minimum amounts give given two amounts based on what can be added for liq */
|
|
54419
54696
|
async getMinDepositAmounts(amountInfo) {
|
|
54420
54697
|
const shares = await this.tokensToShares(amountInfo);
|
|
54421
|
-
const { amount0, amount1 } = await this.contract.call(
|
|
54698
|
+
const { amount0, amount1 } = await this.contract.call(
|
|
54699
|
+
"convert_to_assets",
|
|
54700
|
+
[uint256_exports.bnToUint256(shares.toWei())]
|
|
54701
|
+
);
|
|
54422
54702
|
return {
|
|
54423
54703
|
token0: {
|
|
54424
54704
|
tokenInfo: amountInfo.token0.tokenInfo,
|
|
54425
|
-
amount: Web3Number.fromWei(
|
|
54705
|
+
amount: Web3Number.fromWei(
|
|
54706
|
+
amount0.toString(),
|
|
54707
|
+
amountInfo.token0.tokenInfo.decimals
|
|
54708
|
+
)
|
|
54426
54709
|
},
|
|
54427
54710
|
token1: {
|
|
54428
54711
|
tokenInfo: amountInfo.token1.tokenInfo,
|
|
54429
|
-
amount: Web3Number.fromWei(
|
|
54712
|
+
amount: Web3Number.fromWei(
|
|
54713
|
+
amount1.toString(),
|
|
54714
|
+
amountInfo.token1.tokenInfo.decimals
|
|
54715
|
+
)
|
|
54430
54716
|
}
|
|
54431
54717
|
};
|
|
54432
54718
|
}
|
|
54433
54719
|
async depositCall(amountInfo, receiver) {
|
|
54434
54720
|
const updateAmountInfo = await this.getMinDepositAmounts(amountInfo);
|
|
54435
|
-
const token0Contract = new Contract(
|
|
54436
|
-
|
|
54437
|
-
|
|
54438
|
-
|
|
54439
|
-
|
|
54721
|
+
const token0Contract = new Contract(
|
|
54722
|
+
erc4626_abi_default,
|
|
54723
|
+
amountInfo.token0.tokenInfo.address.address,
|
|
54724
|
+
this.config.provider
|
|
54725
|
+
);
|
|
54726
|
+
const token1Contract = new Contract(
|
|
54727
|
+
erc4626_abi_default,
|
|
54728
|
+
amountInfo.token1.tokenInfo.address.address,
|
|
54729
|
+
this.config.provider
|
|
54730
|
+
);
|
|
54731
|
+
const call1 = token0Contract.populate("approve", [
|
|
54732
|
+
this.address.address,
|
|
54733
|
+
uint256_exports.bnToUint256(updateAmountInfo.token0.amount.toWei())
|
|
54734
|
+
]);
|
|
54735
|
+
const call2 = token1Contract.populate("approve", [
|
|
54736
|
+
this.address.address,
|
|
54737
|
+
uint256_exports.bnToUint256(updateAmountInfo.token1.amount.toWei())
|
|
54738
|
+
]);
|
|
54739
|
+
const call3 = this.contract.populate("deposit", [
|
|
54740
|
+
uint256_exports.bnToUint256(updateAmountInfo.token0.amount.toWei()),
|
|
54741
|
+
uint256_exports.bnToUint256(updateAmountInfo.token1.amount.toWei()),
|
|
54742
|
+
receiver.address
|
|
54743
|
+
]);
|
|
54440
54744
|
const calls = [];
|
|
54441
54745
|
if (updateAmountInfo.token0.amount.greaterThan(0)) calls.push(call1);
|
|
54442
54746
|
if (updateAmountInfo.token1.amount.greaterThan(0)) calls.push(call2);
|
|
@@ -54451,25 +54755,29 @@ var strkfarm_risk_engine = (() => {
|
|
|
54451
54755
|
}
|
|
54452
54756
|
async withdrawCall(amountInfo, receiver, owner) {
|
|
54453
54757
|
const shares = await this.tokensToShares(amountInfo);
|
|
54454
|
-
logger.verbose(
|
|
54455
|
-
|
|
54456
|
-
|
|
54457
|
-
|
|
54458
|
-
|
|
54758
|
+
logger.verbose(
|
|
54759
|
+
`${_EkuboCLVault.name}: withdrawCall: shares=${shares.toString()}`
|
|
54760
|
+
);
|
|
54761
|
+
return [
|
|
54762
|
+
this.contract.populate("withdraw", [
|
|
54763
|
+
uint256_exports.bnToUint256(shares.toWei()),
|
|
54764
|
+
receiver.address
|
|
54765
|
+
])
|
|
54766
|
+
];
|
|
54459
54767
|
}
|
|
54460
54768
|
rebalanceCall(newBounds, swapParams) {
|
|
54461
|
-
return [
|
|
54462
|
-
|
|
54463
|
-
|
|
54464
|
-
|
|
54465
|
-
|
|
54466
|
-
|
|
54467
|
-
|
|
54769
|
+
return [
|
|
54770
|
+
this.contract.populate("rebalance", [
|
|
54771
|
+
{
|
|
54772
|
+
lower: _EkuboCLVault.tickToi129(Number(newBounds.lowerTick)),
|
|
54773
|
+
upper: _EkuboCLVault.tickToi129(Number(newBounds.upperTick))
|
|
54774
|
+
},
|
|
54775
|
+
swapParams
|
|
54776
|
+
])
|
|
54777
|
+
];
|
|
54468
54778
|
}
|
|
54469
54779
|
handleUnusedCall(swapParams) {
|
|
54470
|
-
return [this.contract.populate("handle_unused", [
|
|
54471
|
-
swapParams
|
|
54472
|
-
])];
|
|
54780
|
+
return [this.contract.populate("handle_unused", [swapParams])];
|
|
54473
54781
|
}
|
|
54474
54782
|
handleFeesCall() {
|
|
54475
54783
|
return [this.contract.populate("handle_fees", [])];
|
|
@@ -54484,16 +54792,20 @@ var strkfarm_risk_engine = (() => {
|
|
|
54484
54792
|
const priceNow = await this.getCurrentPrice(blockIdentifier);
|
|
54485
54793
|
let blockNow = typeof blockIdentifier == "number" ? blockIdentifier : (await this.config.provider.getBlockLatestAccepted()).block_number;
|
|
54486
54794
|
const blockNowTime = typeof blockIdentifier == "number" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
|
|
54487
|
-
const blockBefore = blockNow - sinceBlocks;
|
|
54488
|
-
const adjustedSupplyNow = supplyNow.minus(
|
|
54489
|
-
|
|
54795
|
+
const blockBefore = Math.max(blockNow - sinceBlocks, this.metadata.launchBlock);
|
|
54796
|
+
const adjustedSupplyNow = supplyNow.minus(
|
|
54797
|
+
await this.getHarvestRewardShares(blockBefore, blockNow)
|
|
54798
|
+
);
|
|
54799
|
+
let blockBeforeInfo = await this.config.provider.getBlockWithTxs(
|
|
54800
|
+
blockBefore
|
|
54801
|
+
);
|
|
54490
54802
|
const tvlBefore = await this._getTVL(blockBefore);
|
|
54491
54803
|
const supplyBefore = await this.totalSupply(blockBefore);
|
|
54492
54804
|
const priceBefore = await this.getCurrentPrice(blockBefore);
|
|
54493
54805
|
const tvlInToken0Now = tvlNow.amount0.multipliedBy(priceNow.price).plus(tvlNow.amount1);
|
|
54494
|
-
const tvlPerShareNow = tvlInToken0Now.multipliedBy(1e18).dividedBy(adjustedSupplyNow);
|
|
54806
|
+
const tvlPerShareNow = tvlInToken0Now.multipliedBy(1e18).dividedBy(adjustedSupplyNow.toString());
|
|
54495
54807
|
const tvlInToken0Bf = tvlBefore.amount0.multipliedBy(priceBefore.price).plus(tvlBefore.amount1);
|
|
54496
|
-
const tvlPerShareBf = tvlInToken0Bf.multipliedBy(1e18).dividedBy(supplyBefore);
|
|
54808
|
+
const tvlPerShareBf = tvlInToken0Bf.multipliedBy(1e18).dividedBy(supplyBefore.toString());
|
|
54497
54809
|
const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
|
|
54498
54810
|
logger.verbose(`tvlInToken0Now: ${tvlInToken0Now.toString()}`);
|
|
54499
54811
|
logger.verbose(`tvlInToken0Bf: ${tvlInToken0Bf.toString()}`);
|
|
@@ -54504,7 +54816,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
54504
54816
|
logger.verbose(`Supply before: ${supplyBefore.toString()}`);
|
|
54505
54817
|
logger.verbose(`Supply now: ${adjustedSupplyNow.toString()}`);
|
|
54506
54818
|
logger.verbose(`Time diff in seconds: ${timeDiffSeconds}`);
|
|
54507
|
-
const apyForGivenBlocks = Number(
|
|
54819
|
+
const apyForGivenBlocks = Number(
|
|
54820
|
+
tvlPerShareNow.minus(tvlPerShareBf).multipliedBy(1e4).dividedBy(tvlPerShareBf)
|
|
54821
|
+
) / 1e4;
|
|
54508
54822
|
return apyForGivenBlocks * (365 * 24 * 3600) / timeDiffSeconds;
|
|
54509
54823
|
}
|
|
54510
54824
|
async getHarvestRewardShares(fromBlock, toBlock) {
|
|
@@ -54522,25 +54836,39 @@ var strkfarm_risk_engine = (() => {
|
|
|
54522
54836
|
} else {
|
|
54523
54837
|
shares = shares.plus(Web3Number.fromWei(record.shares.toString(), 18));
|
|
54524
54838
|
}
|
|
54525
|
-
logger.verbose(
|
|
54839
|
+
logger.verbose(
|
|
54840
|
+
`${_EkuboCLVault.name}: getHarvestRewardShares: ${i} => ${shares.toWei()}`
|
|
54841
|
+
);
|
|
54526
54842
|
}
|
|
54527
54843
|
return shares;
|
|
54528
54844
|
}
|
|
54529
54845
|
async balanceOf(user, blockIdentifier = "pending") {
|
|
54530
|
-
let bal = await this.contract.call("balance_of", [user.address]
|
|
54846
|
+
let bal = await this.contract.call("balance_of", [user.address], {
|
|
54847
|
+
blockIdentifier
|
|
54848
|
+
});
|
|
54531
54849
|
return Web3Number.fromWei(bal.toString(), 18);
|
|
54532
54850
|
}
|
|
54533
54851
|
async getUserTVL(user, blockIdentifier = "pending") {
|
|
54534
54852
|
let bal = await this.balanceOf(user, blockIdentifier);
|
|
54535
|
-
const assets = await this.contract.call(
|
|
54536
|
-
|
|
54537
|
-
|
|
54853
|
+
const assets = await this.contract.call(
|
|
54854
|
+
"convert_to_assets",
|
|
54855
|
+
[uint256_exports.bnToUint256(bal.toWei())],
|
|
54856
|
+
{
|
|
54857
|
+
blockIdentifier
|
|
54858
|
+
}
|
|
54859
|
+
);
|
|
54538
54860
|
const poolKey = await this.getPoolKey(blockIdentifier);
|
|
54539
54861
|
this.assertValidDepositTokens(poolKey);
|
|
54540
54862
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
54541
54863
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
54542
|
-
const amount0 = Web3Number.fromWei(
|
|
54543
|
-
|
|
54864
|
+
const amount0 = Web3Number.fromWei(
|
|
54865
|
+
assets.amount0.toString(),
|
|
54866
|
+
token0Info.decimals
|
|
54867
|
+
);
|
|
54868
|
+
const amount1 = Web3Number.fromWei(
|
|
54869
|
+
assets.amount1.toString(),
|
|
54870
|
+
token1Info.decimals
|
|
54871
|
+
);
|
|
54544
54872
|
const P0 = await this.pricer.getPrice(token0Info.symbol);
|
|
54545
54873
|
const P1 = await this.pricer.getPrice(token1Info.symbol);
|
|
54546
54874
|
const token0Usd = Number(amount0.toFixed(13)) * P0.price;
|
|
@@ -54564,7 +54892,11 @@ var strkfarm_risk_engine = (() => {
|
|
|
54564
54892
|
blockIdentifier
|
|
54565
54893
|
});
|
|
54566
54894
|
const bounds = await this.getCurrentBounds(blockIdentifier);
|
|
54567
|
-
const { amount0, amount1 } = await this.getLiquidityToAmounts(
|
|
54895
|
+
const { amount0, amount1 } = await this.getLiquidityToAmounts(
|
|
54896
|
+
Web3Number.fromWei(result.toString(), 18),
|
|
54897
|
+
bounds,
|
|
54898
|
+
blockIdentifier
|
|
54899
|
+
);
|
|
54568
54900
|
return { amount0, amount1 };
|
|
54569
54901
|
}
|
|
54570
54902
|
async totalSupply(blockIdentifier = "pending") {
|
|
@@ -54574,8 +54906,14 @@ var strkfarm_risk_engine = (() => {
|
|
|
54574
54906
|
return Web3Number.fromWei(res.toString(), 18);
|
|
54575
54907
|
}
|
|
54576
54908
|
assertValidDepositTokens(poolKey) {
|
|
54577
|
-
assert3(
|
|
54578
|
-
|
|
54909
|
+
assert3(
|
|
54910
|
+
poolKey.token0.eq(this.metadata.depositTokens[0].address),
|
|
54911
|
+
"Expected token0 in depositTokens[0]"
|
|
54912
|
+
);
|
|
54913
|
+
assert3(
|
|
54914
|
+
poolKey.token1.eq(this.metadata.depositTokens[1].address),
|
|
54915
|
+
"Expected token1 in depositTokens[1]"
|
|
54916
|
+
);
|
|
54579
54917
|
}
|
|
54580
54918
|
async getTVL(blockIdentifier = "pending") {
|
|
54581
54919
|
const { amount0, amount1 } = await this._getTVL(blockIdentifier);
|
|
@@ -54605,26 +54943,35 @@ var strkfarm_risk_engine = (() => {
|
|
|
54605
54943
|
const nftID = await this.getCurrentNFTID();
|
|
54606
54944
|
const poolKey = await this.getPoolKey();
|
|
54607
54945
|
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
|
-
|
|
54946
|
+
const result = await this.ekuboPositionsContract.call(
|
|
54947
|
+
"get_token_info",
|
|
54948
|
+
[
|
|
54949
|
+
nftID,
|
|
54950
|
+
{
|
|
54951
|
+
token0: poolKey.token0.address,
|
|
54952
|
+
token1: poolKey.token1.address,
|
|
54953
|
+
fee: poolKey.fee,
|
|
54954
|
+
tick_spacing: poolKey.tick_spacing,
|
|
54955
|
+
extension: poolKey.extension
|
|
54956
|
+
},
|
|
54957
|
+
{
|
|
54958
|
+
lower: _EkuboCLVault.tickToi129(Number(currentBounds.lowerTick)),
|
|
54959
|
+
upper: _EkuboCLVault.tickToi129(Number(currentBounds.upperTick))
|
|
54960
|
+
}
|
|
54961
|
+
]
|
|
54962
|
+
);
|
|
54622
54963
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
54623
54964
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
54624
54965
|
const P0 = await this.pricer.getPrice(token0Info.symbol);
|
|
54625
54966
|
const P1 = await this.pricer.getPrice(token1Info.symbol);
|
|
54626
|
-
const token0Web3 = Web3Number.fromWei(
|
|
54627
|
-
|
|
54967
|
+
const token0Web3 = Web3Number.fromWei(
|
|
54968
|
+
result.fees0.toString(),
|
|
54969
|
+
token0Info.decimals
|
|
54970
|
+
);
|
|
54971
|
+
const token1Web3 = Web3Number.fromWei(
|
|
54972
|
+
result.fees1.toString(),
|
|
54973
|
+
token1Info.decimals
|
|
54974
|
+
);
|
|
54628
54975
|
const token0Usd = Number(token0Web3.toFixed(13)) * P0.price;
|
|
54629
54976
|
const token1Usd = Number(token1Web3.toFixed(13)) * P1.price;
|
|
54630
54977
|
return {
|
|
@@ -54646,31 +54993,52 @@ var strkfarm_risk_engine = (() => {
|
|
|
54646
54993
|
return Number(result.salt.toString());
|
|
54647
54994
|
}
|
|
54648
54995
|
async truePrice() {
|
|
54649
|
-
|
|
54650
|
-
|
|
54651
|
-
|
|
54996
|
+
if (this.metadata.additionalInfo.truePrice) {
|
|
54997
|
+
return this.metadata.additionalInfo.truePrice;
|
|
54998
|
+
} else if (this.lstContract) {
|
|
54999
|
+
const result = await this.lstContract.call("convert_to_assets", [
|
|
55000
|
+
uint256_exports.bnToUint256(BigInt(1e18).toString())
|
|
55001
|
+
]);
|
|
55002
|
+
const truePrice = Number(BigInt(result.toString()) * BigInt(1e9) / BigInt(1e18)) / 1e9;
|
|
55003
|
+
return truePrice;
|
|
55004
|
+
}
|
|
55005
|
+
throw new Error("No true price available");
|
|
54652
55006
|
}
|
|
54653
55007
|
async getCurrentPrice(blockIdentifier = "pending") {
|
|
54654
55008
|
const poolKey = await this.getPoolKey(blockIdentifier);
|
|
54655
55009
|
return this._getCurrentPrice(poolKey, blockIdentifier);
|
|
54656
55010
|
}
|
|
54657
55011
|
async _getCurrentPrice(poolKey, blockIdentifier = "pending") {
|
|
54658
|
-
const priceInfo = await this.ekuboPositionsContract.call(
|
|
55012
|
+
const priceInfo = await this.ekuboPositionsContract.call(
|
|
55013
|
+
"get_pool_price",
|
|
55014
|
+
[
|
|
55015
|
+
{
|
|
55016
|
+
token0: poolKey.token0.address,
|
|
55017
|
+
token1: poolKey.token1.address,
|
|
55018
|
+
fee: poolKey.fee,
|
|
55019
|
+
tick_spacing: poolKey.tick_spacing,
|
|
55020
|
+
extension: poolKey.extension
|
|
55021
|
+
}
|
|
55022
|
+
],
|
|
54659
55023
|
{
|
|
54660
|
-
|
|
54661
|
-
token1: poolKey.token1.address,
|
|
54662
|
-
fee: poolKey.fee,
|
|
54663
|
-
tick_spacing: poolKey.tick_spacing,
|
|
54664
|
-
extension: poolKey.extension
|
|
55024
|
+
blockIdentifier
|
|
54665
55025
|
}
|
|
54666
|
-
|
|
54667
|
-
|
|
54668
|
-
|
|
54669
|
-
|
|
54670
|
-
console.log(
|
|
55026
|
+
);
|
|
55027
|
+
const sqrtRatio = _EkuboCLVault.div2Power128(
|
|
55028
|
+
BigInt(priceInfo.sqrt_ratio.toString())
|
|
55029
|
+
);
|
|
55030
|
+
console.log(
|
|
55031
|
+
`EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, sqrtRatio: ${sqrtRatio}, ${priceInfo.sqrt_ratio.toString()}`
|
|
55032
|
+
);
|
|
54671
55033
|
const price = sqrtRatio * sqrtRatio;
|
|
54672
|
-
const tick = _EkuboCLVault.priceToTick(
|
|
54673
|
-
|
|
55034
|
+
const tick = _EkuboCLVault.priceToTick(
|
|
55035
|
+
price,
|
|
55036
|
+
true,
|
|
55037
|
+
Number(poolKey.tick_spacing)
|
|
55038
|
+
);
|
|
55039
|
+
console.log(
|
|
55040
|
+
`EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, price: ${price}, tick: ${tick.mag}, ${tick.sign}`
|
|
55041
|
+
);
|
|
54674
55042
|
return {
|
|
54675
55043
|
price,
|
|
54676
55044
|
tick: tick.mag * (tick.sign == 0 ? 1 : -1),
|
|
@@ -54710,7 +55078,10 @@ var strkfarm_risk_engine = (() => {
|
|
|
54710
55078
|
};
|
|
54711
55079
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
54712
55080
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
54713
|
-
assert3(
|
|
55081
|
+
assert3(
|
|
55082
|
+
token0Info.decimals == token1Info.decimals,
|
|
55083
|
+
"Tested only for equal decimals"
|
|
55084
|
+
);
|
|
54714
55085
|
this.poolKey = poolKey;
|
|
54715
55086
|
return poolKey;
|
|
54716
55087
|
}
|
|
@@ -54734,11 +55105,18 @@ var strkfarm_risk_engine = (() => {
|
|
|
54734
55105
|
async _getExpectedAmountsForLiquidity(amount0, amount1, bounds, justUseInputAmount = true) {
|
|
54735
55106
|
assert3(amount0.greaterThan(0) || amount1.greaterThan(0), "Amount is 0");
|
|
54736
55107
|
const sampleLiq = 1e20;
|
|
54737
|
-
const { amount0: sampleAmount0, amount1: sampleAmount1 } = await this.getLiquidityToAmounts(
|
|
54738
|
-
|
|
55108
|
+
const { amount0: sampleAmount0, amount1: sampleAmount1 } = await this.getLiquidityToAmounts(
|
|
55109
|
+
Web3Number.fromWei(sampleLiq.toString(), 18),
|
|
55110
|
+
bounds
|
|
55111
|
+
);
|
|
55112
|
+
logger.verbose(
|
|
55113
|
+
`${_EkuboCLVault.name}: _getExpectedAmountsForLiquidity => sampleAmount0: ${sampleAmount0.toString()}, sampleAmount1: ${sampleAmount1.toString()}`
|
|
55114
|
+
);
|
|
54739
55115
|
assert3(!sampleAmount0.eq(0) || !sampleAmount1.eq(0), "Sample amount is 0");
|
|
54740
55116
|
const price = await (await this.getCurrentPrice()).price;
|
|
54741
|
-
logger.verbose(
|
|
55117
|
+
logger.verbose(
|
|
55118
|
+
`${_EkuboCLVault.name}: _getExpectedAmountsForLiquidity => price: ${price}`
|
|
55119
|
+
);
|
|
54742
55120
|
if (amount1.eq(0) && amount0.greaterThan(0)) {
|
|
54743
55121
|
if (sampleAmount1.eq(0)) {
|
|
54744
55122
|
return {
|
|
@@ -54768,12 +55146,22 @@ var strkfarm_risk_engine = (() => {
|
|
|
54768
55146
|
};
|
|
54769
55147
|
}
|
|
54770
55148
|
}
|
|
54771
|
-
assert3(
|
|
55149
|
+
assert3(
|
|
55150
|
+
sampleAmount0.decimals == sampleAmount1.decimals,
|
|
55151
|
+
"Sample amounts have different decimals"
|
|
55152
|
+
);
|
|
54772
55153
|
const ratioWeb3Number = sampleAmount0.multipliedBy(1e18).dividedBy(sampleAmount1.toString()).dividedBy(1e18);
|
|
54773
55154
|
const ratio = Number(ratioWeb3Number.toFixed(18));
|
|
54774
|
-
logger.verbose(
|
|
55155
|
+
logger.verbose(
|
|
55156
|
+
`${_EkuboCLVault.name}: ${this.metadata.name} => ratio: ${ratio.toString()}`
|
|
55157
|
+
);
|
|
54775
55158
|
if (justUseInputAmount)
|
|
54776
|
-
return this._solveExpectedAmountsEq(
|
|
55159
|
+
return this._solveExpectedAmountsEq(
|
|
55160
|
+
amount0,
|
|
55161
|
+
amount1,
|
|
55162
|
+
ratioWeb3Number,
|
|
55163
|
+
price
|
|
55164
|
+
);
|
|
54777
55165
|
if (amount1.eq(0) && amount0.greaterThan(0)) {
|
|
54778
55166
|
const _amount1 = amount0.dividedBy(ratioWeb3Number);
|
|
54779
55167
|
return {
|
|
@@ -54789,7 +55177,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
54789
55177
|
ratio
|
|
54790
55178
|
};
|
|
54791
55179
|
} else {
|
|
54792
|
-
throw new Error(
|
|
55180
|
+
throw new Error(
|
|
55181
|
+
"Both amounts are non-zero, cannot compute expected amounts"
|
|
55182
|
+
);
|
|
54793
55183
|
}
|
|
54794
55184
|
}
|
|
54795
55185
|
_solveExpectedAmountsEq(availableAmount0, availableAmount1, ratio, price) {
|
|
@@ -54806,34 +55196,65 @@ var strkfarm_risk_engine = (() => {
|
|
|
54806
55196
|
const erc20Mod = new ERC20(this.config);
|
|
54807
55197
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
54808
55198
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
54809
|
-
const token0Bal1 = await erc20Mod.balanceOf(
|
|
54810
|
-
|
|
54811
|
-
|
|
55199
|
+
const token0Bal1 = await erc20Mod.balanceOf(
|
|
55200
|
+
poolKey.token0,
|
|
55201
|
+
this.address.address,
|
|
55202
|
+
token0Info.decimals
|
|
55203
|
+
);
|
|
55204
|
+
const token1Bal1 = await erc20Mod.balanceOf(
|
|
55205
|
+
poolKey.token1,
|
|
55206
|
+
this.address.address,
|
|
55207
|
+
token1Info.decimals
|
|
55208
|
+
);
|
|
55209
|
+
logger.verbose(
|
|
55210
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal1: ${token0Bal1.toString()}, token1Bal1: ${token1Bal1.toString()}`
|
|
55211
|
+
);
|
|
54812
55212
|
const token0Price = await this.pricer.getPrice(token0Info.symbol);
|
|
54813
55213
|
const token1Price = await this.pricer.getPrice(token1Info.symbol);
|
|
54814
55214
|
const token0PriceUsd = token0Price.price * Number(token0Bal1.toFixed(13));
|
|
54815
55215
|
const token1PriceUsd = token1Price.price * Number(token1Bal1.toFixed(13));
|
|
54816
55216
|
if (token0PriceUsd > 1 && token1PriceUsd > 1) {
|
|
54817
|
-
throw new Error(
|
|
55217
|
+
throw new Error(
|
|
55218
|
+
"Both tokens are non-zero and above $1, call handle_fees first"
|
|
55219
|
+
);
|
|
54818
55220
|
}
|
|
54819
55221
|
let token0Bal = token0Bal1;
|
|
54820
55222
|
let token1Bal = token1Bal1;
|
|
54821
55223
|
if (considerRebalance) {
|
|
54822
|
-
logger.verbose(
|
|
55224
|
+
logger.verbose(
|
|
55225
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => considerRebalance: true`
|
|
55226
|
+
);
|
|
54823
55227
|
const tvl = await this.getTVL();
|
|
54824
55228
|
token0Bal = token0Bal.plus(tvl.token0.amount.toString());
|
|
54825
55229
|
token1Bal = token1Bal.plus(tvl.token1.amount.toString());
|
|
54826
55230
|
} else {
|
|
54827
|
-
logger.verbose(
|
|
55231
|
+
logger.verbose(
|
|
55232
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => considerRebalance: false`
|
|
55233
|
+
);
|
|
54828
55234
|
}
|
|
54829
|
-
logger.verbose(
|
|
55235
|
+
logger.verbose(
|
|
55236
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`
|
|
55237
|
+
);
|
|
54830
55238
|
const newBounds = await this.getNewBounds();
|
|
54831
|
-
logger.verbose(
|
|
54832
|
-
|
|
55239
|
+
logger.verbose(
|
|
55240
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newBounds: ${newBounds.lowerTick}, ${newBounds.upperTick}`
|
|
55241
|
+
);
|
|
55242
|
+
return await this.getSwapInfoGivenAmounts(
|
|
55243
|
+
poolKey,
|
|
55244
|
+
token0Bal,
|
|
55245
|
+
token1Bal,
|
|
55246
|
+
newBounds
|
|
55247
|
+
);
|
|
54833
55248
|
}
|
|
54834
55249
|
async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds) {
|
|
54835
|
-
let expectedAmounts = await this._getExpectedAmountsForLiquidity(
|
|
54836
|
-
|
|
55250
|
+
let expectedAmounts = await this._getExpectedAmountsForLiquidity(
|
|
55251
|
+
token0Bal,
|
|
55252
|
+
token1Bal,
|
|
55253
|
+
bounds
|
|
55254
|
+
);
|
|
55255
|
+
logger.verbose(
|
|
55256
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`
|
|
55257
|
+
);
|
|
54837
55258
|
let retry = 0;
|
|
54838
55259
|
const maxRetry = 10;
|
|
54839
55260
|
while (retry < maxRetry) {
|
|
@@ -54850,9 +55271,15 @@ var strkfarm_risk_engine = (() => {
|
|
|
54850
55271
|
const remainingSellAmount = tokenToSell == poolKey.token0 ? expectedAmounts.amount0 : expectedAmounts.amount1;
|
|
54851
55272
|
const tokenToBuyInfo = await Global.getTokenInfoFromAddr(tokenToBuy);
|
|
54852
55273
|
const expectedRatio = expectedAmounts.ratio;
|
|
54853
|
-
logger.verbose(
|
|
54854
|
-
|
|
54855
|
-
|
|
55274
|
+
logger.verbose(
|
|
55275
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => tokenToSell: ${tokenToSell.address}, tokenToBuy: ${tokenToBuy.address}, amountToSell: ${amountToSell.toWei()}`
|
|
55276
|
+
);
|
|
55277
|
+
logger.verbose(
|
|
55278
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => remainingSellAmount: ${remainingSellAmount.toString()}`
|
|
55279
|
+
);
|
|
55280
|
+
logger.verbose(
|
|
55281
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedRatio: ${expectedRatio}`
|
|
55282
|
+
);
|
|
54856
55283
|
if (amountToSell.eq(0)) {
|
|
54857
55284
|
return {
|
|
54858
55285
|
token_from_address: tokenToSell.address,
|
|
@@ -54866,23 +55293,62 @@ var strkfarm_risk_engine = (() => {
|
|
|
54866
55293
|
routes: []
|
|
54867
55294
|
};
|
|
54868
55295
|
}
|
|
54869
|
-
const quote = await this.avnu.getQuotes(
|
|
55296
|
+
const quote = await this.avnu.getQuotes(
|
|
55297
|
+
tokenToSell.address,
|
|
55298
|
+
tokenToBuy.address,
|
|
55299
|
+
amountToSell.toWei(),
|
|
55300
|
+
this.address.address
|
|
55301
|
+
);
|
|
54870
55302
|
if (remainingSellAmount.eq(0)) {
|
|
54871
|
-
const minAmountOut = Web3Number.fromWei(
|
|
54872
|
-
|
|
55303
|
+
const minAmountOut = Web3Number.fromWei(
|
|
55304
|
+
quote.buyAmount.toString(),
|
|
55305
|
+
tokenToBuyInfo.decimals
|
|
55306
|
+
).multipliedBy(0.9999);
|
|
55307
|
+
return await this.avnu.getSwapInfo(
|
|
55308
|
+
quote,
|
|
55309
|
+
this.address.address,
|
|
55310
|
+
0,
|
|
55311
|
+
this.address.address,
|
|
55312
|
+
minAmountOut.toWei()
|
|
55313
|
+
);
|
|
54873
55314
|
}
|
|
54874
|
-
const amountOut = Web3Number.fromWei(
|
|
55315
|
+
const amountOut = Web3Number.fromWei(
|
|
55316
|
+
quote.buyAmount.toString(),
|
|
55317
|
+
tokenToBuyInfo.decimals
|
|
55318
|
+
);
|
|
54875
55319
|
const swapPrice = tokenToSell == poolKey.token0 ? amountOut.dividedBy(amountToSell) : amountToSell.dividedBy(amountOut);
|
|
54876
55320
|
const newRatio = tokenToSell == poolKey.token0 ? remainingSellAmount.dividedBy(token1Bal.plus(amountOut)) : token0Bal.plus(amountOut).dividedBy(remainingSellAmount);
|
|
54877
|
-
logger.verbose(
|
|
54878
|
-
|
|
54879
|
-
|
|
55321
|
+
logger.verbose(
|
|
55322
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => amountOut: ${amountOut.toString()}`
|
|
55323
|
+
);
|
|
55324
|
+
logger.verbose(
|
|
55325
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => swapPrice: ${swapPrice.toString()}`
|
|
55326
|
+
);
|
|
55327
|
+
logger.verbose(
|
|
55328
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newRatio: ${newRatio.toString()}`
|
|
55329
|
+
);
|
|
54880
55330
|
if (Number(newRatio.toString()) > expectedRatio * 1.0000001 || Number(newRatio.toString()) < expectedRatio * 0.9999999) {
|
|
54881
|
-
expectedAmounts = await this._solveExpectedAmountsEq(
|
|
54882
|
-
|
|
55331
|
+
expectedAmounts = await this._solveExpectedAmountsEq(
|
|
55332
|
+
token0Bal,
|
|
55333
|
+
token1Bal,
|
|
55334
|
+
new Web3Number(Number(expectedRatio).toFixed(13), 18),
|
|
55335
|
+
Number(swapPrice.toString())
|
|
55336
|
+
);
|
|
55337
|
+
logger.verbose(
|
|
55338
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`
|
|
55339
|
+
);
|
|
54883
55340
|
} else {
|
|
54884
|
-
const minAmountOut = Web3Number.fromWei(
|
|
54885
|
-
|
|
55341
|
+
const minAmountOut = Web3Number.fromWei(
|
|
55342
|
+
quote.buyAmount.toString(),
|
|
55343
|
+
tokenToBuyInfo.decimals
|
|
55344
|
+
).multipliedBy(0.9999);
|
|
55345
|
+
return await this.avnu.getSwapInfo(
|
|
55346
|
+
quote,
|
|
55347
|
+
this.address.address,
|
|
55348
|
+
0,
|
|
55349
|
+
this.address.address,
|
|
55350
|
+
minAmountOut.toWei()
|
|
55351
|
+
);
|
|
54886
55352
|
}
|
|
54887
55353
|
retry++;
|
|
54888
55354
|
}
|
|
@@ -54891,8 +55357,8 @@ var strkfarm_risk_engine = (() => {
|
|
|
54891
55357
|
/**
|
|
54892
55358
|
* Attempts to rebalance the vault by iteratively adjusting swap amounts if initial attempt fails.
|
|
54893
55359
|
* Uses binary search approach to find optimal swap amount.
|
|
54894
|
-
*
|
|
54895
|
-
* @param newBounds - The new tick bounds to rebalance to
|
|
55360
|
+
*
|
|
55361
|
+
* @param newBounds - The new tick bounds to rebalance to
|
|
54896
55362
|
* @param swapInfo - Initial swap parameters for rebalancing
|
|
54897
55363
|
* @param acc - Account to estimate gas fees with
|
|
54898
55364
|
* @param retry - Current retry attempt number (default 0)
|
|
@@ -54919,7 +55385,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
54919
55385
|
logger.error(`Rebalance failed after ${MAX_RETRIES} retries`);
|
|
54920
55386
|
throw err2;
|
|
54921
55387
|
}
|
|
54922
|
-
logger.error(
|
|
55388
|
+
logger.error(
|
|
55389
|
+
`Rebalance attempt ${retry + 1} failed, adjusting swap amount...`
|
|
55390
|
+
);
|
|
54923
55391
|
const newSwapInfo = { ...swapInfo };
|
|
54924
55392
|
const currentAmount = Web3Number.fromWei(fromAmount.toString(), 18);
|
|
54925
55393
|
logger.verbose(`Current amount: ${currentAmount.toString()}`);
|
|
@@ -55011,23 +55479,39 @@ var strkfarm_risk_engine = (() => {
|
|
|
55011
55479
|
const currentPrice = _currentPrice || await this.getCurrentPrice(blockIdentifier);
|
|
55012
55480
|
const lowerPrice = _EkuboCLVault.tickToPrice(bounds.lowerTick);
|
|
55013
55481
|
const upperPrice = _EkuboCLVault.tickToPrice(bounds.upperTick);
|
|
55014
|
-
logger.verbose(
|
|
55015
|
-
|
|
55016
|
-
|
|
55482
|
+
logger.verbose(
|
|
55483
|
+
`${_EkuboCLVault.name}: getLiquidityToAmounts => currentPrice: ${currentPrice.price}, lowerPrice: ${lowerPrice}, upperPrice: ${upperPrice}`
|
|
55484
|
+
);
|
|
55485
|
+
const result = await this.ekuboMathContract.call(
|
|
55486
|
+
"liquidity_delta_to_amount_delta",
|
|
55487
|
+
[
|
|
55488
|
+
uint256_exports.bnToUint256(currentPrice.sqrtRatio),
|
|
55489
|
+
{
|
|
55490
|
+
mag: liquidity.toWei(),
|
|
55491
|
+
sign: 0
|
|
55492
|
+
},
|
|
55493
|
+
uint256_exports.bnToUint256(
|
|
55494
|
+
_EkuboCLVault.priceToSqrtRatio(lowerPrice).toString()
|
|
55495
|
+
),
|
|
55496
|
+
uint256_exports.bnToUint256(
|
|
55497
|
+
_EkuboCLVault.priceToSqrtRatio(upperPrice).toString()
|
|
55498
|
+
)
|
|
55499
|
+
],
|
|
55017
55500
|
{
|
|
55018
|
-
|
|
55019
|
-
|
|
55020
|
-
|
|
55021
|
-
uint256_exports.bnToUint256(_EkuboCLVault.priceToSqrtRatio(lowerPrice).toString()),
|
|
55022
|
-
uint256_exports.bnToUint256(_EkuboCLVault.priceToSqrtRatio(upperPrice).toString())
|
|
55023
|
-
], {
|
|
55024
|
-
blockIdentifier
|
|
55025
|
-
});
|
|
55501
|
+
blockIdentifier
|
|
55502
|
+
}
|
|
55503
|
+
);
|
|
55026
55504
|
const poolKey = _poolKey || await this.getPoolKey(blockIdentifier);
|
|
55027
55505
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
55028
55506
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
55029
|
-
const amount0 = Web3Number.fromWei(
|
|
55030
|
-
|
|
55507
|
+
const amount0 = Web3Number.fromWei(
|
|
55508
|
+
_EkuboCLVault.i129ToNumber(result.amount0).toString(),
|
|
55509
|
+
token0Info.decimals
|
|
55510
|
+
);
|
|
55511
|
+
const amount1 = Web3Number.fromWei(
|
|
55512
|
+
_EkuboCLVault.i129ToNumber(result.amount1).toString(),
|
|
55513
|
+
token1Info.decimals
|
|
55514
|
+
);
|
|
55031
55515
|
return {
|
|
55032
55516
|
amount0,
|
|
55033
55517
|
amount1
|
|
@@ -55035,7 +55519,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
55035
55519
|
}
|
|
55036
55520
|
async harvest(acc) {
|
|
55037
55521
|
const ekuboHarvests = new EkuboHarvests(this.config);
|
|
55038
|
-
const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(
|
|
55522
|
+
const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(
|
|
55523
|
+
this.address
|
|
55524
|
+
);
|
|
55039
55525
|
const poolKey = await this.getPoolKey();
|
|
55040
55526
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
55041
55527
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
@@ -55045,18 +55531,38 @@ var strkfarm_risk_engine = (() => {
|
|
|
55045
55531
|
const fee = claim.claim.amount.multipliedBy(this.metadata.additionalInfo.feeBps).dividedBy(1e4);
|
|
55046
55532
|
const postFeeAmount = claim.claim.amount.minus(fee);
|
|
55047
55533
|
const isToken1 = claim.token.eq(poolKey.token1);
|
|
55048
|
-
logger.verbose(
|
|
55534
|
+
logger.verbose(
|
|
55535
|
+
`${_EkuboCLVault.name}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`
|
|
55536
|
+
);
|
|
55049
55537
|
const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
|
|
55050
55538
|
const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
|
|
55051
|
-
logger.verbose(
|
|
55052
|
-
|
|
55539
|
+
logger.verbose(
|
|
55540
|
+
`${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
|
|
55541
|
+
);
|
|
55542
|
+
const swapInfo = await this.getSwapInfoGivenAmounts(
|
|
55543
|
+
poolKey,
|
|
55544
|
+
token0Amt,
|
|
55545
|
+
token1Amt,
|
|
55546
|
+
bounds
|
|
55547
|
+
);
|
|
55053
55548
|
swapInfo.token_to_address = token0Info.address.address;
|
|
55054
|
-
logger.verbose(
|
|
55055
|
-
|
|
55549
|
+
logger.verbose(
|
|
55550
|
+
`${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
|
|
55551
|
+
);
|
|
55552
|
+
logger.verbose(
|
|
55553
|
+
`${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
|
|
55554
|
+
);
|
|
55056
55555
|
const harvestEstimateCall = async (swapInfo1) => {
|
|
55057
|
-
const swap1Amount = Web3Number.fromWei(
|
|
55556
|
+
const swap1Amount = Web3Number.fromWei(
|
|
55557
|
+
uint256_exports.uint256ToBN(swapInfo1.token_from_amount).toString(),
|
|
55558
|
+
18
|
|
55559
|
+
// cause its always STRK?
|
|
55560
|
+
);
|
|
55058
55561
|
const remainingAmount = postFeeAmount.minus(swap1Amount);
|
|
55059
|
-
const swapInfo2 = {
|
|
55562
|
+
const swapInfo2 = {
|
|
55563
|
+
...swapInfo,
|
|
55564
|
+
token_from_amount: uint256_exports.bnToUint256(remainingAmount.toWei())
|
|
55565
|
+
};
|
|
55060
55566
|
swapInfo2.token_to_address = token1Info.address.address;
|
|
55061
55567
|
const calldata = [
|
|
55062
55568
|
claim.rewardsContract.address,
|
|
@@ -55069,11 +55575,23 @@ var strkfarm_risk_engine = (() => {
|
|
|
55069
55575
|
swapInfo,
|
|
55070
55576
|
swapInfo2
|
|
55071
55577
|
];
|
|
55072
|
-
logger.verbose(
|
|
55578
|
+
logger.verbose(
|
|
55579
|
+
`${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
|
|
55580
|
+
calldata
|
|
55581
|
+
)}`
|
|
55582
|
+
);
|
|
55073
55583
|
return [this.contract.populate("harvest", calldata)];
|
|
55074
55584
|
};
|
|
55075
|
-
const _callsFinal = await this.rebalanceIter(
|
|
55076
|
-
|
|
55585
|
+
const _callsFinal = await this.rebalanceIter(
|
|
55586
|
+
swapInfo,
|
|
55587
|
+
acc,
|
|
55588
|
+
harvestEstimateCall
|
|
55589
|
+
);
|
|
55590
|
+
logger.verbose(
|
|
55591
|
+
`${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
|
|
55592
|
+
_callsFinal
|
|
55593
|
+
)}`
|
|
55594
|
+
);
|
|
55077
55595
|
calls.push(..._callsFinal);
|
|
55078
55596
|
}
|
|
55079
55597
|
return calls;
|
|
@@ -55083,24 +55601,37 @@ var strkfarm_risk_engine = (() => {
|
|
|
55083
55601
|
const poolKey = await this.getPoolKey();
|
|
55084
55602
|
const linkedFlow = {
|
|
55085
55603
|
title: this.metadata.name,
|
|
55086
|
-
subItems: [
|
|
55604
|
+
subItems: [
|
|
55605
|
+
{
|
|
55606
|
+
key: "Pool",
|
|
55607
|
+
value: `${(_EkuboCLVault.div2Power128(BigInt(poolKey.fee)) * 100).toFixed(2)}%, ${poolKey.tick_spacing} tick spacing`
|
|
55608
|
+
}
|
|
55609
|
+
],
|
|
55087
55610
|
linkedFlows: [],
|
|
55088
55611
|
style: { backgroundColor: "#35484f" /* Blue */.valueOf() }
|
|
55089
55612
|
};
|
|
55090
55613
|
const baseFlow = {
|
|
55091
55614
|
id: "base",
|
|
55092
55615
|
title: "Your Deposit",
|
|
55093
|
-
subItems: [
|
|
55616
|
+
subItems: [
|
|
55617
|
+
{ key: `Net yield`, value: `${(netYield * 100).toFixed(2)}%` },
|
|
55618
|
+
{
|
|
55619
|
+
key: `Performance Fee`,
|
|
55620
|
+
value: `${(this.metadata.additionalInfo.feeBps / 100).toFixed(2)}%`
|
|
55621
|
+
}
|
|
55622
|
+
],
|
|
55094
55623
|
linkedFlows: [linkedFlow],
|
|
55095
55624
|
style: { backgroundColor: "#6e53dc" /* Purple */.valueOf() }
|
|
55096
55625
|
};
|
|
55097
55626
|
const rebalanceFlow = {
|
|
55098
55627
|
id: "rebalance",
|
|
55099
55628
|
title: "Automated Rebalance",
|
|
55100
|
-
subItems: [
|
|
55101
|
-
|
|
55102
|
-
|
|
55103
|
-
|
|
55629
|
+
subItems: [
|
|
55630
|
+
{
|
|
55631
|
+
key: "Range selection",
|
|
55632
|
+
value: `${this.metadata.additionalInfo.newBounds.lower * Number(poolKey.tick_spacing)} to ${this.metadata.additionalInfo.newBounds.upper * Number(poolKey.tick_spacing)} ticks`
|
|
55633
|
+
}
|
|
55634
|
+
],
|
|
55104
55635
|
linkedFlows: [linkedFlow],
|
|
55105
55636
|
style: { backgroundColor: "purple" /* Green */.valueOf() }
|
|
55106
55637
|
};
|
|
@@ -55108,43 +55639,145 @@ var strkfarm_risk_engine = (() => {
|
|
|
55108
55639
|
}
|
|
55109
55640
|
};
|
|
55110
55641
|
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 = {
|
|
55642
|
+
var _protocol2 = {
|
|
55643
|
+
name: "Ekubo",
|
|
55644
|
+
logo: "https://app.ekubo.org/favicon.ico"
|
|
55645
|
+
};
|
|
55112
55646
|
var _riskFactor2 = [
|
|
55113
55647
|
{ type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 0.5, weight: 25 },
|
|
55114
55648
|
{ type: "Impermanent Loss Risk" /* IMPERMANENT_LOSS */, value: 1, weight: 75 }
|
|
55115
55649
|
];
|
|
55650
|
+
var _riskFactorStable = [
|
|
55651
|
+
{ type: "Smart Contract Risk" /* SMART_CONTRACT_RISK */, value: 0.5, weight: 25 }
|
|
55652
|
+
];
|
|
55116
55653
|
var AUDIT_URL2 = "https://assets.strkfarm.com/strkfarm/audit_report_vesu_and_ekubo_strats.pdf";
|
|
55117
|
-
var
|
|
55118
|
-
|
|
55119
|
-
|
|
55120
|
-
|
|
55121
|
-
|
|
55122
|
-
|
|
55123
|
-
|
|
55654
|
+
var faqs2 = [
|
|
55655
|
+
{
|
|
55656
|
+
question: "What is the Ekubo CL Vault strategy?",
|
|
55657
|
+
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."
|
|
55658
|
+
},
|
|
55659
|
+
{
|
|
55660
|
+
question: "How are trading fees and rewards handled?",
|
|
55661
|
+
answer: "Trading fees and DeFi Spring rewards are automatically compounded back into the strategy, increasing your overall returns."
|
|
55662
|
+
},
|
|
55663
|
+
{
|
|
55664
|
+
question: "What happens during withdrawal?",
|
|
55665
|
+
answer: "During withdrawal, you may receive either or both tokens depending on market conditions and prevailing prices."
|
|
55666
|
+
},
|
|
55667
|
+
{
|
|
55668
|
+
question: "Is the strategy audited?",
|
|
55669
|
+
answer: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
55670
|
+
"Yes, the strategy has been audited. You can review the audit report in our docs ",
|
|
55671
|
+
/* @__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" }),
|
|
55672
|
+
"."
|
|
55124
55673
|
] })
|
|
55125
|
-
|
|
55126
|
-
|
|
55127
|
-
|
|
55128
|
-
|
|
55129
|
-
|
|
55130
|
-
|
|
55131
|
-
|
|
55132
|
-
|
|
55133
|
-
|
|
55134
|
-
|
|
55135
|
-
|
|
55136
|
-
|
|
55137
|
-
|
|
55138
|
-
|
|
55139
|
-
|
|
55140
|
-
|
|
55141
|
-
|
|
55142
|
-
|
|
55674
|
+
}
|
|
55675
|
+
];
|
|
55676
|
+
var EkuboCLVaultStrategies = [
|
|
55677
|
+
{
|
|
55678
|
+
name: "Ekubo xSTRK/STRK",
|
|
55679
|
+
description: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
55680
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: _description2.replace("{{POOL_NAME}}", "xSTRK/STRK") }),
|
|
55681
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
55682
|
+
"ul",
|
|
55683
|
+
{
|
|
55684
|
+
style: {
|
|
55685
|
+
marginLeft: "20px",
|
|
55686
|
+
listStyle: "circle",
|
|
55687
|
+
fontSize: "12px"
|
|
55688
|
+
},
|
|
55689
|
+
children: [
|
|
55690
|
+
/* @__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." }),
|
|
55691
|
+
/* @__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." })
|
|
55692
|
+
]
|
|
55693
|
+
}
|
|
55694
|
+
)
|
|
55695
|
+
] }),
|
|
55696
|
+
address: ContractAddr.from(
|
|
55697
|
+
"0x01f083b98674bc21effee29ef443a00c7b9a500fd92cf30341a3da12c73f2324"
|
|
55698
|
+
),
|
|
55699
|
+
launchBlock: 1209881,
|
|
55700
|
+
type: "Other",
|
|
55701
|
+
// must be same order as poolKey token0 and token1
|
|
55702
|
+
depositTokens: [
|
|
55703
|
+
Global.getDefaultTokens().find((t) => t.symbol === "xSTRK"),
|
|
55704
|
+
Global.getDefaultTokens().find((t) => t.symbol === "STRK")
|
|
55705
|
+
],
|
|
55706
|
+
protocols: [_protocol2],
|
|
55707
|
+
auditUrl: AUDIT_URL2,
|
|
55708
|
+
maxTVL: Web3Number.fromWei("0", 18),
|
|
55709
|
+
risk: {
|
|
55710
|
+
riskFactor: _riskFactor2,
|
|
55711
|
+
netRisk: _riskFactor2.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactor2.reduce((acc, curr) => acc + curr.weight, 0),
|
|
55712
|
+
notARisks: getNoRiskTags(_riskFactor2)
|
|
55713
|
+
},
|
|
55714
|
+
apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
|
|
55715
|
+
additionalInfo: {
|
|
55716
|
+
newBounds: {
|
|
55717
|
+
lower: -1,
|
|
55718
|
+
upper: 1
|
|
55719
|
+
},
|
|
55720
|
+
lstContract: ContractAddr.from(
|
|
55721
|
+
"0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a"
|
|
55722
|
+
),
|
|
55723
|
+
feeBps: 1e3
|
|
55724
|
+
},
|
|
55725
|
+
faqs: [
|
|
55726
|
+
...faqs2,
|
|
55727
|
+
{
|
|
55728
|
+
question: "Why might I see a negative APY?",
|
|
55729
|
+
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."
|
|
55730
|
+
}
|
|
55731
|
+
]
|
|
55732
|
+
},
|
|
55733
|
+
{
|
|
55734
|
+
name: "Ekubo USDC/USDT",
|
|
55735
|
+
description: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
55736
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: _description2.replace("{{POOL_NAME}}", "USDC/USDT") }),
|
|
55737
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
55738
|
+
"ul",
|
|
55739
|
+
{
|
|
55740
|
+
style: {
|
|
55741
|
+
marginLeft: "20px",
|
|
55742
|
+
listStyle: "circle",
|
|
55743
|
+
fontSize: "12px"
|
|
55744
|
+
},
|
|
55745
|
+
children: /* @__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." })
|
|
55746
|
+
}
|
|
55747
|
+
)
|
|
55748
|
+
] }),
|
|
55749
|
+
address: ContractAddr.from(
|
|
55750
|
+
"0xd647ed735f0db52f2a5502b6e06ed21dc4284a43a36af4b60d3c80fbc56c91"
|
|
55751
|
+
),
|
|
55752
|
+
launchBlock: 1385576,
|
|
55753
|
+
type: "Other",
|
|
55754
|
+
// must be same order as poolKey token0 and token1
|
|
55755
|
+
depositTokens: [
|
|
55756
|
+
Global.getDefaultTokens().find((t) => t.symbol === "USDC"),
|
|
55757
|
+
Global.getDefaultTokens().find((t) => t.symbol === "USDT")
|
|
55758
|
+
],
|
|
55759
|
+
protocols: [_protocol2],
|
|
55760
|
+
auditUrl: AUDIT_URL2,
|
|
55761
|
+
maxTVL: Web3Number.fromWei("0", 6),
|
|
55762
|
+
risk: {
|
|
55763
|
+
riskFactor: _riskFactorStable,
|
|
55764
|
+
netRisk: _riskFactorStable.reduce((acc, curr) => acc + curr.value * curr.weight, 0) / _riskFactorStable.reduce((acc, curr) => acc + curr.weight, 0),
|
|
55765
|
+
notARisks: getNoRiskTags(_riskFactorStable)
|
|
55766
|
+
},
|
|
55767
|
+
apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
|
|
55768
|
+
additionalInfo: {
|
|
55769
|
+
newBounds: {
|
|
55770
|
+
lower: -1,
|
|
55771
|
+
upper: 1
|
|
55772
|
+
},
|
|
55773
|
+
truePrice: 1,
|
|
55774
|
+
feeBps: 1e3
|
|
55143
55775
|
},
|
|
55144
|
-
|
|
55145
|
-
|
|
55776
|
+
faqs: [
|
|
55777
|
+
...faqs2
|
|
55778
|
+
]
|
|
55146
55779
|
}
|
|
55147
|
-
|
|
55780
|
+
];
|
|
55148
55781
|
return __toCommonJS(index_browser_exports);
|
|
55149
55782
|
})();
|
|
55150
55783
|
/*! Bundled license information:
|