@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.
package/dist/index.js CHANGED
@@ -2271,10 +2271,9 @@ function getTrovesEndpoint() {
2271
2271
  }
2272
2272
 
2273
2273
  // src/modules/avnu.ts
2274
- var AvnuWrapper = class _AvnuWrapper {
2274
+ var AvnuWrapper = class {
2275
2275
  async getQuotes(fromToken, toToken, amountWei, taker, retry = 0, excludeSources = ["Haiko(Solvers)"]) {
2276
2276
  const MAX_RETRY = 5;
2277
- logger.verbose(`${_AvnuWrapper.name}: getQuotes => Getting quotes for ${fromToken} -> ${toToken}, amount: ${amountWei}, taker: ${taker}, retry: ${retry}`);
2278
2277
  const params = {
2279
2278
  sellTokenAddress: fromToken,
2280
2279
  buyTokenAddress: toToken,
@@ -2317,9 +2316,6 @@ var AvnuWrapper = class _AvnuWrapper {
2317
2316
  startIndex += 5 + swap_params_len;
2318
2317
  }
2319
2318
  const _minAmount = minAmount || (quote.buyAmount * 95n / 100n).toString();
2320
- logger.verbose(`${_AvnuWrapper.name}: getSwapInfo => sellToken: ${quote.sellTokenAddress}, sellAmount: ${quote.sellAmount}`);
2321
- logger.verbose(`${_AvnuWrapper.name}: getSwapInfo => buyToken: ${quote.buyTokenAddress}`);
2322
- logger.verbose(`${_AvnuWrapper.name}: getSwapInfo => buyAmount: ${quote.buyAmount}, minAmount: ${_minAmount}`);
2323
2319
  const swapInfo = {
2324
2320
  token_from_address: quote.sellTokenAddress,
2325
2321
  token_from_amount: import_starknet6.uint256.bnToUint256(quote.sellAmount),
@@ -4140,20 +4136,26 @@ var Harvests = class _Harvests {
4140
4136
  const rewards = await this.getHarvests(addr);
4141
4137
  if (rewards.length == 0) return [];
4142
4138
  const unClaimed = [];
4143
- const reward = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime())[0];
4144
- const cls = await this.config.provider.getClassAt(reward.rewardsContract.address);
4145
- const contract = new import_starknet9.Contract({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
4146
- const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
4147
- logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
4148
- if (isClaimed) {
4149
- return unClaimed;
4139
+ const sortedRewards = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime());
4140
+ if (sortedRewards.length == 0) {
4141
+ logger.verbose(`${_Harvests.name}: no rewards found`);
4142
+ return [];
4150
4143
  }
4151
- const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
4152
- if (bal.lessThan(reward.claim.amount)) {
4153
- logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
4154
- return unClaimed;
4144
+ const cls = await this.config.provider.getClassAt(sortedRewards[0].rewardsContract.address);
4145
+ for (const reward of sortedRewards) {
4146
+ const contract = new import_starknet9.Contract({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
4147
+ const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
4148
+ logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}, claim id: ${reward.claim.id}, address: ${reward.rewardsContract.address}`);
4149
+ if (isClaimed) {
4150
+ continue;
4151
+ }
4152
+ const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
4153
+ if (bal.lessThan(reward.claim.amount)) {
4154
+ logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
4155
+ continue;
4156
+ }
4157
+ unClaimed.push(reward);
4155
4158
  }
4156
- unClaimed.unshift(reward);
4157
4159
  return unClaimed;
4158
4160
  }
4159
4161
  };
@@ -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
- import_starknet11.uint256.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
+ import_starknet11.uint256.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 = import_starknet11.uint256.bnToUint256(swap1Amount.toWei());
16732
- swapInfo.token_to_min_amount = import_starknet11.uint256.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 = import_starknet11.uint256.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: import_starknet11.uint256.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 = import_starknet11.uint256.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) => import_starknet11.num.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 = import_starknet11.uint256.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
  };
@@ -32220,13 +32243,42 @@ async function executeTransactions(calls, acc, provider2, remarks) {
32220
32243
  console.log(`Transaction confirmed: ${tx.transaction_hash}`);
32221
32244
  return tx;
32222
32245
  }
32246
+ async function myWaitForTransaction(transaction_hash, provider2, retry = 0) {
32247
+ const MAX_RETRIES = 60;
32248
+ logger.verbose(`Waiting for transaction: ${transaction_hash}, retry: ${retry}`);
32249
+ try {
32250
+ const status = await provider2.getTransactionStatus(transaction_hash);
32251
+ logger.verbose(`Transaction status: ${JSON.stringify(status.execution_status)}`);
32252
+ if (status.execution_status == import_starknet19.TransactionExecutionStatus.SUCCEEDED) {
32253
+ return true;
32254
+ }
32255
+ if (status.execution_status == import_starknet19.TransactionExecutionStatus.REVERTED) {
32256
+ throw new Error(`Transaction reverted: ${transaction_hash}`);
32257
+ }
32258
+ if (retry > MAX_RETRIES) {
32259
+ throw new Error(`Transaction not found: ${transaction_hash}`);
32260
+ }
32261
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
32262
+ return myWaitForTransaction(transaction_hash, provider2, retry + 1);
32263
+ } catch (error) {
32264
+ if (error instanceof Error && error.message.includes("Transaction reverted")) {
32265
+ throw new Error(`Transaction reverted: ${transaction_hash}`);
32266
+ }
32267
+ if (retry > MAX_RETRIES) {
32268
+ throw error;
32269
+ }
32270
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
32271
+ return myWaitForTransaction(transaction_hash, provider2, retry + 1);
32272
+ }
32273
+ }
32223
32274
  var Deployer = {
32224
32275
  getAccount,
32225
32276
  myDeclare,
32226
32277
  deployContract,
32227
32278
  prepareMultiDeployContracts,
32228
32279
  executeDeployCalls,
32229
- executeTransactions
32280
+ executeTransactions,
32281
+ myWaitForTransaction
32230
32282
  };
32231
32283
  var deployer_default = Deployer;
32232
32284
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.mjs CHANGED
@@ -2165,10 +2165,9 @@ function getTrovesEndpoint() {
2165
2165
  }
2166
2166
 
2167
2167
  // src/modules/avnu.ts
2168
- var AvnuWrapper = class _AvnuWrapper {
2168
+ var AvnuWrapper = class {
2169
2169
  async getQuotes(fromToken, toToken, amountWei, taker, retry = 0, excludeSources = ["Haiko(Solvers)"]) {
2170
2170
  const MAX_RETRY = 5;
2171
- logger.verbose(`${_AvnuWrapper.name}: getQuotes => Getting quotes for ${fromToken} -> ${toToken}, amount: ${amountWei}, taker: ${taker}, retry: ${retry}`);
2172
2171
  const params = {
2173
2172
  sellTokenAddress: fromToken,
2174
2173
  buyTokenAddress: toToken,
@@ -2211,9 +2210,6 @@ var AvnuWrapper = class _AvnuWrapper {
2211
2210
  startIndex += 5 + swap_params_len;
2212
2211
  }
2213
2212
  const _minAmount = minAmount || (quote.buyAmount * 95n / 100n).toString();
2214
- logger.verbose(`${_AvnuWrapper.name}: getSwapInfo => sellToken: ${quote.sellTokenAddress}, sellAmount: ${quote.sellAmount}`);
2215
- logger.verbose(`${_AvnuWrapper.name}: getSwapInfo => buyToken: ${quote.buyTokenAddress}`);
2216
- logger.verbose(`${_AvnuWrapper.name}: getSwapInfo => buyAmount: ${quote.buyAmount}, minAmount: ${_minAmount}`);
2217
2213
  const swapInfo = {
2218
2214
  token_from_address: quote.sellTokenAddress,
2219
2215
  token_from_amount: uint256.bnToUint256(quote.sellAmount),
@@ -4034,20 +4030,26 @@ var Harvests = class _Harvests {
4034
4030
  const rewards = await this.getHarvests(addr);
4035
4031
  if (rewards.length == 0) return [];
4036
4032
  const unClaimed = [];
4037
- const reward = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime())[0];
4038
- const cls = await this.config.provider.getClassAt(reward.rewardsContract.address);
4039
- const contract = new Contract4({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
4040
- const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
4041
- logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
4042
- if (isClaimed) {
4043
- return unClaimed;
4033
+ const sortedRewards = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime());
4034
+ if (sortedRewards.length == 0) {
4035
+ logger.verbose(`${_Harvests.name}: no rewards found`);
4036
+ return [];
4044
4037
  }
4045
- const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
4046
- if (bal.lessThan(reward.claim.amount)) {
4047
- logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
4048
- return unClaimed;
4038
+ const cls = await this.config.provider.getClassAt(sortedRewards[0].rewardsContract.address);
4039
+ for (const reward of sortedRewards) {
4040
+ const contract = new Contract4({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
4041
+ const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
4042
+ logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}, claim id: ${reward.claim.id}, address: ${reward.rewardsContract.address}`);
4043
+ if (isClaimed) {
4044
+ continue;
4045
+ }
4046
+ const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
4047
+ if (bal.lessThan(reward.claim.amount)) {
4048
+ logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
4049
+ continue;
4050
+ }
4051
+ unClaimed.push(reward);
4049
4052
  }
4050
- unClaimed.unshift(reward);
4051
4053
  return unClaimed;
4052
4054
  }
4053
4055
  };
@@ -16538,11 +16540,15 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16538
16540
  amount1
16539
16541
  };
16540
16542
  }
16541
- async harvest(acc, maxIterations = 20, priceRatioPrecision = 4) {
16543
+ async harvest(acc, maxIterations = 20, priceRatioPrecision = 4, minRewardAmount = new Web3Number(0, 18)) {
16542
16544
  const ekuboHarvests = new EkuboHarvests(this.config);
16543
- const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(
16545
+ const unClaimedRewards = (await ekuboHarvests.getUnHarvestedRewards(
16544
16546
  this.address
16545
- );
16547
+ )).filter((claim) => claim.actualReward.greaterThanOrEqualTo(minRewardAmount));
16548
+ if (unClaimedRewards.length == 0) {
16549
+ logger.verbose(`${_EkuboCLVault.name}: harvest => no unclaimed rewards found`);
16550
+ return [];
16551
+ }
16546
16552
  const poolKey = await this.getPoolKey();
16547
16553
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
16548
16554
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
@@ -16551,7 +16557,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16551
16557
  `${_EkuboCLVault.name}: harvest => unClaimedRewards: ${unClaimedRewards.length}`
16552
16558
  );
16553
16559
  const calls = [];
16554
- for (let claim of unClaimedRewards) {
16560
+ const chosenClaim = unClaimedRewards[0];
16561
+ logger.info(`${_EkuboCLVault.name}: harvest => doing one at a time`);
16562
+ 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()}`);
16563
+ for (let claim of [chosenClaim]) {
16555
16564
  const fee = claim.claim.amount.multipliedBy(this.metadata.additionalInfo.feeBps).dividedBy(1e4);
16556
16565
  const postFeeAmount = claim.claim.amount.minus(fee);
16557
16566
  const isToken1 = claim.token.eq(poolKey.token1);
@@ -16600,57 +16609,41 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16600
16609
  const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
16601
16610
  const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
16602
16611
  logger.verbose(
16603
- `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
16604
- );
16605
- const swapInfo = await this.getSwapInfoGivenAmounts(
16606
- poolKey,
16607
- token0Amt,
16608
- token1Amt,
16609
- bounds,
16610
- maxIterations,
16611
- priceRatioPrecision
16612
- );
16613
- swapInfo.token_to_address = token0Info.address.address;
16614
- logger.verbose(
16615
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
16612
+ `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toFixed(18)}, token1Amt: ${token1Amt.toFixed(18)}`
16616
16613
  );
16617
16614
  logger.verbose(
16618
16615
  `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
16619
16616
  );
16620
- const harvestEstimateCall = async (swapInfo1) => {
16621
- const swap1Amount = Web3Number.fromWei(
16622
- uint2564.uint256ToBN(swapInfo1.token_from_amount).toString(),
16623
- 18
16624
- // cause its always STRK?
16617
+ const claimTokenInfo = await Global.getTokenInfoFromAddr(claim.token);
16618
+ const harvestEstimateCall = async (baseSwapInfo2) => {
16619
+ let baseSwapAmount = Web3Number.fromWei(
16620
+ uint2564.uint256ToBN(baseSwapInfo2.token_from_amount).toString(),
16621
+ claimTokenInfo.decimals
16625
16622
  ).minimum(
16626
- postFeeAmount.toFixed(18)
16627
- // cause always strk
16628
- );
16629
- swapInfo.token_from_amount = uint2564.bnToUint256(swap1Amount.toWei());
16630
- swapInfo.token_to_min_amount = uint2564.bnToUint256(
16631
- swap1Amount.multipliedBy(0).toWei()
16632
- // placeholder
16623
+ postFeeAmount.toFixed(claimTokenInfo.decimals)
16633
16624
  );
16625
+ if (baseSwapAmount.lt(1e-4)) {
16626
+ baseSwapAmount = new Web3Number(0, claimTokenInfo.decimals);
16627
+ }
16628
+ baseSwapInfo2.token_from_amount = uint2564.bnToUint256(baseSwapAmount.toWei());
16629
+ const isToken0ClaimToken2 = claim.token.eq(poolKey.token0);
16634
16630
  logger.verbose(
16635
- `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
16631
+ `${_EkuboCLVault.name}: harvest => isToken0ClaimToken: ${isToken0ClaimToken2}, baseSwapAmount: ${baseSwapAmount}`
16636
16632
  );
16637
- const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
16633
+ const remainingAmount = postFeeAmount.minus(baseSwapAmount).maximum(0);
16638
16634
  logger.verbose(
16639
16635
  `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
16640
16636
  );
16641
- const swapInfo2 = {
16642
- ...swapInfo,
16643
- token_from_amount: uint2564.bnToUint256(remainingAmount.toWei())
16644
- };
16645
- swapInfo2.token_to_address = token1Info.address.address;
16637
+ let dummySwapInfo = AvnuWrapper.buildZeroSwap(claim.token, this.address.address, claim.token);
16638
+ dummySwapInfo.token_from_amount = uint2564.bnToUint256(remainingAmount.toWei());
16646
16639
  logger.verbose(
16647
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
16648
- swapInfo
16640
+ `${_EkuboCLVault.name}: harvest => dummySwapInfo: ${JSON.stringify(
16641
+ dummySwapInfo
16649
16642
  )}`
16650
16643
  );
16651
16644
  logger.verbose(
16652
- `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
16653
- swapInfo2
16645
+ `${_EkuboCLVault.name}: harvest => baseSwapInfo: ${JSON.stringify(
16646
+ baseSwapInfo2
16654
16647
  )}`
16655
16648
  );
16656
16649
  const calldata = [
@@ -16661,18 +16654,36 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16661
16654
  claimee: claim.claim.claimee.address
16662
16655
  },
16663
16656
  claim.proof.map((p) => num5.getDecimalString(p)),
16664
- swapInfo,
16665
- swapInfo2
16657
+ isToken0ClaimToken2 ? dummySwapInfo : baseSwapInfo2,
16658
+ // is token0 claim token, its just dummy swap
16659
+ isToken0ClaimToken2 ? baseSwapInfo2 : dummySwapInfo
16666
16660
  ];
16667
- logger.verbose(
16668
- `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
16669
- calldata
16670
- )}`
16671
- );
16672
16661
  return [this.contract.populate("harvest", calldata)];
16673
16662
  };
16663
+ const isToken0ClaimToken = claim.token.eq(poolKey.token0);
16664
+ let baseSwapInfo = AvnuWrapper.buildZeroSwap(claim.token, this.address.address, isToken0ClaimToken ? token1Info.address : token0Info.address);
16665
+ baseSwapInfo.token_from_amount = uint2564.bnToUint256(postFeeAmount.toWei());
16666
+ if (postFeeAmount.greaterThan(0) && !isToken0ClaimToken) {
16667
+ const avnuWrapper = new AvnuWrapper();
16668
+ const quote = await avnuWrapper.getQuotes(
16669
+ claim.token.address,
16670
+ token0Info.address.address,
16671
+ postFeeAmount.toWei(),
16672
+ this.address.address
16673
+ );
16674
+ baseSwapInfo = await avnuWrapper.getSwapInfo(quote, this.address.address, 0, this.address.address);
16675
+ } else if (postFeeAmount.greaterThan(0) && isToken0ClaimToken) {
16676
+ const avnuWrapper = new AvnuWrapper();
16677
+ const quote = await avnuWrapper.getQuotes(
16678
+ claim.token.address,
16679
+ token1Info.address.address,
16680
+ postFeeAmount.toWei(),
16681
+ this.address.address
16682
+ );
16683
+ baseSwapInfo = await avnuWrapper.getSwapInfo(quote, this.address.address, 0, this.address.address);
16684
+ }
16674
16685
  const _callsFinal = await this.rebalanceIter(
16675
- swapInfo,
16686
+ baseSwapInfo,
16676
16687
  acc,
16677
16688
  harvestEstimateCall,
16678
16689
  claim.token.eq(poolKey.token0),
@@ -16716,32 +16727,40 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16716
16727
  async harvestMismatchEstimateCallFn(params) {
16717
16728
  const { postFeeAmount, claim, token0Info, token1Info, acc } = params;
16718
16729
  let harvestCall = null;
16730
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => postFeeAmount: ${postFeeAmount.toString()}`);
16731
+ let attempt = 0;
16732
+ let MAX_ATTEMPTS = 50;
16719
16733
  const binarySearchCallbackFn = async (mid) => {
16734
+ attempt++;
16735
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => mid: ${mid}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16720
16736
  const rewardPart2 = BigInt(postFeeAmount.toWei()) - mid;
16721
16737
  const avnuWrapper = new AvnuWrapper();
16722
16738
  const beneficiary = this.address.address;
16723
- const quote1 = await avnuWrapper.getQuotes(
16739
+ const quote1Prom = avnuWrapper.getQuotes(
16724
16740
  claim.token.address,
16725
16741
  token0Info.address.address,
16726
16742
  mid.toString(),
16727
16743
  beneficiary
16728
16744
  );
16745
+ const quote2Prom = avnuWrapper.getQuotes(
16746
+ claim.token.address,
16747
+ token1Info.address.address,
16748
+ rewardPart2.toString(),
16749
+ beneficiary
16750
+ );
16751
+ const [quote1, quote2] = await Promise.all([quote1Prom, quote2Prom]);
16729
16752
  const swapInfo1 = await avnuWrapper.getSwapInfo(
16730
16753
  quote1,
16731
16754
  beneficiary,
16732
16755
  0,
16733
- beneficiary
16734
- );
16735
- const quote2 = await avnuWrapper.getQuotes(
16736
- claim.token.address,
16737
- token1Info.address.address,
16738
- rewardPart2.toString(),
16756
+ // fee bps
16739
16757
  beneficiary
16740
16758
  );
16741
16759
  const swapInfo2 = await avnuWrapper.getSwapInfo(
16742
16760
  quote2,
16743
16761
  beneficiary,
16744
16762
  0,
16763
+ // fee bps
16745
16764
  beneficiary
16746
16765
  );
16747
16766
  try {
@@ -16758,13 +16777,17 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16758
16777
  ];
16759
16778
  harvestCall = this.contract.populate("harvest", calldata);
16760
16779
  const gas = await acc.estimateInvokeFee(harvestCall);
16780
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => gas: ${gas.overall_fee.toString()}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16761
16781
  return "found";
16762
16782
  } catch (err) {
16763
16783
  if (err.message.includes("invalid token0 amount")) {
16784
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => invalid token0 amount, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16764
16785
  return "go_low";
16765
16786
  } else if (err.message.includes("invalid token1 amount")) {
16787
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => invalid token1 amount, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16766
16788
  return "go_high";
16767
16789
  }
16790
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => error: ${err.message}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16768
16791
  return "retry";
16769
16792
  }
16770
16793
  };
@@ -32118,13 +32141,42 @@ async function executeTransactions(calls, acc, provider2, remarks) {
32118
32141
  console.log(`Transaction confirmed: ${tx.transaction_hash}`);
32119
32142
  return tx;
32120
32143
  }
32144
+ async function myWaitForTransaction(transaction_hash, provider2, retry = 0) {
32145
+ const MAX_RETRIES = 60;
32146
+ logger.verbose(`Waiting for transaction: ${transaction_hash}, retry: ${retry}`);
32147
+ try {
32148
+ const status = await provider2.getTransactionStatus(transaction_hash);
32149
+ logger.verbose(`Transaction status: ${JSON.stringify(status.execution_status)}`);
32150
+ if (status.execution_status == TransactionExecutionStatus.SUCCEEDED) {
32151
+ return true;
32152
+ }
32153
+ if (status.execution_status == TransactionExecutionStatus.REVERTED) {
32154
+ throw new Error(`Transaction reverted: ${transaction_hash}`);
32155
+ }
32156
+ if (retry > MAX_RETRIES) {
32157
+ throw new Error(`Transaction not found: ${transaction_hash}`);
32158
+ }
32159
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
32160
+ return myWaitForTransaction(transaction_hash, provider2, retry + 1);
32161
+ } catch (error) {
32162
+ if (error instanceof Error && error.message.includes("Transaction reverted")) {
32163
+ throw new Error(`Transaction reverted: ${transaction_hash}`);
32164
+ }
32165
+ if (retry > MAX_RETRIES) {
32166
+ throw error;
32167
+ }
32168
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
32169
+ return myWaitForTransaction(transaction_hash, provider2, retry + 1);
32170
+ }
32171
+ }
32121
32172
  var Deployer = {
32122
32173
  getAccount,
32123
32174
  myDeclare,
32124
32175
  deployContract,
32125
32176
  prepareMultiDeployContracts,
32126
32177
  executeDeployCalls,
32127
- executeTransactions
32178
+ executeTransactions,
32179
+ myWaitForTransaction
32128
32180
  };
32129
32181
  var deployer_default = Deployer;
32130
32182
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strkfarm/sdk",
3
- "version": "1.1.50",
3
+ "version": "1.1.51",
4
4
  "description": "STRKFarm TS SDK (Meant for our internal use, but feel free to use it)",
5
5
  "typings": "dist/index.d.ts",
6
6
  "types": "dist/index.d.ts",