@strkfarm/sdk 1.0.40 → 1.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.browser.global.js +138 -54
- package/dist/index.browser.mjs +138 -54
- package/dist/index.d.ts +18 -0
- package/dist/index.js +138 -54
- package/dist/index.mjs +138 -54
- package/package.json +1 -1
- package/src/modules/avnu.ts +18 -0
- package/src/strategies/ekubo-cl-vault.tsx +197 -79
|
@@ -38168,6 +38168,19 @@ var strkfarm_risk_engine = (() => {
|
|
|
38168
38168
|
};
|
|
38169
38169
|
return swapInfo;
|
|
38170
38170
|
}
|
|
38171
|
+
static buildZeroSwap(tokenToSell, address) {
|
|
38172
|
+
return {
|
|
38173
|
+
token_from_address: tokenToSell.address,
|
|
38174
|
+
token_from_amount: uint256_exports.bnToUint256(0),
|
|
38175
|
+
token_to_address: tokenToSell.address,
|
|
38176
|
+
token_to_amount: uint256_exports.bnToUint256(0),
|
|
38177
|
+
token_to_min_amount: uint256_exports.bnToUint256(0),
|
|
38178
|
+
beneficiary: address,
|
|
38179
|
+
integrator_fee_amount_bps: 0,
|
|
38180
|
+
integrator_fee_recipient: address,
|
|
38181
|
+
routes: []
|
|
38182
|
+
};
|
|
38183
|
+
}
|
|
38171
38184
|
};
|
|
38172
38185
|
|
|
38173
38186
|
// src/interfaces/common.ts
|
|
@@ -54789,7 +54802,10 @@ var strkfarm_risk_engine = (() => {
|
|
|
54789
54802
|
const priceNow = await this.getCurrentPrice(blockIdentifier);
|
|
54790
54803
|
let blockNow = typeof blockIdentifier == "number" ? blockIdentifier : (await this.config.provider.getBlockLatestAccepted()).block_number;
|
|
54791
54804
|
const blockNowTime = typeof blockIdentifier == "number" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
|
|
54792
|
-
const blockBefore = Math.max(
|
|
54805
|
+
const blockBefore = Math.max(
|
|
54806
|
+
blockNow - sinceBlocks,
|
|
54807
|
+
this.metadata.launchBlock
|
|
54808
|
+
);
|
|
54793
54809
|
const adjustedSupplyNow = supplyNow.minus(
|
|
54794
54810
|
await this.getHarvestRewardShares(blockBefore, blockNow)
|
|
54795
54811
|
);
|
|
@@ -55182,14 +55198,24 @@ var strkfarm_risk_engine = (() => {
|
|
|
55182
55198
|
_solveExpectedAmountsEq(availableAmount0, availableAmount1, ratio, price) {
|
|
55183
55199
|
const y = ratio.multipliedBy(availableAmount1).minus(availableAmount0).dividedBy(ratio.plus(1 / price));
|
|
55184
55200
|
const x = y.dividedBy(price);
|
|
55201
|
+
logger.verbose(
|
|
55202
|
+
`${_EkuboCLVault.name}: _solveExpectedAmountsEq => x: ${x.toString()}, y: ${y.toString()}, amount0: ${availableAmount0.toString()}, amount1: ${availableAmount1.toString()}`
|
|
55203
|
+
);
|
|
55204
|
+
if (ratio.eq(0)) {
|
|
55205
|
+
return {
|
|
55206
|
+
amount0: Web3Number.fromWei("0", availableAmount0.decimals),
|
|
55207
|
+
amount1: availableAmount1.minus(y),
|
|
55208
|
+
ratio: 0
|
|
55209
|
+
};
|
|
55210
|
+
}
|
|
55185
55211
|
return {
|
|
55186
55212
|
amount0: availableAmount0.plus(x),
|
|
55187
55213
|
amount1: availableAmount1.minus(y),
|
|
55188
55214
|
ratio: Number(ratio.toString())
|
|
55189
55215
|
};
|
|
55190
55216
|
}
|
|
55191
|
-
async
|
|
55192
|
-
const poolKey = await this.getPoolKey();
|
|
55217
|
+
async unusedBalances(_poolKey) {
|
|
55218
|
+
const poolKey = _poolKey || await this.getPoolKey();
|
|
55193
55219
|
const erc20Mod = new ERC20(this.config);
|
|
55194
55220
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
55195
55221
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
@@ -55210,11 +55236,24 @@ var strkfarm_risk_engine = (() => {
|
|
|
55210
55236
|
const token1Price = await this.pricer.getPrice(token1Info.symbol);
|
|
55211
55237
|
const token0PriceUsd = token0Price.price * Number(token0Bal1.toFixed(13));
|
|
55212
55238
|
const token1PriceUsd = token1Price.price * Number(token1Bal1.toFixed(13));
|
|
55213
|
-
|
|
55214
|
-
|
|
55215
|
-
|
|
55216
|
-
|
|
55217
|
-
|
|
55239
|
+
return {
|
|
55240
|
+
token0: {
|
|
55241
|
+
amount: token0Bal1,
|
|
55242
|
+
tokenInfo: token0Info,
|
|
55243
|
+
usdValue: token0PriceUsd
|
|
55244
|
+
},
|
|
55245
|
+
token1: {
|
|
55246
|
+
amount: token1Bal1,
|
|
55247
|
+
tokenInfo: token1Info,
|
|
55248
|
+
usdValue: token1PriceUsd
|
|
55249
|
+
}
|
|
55250
|
+
};
|
|
55251
|
+
}
|
|
55252
|
+
async getSwapInfoToHandleUnused(considerRebalance = true) {
|
|
55253
|
+
const poolKey = await this.getPoolKey();
|
|
55254
|
+
const unusedBalances = await this.unusedBalances(poolKey);
|
|
55255
|
+
const { amount: token0Bal1, usdValue: token0PriceUsd } = unusedBalances.token0;
|
|
55256
|
+
const { amount: token1Bal1, usdValue: token1PriceUsd } = unusedBalances.token1;
|
|
55218
55257
|
let token0Bal = token0Bal1;
|
|
55219
55258
|
let token1Bal = token1Bal1;
|
|
55220
55259
|
if (considerRebalance) {
|
|
@@ -55232,63 +55271,71 @@ var strkfarm_risk_engine = (() => {
|
|
|
55232
55271
|
logger.verbose(
|
|
55233
55272
|
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`
|
|
55234
55273
|
);
|
|
55235
|
-
|
|
55274
|
+
let ekuboBounds;
|
|
55275
|
+
if (considerRebalance) {
|
|
55276
|
+
ekuboBounds = await this.getNewBounds();
|
|
55277
|
+
} else {
|
|
55278
|
+
ekuboBounds = await this.getCurrentBounds();
|
|
55279
|
+
}
|
|
55236
55280
|
logger.verbose(
|
|
55237
|
-
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newBounds: ${
|
|
55281
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newBounds: ${ekuboBounds.lowerTick}, ${ekuboBounds.upperTick}`
|
|
55238
55282
|
);
|
|
55239
55283
|
return await this.getSwapInfoGivenAmounts(
|
|
55240
55284
|
poolKey,
|
|
55241
55285
|
token0Bal,
|
|
55242
55286
|
token1Bal,
|
|
55243
|
-
|
|
55287
|
+
ekuboBounds
|
|
55244
55288
|
);
|
|
55245
55289
|
}
|
|
55246
55290
|
async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds) {
|
|
55291
|
+
logger.verbose(
|
|
55292
|
+
`${_EkuboCLVault.name}: getSwapInfoGivenAmounts::pre => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`
|
|
55293
|
+
);
|
|
55247
55294
|
let expectedAmounts = await this._getExpectedAmountsForLiquidity(
|
|
55248
55295
|
token0Bal,
|
|
55249
55296
|
token1Bal,
|
|
55250
55297
|
bounds
|
|
55251
55298
|
);
|
|
55252
55299
|
logger.verbose(
|
|
55253
|
-
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused =>
|
|
55300
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts2: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`
|
|
55254
55301
|
);
|
|
55255
55302
|
let retry = 0;
|
|
55256
55303
|
const maxRetry = 10;
|
|
55257
|
-
|
|
55258
|
-
|
|
55259
|
-
if (expectedAmounts.amount0.lessThan(token0Bal) && expectedAmounts.amount1.lessThan(token1Bal)) {
|
|
55304
|
+
function assertValidAmounts(expectedAmounts2, token0Bal2, token1Bal2) {
|
|
55305
|
+
if (expectedAmounts2.amount0.lessThan(token0Bal2) && expectedAmounts2.amount1.lessThan(token1Bal2)) {
|
|
55260
55306
|
throw new Error("Both tokens are decreased, something is wrong");
|
|
55261
55307
|
}
|
|
55262
|
-
if (
|
|
55308
|
+
if (expectedAmounts2.amount0.greaterThan(token0Bal2) && expectedAmounts2.amount1.greaterThan(token1Bal2)) {
|
|
55263
55309
|
throw new Error("Both tokens are increased, something is wrong");
|
|
55264
55310
|
}
|
|
55265
|
-
|
|
55266
|
-
|
|
55267
|
-
|
|
55268
|
-
const
|
|
55269
|
-
const
|
|
55270
|
-
const
|
|
55271
|
-
|
|
55272
|
-
|
|
55273
|
-
|
|
55311
|
+
}
|
|
55312
|
+
function getSwapParams(expectedAmounts2, poolKey2, token0Bal2, token1Bal2) {
|
|
55313
|
+
const tokenToSell = expectedAmounts2.amount0.lessThan(token0Bal2) ? poolKey2.token0 : poolKey2.token1;
|
|
55314
|
+
const tokenToBuy = tokenToSell == poolKey2.token0 ? poolKey2.token1 : poolKey2.token0;
|
|
55315
|
+
const amountToSell = tokenToSell == poolKey2.token0 ? token0Bal2.minus(expectedAmounts2.amount0) : token1Bal2.minus(expectedAmounts2.amount1);
|
|
55316
|
+
const remainingSellAmount = tokenToSell == poolKey2.token0 ? expectedAmounts2.amount0 : expectedAmounts2.amount1;
|
|
55317
|
+
return { tokenToSell, tokenToBuy, amountToSell, remainingSellAmount };
|
|
55318
|
+
}
|
|
55319
|
+
while (retry < maxRetry) {
|
|
55320
|
+
retry++;
|
|
55274
55321
|
logger.verbose(
|
|
55275
|
-
|
|
55322
|
+
`getSwapInfoGivenAmounts::Retry attempt: ${retry}/${maxRetry}`
|
|
55276
55323
|
);
|
|
55324
|
+
assertValidAmounts(expectedAmounts, token0Bal, token1Bal);
|
|
55325
|
+
const { tokenToSell, tokenToBuy, amountToSell, remainingSellAmount } = getSwapParams(expectedAmounts, poolKey, token0Bal, token1Bal);
|
|
55326
|
+
const tokenToBuyInfo = await Global.getTokenInfoFromAddr(tokenToBuy);
|
|
55327
|
+
const expectedRatio = expectedAmounts.ratio;
|
|
55277
55328
|
logger.verbose(
|
|
55278
|
-
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused =>
|
|
55329
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => iteration info: ${JSON.stringify({
|
|
55330
|
+
tokenToSell: tokenToSell.address,
|
|
55331
|
+
tokenToBuy: tokenToBuy.address,
|
|
55332
|
+
amountToSell: amountToSell.toString(),
|
|
55333
|
+
remainingSellAmount: remainingSellAmount.toString(),
|
|
55334
|
+
expectedRatio
|
|
55335
|
+
})}`
|
|
55279
55336
|
);
|
|
55280
55337
|
if (amountToSell.eq(0)) {
|
|
55281
|
-
return
|
|
55282
|
-
token_from_address: tokenToSell.address,
|
|
55283
|
-
token_from_amount: uint256_exports.bnToUint256(0),
|
|
55284
|
-
token_to_address: tokenToSell.address,
|
|
55285
|
-
token_to_amount: uint256_exports.bnToUint256(0),
|
|
55286
|
-
token_to_min_amount: uint256_exports.bnToUint256(0),
|
|
55287
|
-
beneficiary: this.address.address,
|
|
55288
|
-
integrator_fee_amount_bps: 0,
|
|
55289
|
-
integrator_fee_recipient: this.address.address,
|
|
55290
|
-
routes: []
|
|
55291
|
-
};
|
|
55338
|
+
return AvnuWrapper.buildZeroSwap(tokenToSell, this.address.address);
|
|
55292
55339
|
}
|
|
55293
55340
|
const quote = await this.avnu.getQuotes(
|
|
55294
55341
|
tokenToSell.address,
|
|
@@ -55316,15 +55363,14 @@ var strkfarm_risk_engine = (() => {
|
|
|
55316
55363
|
const swapPrice = tokenToSell == poolKey.token0 ? amountOut.dividedBy(amountToSell) : amountToSell.dividedBy(amountOut);
|
|
55317
55364
|
const newRatio = tokenToSell == poolKey.token0 ? remainingSellAmount.dividedBy(token1Bal.plus(amountOut)) : token0Bal.plus(amountOut).dividedBy(remainingSellAmount);
|
|
55318
55365
|
logger.verbose(
|
|
55319
|
-
`${_EkuboCLVault.name}
|
|
55366
|
+
`${_EkuboCLVault.name} getSwapInfoToHandleUnused => iter post calc: ${JSON.stringify({
|
|
55367
|
+
amountOut: amountOut.toString(),
|
|
55368
|
+
swapPrice: swapPrice.toString(),
|
|
55369
|
+
newRatio: newRatio.toString()
|
|
55370
|
+
})}`
|
|
55320
55371
|
);
|
|
55321
|
-
|
|
55322
|
-
|
|
55323
|
-
);
|
|
55324
|
-
logger.verbose(
|
|
55325
|
-
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newRatio: ${newRatio.toString()}`
|
|
55326
|
-
);
|
|
55327
|
-
if (Number(newRatio.toString()) > expectedRatio * 1.0000001 || Number(newRatio.toString()) < expectedRatio * 0.9999999) {
|
|
55372
|
+
const expectedPrecision = Math.min(7, tokenToBuyInfo.decimals - 2);
|
|
55373
|
+
if (Number(newRatio.toString()) > expectedRatio * (1 + 1 / 10 ** expectedPrecision) || Number(newRatio.toString()) < expectedRatio * (1 - 1 / 10 ** expectedPrecision)) {
|
|
55328
55374
|
expectedAmounts = await this._solveExpectedAmountsEq(
|
|
55329
55375
|
token0Bal,
|
|
55330
55376
|
token1Bal,
|
|
@@ -55523,6 +55569,9 @@ var strkfarm_risk_engine = (() => {
|
|
|
55523
55569
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
55524
55570
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
55525
55571
|
const bounds = await this.getCurrentBounds();
|
|
55572
|
+
logger.verbose(
|
|
55573
|
+
`${_EkuboCLVault.name}: harvest => unClaimedRewards: ${unClaimedRewards.length}`
|
|
55574
|
+
);
|
|
55526
55575
|
const calls = [];
|
|
55527
55576
|
for (let claim of unClaimedRewards) {
|
|
55528
55577
|
const fee = claim.claim.amount.multipliedBy(this.metadata.additionalInfo.feeBps).dividedBy(1e4);
|
|
@@ -55555,12 +55604,28 @@ var strkfarm_risk_engine = (() => {
|
|
|
55555
55604
|
18
|
|
55556
55605
|
// cause its always STRK?
|
|
55557
55606
|
);
|
|
55607
|
+
logger.verbose(
|
|
55608
|
+
`${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
|
|
55609
|
+
);
|
|
55558
55610
|
const remainingAmount = postFeeAmount.minus(swap1Amount);
|
|
55611
|
+
logger.verbose(
|
|
55612
|
+
`${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
|
|
55613
|
+
);
|
|
55559
55614
|
const swapInfo2 = {
|
|
55560
55615
|
...swapInfo,
|
|
55561
55616
|
token_from_amount: uint256_exports.bnToUint256(remainingAmount.toWei())
|
|
55562
55617
|
};
|
|
55563
55618
|
swapInfo2.token_to_address = token1Info.address.address;
|
|
55619
|
+
logger.verbose(
|
|
55620
|
+
`${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
|
|
55621
|
+
swapInfo
|
|
55622
|
+
)}`
|
|
55623
|
+
);
|
|
55624
|
+
logger.verbose(
|
|
55625
|
+
`${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
|
|
55626
|
+
swapInfo2
|
|
55627
|
+
)}`
|
|
55628
|
+
);
|
|
55564
55629
|
const calldata = [
|
|
55565
55630
|
claim.rewardsContract.address,
|
|
55566
55631
|
{
|
|
@@ -55664,8 +55729,16 @@ var strkfarm_risk_engine = (() => {
|
|
|
55664
55729
|
{
|
|
55665
55730
|
question: "Is the strategy audited?",
|
|
55666
55731
|
answer: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
55667
|
-
"Yes, the strategy has been audited. You can review the audit report in our docs
|
|
55668
|
-
|
|
55732
|
+
"Yes, the strategy has been audited. You can review the audit report in our docs",
|
|
55733
|
+
" ",
|
|
55734
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
55735
|
+
"a",
|
|
55736
|
+
{
|
|
55737
|
+
href: "https://docs.strkfarm.com/p/ekubo-cl-vaults#technical-details",
|
|
55738
|
+
style: { textDecoration: "underline", marginLeft: "5px" },
|
|
55739
|
+
children: "Here"
|
|
55740
|
+
}
|
|
55741
|
+
),
|
|
55669
55742
|
"."
|
|
55670
55743
|
] })
|
|
55671
55744
|
}
|
|
@@ -55717,7 +55790,12 @@ var strkfarm_risk_engine = (() => {
|
|
|
55717
55790
|
lstContract: ContractAddr.from(
|
|
55718
55791
|
"0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a"
|
|
55719
55792
|
),
|
|
55720
|
-
feeBps: 1e3
|
|
55793
|
+
feeBps: 1e3,
|
|
55794
|
+
rebalanceConditions: {
|
|
55795
|
+
customShouldRebalance: async (currentPrice) => true,
|
|
55796
|
+
minWaitHours: 24,
|
|
55797
|
+
direction: "uponly"
|
|
55798
|
+
}
|
|
55721
55799
|
},
|
|
55722
55800
|
faqs: [
|
|
55723
55801
|
...faqs2,
|
|
@@ -55758,7 +55836,10 @@ var strkfarm_risk_engine = (() => {
|
|
|
55758
55836
|
maxTVL: Web3Number.fromWei("0", 6),
|
|
55759
55837
|
risk: {
|
|
55760
55838
|
riskFactor: _riskFactorStable,
|
|
55761
|
-
netRisk: _riskFactorStable.reduce(
|
|
55839
|
+
netRisk: _riskFactorStable.reduce(
|
|
55840
|
+
(acc, curr) => acc + curr.value * curr.weight,
|
|
55841
|
+
0
|
|
55842
|
+
) / _riskFactorStable.reduce((acc, curr) => acc + curr.weight, 0),
|
|
55762
55843
|
notARisks: getNoRiskTags(_riskFactorStable)
|
|
55763
55844
|
},
|
|
55764
55845
|
apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
|
|
@@ -55768,11 +55849,14 @@ var strkfarm_risk_engine = (() => {
|
|
|
55768
55849
|
upper: 1
|
|
55769
55850
|
},
|
|
55770
55851
|
truePrice: 1,
|
|
55771
|
-
feeBps: 1e3
|
|
55852
|
+
feeBps: 1e3,
|
|
55853
|
+
rebalanceConditions: {
|
|
55854
|
+
customShouldRebalance: async (currentPrice) => currentPrice > 0.99 && currentPrice < 1.01,
|
|
55855
|
+
minWaitHours: 6,
|
|
55856
|
+
direction: "any"
|
|
55857
|
+
}
|
|
55772
55858
|
},
|
|
55773
|
-
faqs: [
|
|
55774
|
-
...faqs2
|
|
55775
|
-
]
|
|
55859
|
+
faqs: [...faqs2]
|
|
55776
55860
|
}
|
|
55777
55861
|
];
|
|
55778
55862
|
return __toCommonJS(index_browser_exports);
|
package/dist/index.browser.mjs
CHANGED
|
@@ -1948,6 +1948,19 @@ var AvnuWrapper = class _AvnuWrapper {
|
|
|
1948
1948
|
};
|
|
1949
1949
|
return swapInfo;
|
|
1950
1950
|
}
|
|
1951
|
+
static buildZeroSwap(tokenToSell, address) {
|
|
1952
|
+
return {
|
|
1953
|
+
token_from_address: tokenToSell.address,
|
|
1954
|
+
token_from_amount: uint256.bnToUint256(0),
|
|
1955
|
+
token_to_address: tokenToSell.address,
|
|
1956
|
+
token_to_amount: uint256.bnToUint256(0),
|
|
1957
|
+
token_to_min_amount: uint256.bnToUint256(0),
|
|
1958
|
+
beneficiary: address,
|
|
1959
|
+
integrator_fee_amount_bps: 0,
|
|
1960
|
+
integrator_fee_recipient: address,
|
|
1961
|
+
routes: []
|
|
1962
|
+
};
|
|
1963
|
+
}
|
|
1951
1964
|
};
|
|
1952
1965
|
|
|
1953
1966
|
// src/interfaces/common.ts
|
|
@@ -18583,7 +18596,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
18583
18596
|
const priceNow = await this.getCurrentPrice(blockIdentifier);
|
|
18584
18597
|
let blockNow = typeof blockIdentifier == "number" ? blockIdentifier : (await this.config.provider.getBlockLatestAccepted()).block_number;
|
|
18585
18598
|
const blockNowTime = typeof blockIdentifier == "number" ? (await this.config.provider.getBlockWithTxs(blockIdentifier)).timestamp : (/* @__PURE__ */ new Date()).getTime() / 1e3;
|
|
18586
|
-
const blockBefore = Math.max(
|
|
18599
|
+
const blockBefore = Math.max(
|
|
18600
|
+
blockNow - sinceBlocks,
|
|
18601
|
+
this.metadata.launchBlock
|
|
18602
|
+
);
|
|
18587
18603
|
const adjustedSupplyNow = supplyNow.minus(
|
|
18588
18604
|
await this.getHarvestRewardShares(blockBefore, blockNow)
|
|
18589
18605
|
);
|
|
@@ -18976,14 +18992,24 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
18976
18992
|
_solveExpectedAmountsEq(availableAmount0, availableAmount1, ratio, price) {
|
|
18977
18993
|
const y = ratio.multipliedBy(availableAmount1).minus(availableAmount0).dividedBy(ratio.plus(1 / price));
|
|
18978
18994
|
const x = y.dividedBy(price);
|
|
18995
|
+
logger.verbose(
|
|
18996
|
+
`${_EkuboCLVault.name}: _solveExpectedAmountsEq => x: ${x.toString()}, y: ${y.toString()}, amount0: ${availableAmount0.toString()}, amount1: ${availableAmount1.toString()}`
|
|
18997
|
+
);
|
|
18998
|
+
if (ratio.eq(0)) {
|
|
18999
|
+
return {
|
|
19000
|
+
amount0: Web3Number.fromWei("0", availableAmount0.decimals),
|
|
19001
|
+
amount1: availableAmount1.minus(y),
|
|
19002
|
+
ratio: 0
|
|
19003
|
+
};
|
|
19004
|
+
}
|
|
18979
19005
|
return {
|
|
18980
19006
|
amount0: availableAmount0.plus(x),
|
|
18981
19007
|
amount1: availableAmount1.minus(y),
|
|
18982
19008
|
ratio: Number(ratio.toString())
|
|
18983
19009
|
};
|
|
18984
19010
|
}
|
|
18985
|
-
async
|
|
18986
|
-
const poolKey = await this.getPoolKey();
|
|
19011
|
+
async unusedBalances(_poolKey) {
|
|
19012
|
+
const poolKey = _poolKey || await this.getPoolKey();
|
|
18987
19013
|
const erc20Mod = new ERC20(this.config);
|
|
18988
19014
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
18989
19015
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
@@ -19004,11 +19030,24 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
19004
19030
|
const token1Price = await this.pricer.getPrice(token1Info.symbol);
|
|
19005
19031
|
const token0PriceUsd = token0Price.price * Number(token0Bal1.toFixed(13));
|
|
19006
19032
|
const token1PriceUsd = token1Price.price * Number(token1Bal1.toFixed(13));
|
|
19007
|
-
|
|
19008
|
-
|
|
19009
|
-
|
|
19010
|
-
|
|
19011
|
-
|
|
19033
|
+
return {
|
|
19034
|
+
token0: {
|
|
19035
|
+
amount: token0Bal1,
|
|
19036
|
+
tokenInfo: token0Info,
|
|
19037
|
+
usdValue: token0PriceUsd
|
|
19038
|
+
},
|
|
19039
|
+
token1: {
|
|
19040
|
+
amount: token1Bal1,
|
|
19041
|
+
tokenInfo: token1Info,
|
|
19042
|
+
usdValue: token1PriceUsd
|
|
19043
|
+
}
|
|
19044
|
+
};
|
|
19045
|
+
}
|
|
19046
|
+
async getSwapInfoToHandleUnused(considerRebalance = true) {
|
|
19047
|
+
const poolKey = await this.getPoolKey();
|
|
19048
|
+
const unusedBalances = await this.unusedBalances(poolKey);
|
|
19049
|
+
const { amount: token0Bal1, usdValue: token0PriceUsd } = unusedBalances.token0;
|
|
19050
|
+
const { amount: token1Bal1, usdValue: token1PriceUsd } = unusedBalances.token1;
|
|
19012
19051
|
let token0Bal = token0Bal1;
|
|
19013
19052
|
let token1Bal = token1Bal1;
|
|
19014
19053
|
if (considerRebalance) {
|
|
@@ -19026,63 +19065,71 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
19026
19065
|
logger.verbose(
|
|
19027
19066
|
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`
|
|
19028
19067
|
);
|
|
19029
|
-
|
|
19068
|
+
let ekuboBounds;
|
|
19069
|
+
if (considerRebalance) {
|
|
19070
|
+
ekuboBounds = await this.getNewBounds();
|
|
19071
|
+
} else {
|
|
19072
|
+
ekuboBounds = await this.getCurrentBounds();
|
|
19073
|
+
}
|
|
19030
19074
|
logger.verbose(
|
|
19031
|
-
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newBounds: ${
|
|
19075
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newBounds: ${ekuboBounds.lowerTick}, ${ekuboBounds.upperTick}`
|
|
19032
19076
|
);
|
|
19033
19077
|
return await this.getSwapInfoGivenAmounts(
|
|
19034
19078
|
poolKey,
|
|
19035
19079
|
token0Bal,
|
|
19036
19080
|
token1Bal,
|
|
19037
|
-
|
|
19081
|
+
ekuboBounds
|
|
19038
19082
|
);
|
|
19039
19083
|
}
|
|
19040
19084
|
async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds) {
|
|
19085
|
+
logger.verbose(
|
|
19086
|
+
`${_EkuboCLVault.name}: getSwapInfoGivenAmounts::pre => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`
|
|
19087
|
+
);
|
|
19041
19088
|
let expectedAmounts = await this._getExpectedAmountsForLiquidity(
|
|
19042
19089
|
token0Bal,
|
|
19043
19090
|
token1Bal,
|
|
19044
19091
|
bounds
|
|
19045
19092
|
);
|
|
19046
19093
|
logger.verbose(
|
|
19047
|
-
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused =>
|
|
19094
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => expectedAmounts2: ${expectedAmounts.amount0.toString()}, ${expectedAmounts.amount1.toString()}`
|
|
19048
19095
|
);
|
|
19049
19096
|
let retry = 0;
|
|
19050
19097
|
const maxRetry = 10;
|
|
19051
|
-
|
|
19052
|
-
|
|
19053
|
-
if (expectedAmounts.amount0.lessThan(token0Bal) && expectedAmounts.amount1.lessThan(token1Bal)) {
|
|
19098
|
+
function assertValidAmounts(expectedAmounts2, token0Bal2, token1Bal2) {
|
|
19099
|
+
if (expectedAmounts2.amount0.lessThan(token0Bal2) && expectedAmounts2.amount1.lessThan(token1Bal2)) {
|
|
19054
19100
|
throw new Error("Both tokens are decreased, something is wrong");
|
|
19055
19101
|
}
|
|
19056
|
-
if (
|
|
19102
|
+
if (expectedAmounts2.amount0.greaterThan(token0Bal2) && expectedAmounts2.amount1.greaterThan(token1Bal2)) {
|
|
19057
19103
|
throw new Error("Both tokens are increased, something is wrong");
|
|
19058
19104
|
}
|
|
19059
|
-
|
|
19060
|
-
|
|
19061
|
-
|
|
19062
|
-
const
|
|
19063
|
-
const
|
|
19064
|
-
const
|
|
19065
|
-
|
|
19066
|
-
|
|
19067
|
-
|
|
19105
|
+
}
|
|
19106
|
+
function getSwapParams(expectedAmounts2, poolKey2, token0Bal2, token1Bal2) {
|
|
19107
|
+
const tokenToSell = expectedAmounts2.amount0.lessThan(token0Bal2) ? poolKey2.token0 : poolKey2.token1;
|
|
19108
|
+
const tokenToBuy = tokenToSell == poolKey2.token0 ? poolKey2.token1 : poolKey2.token0;
|
|
19109
|
+
const amountToSell = tokenToSell == poolKey2.token0 ? token0Bal2.minus(expectedAmounts2.amount0) : token1Bal2.minus(expectedAmounts2.amount1);
|
|
19110
|
+
const remainingSellAmount = tokenToSell == poolKey2.token0 ? expectedAmounts2.amount0 : expectedAmounts2.amount1;
|
|
19111
|
+
return { tokenToSell, tokenToBuy, amountToSell, remainingSellAmount };
|
|
19112
|
+
}
|
|
19113
|
+
while (retry < maxRetry) {
|
|
19114
|
+
retry++;
|
|
19068
19115
|
logger.verbose(
|
|
19069
|
-
|
|
19116
|
+
`getSwapInfoGivenAmounts::Retry attempt: ${retry}/${maxRetry}`
|
|
19070
19117
|
);
|
|
19118
|
+
assertValidAmounts(expectedAmounts, token0Bal, token1Bal);
|
|
19119
|
+
const { tokenToSell, tokenToBuy, amountToSell, remainingSellAmount } = getSwapParams(expectedAmounts, poolKey, token0Bal, token1Bal);
|
|
19120
|
+
const tokenToBuyInfo = await Global.getTokenInfoFromAddr(tokenToBuy);
|
|
19121
|
+
const expectedRatio = expectedAmounts.ratio;
|
|
19071
19122
|
logger.verbose(
|
|
19072
|
-
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused =>
|
|
19123
|
+
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => iteration info: ${JSON.stringify({
|
|
19124
|
+
tokenToSell: tokenToSell.address,
|
|
19125
|
+
tokenToBuy: tokenToBuy.address,
|
|
19126
|
+
amountToSell: amountToSell.toString(),
|
|
19127
|
+
remainingSellAmount: remainingSellAmount.toString(),
|
|
19128
|
+
expectedRatio
|
|
19129
|
+
})}`
|
|
19073
19130
|
);
|
|
19074
19131
|
if (amountToSell.eq(0)) {
|
|
19075
|
-
return
|
|
19076
|
-
token_from_address: tokenToSell.address,
|
|
19077
|
-
token_from_amount: uint2564.bnToUint256(0),
|
|
19078
|
-
token_to_address: tokenToSell.address,
|
|
19079
|
-
token_to_amount: uint2564.bnToUint256(0),
|
|
19080
|
-
token_to_min_amount: uint2564.bnToUint256(0),
|
|
19081
|
-
beneficiary: this.address.address,
|
|
19082
|
-
integrator_fee_amount_bps: 0,
|
|
19083
|
-
integrator_fee_recipient: this.address.address,
|
|
19084
|
-
routes: []
|
|
19085
|
-
};
|
|
19132
|
+
return AvnuWrapper.buildZeroSwap(tokenToSell, this.address.address);
|
|
19086
19133
|
}
|
|
19087
19134
|
const quote = await this.avnu.getQuotes(
|
|
19088
19135
|
tokenToSell.address,
|
|
@@ -19110,15 +19157,14 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
19110
19157
|
const swapPrice = tokenToSell == poolKey.token0 ? amountOut.dividedBy(amountToSell) : amountToSell.dividedBy(amountOut);
|
|
19111
19158
|
const newRatio = tokenToSell == poolKey.token0 ? remainingSellAmount.dividedBy(token1Bal.plus(amountOut)) : token0Bal.plus(amountOut).dividedBy(remainingSellAmount);
|
|
19112
19159
|
logger.verbose(
|
|
19113
|
-
`${_EkuboCLVault.name}
|
|
19160
|
+
`${_EkuboCLVault.name} getSwapInfoToHandleUnused => iter post calc: ${JSON.stringify({
|
|
19161
|
+
amountOut: amountOut.toString(),
|
|
19162
|
+
swapPrice: swapPrice.toString(),
|
|
19163
|
+
newRatio: newRatio.toString()
|
|
19164
|
+
})}`
|
|
19114
19165
|
);
|
|
19115
|
-
|
|
19116
|
-
|
|
19117
|
-
);
|
|
19118
|
-
logger.verbose(
|
|
19119
|
-
`${_EkuboCLVault.name}: getSwapInfoToHandleUnused => newRatio: ${newRatio.toString()}`
|
|
19120
|
-
);
|
|
19121
|
-
if (Number(newRatio.toString()) > expectedRatio * 1.0000001 || Number(newRatio.toString()) < expectedRatio * 0.9999999) {
|
|
19166
|
+
const expectedPrecision = Math.min(7, tokenToBuyInfo.decimals - 2);
|
|
19167
|
+
if (Number(newRatio.toString()) > expectedRatio * (1 + 1 / 10 ** expectedPrecision) || Number(newRatio.toString()) < expectedRatio * (1 - 1 / 10 ** expectedPrecision)) {
|
|
19122
19168
|
expectedAmounts = await this._solveExpectedAmountsEq(
|
|
19123
19169
|
token0Bal,
|
|
19124
19170
|
token1Bal,
|
|
@@ -19317,6 +19363,9 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
19317
19363
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
19318
19364
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
19319
19365
|
const bounds = await this.getCurrentBounds();
|
|
19366
|
+
logger.verbose(
|
|
19367
|
+
`${_EkuboCLVault.name}: harvest => unClaimedRewards: ${unClaimedRewards.length}`
|
|
19368
|
+
);
|
|
19320
19369
|
const calls = [];
|
|
19321
19370
|
for (let claim of unClaimedRewards) {
|
|
19322
19371
|
const fee = claim.claim.amount.multipliedBy(this.metadata.additionalInfo.feeBps).dividedBy(1e4);
|
|
@@ -19349,12 +19398,28 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
19349
19398
|
18
|
|
19350
19399
|
// cause its always STRK?
|
|
19351
19400
|
);
|
|
19401
|
+
logger.verbose(
|
|
19402
|
+
`${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
|
|
19403
|
+
);
|
|
19352
19404
|
const remainingAmount = postFeeAmount.minus(swap1Amount);
|
|
19405
|
+
logger.verbose(
|
|
19406
|
+
`${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
|
|
19407
|
+
);
|
|
19353
19408
|
const swapInfo2 = {
|
|
19354
19409
|
...swapInfo,
|
|
19355
19410
|
token_from_amount: uint2564.bnToUint256(remainingAmount.toWei())
|
|
19356
19411
|
};
|
|
19357
19412
|
swapInfo2.token_to_address = token1Info.address.address;
|
|
19413
|
+
logger.verbose(
|
|
19414
|
+
`${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
|
|
19415
|
+
swapInfo
|
|
19416
|
+
)}`
|
|
19417
|
+
);
|
|
19418
|
+
logger.verbose(
|
|
19419
|
+
`${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
|
|
19420
|
+
swapInfo2
|
|
19421
|
+
)}`
|
|
19422
|
+
);
|
|
19358
19423
|
const calldata = [
|
|
19359
19424
|
claim.rewardsContract.address,
|
|
19360
19425
|
{
|
|
@@ -19458,8 +19523,16 @@ var faqs2 = [
|
|
|
19458
19523
|
{
|
|
19459
19524
|
question: "Is the strategy audited?",
|
|
19460
19525
|
answer: /* @__PURE__ */ jsxs2("div", { children: [
|
|
19461
|
-
"Yes, the strategy has been audited. You can review the audit report in our docs
|
|
19462
|
-
|
|
19526
|
+
"Yes, the strategy has been audited. You can review the audit report in our docs",
|
|
19527
|
+
" ",
|
|
19528
|
+
/* @__PURE__ */ jsx2(
|
|
19529
|
+
"a",
|
|
19530
|
+
{
|
|
19531
|
+
href: "https://docs.strkfarm.com/p/ekubo-cl-vaults#technical-details",
|
|
19532
|
+
style: { textDecoration: "underline", marginLeft: "5px" },
|
|
19533
|
+
children: "Here"
|
|
19534
|
+
}
|
|
19535
|
+
),
|
|
19463
19536
|
"."
|
|
19464
19537
|
] })
|
|
19465
19538
|
}
|
|
@@ -19511,7 +19584,12 @@ var EkuboCLVaultStrategies = [
|
|
|
19511
19584
|
lstContract: ContractAddr.from(
|
|
19512
19585
|
"0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a"
|
|
19513
19586
|
),
|
|
19514
|
-
feeBps: 1e3
|
|
19587
|
+
feeBps: 1e3,
|
|
19588
|
+
rebalanceConditions: {
|
|
19589
|
+
customShouldRebalance: async (currentPrice) => true,
|
|
19590
|
+
minWaitHours: 24,
|
|
19591
|
+
direction: "uponly"
|
|
19592
|
+
}
|
|
19515
19593
|
},
|
|
19516
19594
|
faqs: [
|
|
19517
19595
|
...faqs2,
|
|
@@ -19552,7 +19630,10 @@ var EkuboCLVaultStrategies = [
|
|
|
19552
19630
|
maxTVL: Web3Number.fromWei("0", 6),
|
|
19553
19631
|
risk: {
|
|
19554
19632
|
riskFactor: _riskFactorStable,
|
|
19555
|
-
netRisk: _riskFactorStable.reduce(
|
|
19633
|
+
netRisk: _riskFactorStable.reduce(
|
|
19634
|
+
(acc, curr) => acc + curr.value * curr.weight,
|
|
19635
|
+
0
|
|
19636
|
+
) / _riskFactorStable.reduce((acc, curr) => acc + curr.weight, 0),
|
|
19556
19637
|
notARisks: getNoRiskTags(_riskFactorStable)
|
|
19557
19638
|
},
|
|
19558
19639
|
apyMethodology: "APY based on 7-day historical performance, including fees and rewards.",
|
|
@@ -19562,11 +19643,14 @@ var EkuboCLVaultStrategies = [
|
|
|
19562
19643
|
upper: 1
|
|
19563
19644
|
},
|
|
19564
19645
|
truePrice: 1,
|
|
19565
|
-
feeBps: 1e3
|
|
19646
|
+
feeBps: 1e3,
|
|
19647
|
+
rebalanceConditions: {
|
|
19648
|
+
customShouldRebalance: async (currentPrice) => currentPrice > 0.99 && currentPrice < 1.01,
|
|
19649
|
+
minWaitHours: 6,
|
|
19650
|
+
direction: "any"
|
|
19651
|
+
}
|
|
19566
19652
|
},
|
|
19567
|
-
faqs: [
|
|
19568
|
-
...faqs2
|
|
19569
|
-
]
|
|
19653
|
+
faqs: [...faqs2]
|
|
19570
19654
|
}
|
|
19571
19655
|
];
|
|
19572
19656
|
export {
|
package/dist/index.d.ts
CHANGED
|
@@ -289,6 +289,7 @@ interface SwapInfo {
|
|
|
289
289
|
declare class AvnuWrapper {
|
|
290
290
|
getQuotes(fromToken: string, toToken: string, amountWei: string, taker: string, retry?: number): Promise<Quote>;
|
|
291
291
|
getSwapInfo(quote: Quote, taker: string, integratorFeeBps: number, integratorFeeRecipient: string, minAmount?: string): Promise<SwapInfo>;
|
|
292
|
+
static buildZeroSwap(tokenToSell: ContractAddr, address: string): SwapInfo;
|
|
292
293
|
}
|
|
293
294
|
|
|
294
295
|
declare class FatalError extends Error {
|
|
@@ -598,6 +599,11 @@ interface CLVaultStrategySettings {
|
|
|
598
599
|
lstContract?: ContractAddr;
|
|
599
600
|
truePrice?: number;
|
|
600
601
|
feeBps: number;
|
|
602
|
+
rebalanceConditions: {
|
|
603
|
+
minWaitHours: number;
|
|
604
|
+
direction: "any" | "uponly";
|
|
605
|
+
customShouldRebalance: (currentPoolPrice: number) => Promise<boolean>;
|
|
606
|
+
};
|
|
601
607
|
}
|
|
602
608
|
declare class EkuboCLVault extends BaseStrategy<DualTokenInfo, DualActionAmount> {
|
|
603
609
|
/** Contract address of the strategy */
|
|
@@ -672,6 +678,18 @@ declare class EkuboCLVault extends BaseStrategy<DualTokenInfo, DualActionAmount>
|
|
|
672
678
|
*/
|
|
673
679
|
private _getExpectedAmountsForLiquidity;
|
|
674
680
|
private _solveExpectedAmountsEq;
|
|
681
|
+
unusedBalances(_poolKey?: EkuboPoolKey): Promise<{
|
|
682
|
+
token0: {
|
|
683
|
+
amount: Web3Number;
|
|
684
|
+
tokenInfo: TokenInfo;
|
|
685
|
+
usdValue: number;
|
|
686
|
+
};
|
|
687
|
+
token1: {
|
|
688
|
+
amount: Web3Number;
|
|
689
|
+
tokenInfo: TokenInfo;
|
|
690
|
+
usdValue: number;
|
|
691
|
+
};
|
|
692
|
+
}>;
|
|
675
693
|
getSwapInfoToHandleUnused(considerRebalance?: boolean): Promise<SwapInfo>;
|
|
676
694
|
getSwapInfoGivenAmounts(poolKey: EkuboPoolKey, token0Bal: Web3Number, token1Bal: Web3Number, bounds: EkuboBounds): Promise<SwapInfo>;
|
|
677
695
|
/**
|