@strkfarm/sdk 1.1.49 → 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
  };
@@ -15758,13 +15760,27 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
15758
15760
  const tvlBefore = await this._getTVL(blockBefore);
15759
15761
  const supplyBefore = await this.totalSupply(blockBefore);
15760
15762
  const priceBefore = await this.getCurrentPrice(blockBefore);
15761
- const tvlInToken0Now = tvlNow.amount0.multipliedBy(priceNow.price).plus(tvlNow.amount1);
15762
- const tvlPerShareNow = tvlInToken0Now.multipliedBy(1e18).dividedBy(adjustedSupplyNow.toString());
15763
- const tvlInToken0Bf = tvlBefore.amount0.multipliedBy(priceBefore.price).plus(tvlBefore.amount1);
15764
- const tvlPerShareBf = tvlInToken0Bf.multipliedBy(1e18).dividedBy(supplyBefore.toString());
15763
+ const poolKey = await this.getPoolKey(blockBefore);
15764
+ logger.verbose(`priceBefore: ${priceBefore.price.toString()}`);
15765
+ logger.verbose(`priceNow: ${priceNow.price.toString()}`);
15766
+ logger.verbose(`tvlBefore: ${JSON.stringify(tvlBefore)}`);
15767
+ logger.verbose(`tvlNow: ${JSON.stringify(tvlNow)}`);
15768
+ const isQuoteTokenToken0 = this.metadata.additionalInfo.quoteAsset.address.eq(poolKey.token0);
15769
+ logger.verbose(`isQuoteTokenToken0: ${isQuoteTokenToken0}`);
15770
+ let tvlBeforeInBaseAsset = Web3Number.fromWei(0, this.metadata.additionalInfo.quoteAsset.decimals);
15771
+ let tvlNowInBaseAsset = Web3Number.fromWei(0, this.metadata.additionalInfo.quoteAsset.decimals);
15772
+ if (!isQuoteTokenToken0) {
15773
+ tvlNowInBaseAsset = tvlNow.amount0.multipliedBy(priceNow.price).plus(tvlNow.amount1);
15774
+ tvlBeforeInBaseAsset = tvlBefore.amount0.multipliedBy(priceBefore.price).plus(tvlBefore.amount1);
15775
+ } else {
15776
+ tvlNowInBaseAsset = tvlNow.amount1.multipliedBy(1 / priceNow.price).plus(tvlNow.amount0);
15777
+ tvlBeforeInBaseAsset = tvlBefore.amount1.multipliedBy(1 / priceBefore.price).plus(tvlBefore.amount0);
15778
+ }
15779
+ const tvlPerShareNow = tvlNowInBaseAsset.multipliedBy(1e18).dividedBy(adjustedSupplyNow.toString());
15780
+ const tvlPerShareBf = tvlBeforeInBaseAsset.multipliedBy(1e18).dividedBy(supplyBefore.toString());
15765
15781
  const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
15766
- logger.verbose(`tvlInToken0Now: ${tvlInToken0Now.toString()}`);
15767
- logger.verbose(`tvlInToken0Bf: ${tvlInToken0Bf.toString()}`);
15782
+ logger.verbose(`tvlNowInBaseAsset: ${tvlNowInBaseAsset.toString()}`);
15783
+ logger.verbose(`tvlBeforeInBaseAsset: ${tvlBeforeInBaseAsset.toString()}`);
15768
15784
  logger.verbose(`tvlPerShareNow: ${tvlPerShareNow.toString()}`);
15769
15785
  logger.verbose(`tvlPerShareBf: ${tvlPerShareBf.toString()}`);
15770
15786
  logger.verbose(`Price before: ${priceBefore.price.toString()}`);
@@ -16626,11 +16642,15 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16626
16642
  amount1
16627
16643
  };
16628
16644
  }
