@strkfarm/sdk 1.1.50 → 1.1.52

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
  };
@@ -31025,6 +31048,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
31025
31048
  * @param params
31026
31049
  */
31027
31050
  async getVesuMultiplyCall(params) {
31051
+ const maxEkuboPriceImpact = params.maxEkuboPriceImpact || 0.01;
31028
31052
  const vesuAdapter1 = this.getVesuSameTokenAdapter();
31029
31053
  const legLTV = await vesuAdapter1.getLTVConfig(this.config);
31030
31054
  logger.verbose(`${this.getTag()}::getVesuMultiplyCall legLTV: ${legLTV}`);
@@ -31060,7 +31084,8 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
31060
31084
  marginAmount,
31061
31085
  debtAmount,
31062
31086
  lstDexPriceInUnderlying: dexPrice,
31063
- isIncrease: debtAmount.greaterThan(0)
31087
+ isIncrease: debtAmount.greaterThan(0),
31088
+ maxEkuboPriceImpact
31064
31089
  });
31065
31090
  }
31066
31091
  getLSTUnderlyingTokenInfo() {
@@ -31237,7 +31262,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
31237
31262
  // negative for exact amount out
31238
31263
  );
31239
31264
  logger.verbose(`${this.getTag()}::getModifyLeverCall leverSwapQuote: ${JSON.stringify(leverSwapQuote)}`);
31240
- assert(leverSwapQuote.price_impact < 0.01, "getIncreaseLeverCall: Price impact is too high [Debt swap]");
31265
+ assert(leverSwapQuote.price_impact <= params.maxEkuboPriceImpact, "getIncreaseLeverCall: Price impact is too high [Debt swap]");
31241
31266
  const leverSwap = ekuboQuoter.getVesuMultiplyQuote(leverSwapQuote, fromToken, toToken);
31242
31267
  logger.verbose(`${this.getTag()}::getModifyLeverCall leverSwap: ${JSON.stringify(leverSwap)}`);
31243
31268
  let minLSTReceived = params.debtAmount.dividedBy(lstDexPriceInUnderlying).multipliedBy(1 - MAX_SLIPPAGE);
@@ -32220,13 +32245,42 @@ async function executeTransactions(calls, acc, provider2, remarks) {
32220
32245
  console.log(`Transaction confirmed: ${tx.transaction_hash}`);
32221
32246
  return tx;
32222
32247
  }
32248
+ async function myWaitForTransaction(transaction_hash, provider2, retry = 0) {
32249
+ const MAX_RETRIES = 60;
32250
+ logger.verbose(`Waiting for transaction: ${transaction_hash}, retry: ${retry}`);
32251
+ try {
32252
+ const status = await provider2.getTransactionStatus(transaction_hash);
32253
+ logger.verbose(`Transaction status: ${JSON.stringify(status.execution_status)}`);
32254
+ if (status.execution_status == import_starknet19.TransactionExecutionStatus.SUCCEEDED) {
32255
+ return true;
32256
+ }
32257
+ if (status.execution_status == import_starknet19.TransactionExecutionStatus.REVERTED) {
32258
+ throw new Error(`Transaction reverted: ${transaction_hash}`);
32259
+ }
32260
+ if (retry > MAX_RETRIES) {
32261
+ throw new Error(`Transaction not found: ${transaction_hash}`);
32262
+ }
32263
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
32264
+ return myWaitForTransaction(transaction_hash, provider2, retry + 1);
32265
+ } catch (error) {
32266
+ if (error instanceof Error && error.message.includes("Transaction reverted")) {
32267
+ throw new Error(`Transaction reverted: ${transaction_hash}`);
32268
+ }
32269
+ if (retry > MAX_RETRIES) {
32270
+ throw error;
32271
+ }
32272
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
32273
+ return myWaitForTransaction(transaction_hash, provider2, retry + 1);
32274
+ }
32275
+ }
32223
32276
  var Deployer = {
32224
32277
  getAccount,
32225
32278
  myDeclare,
32226
32279
  deployContract,
32227
32280
  prepareMultiDeployContracts,
32228
32281
  executeDeployCalls,
32229
- executeTransactions
32282
+ executeTransactions,
32283
+ myWaitForTransaction
32230
32284
  };
32231
32285
  var deployer_default = Deployer;
32232
32286
  // Annotate the CommonJS export names for ESM import in node: