@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.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
  };
@@ -15656,13 +15658,27 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
15656
15658
  const tvlBefore = await this._getTVL(blockBefore);
15657
15659
  const supplyBefore = await this.totalSupply(blockBefore);
15658
15660
  const priceBefore = await this.getCurrentPrice(blockBefore);
15659
- const tvlInToken0Now = tvlNow.amount0.multipliedBy(priceNow.price).plus(tvlNow.amount1);
15660
- const tvlPerShareNow = tvlInToken0Now.multipliedBy(1e18).dividedBy(adjustedSupplyNow.toString());
15661
- const tvlInToken0Bf = tvlBefore.amount0.multipliedBy(priceBefore.price).plus(tvlBefore.amount1);
15662
- const tvlPerShareBf = tvlInToken0Bf.multipliedBy(1e18).dividedBy(supplyBefore.toString());
15661
+ const poolKey = await this.getPoolKey(blockBefore);
15662
+ logger.verbose(`priceBefore: ${priceBefore.price.toString()}`);
15663
+ logger.verbose(`priceNow: ${priceNow.price.toString()}`);
15664
+ logger.verbose(`tvlBefore: ${JSON.stringify(tvlBefore)}`);
15665
+ logger.verbose(`tvlNow: ${JSON.stringify(tvlNow)}`);
15666
+ const isQuoteTokenToken0 = this.metadata.additionalInfo.quoteAsset.address.eq(poolKey.token0);
15667
+ logger.verbose(`isQuoteTokenToken0: ${isQuoteTokenToken0}`);
15668
+ let tvlBeforeInBaseAsset = Web3Number.fromWei(0, this.metadata.additionalInfo.quoteAsset.decimals);
15669
+ let tvlNowInBaseAsset = Web3Number.fromWei(0, this.metadata.additionalInfo.quoteAsset.decimals);
15670
+ if (!isQuoteTokenToken0) {
15671
+ tvlNowInBaseAsset = tvlNow.amount0.multipliedBy(priceNow.price).plus(tvlNow.amount1);
15672
+ tvlBeforeInBaseAsset = tvlBefore.amount0.multipliedBy(priceBefore.price).plus(tvlBefore.amount1);
15673
+ } else {
15674
+ tvlNowInBaseAsset = tvlNow.amount1.multipliedBy(1 / priceNow.price).plus(tvlNow.amount0);
15675
+ tvlBeforeInBaseAsset = tvlBefore.amount1.multipliedBy(1 / priceBefore.price).plus(tvlBefore.amount0);
15676
+ }
15677
+ const tvlPerShareNow = tvlNowInBaseAsset.multipliedBy(1e18).dividedBy(adjustedSupplyNow.toString());
15678
+ const tvlPerShareBf = tvlBeforeInBaseAsset.multipliedBy(1e18).dividedBy(supplyBefore.toString());
15663
15679
  const timeDiffSeconds = blockNowTime - blockBeforeInfo.timestamp;
15664
- logger.verbose(`tvlInToken0Now: ${tvlInToken0Now.toString()}`);
15665
- logger.verbose(`tvlInToken0Bf: ${tvlInToken0Bf.toString()}`);
15680
+ logger.verbose(`tvlNowInBaseAsset: ${tvlNowInBaseAsset.toString()}`);
15681
+ logger.verbose(`tvlBeforeInBaseAsset: ${tvlBeforeInBaseAsset.toString()}`);
15666
15682
  logger.verbose(`tvlPerShareNow: ${tvlPerShareNow.toString()}`);
15667
15683
  logger.verbose(`tvlPerShareBf: ${tvlPerShareBf.toString()}`);
15668
15684
  logger.verbose(`Price before: ${priceBefore.price.toString()}`);
@@ -16524,11 +16540,15 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16524
16540
  amount1
16525
16541
  };
16526
16542
  }
