@strkfarm/sdk 1.1.50 → 1.1.51

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.
@@ -53725,10 +53725,9 @@ ${JSON.stringify(data, null, 2)}`;
53725
53725
  }
53726
53726
 
53727
53727
  // src/modules/avnu.ts
53728
- var AvnuWrapper = class _AvnuWrapper {
53728
+ var AvnuWrapper = class {
53729
53729
  async getQuotes(fromToken, toToken, amountWei, taker, retry = 0, excludeSources = ["Haiko(Solvers)"]) {
53730
53730
  const MAX_RETRY = 5;
53731
- logger2.verbose(`${_AvnuWrapper.name}: getQuotes => Getting quotes for ${fromToken} -> ${toToken}, amount: ${amountWei}, taker: ${taker}, retry: ${retry}`);
53732
53731
  const params = {
53733
53732
  sellTokenAddress: fromToken,
53734
53733
  buyTokenAddress: toToken,
@@ -53771,9 +53770,6 @@ ${JSON.stringify(data, null, 2)}`;
53771
53770
  startIndex += 5 + swap_params_len;
53772
53771
  }
53773
53772
  const _minAmount = minAmount || (quote.buyAmount * 95n / 100n).toString();
53774
- logger2.verbose(`${_AvnuWrapper.name}: getSwapInfo => sellToken: ${quote.sellTokenAddress}, sellAmount: ${quote.sellAmount}`);
53775
- logger2.verbose(`${_AvnuWrapper.name}: getSwapInfo => buyToken: ${quote.buyTokenAddress}`);
53776
- logger2.verbose(`${_AvnuWrapper.name}: getSwapInfo => buyAmount: ${quote.buyAmount}, minAmount: ${_minAmount}`);
53777
53773
  const swapInfo = {
53778
53774
  token_from_address: quote.sellTokenAddress,
53779
53775
  token_from_amount: uint256_exports.bnToUint256(quote.sellAmount),
@@ -55736,20 +55732,26 @@ ${JSON.stringify(data, null, 2)}`;
55736
55732
  const rewards = await this.getHarvests(addr);
55737
55733
  if (rewards.length == 0) return [];
55738
55734
  const unClaimed = [];
55739
- const reward = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime())[0];
55740
- const cls = await this.config.provider.getClassAt(reward.rewardsContract.address);
55741
- const contract = new Contract({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
55742
- const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
55743
- logger2.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
55744
- if (isClaimed) {
55745
- return unClaimed;
55746
- }
55747
- const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
55748
- if (bal.lessThan(reward.claim.amount)) {
55749
- logger2.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
55750
- return unClaimed;
55751
- }
55752
- unClaimed.unshift(reward);
55735
+ const sortedRewards = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime());
55736
+ if (sortedRewards.length == 0) {
55737
+ logger2.verbose(`${_Harvests.name}: no rewards found`);
55738
+ return [];
55739
+ }
55740
+ const cls = await this.config.provider.getClassAt(sortedRewards[0].rewardsContract.address);
55741
+ for (const reward of sortedRewards) {
55742
+ const contract = new Contract({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
55743
+ const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
55744
+ logger2.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}, claim id: ${reward.claim.id}, address: ${reward.rewardsContract.address}`);
55745
+ if (isClaimed) {
55746
+ continue;
55747
+ }
55748
+ const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
55749
+ if (bal.lessThan(reward.claim.amount)) {
55750
+ logger2.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
55751
+ continue;
55752
+ }
55753
+ unClaimed.push(reward);
55754
+ }
55753
55755
  return unClaimed;
55754
55756
  }
55755
55757
  };
