@strkfarm/sdk 1.1.39 → 1.1.41
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 +722 -186
- package/dist/index.browser.mjs +721 -183
- package/dist/index.d.ts +126 -13
- package/dist/index.js +722 -183
- package/dist/index.mjs +721 -183
- package/package.json +1 -1
- package/src/global.ts +18 -0
- package/src/modules/avnu.ts +5 -4
- package/src/modules/harvests.ts +16 -15
- package/src/strategies/ekubo-cl-vault.tsx +254 -86
- package/src/strategies/universal-adapters/baseAdapter.ts +184 -2
- package/src/strategies/universal-adapters/vesu-adapter.ts +34 -17
- package/src/strategies/universal-adapters/vesu-supply-only-adapter.ts +322 -0
- package/src/strategies/universal-lst-muliplier-strategy.tsx +226 -67
- package/src/strategies/universal-strategy.tsx +5 -5
- package/src/utils/health-factor-math.ts +83 -0
- package/src/utils/math-utils.ts +150 -0
package/package.json
CHANGED
package/src/global.ts
CHANGED
|
@@ -136,6 +136,24 @@ const defaultTokens: TokenInfo[] = [{
|
|
|
136
136
|
displayDecimals: 6,
|
|
137
137
|
priceProxySymbol: 'WBTC',
|
|
138
138
|
priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
|
|
139
|
+
}, {
|
|
140
|
+
name: 'mRe7BTC',
|
|
141
|
+
symbol: 'mRe7BTC',
|
|
142
|
+
logo: 'https://imagedelivery.net/0xPAQaDtnQhBs8IzYRIlNg/3a62ecee-1e58-45d3-9862-3ce90dff1900/logo',
|
|
143
|
+
address: ContractAddr.from('0x4e4fb1a9ca7e84bae609b9dc0078ad7719e49187ae7e425bb47d131710eddac'),
|
|
144
|
+
decimals: 18,
|
|
145
|
+
coingeckId: undefined,
|
|
146
|
+
displayDecimals: 6,
|
|
147
|
+
priceCheckAmount: 0.0001, // 112000 * 0.0001 = $11.2
|
|
148
|
+
}, {
|
|
149
|
+
name: 'mRe7YIELD',
|
|
150
|
+
symbol: 'mRe7YIELD',
|
|
151
|
+
logo: 'https://midas.app/assets/mre7-BcOOHm7i.svg',
|
|
152
|
+
address: ContractAddr.from('0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc'),
|
|
153
|
+
decimals: 18,
|
|
154
|
+
coingeckId: undefined,
|
|
155
|
+
displayDecimals: 2,
|
|
156
|
+
priceCheckAmount: 100,
|
|
139
157
|
}]
|
|
140
158
|
const tokens: TokenInfo[] = defaultTokens;
|
|
141
159
|
|
package/src/modules/avnu.ts
CHANGED
|
@@ -120,17 +120,18 @@ export class AvnuWrapper {
|
|
|
120
120
|
|
|
121
121
|
static buildZeroSwap(
|
|
122
122
|
tokenToSell: ContractAddr,
|
|
123
|
-
|
|
123
|
+
beneficiary: string,
|
|
124
|
+
tokenToBuy: ContractAddr = tokenToSell
|
|
124
125
|
): SwapInfo {
|
|
125
126
|
return {
|
|
126
127
|
token_from_address: tokenToSell.address,
|
|
127
128
|
token_from_amount: uint256.bnToUint256(0),
|
|
128
|
-
token_to_address:
|
|
129
|
+
token_to_address: tokenToBuy.address,
|
|
129
130
|
token_to_amount: uint256.bnToUint256(0),
|
|
130
131
|
token_to_min_amount: uint256.bnToUint256(0),
|
|
131
|
-
beneficiary:
|
|
132
|
+
beneficiary: beneficiary,
|
|
132
133
|
integrator_fee_amount_bps: 0,
|
|
133
|
-
integrator_fee_recipient:
|
|
134
|
+
integrator_fee_recipient: beneficiary,
|
|
134
135
|
routes: [],
|
|
135
136
|
};
|
|
136
137
|
}
|
package/src/modules/harvests.ts
CHANGED
|
@@ -33,23 +33,24 @@ export class Harvests {
|
|
|
33
33
|
|
|
34
34
|
const unClaimed: HarvestInfo[] = [];
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const contract = new Contract({abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider});
|
|
39
|
-
const isClaimed = await contract.call('is_claimed', [reward.claim.id]);
|
|
40
|
-
logger.verbose(`${Harvests.name}: isClaimed: ${isClaimed}`);
|
|
41
|
-
if (isClaimed) {
|
|
42
|
-
return unClaimed;
|
|
43
|
-
}
|
|
44
|
-
// rewards contract must have enough balance to claim
|
|
45
|
-
const bal = await (new ERC20(this.config)).balanceOf(reward.token, reward.rewardsContract.address, 18);
|
|
46
|
-
if (bal.lessThan(reward.claim.amount)) {
|
|
47
|
-
logger.verbose(`${Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
36
|
+
// use the latest one
|
|
37
|
+
const reward = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime())[0];
|
|
50
38
|
|
|
51
|
-
|
|
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;
|
|
52
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;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
unClaimed.unshift(reward); // to ensure older harvest is first
|
|
53
54
|
return unClaimed;
|
|
54
55
|
}
|
|
55
56
|
}
|
|
@@ -33,12 +33,13 @@ import { BaseStrategy } from "./base-strategy";
|
|
|
33
33
|
import { DualActionAmount } from "./base-strategy";
|
|
34
34
|
import { DualTokenInfo } from "./base-strategy";
|
|
35
35
|
import { log } from "winston";
|
|
36
|
-
import { EkuboHarvests } from "@/modules/harvests";
|
|
36
|
+
import { EkuboHarvests, HarvestInfo } from "@/modules/harvests";
|
|
37
37
|
import { logger } from "@/utils/logger";
|
|
38
38
|
import { COMMON_CONTRACTS } from "./constants";
|
|
39
39
|
import { DepegRiskLevel, ImpermanentLossLevel, MarketRiskLevel, SmartContractRiskLevel } from "@/interfaces/risks";
|
|
40
40
|
import { gql } from "@apollo/client";
|
|
41
41
|
import apolloClient from "@/modules/apollo-client";
|
|
42
|
+
import { binarySearch } from "@/utils/math-utils";
|
|
42
43
|
|
|
43
44
|
export interface EkuboPoolKey {
|
|
44
45
|
token0: ContractAddr;
|
|
@@ -481,7 +482,6 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
481
482
|
for (let i = len - 1; i >= 0; --i) {
|
|
482
483
|
let record: any = await this.contract.call("get_rewards_info", [i]);
|
|
483
484
|
logger.verbose(`${EkuboCLVault.name}: getHarvestRewardShares: ${i}`);
|
|
484
|
-
console.log(record);
|
|
485
485
|
const block = Number(record.block_number);
|
|
486
486
|
if (block < fromBlock) {
|
|
487
487
|
return shares;
|
|
@@ -713,16 +713,10 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
713
713
|
const sqrtRatio = EkuboCLVault.div2Power128(
|
|
714
714
|
BigInt(priceInfo.sqrt_ratio.toString())
|
|
715
715
|
);
|
|
716
|
-
console.log(
|
|
717
|
-
`EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, sqrtRatio: ${sqrtRatio}, ${priceInfo.sqrt_ratio.toString()}`
|
|
718
|
-
);
|
|
719
716
|
const token0Info = await Global.getTokenInfoFromAddr(poolKey.token0);
|
|
720
717
|
const token1Info = await Global.getTokenInfoFromAddr(poolKey.token1);
|
|
721
718
|
const price = sqrtRatio * sqrtRatio * (10 ** token0Info.decimals) / ( 10 ** token1Info.decimals);
|
|
722
719
|
const tick = priceInfo.tick;
|
|
723
|
-
console.log(
|
|
724
|
-
`EkuboCLVault: getCurrentPrice: blockIdentifier: ${blockIdentifier}, price: ${price}, tick: ${tick.mag}, ${tick.sign}`
|
|
725
|
-
);
|
|
726
720
|
return {
|
|
727
721
|
price,
|
|
728
722
|
tick: Number(tick.mag) * (tick.sign ? -1 : 1),
|
|
@@ -1592,70 +1586,249 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
1592
1586
|
}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`
|
|
1593
1587
|
);
|
|
1594
1588
|
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1589
|
+
const isRewardTokenMatch = claim.token.eq(poolKey.token0) || claim.token.eq(poolKey.token1);
|
|
1590
|
+
if (isRewardTokenMatch) {
|
|
1591
|
+
const _callsFinal = await this._handleRewardAndVaultTokenMatchHarvest({
|
|
1592
|
+
acc,
|
|
1593
|
+
claim,
|
|
1594
|
+
isToken1,
|
|
1595
|
+
token0Info,
|
|
1596
|
+
token1Info,
|
|
1597
|
+
postFeeAmount,
|
|
1598
|
+
poolKey,
|
|
1599
|
+
bounds,
|
|
1600
|
+
maxIterations,
|
|
1601
|
+
priceRatioPrecision,
|
|
1602
|
+
});
|
|
1603
|
+
calls.push(..._callsFinal);
|
|
1604
|
+
} else {
|
|
1605
|
+
const _callsFinal = await this._handleRewardAndVaultTokenMismatchHarvest({
|
|
1606
|
+
claim,
|
|
1607
|
+
token0Info,
|
|
1608
|
+
token1Info,
|
|
1609
|
+
postFeeAmount,
|
|
1610
|
+
poolKey,
|
|
1611
|
+
bounds,
|
|
1612
|
+
maxIterations,
|
|
1613
|
+
priceRatioPrecision,
|
|
1614
|
+
acc,
|
|
1615
|
+
});
|
|
1616
|
+
calls.push(..._callsFinal);
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
return calls;
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
/**
|
|
1623
|
+
* @description This funciton requires atleast one of the pool tokens to be reward token
|
|
1624
|
+
* i.e. STRK.
|
|
1625
|
+
* @param params
|
|
1626
|
+
*/
|
|
1627
|
+
async _handleRewardAndVaultTokenMatchHarvest(params: {
|
|
1628
|
+
claim: HarvestInfo;
|
|
1629
|
+
isToken1: boolean;
|
|
1630
|
+
token0Info: TokenInfo;
|
|
1631
|
+
token1Info: TokenInfo;
|
|
1632
|
+
postFeeAmount: Web3Number;
|
|
1633
|
+
poolKey: EkuboPoolKey;
|
|
1634
|
+
bounds: EkuboBounds;
|
|
1635
|
+
maxIterations: number;
|
|
1636
|
+
priceRatioPrecision: number;
|
|
1637
|
+
acc: Account;
|
|
1638
|
+
}) {
|
|
1639
|
+
const { acc, claim, isToken1, token0Info, token1Info, postFeeAmount, poolKey, bounds, maxIterations, priceRatioPrecision } = params;
|
|
1640
|
+
const token0Amt = isToken1
|
|
1641
|
+
? new Web3Number(0, token0Info.decimals)
|
|
1642
|
+
: postFeeAmount;
|
|
1643
|
+
const token1Amt = isToken1
|
|
1644
|
+
? postFeeAmount
|
|
1645
|
+
: new Web3Number(0, token0Info.decimals);
|
|
1646
|
+
logger.verbose(
|
|
1647
|
+
`${
|
|
1648
|
+
EkuboCLVault.name
|
|
1649
|
+
}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
|
|
1650
|
+
);
|
|
1651
|
+
|
|
1652
|
+
// THis function cannot handle swapping of non-STRK pool,
|
|
1653
|
+
// bcz atleast one of token0Amt or token1Amt are in STRK terms.
|
|
1654
|
+
const swapInfo = await this.getSwapInfoGivenAmounts(
|
|
1655
|
+
poolKey,
|
|
1656
|
+
token0Amt,
|
|
1657
|
+
token1Amt,
|
|
1658
|
+
bounds,
|
|
1659
|
+
maxIterations,
|
|
1660
|
+
priceRatioPrecision
|
|
1661
|
+
);
|
|
1662
|
+
swapInfo.token_to_address = token0Info.address.address;
|
|
1663
|
+
logger.verbose(
|
|
1664
|
+
`${EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
|
|
1665
|
+
);
|
|
1666
|
+
|
|
1667
|
+
logger.verbose(
|
|
1668
|
+
`${EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
|
|
1669
|
+
);
|
|
1670
|
+
const harvestEstimateCall = async (swapInfo1: SwapInfo) => {
|
|
1671
|
+
const swap1Amount = Web3Number.fromWei(
|
|
1672
|
+
uint256.uint256ToBN(swapInfo1.token_from_amount).toString(),
|
|
1673
|
+
18 // cause its always STRK?
|
|
1674
|
+
).minimum(
|
|
1675
|
+
postFeeAmount.toFixed(18) // cause always strk
|
|
1676
|
+
); // ensure we don't swap more than we have
|
|
1677
|
+
swapInfo.token_from_amount = uint256.bnToUint256(swap1Amount.toWei());
|
|
1678
|
+
swapInfo.token_to_min_amount = uint256.bnToUint256(
|
|
1679
|
+
swap1Amount.multipliedBy(0).toWei() // placeholder
|
|
1680
|
+
); // 0.01% slippage
|
|
1681
|
+
|
|
1602
1682
|
logger.verbose(
|
|
1603
|
-
`${
|
|
1604
|
-
EkuboCLVault.name
|
|
1605
|
-
}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
|
|
1683
|
+
`${EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
|
|
1606
1684
|
);
|
|
1607
1685
|
|
|
1608
|
-
const
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1686
|
+
const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
|
|
1687
|
+
logger.verbose(
|
|
1688
|
+
`${EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
|
|
1689
|
+
);
|
|
1690
|
+
const swapInfo2 = {
|
|
1691
|
+
...swapInfo,
|
|
1692
|
+
token_from_amount: uint256.bnToUint256(remainingAmount.toWei()),
|
|
1693
|
+
};
|
|
1694
|
+
swapInfo2.token_to_address = token1Info.address.address;
|
|
1695
|
+
logger.verbose(
|
|
1696
|
+
`${EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
|
|
1697
|
+
swapInfo
|
|
1698
|
+
)}`
|
|
1615
1699
|
);
|
|
1616
|
-
swapInfo.token_to_address = token0Info.address.address;
|
|
1617
1700
|
logger.verbose(
|
|
1618
|
-
`${EkuboCLVault.name}: harvest =>
|
|
1701
|
+
`${EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
|
|
1702
|
+
swapInfo2
|
|
1703
|
+
)}`
|
|
1619
1704
|
);
|
|
1620
|
-
|
|
1705
|
+
const calldata = [
|
|
1706
|
+
claim.rewardsContract.address,
|
|
1707
|
+
{
|
|
1708
|
+
id: claim.claim.id,
|
|
1709
|
+
amount: claim.claim.amount.toWei(),
|
|
1710
|
+
claimee: claim.claim.claimee.address,
|
|
1711
|
+
},
|
|
1712
|
+
claim.proof.map((p) => num.getDecimalString(p)),
|
|
1713
|
+
swapInfo,
|
|
1714
|
+
swapInfo2,
|
|
1715
|
+
];
|
|
1621
1716
|
logger.verbose(
|
|
1622
|
-
`${EkuboCLVault.name}: harvest =>
|
|
1717
|
+
`${EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
|
|
1718
|
+
calldata
|
|
1719
|
+
)}`
|
|
1720
|
+
);
|
|
1721
|
+
return [this.contract.populate("harvest", calldata)];
|
|
1722
|
+
};
|
|
1723
|
+
const _callsFinal = await this.rebalanceIter(
|
|
1724
|
+
swapInfo,
|
|
1725
|
+
acc,
|
|
1726
|
+
harvestEstimateCall,
|
|
1727
|
+
claim.token.eq(poolKey.token0),
|
|
1728
|
+
0,
|
|
1729
|
+
0n,
|
|
1730
|
+
BigInt(postFeeAmount.toWei()), // upper limit is the post fee amount
|
|
1731
|
+
);
|
|
1732
|
+
logger.verbose(
|
|
1733
|
+
`${EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
|
|
1734
|
+
_callsFinal
|
|
1735
|
+
)}`
|
|
1736
|
+
);
|
|
1737
|
+
|
|
1738
|
+
return _callsFinal;
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
/**
|
|
1742
|
+
* @description This function handles harvesting of reward token that is not the same as any of the vault token
|
|
1743
|
+
* i.e. STRK is not part of vault tokens like BTC/ETH
|
|
1744
|
+
* @param params
|
|
1745
|
+
* @returns
|
|
1746
|
+
*/
|
|
1747
|
+
async _handleRewardAndVaultTokenMismatchHarvest(params: {
|
|
1748
|
+
claim: HarvestInfo;
|
|
1749
|
+
token0Info: TokenInfo;
|
|
1750
|
+
token1Info: TokenInfo;
|
|
1751
|
+
postFeeAmount: Web3Number;
|
|
1752
|
+
poolKey: EkuboPoolKey;
|
|
1753
|
+
bounds: EkuboBounds;
|
|
1754
|
+
maxIterations: number;
|
|
1755
|
+
priceRatioPrecision: number;
|
|
1756
|
+
acc: Account;
|
|
1757
|
+
}) {
|
|
1758
|
+
const { acc, claim, token0Info, token1Info, postFeeAmount, poolKey, bounds, maxIterations, priceRatioPrecision } = params;
|
|
1759
|
+
let token0Amt = postFeeAmount;
|
|
1760
|
+
|
|
1761
|
+
// receiver of output swap tokens (vault itself)
|
|
1762
|
+
const beneficiary = this.address.address;
|
|
1763
|
+
let harvestCall: Call | null = null;
|
|
1764
|
+
|
|
1765
|
+
/**
|
|
1766
|
+
* Approach: Use binary search to decide the optimal split of reward
|
|
1767
|
+
* such that the output tokens can be used for exact liquidity addition
|
|
1768
|
+
*/
|
|
1769
|
+
harvestCall = await this.harvestMismatchEstimateCallFn({
|
|
1770
|
+
postFeeAmount,
|
|
1771
|
+
claim,
|
|
1772
|
+
token0Info,
|
|
1773
|
+
token1Info,
|
|
1774
|
+
acc,
|
|
1775
|
+
});
|
|
1776
|
+
if (!harvestCall) {
|
|
1777
|
+
throw new Error("Harvest call not found");
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
return [harvestCall];
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
// given an amount (i.e. portion of reward to use to swap to token0), returns info on increasing or decreasing
|
|
1784
|
+
// amount for binary search
|
|
1785
|
+
async harvestMismatchEstimateCallFn(params: {
|
|
1786
|
+
postFeeAmount: Web3Number;
|
|
1787
|
+
claim: HarvestInfo;
|
|
1788
|
+
token0Info: TokenInfo;
|
|
1789
|
+
token1Info: TokenInfo;
|
|
1790
|
+
acc: Account;
|
|
1791
|
+
}) {
|
|
1792
|
+
const { postFeeAmount, claim, token0Info, token1Info, acc } = params;
|
|
1793
|
+
let harvestCall: Call | null = null;
|
|
1794
|
+
|
|
1795
|
+
const binarySearchCallbackFn = async (mid: bigint) => {
|
|
1796
|
+
const rewardPart2 = BigInt(postFeeAmount.toWei()) - mid;
|
|
1797
|
+
const avnuWrapper = new AvnuWrapper();
|
|
1798
|
+
const beneficiary = this.address.address;
|
|
1799
|
+
|
|
1800
|
+
// get quote for 1st part
|
|
1801
|
+
const quote1 = await avnuWrapper.getQuotes(
|
|
1802
|
+
claim.token.address,
|
|
1803
|
+
token0Info.address.address,
|
|
1804
|
+
mid.toString(),
|
|
1805
|
+
beneficiary
|
|
1806
|
+
);
|
|
1807
|
+
// default min amount is ok
|
|
1808
|
+
const swapInfo1 = await avnuWrapper.getSwapInfo(
|
|
1809
|
+
quote1,
|
|
1810
|
+
beneficiary,
|
|
1811
|
+
0,
|
|
1812
|
+
beneficiary
|
|
1623
1813
|
);
|
|
1624
|
-
const harvestEstimateCall = async (swapInfo1: SwapInfo) => {
|
|
1625
|
-
const swap1Amount = Web3Number.fromWei(
|
|
1626
|
-
uint256.uint256ToBN(swapInfo1.token_from_amount).toString(),
|
|
1627
|
-
18 // cause its always STRK?
|
|
1628
|
-
).minimum(
|
|
1629
|
-
postFeeAmount.toFixed(18) // cause always strk
|
|
1630
|
-
); // ensure we don't swap more than we have
|
|
1631
|
-
swapInfo.token_from_amount = uint256.bnToUint256(swap1Amount.toWei());
|
|
1632
|
-
swapInfo.token_to_min_amount = uint256.bnToUint256(
|
|
1633
|
-
swap1Amount.multipliedBy(0).toWei() // placeholder
|
|
1634
|
-
); // 0.01% slippage
|
|
1635
1814
|
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1815
|
+
// get quote for 2nd part
|
|
1816
|
+
const quote2 = await avnuWrapper.getQuotes(
|
|
1817
|
+
claim.token.address,
|
|
1818
|
+
token1Info.address.address,
|
|
1819
|
+
rewardPart2.toString(),
|
|
1820
|
+
beneficiary
|
|
1821
|
+
);
|
|
1822
|
+
// default min amount is ok
|
|
1823
|
+
const swapInfo2 = await avnuWrapper.getSwapInfo(
|
|
1824
|
+
quote2,
|
|
1825
|
+
beneficiary,
|
|
1826
|
+
0,
|
|
1827
|
+
beneficiary
|
|
1828
|
+
);
|
|
1639
1829
|
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
`${EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
|
|
1643
|
-
);
|
|
1644
|
-
const swapInfo2 = {
|
|
1645
|
-
...swapInfo,
|
|
1646
|
-
token_from_amount: uint256.bnToUint256(remainingAmount.toWei()),
|
|
1647
|
-
};
|
|
1648
|
-
swapInfo2.token_to_address = token1Info.address.address;
|
|
1649
|
-
logger.verbose(
|
|
1650
|
-
`${EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
|
|
1651
|
-
swapInfo
|
|
1652
|
-
)}`
|
|
1653
|
-
);
|
|
1654
|
-
logger.verbose(
|
|
1655
|
-
`${EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
|
|
1656
|
-
swapInfo2
|
|
1657
|
-
)}`
|
|
1658
|
-
);
|
|
1830
|
+
// estimate the harvest using this swap info
|
|
1831
|
+
try {
|
|
1659
1832
|
const calldata = [
|
|
1660
1833
|
claim.rewardsContract.address,
|
|
1661
1834
|
{
|
|
@@ -1664,33 +1837,28 @@ export class EkuboCLVault extends BaseStrategy<
|
|
|
1664
1837
|
claimee: claim.claim.claimee.address,
|
|
1665
1838
|
},
|
|
1666
1839
|
claim.proof.map((p) => num.getDecimalString(p)),
|
|
1667
|
-
|
|
1840
|
+
swapInfo1,
|
|
1668
1841
|
swapInfo2,
|
|
1669
1842
|
];
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
)
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
0n,
|
|
1684
|
-
BigInt(postFeeAmount.toWei()), // upper limit is the post fee amount
|
|
1685
|
-
);
|
|
1686
|
-
logger.verbose(
|
|
1687
|
-
`${EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
|
|
1688
|
-
_callsFinal
|
|
1689
|
-
)}`
|
|
1690
|
-
);
|
|
1691
|
-
calls.push(..._callsFinal);
|
|
1843
|
+
harvestCall = this.contract.populate("harvest", calldata)
|
|
1844
|
+
const gas = await acc.estimateInvokeFee(harvestCall);
|
|
1845
|
+
return 'found';
|
|
1846
|
+
} catch (err: any) {
|
|
1847
|
+
if (err.message.includes('invalid token0 amount')) {
|
|
1848
|
+
// too much token0 amount left, may be swap less to token0
|
|
1849
|
+
return 'go_low';
|
|
1850
|
+
} else if (err.message.includes('invalid token1 amount')) {
|
|
1851
|
+
// too much token1 balance left, may be swap more to token0
|
|
1852
|
+
return 'go_high';
|
|
1853
|
+
}
|
|
1854
|
+
return 'retry';
|
|
1855
|
+
}
|
|
1692
1856
|
}
|
|
1693
|
-
|
|
1857
|
+
|
|
1858
|
+
// run the binary search
|
|
1859
|
+
await binarySearch(0n, BigInt(postFeeAmount.toWei()), binarySearchCallbackFn);
|
|
1860
|
+
|
|
1861
|
+
return harvestCall;
|
|
1694
1862
|
}
|
|
1695
1863
|
|
|
1696
1864
|
async getInvestmentFlows() {
|