@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.browser.global.js +97 -74
- package/dist/index.browser.mjs +95 -72
- package/dist/index.d.ts +3 -1
- package/dist/index.js +125 -73
- package/dist/index.mjs +125 -73
- 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/dist/index.js
CHANGED
|
@@ -2271,10 +2271,9 @@ function getTrovesEndpoint() {
|
|
|
2271
2271
|
}
|
|
2272
2272
|
|
|
2273
2273
|
// src/modules/avnu.ts
|
|
2274
|
-
var AvnuWrapper = class
|
|
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
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
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
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
16723
|
-
|
|
16724
|
-
|
|
16725
|
-
|
|
16726
|
-
|
|
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(
|
|
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 =>
|
|
16733
|
+
`${_EkuboCLVault.name}: harvest => isToken0ClaimToken: ${isToken0ClaimToken2}, baseSwapAmount: ${baseSwapAmount}`
|
|
16738
16734
|
);
|
|
16739
|
-
const remainingAmount = postFeeAmount.minus(
|
|
16735
|
+
const remainingAmount = postFeeAmount.minus(baseSwapAmount).maximum(0);
|
|
16740
16736
|
logger.verbose(
|
|
16741
16737
|
`${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
|
|
16742
16738
|
);
|
|
16743
|
-
|
|
16744
|
-
|
|
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 =>
|
|
16750
|
-
|
|
16742
|
+
`${_EkuboCLVault.name}: harvest => dummySwapInfo: ${JSON.stringify(
|
|
16743
|
+
dummySwapInfo
|
|
16751
16744
|
)}`
|
|
16752
16745
|
);
|
|
16753
16746
|
logger.verbose(
|
|
16754
|
-
`${_EkuboCLVault.name}: harvest =>
|
|
16755
|
-
|
|
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
|
-
|
|
16767
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
};
|
|
@@ -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 {
|