@@ -80563,11 +80565,15 @@ spurious results.`);
80563
80565
  amount1
80564
80566
  };
80565
80567
  }
80566
- async harvest(acc, maxIterations = 20, priceRatioPrecision = 4) {
80568
+ async harvest(acc, maxIterations = 20, priceRatioPrecision = 4, minRewardAmount = new Web3Number(0, 18)) {
80567
80569
  const ekuboHarvests = new EkuboHarvests(this.config);
80568
- const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(
80570
+ const unClaimedRewards = (await ekuboHarvests.getUnHarvestedRewards(
80569
80571
  this.address
80570
- );
80572
+ )).filter((claim) => claim.actualReward.greaterThanOrEqualTo(minRewardAmount));
80573
+ if (unClaimedRewards.length == 0) {
80574
+ logger2.verbose(`${_EkuboCLVault.name}: harvest => no unclaimed rewards found`);
80575
+ return [];
80576
+ }
80571
80577
  const poolKey = await this.getPoolKey();
80572
80578
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
80573
80579
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
@@ -80576,7 +80582,10 @@ spurious results.`);
80576
80582
  `${_EkuboCLVault.name}: harvest => unClaimedRewards: ${unClaimedRewards.length}`
80577
80583
  );
80578
80584
  const calls = [];