16629
- async harvest(acc, maxIterations = 20, priceRatioPrecision = 4) {
16645
+ async harvest(acc, maxIterations = 20, priceRatioPrecision = 4, minRewardAmount = new Web3Number(0, 18)) {
16630
16646
  const ekuboHarvests = new EkuboHarvests(this.config);
16631
- const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(
16647
+ const unClaimedRewards = (await ekuboHarvests.getUnHarvestedRewards(
16632
16648
  this.address
16633
- );
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
+ }
16634
16654
  const poolKey = await this.getPoolKey();
16635
16655
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
16636
16656
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
@@ -16639,7 +16659,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16639
16659
  `${_EkuboCLVault.name}: harvest => unClaimedRewards: ${unClaimedRewards.length}`
16640
16660
  );
16641
16661
  const calls = [];
16642
- 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]) {
16643
16666
  const fee = claim.claim.amount.multipliedBy(this.metadata.additionalInfo.feeBps).dividedBy(1e4);
16644
16667
  const postFeeAmount = claim.claim.amount.minus(fee);
16645
16668
  const isToken1 = claim.token.eq(poolKey.token1);
@@ -16688,57 +16711,41 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16688
16711
  const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
16689
16712
  const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
16690
16713
  logger.verbose(
16691
- `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
16692
- );
16693
- const swapInfo = await this.getSwapInfoGivenAmounts(
16694
- poolKey,
16695
- token0Amt,
16696
- token1Amt,
16697
- bounds,
16698
- maxIterations,
16699
- priceRatioPrecision
16700
- );
16701
- swapInfo.token_to_address = token0Info.address.address;
16702
- logger.verbose(
16703
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
16714
+ `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toFixed(18)}, token1Amt: ${token1Amt.toFixed(18)}`
16704
16715
  );
16705
16716
  logger.verbose(
16706
16717
  `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
16707
16718
  );
16708
- const harvestEstimateCall = async (swapInfo1) => {
16709
- const swap1Amount = Web3Number.fromWei(
16710
- import_starknet11.uint256.uint256ToBN(swapInfo1.token_from_amount).toString(),
16711
- 18
16712
- // 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
16713
16724
  ).minimum(
16714
- postFeeAmount.toFixed(18)
16715
- // cause always strk
16716
- );
16717
- swapInfo.token_from_amount = import_starknet11.uint256.bnToUint256(swap1Amount.toWei());
16718
- swapInfo.token_to_min_amount = import_starknet11.uint256.bnToUint256(
16719
- swap1Amount.multipliedBy(0).toWei()
16720
- // placeholder
16725
+ postFeeAmount.toFixed(claimTokenInfo.decimals)
16721
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);
16722
16732
  logger.verbose(
16723
- `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
16733
+ `${_EkuboCLVault.name}: harvest => isToken0ClaimToken: ${isToken0ClaimToken2}, baseSwapAmount: ${baseSwapAmount}`
16724
16734
  );
16725
- const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
16735
+ const remainingAmount = postFeeAmount.minus(baseSwapAmount).maximum(0);
16726
16736
  logger.verbose(
16727
16737
  `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
16728
16738
  );
16729
- const swapInfo2 = {
16730
- ...swapInfo,
16731
- token_from_amount: import_starknet11.uint256.bnToUint256(remainingAmount.toWei())
16732
- };
16733
- 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());
16734
16741
  logger.verbose(
16735
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
16736
- swapInfo
16742
+ `${_EkuboCLVault.name}: harvest => dummySwapInfo: ${JSON.stringify(
16743
+ dummySwapInfo
16737
16744
  )}`
16738
16745
  );
