@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.browser.global.js +101 -76
- package/dist/index.browser.mjs +99 -74
- package/dist/index.d.ts +5 -1
- package/dist/index.js +129 -75
- package/dist/index.mjs +129 -75
- package/package.json +1 -1
- package/src/modules/avnu.ts +4 -4
- package/src/modules/harvests.ts +22 -15
- package/src/node/deployer.ts +36 -1
- package/src/strategies/ekubo-cl-vault.tsx +97 -57
- package/src/strategies/universal-lst-muliplier-strategy.tsx +8 -4
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
|
|
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
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
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
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
16621
|
-
|
|
16622
|
-
|
|
16623
|
-
|
|
16624
|
-
|
|
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(
|
|
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 =>
|
|
16631
|
+
`${_EkuboCLVault.name}: harvest => isToken0ClaimToken: ${isToken0ClaimToken2}, baseSwapAmount: ${baseSwapAmount}`
|
|
16636
16632
|
);
|
|
16637
|
-
const remainingAmount = postFeeAmount.minus(
|
|
16633
|
+
const remainingAmount = postFeeAmount.minus(baseSwapAmount).maximum(0);
|
|
16638
16634
|
logger.verbose(
|
|
16639
16635
|
`${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
|
|
16640
16636
|
);
|
|
16641
|
-
|
|
16642
|
-
|
|
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 =>
|
|
16648
|
-
|
|
16640
|
+
`${_EkuboCLVault.name}: harvest => dummySwapInfo: ${JSON.stringify(
|
|
16641
|
+
dummySwapInfo
|
|
16649
16642
|
)}`
|
|
16650
16643
|
);
|
|
16651
16644
|
logger.verbose(
|
|
16652
|
-
`${_EkuboCLVault.name}: harvest =>
|
|
16653
|
-
|
|
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
|
-
|
|
16665
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
};
|
|
@@ -30923,6 +30946,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30923
30946
|
* @param params
|
|
30924
30947
|
*/
|
|
30925
30948
|
async getVesuMultiplyCall(params) {
|
|
30949
|
+
const maxEkuboPriceImpact = params.maxEkuboPriceImpact || 0.01;
|
|
30926
30950
|
const vesuAdapter1 = this.getVesuSameTokenAdapter();
|
|
30927
30951
|
const legLTV = await vesuAdapter1.getLTVConfig(this.config);
|
|
30928
30952
|
logger.verbose(`${this.getTag()}::getVesuMultiplyCall legLTV: ${legLTV}`);
|
|
@@ -30958,7 +30982,8 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30958
30982
|
marginAmount,
|
|
30959
30983
|
debtAmount,
|
|
30960
30984
|
lstDexPriceInUnderlying: dexPrice,
|
|
30961
|
-
isIncrease: debtAmount.greaterThan(0)
|
|
30985
|
+
isIncrease: debtAmount.greaterThan(0),
|
|
30986
|
+
maxEkuboPriceImpact
|
|
30962
30987
|
});
|
|
30963
30988
|
}
|
|
30964
30989
|
getLSTUnderlyingTokenInfo() {
|
|
@@ -31135,7 +31160,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
31135
31160
|
// negative for exact amount out
|
|
31136
31161
|
);
|
|
31137
31162
|
logger.verbose(`${this.getTag()}::getModifyLeverCall leverSwapQuote: ${JSON.stringify(leverSwapQuote)}`);
|
|
31138
|
-
assert(leverSwapQuote.price_impact
|
|
31163
|
+
assert(leverSwapQuote.price_impact <= params.maxEkuboPriceImpact, "getIncreaseLeverCall: Price impact is too high [Debt swap]");
|
|
31139
31164
|
const leverSwap = ekuboQuoter.getVesuMultiplyQuote(leverSwapQuote, fromToken, toToken);
|
|
31140
31165
|
logger.verbose(`${this.getTag()}::getModifyLeverCall leverSwap: ${JSON.stringify(leverSwap)}`);
|
|
31141
31166
|
let minLSTReceived = params.debtAmount.dividedBy(lstDexPriceInUnderlying).multipliedBy(1 - MAX_SLIPPAGE);
|
|
@@ -32118,13 +32143,42 @@ async function executeTransactions(calls, acc, provider2, remarks) {
|
|
|
32118
32143
|
console.log(`Transaction confirmed: ${tx.transaction_hash}`);
|
|
32119
32144
|
return tx;
|
|
32120
32145
|
}
|
|
32146
|
+
async function myWaitForTransaction(transaction_hash, provider2, retry = 0) {
|
|
32147
|
+
const MAX_RETRIES = 60;
|
|
32148
|
+
logger.verbose(`Waiting for transaction: ${transaction_hash}, retry: ${retry}`);
|
|
32149
|
+
try {
|
|
32150
|
+
const status = await provider2.getTransactionStatus(transaction_hash);
|
|
32151
|
+
logger.verbose(`Transaction status: ${JSON.stringify(status.execution_status)}`);
|
|
32152
|
+
if (status.execution_status == TransactionExecutionStatus.SUCCEEDED) {
|
|
32153
|
+
return true;
|
|
32154
|
+
}
|
|
32155
|
+
if (status.execution_status == TransactionExecutionStatus.REVERTED) {
|
|
32156
|
+
throw new Error(`Transaction reverted: ${transaction_hash}`);
|
|
32157
|
+
}
|
|
32158
|
+
if (retry > MAX_RETRIES) {
|
|
32159
|
+
throw new Error(`Transaction not found: ${transaction_hash}`);
|
|
32160
|
+
}
|
|
32161
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
32162
|
+
return myWaitForTransaction(transaction_hash, provider2, retry + 1);
|
|
32163
|
+
} catch (error) {
|
|
32164
|
+
if (error instanceof Error && error.message.includes("Transaction reverted")) {
|
|
32165
|
+
throw new Error(`Transaction reverted: ${transaction_hash}`);
|
|
32166
|
+
}
|
|
32167
|
+
if (retry > MAX_RETRIES) {
|
|
32168
|
+
throw error;
|
|
32169
|
+
}
|
|
32170
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
32171
|
+
return myWaitForTransaction(transaction_hash, provider2, retry + 1);
|
|
32172
|
+
}
|
|
32173
|
+
}
|
|
32121
32174
|
var Deployer = {
|
|
32122
32175
|
getAccount,
|
|
32123
32176
|
myDeclare,
|
|
32124
32177
|
deployContract,
|
|
32125
32178
|
prepareMultiDeployContracts,
|
|
32126
32179
|
executeDeployCalls,
|
|
32127
|
-
executeTransactions
|
|
32180
|
+
executeTransactions,
|
|
32181
|
+
myWaitForTransaction
|
|
32128
32182
|
};
|
|
32129
32183
|
var deployer_default = Deployer;
|
|
32130
32184
|
export {
|
package/package.json
CHANGED
package/src/modules/avnu.ts
CHANGED
|
@@ -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),
|
package/src/modules/harvests.ts
CHANGED
|
@@ -34,23 +34,30 @@ export class Harvests {
|
|
|
34
34
|
const unClaimed: HarvestInfo[] = [];
|
|
35
35
|
|
|
36
36
|
// use the latest one
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
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
|
}
|
package/src/node/deployer.ts
CHANGED
|
@@ -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;
|