80579
- for (let claim of unClaimedRewards) {
80585
+ const chosenClaim = unClaimedRewards[0];
80586
+ logger2.info(`${_EkuboCLVault.name}: harvest => doing one at a time`);
80587
+ logger2.info(`${_EkuboCLVault.name}: harvest => chosenClaim -> Claim ID: ${chosenClaim.claim.id}, Amount: ${chosenClaim.claim.amount.toString()}, actualAmount: ${chosenClaim.actualReward.toString()}, addr: ${chosenClaim.claim.claimee.toString()}`);
80588
+ for (let claim of [chosenClaim]) {
80580
80589
  const fee = claim.claim.amount.multipliedBy(this.metadata.additionalInfo.feeBps).dividedBy(1e4);
80581
80590
  const postFeeAmount = claim.claim.amount.minus(fee);
80582
80591
  const isToken1 = claim.token.eq(poolKey.token1);
@@ -80625,57 +80634,41 @@ spurious results.`);
80625
80634
  const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
80626
80635
  const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
80627
80636
  logger2.verbose(
80628
- `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
80629
- );
80630
- const swapInfo = await this.getSwapInfoGivenAmounts(
80631
- poolKey,
80632
- token0Amt,
80633
- token1Amt,
80634
- bounds,
80635
- maxIterations,
80636
- priceRatioPrecision
80637
- );
80638
- swapInfo.token_to_address = token0Info.address.address;
80639
- logger2.verbose(
80640
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
80637
+ `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toFixed(18)}, token1Amt: ${token1Amt.toFixed(18)}`
80641
80638
  );
80642
80639
  logger2.verbose(
80643
80640
  `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
80644
80641
  );
80645
- const harvestEstimateCall = async (swapInfo1) => {
80646
- const swap1Amount = Web3Number.fromWei(
80647
- uint256_exports.uint256ToBN(swapInfo1.token_from_amount).toString(),
80648
- 18
80649
- // cause its always STRK?
80642
+ const claimTokenInfo = await Global.getTokenInfoFromAddr(claim.token);
80643
+ const harvestEstimateCall = async (baseSwapInfo2) => {
80644
+ let baseSwapAmount = Web3Number.fromWei(
80645
+ uint256_exports.uint256ToBN(baseSwapInfo2.token_from_amount).toString(),
80646
+ claimTokenInfo.decimals
80650
80647
  ).minimum(
80651
- postFeeAmount.toFixed(18)
80652
- // cause always strk
80653
- );
80654
- swapInfo.token_from_amount = uint256_exports.bnToUint256(swap1Amount.toWei());
80655
- swapInfo.token_to_min_amount = uint256_exports.bnToUint256(
80656
- swap1Amount.multipliedBy(0).toWei()
80657
- // placeholder
80648
+ postFeeAmount.toFixed(claimTokenInfo.decimals)
80658
80649
  );
80650
+ if (baseSwapAmount.lt(1e-4)) {
80651
+ baseSwapAmount = new Web3Number(0, claimTokenInfo.decimals);
80652
+ }
80653
+ baseSwapInfo2.token_from_amount = uint256_exports.bnToUint256(baseSwapAmount.toWei());
80654
+ const isToken0ClaimToken2 = claim.token.eq(poolKey.token0);
80659
80655
  logger2.verbose(
80660
- `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
80656
+ `${_EkuboCLVault.name}: harvest => isToken0ClaimToken: ${isToken0ClaimToken2}, baseSwapAmount: ${baseSwapAmount}`
80661
80657
  );
80662
- const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
80658
+ const remainingAmount = postFeeAmount.minus(baseSwapAmount).maximum(0);
80663
80659
  logger2.verbose(
80664
80660
  `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
80665
80661
  );
80666
- const swapInfo2 = {
80667
- ...swapInfo,
80668
- token_from_amount: uint256_exports.bnToUint256(remainingAmount.toWei())
80669
- };
80670
- swapInfo2.token_to_address = token1Info.address.address;
80662
+ let dummySwapInfo = AvnuWrapper.buildZeroSwap(claim.token, this.address.address, claim.token);
80663
+ dummySwapInfo.token_from_amount = uint256_exports.bnToUint256(remainingAmount.toWei());
80671
80664
  logger2.verbose(
80672
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
80673
- swapInfo
80665
+ `${_EkuboCLVault.name}: harvest => dummySwapInfo: ${JSON.stringify(
80666
+ dummySwapInfo
80674
80667
  )}`
80675
80668
  );
80676
80669
  logger2.verbose(
80677
- `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
80678
- swapInfo2
80670
+ `${_EkuboCLVault.name}: harvest => baseSwapInfo: ${JSON.stringify(
80671
+ baseSwapInfo2
80679
80672
  )}`
80680
80673
  );
80681
80674
  const calldata = [
@@ -80686,18 +80679,36 @@ spurious results.`);
80686
80679
  claimee: claim.claim.claimee.address
80687
80680
  },
80688
80681
  claim.proof.map((p) => num_exports.getDecimalString(p)),
80689
- swapInfo,
80690
- swapInfo2
80682
+ isToken0ClaimToken2 ? dummySwapInfo : baseSwapInfo2,
80683
+ // is token0 claim token, its just dummy swap
80684
+ isToken0ClaimToken2 ? baseSwapInfo2 : dummySwapInfo
80691
80685
  ];
80692
- logger2.verbose(
80693
- `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
80694
- calldata
80695
- )}`
80696
- );
80697
80686
  return [this.contract.populate("harvest", calldata)];
80698
80687
  };
80688
+ const isToken0ClaimToken = claim.token.eq(poolKey.token0);
80689
+ let baseSwapInfo = AvnuWrapper.buildZeroSwap(claim.token, this.address.address, isToken0ClaimToken ? token1Info.address : token0Info.address);
80690
+ baseSwapInfo.token_from_amount = uint256_exports.bnToUint256(postFeeAmount.toWei());
80691
+ if (postFeeAmount.greaterThan(0) && !isToken0ClaimToken) {
80692
+ const avnuWrapper = new AvnuWrapper();
80693
+ const quote = await avnuWrapper.getQuotes(
80694
+ claim.token.address,
80695
+ token0Info.address.address,
80696
+ postFeeAmount.toWei(),
80697
+ this.address.address
80698
+ );
80699
+ baseSwapInfo = await avnuWrapper.getSwapInfo(quote, this.address.address, 0, this.address.address);
80700
+ } else if (postFeeAmount.greaterThan(0) && isToken0ClaimToken) {
80701
+ const avnuWrapper = new AvnuWrapper();
80702
+ const quote = await avnuWrapper.getQuotes(
80703
+ claim.token.address,
80704
+ token1Info.address.address,
80705
+ postFeeAmount.toWei(),
80706
+ this.address.address
80707
+ );
80708
+ baseSwapInfo = await avnuWrapper.getSwapInfo(quote, this.address.address, 0, this.address.address);
80709
+ }
80699
80710
  const _callsFinal = await this.rebalanceIter(
80700
- swapInfo,
80711
+ baseSwapInfo,
80701
80712
  acc,
80702
80713
  harvestEstimateCall,
80703
80714
  claim.token.eq(poolKey.token0),
@@ -80741,32 +80752,40 @@ spurious results.`);
80741
80752
  async harvestMismatchEstimateCallFn(params) {
80742
80753
  const { postFeeAmount, claim, token0Info, token1Info, acc } = params;
80743
80754
  let harvestCall = null;
80755
+ logger2.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => postFeeAmount: ${postFeeAmount.toString()}`);
80756
+ let attempt = 0;
80757
+ let MAX_ATTEMPTS = 50;
80744
80758
  const binarySearchCallbackFn = async (mid) => {
80759
+ attempt++;
80760
+ logger2.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => mid: ${mid}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
80745
80761
  const rewardPart2 = BigInt(postFeeAmount.toWei()) - mid;
80746
80762
  const avnuWrapper = new AvnuWrapper();
80747
80763
  const beneficiary = this.address.address;
80748
- const quote1 = await avnuWrapper.getQuotes(
80764
+ const quote1Prom = avnuWrapper.getQuotes(
80749
80765
  claim.token.address,
80750
80766
  token0Info.address.address,
80751
80767
  mid.toString(),
80752
80768
  beneficiary
80753
80769
  );
80770
+ const quote2Prom = avnuWrapper.getQuotes(
80771
+ claim.token.address,
80772
+ token1Info.address.address,
80773
+ rewardPart2.toString(),
80774
+ beneficiary
80775
+ );
80776
+ const [quote1, quote2] = await Promise.all([quote1Prom, quote2Prom]);
80754
80777
  const swapInfo1 = await avnuWrapper.getSwapInfo(
80755
80778
  quote1,
80756
80779
  beneficiary,
80757
80780
  0,
80758
- beneficiary
80759
- );
80760
- const quote2 = await avnuWrapper.getQuotes(
80761
- claim.token.address,
80762
- token1Info.address.address,
80763
- rewardPart2.toString(),
80781
+ // fee bps
80764
80782
  beneficiary
80765
80783
  );
80766
80784
  const swapInfo2 = await avnuWrapper.getSwapInfo(
80767
80785
  quote2,
80768
80786
  beneficiary,
80769
80787
  0,
80788
+ // fee bps
80770
80789
  beneficiary
80771
80790
  );
80772
80791
  try {
@@ -80783,13 +80802,17 @@ spurious results.`);
80783
80802
  ];
