@strkfarm/sdk 2.0.0-dev.4 → 2.0.0-dev.6
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 +490 -203
- package/dist/index.browser.mjs +490 -203
- package/dist/index.js +490 -203
- package/dist/index.mjs +490 -203
- package/package.json +1 -1
- package/src/strategies/universal-adapters/avnu-adapter.ts +1 -1
- package/src/strategies/universal-adapters/extended-adapter.ts +150 -72
- package/src/strategies/universal-adapters/vesu-multiply-adapter.ts +775 -395
- package/src/strategies/vesu-extended-strategy/utils/helper.ts +2 -4
- package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +9 -8
|
@@ -92419,8 +92419,7 @@ spurious results.`);
|
|
|
92419
92419
|
vesu_leverage: 0
|
|
92420
92420
|
};
|
|
92421
92421
|
}
|
|
92422
|
-
const
|
|
92423
|
-
const extendedExposureUSD = extendedBTCExposure.multipliedBy(collateralPrice);
|
|
92422
|
+
const extendedExposureUSD = extendedPosition.length > 0 ? new Web3Number(extendedPosition[0].value, WBTC_TOKEN_DECIMALS) : new Web3Number(0, WBTC_TOKEN_DECIMALS);
|
|
92424
92423
|
const vesuBTCExposureUSD = collateralUnits.multipliedBy(collateralPrice);
|
|
92425
92424
|
const numerator1 = vesu_leverage * amount + vesuBTCExposureUSD.toNumber();
|
|
92426
92425
|
const numerator2 = extendedExposureUSD.toNumber();
|
|
@@ -92638,21 +92637,35 @@ spurious results.`);
|
|
|
92638
92637
|
vaultAllocator: config3.vaultAllocator,
|
|
92639
92638
|
id: ""
|
|
92640
92639
|
});
|
|
92641
|
-
this.tokenMarketData = new TokenMarketData(
|
|
92640
|
+
this.tokenMarketData = new TokenMarketData(
|
|
92641
|
+
this.config.pricer,
|
|
92642
|
+
this.config.networkConfig
|
|
92643
|
+
);
|
|
92642
92644
|
}
|
|
92643
92645
|
async getAPY(supportedPosition) {
|
|
92644
92646
|
const CACHE_KEY = `apy_${this.config.poolId.address}_${supportedPosition.asset.symbol}`;
|
|
92645
92647
|
const cacheData = this.getCache(CACHE_KEY);
|
|
92646
|
-
console.log(
|
|
92648
|
+
console.log(
|
|
92649
|
+
`${_VesuMultiplyAdapter.name}::getAPY cacheData: ${JSON.stringify(
|
|
92650
|
+
cacheData
|
|
92651
|
+
)}`,
|
|
92652
|
+
this.vesuAdapter.config.poolId.shortString(),
|
|
92653
|
+
this.vesuAdapter.config.collateral.symbol,
|
|
92654
|
+
this.vesuAdapter.config.debt.symbol
|
|
92655
|
+
);
|
|
92647
92656
|
if (cacheData) {
|
|
92648
92657
|
return cacheData;
|
|
92649
92658
|
}
|
|
92650
92659
|
try {
|
|
92651
92660
|
const allVesuPools = await VesuAdapter.getVesuPools();
|
|
92652
92661
|
const asset = supportedPosition.asset;
|
|
92653
|
-
const pool = allVesuPools.pools.find(
|
|
92662
|
+
const pool = allVesuPools.pools.find(
|
|
92663
|
+
(p) => this.vesuAdapter.config.poolId.eqString(num_exports.getHexString(p.id))
|
|
92664
|
+
);
|
|
92654
92665
|
if (!pool) {
|
|
92655
|
-
logger2.warn(
|
|
92666
|
+
logger2.warn(
|
|
92667
|
+
`VesuMultiplyAdapter: Pool not found for token ${asset.symbol}`
|
|
92668
|
+
);
|
|
92656
92669
|
return {
|
|
92657
92670
|
apy: 0,
|
|
92658
92671
|
type: "base" /* BASE */
|
|
@@ -92662,7 +92675,9 @@ spurious results.`);
|
|
|
92662
92675
|
(a) => a.symbol.toLowerCase() === asset.symbol.toLowerCase()
|
|
92663
92676
|
)?.stats;
|
|
92664
92677
|
if (!assetStats) {
|
|
92665
|
-
logger2.warn(
|
|
92678
|
+
logger2.warn(
|
|
92679
|
+
`VesuMultiplyAdapter: Asset stats not found for token ${asset.symbol}`
|
|
92680
|
+
);
|
|
92666
92681
|
return {
|
|
92667
92682
|
apy: 0,
|
|
92668
92683
|
type: "base" /* BASE */
|
|
@@ -92673,7 +92688,9 @@ spurious results.`);
|
|
|
92673
92688
|
apy = Number(assetStats.borrowApr?.value || 0) / 1e18;
|
|
92674
92689
|
} else {
|
|
92675
92690
|
const isAssetBTC = asset.symbol.toLowerCase().includes("btc");
|
|
92676
|
-
const baseAPY = Number(
|
|
92691
|
+
const baseAPY = Number(
|
|
92692
|
+
isAssetBTC ? assetStats.btcFiSupplyApr?.value + assetStats.supplyApy?.value : assetStats.supplyApy?.value || 0
|
|
92693
|
+
) / 1e18;
|
|
92677
92694
|
const rewardAPY = Number(assetStats.defiSpringSupplyApr?.value || "0") / 1e18;
|
|
92678
92695
|
const isSupported = this.tokenMarketData.isAPYSupported(asset);
|
|
92679
92696
|
apy = baseAPY + rewardAPY;
|
|
@@ -92689,7 +92706,10 @@ spurious results.`);
|
|
|
92689
92706
|
this.setCache(CACHE_KEY, result2, 3e5);
|
|
92690
92707
|
return result2;
|
|
92691
92708
|
} catch (error2) {
|
|
92692
|
-
logger2.error(
|
|
92709
|
+
logger2.error(
|
|
92710
|
+
`VesuMultiplyAdapter: Error getting APY for ${supportedPosition.asset.symbol}:`,
|
|
92711
|
+
error2
|
|
92712
|
+
);
|
|
92693
92713
|
throw error2;
|
|
92694
92714
|
}
|
|
92695
92715
|
}
|
|
@@ -92702,12 +92722,16 @@ spurious results.`);
|
|
|
92702
92722
|
try {
|
|
92703
92723
|
this.vesuAdapter.networkConfig = this.config.networkConfig;
|
|
92704
92724
|
this.vesuAdapter.pricer = this.config.pricer;
|
|
92705
|
-
const positions = await this.vesuAdapter.getPositions(
|
|
92725
|
+
const positions = await this.vesuAdapter.getPositions(
|
|
92726
|
+
this.config.networkConfig
|
|
92727
|
+
);
|
|
92706
92728
|
let position = positions.find(
|
|
92707
92729
|
(p) => p.token.address.eq(supportedPosition.asset.address)
|
|
92708
92730
|
);
|
|
92709
92731
|
if (!position) {
|
|
92710
|
-
logger2.warn(
|
|
92732
|
+
logger2.warn(
|
|
92733
|
+
`VesuMultiplyAdapter: Position not found for token ${supportedPosition.asset.symbol}`
|
|
92734
|
+
);
|
|
92711
92735
|
return {
|
|
92712
92736
|
amount: new Web3Number("0", supportedPosition.asset.decimals),
|
|
92713
92737
|
remarks: "Position not found"
|
|
@@ -92720,12 +92744,18 @@ spurious results.`);
|
|
|
92720
92744
|
this.setCache(CACHE_KEY, position, 6e4);
|
|
92721
92745
|
return position;
|
|
92722
92746
|
} catch (error2) {
|
|
92723
|
-
logger2.error(
|
|
92747
|
+
logger2.error(
|
|
92748
|
+
`VesuMultiplyAdapter: Error getting position for ${supportedPosition.asset.symbol}:`,
|
|
92749
|
+
error2
|
|
92750
|
+
);
|
|
92724
92751
|
throw error2;
|
|
92725
92752
|
}
|
|
92726
92753
|
}
|
|
92727
92754
|
async maxBorrowableAPY() {
|
|
92728
|
-
const collateralAPY = await this.getAPY({
|
|
92755
|
+
const collateralAPY = await this.getAPY({
|
|
92756
|
+
asset: this.config.collateral,
|
|
92757
|
+
isDebt: false
|
|
92758
|
+
});
|
|
92729
92759
|
const apy = collateralAPY.apy * 0.8;
|
|
92730
92760
|
return apy;
|
|
92731
92761
|
}
|
|
@@ -92735,9 +92765,15 @@ spurious results.`);
|
|
|
92735
92765
|
try {
|
|
92736
92766
|
this.vesuAdapter.networkConfig = this.config.networkConfig;
|
|
92737
92767
|
this.vesuAdapter.pricer = this.config.pricer;
|
|
92738
|
-
const positions = await this.vesuAdapter.getPositions(
|
|
92739
|
-
|
|
92740
|
-
|
|
92768
|
+
const positions = await this.vesuAdapter.getPositions(
|
|
92769
|
+
this.config.networkConfig
|
|
92770
|
+
);
|
|
92771
|
+
const collateralPosition = positions.find(
|
|
92772
|
+
(p) => p.token.address.eq(collateral.address)
|
|
92773
|
+
);
|
|
92774
|
+
const debtPosition = positions.find(
|
|
92775
|
+
(p) => p.token.address.eq(debt.address)
|
|
92776
|
+
);
|
|
92741
92777
|
if (!collateralPosition || !debtPosition) {
|
|
92742
92778
|
throw new Error("Could not find current positions");
|
|
92743
92779
|
}
|
|
@@ -92747,13 +92783,23 @@ spurious results.`);
|
|
|
92747
92783
|
debt,
|
|
92748
92784
|
maxBorrowableAPY
|
|
92749
92785
|
);
|
|
92750
|
-
logger2.verbose(
|
|
92751
|
-
|
|
92786
|
+
logger2.verbose(
|
|
92787
|
+
`VesuMultiplyAdapter: Max borrowable: ${maxBorrowable.toNumber()}`
|
|
92788
|
+
);
|
|
92789
|
+
const debtCap = await this.vesuAdapter.getDebtCap(
|
|
92790
|
+
this.config.networkConfig
|
|
92791
|
+
);
|
|
92752
92792
|
logger2.verbose(`VesuMultiplyAdapter: Debt cap: ${debtCap.toNumber()}`);
|
|
92753
92793
|
const actualMaxBorrowable = maxBorrowable.minimum(debtCap);
|
|
92754
|
-
logger2.verbose(
|
|
92755
|
-
|
|
92756
|
-
|
|
92794
|
+
logger2.verbose(
|
|
92795
|
+
`VesuMultiplyAdapter: Actual max borrowable: ${actualMaxBorrowable.toNumber()}`
|
|
92796
|
+
);
|
|
92797
|
+
const maxLTV = await this.vesuAdapter.getLTVConfig(
|
|
92798
|
+
this.config.networkConfig
|
|
92799
|
+
);
|
|
92800
|
+
const collateralPrice = await this.config.pricer.getPrice(
|
|
92801
|
+
collateral.symbol
|
|
92802
|
+
);
|
|
92757
92803
|
if (collateralPrice.price === 0) {
|
|
92758
92804
|
throw new Error("Collateral price is 0");
|
|
92759
92805
|
}
|
|
@@ -92771,14 +92817,25 @@ spurious results.`);
|
|
|
92771
92817
|
);
|
|
92772
92818
|
const maxDepositAmount = amount ? amount.minimum(maxCollateralFromDebt) : maxCollateralFromDebt;
|
|
92773
92819
|
const usdValue = await this.getUSDValue(collateral, maxDepositAmount);
|
|
92774
|
-
logger2.verbose(
|
|
92775
|
-
|
|
92776
|
-
|
|
92820
|
+
logger2.verbose(
|
|
92821
|
+
`VesuMultiplyAdapter: Max deposit::USD value: ${usdValue}, amount: ${maxDepositAmount.toNumber()}`
|
|
92822
|
+
);
|
|
92823
|
+
const apys = await Promise.all([
|
|
92824
|
+
this.getAPY({ asset: collateral, isDebt: false }),
|
|
92825
|
+
this.getAPY({ asset: debt, isDebt: true })
|
|
92826
|
+
]);
|
|
92827
|
+
logger2.verbose(
|
|
92828
|
+
`VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`
|
|
92829
|
+
);
|
|
92777
92830
|
const borrowAmountUSD = actualMaxBorrowable.multipliedBy(debtPrice.price);
|
|
92778
|
-
logger2.verbose(
|
|
92831
|
+
logger2.verbose(
|
|
92832
|
+
`VesuMultiplyAdapter: Borrow amount: ${actualMaxBorrowable.toNumber()}, borrow amount USD: ${borrowAmountUSD.toNumber()}`
|
|
92833
|
+
);
|
|
92779
92834
|
const netCollateralUSD = usdValue + borrowAmountUSD.toNumber();
|
|
92780
92835
|
const netAPY = (apys[0].apy * netCollateralUSD + apys[1].apy * borrowAmountUSD.toNumber()) / usdValue;
|
|
92781
|
-
logger2.verbose(
|
|
92836
|
+
logger2.verbose(
|
|
92837
|
+
`VesuMultiplyAdapter: Max deposit amount: ${maxDepositAmount.toNumber()}, netAPY: ${netAPY}`
|
|
92838
|
+
);
|
|
92782
92839
|
return {
|
|
92783
92840
|
tokenInfo: collateral,
|
|
92784
92841
|
amount: maxDepositAmount,
|
|
@@ -92791,7 +92848,10 @@ spurious results.`);
|
|
|
92791
92848
|
protocol: this.protocol
|
|
92792
92849
|
};
|
|
92793
92850
|
} catch (error2) {
|
|
92794
|
-
logger2.error(
|
|
92851
|
+
logger2.error(
|
|
92852
|
+
`VesuMultiplyAdapter: Error calculating max deposit:`,
|
|
92853
|
+
error2
|
|
92854
|
+
);
|
|
92795
92855
|
throw error2;
|
|
92796
92856
|
}
|
|
92797
92857
|
}
|
|
@@ -92801,9 +92861,15 @@ spurious results.`);
|
|
|
92801
92861
|
try {
|
|
92802
92862
|
this.vesuAdapter.networkConfig = this.config.networkConfig;
|
|
92803
92863
|
this.vesuAdapter.pricer = this.config.pricer;
|
|
92804
|
-
const positions = await this.vesuAdapter.getPositions(
|
|
92805
|
-
|
|
92806
|
-
|
|
92864
|
+
const positions = await this.vesuAdapter.getPositions(
|
|
92865
|
+
this.config.networkConfig
|
|
92866
|
+
);
|
|
92867
|
+
const collateralPosition = positions.find(
|
|
92868
|
+
(p) => p.token.address.eq(collateral.address)
|
|
92869
|
+
);
|
|
92870
|
+
const debtPosition = positions.find(
|
|
92871
|
+
(p) => p.token.address.eq(this.config.debt.address)
|
|
92872
|
+
);
|
|
92807
92873
|
if (!collateralPosition || !debtPosition) {
|
|
92808
92874
|
throw new Error("Could not find current positions");
|
|
92809
92875
|
}
|
|
@@ -92813,11 +92879,20 @@ spurious results.`);
|
|
|
92813
92879
|
const result2 = maxWithdrawable.greaterThan(0) ? maxWithdrawable : new Web3Number("0", collateral.decimals);
|
|
92814
92880
|
const usdValue = await this.getUSDValue(collateral, result2);
|
|
92815
92881
|
const debtUSD = debtPosition.usdValue;
|
|
92816
|
-
logger2.verbose(
|
|
92817
|
-
|
|
92818
|
-
|
|
92882
|
+
logger2.verbose(
|
|
92883
|
+
`VesuMultiplyAdapter: Debt USD: ${debtUSD}, collateral USD: ${usdValue}`
|
|
92884
|
+
);
|
|
92885
|
+
const apys = await Promise.all([
|
|
92886
|
+
this.getAPY({ asset: collateral, isDebt: false }),
|
|
92887
|
+
this.getAPY({ asset: debt, isDebt: true })
|
|
92888
|
+
]);
|
|
92889
|
+
logger2.verbose(
|
|
92890
|
+
`VesuMultiplyAdapter: Apys: ${apys[0].apy}, ${apys[1].apy}`
|
|
92891
|
+
);
|
|
92819
92892
|
const netAPY = usdValue - debtUSD > 0 ? (apys[0].apy * usdValue + apys[1].apy * debtUSD) / (usdValue - debtUSD) : 0;
|
|
92820
|
-
logger2.verbose(
|
|
92893
|
+
logger2.verbose(
|
|
92894
|
+
`VesuMultiplyAdapter: Max withdraw amount: ${result2.toNumber()}, netAPY: ${netAPY}`
|
|
92895
|
+
);
|
|
92821
92896
|
return {
|
|
92822
92897
|
tokenInfo: collateral,
|
|
92823
92898
|
amount: result2,
|
|
@@ -92830,14 +92905,19 @@ spurious results.`);
|
|
|
92830
92905
|
protocol: this.protocol
|
|
92831
92906
|
};
|
|
92832
92907
|
} catch (error2) {
|
|
92833
|
-
logger2.error(
|
|
92908
|
+
logger2.error(
|
|
92909
|
+
`VesuMultiplyAdapter: Error calculating max withdraw:`,
|
|
92910
|
+
error2
|
|
92911
|
+
);
|
|
92834
92912
|
throw error2;
|
|
92835
92913
|
}
|
|
92836
92914
|
}
|
|
92837
92915
|
_getDepositLeaf() {
|
|
92838
92916
|
const collateral = this.config.collateral;
|
|
92839
92917
|
const debt = this.config.debt;
|
|
92840
|
-
const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
|
|
92918
|
+
const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
|
|
92919
|
+
this.config.poolId
|
|
92920
|
+
);
|
|
92841
92921
|
const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
|
|
92842
92922
|
return [
|
|
92843
92923
|
// Approval step for collateral
|
|
@@ -92901,7 +92981,9 @@ spurious results.`);
|
|
|
92901
92981
|
];
|
|
92902
92982
|
}
|
|
92903
92983
|
_getWithdrawLeaf() {
|
|
92904
|
-
const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
|
|
92984
|
+
const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
|
|
92985
|
+
this.config.poolId
|
|
92986
|
+
);
|
|
92905
92987
|
const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
|
|
92906
92988
|
const collateral = this.config.collateral;
|
|
92907
92989
|
const debt = this.config.debt;
|
|
@@ -92958,33 +93040,51 @@ spurious results.`);
|
|
|
92958
93040
|
const leafConfigs = this._getDepositLeaf();
|
|
92959
93041
|
const leaves = leafConfigs.map((config3) => {
|
|
92960
93042
|
const { target, method, packedArguments, sanitizer, id } = config3;
|
|
92961
|
-
const leaf = this.constructSimpleLeafData(
|
|
92962
|
-
|
|
92963
|
-
|
|
92964
|
-
|
|
92965
|
-
|
|
92966
|
-
|
|
93043
|
+
const leaf = this.constructSimpleLeafData(
|
|
93044
|
+
{
|
|
93045
|
+
id,
|
|
93046
|
+
target,
|
|
93047
|
+
method,
|
|
93048
|
+
packedArguments
|
|
93049
|
+
},
|
|
93050
|
+
sanitizer
|
|
93051
|
+
);
|
|
92967
93052
|
return leaf;
|
|
92968
93053
|
});
|
|
92969
|
-
return {
|
|
93054
|
+
return {
|
|
93055
|
+
leaves,
|
|
93056
|
+
callConstructor: this.getDepositCall.bind(
|
|
93057
|
+
this
|
|
93058
|
+
)
|
|
93059
|
+
};
|
|
92970
93060
|
}
|
|
92971
93061
|
getWithdrawAdapter() {
|
|
92972
93062
|
const leafConfigs = this._getWithdrawLeaf();
|
|
92973
93063
|
const leaves = leafConfigs.map((config3) => {
|
|
92974
93064
|
const { target, method, packedArguments, sanitizer, id } = config3;
|
|
92975
|
-
const leaf = this.constructSimpleLeafData(
|
|
92976
|
-
|
|
92977
|
-
|
|
92978
|
-
|
|
92979
|
-
|
|
92980
|
-
|
|
93065
|
+
const leaf = this.constructSimpleLeafData(
|
|
93066
|
+
{
|
|
93067
|
+
id,
|
|
93068
|
+
target,
|
|
93069
|
+
method,
|
|
93070
|
+
packedArguments
|
|
93071
|
+
},
|
|
93072
|
+
sanitizer
|
|
93073
|
+
);
|
|
92981
93074
|
return leaf;
|
|
92982
93075
|
});
|
|
92983
|
-
return {
|
|
93076
|
+
return {
|
|
93077
|
+
leaves,
|
|
93078
|
+
callConstructor: this.getWithdrawCall.bind(
|
|
93079
|
+
this
|
|
93080
|
+
)
|
|
93081
|
+
};
|
|
92984
93082
|
}
|
|
92985
93083
|
async getDepositCall(params) {
|
|
92986
93084
|
const collateral = this.config.collateral;
|
|
92987
|
-
const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
|
|
93085
|
+
const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
|
|
93086
|
+
this.config.poolId
|
|
93087
|
+
);
|
|
92988
93088
|
const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
|
|
92989
93089
|
const uint256MarginAmount = uint256_exports.bnToUint256(params.amount.toWei());
|
|
92990
93090
|
return [
|
|
@@ -93056,7 +93156,9 @@ spurious results.`);
|
|
|
93056
93156
|
];
|
|
93057
93157
|
}
|
|
93058
93158
|
async getWithdrawCall(params) {
|
|
93059
|
-
const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
|
|
93159
|
+
const { addr: vesuSingleton, isV2 } = getVesuSingletonAddress(
|
|
93160
|
+
this.config.poolId
|
|
93161
|
+
);
|
|
93060
93162
|
const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
|
|
93061
93163
|
return [
|
|
93062
93164
|
// Switch delegation on
|
|
@@ -93111,7 +93213,11 @@ spurious results.`);
|
|
|
93111
93213
|
];
|
|
93112
93214
|
}
|
|
93113
93215
|
async getMultiplyCallCalldata(params, isDeposit) {
|
|
93114
|
-
logger2.verbose(
|
|
93216
|
+
logger2.verbose(
|
|
93217
|
+
`${_VesuMultiplyAdapter.name}::getMultiplyCallCalldata params: ${JSON.stringify(
|
|
93218
|
+
params
|
|
93219
|
+
)}, isDeposit: ${isDeposit}, collateral: ${this.config.collateral.symbol}, debt: ${this.config.debt.symbol}`
|
|
93220
|
+
);
|
|
93115
93221
|
const { isV2 } = getVesuSingletonAddress(this.config.poolId);
|
|
93116
93222
|
const vesuMultiply = isV2 ? this.vesuAdapter.VESU_MULTIPLY : this.vesuAdapter.VESU_MULTIPLY_V1;
|
|
93117
93223
|
const multiplyContract = new Contract({
|
|
@@ -93121,42 +93227,83 @@ spurious results.`);
|
|
|
93121
93227
|
});
|
|
93122
93228
|
let leverSwap = [];
|
|
93123
93229
|
let leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
|
|
93124
|
-
const existingPositions = await this.vesuAdapter.getPositions(
|
|
93125
|
-
|
|
93230
|
+
const existingPositions = await this.vesuAdapter.getPositions(
|
|
93231
|
+
this.config.networkConfig
|
|
93232
|
+
);
|
|
93233
|
+
const collateralisation = await this.vesuAdapter.getCollateralization(
|
|
93234
|
+
this.config.networkConfig
|
|
93235
|
+
);
|
|
93126
93236
|
const existingCollateralInfo = existingPositions[0];
|
|
93127
93237
|
const existingDebtInfo = existingPositions[1];
|
|
93128
93238
|
const isDexPriceRequired = existingDebtInfo.token.symbol !== "USDC";
|
|
93129
|
-
logger2.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(
|
|
93130
|
-
|
|
93239
|
+
logger2.debug(`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(
|
|
93240
|
+
existingCollateralInfo
|
|
93241
|
+
)},
|
|
93242
|
+
existingDebtInfo: ${JSON.stringify(
|
|
93243
|
+
existingDebtInfo
|
|
93244
|
+
)}, collateralisation: ${JSON.stringify(collateralisation)}`);
|
|
93131
93245
|
const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : (await this.config.pricer.getPrice(this.config.collateral.symbol)).price;
|
|
93132
93246
|
const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : (await this.config.pricer.getPrice(this.config.debt.symbol)).price;
|
|
93133
|
-
logger2.debug(
|
|
93134
|
-
|
|
93135
|
-
|
|
93136
|
-
const
|
|
93137
|
-
|
|
93247
|
+
logger2.debug(
|
|
93248
|
+
`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`
|
|
93249
|
+
);
|
|
93250
|
+
const legLTV = await this.vesuAdapter.getLTVConfig(
|
|
93251
|
+
this.config.networkConfig
|
|
93252
|
+
);
|
|
93253
|
+
const ekuboQuoter = new EkuboQuoter(
|
|
93254
|
+
this.config.networkConfig,
|
|
93255
|
+
this.config.pricer
|
|
93256
|
+
);
|
|
93257
|
+
const dexPrice = isDexPriceRequired ? await ekuboQuoter.getDexPrice(
|
|
93258
|
+
this.config.collateral,
|
|
93259
|
+
this.config.debt,
|
|
93260
|
+
this.config.quoteAmountToFetchPrice
|
|
93261
|
+
) : 1;
|
|
93262
|
+
logger2.verbose(
|
|
93263
|
+
`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall dexPrice: ${dexPrice}, ltv: ${legLTV}`
|
|
93264
|
+
);
|
|
93138
93265
|
const addedCollateral = params.amount.multipliedBy(isDeposit ? 1 : -1);
|
|
93139
|
-
logger2.verbose(
|
|
93266
|
+
logger2.verbose(
|
|
93267
|
+
`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall addedCollateral: ${addedCollateral}`
|
|
93268
|
+
);
|
|
93140
93269
|
const numeratorPart1 = existingCollateralInfo.amount.plus(addedCollateral).multipliedBy(collateralPrice).multipliedBy(legLTV);
|
|
93141
|
-
logger2.verbose(
|
|
93270
|
+
logger2.verbose(
|
|
93271
|
+
`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}`
|
|
93272
|
+
);
|
|
93142
93273
|
const numeratorPart2 = existingDebtInfo.amount.multipliedBy(debtPrice).multipliedBy(this.config.targetHealthFactor);
|
|
93143
|
-
logger2.verbose(
|
|
93274
|
+
logger2.verbose(
|
|
93275
|
+
`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart2: ${numeratorPart2}`
|
|
93276
|
+
);
|
|
93144
93277
|
const denominatorPart = this.config.targetHealthFactor - legLTV / dexPrice;
|
|
93145
|
-
logger2.verbose(
|
|
93278
|
+
logger2.verbose(
|
|
93279
|
+
`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall denominatorPart: ${denominatorPart}`
|
|
93280
|
+
);
|
|
93146
93281
|
const x_debt_usd = numeratorPart1.minus(numeratorPart2).dividedBy(denominatorPart);
|
|
93147
|
-
logger2.verbose(
|
|
93148
|
-
|
|
93149
|
-
|
|
93282
|
+
logger2.verbose(
|
|
93283
|
+
`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall x_debt_usd: ${x_debt_usd}`
|
|
93284
|
+
);
|
|
93285
|
+
logger2.debug(
|
|
93286
|
+
`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall numeratorPart1: ${numeratorPart1}, numeratorPart2: ${numeratorPart2}, denominatorPart: ${denominatorPart}`
|
|
93287
|
+
);
|
|
93288
|
+
let debtAmount = new Web3Number(
|
|
93289
|
+
x_debt_usd.dividedBy(debtPrice).toFixed(this.config.debt.decimals),
|
|
93290
|
+
this.config.debt.decimals
|
|
93291
|
+
);
|
|
93150
93292
|
const marginAmount = addedCollateral;
|
|
93151
93293
|
const collateralToken = this.config.collateral;
|
|
93152
93294
|
const debtToken = this.config.debt;
|
|
93153
|
-
const debtAmountInCollateralUnits = new Web3Number(
|
|
93295
|
+
const debtAmountInCollateralUnits = new Web3Number(
|
|
93296
|
+
debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).multipliedBy(10 ** collateralToken.decimals).toFixed(0),
|
|
93297
|
+
collateralToken.decimals
|
|
93298
|
+
);
|
|
93154
93299
|
const isIncrease = debtAmount.greaterThanOrEqualTo(0);
|
|
93155
93300
|
if (isIncrease && debtAmount.lessThan(0)) {
|
|
93156
93301
|
} else if (!isIncrease && debtAmount.greaterThan(0)) {
|
|
93157
93302
|
debtAmount = Web3Number.fromWei(0, this.config.debt.decimals);
|
|
93158
93303
|
}
|
|
93159
|
-
logger2.verbose(
|
|
93304
|
+
logger2.verbose(
|
|
93305
|
+
`${_VesuMultiplyAdapter.name}::getVesuMultiplyCall debtAmount: ${debtAmount}, marginAmount: ${marginAmount}`
|
|
93306
|
+
);
|
|
93160
93307
|
if (!debtAmount.isZero()) {
|
|
93161
93308
|
try {
|
|
93162
93309
|
const swapQuote = await ekuboQuoter.getQuote(
|
|
@@ -93166,26 +93313,49 @@ spurious results.`);
|
|
|
93166
93313
|
// negative for exact amount out
|
|
93167
93314
|
);
|
|
93168
93315
|
if (swapQuote.price_impact < 0.01) {
|
|
93169
|
-
leverSwap = ekuboQuoter.getVesuMultiplyQuote(
|
|
93316
|
+
leverSwap = debtAmount.isNegative() ? ekuboQuoter.getVesuMultiplyQuote(
|
|
93317
|
+
swapQuote,
|
|
93318
|
+
collateralToken,
|
|
93319
|
+
debtToken
|
|
93320
|
+
) : ekuboQuoter.getVesuMultiplyQuote(
|
|
93321
|
+
swapQuote,
|
|
93322
|
+
debtToken,
|
|
93323
|
+
collateralToken
|
|
93324
|
+
);
|
|
93170
93325
|
const MAX_SLIPPAGE = 2e-3;
|
|
93171
93326
|
if (debtAmount.greaterThan(0)) {
|
|
93172
93327
|
leverSwapLimitAmount = debtAmount.multipliedBy(1 + MAX_SLIPPAGE);
|
|
93173
93328
|
} else if (debtAmount.lessThan(0)) {
|
|
93174
93329
|
leverSwapLimitAmount = debtAmount.abs().multipliedBy(1 - MAX_SLIPPAGE);
|
|
93175
93330
|
} else {
|
|
93176
|
-
leverSwapLimitAmount = Web3Number.fromWei(
|
|
93331
|
+
leverSwapLimitAmount = Web3Number.fromWei(
|
|
93332
|
+
0,
|
|
93333
|
+
this.config.debt.decimals
|
|
93334
|
+
);
|
|
93177
93335
|
}
|
|
93178
93336
|
await new Promise((resolve) => setTimeout(resolve, 1e4));
|
|
93179
93337
|
} else {
|
|
93180
|
-
throw new Error(
|
|
93338
|
+
throw new Error(
|
|
93339
|
+
`VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`
|
|
93340
|
+
);
|
|
93181
93341
|
}
|
|
93182
93342
|
} catch (error2) {
|
|
93183
|
-
throw new Error(
|
|
93343
|
+
throw new Error(
|
|
93344
|
+
`VesuMultiplyAdapter: Failed to get swap quote: ${error2}`
|
|
93345
|
+
);
|
|
93184
93346
|
}
|
|
93185
93347
|
}
|
|
93186
|
-
const multiplyParams = await this.getLeverParams(
|
|
93348
|
+
const multiplyParams = await this.getLeverParams(
|
|
93349
|
+
isIncrease,
|
|
93350
|
+
params,
|
|
93351
|
+
leverSwap,
|
|
93352
|
+
leverSwapLimitAmount
|
|
93353
|
+
);
|
|
93187
93354
|
const call = multiplyContract.populate("modify_lever", {
|
|
93188
|
-
modify_lever_params: this.formatMultiplyParams(
|
|
93355
|
+
modify_lever_params: this.formatMultiplyParams(
|
|
93356
|
+
isIncrease,
|
|
93357
|
+
multiplyParams
|
|
93358
|
+
)
|
|
93189
93359
|
});
|
|
93190
93360
|
return call.calldata;
|
|
93191
93361
|
}
|
|
@@ -93199,7 +93369,10 @@ spurious results.`);
|
|
|
93199
93369
|
add_margin: params.amount,
|
|
93200
93370
|
// multiplied by collateral decimals in format
|
|
93201
93371
|
margin_swap: [],
|
|
93202
|
-
margin_swap_limit_amount: Web3Number.fromWei(
|
|
93372
|
+
margin_swap_limit_amount: Web3Number.fromWei(
|
|
93373
|
+
0,
|
|
93374
|
+
this.config.collateral.decimals
|
|
93375
|
+
),
|
|
93203
93376
|
lever_swap: leverSwap,
|
|
93204
93377
|
lever_swap_limit_amount: leverSwapLimitAmount
|
|
93205
93378
|
} : {
|
|
@@ -93213,7 +93386,10 @@ spurious results.`);
|
|
|
93213
93386
|
lever_swap_limit_amount: leverSwapLimitAmount,
|
|
93214
93387
|
lever_swap_weights: [],
|
|
93215
93388
|
withdraw_swap: [],
|
|
93216
|
-
withdraw_swap_limit_amount: Web3Number.fromWei(
|
|
93389
|
+
withdraw_swap_limit_amount: Web3Number.fromWei(
|
|
93390
|
+
0,
|
|
93391
|
+
this.config.collateral.decimals
|
|
93392
|
+
),
|
|
93217
93393
|
withdraw_swap_weights: [],
|
|
93218
93394
|
close_position: false
|
|
93219
93395
|
};
|
|
@@ -93229,12 +93405,16 @@ spurious results.`);
|
|
|
93229
93405
|
});
|
|
93230
93406
|
let leverSwap = [];
|
|
93231
93407
|
let leverSwapLimitAmount = Web3Number.fromWei(0, this.config.debt.decimals);
|
|
93232
|
-
const existingPositions = await this.vesuAdapter.getPositions(
|
|
93408
|
+
const existingPositions = await this.vesuAdapter.getPositions(
|
|
93409
|
+
this.config.networkConfig
|
|
93410
|
+
);
|
|
93233
93411
|
const existingCollateralInfo = existingPositions[0];
|
|
93234
93412
|
const existingDebtInfo = existingPositions[1];
|
|
93235
93413
|
const collateralToken = this.config.collateral;
|
|
93236
93414
|
const debtToken = this.config.debt;
|
|
93237
|
-
const collateralPrice = await this.config.pricer.getPrice(
|
|
93415
|
+
const collateralPrice = await this.config.pricer.getPrice(
|
|
93416
|
+
collateralToken.symbol
|
|
93417
|
+
);
|
|
93238
93418
|
const debtPrice = await this.config.pricer.getPrice(debtToken.symbol);
|
|
93239
93419
|
const { deltadebtAmountUnits: debtAmountToRepay } = calculateDebtReductionAmountForWithdrawal(
|
|
93240
93420
|
existingDebtInfo.amount,
|
|
@@ -93248,8 +93428,14 @@ spurious results.`);
|
|
|
93248
93428
|
if (!debtAmountToRepay) {
|
|
93249
93429
|
throw new Error("error calculating debt amount to repay");
|
|
93250
93430
|
}
|
|
93251
|
-
const ekuboQuoter = new EkuboQuoter(
|
|
93252
|
-
|
|
93431
|
+
const ekuboQuoter = new EkuboQuoter(
|
|
93432
|
+
this.config.networkConfig,
|
|
93433
|
+
this.config.pricer
|
|
93434
|
+
);
|
|
93435
|
+
const debtInDebtUnits = new Web3Number(
|
|
93436
|
+
debtAmountToRepay,
|
|
93437
|
+
debtToken.decimals
|
|
93438
|
+
).dividedBy(debtPrice.price).multipliedBy(10 ** debtToken.decimals);
|
|
93253
93439
|
const swapQuote = await ekuboQuoter.getQuote(
|
|
93254
93440
|
debtToken.address.address,
|
|
93255
93441
|
collateralToken.address.address,
|
|
@@ -93257,12 +93443,23 @@ spurious results.`);
|
|
|
93257
93443
|
);
|
|
93258
93444
|
const MAX_SLIPPAGE = 2e-3;
|
|
93259
93445
|
if (swapQuote.price_impact < 25e-4) {
|
|
93260
|
-
leverSwap = ekuboQuoter.getVesuMultiplyQuote(
|
|
93446
|
+
leverSwap = ekuboQuoter.getVesuMultiplyQuote(
|
|
93447
|
+
swapQuote,
|
|
93448
|
+
collateralToken,
|
|
93449
|
+
debtToken
|
|
93450
|
+
);
|
|
93261
93451
|
} else {
|
|
93262
|
-
logger2.error(
|
|
93452
|
+
logger2.error(
|
|
93453
|
+
`VesuMultiplyAdapter: Price impact too high (${swapQuote.price_impact}), skipping swap`
|
|
93454
|
+
);
|
|
93263
93455
|
}
|
|
93264
93456
|
leverSwapLimitAmount = new Web3Number(debtAmountToRepay, debtToken.decimals).abs().multipliedBy(1 + MAX_SLIPPAGE);
|
|
93265
|
-
const multiplyParams = await this.getLeverParams(
|
|
93457
|
+
const multiplyParams = await this.getLeverParams(
|
|
93458
|
+
false,
|
|
93459
|
+
params,
|
|
93460
|
+
leverSwap,
|
|
93461
|
+
leverSwapLimitAmount
|
|
93462
|
+
);
|
|
93266
93463
|
const call = multiplyContract.populate("modify_lever", {
|
|
93267
93464
|
modify_lever_params: this.formatMultiplyParams(false, multiplyParams)
|
|
93268
93465
|
});
|
|
@@ -93272,100 +93469,132 @@ spurious results.`);
|
|
|
93272
93469
|
if (isIncrease) {
|
|
93273
93470
|
const _params2 = params;
|
|
93274
93471
|
return {
|
|
93275
|
-
action: new CairoCustomEnum({
|
|
93276
|
-
|
|
93277
|
-
|
|
93278
|
-
|
|
93279
|
-
|
|
93280
|
-
|
|
93281
|
-
|
|
93472
|
+
action: new CairoCustomEnum({
|
|
93473
|
+
IncreaseLever: {
|
|
93474
|
+
pool_id: _params2.pool_id.toBigInt(),
|
|
93475
|
+
collateral_asset: _params2.collateral_asset.toBigInt(),
|
|
93476
|
+
debt_asset: _params2.debt_asset.toBigInt(),
|
|
93477
|
+
user: _params2.user.toBigInt(),
|
|
93478
|
+
add_margin: BigInt(_params2.add_margin.toWei()),
|
|
93479
|
+
margin_swap: _params2.margin_swap.map((swap) => ({
|
|
93480
|
+
route: swap.route.map((route) => ({
|
|
93481
|
+
pool_key: {
|
|
93482
|
+
token0: route.pool_key.token0.toBigInt(),
|
|
93483
|
+
token1: route.pool_key.token1.toBigInt(),
|
|
93484
|
+
fee: route.pool_key.fee,
|
|
93485
|
+
tick_spacing: route.pool_key.tick_spacing,
|
|
93486
|
+
extension: BigInt(
|
|
93487
|
+
num_exports.hexToDecimalString(route.pool_key.extension)
|
|
93488
|
+
)
|
|
93489
|
+
},
|
|
93490
|
+
sqrt_ratio_limit: uint256_exports.bnToUint256(
|
|
93491
|
+
route.sqrt_ratio_limit.toWei()
|
|
93492
|
+
),
|
|
93493
|
+
skip_ahead: BigInt(100)
|
|
93494
|
+
})),
|
|
93495
|
+
token_amount: {
|
|
93496
|
+
token: swap.token_amount.token.toBigInt(),
|
|
93497
|
+
amount: swap.token_amount.amount.toI129()
|
|
93498
|
+
}
|
|
93499
|
+
})),
|
|
93500
|
+
margin_swap_limit_amount: BigInt(
|
|
93501
|
+
_params2.margin_swap_limit_amount.toWei()
|
|
93502
|
+
),
|
|
93503
|
+
lever_swap: _params2.lever_swap.map((swap) => ({
|
|
93504
|
+
route: swap.route.map((route) => ({
|
|
93505
|
+
pool_key: {
|
|
93506
|
+
token0: route.pool_key.token0.toBigInt(),
|
|
93507
|
+
token1: route.pool_key.token1.toBigInt(),
|
|
93508
|
+
fee: route.pool_key.fee,
|
|
93509
|
+
tick_spacing: route.pool_key.tick_spacing,
|
|
93510
|
+
extension: BigInt(
|
|
93511
|
+
num_exports.hexToDecimalString(route.pool_key.extension)
|
|
93512
|
+
)
|
|
93513
|
+
},
|
|
93514
|
+
sqrt_ratio_limit: uint256_exports.bnToUint256(
|
|
93515
|
+
route.sqrt_ratio_limit.toWei()
|
|
93516
|
+
),
|
|
93517
|
+
skip_ahead: BigInt(0)
|
|
93518
|
+
})),
|
|
93519
|
+
token_amount: {
|
|
93520
|
+
token: swap.token_amount.token.toBigInt(),
|
|
93521
|
+
amount: swap.token_amount.amount.toI129()
|
|
93522
|
+
}
|
|
93523
|
+
})),
|
|
93524
|
+
lever_swap_limit_amount: BigInt(
|
|
93525
|
+
_params2.lever_swap_limit_amount.toWei()
|
|
93526
|
+
)
|
|
93527
|
+
}
|
|
93528
|
+
})
|
|
93529
|
+
};
|
|
93530
|
+
}
|
|
93531
|
+
const _params = params;
|
|
93532
|
+
return {
|
|
93533
|
+
action: new CairoCustomEnum({
|
|
93534
|
+
DecreaseLever: {
|
|
93535
|
+
pool_id: _params.pool_id.toBigInt(),
|
|
93536
|
+
collateral_asset: _params.collateral_asset.toBigInt(),
|
|
93537
|
+
debt_asset: _params.debt_asset.toBigInt(),
|
|
93538
|
+
user: _params.user.toBigInt(),
|
|
93539
|
+
sub_margin: BigInt(_params.sub_margin.toWei()),
|
|
93540
|
+
recipient: _params.recipient.toBigInt(),
|
|
93541
|
+
lever_swap: _params.lever_swap.map((swap) => ({
|
|
93282
93542
|
route: swap.route.map((route) => ({
|
|
93283
93543
|
pool_key: {
|
|
93284
93544
|
token0: route.pool_key.token0.toBigInt(),
|
|
93285
93545
|
token1: route.pool_key.token1.toBigInt(),
|
|
93286
93546
|
fee: route.pool_key.fee,
|
|
93287
93547
|
tick_spacing: route.pool_key.tick_spacing,
|
|
93288
|
-
extension:
|
|
93548
|
+
extension: ContractAddr.from(
|
|
93549
|
+
route.pool_key.extension
|
|
93550
|
+
).toBigInt()
|
|
93289
93551
|
},
|
|
93290
|
-
sqrt_ratio_limit: uint256_exports.bnToUint256(
|
|
93291
|
-
|
|
93552
|
+
sqrt_ratio_limit: uint256_exports.bnToUint256(
|
|
93553
|
+
route.sqrt_ratio_limit.toWei()
|
|
93554
|
+
),
|
|
93555
|
+
skip_ahead: BigInt(route.skip_ahead.toWei())
|
|
93292
93556
|
})),
|
|
93293
93557
|
token_amount: {
|
|
93294
93558
|
token: swap.token_amount.token.toBigInt(),
|
|
93295
93559
|
amount: swap.token_amount.amount.toI129()
|
|
93296
93560
|
}
|
|
93297
93561
|
})),
|
|
93298
|
-
|
|
93299
|
-
|
|
93562
|
+
lever_swap_limit_amount: BigInt(
|
|
93563
|
+
_params.lever_swap_limit_amount.toWei()
|
|
93564
|
+
),
|
|
93565
|
+
lever_swap_weights: _params.lever_swap_weights.map(
|
|
93566
|
+
(weight) => BigInt(weight.toWei())
|
|
93567
|
+
),
|
|
93568
|
+
withdraw_swap: _params.withdraw_swap.map((swap) => ({
|
|
93300
93569
|
route: swap.route.map((route) => ({
|
|
93301
93570
|
pool_key: {
|
|
93302
93571
|
token0: route.pool_key.token0.toBigInt(),
|
|
93303
93572
|
token1: route.pool_key.token1.toBigInt(),
|
|
93304
93573
|
fee: route.pool_key.fee,
|
|
93305
93574
|
tick_spacing: route.pool_key.tick_spacing,
|
|
93306
|
-
extension:
|
|
93575
|
+
extension: ContractAddr.from(
|
|
93576
|
+
route.pool_key.extension
|
|
93577
|
+
).toBigInt()
|
|
93307
93578
|
},
|
|
93308
|
-
sqrt_ratio_limit: uint256_exports.bnToUint256(
|
|
93309
|
-
|
|
93579
|
+
sqrt_ratio_limit: uint256_exports.bnToUint256(
|
|
93580
|
+
route.sqrt_ratio_limit.toWei()
|
|
93581
|
+
),
|
|
93582
|
+
skip_ahead: BigInt(route.skip_ahead.toWei())
|
|
93310
93583
|
})),
|
|
93311
93584
|
token_amount: {
|
|
93312
93585
|
token: swap.token_amount.token.toBigInt(),
|
|
93313
93586
|
amount: swap.token_amount.amount.toI129()
|
|
93314
93587
|
}
|
|
93315
93588
|
})),
|
|
93316
|
-
|
|
93317
|
-
|
|
93318
|
-
|
|
93319
|
-
|
|
93320
|
-
|
|
93321
|
-
|
|
93322
|
-
|
|
93323
|
-
|
|
93324
|
-
|
|
93325
|
-
debt_asset: _params.debt_asset.toBigInt(),
|
|
93326
|
-
user: _params.user.toBigInt(),
|
|
93327
|
-
sub_margin: BigInt(_params.sub_margin.toWei()),
|
|
93328
|
-
recipient: _params.recipient.toBigInt(),
|
|
93329
|
-
lever_swap: _params.lever_swap.map((swap) => ({
|
|
93330
|
-
route: swap.route.map((route) => ({
|
|
93331
|
-
pool_key: {
|
|
93332
|
-
token0: route.pool_key.token0.toBigInt(),
|
|
93333
|
-
token1: route.pool_key.token1.toBigInt(),
|
|
93334
|
-
fee: route.pool_key.fee,
|
|
93335
|
-
tick_spacing: route.pool_key.tick_spacing,
|
|
93336
|
-
extension: ContractAddr.from(route.pool_key.extension).toBigInt()
|
|
93337
|
-
},
|
|
93338
|
-
sqrt_ratio_limit: uint256_exports.bnToUint256(route.sqrt_ratio_limit.toWei()),
|
|
93339
|
-
skip_ahead: BigInt(route.skip_ahead.toWei())
|
|
93340
|
-
})),
|
|
93341
|
-
token_amount: {
|
|
93342
|
-
token: swap.token_amount.token.toBigInt(),
|
|
93343
|
-
amount: swap.token_amount.amount.toI129()
|
|
93344
|
-
}
|
|
93345
|
-
})),
|
|
93346
|
-
lever_swap_limit_amount: BigInt(_params.lever_swap_limit_amount.toWei()),
|
|
93347
|
-
lever_swap_weights: _params.lever_swap_weights.map((weight) => BigInt(weight.toWei())),
|
|
93348
|
-
withdraw_swap: _params.withdraw_swap.map((swap) => ({
|
|
93349
|
-
route: swap.route.map((route) => ({
|
|
93350
|
-
pool_key: {
|
|
93351
|
-
token0: route.pool_key.token0.toBigInt(),
|
|
93352
|
-
token1: route.pool_key.token1.toBigInt(),
|
|
93353
|
-
fee: route.pool_key.fee,
|
|
93354
|
-
tick_spacing: route.pool_key.tick_spacing,
|
|
93355
|
-
extension: ContractAddr.from(route.pool_key.extension).toBigInt()
|
|
93356
|
-
},
|
|
93357
|
-
sqrt_ratio_limit: uint256_exports.bnToUint256(route.sqrt_ratio_limit.toWei()),
|
|
93358
|
-
skip_ahead: BigInt(route.skip_ahead.toWei())
|
|
93359
|
-
})),
|
|
93360
|
-
token_amount: {
|
|
93361
|
-
token: swap.token_amount.token.toBigInt(),
|
|
93362
|
-
amount: swap.token_amount.amount.toI129()
|
|
93363
|
-
}
|
|
93364
|
-
})),
|
|
93365
|
-
withdraw_swap_limit_amount: BigInt(_params.withdraw_swap_limit_amount.toWei()),
|
|
93366
|
-
withdraw_swap_weights: _params.withdraw_swap_weights.map((weight) => BigInt(weight.toWei())),
|
|
93367
|
-
close_position: _params.close_position
|
|
93368
|
-
} })
|
|
93589
|
+
withdraw_swap_limit_amount: BigInt(
|
|
93590
|
+
_params.withdraw_swap_limit_amount.toWei()
|
|
93591
|
+
),
|
|
93592
|
+
withdraw_swap_weights: _params.withdraw_swap_weights.map(
|
|
93593
|
+
(weight) => BigInt(weight.toWei())
|
|
93594
|
+
),
|
|
93595
|
+
close_position: _params.close_position
|
|
93596
|
+
}
|
|
93597
|
+
})
|
|
93369
93598
|
};
|
|
93370
93599
|
}
|
|
93371
93600
|
async getHealthFactor() {
|
|
@@ -93374,11 +93603,15 @@ spurious results.`);
|
|
|
93374
93603
|
}
|
|
93375
93604
|
async getNetAPY() {
|
|
93376
93605
|
const positions = await this.getPositions();
|
|
93377
|
-
logger2.verbose(
|
|
93606
|
+
logger2.verbose(
|
|
93607
|
+
`${this.name}::getNetAPY: positions: ${JSON.stringify(positions)}`
|
|
93608
|
+
);
|
|
93378
93609
|
const allZero = positions.every((p) => p.usdValue === 0);
|
|
93379
93610
|
if (allZero) {
|
|
93380
93611
|
const collateralUSD = 1e3;
|
|
93381
|
-
const maxLTV = await this.vesuAdapter.getLTVConfig(
|
|
93612
|
+
const maxLTV = await this.vesuAdapter.getLTVConfig(
|
|
93613
|
+
this.config.networkConfig
|
|
93614
|
+
);
|
|
93382
93615
|
const targetHF = this.config.targetHealthFactor;
|
|
93383
93616
|
const maxDebt = HealthFactorMath.getMaxDebtAmountOnLooping(
|
|
93384
93617
|
new Web3Number(collateralUSD, this.config.collateral.decimals),
|
|
@@ -93417,7 +93650,10 @@ spurious results.`);
|
|
|
93417
93650
|
//abstract means the method has no implementation in this class; instead, child classes must implement it.
|
|
93418
93651
|
async getAPY(supportedPosition) {
|
|
93419
93652
|
const side = supportedPosition.isDebt ? "LONG" : "SHORT";
|
|
93420
|
-
const fundingRates = await this.client.getFundingRates(
|
|
93653
|
+
const fundingRates = await this.client.getFundingRates(
|
|
93654
|
+
this.config.extendedMarketName,
|
|
93655
|
+
side
|
|
93656
|
+
);
|
|
93421
93657
|
if (fundingRates.status !== "OK") {
|
|
93422
93658
|
logger2.error("error getting funding rates", fundingRates);
|
|
93423
93659
|
return { apy: 0, type: "base" /* BASE */ };
|
|
@@ -93461,14 +93697,14 @@ spurious results.`);
|
|
|
93461
93697
|
});
|
|
93462
93698
|
}
|
|
93463
93699
|
_getDepositLeaf() {
|
|
93464
|
-
const usdceToken = Global.getDefaultTokens().find(
|
|
93700
|
+
const usdceToken = Global.getDefaultTokens().find(
|
|
93701
|
+
(token) => token.symbol === "USDCe"
|
|
93702
|
+
);
|
|
93465
93703
|
return [
|
|
93466
93704
|
{
|
|
93467
93705
|
target: this.config.supportedPositions[0].asset.address,
|
|
93468
93706
|
method: "approve",
|
|
93469
|
-
packedArguments: [
|
|
93470
|
-
AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()
|
|
93471
|
-
],
|
|
93707
|
+
packedArguments: [AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()],
|
|
93472
93708
|
id: `extended_approve_${this.config.supportedPositions[0].asset.symbol}`,
|
|
93473
93709
|
sanitizer: AVNU_LEGACY_SANITIZER
|
|
93474
93710
|
},
|
|
@@ -93499,25 +93735,33 @@ spurious results.`);
|
|
|
93499
93735
|
const leafConfigs = this._getSwapFromLegacyLeaf();
|
|
93500
93736
|
const leaves = leafConfigs.map((config3) => {
|
|
93501
93737
|
const { target, method, packedArguments, sanitizer, id } = config3;
|
|
93502
|
-
const leaf = this.constructSimpleLeafData(
|
|
93503
|
-
|
|
93504
|
-
|
|
93505
|
-
|
|
93506
|
-
|
|
93507
|
-
|
|
93738
|
+
const leaf = this.constructSimpleLeafData(
|
|
93739
|
+
{
|
|
93740
|
+
id,
|
|
93741
|
+
target,
|
|
93742
|
+
method,
|
|
93743
|
+
packedArguments
|
|
93744
|
+
},
|
|
93745
|
+
sanitizer
|
|
93746
|
+
);
|
|
93508
93747
|
return leaf;
|
|
93509
93748
|
});
|
|
93510
|
-
return {
|
|
93749
|
+
return {
|
|
93750
|
+
leaves,
|
|
93751
|
+
callConstructor: this.getSwapFromLegacyCall.bind(
|
|
93752
|
+
this
|
|
93753
|
+
)
|
|
93754
|
+
};
|
|
93511
93755
|
}
|
|
93512
93756
|
_getSwapFromLegacyLeaf() {
|
|
93513
|
-
const usdceToken = Global.getDefaultTokens().find(
|
|
93757
|
+
const usdceToken = Global.getDefaultTokens().find(
|
|
93758
|
+
(token) => token.symbol === "USDCe"
|
|
93759
|
+
);
|
|
93514
93760
|
return [
|
|
93515
93761
|
{
|
|
93516
93762
|
target: usdceToken.address,
|
|
93517
93763
|
method: "approve",
|
|
93518
|
-
packedArguments: [
|
|
93519
|
-
AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()
|
|
93520
|
-
],
|
|
93764
|
+
packedArguments: [AVNU_EXCHANGE_FOR_LEGACY_USDC.toBigInt()],
|
|
93521
93765
|
id: `extendedswaplegacyapprove_${usdceToken.symbol}`,
|
|
93522
93766
|
sanitizer: AVNU_LEGACY_SANITIZER
|
|
93523
93767
|
},
|
|
@@ -93536,11 +93780,13 @@ spurious results.`);
|
|
|
93536
93780
|
async getDepositCall(params) {
|
|
93537
93781
|
try {
|
|
93538
93782
|
const usdcToken = this.config.supportedPositions[0].asset;
|
|
93539
|
-
const usdceToken = Global.getDefaultTokens().find(
|
|
93540
|
-
|
|
93541
|
-
|
|
93783
|
+
const usdceToken = Global.getDefaultTokens().find(
|
|
93784
|
+
(token) => token.symbol === "USDCe"
|
|
93785
|
+
);
|
|
93786
|
+
const salt = Math.floor(Math.random() * 10 ** usdcToken.decimals);
|
|
93787
|
+
const amount = uint256_exports.bnToUint256(
|
|
93788
|
+
params.amount.multipliedBy(10).toWei()
|
|
93542
93789
|
);
|
|
93543
|
-
const amount = uint256_exports.bnToUint256(params.amount.multipliedBy(10).toWei());
|
|
93544
93790
|
const quotes = await this.config.avnuAdapter.getQuotesAvnu(
|
|
93545
93791
|
usdcToken.address.toString(),
|
|
93546
93792
|
usdceToken.address.toString(),
|
|
@@ -93553,7 +93799,9 @@ spurious results.`);
|
|
|
93553
93799
|
logger2.error("error getting quotes from avnu");
|
|
93554
93800
|
return [];
|
|
93555
93801
|
}
|
|
93556
|
-
const getCalldata = await this.config.avnuAdapter.getSwapCallData(
|
|
93802
|
+
const getCalldata = await this.config.avnuAdapter.getSwapCallData(
|
|
93803
|
+
quotes
|
|
93804
|
+
);
|
|
93557
93805
|
const swapCallData = getCalldata[0];
|
|
93558
93806
|
return [
|
|
93559
93807
|
{
|
|
@@ -93629,8 +93877,12 @@ spurious results.`);
|
|
|
93629
93877
|
async getSwapFromLegacyCall(params) {
|
|
93630
93878
|
try {
|
|
93631
93879
|
const usdcToken = this.config.supportedPositions[0].asset;
|
|
93632
|
-
const usdceToken = Global.getDefaultTokens().find(
|
|
93633
|
-
|
|
93880
|
+
const usdceToken = Global.getDefaultTokens().find(
|
|
93881
|
+
(token) => token.symbol === "USDCe"
|
|
93882
|
+
);
|
|
93883
|
+
const amount = uint256_exports.bnToUint256(
|
|
93884
|
+
params.amount.multipliedBy(10).toWei()
|
|
93885
|
+
);
|
|
93634
93886
|
const quotes = await this.config.avnuAdapter.getQuotesAvnu(
|
|
93635
93887
|
usdceToken.address.toString(),
|
|
93636
93888
|
usdcToken.address.toString(),
|
|
@@ -93643,7 +93895,9 @@ spurious results.`);
|
|
|
93643
93895
|
logger2.error("error getting quotes from avnu");
|
|
93644
93896
|
return [];
|
|
93645
93897
|
}
|
|
93646
|
-
const getCalldata = await this.config.avnuAdapter.getSwapCallData(
|
|
93898
|
+
const getCalldata = await this.config.avnuAdapter.getSwapCallData(
|
|
93899
|
+
quotes
|
|
93900
|
+
);
|
|
93647
93901
|
const swapCallData = getCalldata[0];
|
|
93648
93902
|
return [
|
|
93649
93903
|
{
|
|
@@ -93691,9 +93945,14 @@ spurious results.`);
|
|
|
93691
93945
|
if (!this.client) {
|
|
93692
93946
|
throw new Error("Client not initialized");
|
|
93693
93947
|
}
|
|
93694
|
-
const withdrawalRequest = await this.client.withdrawUSDC(
|
|
93948
|
+
const withdrawalRequest = await this.client.withdrawUSDC(
|
|
93949
|
+
amount.toFixed(2)
|
|
93950
|
+
);
|
|
93695
93951
|
if (withdrawalRequest.status === "OK") {
|
|
93696
|
-
const withdrawalStatus = await this.getDepositOrWithdrawalStatus(
|
|
93952
|
+
const withdrawalStatus = await this.getDepositOrWithdrawalStatus(
|
|
93953
|
+
withdrawalRequest.data,
|
|
93954
|
+
"WITHDRAWAL" /* WITHDRAWAL */
|
|
93955
|
+
);
|
|
93697
93956
|
return withdrawalStatus;
|
|
93698
93957
|
}
|
|
93699
93958
|
return false;
|
|
@@ -93766,17 +94025,34 @@ spurious results.`);
|
|
|
93766
94025
|
logger2.error("error initializing client");
|
|
93767
94026
|
return null;
|
|
93768
94027
|
}
|
|
93769
|
-
|
|
94028
|
+
let orderhistory = await this.getOrderHistory(marketName);
|
|
93770
94029
|
if (!orderhistory || orderhistory.length === 0) {
|
|
93771
|
-
logger2.error(`error getting order: ${orderId}`);
|
|
93772
|
-
|
|
94030
|
+
logger2.error(`error getting order history: ${orderId}`);
|
|
94031
|
+
} else {
|
|
94032
|
+
const order = orderhistory.slice(0, 5).find((order2) => order2.id.toString() === orderId);
|
|
94033
|
+
if (order) {
|
|
94034
|
+
return order;
|
|
94035
|
+
}
|
|
93773
94036
|
}
|
|
93774
|
-
|
|
93775
|
-
|
|
93776
|
-
|
|
93777
|
-
|
|
94037
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
94038
|
+
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
94039
|
+
orderhistory = await this.getOrderHistory(marketName);
|
|
94040
|
+
if (!orderhistory || orderhistory.length === 0) {
|
|
94041
|
+
logger2.error(
|
|
94042
|
+
`error getting order history on retry ${attempt}: ${orderId}`
|
|
94043
|
+
);
|
|
94044
|
+
continue;
|
|
94045
|
+
}
|
|
94046
|
+
const order = orderhistory.slice(0, 5).find((order2) => order2.id.toString() === orderId);
|
|
94047
|
+
if (order) {
|
|
94048
|
+
return order;
|
|
94049
|
+
}
|
|
94050
|
+
logger2.error(
|
|
94051
|
+
`order not found in top 5 entries on retry ${attempt}: ${orderId}`
|
|
94052
|
+
);
|
|
93778
94053
|
}
|
|
93779
|
-
|
|
94054
|
+
logger2.error(`error getting order after all retries: ${orderId}`);
|
|
94055
|
+
return null;
|
|
93780
94056
|
}
|
|
93781
94057
|
async fetchOrderBookBTCUSDC() {
|
|
93782
94058
|
try {
|
|
@@ -93849,7 +94125,10 @@ spurious results.`);
|
|
|
93849
94125
|
return null;
|
|
93850
94126
|
}
|
|
93851
94127
|
await new Promise((resolve) => setTimeout(resolve, 5e3));
|
|
93852
|
-
const openOrder = await this.getOrderStatus(
|
|
94128
|
+
const openOrder = await this.getOrderStatus(
|
|
94129
|
+
result2.position_id,
|
|
94130
|
+
this.config.extendedMarketName
|
|
94131
|
+
);
|
|
93853
94132
|
if (!openOrder || openOrder.status !== "FILLED" /* FILLED */) {
|
|
93854
94133
|
if (attempt >= maxAttempts) {
|
|
93855
94134
|
logger2.error("Max retries reached \u2014 could not verify open position");
|
|
@@ -93872,7 +94151,9 @@ spurious results.`);
|
|
|
93872
94151
|
};
|
|
93873
94152
|
}
|
|
93874
94153
|
} catch (err2) {
|
|
93875
|
-
logger2.error(
|
|
94154
|
+
logger2.error(
|
|
94155
|
+
`createShortOrder failed on attempt ${attempt}: ${err2.message}`
|
|
94156
|
+
);
|
|
93876
94157
|
if (attempt < maxAttempts) {
|
|
93877
94158
|
const backoff = 1200 * attempt;
|
|
93878
94159
|
logger2.info(`Retrying after ${backoff}ms...`);
|
|
@@ -93917,13 +94198,17 @@ spurious results.`);
|
|
|
93917
94198
|
operationsStatus: ["COMPLETED" /* COMPLETED */]
|
|
93918
94199
|
});
|
|
93919
94200
|
if (operationsType === "DEPOSIT" /* DEPOSIT */) {
|
|
93920
|
-
const myTransferStatus = transferHistory.data.find(
|
|
94201
|
+
const myTransferStatus = transferHistory.data.find(
|
|
94202
|
+
(operation) => operation.transactionHash === orderId
|
|
94203
|
+
);
|
|
93921
94204
|
if (!myTransferStatus) {
|
|
93922
94205
|
return true;
|
|
93923
94206
|
}
|
|
93924
94207
|
return true;
|
|
93925
94208
|
} else {
|
|
93926
|
-
const myTransferStatus = transferHistory.data.find(
|
|
94209
|
+
const myTransferStatus = transferHistory.data.find(
|
|
94210
|
+
(operation) => operation.id.toString() === orderId.toString()
|
|
94211
|
+
);
|
|
93927
94212
|
if (!myTransferStatus) {
|
|
93928
94213
|
return true;
|
|
93929
94214
|
}
|
|
@@ -97536,6 +97821,7 @@ spurious results.`);
|
|
|
97536
97821
|
toToken.decimals,
|
|
97537
97822
|
true
|
|
97538
97823
|
);
|
|
97824
|
+
console.log(`${_AvnuAdapter.name}::getDepositCall quote: ${quote?.sellAmountInUsd}`);
|
|
97539
97825
|
if (!quote) {
|
|
97540
97826
|
logger2.error("error getting quote from avnu");
|
|
97541
97827
|
return [];
|
|
@@ -97654,7 +97940,7 @@ spurious results.`);
|
|
|
97654
97940
|
}
|
|
97655
97941
|
throw new Error("Failed to fetch quote after retries");
|
|
97656
97942
|
}
|
|
97657
|
-
async getQuotesAvnu(from_token_address, to_token_address, amount, takerAddress, toTokenDecimals, usdcToBtc, maxIterations = 5, tolerance =
|
|
97943
|
+
async getQuotesAvnu(from_token_address, to_token_address, amount, takerAddress, toTokenDecimals, usdcToBtc, maxIterations = 5, tolerance = 5e3) {
|
|
97658
97944
|
try {
|
|
97659
97945
|
const fromToken = this.config.supportedPositions[0].asset;
|
|
97660
97946
|
const toToken = this.config.supportedPositions[1].asset;
|
|
@@ -97894,7 +98180,8 @@ spurious results.`);
|
|
|
97894
98180
|
}
|
|
97895
98181
|
const balance = await this.getUnusedBalance();
|
|
97896
98182
|
const usdcBalanceOnExtended = await extendedAdapter.getExtendedDepositAmount();
|
|
97897
|
-
const amountToInvest = balance.
|
|
98183
|
+
const amountToInvest = new Web3Number(balance.usdValue, USDC_TOKEN_DECIMALS).plus(usdcBalanceOnExtended?.availableForWithdrawal ?? 0).minus(LIMIT_BALANCE);
|
|
98184
|
+
logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest amountToInvest: ${amountToInvest.toNumber()}`);
|
|
97898
98185
|
if (amountToInvest.lessThan(0)) {
|
|
97899
98186
|
return {
|
|
97900
98187
|
shouldInvest: false,
|
|
@@ -97947,6 +98234,7 @@ spurious results.`);
|
|
|
97947
98234
|
vesuLeverage: 0
|
|
97948
98235
|
};
|
|
97949
98236
|
}
|
|
98237
|
+
logger2.info(`${_VesuExtendedMultiplierStrategy.name}::shouldInvest vesu_amount: ${vesu_amount.toNumber()}, extended_amount: ${extended_amount.toNumber()}`);
|
|
97950
98238
|
return {
|
|
97951
98239
|
shouldInvest: true,
|
|
97952
98240
|
vesuAmount: vesu_amount,
|
|
@@ -98026,15 +98314,15 @@ spurious results.`);
|
|
|
98026
98314
|
}
|
|
98027
98315
|
const usdcAmountInWallet = (await this.getUnusedBalance()).amount;
|
|
98028
98316
|
const usdcAmountOnExtended = parseFloat(
|
|
98029
|
-
extendedHoldings.
|
|
98317
|
+
extendedHoldings.availableForWithdrawal
|
|
98030
98318
|
);
|
|
98031
|
-
if (extendedAmount.
|
|
98319
|
+
if (extendedAmount.minus(usdcAmountOnExtended).greaterThan(0)) {
|
|
98032
98320
|
try {
|
|
98033
98321
|
const { calls: extendedCalls } = await this.moveAssets(
|
|
98034
98322
|
{
|
|
98035
98323
|
to: Protocols.EXTENDED.name,
|
|
98036
98324
|
from: Protocols.VAULT.name,
|
|
98037
|
-
amount: extendedAmount.
|
|
98325
|
+
amount: extendedAmount.minus(usdcAmountOnExtended)
|
|
98038
98326
|
},
|
|
98039
98327
|
extendedAdapter,
|
|
98040
98328
|
vesuAdapter
|
|
@@ -98141,7 +98429,7 @@ spurious results.`);
|
|
|
98141
98429
|
const withdrawalFromExtended = await extendedAdapter.withdrawFromExtended(params.amount);
|
|
98142
98430
|
if (withdrawalFromExtended) {
|
|
98143
98431
|
const extendedHoldings2 = await extendedAdapter.getExtendedDepositAmount();
|
|
98144
|
-
logger2.info(`extendedHoldings after withdrawal ${extendedHoldings2}`);
|
|
98432
|
+
logger2.info(`extendedHoldings after withdrawal ${extendedHoldings2?.availableForWithdrawal}`);
|
|
98145
98433
|
await new Promise((resolve) => setTimeout(resolve, 1e4));
|
|
98146
98434
|
const calls = await this.moveAssetsToVaultAllocator(params.amount, extendedAdapter);
|
|
98147
98435
|
if (calls.length > 0) {
|
|
@@ -98272,7 +98560,7 @@ spurious results.`);
|
|
|
98272
98560
|
};
|
|
98273
98561
|
}
|
|
98274
98562
|
const extendedHoldingAmount = new Web3Number(
|
|
98275
|
-
extendedHoldings.
|
|
98563
|
+
extendedHoldings.availableForWithdrawal,
|
|
98276
98564
|
USDC_TOKEN_DECIMALS
|
|
98277
98565
|
);
|
|
98278
98566
|
const {
|
|
@@ -98332,7 +98620,6 @@ spurious results.`);
|
|
|
98332
98620
|
extendedAmountInBTC: new Web3Number(0, 0),
|
|
98333
98621
|
calls: []
|
|
98334
98622
|
};
|
|
98335
|
-
;
|
|
98336
98623
|
}
|
|
98337
98624
|
}
|
|
98338
98625
|
async checkPriceDifferenceBetweenAvnuAndExtended(extendedAdapter, vesuAdapter, avnuAdapter) {
|