16527
- async harvest(acc, maxIterations = 20, priceRatioPrecision = 4) {
16543
+ async harvest(acc, maxIterations = 20, priceRatioPrecision = 4, minRewardAmount = new Web3Number(0, 18)) {
16528
16544
  const ekuboHarvests = new EkuboHarvests(this.config);
16529
- const unClaimedRewards = await ekuboHarvests.getUnHarvestedRewards(
16545
+ const unClaimedRewards = (await ekuboHarvests.getUnHarvestedRewards(
16530
16546
  this.address
16531
- );
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
+ }
16532
16552
  const poolKey = await this.getPoolKey();
16533
16553
  const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
16534
16554
  const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
@@ -16537,7 +16557,10 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16537
16557
  `${_EkuboCLVault.name}: harvest => unClaimedRewards: ${unClaimedRewards.length}`
16538
16558
  );
16539
16559
  const calls = [];
16540
- 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]) {
16541
16564
  const fee = claim.claim.amount.multipliedBy(this.metadata.additionalInfo.feeBps).dividedBy(1e4);
16542
16565
  const postFeeAmount = claim.claim.amount.minus(fee);
16543
16566
  const isToken1 = claim.token.eq(poolKey.token1);
@@ -16586,57 +16609,41 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16586
16609
  const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
16587
16610
  const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
16588
16611
  logger.verbose(
16589
- `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
16590
- );
16591
- const swapInfo = await this.getSwapInfoGivenAmounts(
16592
- poolKey,
16593
- token0Amt,
16594
- token1Amt,
16595
- bounds,
16596
- maxIterations,
16597
- priceRatioPrecision
16598
- );
16599
- swapInfo.token_to_address = token0Info.address.address;
16600
- logger.verbose(
16601
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
16612
+ `${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toFixed(18)}, token1Amt: ${token1Amt.toFixed(18)}`
16602
16613
  );
16603
16614
  logger.verbose(
16604
16615
  `${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
16605
16616
  );
16606
- const harvestEstimateCall = async (swapInfo1) => {
16607
- const swap1Amount = Web3Number.fromWei(
16608
- uint2564.uint256ToBN(swapInfo1.token_from_amount).toString(),
16609
- 18
16610
- // 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
16611
16622
  ).minimum(
16612
- postFeeAmount.toFixed(18)
16613
- // cause always strk
16614
- );
16615
- swapInfo.token_from_amount = uint2564.bnToUint256(swap1Amount.toWei());
16616
- swapInfo.token_to_min_amount = uint2564.bnToUint256(
16617
- swap1Amount.multipliedBy(0).toWei()
16618
- // placeholder
16623
+ postFeeAmount.toFixed(claimTokenInfo.decimals)
16619
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);
16620
16630
  logger.verbose(
16621
- `${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
16631
+ `${_EkuboCLVault.name}: harvest => isToken0ClaimToken: ${isToken0ClaimToken2}, baseSwapAmount: ${baseSwapAmount}`
16622
16632
  );
16623
- const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
16633
+ const remainingAmount = postFeeAmount.minus(baseSwapAmount).maximum(0);
16624
16634
  logger.verbose(
16625
16635
  `${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
16626
16636
  );
16627
- const swapInfo2 = {
16628
- ...swapInfo,
16629
- token_from_amount: uint2564.bnToUint256(remainingAmount.toWei())
16630
- };
16631
- 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());
16632
16639
  logger.verbose(
16633
- `${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
16634
- swapInfo
16640
+ `${_EkuboCLVault.name}: harvest => dummySwapInfo: ${JSON.stringify(
16641
+ dummySwapInfo
16635
16642
  )}`
16636
16643
  );
16637
16644
  logger.verbose(
16638
- `${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
16639
- swapInfo2
16645
+ `${_EkuboCLVault.name}: harvest => baseSwapInfo: ${JSON.stringify(
16646
+ baseSwapInfo2
16640
16647
  )}`
16641
16648
  );
16642
16649
  const calldata = [
@@ -16647,18 +16654,36 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16647
16654
  claimee: claim.claim.claimee.address
16648
16655
  },
16649
16656
  claim.proof.map((p) => num5.getDecimalString(p)),
16650
- swapInfo,
16651
- swapInfo2
16657
+ isToken0ClaimToken2 ? dummySwapInfo : baseSwapInfo2,
16658
+ // is token0 claim token, its just dummy swap
16659
+ isToken0ClaimToken2 ? baseSwapInfo2 : dummySwapInfo
16652
16660
  ];
16653
- logger.verbose(
16654
- `${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
16655
- calldata
16656
- )}`
16657
- );
16658
16661
  return [this.contract.populate("harvest", calldata)];
16659
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
+ }
16660
16685
  const _callsFinal = await this.rebalanceIter(
16661
- swapInfo,
16686
+ baseSwapInfo,
16662
16687
  acc,
16663
16688
  harvestEstimateCall,
16664
16689
  claim.token.eq(poolKey.token0),
@@ -16702,32 +16727,40 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16702
16727
  async harvestMismatchEstimateCallFn(params) {
16703
16728
  const { postFeeAmount, claim, token0Info, token1Info, acc } = params;
16704
16729
  let harvestCall = null;
16730
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => postFeeAmount: ${postFeeAmount.toString()}`);
16731
+ let attempt = 0;
16732
+ let MAX_ATTEMPTS = 50;
16705
16733
  const binarySearchCallbackFn = async (mid) => {
16734
+ attempt++;
16735
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => mid: ${mid}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16706
16736
  const rewardPart2 = BigInt(postFeeAmount.toWei()) - mid;
16707
16737
  const avnuWrapper = new AvnuWrapper();
16708
16738
  const beneficiary = this.address.address;
16709
- const quote1 = await avnuWrapper.getQuotes(
16739
+ const quote1Prom = avnuWrapper.getQuotes(
16710
16740
  claim.token.address,
16711
16741
  token0Info.address.address,
16712
16742
  mid.toString(),
16713
16743
  beneficiary
16714
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]);
16715
16752
  const swapInfo1 = await avnuWrapper.getSwapInfo(
16716
16753
  quote1,
16717
16754
  beneficiary,
16718
16755
  0,
16719
- beneficiary
16720
- );
16721
- const quote2 = await avnuWrapper.getQuotes(
16722
- claim.token.address,
16723
- token1Info.address.address,
16724
- rewardPart2.toString(),
16756
+ // fee bps
16725
16757
  beneficiary
16726
16758
  );
16727
16759
  const swapInfo2 = await avnuWrapper.getSwapInfo(
16728
16760
  quote2,
16729
16761
  beneficiary,
16730
16762
  0,
16763
+ // fee bps
16731
16764
  beneficiary
16732
16765
  );
16733
16766
  try {
@@ -16744,13 +16777,17 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
16744
16777
  ];
16745
16778
  harvestCall = this.contract.populate("harvest", calldata);
16746
16779
  const gas = await acc.estimateInvokeFee(harvestCall);
16780
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => gas: ${gas.overall_fee.toString()}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16747
16781
  return "found";
16748
16782
  } catch (err) {
16749
16783
  if (err.message.includes("invalid token0 amount")) {
16784
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => invalid token0 amount, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16750
16785
  return "go_low";
16751
16786
  } else if (err.message.includes("invalid token1 amount")) {
16787
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => invalid token1 amount, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16752
16788
  return "go_high";
16753
16789
  }
16790
+ logger.verbose(`${_EkuboCLVault.name}: harvestMismatchEstimateCallFn => error: ${err.message}, attempt: ${attempt}/${MAX_ATTEMPTS}`);
16754
16791
  return "retry";
16755
16792
  }
16756
16793
  };
@@ -32104,13 +32141,42 @@ async function executeTransactions(calls, acc, provider2, remarks) {
32104
32141
  console.log(`Transaction confirmed: ${tx.transaction_hash}`);
32105
32142
  return tx;
32106
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
+ }
32107
32172
  var Deployer = {
32108
32173
  getAccount,
32109
32174
  myDeclare,
32110
32175
  deployContract,
32111
32176
  prepareMultiDeployContracts,
32112
32177
  executeDeployCalls,
32113
- executeTransactions
32178
+ executeTransactions,
32179
+ myWaitForTransaction
32114
32180
  };
32115
32181
  var deployer_default = Deployer;
32116
32182
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strkfarm/sdk",
3
- "version": "1.1.49",
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",
@@ -37,7 +37,7 @@ export class AvnuWrapper {
37
37
  excludeSources = ['Haiko(Solvers)']
38
38
  ): Promise<Quote> {
39
39
  const MAX_RETRY = 5;
40
- logger.verbose(`${AvnuWrapper.name}: getQuotes => Getting quotes for ${fromToken} -> ${toToken}, amount: ${amountWei}, taker: ${taker}, retry: ${retry}`);
40
+ // logger.verbose(`${AvnuWrapper.name}: getQuotes => Getting quotes for ${fromToken} -> ${toToken}, amount: ${amountWei}, taker: ${taker}, retry: ${retry}`);
41
41
  const params: any = {
42
42
  sellTokenAddress: fromToken,
43
43
  buyTokenAddress: toToken,
@@ -100,9 +100,9 @@ export class AvnuWrapper {
100
100
  // swapInfo as expected by the strategy
101
101
  // fallback, max 1% slippage
102
102
  const _minAmount = minAmount || (quote.buyAmount * 95n / 100n).toString();
103
- logger.verbose(`${AvnuWrapper.name}: getSwapInfo => sellToken: ${quote.sellTokenAddress}, sellAmount: ${quote.sellAmount}`);
104
- logger.verbose(`${AvnuWrapper.name}: getSwapInfo => buyToken: ${quote.buyTokenAddress}`);
105
- logger.verbose(`${AvnuWrapper.name}: getSwapInfo => buyAmount: ${quote.buyAmount}, minAmount: ${_minAmount}`);
103
+ // logger.verbose(`${AvnuWrapper.name}: getSwapInfo => sellToken: ${quote.sellTokenAddress}, sellAmount: ${quote.sellAmount}`);
104
+ // logger.verbose(`${AvnuWrapper.name}: getSwapInfo => buyToken: ${quote.buyTokenAddress}`);
105
+ // logger.verbose(`${AvnuWrapper.name}: getSwapInfo => buyAmount: ${quote.buyAmount}, minAmount: ${_minAmount}`);
106
106
  const swapInfo: SwapInfo = {
107
107
  token_from_address: quote.sellTokenAddress,
108
108
  token_from_amount: uint256.bnToUint256(quote.sellAmount),
@@ -34,23 +34,30 @@ export class Harvests {
34
34
  const unClaimed: HarvestInfo[] = [];
35
35
 
36
36
  // use the latest one
37
- const reward = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime())[0];
38
-
39
- const cls = await this.config.provider.getClassAt(reward.rewardsContract.address);
40
- const contract = new Contract({abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider});
41
- const isClaimed = await contract.call('is_claimed', [reward.claim.id]);
42
- logger.verbose(`${Harvests.name}: isClaimed: ${isClaimed}`);
43
- if (isClaimed) {
44
- return unClaimed;
45
- }
46
- // rewards contract must have enough balance to claim
47
- const bal = await (new ERC20(this.config)).balanceOf(reward.token, reward.rewardsContract.address, 18);
48
- if (bal.lessThan(reward.claim.amount)) {
49
- logger.verbose(`${Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
50
- return unClaimed;
37
+ const sortedRewards = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime());
38
+ if (sortedRewards.length == 0) {
39
+ logger.verbose(`${Harvests.name}: no rewards found`);
40
+ return [];
51
41
  }
52
42
 
53
- unClaimed.unshift(reward); // to ensure older harvest is first
43
+ const cls = await this.config.provider.getClassAt(sortedRewards[0].rewardsContract.address);
44
+
45
+ for (const reward of sortedRewards) {
46
+ const contract = new Contract({abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider});
47
+ const isClaimed = await contract.call('is_claimed', [reward.claim.id]);
48
+ logger.verbose(`${Harvests.name}: isClaimed: ${isClaimed}, claim id: ${reward.claim.id}, address: ${reward.rewardsContract.address}`);
49
+ if (isClaimed) {
50
+ continue;
51
+ }
52
+ // rewards contract must have enough balance to claim
53
+ const bal = await (new ERC20(this.config)).balanceOf(reward.token, reward.rewardsContract.address, 18);
54
+ if (bal.lessThan(reward.claim.amount)) {
55
+ logger.verbose(`${Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
56
+ continue;
57
+ }
58
+
59
+ unClaimed.push(reward); // to ensure older harvest is first
60
+ }
54
61
  return unClaimed;
55
62
  }
56
63
  }
@@ -4,6 +4,7 @@ import { readFileSync, existsSync, writeFileSync } from 'fs'
4
4
  import { IConfig } from '../interfaces';
5
5
  import { Store, getDefaultStoreConfig } from '../utils/store';
6
6
  import { add } from 'winston';
7
+ import { logger } from '@/utils';
7
8
 
8
9
  function getContracts() {
9
10
  const PATH = './contracts.json'
@@ -207,13 +208,47 @@ async function executeTransactions(
207
208
  return tx;
208
209
  }
209
210
 
211
+ async function myWaitForTransaction(
212
+ transaction_hash: string,
213
+ provider: RpcProvider,
214
+ retry = 0
215
+ ) {
216
+ const MAX_RETRIES = 60;
217
+ logger.verbose(`Waiting for transaction: ${transaction_hash}, retry: ${retry}`);
218
+ try {
219
+ const status = await provider.getTransactionStatus(transaction_hash);
220
+ logger.verbose(`Transaction status: ${JSON.stringify(status.execution_status)}`);
221
+ if (status.execution_status == TransactionExecutionStatus.SUCCEEDED) {
222
+ return true;
223
+ }
224
+ if (status.execution_status == TransactionExecutionStatus.REVERTED) {
225
+ throw new Error(`Transaction reverted: ${transaction_hash}`);
226
+ }
227
+ if (retry > MAX_RETRIES) {
228
+ throw new Error(`Transaction not found: ${transaction_hash}`);
229
+ }
230
+ await new Promise(resolve => setTimeout(resolve, 1000));
231
+ return myWaitForTransaction(transaction_hash, provider, retry + 1);
232
+ } catch (error) {
233
+ if (error instanceof Error && error.message.includes('Transaction reverted')) {
234
+ throw new Error(`Transaction reverted: ${transaction_hash}`);
235
+ }
236
+ if (retry > MAX_RETRIES) {
237
+ throw error;
238
+ }
239
+ await new Promise(resolve => setTimeout(resolve, 1000));
240
+ return myWaitForTransaction(transaction_hash, provider, retry + 1);
241
+ }
242
+ }
243
+
210
244
  const Deployer = {
211
245
  getAccount,
212
246
  myDeclare,
213
247
  deployContract,
214
248
  prepareMultiDeployContracts,
215
249
  executeDeployCalls,
216
- executeTransactions
250
+ executeTransactions,
251
+ myWaitForTransaction
217
252
  }
218
253
 
219
254
  export default Deployer;