16739
16746
  logger.verbose(
16740
- `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
16741
- swapInfo2
16747
+ `${_EkuboCLVault.name}: harvest => baseSwapInfo: ${JSON.stringify(
16748
+ baseSwapInfo2
16742
16749
  )}`
16743
16750
  );
16744
16751
  const calldata = [
@@ -16749,18 +16756,36 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16749
16756
  claimee: claim.claim.claimee.address
16750
16757
  },
16751
16758
  claim.proof.map((p) => import_starknet11.num.getDecimalString(p)),
16752
- swapInfo,
16753
- swapInfo2
16759
+ isToken0ClaimToken2 ? dummySwapInfo : baseSwapInfo2,
16760
+ // is token0 claim token, its just dummy swap
16761
+ isToken0ClaimToken2 ? baseSwapInfo2 : dummySwapInfo
16754
16762
  ];
16755
- logger.verbose(
16756
- `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
16757
- calldata
16758
- )}`
16759
- );
16760
16763
  return [this.contract.populate("harvest", calldata)];
16761
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
+ }
16762
16787
  const _callsFinal = await this.rebalanceIter(
16763
- swapInfo,
16788
+ baseSwapInfo,
16764
16789
  acc,
16765
16790
  harvestEstimateCall,
16766
16791
  claim.token.eq(poolKey.token0),
@@ -16804,32 +16829,40 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16804
16829
  async harvestMismatchEstimateCallFn(params) {
16805
16830
  const { postFeeAmount, claim, token0Info, token1Info, acc } = params;
16806
16831
  let harvestCall = null;
16832
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => postFeeAmount: ${postFeeAmount.toString()}`);
16833
+ let attempt = 0;
16834
+ let MAX_ATTEMPTS = 50;
16807
16835
  const binarySearchCallbackFn = async (mid) => {
16836
+ attempt++;
16837
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => mid: ${mid}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16808
16838
  const rewardPart2 = BigInt(postFeeAmount.toWei()) - mid;
16809
16839
  const avnuWrapper = new AvnuWrapper();
16810
16840
  const beneficiary = this.address.address;
16811
- const quote1 = await avnuWrapper.getQuotes(
16841
+ const quote1Prom = avnuWrapper.getQuotes(
16812
16842
  claim.token.address,
16813
16843
  token0Info.address.address,
16814
16844
  mid.toString(),
16815
16845
  beneficiary
16816
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]);
16817
16854
  const swapInfo1 = await avnuWrapper.getSwapInfo(
16818
16855
  quote1,
16819
16856
  beneficiary,
16820
16857
  0,
16821
- beneficiary
16822
- );
16823
- const quote2 = await avnuWrapper.getQuotes(
16824
- claim.token.address,
16825
- token1Info.address.address,
16826
- rewardPart2.toString(),
16858
+ // fee bps
16827
16859
  beneficiary
16828
16860
  );
16829
16861
  const swapInfo2 = await avnuWrapper.getSwapInfo(
16830
16862
  quote2,
16831
16863
  beneficiary,
16832
16864
  0,
16865
+ // fee bps
16833
16866
  beneficiary
16834
16867
  );
16835
16868
  try {
@@ -16846,13 +16879,17 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16846
16879
  ];
16847
16880
  harvestCall = this.contract.populate("harvest", calldata);
16848
16881
  const gas = await acc.estimateInvokeFee(harvestCall);
16882
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => gas: ${gas.overall_fee.toString()}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16849
16883
  return "found";
16850
16884
  } catch (err) {
16851
16885
  if (err.message.includes("invalid token0 amount")) {
16886
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => invalid token0 amount, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16852
16887
  return "go_low";
16853
16888
  } else if (err.message.includes("invalid token1 amount")) {
16889
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => invalid token1 amount, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16854
16890
  return "go_high";
16855
16891
  }
16892
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => error: ${err.message}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16856
16893
  return "retry";
16857
16894
  }
16858
16895
  };
@@ -32206,13 +32243,42 @@ async function executeTransactions(calls, acc, provider2, remarks) {
32206
32243
  console.log(`Transaction confirmed: ${tx.transaction_hash}`);
32207
32244
  return tx;
32208
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
+ }
32209
32274
  var Deployer = {
32210
32275
  getAccount,
32211
32276
  myDeclare,
32212
32277
  deployContract,
32213
32278
  prepareMultiDeployContracts,
32214
32279
  executeDeployCalls,
32215
- executeTransactions
32280
+ executeTransactions,
32281
+ myWaitForTransaction
32216
32282
  };
32217
32283
  var deployer_default = Deployer;
32218
32284
  // Annotate the CommonJS export names for ESM import in node: