@strkfarm/sdk 1.1.59 → 1.1.61
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 +44 -14
- package/dist/index.browser.mjs +44 -14
- package/dist/index.d.ts +10 -4
- package/dist/index.js +44 -14
- package/dist/index.mjs +44 -14
- package/package.json +1 -1
- package/src/strategies/ekubo-cl-vault.tsx +57 -14
|
@@ -80220,7 +80220,7 @@ spurious results.`);
|
|
|
80220
80220
|
}
|
|
80221
80221
|
};
|
|
80222
80222
|
}
|
|
80223
|
-
async getSwapInfoToHandleUnused(considerRebalance = true, newBounds = null, maxIterations = 20, priceRatioPrecision = 4) {
|
|
80223
|
+
async getSwapInfoToHandleUnused(considerRebalance = true, newBounds = null, maxIterations = 20, priceRatioPrecision = 4, getQuoteCallback = this.avnu.getQuotes) {
|
|
80224
80224
|
const poolKey = await this.getPoolKey();
|
|
80225
80225
|
const unusedBalances = await this.unusedBalances(poolKey);
|
|
80226
80226
|
const { amount: token0Bal1, usdValue: token0PriceUsd } = unusedBalances.token0;
|
|
@@ -80260,7 +80260,8 @@ spurious results.`);
|
|
|
80260
80260
|
token1Bal,
|
|
80261
80261
|
ekuboBounds,
|
|
80262
80262
|
maxIterations,
|
|
80263
|
-
priceRatioPrecision
|
|
80263
|
+
priceRatioPrecision,
|
|
80264
|
+
getQuoteCallback
|
|
80264
80265
|
);
|
|
80265
80266
|
}
|
|
80266
80267
|
assertValidBounds(bounds) {
|
|
@@ -80305,7 +80306,7 @@ spurious results.`);
|
|
|
80305
80306
|
* @returns {Promise<SwapInfo>}
|
|
80306
80307
|
*
|
|
80307
80308
|
*/
|
|
80308
|
-
async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds, maxIterations = 20, priceRatioPrecision = 4) {
|
|
80309
|
+
async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds, maxIterations = 20, priceRatioPrecision = 4, getQuoteCallback = this.avnu.getQuotes) {
|
|
80309
80310
|
logger2.verbose(
|
|
80310
80311
|
`${_EkuboCLVault.name}: getSwapInfoGivenAmounts::pre => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`
|
|
80311
80312
|
);
|
|
@@ -80340,12 +80341,7 @@ spurious results.`);
|
|
|
80340
80341
|
if (amountToSell.eq(0)) {
|
|
80341
80342
|
return AvnuWrapper.buildZeroSwap(tokenToSell, this.address.address);
|
|
80342
80343
|
}
|
|
80343
|
-
const quote = await this.
|
|
80344
|
-
tokenToSell.address,
|
|
80345
|
-
tokenToBuy.address,
|
|
80346
|
-
amountToSell.toWei(),
|
|
80347
|
-
this.address.address
|
|
80348
|
-
);
|
|
80344
|
+
const quote = await getQuoteCallback(tokenToSell.address, tokenToBuy.address, amountToSell.toWei(), this.address.address);
|
|
80349
80345
|
if (remainingSellAmount.eq(0)) {
|
|
80350
80346
|
const minAmountOut = Web3Number.fromWei(
|
|
80351
80347
|
quote.buyAmount.toString(),
|
|
@@ -80428,13 +80424,20 @@ spurious results.`);
|
|
|
80428
80424
|
* @param retry - Current retry attempt number (default 0)
|
|
80429
80425
|
* @param adjustmentFactor - Percentage to adjust swap amount by (default 1)
|
|
80430
80426
|
* @param isToken0Deficit - Whether token0 balance needs increasing (default true)
|
|
80427
|
+
* @param MAX_RETRIES - Maximum number of retries (default 40)
|
|
80428
|
+
* @param sameErrorCount - For certain errors, we just retry with same amount again. This is the count of such retries (default { count: 0, error: null })
|
|
80429
|
+
* @param MAX_SAME_ERROR_COUNT - For certain errors, we just retry with same amount again. This limits such retries (default 10)
|
|
80431
80430
|
* @returns Array of contract calls needed for rebalancing
|
|
80432
|
-
* @throws Error if max retries reached without successful rebalance
|
|
80431
|
+
* @throws Error if max retries reached without successful rebalance or max same errors reached
|
|
80433
80432
|
*/
|
|
80434
|
-
async rebalanceIter(swapInfo, acc, estimateCall, isSellTokenToken0 = true, retry = 0, lowerLimit = 0n, upperLimit = 0n, MAX_RETRIES = 40) {
|
|
80433
|
+
async rebalanceIter(swapInfo, acc, estimateCall, isSellTokenToken0 = true, retry = 0, lowerLimit = 0n, upperLimit = 0n, MAX_RETRIES = 40, sameErrorCount = { count: 0, error: null }, MAX_SAME_ERROR_COUNT = 10) {
|
|
80435
80434
|
logger2.verbose(
|
|
80436
|
-
`Rebalancing ${this.metadata.name}: retry=${retry}, lowerLimit=${lowerLimit}, upperLimit=${upperLimit}, isSellTokenToken0=${isSellTokenToken0}`
|
|
80435
|
+
`Rebalancing ${this.metadata.name}: retry=${retry}, lowerLimit=${lowerLimit}, upperLimit=${upperLimit}, isSellTokenToken0=${isSellTokenToken0}, MAX_RETRIES=${MAX_RETRIES}, sameErrorCount=${sameErrorCount.error} (${sameErrorCount.count})`
|
|
80437
80436
|
);
|
|
80437
|
+
if (sameErrorCount.count >= MAX_SAME_ERROR_COUNT) {
|
|
80438
|
+
logger2.error(`Rebalance failed after ${MAX_SAME_ERROR_COUNT} same errors`);
|
|
80439
|
+
throw new Error(`Rebalance failed after ${MAX_SAME_ERROR_COUNT} same errors`);
|
|
80440
|
+
}
|
|
80438
80441
|
const fromAmount = uint256_exports.uint256ToBN(swapInfo.token_from_amount);
|
|
80439
80442
|
logger2.verbose(
|
|
80440
80443
|
`Selling ${fromAmount.toString()} of token ${swapInfo.token_from_address}`
|
|
@@ -80453,7 +80456,7 @@ spurious results.`);
|
|
|
80453
80456
|
);
|
|
80454
80457
|
const newSwapInfo = { ...swapInfo };
|
|
80455
80458
|
const currentAmount = Web3Number.fromWei(fromAmount.toString(), 18);
|
|
80456
|
-
logger2.verbose(`Current amount: ${currentAmount.toString()}`);
|
|
80459
|
+
logger2.verbose(`Current amount: ${currentAmount.toString()}, lowerLimit: ${lowerLimit.toString()}, upperLimit: ${upperLimit.toString()}`);
|
|
80457
80460
|
if (err2.message.includes("invalid token0 balance") || err2.message.includes("invalid token0 amount")) {
|
|
80458
80461
|
if (!isSellTokenToken0) {
|
|
80459
80462
|
logger2.verbose("Reducing swap amount - excess token0");
|
|
@@ -80500,6 +80503,30 @@ spurious results.`);
|
|
|
80500
80503
|
}
|
|
80501
80504
|
newSwapInfo.token_from_amount = uint256_exports.bnToUint256(nextAmount);
|
|
80502
80505
|
}
|
|
80506
|
+
} else if (err2.message.includes("Residual tokens")) {
|
|
80507
|
+
logger2.error("Residual tokens");
|
|
80508
|
+
if (sameErrorCount.error == "Residual tokens") {
|
|
80509
|
+
sameErrorCount.count++;
|
|
80510
|
+
} else {
|
|
80511
|
+
sameErrorCount.error = "Residual tokens";
|
|
80512
|
+
sameErrorCount.count = 1;
|
|
80513
|
+
}
|
|
80514
|
+
} else if (err2.message.includes("Insufficient tokens received")) {
|
|
80515
|
+
logger2.error("Insufficient tokens received");
|
|
80516
|
+
if (sameErrorCount.error == "Insufficient tokens received") {
|
|
80517
|
+
sameErrorCount.count++;
|
|
80518
|
+
} else {
|
|
80519
|
+
sameErrorCount.error = "Insufficient tokens received";
|
|
80520
|
+
sameErrorCount.count = 1;
|
|
80521
|
+
}
|
|
80522
|
+
} else if (err2.message.includes("Could not reach the end of the program")) {
|
|
80523
|
+
logger2.error("Could not reach the end of the program, may be the block is full (could be a temp/permanent gas issue)");
|
|
80524
|
+
if (sameErrorCount.error == "Could not reach the end of the program") {
|
|
80525
|
+
sameErrorCount.count++;
|
|
80526
|
+
} else {
|
|
80527
|
+
sameErrorCount.error = "Could not reach the end of the program";
|
|
80528
|
+
sameErrorCount.count = 1;
|
|
80529
|
+
}
|
|
80503
80530
|
} else {
|
|
80504
80531
|
logger2.error("Unexpected error:", err2);
|
|
80505
80532
|
throw err2;
|
|
@@ -80512,7 +80539,10 @@ spurious results.`);
|
|
|
80512
80539
|
isSellTokenToken0,
|
|
80513
80540
|
retry + 1,
|
|
80514
80541
|
lowerLimit,
|
|
80515
|
-
upperLimit
|
|
80542
|
+
upperLimit,
|
|
80543
|
+
MAX_RETRIES,
|
|
80544
|
+
sameErrorCount,
|
|
80545
|
+
MAX_SAME_ERROR_COUNT
|
|
80516
80546
|
);
|
|
80517
80547
|
}
|
|
80518
80548
|
}
|
package/dist/index.browser.mjs
CHANGED
|
@@ -16297,7 +16297,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16297
16297
|
}
|
|
16298
16298
|
};
|
|
16299
16299
|
}
|
|
16300
|
-
async getSwapInfoToHandleUnused(considerRebalance = true, newBounds = null, maxIterations = 20, priceRatioPrecision = 4) {
|
|
16300
|
+
async getSwapInfoToHandleUnused(considerRebalance = true, newBounds = null, maxIterations = 20, priceRatioPrecision = 4, getQuoteCallback = this.avnu.getQuotes) {
|
|
16301
16301
|
const poolKey = await this.getPoolKey();
|
|
16302
16302
|
const unusedBalances = await this.unusedBalances(poolKey);
|
|
16303
16303
|
const { amount: token0Bal1, usdValue: token0PriceUsd } = unusedBalances.token0;
|
|
@@ -16337,7 +16337,8 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16337
16337
|
token1Bal,
|
|
16338
16338
|
ekuboBounds,
|
|
16339
16339
|
maxIterations,
|
|
16340
|
-
priceRatioPrecision
|
|
16340
|
+
priceRatioPrecision,
|
|
16341
|
+
getQuoteCallback
|
|
16341
16342
|
);
|
|
16342
16343
|
}
|
|
16343
16344
|
assertValidBounds(bounds) {
|
|
@@ -16382,7 +16383,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16382
16383
|
* @returns {Promise<SwapInfo>}
|
|
16383
16384
|
*
|
|
16384
16385
|
*/
|
|
16385
|
-
async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds, maxIterations = 20, priceRatioPrecision = 4) {
|
|
16386
|
+
async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds, maxIterations = 20, priceRatioPrecision = 4, getQuoteCallback = this.avnu.getQuotes) {
|
|
16386
16387
|
logger.verbose(
|
|
16387
16388
|
`${_EkuboCLVault.name}: getSwapInfoGivenAmounts::pre => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`
|
|
16388
16389
|
);
|
|
@@ -16417,12 +16418,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16417
16418
|
if (amountToSell.eq(0)) {
|
|
16418
16419
|
return AvnuWrapper.buildZeroSwap(tokenToSell, this.address.address);
|
|
16419
16420
|
}
|
|
16420
|
-
const quote = await this.
|
|
16421
|
-
tokenToSell.address,
|
|
16422
|
-
tokenToBuy.address,
|
|
16423
|
-
amountToSell.toWei(),
|
|
16424
|
-
this.address.address
|
|
16425
|
-
);
|
|
16421
|
+
const quote = await getQuoteCallback(tokenToSell.address, tokenToBuy.address, amountToSell.toWei(), this.address.address);
|
|
16426
16422
|
if (remainingSellAmount.eq(0)) {
|
|
16427
16423
|
const minAmountOut = Web3Number.fromWei(
|
|
16428
16424
|
quote.buyAmount.toString(),
|
|
@@ -16505,13 +16501,20 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16505
16501
|
* @param retry - Current retry attempt number (default 0)
|
|
16506
16502
|
* @param adjustmentFactor - Percentage to adjust swap amount by (default 1)
|
|
16507
16503
|
* @param isToken0Deficit - Whether token0 balance needs increasing (default true)
|
|
16504
|
+
* @param MAX_RETRIES - Maximum number of retries (default 40)
|
|
16505
|
+
* @param sameErrorCount - For certain errors, we just retry with same amount again. This is the count of such retries (default { count: 0, error: null })
|
|
16506
|
+
* @param MAX_SAME_ERROR_COUNT - For certain errors, we just retry with same amount again. This limits such retries (default 10)
|
|
16508
16507
|
* @returns Array of contract calls needed for rebalancing
|
|
16509
|
-
* @throws Error if max retries reached without successful rebalance
|
|
16508
|
+
* @throws Error if max retries reached without successful rebalance or max same errors reached
|
|
16510
16509
|
*/
|
|
16511
|
-
async rebalanceIter(swapInfo, acc, estimateCall, isSellTokenToken0 = true, retry = 0, lowerLimit = 0n, upperLimit = 0n, MAX_RETRIES = 40) {
|
|
16510
|
+
async rebalanceIter(swapInfo, acc, estimateCall, isSellTokenToken0 = true, retry = 0, lowerLimit = 0n, upperLimit = 0n, MAX_RETRIES = 40, sameErrorCount = { count: 0, error: null }, MAX_SAME_ERROR_COUNT = 10) {
|
|
16512
16511
|
logger.verbose(
|
|
16513
|
-
`Rebalancing ${this.metadata.name}: retry=${retry}, lowerLimit=${lowerLimit}, upperLimit=${upperLimit}, isSellTokenToken0=${isSellTokenToken0}`
|
|
16512
|
+
`Rebalancing ${this.metadata.name}: retry=${retry}, lowerLimit=${lowerLimit}, upperLimit=${upperLimit}, isSellTokenToken0=${isSellTokenToken0}, MAX_RETRIES=${MAX_RETRIES}, sameErrorCount=${sameErrorCount.error} (${sameErrorCount.count})`
|
|
16514
16513
|
);
|
|
16514
|
+
if (sameErrorCount.count >= MAX_SAME_ERROR_COUNT) {
|
|
16515
|
+
logger.error(`Rebalance failed after ${MAX_SAME_ERROR_COUNT} same errors`);
|
|
16516
|
+
throw new Error(`Rebalance failed after ${MAX_SAME_ERROR_COUNT} same errors`);
|
|
16517
|
+
}
|
|
16515
16518
|
const fromAmount = uint2564.uint256ToBN(swapInfo.token_from_amount);
|
|
16516
16519
|
logger.verbose(
|
|
16517
16520
|
`Selling ${fromAmount.toString()} of token ${swapInfo.token_from_address}`
|
|
@@ -16530,7 +16533,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16530
16533
|
);
|
|
16531
16534
|
const newSwapInfo = { ...swapInfo };
|
|
16532
16535
|
const currentAmount = Web3Number.fromWei(fromAmount.toString(), 18);
|
|
16533
|
-
logger.verbose(`Current amount: ${currentAmount.toString()}`);
|
|
16536
|
+
logger.verbose(`Current amount: ${currentAmount.toString()}, lowerLimit: ${lowerLimit.toString()}, upperLimit: ${upperLimit.toString()}`);
|
|
16534
16537
|
if (err.message.includes("invalid token0 balance") || err.message.includes("invalid token0 amount")) {
|
|
16535
16538
|
if (!isSellTokenToken0) {
|
|
16536
16539
|
logger.verbose("Reducing swap amount - excess token0");
|
|
@@ -16577,6 +16580,30 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16577
16580
|
}
|
|
16578
16581
|
newSwapInfo.token_from_amount = uint2564.bnToUint256(nextAmount);
|
|
16579
16582
|
}
|
|
16583
|
+
} else if (err.message.includes("Residual tokens")) {
|
|
16584
|
+
logger.error("Residual tokens");
|
|
16585
|
+
if (sameErrorCount.error == "Residual tokens") {
|
|
16586
|
+
sameErrorCount.count++;
|
|
16587
|
+
} else {
|
|
16588
|
+
sameErrorCount.error = "Residual tokens";
|
|
16589
|
+
sameErrorCount.count = 1;
|
|
16590
|
+
}
|
|
16591
|
+
} else if (err.message.includes("Insufficient tokens received")) {
|
|
16592
|
+
logger.error("Insufficient tokens received");
|
|
16593
|
+
if (sameErrorCount.error == "Insufficient tokens received") {
|
|
16594
|
+
sameErrorCount.count++;
|
|
16595
|
+
} else {
|
|
16596
|
+
sameErrorCount.error = "Insufficient tokens received";
|
|
16597
|
+
sameErrorCount.count = 1;
|
|
16598
|
+
}
|
|
16599
|
+
} else if (err.message.includes("Could not reach the end of the program")) {
|
|
16600
|
+
logger.error("Could not reach the end of the program, may be the block is full (could be a temp/permanent gas issue)");
|
|
16601
|
+
if (sameErrorCount.error == "Could not reach the end of the program") {
|
|
16602
|
+
sameErrorCount.count++;
|
|
16603
|
+
} else {
|
|
16604
|
+
sameErrorCount.error = "Could not reach the end of the program";
|
|
16605
|
+
sameErrorCount.count = 1;
|
|
16606
|
+
}
|
|
16580
16607
|
} else {
|
|
16581
16608
|
logger.error("Unexpected error:", err);
|
|
16582
16609
|
throw err;
|
|
@@ -16589,7 +16616,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16589
16616
|
isSellTokenToken0,
|
|
16590
16617
|
retry + 1,
|
|
16591
16618
|
lowerLimit,
|
|
16592
|
-
upperLimit
|
|
16619
|
+
upperLimit,
|
|
16620
|
+
MAX_RETRIES,
|
|
16621
|
+
sameErrorCount,
|
|
16622
|
+
MAX_SAME_ERROR_COUNT
|
|
16593
16623
|
);
|
|
16594
16624
|
}
|
|
16595
16625
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -782,7 +782,7 @@ declare class EkuboCLVault extends BaseStrategy<DualTokenInfo, DualActionAmount>
|
|
|
782
782
|
usdValue: number;
|
|
783
783
|
};
|
|
784
784
|
}>;
|
|
785
|
-
getSwapInfoToHandleUnused(considerRebalance?: boolean, newBounds?: EkuboBounds | null, maxIterations?: number, priceRatioPrecision?: number): Promise<SwapInfo>;
|
|
785
|
+
getSwapInfoToHandleUnused(considerRebalance?: boolean, newBounds?: EkuboBounds | null, maxIterations?: number, priceRatioPrecision?: number, getQuoteCallback?: (tokenToSell: string, tokenToBuy: string, amountWei: string, beneficiary: string) => Promise<Quote>): Promise<SwapInfo>;
|
|
786
786
|
assertValidBounds(bounds: EkuboBounds): void;
|
|
787
787
|
assertValidAmounts(expectedAmounts: any, token0Bal: Web3Number, token1Bal: Web3Number): void;
|
|
788
788
|
getSwapParams(expectedAmounts: any, poolKey: EkuboPoolKey, token0Bal: Web3Number, token1Bal: Web3Number): {
|
|
@@ -802,7 +802,7 @@ declare class EkuboCLVault extends BaseStrategy<DualTokenInfo, DualActionAmount>
|
|
|
802
802
|
* @returns {Promise<SwapInfo>}
|
|
803
803
|
*
|
|
804
804
|
*/
|
|
805
|
-
getSwapInfoGivenAmounts(poolKey: EkuboPoolKey, token0Bal: Web3Number, token1Bal: Web3Number, bounds: EkuboBounds, maxIterations?: number, priceRatioPrecision?: number): Promise<SwapInfo>;
|
|
805
|
+
getSwapInfoGivenAmounts(poolKey: EkuboPoolKey, token0Bal: Web3Number, token1Bal: Web3Number, bounds: EkuboBounds, maxIterations?: number, priceRatioPrecision?: number, getQuoteCallback?: (tokenToSell: string, tokenToBuy: string, amountWei: string, beneficiary: string) => Promise<Quote>): Promise<SwapInfo>;
|
|
806
806
|
/**
|
|
807
807
|
* Attempts to rebalance the vault by iteratively adjusting swap amounts if initial attempt fails.
|
|
808
808
|
* Uses binary search approach to find optimal swap amount.
|
|
@@ -813,10 +813,16 @@ declare class EkuboCLVault extends BaseStrategy<DualTokenInfo, DualActionAmount>
|
|
|
813
813
|
* @param retry - Current retry attempt number (default 0)
|
|
814
814
|
* @param adjustmentFactor - Percentage to adjust swap amount by (default 1)
|
|
815
815
|
* @param isToken0Deficit - Whether token0 balance needs increasing (default true)
|
|
816
|
+
* @param MAX_RETRIES - Maximum number of retries (default 40)
|
|
817
|
+
* @param sameErrorCount - For certain errors, we just retry with same amount again. This is the count of such retries (default { count: 0, error: null })
|
|
818
|
+
* @param MAX_SAME_ERROR_COUNT - For certain errors, we just retry with same amount again. This limits such retries (default 10)
|
|
816
819
|
* @returns Array of contract calls needed for rebalancing
|
|
817
|
-
* @throws Error if max retries reached without successful rebalance
|
|
820
|
+
* @throws Error if max retries reached without successful rebalance or max same errors reached
|
|
818
821
|
*/
|
|
819
|
-
rebalanceIter(swapInfo: SwapInfo, acc: Account, estimateCall: (swapInfo: SwapInfo) => Promise<Call[]>, isSellTokenToken0?: boolean, retry?: number, lowerLimit?: bigint, upperLimit?: bigint, MAX_RETRIES?: number
|
|
822
|
+
rebalanceIter(swapInfo: SwapInfo, acc: Account, estimateCall: (swapInfo: SwapInfo) => Promise<Call[]>, isSellTokenToken0?: boolean, retry?: number, lowerLimit?: bigint, upperLimit?: bigint, MAX_RETRIES?: number, sameErrorCount?: {
|
|
823
|
+
count: number;
|
|
824
|
+
error: null | string;
|
|
825
|
+
}, MAX_SAME_ERROR_COUNT?: number): Promise<Call[]>;
|
|
820
826
|
static tickToi129(tick: number): {
|
|
821
827
|
mag: number;
|
|
822
828
|
sign: number;
|
package/dist/index.js
CHANGED
|
@@ -16297,7 +16297,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16297
16297
|
}
|
|
16298
16298
|
};
|
|
16299
16299
|
}
|
|
16300
|
-
async getSwapInfoToHandleUnused(considerRebalance = true, newBounds = null, maxIterations = 20, priceRatioPrecision = 4) {
|
|
16300
|
+
async getSwapInfoToHandleUnused(considerRebalance = true, newBounds = null, maxIterations = 20, priceRatioPrecision = 4, getQuoteCallback = this.avnu.getQuotes) {
|
|
16301
16301
|
const poolKey = await this.getPoolKey();
|
|
16302
16302
|
const unusedBalances = await this.unusedBalances(poolKey);
|
|
16303
16303
|
const { amount: token0Bal1, usdValue: token0PriceUsd } = unusedBalances.token0;
|
|
@@ -16337,7 +16337,8 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16337
16337
|
token1Bal,
|
|
16338
16338
|
ekuboBounds,
|
|
16339
16339
|
maxIterations,
|
|
16340
|
-
priceRatioPrecision
|
|
16340
|
+
priceRatioPrecision,
|
|
16341
|
+
getQuoteCallback
|
|
16341
16342
|
);
|
|
16342
16343
|
}
|
|
16343
16344
|
assertValidBounds(bounds) {
|
|
@@ -16382,7 +16383,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16382
16383
|
* @returns {Promise<SwapInfo>}
|
|
16383
16384
|
*
|
|
16384
16385
|
*/
|
|
16385
|
-
async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds, maxIterations = 20, priceRatioPrecision = 4) {
|
|
16386
|
+
async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds, maxIterations = 20, priceRatioPrecision = 4, getQuoteCallback = this.avnu.getQuotes) {
|
|
16386
16387
|
logger.verbose(
|
|
16387
16388
|
`${_EkuboCLVault.name}: getSwapInfoGivenAmounts::pre => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`
|
|
16388
16389
|
);
|
|
@@ -16417,12 +16418,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16417
16418
|
if (amountToSell.eq(0)) {
|
|
16418
16419
|
return AvnuWrapper.buildZeroSwap(tokenToSell, this.address.address);
|
|
16419
16420
|
}
|
|
16420
|
-
const quote = await this.
|
|
16421
|
-
tokenToSell.address,
|
|
16422
|
-
tokenToBuy.address,
|
|
16423
|
-
amountToSell.toWei(),
|
|
16424
|
-
this.address.address
|
|
16425
|
-
);
|
|
16421
|
+
const quote = await getQuoteCallback(tokenToSell.address, tokenToBuy.address, amountToSell.toWei(), this.address.address);
|
|
16426
16422
|
if (remainingSellAmount.eq(0)) {
|
|
16427
16423
|
const minAmountOut = Web3Number.fromWei(
|
|
16428
16424
|
quote.buyAmount.toString(),
|
|
@@ -16505,13 +16501,20 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16505
16501
|
* @param retry - Current retry attempt number (default 0)
|
|
16506
16502
|
* @param adjustmentFactor - Percentage to adjust swap amount by (default 1)
|
|
16507
16503
|
* @param isToken0Deficit - Whether token0 balance needs increasing (default true)
|
|
16504
|
+
* @param MAX_RETRIES - Maximum number of retries (default 40)
|
|
16505
|
+
* @param sameErrorCount - For certain errors, we just retry with same amount again. This is the count of such retries (default { count: 0, error: null })
|
|
16506
|
+
* @param MAX_SAME_ERROR_COUNT - For certain errors, we just retry with same amount again. This limits such retries (default 10)
|
|
16508
16507
|
* @returns Array of contract calls needed for rebalancing
|
|
16509
|
-
* @throws Error if max retries reached without successful rebalance
|
|
16508
|
+
* @throws Error if max retries reached without successful rebalance or max same errors reached
|
|
16510
16509
|
*/
|
|
16511
|
-
async rebalanceIter(swapInfo, acc, estimateCall, isSellTokenToken0 = true, retry = 0, lowerLimit = 0n, upperLimit = 0n, MAX_RETRIES = 40) {
|
|
16510
|
+
async rebalanceIter(swapInfo, acc, estimateCall, isSellTokenToken0 = true, retry = 0, lowerLimit = 0n, upperLimit = 0n, MAX_RETRIES = 40, sameErrorCount = { count: 0, error: null }, MAX_SAME_ERROR_COUNT = 10) {
|
|
16512
16511
|
logger.verbose(
|
|
16513
|
-
`Rebalancing ${this.metadata.name}: retry=${retry}, lowerLimit=${lowerLimit}, upperLimit=${upperLimit}, isSellTokenToken0=${isSellTokenToken0}`
|
|
16512
|
+
`Rebalancing ${this.metadata.name}: retry=${retry}, lowerLimit=${lowerLimit}, upperLimit=${upperLimit}, isSellTokenToken0=${isSellTokenToken0}, MAX_RETRIES=${MAX_RETRIES}, sameErrorCount=${sameErrorCount.error} (${sameErrorCount.count})`
|
|
16514
16513
|
);
|
|
16514
|
+
if (sameErrorCount.count >= MAX_SAME_ERROR_COUNT) {
|
|
16515
|
+
logger.error(`Rebalance failed after ${MAX_SAME_ERROR_COUNT} same errors`);
|
|
16516
|
+
throw new Error(`Rebalance failed after ${MAX_SAME_ERROR_COUNT} same errors`);
|
|
16517
|
+
}
|
|
16515
16518
|
const fromAmount = import_starknet11.uint256.uint256ToBN(swapInfo.token_from_amount);
|
|
16516
16519
|
logger.verbose(
|
|
16517
16520
|
`Selling ${fromAmount.toString()} of token ${swapInfo.token_from_address}`
|
|
@@ -16530,7 +16533,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16530
16533
|
);
|
|
16531
16534
|
const newSwapInfo = { ...swapInfo };
|
|
16532
16535
|
const currentAmount = Web3Number.fromWei(fromAmount.toString(), 18);
|
|
16533
|
-
logger.verbose(`Current amount: ${currentAmount.toString()}`);
|
|
16536
|
+
logger.verbose(`Current amount: ${currentAmount.toString()}, lowerLimit: ${lowerLimit.toString()}, upperLimit: ${upperLimit.toString()}`);
|
|
16534
16537
|
if (err.message.includes("invalid token0 balance") || err.message.includes("invalid token0 amount")) {
|
|
16535
16538
|
if (!isSellTokenToken0) {
|
|
16536
16539
|
logger.verbose("Reducing swap amount - excess token0");
|
|
@@ -16577,6 +16580,30 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16577
16580
|
}
|
|
16578
16581
|
newSwapInfo.token_from_amount = import_starknet11.uint256.bnToUint256(nextAmount);
|
|
16579
16582
|
}
|
|
16583
|
+
} else if (err.message.includes("Residual tokens")) {
|
|
16584
|
+
logger.error("Residual tokens");
|
|
16585
|
+
if (sameErrorCount.error == "Residual tokens") {
|
|
16586
|
+
sameErrorCount.count++;
|
|
16587
|
+
} else {
|
|
16588
|
+
sameErrorCount.error = "Residual tokens";
|
|
16589
|
+
sameErrorCount.count = 1;
|
|
16590
|
+
}
|
|
16591
|
+
} else if (err.message.includes("Insufficient tokens received")) {
|
|
16592
|
+
logger.error("Insufficient tokens received");
|
|
16593
|
+
if (sameErrorCount.error == "Insufficient tokens received") {
|
|
16594
|
+
sameErrorCount.count++;
|
|
16595
|
+
} else {
|
|
16596
|
+
sameErrorCount.error = "Insufficient tokens received";
|
|
16597
|
+
sameErrorCount.count = 1;
|
|
16598
|
+
}
|
|
16599
|
+
} else if (err.message.includes("Could not reach the end of the program")) {
|
|
16600
|
+
logger.error("Could not reach the end of the program, may be the block is full (could be a temp/permanent gas issue)");
|
|
16601
|
+
if (sameErrorCount.error == "Could not reach the end of the program") {
|
|
16602
|
+
sameErrorCount.count++;
|
|
16603
|
+
} else {
|
|
16604
|
+
sameErrorCount.error = "Could not reach the end of the program";
|
|
16605
|
+
sameErrorCount.count = 1;
|
|
16606
|
+
}
|
|
16580
16607
|
} else {
|
|
16581
16608
|
logger.error("Unexpected error:", err);
|
|
16582
16609
|
throw err;
|
|
@@ -16589,7 +16616,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16589
16616
|
isSellTokenToken0,
|
|
16590
16617
|
retry + 1,
|
|
16591
16618
|
lowerLimit,
|
|
16592
|
-
upperLimit
|
|
16619
|
+
upperLimit,
|
|
16620
|
+
MAX_RETRIES,
|
|
16621
|
+
sameErrorCount,
|
|
16622
|
+
MAX_SAME_ERROR_COUNT
|
|
16593
16623
|
);
|
|
16594
16624
|
}
|
|
16595
16625
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -16195,7 +16195,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16195
16195
|
}
|
|
16196
16196
|
};
|
|
16197
16197
|
}
|
|
16198
|
-
async getSwapInfoToHandleUnused(considerRebalance = true, newBounds = null, maxIterations = 20, priceRatioPrecision = 4) {
|
|
16198
|
+
async getSwapInfoToHandleUnused(considerRebalance = true, newBounds = null, maxIterations = 20, priceRatioPrecision = 4, getQuoteCallback = this.avnu.getQuotes) {
|
|
16199
16199
|
const poolKey = await this.getPoolKey();
|
|
16200
16200
|
const unusedBalances = await this.unusedBalances(poolKey);
|
|
16201
16201
|
const { amount: token0Bal1, usdValue: token0PriceUsd } = unusedBalances.token0;
|
|
@@ -16235,7 +16235,8 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16235
16235
|
token1Bal,
|
|
16236
16236
|
ekuboBounds,
|
|
16237
16237
|
maxIterations,
|
|
16238
|
-
priceRatioPrecision
|
|
16238
|
+
priceRatioPrecision,
|
|
16239
|
+
getQuoteCallback
|
|
16239
16240
|
);
|
|
16240
16241
|
}
|
|
16241
16242
|
assertValidBounds(bounds) {
|
|
@@ -16280,7 +16281,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16280
16281
|
* @returns {Promise<SwapInfo>}
|
|
16281
16282
|
*
|
|
16282
16283
|
*/
|
|
16283
|
-
async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds, maxIterations = 20, priceRatioPrecision = 4) {
|
|
16284
|
+
async getSwapInfoGivenAmounts(poolKey, token0Bal, token1Bal, bounds, maxIterations = 20, priceRatioPrecision = 4, getQuoteCallback = this.avnu.getQuotes) {
|
|
16284
16285
|
logger.verbose(
|
|
16285
16286
|
`${_EkuboCLVault.name}: getSwapInfoGivenAmounts::pre => token0Bal: ${token0Bal.toString()}, token1Bal: ${token1Bal.toString()}`
|
|
16286
16287
|
);
|
|
@@ -16315,12 +16316,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16315
16316
|
if (amountToSell.eq(0)) {
|
|
16316
16317
|
return AvnuWrapper.buildZeroSwap(tokenToSell, this.address.address);
|
|
16317
16318
|
}
|
|
16318
|
-
const quote = await this.
|
|
16319
|
-
tokenToSell.address,
|
|
16320
|
-
tokenToBuy.address,
|
|
16321
|
-
amountToSell.toWei(),
|
|
16322
|
-
this.address.address
|
|
16323
|
-
);
|
|
16319
|
+
const quote = await getQuoteCallback(tokenToSell.address, tokenToBuy.address, amountToSell.toWei(), this.address.address);
|
|
16324
16320
|
if (remainingSellAmount.eq(0)) {
|
|
16325
16321
|
const minAmountOut = Web3Number.fromWei(
|
|
16326
16322
|
quote.buyAmount.toString(),
|
|
@@ -16403,13 +16399,20 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16403
16399
|
* @param retry - Current retry attempt number (default 0)
|
|
16404
16400
|
* @param adjustmentFactor - Percentage to adjust swap amount by (default 1)
|
|
16405
16401
|
* @param isToken0Deficit - Whether token0 balance needs increasing (default true)
|
|
16402
|
+
* @param MAX_RETRIES - Maximum number of retries (default 40)
|
|
16403
|
+
* @param sameErrorCount - For certain errors, we just retry with same amount again. This is the count of such retries (default { count: 0, error: null })
|
|
16404
|
+
* @param MAX_SAME_ERROR_COUNT - For certain errors, we just retry with same amount again. This limits such retries (default 10)
|
|
16406
16405
|
* @returns Array of contract calls needed for rebalancing
|
|
16407
|
-
* @throws Error if max retries reached without successful rebalance
|
|
16406
|
+
* @throws Error if max retries reached without successful rebalance or max same errors reached
|
|
16408
16407
|
*/
|
|
16409
|
-
async rebalanceIter(swapInfo, acc, estimateCall, isSellTokenToken0 = true, retry = 0, lowerLimit = 0n, upperLimit = 0n, MAX_RETRIES = 40) {
|
|
16408
|
+
async rebalanceIter(swapInfo, acc, estimateCall, isSellTokenToken0 = true, retry = 0, lowerLimit = 0n, upperLimit = 0n, MAX_RETRIES = 40, sameErrorCount = { count: 0, error: null }, MAX_SAME_ERROR_COUNT = 10) {
|
|
16410
16409
|
logger.verbose(
|
|
16411
|
-
`Rebalancing ${this.metadata.name}: retry=${retry}, lowerLimit=${lowerLimit}, upperLimit=${upperLimit}, isSellTokenToken0=${isSellTokenToken0}`
|
|
16410
|
+
`Rebalancing ${this.metadata.name}: retry=${retry}, lowerLimit=${lowerLimit}, upperLimit=${upperLimit}, isSellTokenToken0=${isSellTokenToken0}, MAX_RETRIES=${MAX_RETRIES}, sameErrorCount=${sameErrorCount.error} (${sameErrorCount.count})`
|
|
16412
16411
|
);
|
|
16412
|
+
if (sameErrorCount.count >= MAX_SAME_ERROR_COUNT) {
|
|
16413
|
+
logger.error(`Rebalance failed after ${MAX_SAME_ERROR_COUNT} same errors`);
|
|
16414
|
+
throw new Error(`Rebalance failed after ${MAX_SAME_ERROR_COUNT} same errors`);
|
|
16415
|
+
}
|
|
16413
16416
|
const fromAmount = uint2564.uint256ToBN(swapInfo.token_from_amount);
|
|
16414
16417
|
logger.verbose(
|
|
16415
16418
|
`Selling ${fromAmount.toString()} of token ${swapInfo.token_from_address}`
|
|
@@ -16428,7 +16431,7 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16428
16431
|
);
|
|
16429
16432
|
const newSwapInfo = { ...swapInfo };
|
|
16430
16433
|
const currentAmount = Web3Number.fromWei(fromAmount.toString(), 18);
|
|
16431
|
-
logger.verbose(`Current amount: ${currentAmount.toString()}`);
|
|
16434
|
+
logger.verbose(`Current amount: ${currentAmount.toString()}, lowerLimit: ${lowerLimit.toString()}, upperLimit: ${upperLimit.toString()}`);
|
|
16432
16435
|
if (err.message.includes("invalid token0 balance") || err.message.includes("invalid token0 amount")) {
|
|
16433
16436
|
if (!isSellTokenToken0) {
|
|
16434
16437
|
logger.verbose("Reducing swap amount - excess token0");
|
|
@@ -16475,6 +16478,30 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16475
16478
|
}
|
|
16476
16479
|
newSwapInfo.token_from_amount = uint2564.bnToUint256(nextAmount);
|
|
16477
16480
|
}
|
|
16481
|
+
} else if (err.message.includes("Residual tokens")) {
|
|
16482
|
+
logger.error("Residual tokens");
|
|
16483
|
+
if (sameErrorCount.error == "Residual tokens") {
|
|
16484
|
+
sameErrorCount.count++;
|
|
16485
|
+
} else {
|
|
16486
|
+
sameErrorCount.error = "Residual tokens";
|
|
16487
|
+
sameErrorCount.count = 1;
|
|
16488
|
+
}
|
|
16489
|
+
} else if (err.message.includes("Insufficient tokens received")) {
|
|
16490
|
+
logger.error("Insufficient tokens received");
|
|
16491
|
+
if (sameErrorCount.error == "Insufficient tokens received") {
|
|
16492
|
+
sameErrorCount.count++;
|
|
16493
|
+
} else {
|
|
16494
|
+
sameErrorCount.error = "Insufficient tokens received";
|
|
16495
|
+
sameErrorCount.count = 1;
|
|
16496
|
+
}
|
|
16497
|
+
} else if (err.message.includes("Could not reach the end of the program")) {
|
|
16498
|
+
logger.error("Could not reach the end of the program, may be the block is full (could be a temp/permanent gas issue)");
|
|
16499
|
+
if (sameErrorCount.error == "Could not reach the end of the program") {
|
|
16500
|
+
sameErrorCount.count++;
|
|
16501
|
+
} else {
|
|
16502
|
+
sameErrorCount.error = "Could not reach the end of the program";
|
|
16503
|
+
sameErrorCount.count = 1;
|
|
16504
|
+
}
|
|
16478
16505
|
} else {
|
|
16479
16506
|
logger.error("Unexpected error:", err);
|
|
16480
16507
|
throw err;
|
|
@@ -16487,7 +16514,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16487
16514
|
isSellTokenToken0,
|
|
16488
16515
|
retry + 1,
|
|
16489
16516
|
lowerLimit,
|
|
16490
|
-
upperLimit
|
|
16517
|
+
upperLimit,
|
|
16518
|
+
MAX_RETRIES,
|
|
16519
|
+
sameErrorCount,
|
|
16520
|
+
MAX_SAME_ERROR_COUNT
|
|
16491
16521
|
);
|
|
16492
16522
|
}
|
|
16493
16523
|
}
|
package/package.json
CHANGED
|
@@ -40,6 +40,7 @@ import { DepegRiskLevel, ImpermanentLossLevel, MarketRiskLevel, SmartContractRis
|
|
|
40
40
|
import { gql } from "@apollo/client";
|
|
41
41
|
import apolloClient from "@/modules/apollo-client";
|
|
42
42
|
import { binarySearch } from "@/utils/math-utils";
|
|
43
|
+
import { Quote } from "@avnu/avnu-sdk";
|
|
43
44
|
|
|
44
45
|
export interface EkuboPoolKey {
|
|
45
46
|
token0: ContractAddr;
|
|
@@ -1080,7 +1081,12 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
1080
1081
|
};
|
|
1081
1082
|
}
|
|
1082
1083
|
|
|
1083
|
-
async getSwapInfoToHandleUnused(
|
|
1084
|
+
async getSwapInfoToHandleUnused(
|
|
1085
|
+
considerRebalance: boolean = true,
|
|
1086
|
+
newBounds: EkuboBounds | null = null,
|
|
1087
|
+
maxIterations = 20, priceRatioPrecision = 4,
|
|
1088
|
+
getQuoteCallback: (tokenToSell: string, tokenToBuy: string, amountWei: string, beneficiary: string) => Promise<Quote> = this.avnu.getQuotes
|
|
1089
|
+
): Promise<SwapInfo> {
|
|
1084
1090
|
const poolKey = await this.getPoolKey();
|
|
1085
1091
|
|
|
1086
1092
|
// fetch current unused balances of vault
|
|
@@ -1145,7 +1151,8 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
1145
1151
|
token1Bal,
|
|
1146
1152
|
ekuboBounds,
|
|
1147
1153
|
maxIterations,
|
|
1148
|
-
priceRatioPrecision
|
|
1154
|
+
priceRatioPrecision,
|
|
1155
|
+
getQuoteCallback
|
|
1149
1156
|
);
|
|
1150
1157
|
}
|
|
1151
1158
|
|
|
@@ -1229,7 +1236,8 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
1229
1236
|
token1Bal: Web3Number,
|
|
1230
1237
|
bounds: EkuboBounds,
|
|
1231
1238
|
maxIterations: number = 20,
|
|
1232
|
-
priceRatioPrecision: number = 4
|
|
1239
|
+
priceRatioPrecision: number = 4,
|
|
1240
|
+
getQuoteCallback: (tokenToSell: string, tokenToBuy: string, amountWei: string, beneficiary: string) => Promise<Quote> = this.avnu.getQuotes
|
|
1233
1241
|
): Promise<SwapInfo> {
|
|
1234
1242
|
logger.verbose(
|
|
1235
1243
|
`${
|
|
@@ -1284,12 +1292,7 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
1284
1292
|
}
|
|
1285
1293
|
|
|
1286
1294
|
// Get a quote for swapping the calculated amount
|
|
1287
|
-
const quote = await this.
|
|
1288
|
-
tokenToSell.address,
|
|
1289
|
-
tokenToBuy.address,
|
|
1290
|
-
amountToSell.toWei(),
|
|
1291
|
-
this.address.address
|
|
1292
|
-
);
|
|
1295
|
+
const quote = await getQuoteCallback(tokenToSell.address, tokenToBuy.address, amountToSell.toWei(), this.address.address);
|
|
1293
1296
|
|
|
1294
1297
|
// If all of the token is to be swapped, return the swap info directly
|
|
1295
1298
|
if (remainingSellAmount.eq(0)) {
|
|
@@ -1399,8 +1402,11 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
1399
1402
|
* @param retry - Current retry attempt number (default 0)
|
|
1400
1403
|
* @param adjustmentFactor - Percentage to adjust swap amount by (default 1)
|
|
1401
1404
|
* @param isToken0Deficit - Whether token0 balance needs increasing (default true)
|
|
1405
|
+
* @param MAX_RETRIES - Maximum number of retries (default 40)
|
|
1406
|
+
* @param sameErrorCount - For certain errors, we just retry with same amount again. This is the count of such retries (default { count: 0, error: null })
|
|
1407
|
+
* @param MAX_SAME_ERROR_COUNT - For certain errors, we just retry with same amount again. This limits such retries (default 10)
|
|
1402
1408
|
* @returns Array of contract calls needed for rebalancing
|
|
1403
|
-
* @throws Error if max retries reached without successful rebalance
|
|
1409
|
+
* @throws Error if max retries reached without successful rebalance or max same errors reached
|
|
1404
1410
|
*/
|
|
1405
1411
|
async rebalanceIter(
|
|
1406
1412
|
swapInfo: SwapInfo,
|
|
@@ -1410,14 +1416,21 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
1410
1416
|
retry = 0,
|
|
1411
1417
|
lowerLimit = 0n,
|
|
1412
1418
|
upperLimit = 0n,
|
|
1413
|
-
MAX_RETRIES = 40
|
|
1419
|
+
MAX_RETRIES = 40,
|
|
1420
|
+
sameErrorCount: { count: number, error: null | string } = { count: 0, error: null },
|
|
1421
|
+
MAX_SAME_ERROR_COUNT = 10
|
|
1414
1422
|
): Promise<Call[]> {
|
|
1415
1423
|
|
|
1416
1424
|
logger.verbose(
|
|
1417
1425
|
`Rebalancing ${this.metadata.name}: ` +
|
|
1418
|
-
`retry=${retry}, lowerLimit=${lowerLimit}, upperLimit=${upperLimit}, isSellTokenToken0=${isSellTokenToken0}`
|
|
1426
|
+
`retry=${retry}, lowerLimit=${lowerLimit}, upperLimit=${upperLimit}, isSellTokenToken0=${isSellTokenToken0}, MAX_RETRIES=${MAX_RETRIES}, sameErrorCount=${sameErrorCount.error} (${sameErrorCount.count})`
|
|
1419
1427
|
);
|
|
1420
1428
|
|
|
1429
|
+
if (sameErrorCount.count >= MAX_SAME_ERROR_COUNT) {
|
|
1430
|
+
logger.error(`Rebalance failed after ${MAX_SAME_ERROR_COUNT} same errors`);
|
|
1431
|
+
throw new Error(`Rebalance failed after ${MAX_SAME_ERROR_COUNT} same errors`);
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1421
1434
|
const fromAmount = uint256.uint256ToBN(swapInfo.token_from_amount);
|
|
1422
1435
|
logger.verbose(
|
|
1423
1436
|
`Selling ${fromAmount.toString()} of token ${swapInfo.token_from_address}`
|
|
@@ -1439,7 +1452,7 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
1439
1452
|
|
|
1440
1453
|
const newSwapInfo = { ...swapInfo };
|
|
1441
1454
|
const currentAmount = Web3Number.fromWei(fromAmount.toString(), 18); // 18 is ok, as its toWei eventually anyways
|
|
1442
|
-
logger.verbose(`Current amount: ${currentAmount.toString()}`);
|
|
1455
|
+
logger.verbose(`Current amount: ${currentAmount.toString()}, lowerLimit: ${lowerLimit.toString()}, upperLimit: ${upperLimit.toString()}`);
|
|
1443
1456
|
if (
|
|
1444
1457
|
err.message.includes("invalid token0 balance") ||
|
|
1445
1458
|
err.message.includes("invalid token0 amount")
|
|
@@ -1492,6 +1505,33 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
1492
1505
|
}
|
|
1493
1506
|
newSwapInfo.token_from_amount = uint256.bnToUint256(nextAmount);
|
|
1494
1507
|
}
|
|
1508
|
+
} else if (err.message.includes("Residual tokens")) {
|
|
1509
|
+
logger.error("Residual tokens");
|
|
1510
|
+
if (sameErrorCount.error == "Residual tokens") {
|
|
1511
|
+
sameErrorCount.count++;
|
|
1512
|
+
} else {
|
|
1513
|
+
sameErrorCount.error = "Residual tokens";
|
|
1514
|
+
sameErrorCount.count = 1;
|
|
1515
|
+
}
|
|
1516
|
+
// dont do anything, just try again.
|
|
1517
|
+
} else if (err.message.includes("Insufficient tokens received")) {
|
|
1518
|
+
logger.error("Insufficient tokens received");
|
|
1519
|
+
if (sameErrorCount.error == "Insufficient tokens received") {
|
|
1520
|
+
sameErrorCount.count++;
|
|
1521
|
+
} else {
|
|
1522
|
+
sameErrorCount.error = "Insufficient tokens received";
|
|
1523
|
+
sameErrorCount.count = 1;
|
|
1524
|
+
}
|
|
1525
|
+
// dont do anything, just try again.
|
|
1526
|
+
} else if (err.message.includes("Could not reach the end of the program")) {
|
|
1527
|
+
logger.error("Could not reach the end of the program, may be the block is full (could be a temp/permanent gas issue)");
|
|
1528
|
+
if (sameErrorCount.error == "Could not reach the end of the program") {
|
|
1529
|
+
sameErrorCount.count++;
|
|
1530
|
+
} else {
|
|
1531
|
+
sameErrorCount.error = "Could not reach the end of the program";
|
|
1532
|
+
sameErrorCount.count = 1;
|
|
1533
|
+
}
|
|
1534
|
+
// just try again.
|
|
1495
1535
|
} else {
|
|
1496
1536
|
logger.error("Unexpected error:", err);
|
|
1497
1537
|
throw err;
|
|
@@ -1504,7 +1544,10 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
1504
1544
|
isSellTokenToken0,
|
|
1505
1545
|
retry + 1,
|
|
1506
1546
|
lowerLimit,
|
|
1507
|
-
upperLimit
|
|
1547
|
+
upperLimit,
|
|
1548
|
+
MAX_RETRIES,
|
|
1549
|
+
sameErrorCount,
|
|
1550
|
+
MAX_SAME_ERROR_COUNT
|
|
1508
1551
|
);
|
|
1509
1552
|
}
|
|
1510
1553
|
}
|