80784
80803
  harvestCall = this.contract.populate("harvest", calldata);
80785
80804
  const gas = await acc.estimateInvokeFee(harvestCall);
80805
+ logger2.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => gas: ${gas.overall_fee.toString()}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
80786
80806
  return "found";
80787
80807
  } catch (err2) {
80788
80808
  if (err2.message.includes("invalid token0 amount")) {
80809
+ logger2.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => invalid token0 amount, attempt: ${attempt}/${MAX_ATTEMPTS}`);
80789
80810
  return "go_low";
80790
80811
  } else if (err2.message.includes("invalid token1 amount")) {
80812
+ logger2.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => invalid token1 amount, attempt: ${attempt}/${MAX_ATTEMPTS}`);
80791
80813
  return "go_high";
80792
80814
  }
80815
+ logger2.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => error: ${err2.message}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
80793
80816
  return "retry";
80794
80817
  }
80795
80818
  };
@@ -2116,10 +2116,9 @@ function getTrovesEndpoint() {
2116
2116
  }
2117
2117
 
2118
2118
  // src/modules/avnu.ts
2119
- var AvnuWrapper = class _AvnuWrapper {
2119
+ var AvnuWrapper = class {
2120
2120
  async getQuotes(fromToken, toToken, amountWei, taker, retry = 0, excludeSources = ["Haiko(Solvers)"]) {
2121
2121
  const MAX_RETRY = 5;
2122
- logger.verbose(`${_AvnuWrapper.name}: getQuotes => Getting quotes for ${fromToken} -> ${toToken}, amount: ${amountWei}, taker: ${taker}, retry: ${retry}`);
2123
2122
  const params = {
2124
2123
  sellTokenAddress: fromToken,
2125
2124
  buyTokenAddress: toToken,
@@ -2162,9 +2161,6 @@ var AvnuWrapper = class _AvnuWrapper {
2162
2161
  startIndex += 5 + swap_params_len;
2163
2162
  }
2164
2163
  const _minAmount = minAmount || (quote.buyAmount * 95n / 100n).toString();
2165
- logger.verbose(`${_AvnuWrapper.name}: getSwapInfo => sellToken: ${quote.sellTokenAddress}, sellAmount: ${quote.sellAmount}`);
2166
- logger.verbose(`${_AvnuWrapper.name}: getSwapInfo => buyToken: ${quote.buyTokenAddress}`);
2167
- logger.verbose(`${_AvnuWrapper.name}: getSwapInfo => buyAmount: ${quote.buyAmount}, minAmount: ${_minAmount}`);
2168
2164
  const swapInfo = {
2169
2165
  token_from_address: quote.sellTokenAddress,
2170
2166
  token_from_amount: uint256.bnToUint256(quote.sellAmount),
@@ -4136,20 +4132,26 @@ var Harvests = class _Harvests {
4136
4132
  const rewards = await this.getHarvests(addr);
4137
4133
  if (rewards.length == 0) return [];
4138
4134
  const unClaimed = [];
4139
- const reward = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime())[0];
4140
- const cls = await this.config.provider.getClassAt(reward.rewardsContract.address);
4141
- const contract = new Contract4({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
4142
- const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
4143
- logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
4144
- if (isClaimed) {
4145
- return unClaimed;
4135
+ const sortedRewards = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime());
4136
+ if (sortedRewards.length == 0) {
4137
+ logger.verbose(`${_Harvests.name}: no rewards found`);
4138
+ return [];
4146
4139
  }
4147
- const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
4148
- if (bal.lessThan(reward.claim.amount)) {
4149
- logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
4150
- return unClaimed;
4140
+ const cls = await this.config.provider.getClassAt(sortedRewards[0].rewardsContract.address);
4141
+ for (const reward of sortedRewards) {
4142
+ const contract = new Contract4({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
4143
+ const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
4144
+ logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}, claim id: ${reward.claim.id}, address: ${reward.rewardsContract.address}`);
4145
+ if (isClaimed) {
4146
+ continue;
4147
+ }
4148
+ const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
4149
+ if (bal.lessThan(reward.claim.amount)) {
4150
+ logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
4151
+ continue;
4152
+ }
4153
+ unClaimed.push(reward);
4151
4154
  }
4152
- unClaimed.unshift(reward);
4153
4155
  return unClaimed;
4154
4156
  }
4155
4157
  };
@@ -16640,11 +16642,15 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16640
16642
  amount1
16641
16643
  };
16642
16644
  }
16643
- async harvest(acc, maxIterations = 20, priceRatioPrecision = 4) {
16645
+ async harvest(acc, maxIterations = 20, priceRatioPrecision = 4, minRewardAmount = new Web3Number(0, 18)) {
16644
16646
  const ekuboHarvests = new EkuboHarvests(this.config);
16645
- const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(
16647
+ const unClaimedRewards = (await ekuboHarvests.getUnHarvestedRewards(
16646
16648
  this.address
16647
- );
16649
+ )).filter((claim) => claim.actualReward.greaterThanOrEqualTo(minRewardAmount));
16650
+ if (unClaimedRewards.length == 0) {
16651
+ logger.verbose(`${_EkuboCLVault.name}: harvest => no unclaimed rewards found`);
16652
+ return [];
16653
+ }
16648
16654
  const poolKey = await this.getPoolKey();
16649
16655
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
16650
16656
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
@@ -16653,7 +16659,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16653
16659
  `${_EkuboCLVault.name}: harvest => unClaimedRewards: ${unClaimedRewards.length}`
16654
16660
  );
16655
16661
  const calls = [];
16656
- for (let claim of unClaimedRewards) {
16662
+ const chosenClaim = unClaimedRewards[0];
16663
+ logger.info(`${_EkuboCLVault.name}: harvest => doing one at a time`);
16664
+ logger.info(`${_EkuboCLVault.name}: harvest => chosenClaim -> Claim ID: ${chosenClaim.claim.id}, Amount: ${chosenClaim.claim.amount.toString()}, actualAmount: ${chosenClaim.actualReward.toString()}, addr: ${chosenClaim.claim.claimee.toString()}`);
16665
+ for (let claim of [chosenClaim]) {
16657
16666
  const fee = claim.claim.amount.multipliedBy(this.metadata.additionalInfo.feeBps).dividedBy(1e4);
16658
16667
  const postFeeAmount = claim.claim.amount.minus(fee);
16659
16668
  const isToken1 = claim.token.eq(poolKey.token1);
@@ -16702,57 +16711,41 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16702
16711
  const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
16703
16712
  const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
16704
16713
  logger.verbose(
16705
- `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
16706
- );
16707
- const swapInfo = await this.getSwapInfoGivenAmounts(
16708
- poolKey,
16709
- token0Amt,
16710
- token1Amt,
16711
- bounds,
16712
- maxIterations,
16713
- priceRatioPrecision
16714
- );
16715
- swapInfo.token_to_address = token0Info.address.address;
16716
- logger.verbose(
16717
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
16714
+ `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toFixed(18)}, token1Amt: ${token1Amt.toFixed(18)}`
16718
16715
  );
16719
16716
  logger.verbose(
16720
16717
  `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
16721
16718
  );
16722
- const harvestEstimateCall = async (swapInfo1) => {
16723
- const swap1Amount = Web3Number.fromWei(
16724
- uint2564.uint256ToBN(swapInfo1.token_from_amount).toString(),
16725
- 18
16726
- // cause its always STRK?
16719
+ const claimTokenInfo = await Global.getTokenInfoFromAddr(claim.token);
16720
+ const harvestEstimateCall = async (baseSwapInfo2) => {
16721
+ let baseSwapAmount = Web3Number.fromWei(
16722
+ uint2564.uint256ToBN(baseSwapInfo2.token_from_amount).toString(),
16723
+ claimTokenInfo.decimals
16727
16724
  ).minimum(
16728
- postFeeAmount.toFixed(18)
16729
- // cause always strk
16730
- );
16731
- swapInfo.token_from_amount = uint2564.bnToUint256(swap1Amount.toWei());
16732
- swapInfo.token_to_min_amount = uint2564.bnToUint256(
16733
- swap1Amount.multipliedBy(0).toWei()
16734
- // placeholder
16725
+ postFeeAmount.toFixed(claimTokenInfo.decimals)
16735
16726
  );
16727
+ if (baseSwapAmount.lt(1e-4)) {
16728
+ baseSwapAmount = new Web3Number(0, claimTokenInfo.decimals);
16729
+ }
16730
+ baseSwapInfo2.token_from_amount = uint2564.bnToUint256(baseSwapAmount.toWei());
16731
+ const isToken0ClaimToken2 = claim.token.eq(poolKey.token0);
16736
16732
  logger.verbose(
16737
- `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
16733
+ `${_EkuboCLVault.name}: harvest => isToken0ClaimToken: ${isToken0ClaimToken2}, baseSwapAmount: ${baseSwapAmount}`
16738
16734
  );
16739
- const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
16735
+ const remainingAmount = postFeeAmount.minus(baseSwapAmount).maximum(0);
16740
16736
  logger.verbose(
16741
16737
  `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
16742
16738
  );
16743
- const swapInfo2 = {
16744
- ...swapInfo,
16745
- token_from_amount: uint2564.bnToUint256(remainingAmount.toWei())
16746
- };
16747
- swapInfo2.token_to_address = token1Info.address.address;
16739
+ let dummySwapInfo = AvnuWrapper.buildZeroSwap(claim.token, this.address.address, claim.token);
16740
+ dummySwapInfo.token_from_amount = uint2564.bnToUint256(remainingAmount.toWei());
16748
16741
  logger.verbose(
16749
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
16750
- swapInfo
16742
+ `${_EkuboCLVault.name}: harvest => dummySwapInfo: ${JSON.stringify(
16743
+ dummySwapInfo
16751
16744
  )}`
16752
16745
  );
16753
16746
  logger.verbose(
16754
- `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
16755
- swapInfo2
16747
+ `${_EkuboCLVault.name}: harvest => baseSwapInfo: ${JSON.stringify(
16748
+ baseSwapInfo2
16756
16749
  )}`
16757
16750
  );
16758
16751
  const calldata = [
@@ -16763,18 +16756,36 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16763
16756
  claimee: claim.claim.claimee.address
16764
16757
  },
16765
16758
  claim.proof.map((p) => num5.getDecimalString(p)),
16766
- swapInfo,
16767
- swapInfo2
16759
+ isToken0ClaimToken2 ? dummySwapInfo : baseSwapInfo2,
16760
+ // is token0 claim token, its just dummy swap
16761
+ isToken0ClaimToken2 ? baseSwapInfo2 : dummySwapInfo
16768
16762
  ];
16769
- logger.verbose(
16770
- `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
16771
- calldata
16772
- )}`
16773
- );
16774
16763
  return [this.contract.populate("harvest", calldata)];
16775
16764
  };
16765
+ const isToken0ClaimToken = claim.token.eq(poolKey.token0);
16766
+ let baseSwapInfo = AvnuWrapper.buildZeroSwap(claim.token, this.address.address, isToken0ClaimToken ? token1Info.address : token0Info.address);
16767
+ baseSwapInfo.token_from_amount = uint2564.bnToUint256(postFeeAmount.toWei());
16768
+ if (postFeeAmount.greaterThan(0) && !isToken0ClaimToken) {
16769
+ const avnuWrapper = new AvnuWrapper();
16770
+ const quote = await avnuWrapper.getQuotes(
16771
+ claim.token.address,
16772
+ token0Info.address.address,
16773
+ postFeeAmount.toWei(),
16774
+ this.address.address
16775
+ );
16776
+ baseSwapInfo = await avnuWrapper.getSwapInfo(quote, this.address.address, 0, this.address.address);
16777
+ } else if (postFeeAmount.greaterThan(0) && isToken0ClaimToken) {
16778
+ const avnuWrapper = new AvnuWrapper();
16779
+ const quote = await avnuWrapper.getQuotes(
16780
+ claim.token.address,
16781
+ token1Info.address.address,
16782
+ postFeeAmount.toWei(),
16783
+ this.address.address
16784
+ );
16785
+ baseSwapInfo = await avnuWrapper.getSwapInfo(quote, this.address.address, 0, this.address.address);
16786
+ }
16776
16787
  const _callsFinal = await this.rebalanceIter(
16777
- swapInfo,
16788
+ baseSwapInfo,
16778
16789
  acc,
16779
16790
  harvestEstimateCall,
16780
16791
  claim.token.eq(poolKey.token0),
@@ -16818,32 +16829,40 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16818
16829
  async harvestMismatchEstimateCallFn(params) {
16819
16830
  const { postFeeAmount, claim, token0Info, token1Info, acc } = params;
16820
16831
  let harvestCall = null;
16832
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => postFeeAmount: ${postFeeAmount.toString()}`);
16833
+ let attempt = 0;
16834
+ let MAX_ATTEMPTS = 50;
16821
16835
  const binarySearchCallbackFn = async (mid) => {
16836
+ attempt++;
16837
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => mid: ${mid}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16822
16838
  const rewardPart2 = BigInt(postFeeAmount.toWei()) - mid;
16823
16839
  const avnuWrapper = new AvnuWrapper();
16824
16840
  const beneficiary = this.address.address;
16825
- const quote1 = await avnuWrapper.getQuotes(
16841
+ const quote1Prom = avnuWrapper.getQuotes(
16826
16842
  claim.token.address,
16827
16843
  token0Info.address.address,
16828
16844
  mid.toString(),
16829
16845
  beneficiary
16830
16846
  );
16847
+ const quote2Prom = avnuWrapper.getQuotes(
16848
+ claim.token.address,
16849
+ token1Info.address.address,
16850
+ rewardPart2.toString(),
16851
+ beneficiary
16852
+ );
16853
+ const [quote1, quote2] = await Promise.all([quote1Prom, quote2Prom]);
16831
16854
  const swapInfo1 = await avnuWrapper.getSwapInfo(
16832
16855
  quote1,
16833
16856
  beneficiary,
16834
16857
  0,
16835
- beneficiary
16836
- );
16837
- const quote2 = await avnuWrapper.getQuotes(
16838
- claim.token.address,
16839
- token1Info.address.address,
16840
- rewardPart2.toString(),
16858
+ // fee bps
16841
16859
  beneficiary
16842
16860
  );
16843
16861
  const swapInfo2 = await avnuWrapper.getSwapInfo(
16844
16862
  quote2,
16845
16863
  beneficiary,
16846
16864
  0,
16865
+ // fee bps
16847
16866
  beneficiary
16848
16867
  );
16849
16868
  try {
@@ -16860,13 +16879,17 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16860
16879
  ];
16861
16880
  harvestCall = this.contract.populate("harvest", calldata);
16862
16881
  const gas = await acc.estimateInvokeFee(harvestCall);
16882
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => gas: ${gas.overall_fee.toString()}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16863
16883
  return "found";
16864
16884
  } catch (err) {
16865
16885
  if (err.message.includes("invalid token0 amount")) {
16886
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => invalid token0 amount, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16866
16887
  return "go_low";
16867
16888
  } else if (err.message.includes("invalid token1 amount")) {
16889
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => invalid token1 amount, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16868
16890
  return "go_high";
16869
16891
  }
16892
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => error: ${err.message}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16870
16893
  return "retry";
16871
16894
  }
16872
16895
  };
package/dist/index.d.ts CHANGED
@@ -833,7 +833,7 @@ declare class EkuboCLVault extends BaseStrategy<DualTokenInfo, DualActionAmount>
833
833
  amount0: Web3Number;
834
834
  amount1: Web3Number;
835
835
  }>;
836
- harvest(acc: Account, maxIterations?: number, priceRatioPrecision?: number): Promise<Call[]>;
836
+ harvest(acc: Account, maxIterations?: number, priceRatioPrecision?: number, minRewardAmount?: Web3Number): Promise<Call[]>;
837
837
  /**
838
838
  * @description This funciton requires atleast one of the pool tokens to be reward token
839
839
  * i.e. STRK.
@@ -1696,6 +1696,7 @@ declare function executeDeployCalls(contractsInfo: DeployContractResult[], acc:
1696
1696
  declare function executeTransactions(calls: Call[], acc: Account, provider: RpcProvider, remarks?: string): Promise<{
1697
1697
  transaction_hash: string;
1698
1698
  }>;
1699
+ declare function myWaitForTransaction(transaction_hash: string, provider: RpcProvider, retry?: number): Promise<boolean>;
1699
1700
  declare const Deployer: {
1700
1701
  getAccount: typeof getAccount;
1701
1702
  myDeclare: typeof myDeclare;
@@ -1703,6 +1704,7 @@ declare const Deployer: {
1703
1704
  prepareMultiDeployContracts: typeof prepareMultiDeployContracts;
1704
1705
  executeDeployCalls: typeof executeDeployCalls;
1705
1706
  executeTransactions: typeof executeTransactions;
1707
+ myWaitForTransaction: typeof myWaitForTransaction;
1706
1708
  };
1707
1709
 
1708
1710
  /**