@strkfarm/sdk 1.1.38 → 1.1.40
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 +726 -185
- package/dist/index.browser.mjs +725 -182
- package/dist/index.d.ts +126 -13
- package/dist/index.js +726 -182
- package/dist/index.mjs +725 -182
- 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 +255 -79
- 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 +231 -72
- 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/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
APYType: () => APYType,
|
|
33
34
|
AUMTypes: () => AUMTypes,
|
|
34
35
|
AVNU_EXCHANGE: () => AVNU_EXCHANGE,
|
|
35
36
|
AVNU_MIDDLEWARE: () => AVNU_MIDDLEWARE,
|
|
@@ -420,6 +421,25 @@ var defaultTokens = [{
|
|
|
420
421
|
priceProxySymbol: "WBTC",
|
|
421
422
|
priceCheckAmount: 1e-4
|
|
422
423
|
// 112000 * 0.0001 = $11.2
|
|
424
|
+
}, {
|
|
425
|
+
name: "mRe7BTC",
|
|
426
|
+
symbol: "mRe7BTC",
|
|
427
|
+
logo: "https://imagedelivery.net/0xPAQaDtnQhBs8IzYRIlNg/3a62ecee-1e58-45d3-9862-3ce90dff1900/logo",
|
|
428
|
+
address: ContractAddr.from("0x4e4fb1a9ca7e84bae609b9dc0078ad7719e49187ae7e425bb47d131710eddac"),
|
|
429
|
+
decimals: 18,
|
|
430
|
+
coingeckId: void 0,
|
|
431
|
+
displayDecimals: 6,
|
|
432
|
+
priceCheckAmount: 1e-4
|
|
433
|
+
// 112000 * 0.0001 = $11.2
|
|
434
|
+
}, {
|
|
435
|
+
name: "mRe7YIELD",
|
|
436
|
+
symbol: "mRe7YIELD",
|
|
437
|
+
logo: "https://midas.app/assets/mre7-BcOOHm7i.svg",
|
|
438
|
+
address: ContractAddr.from("0x4be8945e61dc3e19ebadd1579a6bd53b262f51ba89e6f8b0c4bc9a7e3c633fc"),
|
|
439
|
+
decimals: 18,
|
|
440
|
+
coingeckId: void 0,
|
|
441
|
+
displayDecimals: 2,
|
|
442
|
+
priceCheckAmount: 100
|
|
423
443
|
}];
|
|
424
444
|
var tokens = defaultTokens;
|
|
425
445
|
var _Global = class _Global {
|
|
@@ -2313,16 +2333,16 @@ var AvnuWrapper = class _AvnuWrapper {
|
|
|
2313
2333
|
};
|
|
2314
2334
|
return swapInfo;
|
|
2315
2335
|
}
|
|
2316
|
-
static buildZeroSwap(tokenToSell,
|
|
2336
|
+
static buildZeroSwap(tokenToSell, beneficiary, tokenToBuy = tokenToSell) {
|
|
2317
2337
|
return {
|
|
2318
2338
|
token_from_address: tokenToSell.address,
|
|
2319
2339
|
token_from_amount: import_starknet6.uint256.bnToUint256(0),
|
|
2320
|
-
token_to_address:
|
|
2340
|
+
token_to_address: tokenToBuy.address,
|
|
2321
2341
|
token_to_amount: import_starknet6.uint256.bnToUint256(0),
|
|
2322
2342
|
token_to_min_amount: import_starknet6.uint256.bnToUint256(0),
|
|
2323
|
-
beneficiary
|
|
2343
|
+
beneficiary,
|
|
2324
2344
|
integrator_fee_amount_bps: 0,
|
|
2325
|
-
integrator_fee_recipient:
|
|
2345
|
+
integrator_fee_recipient: beneficiary,
|
|
2326
2346
|
routes: []
|
|
2327
2347
|
};
|
|
2328
2348
|
}
|
|
@@ -4123,21 +4143,20 @@ var Harvests = class _Harvests {
|
|
|
4123
4143
|
const rewards = await this.getHarvests(addr);
|
|
4124
4144
|
if (rewards.length == 0) return [];
|
|
4125
4145
|
const unClaimed = [];
|
|
4126
|
-
const
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
}
|
|
4134
|
-
const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
|
|
4135
|
-
if (bal.lessThan(reward.claim.amount)) {
|
|
4136
|
-
logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
|
|
4137
|
-
continue;
|
|
4138
|
-
}
|
|
4139
|
-
unClaimed.unshift(reward);
|
|
4146
|
+
const reward = rewards.sort((a, b) => b.endDate.getTime() - a.endDate.getTime())[0];
|
|
4147
|
+
const cls = await this.config.provider.getClassAt(reward.rewardsContract.address);
|
|
4148
|
+
const contract = new import_starknet9.Contract({ abi: cls.abi, address: reward.rewardsContract.address, providerOrAccount: this.config.provider });
|
|
4149
|
+
const isClaimed = await contract.call("is_claimed", [reward.claim.id]);
|
|
4150
|
+
logger.verbose(`${_Harvests.name}: isClaimed: ${isClaimed}`);
|
|
4151
|
+
if (isClaimed) {
|
|
4152
|
+
return unClaimed;
|
|
4140
4153
|
}
|
|
4154
|
+
const bal = await new ERC20(this.config).balanceOf(reward.token, reward.rewardsContract.address, 18);
|
|
4155
|
+
if (bal.lessThan(reward.claim.amount)) {
|
|
4156
|
+
logger.verbose(`${_Harvests.name}: balance: ${bal.toString()}, amount: ${reward.claim.amount.toString()}`);
|
|
4157
|
+
return unClaimed;
|
|
4158
|
+
}
|
|
4159
|
+
unClaimed.unshift(reward);
|
|
4141
4160
|
return unClaimed;
|
|
4142
4161
|
}
|
|
4143
4162
|
};
|
|
@@ -15400,6 +15419,91 @@ var apolloClient = new import_client.ApolloClient({
|
|
|
15400
15419
|
});
|
|
15401
15420
|
var apollo_client_default = apolloClient;
|
|
15402
15421
|
|
|
15422
|
+
// src/utils/math-utils.ts
|
|
15423
|
+
async function binarySearch(lowWei, highWei, callback) {
|
|
15424
|
+
while (lowWei <= highWei) {
|
|
15425
|
+
const diff = highWei - lowWei;
|
|
15426
|
+
const mid = lowWei + diff / 2n;
|
|
15427
|
+
const result = await callback(mid);
|
|
15428
|
+
if (result === "found") {
|
|
15429
|
+
return mid;
|
|
15430
|
+
} else if (result == "retry") {
|
|
15431
|
+
} else if (result === "go_low") {
|
|
15432
|
+
highWei = mid - BigInt(1);
|
|
15433
|
+
} else {
|
|
15434
|
+
lowWei = mid + BigInt(1);
|
|
15435
|
+
}
|
|
15436
|
+
}
|
|
15437
|
+
return null;
|
|
15438
|
+
}
|
|
15439
|
+
async function findMaxInputWithSlippage(options) {
|
|
15440
|
+
const {
|
|
15441
|
+
apiGetOutput,
|
|
15442
|
+
maxInput,
|
|
15443
|
+
maxSlippagePercent,
|
|
15444
|
+
tolerance,
|
|
15445
|
+
minInput = 0,
|
|
15446
|
+
referenceAmountMultiplier = 1e-3,
|
|
15447
|
+
referenceRate = 0
|
|
15448
|
+
} = options;
|
|
15449
|
+
let apiCalls = 0;
|
|
15450
|
+
if (!referenceRate && !referenceAmountMultiplier) {
|
|
15451
|
+
throw new Error("One of referenceRate or referenceAmountMultiplier must be provided");
|
|
15452
|
+
}
|
|
15453
|
+
let _referenceRate = referenceRate;
|
|
15454
|
+
if (!_referenceRate) {
|
|
15455
|
+
const smallAmount = maxInput * referenceAmountMultiplier;
|
|
15456
|
+
const referenceOutput = await apiGetOutput(smallAmount);
|
|
15457
|
+
apiCalls++;
|
|
15458
|
+
_referenceRate = referenceOutput / smallAmount;
|
|
15459
|
+
}
|
|
15460
|
+
async function checkSlippage(inputAmount) {
|
|
15461
|
+
const actualOutput = await apiGetOutput(inputAmount);
|
|
15462
|
+
apiCalls++;
|
|
15463
|
+
const expectedOutput = inputAmount * referenceRate;
|
|
15464
|
+
const slippage = (expectedOutput - actualOutput) / expectedOutput;
|
|
15465
|
+
logger.verbose(`findMaxInputWithSlippage::checkSlippage inputAmount: ${inputAmount}, actualOutput: ${actualOutput}, slippage: ${slippage}, maxSlippagePercent: ${maxSlippagePercent}`);
|
|
15466
|
+
return {
|
|
15467
|
+
acceptable: slippage <= maxSlippagePercent,
|
|
15468
|
+
slippage,
|
|
15469
|
+
output: actualOutput
|
|
15470
|
+
};
|
|
15471
|
+
}
|
|
15472
|
+
const maxCheck = await checkSlippage(maxInput);
|
|
15473
|
+
if (maxCheck.acceptable) {
|
|
15474
|
+
return {
|
|
15475
|
+
optimalInput: maxInput,
|
|
15476
|
+
actualOutput: maxCheck.output,
|
|
15477
|
+
actualSlippage: maxCheck.slippage,
|
|
15478
|
+
apiCallsUsed: apiCalls
|
|
15479
|
+
};
|
|
15480
|
+
}
|
|
15481
|
+
let left = minInput;
|
|
15482
|
+
let right = maxInput;
|
|
15483
|
+
let bestInput = minInput;
|
|
15484
|
+
let bestOutput = 0;
|
|
15485
|
+
let bestSlippage = 0;
|
|
15486
|
+
const convergenceThreshold = tolerance * maxInput;
|
|
15487
|
+
while (right - left > convergenceThreshold) {
|
|
15488
|
+
const mid = (left + right) / 2;
|
|
15489
|
+
const midCheck = await checkSlippage(mid);
|
|
15490
|
+
if (midCheck.acceptable) {
|
|
15491
|
+
bestInput = mid;
|
|
15492
|
+
bestOutput = midCheck.output;
|
|
15493
|
+
bestSlippage = midCheck.slippage;
|
|
15494
|
+
left = mid;
|
|
15495
|
+
} else {
|
|
15496
|
+
right = mid;
|
|
15497
|
+
}
|
|
15498
|
+
}
|
|
15499
|
+
return {
|
|
15500
|
+
optimalInput: bestInput,
|
|
15501
|
+
actualOutput: bestOutput,
|
|
15502
|
+
actualSlippage: bestSlippage,
|
|
15503
|
+
apiCallsUsed: apiCalls
|
|
15504
|
+
};
|
|
15505
|
+
}
|
|
15506
|
+
|
|
15403
15507
|
// src/strategies/ekubo-cl-vault.tsx
|
|
15404
15508
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
15405
15509
|
var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
@@ -16522,62 +16626,193 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16522
16626
|
logger.verbose(
|
|
16523
16627
|
`${_EkuboCLVault.name}: harvest => Processing claim, isToken1: ${isToken1} amount: ${postFeeAmount.toWei()}`
|
|
16524
16628
|
);
|
|
16525
|
-
const
|
|
16526
|
-
|
|
16629
|
+
const isRewardTokenMatch = claim.token.eq(poolKey.token0) || claim.token.eq(poolKey.token1);
|
|
16630
|
+
if (isRewardTokenMatch) {
|
|
16631
|
+
const _callsFinal = await this._handleRewardAndVaultTokenMatchHarvest({
|
|
16632
|
+
acc,
|
|
16633
|
+
claim,
|
|
16634
|
+
isToken1,
|
|
16635
|
+
token0Info,
|
|
16636
|
+
token1Info,
|
|
16637
|
+
postFeeAmount,
|
|
16638
|
+
poolKey,
|
|
16639
|
+
bounds,
|
|
16640
|
+
maxIterations,
|
|
16641
|
+
priceRatioPrecision
|
|
16642
|
+
});
|
|
16643
|
+
calls.push(..._callsFinal);
|
|
16644
|
+
} else {
|
|
16645
|
+
const _callsFinal = await this._handleRewardAndVaultTokenMismatchHarvest({
|
|
16646
|
+
claim,
|
|
16647
|
+
token0Info,
|
|
16648
|
+
token1Info,
|
|
16649
|
+
postFeeAmount,
|
|
16650
|
+
poolKey,
|
|
16651
|
+
bounds,
|
|
16652
|
+
maxIterations,
|
|
16653
|
+
priceRatioPrecision,
|
|
16654
|
+
acc
|
|
16655
|
+
});
|
|
16656
|
+
calls.push(..._callsFinal);
|
|
16657
|
+
}
|
|
16658
|
+
}
|
|
16659
|
+
return calls;
|
|
16660
|
+
}
|
|
16661
|
+
/**
|
|
16662
|
+
* @description This funciton requires atleast one of the pool tokens to be reward token
|
|
16663
|
+
* i.e. STRK.
|
|
16664
|
+
* @param params
|
|
16665
|
+
*/
|
|
16666
|
+
async _handleRewardAndVaultTokenMatchHarvest(params) {
|
|
16667
|
+
const { acc, claim, isToken1, token0Info, token1Info, postFeeAmount, poolKey, bounds, maxIterations, priceRatioPrecision } = params;
|
|
16668
|
+
const token0Amt = isToken1 ? new Web3Number(0, token0Info.decimals) : postFeeAmount;
|
|
16669
|
+
const token1Amt = isToken1 ? postFeeAmount : new Web3Number(0, token0Info.decimals);
|
|
16670
|
+
logger.verbose(
|
|
16671
|
+
`${_EkuboCLVault.name}: harvest => token0Amt: ${token0Amt.toString()}, token1Amt: ${token1Amt.toString()}`
|
|
16672
|
+
);
|
|
16673
|
+
const swapInfo = await this.getSwapInfoGivenAmounts(
|
|
16674
|
+
poolKey,
|
|
16675
|
+
token0Amt,
|
|
16676
|
+
token1Amt,
|
|
16677
|
+
bounds,
|
|
16678
|
+
maxIterations,
|
|
16679
|
+
priceRatioPrecision
|
|
16680
|
+
);
|
|
16681
|
+
swapInfo.token_to_address = token0Info.address.address;
|
|
16682
|
+
logger.verbose(
|
|
16683
|
+
`${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(swapInfo)}`
|
|
16684
|
+
);
|
|
16685
|
+
logger.verbose(
|
|
16686
|
+
`${_EkuboCLVault.name}: harvest => claim: ${JSON.stringify(claim)}`
|
|
16687
|
+
);
|
|
16688
|
+
const harvestEstimateCall = async (swapInfo1) => {
|
|
16689
|
+
const swap1Amount = Web3Number.fromWei(
|
|
16690
|
+
import_starknet11.uint256.uint256ToBN(swapInfo1.token_from_amount).toString(),
|
|
16691
|
+
18
|
|
16692
|
+
// cause its always STRK?
|
|
16693
|
+
).minimum(
|
|
16694
|
+
postFeeAmount.toFixed(18)
|
|
16695
|
+
// cause always strk
|
|
16696
|
+
);
|
|
16697
|
+
swapInfo.token_from_amount = import_starknet11.uint256.bnToUint256(swap1Amount.toWei());
|
|
16698
|
+
swapInfo.token_to_min_amount = import_starknet11.uint256.bnToUint256(
|
|
16699
|
+
swap1Amount.multipliedBy(0).toWei()
|
|
16700
|
+
// placeholder
|
|
16701
|
+
);
|
|
16527
16702
|
logger.verbose(
|
|
16528
|
-
`${_EkuboCLVault.name}: harvest =>
|
|
16703
|
+
`${_EkuboCLVault.name}: harvest => swap1Amount: ${swap1Amount}`
|
|
16529
16704
|
);
|
|
16530
|
-
const
|
|
16531
|
-
|
|
16532
|
-
|
|
16533
|
-
token1Amt,
|
|
16534
|
-
bounds,
|
|
16535
|
-
maxIterations,
|
|
16536
|
-
priceRatioPrecision
|
|
16705
|
+
const remainingAmount = postFeeAmount.minus(swap1Amount).maximum(0);
|
|
16706
|
+
logger.verbose(
|
|
16707
|
+
`${_EkuboCLVault.name}: harvest => remainingAmount: ${remainingAmount}`
|
|
16537
16708
|
);
|
|
16538
|
-
|
|
16709
|
+
const swapInfo2 = {
|
|
16710
|
+
...swapInfo,
|
|
16711
|
+
token_from_amount: import_starknet11.uint256.bnToUint256(remainingAmount.toWei())
|
|
16712
|
+
};
|
|
16713
|
+
swapInfo2.token_to_address = token1Info.address.address;
|
|
16539
16714
|
logger.verbose(
|
|
16540
|
-
`${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
|
|
16715
|
+
`${_EkuboCLVault.name}: harvest => swapInfo: ${JSON.stringify(
|
|
16716
|
+
swapInfo
|
|
16717
|
+
)}`
|
|
16541
16718
|
);
|
|
16542
16719
|
logger.verbose(
|
|
16543
|
-
`${_EkuboCLVault.name}: harvest =>
|
|
16720
|
+
`${_EkuboCLVault.name}: harvest => swapInfo2: ${JSON.stringify(
|
|
16721
|
+
swapInfo2
|
|
16722
|
+
)}`
|
|
16544
16723
|
);
|
|
16545
|
-
const
|
|
16546
|
-
|
|
16547
|
-
|
|
16548
|
-
|
|
16549
|
-
|
|
16550
|
-
|
|
16551
|
-
|
|
16552
|
-
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
|
|
16556
|
-
|
|
16557
|
-
|
|
16558
|
-
|
|
16559
|
-
|
|
16560
|
-
|
|
16561
|
-
|
|
16562
|
-
|
|
16563
|
-
|
|
16564
|
-
|
|
16565
|
-
|
|
16566
|
-
|
|
16567
|
-
|
|
16568
|
-
|
|
16569
|
-
|
|
16570
|
-
|
|
16571
|
-
|
|
16572
|
-
|
|
16573
|
-
|
|
16574
|
-
|
|
16575
|
-
|
|
16576
|
-
|
|
16577
|
-
|
|
16578
|
-
|
|
16579
|
-
|
|
16580
|
-
|
|
16724
|
+
const calldata = [
|
|
16725
|
+
claim.rewardsContract.address,
|
|
16726
|
+
{
|
|
16727
|
+
id: claim.claim.id,
|
|
16728
|
+
amount: claim.claim.amount.toWei(),
|
|
16729
|
+
claimee: claim.claim.claimee.address
|
|
16730
|
+
},
|
|
16731
|
+
claim.proof.map((p) => import_starknet11.num.getDecimalString(p)),
|
|
16732
|
+
swapInfo,
|
|
16733
|
+
swapInfo2
|
|
16734
|
+
];
|
|
16735
|
+
logger.verbose(
|
|
16736
|
+
`${_EkuboCLVault.name}: harvest => calldata: ${JSON.stringify(
|
|
16737
|
+
calldata
|
|
16738
|
+
)}`
|
|
16739
|
+
);
|
|
16740
|
+
return [this.contract.populate("harvest", calldata)];
|
|
16741
|
+
};
|
|
16742
|
+
const _callsFinal = await this.rebalanceIter(
|
|
16743
|
+
swapInfo,
|
|
16744
|
+
acc,
|
|
16745
|
+
harvestEstimateCall,
|
|
16746
|
+
claim.token.eq(poolKey.token0),
|
|
16747
|
+
0,
|
|
16748
|
+
0n,
|
|
16749
|
+
BigInt(postFeeAmount.toWei())
|
|
16750
|
+
// upper limit is the post fee amount
|
|
16751
|
+
);
|
|
16752
|
+
logger.verbose(
|
|
16753
|
+
`${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
|
|
16754
|
+
_callsFinal
|
|
16755
|
+
)}`
|
|
16756
|
+
);
|
|
16757
|
+
return _callsFinal;
|
|
16758
|
+
}
|
|
16759
|
+
/**
|
|
16760
|
+
* @description This function handles harvesting of reward token that is not the same as any of the vault token
|
|
16761
|
+
* i.e. STRK is not part of vault tokens like BTC/ETH
|
|
16762
|
+
* @param params
|
|
16763
|
+
* @returns
|
|
16764
|
+
*/
|
|
16765
|
+
async _handleRewardAndVaultTokenMismatchHarvest(params) {
|
|
16766
|
+
const { acc, claim, token0Info, token1Info, postFeeAmount, poolKey, bounds, maxIterations, priceRatioPrecision } = params;
|
|
16767
|
+
let token0Amt = postFeeAmount;
|
|
16768
|
+
const beneficiary = this.address.address;
|
|
16769
|
+
let harvestCall = null;
|
|
16770
|
+
harvestCall = await this.harvestMismatchEstimateCallFn({
|
|
16771
|
+
postFeeAmount,
|
|
16772
|
+
claim,
|
|
16773
|
+
token0Info,
|
|
16774
|
+
token1Info,
|
|
16775
|
+
acc
|
|
16776
|
+
});
|
|
16777
|
+
if (!harvestCall) {
|
|
16778
|
+
throw new Error("Harvest call not found");
|
|
16779
|
+
}
|
|
16780
|
+
return [harvestCall];
|
|
16781
|
+
}
|
|
16782
|
+
// given an amount (i.e. portion of reward to use to swap to token0), returns info on increasing or decreasing
|
|
16783
|
+
// amount for binary search
|
|
16784
|
+
async harvestMismatchEstimateCallFn(params) {
|
|
16785
|
+
const { postFeeAmount, claim, token0Info, token1Info, acc } = params;
|
|
16786
|
+
let harvestCall = null;
|
|
16787
|
+
const binarySearchCallbackFn = async (mid) => {
|
|
16788
|
+
const rewardPart2 = BigInt(postFeeAmount.toWei()) - mid;
|
|
16789
|
+
const avnuWrapper = new AvnuWrapper();
|
|
16790
|
+
const beneficiary = this.address.address;
|
|
16791
|
+
const quote1 = await avnuWrapper.getQuotes(
|
|
16792
|
+
claim.token.address,
|
|
16793
|
+
token0Info.address.address,
|
|
16794
|
+
mid.toString(),
|
|
16795
|
+
beneficiary
|
|
16796
|
+
);
|
|
16797
|
+
const swapInfo1 = await avnuWrapper.getSwapInfo(
|
|
16798
|
+
quote1,
|
|
16799
|
+
beneficiary,
|
|
16800
|
+
0,
|
|
16801
|
+
beneficiary
|
|
16802
|
+
);
|
|
16803
|
+
const quote2 = await avnuWrapper.getQuotes(
|
|
16804
|
+
claim.token.address,
|
|
16805
|
+
token1Info.address.address,
|
|
16806
|
+
rewardPart2.toString(),
|
|
16807
|
+
beneficiary
|
|
16808
|
+
);
|
|
16809
|
+
const swapInfo2 = await avnuWrapper.getSwapInfo(
|
|
16810
|
+
quote2,
|
|
16811
|
+
beneficiary,
|
|
16812
|
+
0,
|
|
16813
|
+
beneficiary
|
|
16814
|
+
);
|
|
16815
|
+
try {
|
|
16581
16816
|
const calldata = [
|
|
16582
16817
|
claim.rewardsContract.address,
|
|
16583
16818
|
{
|
|
@@ -16586,34 +16821,24 @@ var EkuboCLVault = class _EkuboCLVault extends BaseStrategy {
|
|
|
16586
16821
|
claimee: claim.claim.claimee.address
|
|
16587
16822
|
},
|
|
16588
16823
|
claim.proof.map((p) => import_starknet11.num.getDecimalString(p)),
|
|
16589
|
-
|
|
16824
|
+
swapInfo1,
|
|
16590
16825
|
swapInfo2
|
|
16591
16826
|
];
|
|
16592
|
-
|
|
16593
|
-
|
|
16594
|
-
|
|
16595
|
-
|
|
16596
|
-
);
|
|
16597
|
-
|
|
16598
|
-
|
|
16599
|
-
|
|
16600
|
-
|
|
16601
|
-
|
|
16602
|
-
|
|
16603
|
-
|
|
16604
|
-
|
|
16605
|
-
|
|
16606
|
-
|
|
16607
|
-
// upper limit is the post fee amount
|
|
16608
|
-
);
|
|
16609
|
-
logger.verbose(
|
|
16610
|
-
`${_EkuboCLVault.name}: harvest => _callsFinal: ${JSON.stringify(
|
|
16611
|
-
_callsFinal
|
|
16612
|
-
)}`
|
|
16613
|
-
);
|
|
16614
|
-
calls.push(..._callsFinal);
|
|
16615
|
-
}
|
|
16616
|
-
return calls;
|
|
16827
|
+
harvestCall = this.contract.populate("harvest", calldata);
|
|
16828
|
+
const gas = await acc.estimateInvokeFee(harvestCall);
|
|
16829
|
+
return "found";
|
|
16830
|
+
} catch (err) {
|
|
16831
|
+
console.error(err);
|
|
16832
|
+
if (err.message.includes("invalid token0 amount")) {
|
|
16833
|
+
return "go_low";
|
|
16834
|
+
} else if (err.message.includes("invalid token1 amount")) {
|
|
16835
|
+
return "go_high";
|
|
16836
|
+
}
|
|
16837
|
+
return "retry";
|
|
16838
|
+
}
|
|
16839
|
+
};
|
|
16840
|
+
await binarySearch(0n, BigInt(postFeeAmount.toWei()), binarySearchCallbackFn);
|
|
16841
|
+
return harvestCall;
|
|
16617
16842
|
}
|
|
16618
16843
|
async getInvestmentFlows() {
|
|
16619
16844
|
const netYield = await this.netAPY();
|
|
@@ -19145,7 +19370,58 @@ function toBigInt(value) {
|
|
|
19145
19370
|
}
|
|
19146
19371
|
|
|
19147
19372
|
// src/strategies/universal-adapters/baseAdapter.ts
|
|
19373
|
+
var APYType = /* @__PURE__ */ ((APYType2) => {
|
|
19374
|
+
APYType2["BASE"] = "base";
|
|
19375
|
+
APYType2["REWARD"] = "reward";
|
|
19376
|
+
APYType2["LST"] = "lst";
|
|
19377
|
+
return APYType2;
|
|
19378
|
+
})(APYType || {});
|
|
19148
19379
|
var BaseAdapter = class extends CacheClass {
|
|
19380
|
+
// readonly config: BaseAdapterConfig;
|
|
19381
|
+
// constructor(config: BaseAdapterConfig) {
|
|
19382
|
+
// super();
|
|
19383
|
+
// this.config = config;
|
|
19384
|
+
// }
|
|
19385
|
+
constructor() {
|
|
19386
|
+
super();
|
|
19387
|
+
}
|
|
19388
|
+
// /**
|
|
19389
|
+
// * Loop through all supported positions and return amount, usd value, remarks and apy for each
|
|
19390
|
+
// */
|
|
19391
|
+
// async getPositions(): Promise<PositionInfo[]> {
|
|
19392
|
+
// const results: PositionInfo[] = [];
|
|
19393
|
+
// for (const supported of this.config.supportedPositions) {
|
|
19394
|
+
// const amount = await this.getPosition(supported);
|
|
19395
|
+
// const usdValue = await this.getUSDValue(supported.asset, amount);
|
|
19396
|
+
// const apy = await this.getAPY(supported);
|
|
19397
|
+
// results.push({ amount, usdValue, apy });
|
|
19398
|
+
// }
|
|
19399
|
+
// return results;
|
|
19400
|
+
// }
|
|
19401
|
+
// /**
|
|
19402
|
+
// * Implemented by child adapters to compute APY for a given supported position
|
|
19403
|
+
// */
|
|
19404
|
+
// protected abstract getAPY(supportedPosition: SupportedPosition): Promise<PositionAPY>;
|
|
19405
|
+
// /**
|
|
19406
|
+
// * Implemented by child adapters to fetch amount for a given supported position
|
|
19407
|
+
// */
|
|
19408
|
+
// protected abstract getPosition(supportedPosition: SupportedPosition): Promise<Web3Number>;
|
|
19409
|
+
// /**
|
|
19410
|
+
// * Implemented by child adapters to calculate maximum deposit positions
|
|
19411
|
+
// * @param amount Optional amount in baseToken to deposit
|
|
19412
|
+
// */
|
|
19413
|
+
// protected abstract maxDeposit(amount?: Web3Number): Promise<PositionInfo[]>;
|
|
19414
|
+
// /**
|
|
19415
|
+
// * Implemented by child adapters to calculate maximum withdraw positions
|
|
19416
|
+
// */
|
|
19417
|
+
// protected abstract maxWithdraw(): Promise<PositionInfo[]>;
|
|
19418
|
+
// /**
|
|
19419
|
+
// * Uses pricer to convert an amount of an asset to USD value
|
|
19420
|
+
// */
|
|
19421
|
+
// protected async getUSDValue(asset: TokenInfo, amount: Web3Number): Promise<number> {
|
|
19422
|
+
// const priceInfo = await this.config.pricer.getPrice(asset.symbol);
|
|
19423
|
+
// return amount.toNumber() * priceInfo.price;
|
|
19424
|
+
// }
|
|
19149
19425
|
constructSimpleLeafData(params, sanitizer = SIMPLE_SANITIZER) {
|
|
19150
19426
|
const { id, target, method, packedArguments } = params;
|
|
19151
19427
|
return {
|
|
@@ -19163,6 +19439,94 @@ var BaseAdapter = class extends CacheClass {
|
|
|
19163
19439
|
]
|
|
19164
19440
|
};
|
|
19165
19441
|
}
|
|
19442
|
+
// /**
|
|
19443
|
+
// * Implementor must provide target/method/packedArguments/sanitizer for deposit leaf construction
|
|
19444
|
+
// */
|
|
19445
|
+
// protected abstract _getDepositLeaf(): {
|
|
19446
|
+
// target: ContractAddr,
|
|
19447
|
+
// method: string,
|
|
19448
|
+
// packedArguments: bigint[],
|
|
19449
|
+
// sanitizer: ContractAddr,
|
|
19450
|
+
// id: string
|
|
19451
|
+
// }[];
|
|
19452
|
+
// /**
|
|
19453
|
+
// * Implementor must provide target/method/packedArguments/sanitizer for withdraw leaf construction
|
|
19454
|
+
// */
|
|
19455
|
+
// protected abstract _getWithdrawLeaf(): {
|
|
19456
|
+
// target: ContractAddr,
|
|
19457
|
+
// method: string,
|
|
19458
|
+
// packedArguments: bigint[],
|
|
19459
|
+
// sanitizer: ContractAddr,
|
|
19460
|
+
// id: string
|
|
19461
|
+
// }[];
|
|
19462
|
+
// /**
|
|
19463
|
+
// * Returns deposit leaf adapter using configured proof id
|
|
19464
|
+
// */
|
|
19465
|
+
// getDepositLeaf(): AdapterLeafType<T1> {
|
|
19466
|
+
// const leafConfigs = this._getDepositLeaf();
|
|
19467
|
+
// const leaves = leafConfigs.map(config => {
|
|
19468
|
+
// const { target, method, packedArguments, sanitizer, id } = config;
|
|
19469
|
+
// const leaf = this.constructSimpleLeafData({
|
|
19470
|
+
// id: id,
|
|
19471
|
+
// target,
|
|
19472
|
+
// method,
|
|
19473
|
+
// packedArguments
|
|
19474
|
+
// }, sanitizer);
|
|
19475
|
+
// return leaf;
|
|
19476
|
+
// });
|
|
19477
|
+
// return { leaves, callConstructor: this.getDepositCall.bind(this) as unknown as GenerateCallFn<T1> };
|
|
19478
|
+
// }
|
|
19479
|
+
// /**
|
|
19480
|
+
// * Returns withdraw leaf adapter using configured proof id
|
|
19481
|
+
// */
|
|
19482
|
+
// getWithdrawLeaf(): AdapterLeafType<T2> {
|
|
19483
|
+
// const leafConfigs = this._getWithdrawLeaf();
|
|
19484
|
+
// const leaves = leafConfigs.map(config => {
|
|
19485
|
+
// const { target, method, packedArguments, sanitizer, id } = config;
|
|
19486
|
+
// const leaf = this.constructSimpleLeafData({
|
|
19487
|
+
// id: id,
|
|
19488
|
+
// target,
|
|
19489
|
+
// method,
|
|
19490
|
+
// packedArguments
|
|
19491
|
+
// }, sanitizer ?? SIMPLE_SANITIZER);
|
|
19492
|
+
// return leaf;
|
|
19493
|
+
// });
|
|
19494
|
+
// return { leaves, callConstructor: this.getWithdrawCall.bind(this) as unknown as GenerateCallFn<T2> };
|
|
19495
|
+
// }
|
|
19496
|
+
// /**
|
|
19497
|
+
// * Default deposit callConstructor: expects params as calldata (bigint[])
|
|
19498
|
+
// */
|
|
19499
|
+
// protected getDepositCall<T1 = bigint[]>(params: T1): ManageCall[] {
|
|
19500
|
+
// const leafConfigs = this._getDepositLeaf();
|
|
19501
|
+
// return leafConfigs.map(config => {
|
|
19502
|
+
// const { target, method, sanitizer } = config;
|
|
19503
|
+
// return {
|
|
19504
|
+
// sanitizer: sanitizer ?? SIMPLE_SANITIZER,
|
|
19505
|
+
// call: {
|
|
19506
|
+
// contractAddress: target,
|
|
19507
|
+
// selector: hash.getSelectorFromName(method),
|
|
19508
|
+
// calldata: params as unknown as bigint[]
|
|
19509
|
+
// }
|
|
19510
|
+
// };
|
|
19511
|
+
// });
|
|
19512
|
+
// }
|
|
19513
|
+
// /**
|
|
19514
|
+
// * Default withdraw callConstructor: expects params as calldata (bigint[])
|
|
19515
|
+
// */
|
|
19516
|
+
// protected getWithdrawCall<T2 = bigint[]>(params: T2): ManageCall[] {
|
|
19517
|
+
// const leafConfigs = this._getWithdrawLeaf();
|
|
19518
|
+
// return leafConfigs.map(config => {
|
|
19519
|
+
// const { target, method, sanitizer } = config;
|
|
19520
|
+
// return {
|
|
19521
|
+
// sanitizer: sanitizer ?? SIMPLE_SANITIZER,
|
|
19522
|
+
// call: {
|
|
19523
|
+
// contractAddress: target,
|
|
19524
|
+
// selector: hash.getSelectorFromName(method),
|
|
19525
|
+
// calldata: params as unknown as bigint[]
|
|
19526
|
+
// }
|
|
19527
|
+
// };
|
|
19528
|
+
// });
|
|
19529
|
+
// }
|
|
19166
19530
|
};
|
|
19167
19531
|
|
|
19168
19532
|
// src/strategies/universal-adapters/common-adapter.ts
|
|
@@ -26765,7 +27129,20 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
26765
27129
|
}
|
|
26766
27130
|
const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address]);
|
|
26767
27131
|
logger.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap debt_cap: ${output.debt_cap.toString()}`);
|
|
26768
|
-
|
|
27132
|
+
if (!isV2) {
|
|
27133
|
+
throw new Error("getDebtCap is not supported for v1");
|
|
27134
|
+
}
|
|
27135
|
+
const currentDebt = await this.getCurrentDebtUtilisationAmount(config);
|
|
27136
|
+
logger.verbose(`${this.config.debt.symbol}::VesuAdapter::getDebtCap currentDebt: ${currentDebt.toString()}`);
|
|
27137
|
+
return Web3Number.fromWei(output.debt_cap.toString(), this.config.debt.decimals).minus(currentDebt);
|
|
27138
|
+
}
|
|
27139
|
+
async getCurrentDebtUtilisationAmount(config) {
|
|
27140
|
+
const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
|
|
27141
|
+
if (!isV2) {
|
|
27142
|
+
throw new Error("getCurrentDebtUtilisationAmount is not supported for v1");
|
|
27143
|
+
}
|
|
27144
|
+
const output = await contract.call("pairs", [this.config.collateral.address.address, this.config.debt.address.address]);
|
|
27145
|
+
return new Web3Number((Number(output.total_nominal_debt) / 1e18).toFixed(9), this.config.debt.decimals);
|
|
26769
27146
|
}
|
|
26770
27147
|
async getMaxBorrowableByInterestRate(config, asset, maxBorrowAPY) {
|
|
26771
27148
|
const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
|
|
@@ -26798,16 +27175,17 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
26798
27175
|
const assetConfig = isV2 ? _assetConfig : _assetConfig["0"];
|
|
26799
27176
|
const timeDelta = assetConfig.last_updated;
|
|
26800
27177
|
const lastFullUtilizationRate = assetConfig.last_full_utilization_rate;
|
|
26801
|
-
const
|
|
27178
|
+
const currentDebt = new Web3Number((Number(assetConfig.total_nominal_debt) / 1e18).toFixed(9), asset.decimals);
|
|
27179
|
+
const totalSupply = currentDebt.plus(Web3Number.fromWei(assetConfig.reserve, asset.decimals));
|
|
26802
27180
|
const ratePerSecond = BigInt(Math.round(maxBorrowAPY / 365 / 24 / 60 / 60 * Number(SCALE)));
|
|
26803
27181
|
const maxUtilisation = this.getMaxUtilizationGivenRatePerSecond(interestRateConfig, ratePerSecond, timeDelta, lastFullUtilizationRate);
|
|
26804
27182
|
logger.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate maxUtilisation: ${Number(maxUtilisation) / 1e18}, totalSupply: ${totalSupply.toString()}`);
|
|
26805
27183
|
const maxDebtToHave = totalSupply.multipliedBy(Number(maxUtilisation) / 1e18);
|
|
26806
|
-
|
|
27184
|
+
logger.verbose(`${asset.symbol}::VesuAdapter::getMaxBorrowableByInterestRate currentDebt: ${currentDebt.toString()}, maxDebtToHave: ${maxDebtToHave.toString()}`);
|
|
26807
27185
|
return maxDebtToHave.minus(currentDebt);
|
|
26808
27186
|
}
|
|
26809
|
-
async getLTVConfig(config) {
|
|
26810
|
-
const CACHE_KEY =
|
|
27187
|
+
async getLTVConfig(config, blockNumber = "latest") {
|
|
27188
|
+
const CACHE_KEY = `ltv_config_${blockNumber}`;
|
|
26811
27189
|
const cacheData = this.getCache(CACHE_KEY);
|
|
26812
27190
|
if (cacheData) {
|
|
26813
27191
|
return cacheData;
|
|
@@ -26815,10 +27193,10 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
26815
27193
|
const { contract, isV2 } = await this.getVesuSingletonContract(config, this.config.poolId);
|
|
26816
27194
|
let ltv = 0;
|
|
26817
27195
|
if (isV2) {
|
|
26818
|
-
const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address]);
|
|
27196
|
+
const output = await contract.call("pair_config", [this.config.collateral.address.address, this.config.debt.address.address], { blockIdentifier: blockNumber });
|
|
26819
27197
|
ltv = Number(output.max_ltv) / 1e18;
|
|
26820
27198
|
} else {
|
|
26821
|
-
const output = await contract.call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address]);
|
|
27199
|
+
const output = await contract.call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address], { blockIdentifier: blockNumber });
|
|
26822
27200
|
ltv = Number(output.max_ltv) / 1e18;
|
|
26823
27201
|
}
|
|
26824
27202
|
if (ltv == 0) {
|
|
@@ -26827,11 +27205,11 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
26827
27205
|
this.setCache(CACHE_KEY, ltv, 3e5);
|
|
26828
27206
|
return this.getCache(CACHE_KEY);
|
|
26829
27207
|
}
|
|
26830
|
-
async getPositions(config) {
|
|
27208
|
+
async getPositions(config, blockNumber = "latest") {
|
|
26831
27209
|
if (!this.pricer) {
|
|
26832
27210
|
throw new Error("Pricer is not initialized");
|
|
26833
27211
|
}
|
|
26834
|
-
const CACHE_KEY =
|
|
27212
|
+
const CACHE_KEY = `positions_${blockNumber}`;
|
|
26835
27213
|
const cacheData = this.getCache(CACHE_KEY);
|
|
26836
27214
|
if (cacheData) {
|
|
26837
27215
|
return cacheData;
|
|
@@ -26843,7 +27221,8 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
26843
27221
|
this.config.collateral.address.address,
|
|
26844
27222
|
this.config.debt.address.address,
|
|
26845
27223
|
this.config.vaultAllocator.address
|
|
26846
|
-
]);
|
|
27224
|
+
], { blockIdentifier: blockNumber });
|
|
27225
|
+
console.log(output);
|
|
26847
27226
|
const token1Price = await this.pricer.getPrice(this.config.collateral.symbol);
|
|
26848
27227
|
const token2Price = await this.pricer.getPrice(this.config.debt.symbol);
|
|
26849
27228
|
logger.verbose(`VesuAdapter::getPositions token1Price: ${token1Price.price}, token2Price: ${token2Price.price}`);
|
|
@@ -26863,11 +27242,11 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
26863
27242
|
this.setCache(CACHE_KEY, value, 6e4);
|
|
26864
27243
|
return value;
|
|
26865
27244
|
}
|
|
26866
|
-
async getCollateralization(config) {
|
|
27245
|
+
async getCollateralization(config, blockNumber = "latest") {
|
|
26867
27246
|
if (!this.pricer) {
|
|
26868
27247
|
throw new Error("Pricer is not initialized");
|
|
26869
27248
|
}
|
|
26870
|
-
const CACHE_KEY =
|
|
27249
|
+
const CACHE_KEY = `collateralization_${blockNumber}`;
|
|
26871
27250
|
const cacheData = this.getCache(CACHE_KEY);
|
|
26872
27251
|
if (cacheData) {
|
|
26873
27252
|
return cacheData;
|
|
@@ -26879,7 +27258,7 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
26879
27258
|
this.config.collateral.address.address,
|
|
26880
27259
|
this.config.debt.address.address,
|
|
26881
27260
|
this.config.vaultAllocator.address
|
|
26882
|
-
]);
|
|
27261
|
+
], { blockIdentifier: blockNumber });
|
|
26883
27262
|
const collateralAmount = Web3Number.fromWei(output["1"].toString(), 18);
|
|
26884
27263
|
const debtAmount = Web3Number.fromWei(output["2"].toString(), 18);
|
|
26885
27264
|
const value = [{
|
|
@@ -26916,9 +27295,9 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
26916
27295
|
ltv
|
|
26917
27296
|
};
|
|
26918
27297
|
}
|
|
26919
|
-
async getHealthFactor() {
|
|
26920
|
-
const ltv = await this.getLTVConfig(this.networkConfig);
|
|
26921
|
-
const collateralisation = await this.getCollateralization(this.networkConfig);
|
|
27298
|
+
async getHealthFactor(blockNumber = "latest") {
|
|
27299
|
+
const ltv = await this.getLTVConfig(this.networkConfig, blockNumber);
|
|
27300
|
+
const collateralisation = await this.getCollateralization(this.networkConfig, blockNumber);
|
|
26922
27301
|
return collateralisation[0].usdValue * ltv / collateralisation[1].usdValue;
|
|
26923
27302
|
}
|
|
26924
27303
|
static async getVesuPools(retry = 0) {
|
|
@@ -29580,11 +29959,11 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
|
|
|
29580
29959
|
vesuAdapter2.networkConfig = this.config;
|
|
29581
29960
|
return [vesuAdapter1, vesuAdapter2];
|
|
29582
29961
|
}
|
|
29583
|
-
async getVesuPositions() {
|
|
29962
|
+
async getVesuPositions(blockNumber = "latest") {
|
|
29584
29963
|
const adapters = this.getVesuAdapters();
|
|
29585
29964
|
const positions = [];
|
|
29586
29965
|
for (const adapter of adapters) {
|
|
29587
|
-
positions.push(...await adapter.getPositions(this.config));
|
|
29966
|
+
positions.push(...await adapter.getPositions(this.config, blockNumber));
|
|
29588
29967
|
}
|
|
29589
29968
|
return positions;
|
|
29590
29969
|
}
|
|
@@ -29653,8 +30032,8 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
|
|
|
29653
30032
|
async getLSTAPR(address) {
|
|
29654
30033
|
return 0;
|
|
29655
30034
|
}
|
|
29656
|
-
async getVesuHealthFactors() {
|
|
29657
|
-
return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor()));
|
|
30035
|
+
async getVesuHealthFactors(blockNumber = "latest") {
|
|
30036
|
+
return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor(blockNumber)));
|
|
29658
30037
|
}
|
|
29659
30038
|
async computeRebalanceConditionAndReturnCalls() {
|
|
29660
30039
|
const vesuAdapters = this.getVesuAdapters();
|
|
@@ -30250,6 +30629,42 @@ var UniversalStrategies = [
|
|
|
30250
30629
|
|
|
30251
30630
|
// src/strategies/universal-lst-muliplier-strategy.tsx
|
|
30252
30631
|
var import_starknet17 = require("starknet");
|
|
30632
|
+
|
|
30633
|
+
// src/utils/health-factor-math.ts
|
|
30634
|
+
var HealthFactorMath = class {
|
|
30635
|
+
static getCollateralRequired(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo) {
|
|
30636
|
+
const numerator = debtAmount.multipliedBy(debtPrice).multipliedBy(targetHF);
|
|
30637
|
+
const denominator = collateralPrice * maxLTV;
|
|
30638
|
+
const collateralAmount = numerator.dividedBy(denominator);
|
|
30639
|
+
const netCollateral = new Web3Number(collateralAmount.toString(), collateralTokenInfo.decimals);
|
|
30640
|
+
return netCollateral;
|
|
30641
|
+
}
|
|
30642
|
+
static getMinCollateralRequiredOnLooping(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo) {
|
|
30643
|
+
const netCollateral = this.getCollateralRequired(debtAmount, debtPrice, targetHF, maxLTV, collateralPrice, collateralTokenInfo);
|
|
30644
|
+
const collateralFromDebt = new Web3Number(debtAmount.multipliedBy(debtPrice).dividedBy(collateralPrice).toString(), collateralTokenInfo.decimals);
|
|
30645
|
+
return netCollateral.minus(collateralFromDebt);
|
|
30646
|
+
}
|
|
30647
|
+
static getHealthFactor(collateralAmount, collateralPrice, maxLTV, debtAmount, debtPrice) {
|
|
30648
|
+
const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
|
|
30649
|
+
const denominator = debtAmount.multipliedBy(debtPrice);
|
|
30650
|
+
const healthFactor = numerator.dividedBy(denominator);
|
|
30651
|
+
return healthFactor.toNumber();
|
|
30652
|
+
}
|
|
30653
|
+
static getMaxDebtAmountOnLooping(collateralAmount, collateralPrice, maxLTV, targetHF, debtPrice, debtTokenInfo) {
|
|
30654
|
+
const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
|
|
30655
|
+
const denominator = targetHF - maxLTV;
|
|
30656
|
+
const debtAmount = numerator.dividedBy(denominator);
|
|
30657
|
+
return new Web3Number(debtAmount.toString(), debtTokenInfo.decimals);
|
|
30658
|
+
}
|
|
30659
|
+
static getMaxDebtAmount(collateralAmount, collateralPrice, maxLTV, targetHF, debtPrice, debtTokenInfo) {
|
|
30660
|
+
const numerator = collateralAmount.multipliedBy(collateralPrice).multipliedBy(maxLTV);
|
|
30661
|
+
const denominator = targetHF * debtPrice;
|
|
30662
|
+
const debtAmount = numerator.dividedBy(denominator);
|
|
30663
|
+
return new Web3Number(debtAmount.toString(), debtTokenInfo.decimals);
|
|
30664
|
+
}
|
|
30665
|
+
};
|
|
30666
|
+
|
|
30667
|
+
// src/strategies/universal-lst-muliplier-strategy.tsx
|
|
30253
30668
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
30254
30669
|
var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy extends UniversalStrategy {
|
|
30255
30670
|
constructor(config, pricer, metadata) {
|
|
@@ -30264,15 +30679,14 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30264
30679
|
}
|
|
30265
30680
|
}
|
|
30266
30681
|
asset() {
|
|
30267
|
-
|
|
30268
|
-
return vesuAdapter1.config.collateral;
|
|
30682
|
+
return this.getVesuSameTokenAdapter().config.collateral;
|
|
30269
30683
|
}
|
|
30270
30684
|
getTag() {
|
|
30271
30685
|
return `${_UniversalLstMultiplierStrategy.name}:${this.metadata.name}`;
|
|
30272
30686
|
}
|
|
30273
30687
|
// Vesu adapter with LST and base token match
|
|
30274
30688
|
getVesuSameTokenAdapter() {
|
|
30275
|
-
const baseAdapter = this.getAdapter("
|
|
30689
|
+
const baseAdapter = this.getAdapter(getVesuLegId("vesu_leg1" /* VESU_LEG1 */, this.metadata.additionalInfo.underlyingToken.symbol));
|
|
30276
30690
|
baseAdapter.networkConfig = this.config;
|
|
30277
30691
|
baseAdapter.pricer = this.pricer;
|
|
30278
30692
|
return baseAdapter;
|
|
@@ -30320,20 +30734,52 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30320
30734
|
return price;
|
|
30321
30735
|
}
|
|
30322
30736
|
async getAvnuSwapMultiplyCall(params) {
|
|
30323
|
-
|
|
30324
|
-
|
|
30325
|
-
|
|
30326
|
-
|
|
30327
|
-
|
|
30737
|
+
assert(params.isDeposit, "Only deposit is supported in getAvnuSwapMultiplyCall");
|
|
30738
|
+
const maxBorrowableAmounts = await this.getMaxBorrowableAmount({ isAPYComputation: false });
|
|
30739
|
+
const allVesuAdapters = this.getVesuAdapters();
|
|
30740
|
+
let remainingAmount = params.leg1DepositAmount;
|
|
30741
|
+
const lstExRate = await this.getLSTExchangeRate();
|
|
30742
|
+
const baseAssetPrice = await this.pricer.getPrice(this.getLSTUnderlyingTokenInfo().symbol);
|
|
30743
|
+
const lstPrice = baseAssetPrice.price * lstExRate;
|
|
30744
|
+
for (let i = 0; i < maxBorrowableAmounts.maxBorrowables.length; i++) {
|
|
30745
|
+
const maxBorrowable = maxBorrowableAmounts.maxBorrowables[i];
|
|
30746
|
+
const vesuAdapter = allVesuAdapters.find((adapter) => adapter.config.debt.address.eq(maxBorrowable.borrowableAsset.address));
|
|
30747
|
+
if (!vesuAdapter) {
|
|
30748
|
+
throw new Error(`${this.getTag()}::getAvnuSwapMultiplyCall: vesuAdapter not found for borrowable asset: ${maxBorrowable.borrowableAsset.symbol}`);
|
|
30749
|
+
}
|
|
30750
|
+
const maxLTV = await vesuAdapter.getLTVConfig(this.config);
|
|
30751
|
+
const debtPrice = await this.pricer.getPrice(maxBorrowable.borrowableAsset.symbol);
|
|
30752
|
+
const maxAmountToDeposit = HealthFactorMath.getMinCollateralRequiredOnLooping(
|
|
30753
|
+
maxBorrowable.amount,
|
|
30754
|
+
debtPrice.price,
|
|
30755
|
+
this.metadata.additionalInfo.targetHealthFactor,
|
|
30756
|
+
maxLTV,
|
|
30757
|
+
lstPrice,
|
|
30758
|
+
this.asset()
|
|
30759
|
+
);
|
|
30760
|
+
const amountToDeposit = remainingAmount.minimum(maxAmountToDeposit);
|
|
30761
|
+
logger.verbose(`${this.getTag()}::getAvnuSwapMultiplyCall::${vesuAdapter.config.debt.symbol}:: remainingAmount: ${remainingAmount}, amountToDeposit: ${amountToDeposit}, depositAmount: ${amountToDeposit}, maxBorrowable: ${maxBorrowable.amount}`);
|
|
30762
|
+
const call = await this._getAvnuDepositSwapLegCall({
|
|
30763
|
+
isDeposit: params.isDeposit,
|
|
30764
|
+
// adjust decimals of debt asset
|
|
30765
|
+
leg1DepositAmount: amountToDeposit,
|
|
30766
|
+
minHF: 1.1,
|
|
30767
|
+
// undo
|
|
30768
|
+
vesuAdapter
|
|
30769
|
+
});
|
|
30770
|
+
remainingAmount = remainingAmount.minus(amountToDeposit);
|
|
30771
|
+
return { call, vesuAdapter };
|
|
30772
|
+
}
|
|
30773
|
+
throw new Error(`${this.getTag()}::getAvnuSwapMultiplyCall: no calls found`);
|
|
30328
30774
|
}
|
|
30329
30775
|
async _getAvnuDepositSwapLegCall(params) {
|
|
30776
|
+
const { vesuAdapter } = params;
|
|
30330
30777
|
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall params: ${JSON.stringify(params)}`);
|
|
30331
30778
|
assert(params.isDeposit, "Only deposit is supported in _getAvnuDepositSwapLegCall");
|
|
30332
|
-
const
|
|
30333
|
-
const legLTV = await vesuAdapter1.getLTVConfig(this.config);
|
|
30779
|
+
const legLTV = await vesuAdapter.getLTVConfig(this.config);
|
|
30334
30780
|
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall legLTV: ${legLTV}`);
|
|
30335
|
-
const existingPositions = await
|
|
30336
|
-
const collateralisation = await
|
|
30781
|
+
const existingPositions = await vesuAdapter.getPositions(this.config);
|
|
30782
|
+
const collateralisation = await vesuAdapter.getCollateralization(this.config);
|
|
30337
30783
|
const existingCollateralInfo = existingPositions[0];
|
|
30338
30784
|
const existingDebtInfo = existingPositions[1];
|
|
30339
30785
|
logger.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
|
|
@@ -30341,11 +30787,40 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30341
30787
|
const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
|
|
30342
30788
|
const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
|
|
30343
30789
|
logger.debug(`${this.getTag()}::_getAvnuDepositSwapLegCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
|
|
30790
|
+
const debtTokenInfo = vesuAdapter.config.debt;
|
|
30791
|
+
let newDepositAmount = params.leg1DepositAmount;
|
|
30344
30792
|
const totalCollateral = existingCollateralInfo.amount.plus(params.leg1DepositAmount);
|
|
30345
30793
|
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalCollateral: ${totalCollateral}`);
|
|
30346
|
-
const totalDebtAmount =
|
|
30347
|
-
|
|
30348
|
-
|
|
30794
|
+
const totalDebtAmount = new Web3Number(
|
|
30795
|
+
totalCollateral.multipliedBy(collateralPrice).multipliedBy(legLTV).dividedBy(debtPrice).dividedBy(params.minHF).toString(),
|
|
30796
|
+
debtTokenInfo.decimals
|
|
30797
|
+
);
|
|
30798
|
+
let debtAmount = totalDebtAmount.minus(existingDebtInfo.amount);
|
|
30799
|
+
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall totalDebtAmount: ${totalDebtAmount}, initial computed debt: ${debtAmount}`);
|
|
30800
|
+
const maxBorrowable = await this.getMaxBorrowableAmountByVesuAdapter(vesuAdapter, false);
|
|
30801
|
+
if (debtAmount.gt(0) && maxBorrowable.amount.eq(0)) {
|
|
30802
|
+
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall maxBorrowable is 0, skipping`);
|
|
30803
|
+
return void 0;
|
|
30804
|
+
} else if (debtAmount.gt(0) && maxBorrowable.amount.gt(0)) {
|
|
30805
|
+
debtAmount = maxBorrowable.amount.minimum(debtAmount);
|
|
30806
|
+
const newDebtUSDValue = debtAmount.multipliedBy(debtPrice);
|
|
30807
|
+
const totalCollateralRequired = HealthFactorMath.getCollateralRequired(
|
|
30808
|
+
debtAmount.plus(existingDebtInfo.amount),
|
|
30809
|
+
debtPrice,
|
|
30810
|
+
params.minHF,
|
|
30811
|
+
legLTV,
|
|
30812
|
+
collateralPrice,
|
|
30813
|
+
this.asset()
|
|
30814
|
+
);
|
|
30815
|
+
newDepositAmount = totalCollateralRequired.minus(existingCollateralInfo.amount);
|
|
30816
|
+
if (newDepositAmount.lt(0)) {
|
|
30817
|
+
throw new Error(`${this.getTag()}::_getAvnuDepositSwapLegCall newDepositAmount is less than 0, newDepositAmount: ${newDepositAmount}, totalCollateralRequired: ${totalCollateralRequired}, existingCollateralInfo.amount: ${existingCollateralInfo.amount}`);
|
|
30818
|
+
}
|
|
30819
|
+
if (newDebtUSDValue.toNumber() < 100) {
|
|
30820
|
+
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall newDebtUSDValue is less than 100, skipping`);
|
|
30821
|
+
return void 0;
|
|
30822
|
+
}
|
|
30823
|
+
}
|
|
30349
30824
|
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall debtAmount: ${debtAmount}`);
|
|
30350
30825
|
if (debtAmount.lt(0)) {
|
|
30351
30826
|
const lstDEXPrice = await this.getLSTDexPrice();
|
|
@@ -30357,32 +30832,34 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30357
30832
|
assert(calls.length == 1, `Expected 1 call for unwind, got ${calls.length}`);
|
|
30358
30833
|
return calls[0];
|
|
30359
30834
|
}
|
|
30835
|
+
console.log(`debtAmount`, debtAmount.toWei(), params.leg1DepositAmount.toWei());
|
|
30360
30836
|
const STEP0 = "approve_token1" /* APPROVE_TOKEN1 */;
|
|
30361
30837
|
const manage0Info = this.getProofs(STEP0);
|
|
30362
30838
|
const manageCall0 = manage0Info.callConstructor({
|
|
30363
|
-
amount:
|
|
30839
|
+
amount: newDepositAmount
|
|
30364
30840
|
});
|
|
30365
|
-
const STEP1 = "vesu_leg1" /* VESU_LEG1
|
|
30841
|
+
const STEP1 = getVesuLegId("vesu_leg1" /* VESU_LEG1 */, vesuAdapter.config.debt.symbol);
|
|
30366
30842
|
const manage1Info = this.getProofs(STEP1);
|
|
30367
30843
|
const manageCall1 = manage1Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
|
|
30368
|
-
collateralAmount:
|
|
30844
|
+
collateralAmount: newDepositAmount,
|
|
30369
30845
|
isAddCollateral: params.isDeposit,
|
|
30370
30846
|
debtAmount,
|
|
30371
30847
|
isBorrow: params.isDeposit
|
|
30372
30848
|
}));
|
|
30849
|
+
console.log(`manageCall1`, manageCall1.call, debtAmount.toWei(), newDepositAmount.toWei());
|
|
30373
30850
|
const proofIds = [STEP0, STEP1];
|
|
30374
30851
|
const manageCalls = [manageCall0, manageCall1];
|
|
30375
30852
|
if (debtAmount.gt(0)) {
|
|
30376
|
-
const STEP2 = "
|
|
30853
|
+
const STEP2 = getAvnuManageIDs("avnu_mul_approve_dep" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */, vesuAdapter.config.debt.symbol);
|
|
30377
30854
|
const manage2Info = this.getProofs(STEP2);
|
|
30378
30855
|
const manageCall2 = manage2Info.callConstructor({
|
|
30379
30856
|
amount: debtAmount
|
|
30380
30857
|
});
|
|
30381
|
-
const
|
|
30858
|
+
const debtTokenInfo2 = vesuAdapter.config.debt;
|
|
30382
30859
|
const lstTokenInfo = this.asset();
|
|
30383
30860
|
const avnuModule = new AvnuWrapper();
|
|
30384
30861
|
const quote = await avnuModule.getQuotes(
|
|
30385
|
-
|
|
30862
|
+
debtTokenInfo2.address.address,
|
|
30386
30863
|
lstTokenInfo.address.address,
|
|
30387
30864
|
debtAmount.toWei(),
|
|
30388
30865
|
this.metadata.additionalInfo.vaultAllocator.address
|
|
@@ -30398,7 +30875,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30398
30875
|
minAmountWei
|
|
30399
30876
|
);
|
|
30400
30877
|
logger.verbose(`${this.getTag()}::_getAvnuDepositSwapLegCall swapInfo: ${JSON.stringify(swapInfo)}`);
|
|
30401
|
-
const STEP3 = "
|
|
30878
|
+
const STEP3 = getAvnuManageIDs("avnu_mul_swap_dep" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, vesuAdapter.config.debt.symbol);
|
|
30402
30879
|
const manage3Info = this.getProofs(STEP3);
|
|
30403
30880
|
const manageCall3 = manage3Info.callConstructor({
|
|
30404
30881
|
props: swapInfo
|
|
@@ -30416,7 +30893,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30416
30893
|
const manageCall4 = manage4Info.callConstructor({
|
|
30417
30894
|
amount: minAmount
|
|
30418
30895
|
});
|
|
30419
|
-
const STEP5 = "vesu_leg1" /* VESU_LEG1
|
|
30896
|
+
const STEP5 = getVesuLegId("vesu_leg1" /* VESU_LEG1 */, vesuAdapter.config.debt.symbol);
|
|
30420
30897
|
const manage5Info = this.getProofs(STEP5);
|
|
30421
30898
|
const manageCall5 = manage5Info.callConstructor(VesuAdapter.getDefaultModifyPositionCallParams({
|
|
30422
30899
|
collateralAmount: minAmount,
|
|
@@ -30433,28 +30910,41 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30433
30910
|
}
|
|
30434
30911
|
// todo unwind or not deposit when the yield is bad.
|
|
30435
30912
|
async getLSTMultiplierRebalanceCall() {
|
|
30436
|
-
|
|
30437
|
-
|
|
30913
|
+
let shouldRebalance = false;
|
|
30914
|
+
const calls = [];
|
|
30915
|
+
const allVesuAdapters = this.getVesuAdapters().filter((vesuAdapter) => vesuAdapter.config.debt.symbol === "LBTC");
|
|
30916
|
+
for (const vesuAdapter of allVesuAdapters) {
|
|
30917
|
+
const call = await this._getLSTMultiplierRebalanceCall(vesuAdapter);
|
|
30918
|
+
if (call.shouldRebalance && call.manageCall) {
|
|
30919
|
+
shouldRebalance = true;
|
|
30920
|
+
calls.push({ vesuAdapter, manageCall: call.manageCall });
|
|
30921
|
+
}
|
|
30922
|
+
}
|
|
30923
|
+
return { shouldRebalance, manageCalls: calls };
|
|
30924
|
+
}
|
|
30925
|
+
async _getLSTMultiplierRebalanceCall(vesuAdapter) {
|
|
30926
|
+
const positions = await vesuAdapter.getPositions(this.config);
|
|
30927
|
+
assert(positions.length == 2, "Rebalance call is only supported for 2 positions");
|
|
30438
30928
|
const existingCollateralInfo = positions[0];
|
|
30439
30929
|
const existingDebtInfo = positions[1];
|
|
30440
|
-
const unusedBalance =
|
|
30441
|
-
const
|
|
30442
|
-
const
|
|
30443
|
-
|
|
30444
|
-
const collateralisation = await vesuAdapter1.getCollateralization(this.config);
|
|
30445
|
-
logger.debug(`${this.getTag()}::getVesuMultiplyCall existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
|
|
30930
|
+
const unusedBalance = await this.getUnusedBalance();
|
|
30931
|
+
const healthFactor = await vesuAdapter.getHealthFactor();
|
|
30932
|
+
const collateralisation = await vesuAdapter.getCollateralization(this.config);
|
|
30933
|
+
logger.debug(`${this.getTag()}::getVesuMultiplyCall::${vesuAdapter.config.debt.symbol} existingCollateralInfo: ${JSON.stringify(existingCollateralInfo)},
|
|
30446
30934
|
existingDebtInfo: ${JSON.stringify(existingDebtInfo)}, collateralisation: ${JSON.stringify(collateralisation)}`);
|
|
30447
30935
|
const collateralPrice = collateralisation[0].usdValue > 0 ? collateralisation[0].usdValue / existingCollateralInfo.amount.toNumber() : 1;
|
|
30448
30936
|
const debtPrice = collateralisation[1].usdValue > 0 ? collateralisation[1].usdValue / existingDebtInfo.amount.toNumber() : 1;
|
|
30449
30937
|
logger.debug(`${this.getTag()}::getVesuMultiplyCall collateralPrice: ${collateralPrice}, debtPrice: ${debtPrice}`);
|
|
30938
|
+
logger.debug(`${this.getTag()}::getVesuMultiplyCall healthFactor: ${healthFactor}`);
|
|
30450
30939
|
const isHFTooLow = healthFactor < this.metadata.additionalInfo.minHealthFactor;
|
|
30451
30940
|
const isHFTooHigh = healthFactor > this.metadata.additionalInfo.targetHealthFactor + 0.05;
|
|
30452
|
-
if (isHFTooLow || isHFTooHigh) {
|
|
30941
|
+
if (isHFTooLow || isHFTooHigh || 1) {
|
|
30453
30942
|
const manageCall = await this._getAvnuDepositSwapLegCall({
|
|
30454
30943
|
isDeposit: true,
|
|
30455
30944
|
leg1DepositAmount: unusedBalance.amount,
|
|
30456
|
-
minHF: 1.02
|
|
30945
|
+
minHF: 1.02,
|
|
30457
30946
|
// todo, shouldnt use this 1.02 HF, if there isn;t more looping left.
|
|
30947
|
+
vesuAdapter
|
|
30458
30948
|
});
|
|
30459
30949
|
return { shouldRebalance: true, manageCall };
|
|
30460
30950
|
} else {
|
|
@@ -30487,7 +30977,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30487
30977
|
async _getMinOutputAmountLSTBuy(amountInUnderlying) {
|
|
30488
30978
|
const lstTruePrice = await this.getLSTExchangeRate();
|
|
30489
30979
|
const minOutputAmount = amountInUnderlying.dividedBy(lstTruePrice).multipliedBy(0.99979);
|
|
30490
|
-
return minOutputAmount;
|
|
30980
|
+
return new Web3Number(minOutputAmount.toString(), this.asset().decimals);
|
|
30491
30981
|
}
|
|
30492
30982
|
async _getMinOutputAmountLSTSell(amountInLST) {
|
|
30493
30983
|
const lstTruePrice = await this.getLSTExchangeRate();
|
|
@@ -30544,21 +31034,52 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30544
31034
|
const vesuAdapter1 = this.getVesuSameTokenAdapter();
|
|
30545
31035
|
return vesuAdapter1.config.debt;
|
|
30546
31036
|
}
|
|
30547
|
-
async getMaxBorrowableAmount() {
|
|
31037
|
+
async getMaxBorrowableAmount(params = { isAPYComputation: false }) {
|
|
30548
31038
|
const vesuAdapters = this.getVesuAdapters();
|
|
30549
31039
|
let netMaxBorrowableAmount = Web3Number.fromWei("0", this.getLSTUnderlyingTokenInfo().decimals);
|
|
30550
31040
|
const maxBorrowables = [];
|
|
30551
|
-
const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
|
|
30552
|
-
const maxInterestRate = lstAPY * 0.8;
|
|
30553
31041
|
for (const vesuAdapter of vesuAdapters) {
|
|
30554
|
-
|
|
30555
|
-
const debtCap = await vesuAdapter.getDebtCap(this.config);
|
|
30556
|
-
maxBorrowables.push({ amount: maxBorrowableAmount.minimum(debtCap), borrowableAsset: vesuAdapter.config.debt });
|
|
31042
|
+
maxBorrowables.push(await this.getMaxBorrowableAmountByVesuAdapter(vesuAdapter, params.isAPYComputation));
|
|
30557
31043
|
}
|
|
30558
31044
|
maxBorrowables.sort((a, b) => b.amount.toNumber() - a.amount.toNumber());
|
|
30559
31045
|
netMaxBorrowableAmount = maxBorrowables.reduce((acc, curr) => acc.plus(curr.amount), Web3Number.fromWei("0", this.getLSTUnderlyingTokenInfo().decimals));
|
|
30560
31046
|
return { netMaxBorrowableAmount, maxBorrowables };
|
|
30561
31047
|
}
|
|
31048
|
+
// recursively, using binary search computes max swappable.
|
|
31049
|
+
// @dev assumes 1 token of from == 1 token of to
|
|
31050
|
+
async getMaxSwappableWithMaxSlippage(fromToken, toToken, maxSlippage, maxAmount) {
|
|
31051
|
+
const output = await findMaxInputWithSlippage({
|
|
31052
|
+
apiGetOutput: async (inputAmount) => {
|
|
31053
|
+
const ekuboQuoter = new EkuboQuoter(this.config);
|
|
31054
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
31055
|
+
const quote = await ekuboQuoter.getQuote(fromToken.address.address, toToken.address.address, new Web3Number(inputAmount.toFixed(9), fromToken.decimals));
|
|
31056
|
+
return Web3Number.fromWei(quote.total_calculated.toString(), toToken.decimals).toNumber();
|
|
31057
|
+
},
|
|
31058
|
+
maxInput: maxAmount.toNumber(),
|
|
31059
|
+
maxSlippagePercent: maxSlippage,
|
|
31060
|
+
tolerance: 1e-3,
|
|
31061
|
+
referenceRate: 1
|
|
31062
|
+
});
|
|
31063
|
+
return new Web3Number(output.optimalInput, fromToken.decimals);
|
|
31064
|
+
}
|
|
31065
|
+
async getMaxBorrowableAmountByVesuAdapter(vesuAdapter, isAPYComputation) {
|
|
31066
|
+
const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
|
|
31067
|
+
const maxInterestRate = lstAPY * 0.8;
|
|
31068
|
+
const maxBorrowableAmount = await vesuAdapter.getMaxBorrowableByInterestRate(this.config, vesuAdapter.config.debt, maxInterestRate);
|
|
31069
|
+
const debtCap = await vesuAdapter.getDebtCap(this.config);
|
|
31070
|
+
const maxBorrowable = maxBorrowableAmount.minimum(debtCap).multipliedBy(0.999);
|
|
31071
|
+
if (vesuAdapter.config.debt.address.eq(this.getLSTUnderlyingTokenInfo().address) || isAPYComputation) {
|
|
31072
|
+
return { amount: maxBorrowable, dexSwappableAmount: maxBorrowable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
|
|
31073
|
+
}
|
|
31074
|
+
try {
|
|
31075
|
+
const maxSwappable = await this.getMaxSwappableWithMaxSlippage(vesuAdapter.config.debt, this.getLSTUnderlyingTokenInfo(), 2e-4, maxBorrowable);
|
|
31076
|
+
return { amount: maxBorrowable.minimum(maxSwappable), dexSwappableAmount: maxSwappable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
|
|
31077
|
+
} catch (error) {
|
|
31078
|
+
logger.warn(`${this.getTag()}: Failed to get max swappable: ${error}`);
|
|
31079
|
+
const maxSwappable = Web3Number.fromWei("0", vesuAdapter.config.debt.decimals);
|
|
31080
|
+
return { amount: maxBorrowable.minimum(maxSwappable), dexSwappableAmount: maxSwappable, maxBorrowableAmount: maxBorrowable, borrowableAsset: vesuAdapter.config.debt };
|
|
31081
|
+
}
|
|
31082
|
+
}
|
|
30562
31083
|
// todo how much to unwind to get back healthy APY zone again
|
|
30563
31084
|
// if net APY < LST APR + 0.5%, we need to unwind to get back to LST APR + 1% atleast or 0 vesu position
|
|
30564
31085
|
// For xSTRK, simply deposit in Vesu if looping is not viable
|
|
@@ -30582,7 +31103,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30582
31103
|
// todo undo this
|
|
30583
31104
|
async netAPY() {
|
|
30584
31105
|
const unusedBalance = await this.getUnusedBalance();
|
|
30585
|
-
const maxNewDeposits = await this.maxNewDeposits();
|
|
31106
|
+
const maxNewDeposits = await this.maxNewDeposits({ isAPYComputation: true });
|
|
30586
31107
|
const lstAPY = await this.getLSTAPR(this.getLSTUnderlyingTokenInfo().address);
|
|
30587
31108
|
if (maxNewDeposits * 1.5 < unusedBalance.amount.toNumber()) {
|
|
30588
31109
|
logger.verbose(`${this.getTag()}::netAPY: unused balance is > max servicable from loan, lstAPY: ${lstAPY}`);
|
|
@@ -30599,8 +31120,8 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30599
31120
|
return output;
|
|
30600
31121
|
}
|
|
30601
31122
|
}
|
|
30602
|
-
async maxNewDeposits() {
|
|
30603
|
-
const maxBorrowableAmounts = await this.getMaxBorrowableAmount();
|
|
31123
|
+
async maxNewDeposits(params = { isAPYComputation: false }) {
|
|
31124
|
+
const maxBorrowableAmounts = await this.getMaxBorrowableAmount(params);
|
|
30604
31125
|
let ltv = void 0;
|
|
30605
31126
|
for (let adapter of this.getVesuAdapters()) {
|
|
30606
31127
|
const maxBorrowableAmount = maxBorrowableAmounts.maxBorrowables.find((b) => b.borrowableAsset.address.eq(adapter.config.debt.address))?.amount;
|
|
@@ -30703,7 +31224,7 @@ var UniversalLstMultiplierStrategy = class _UniversalLstMultiplierStrategy exten
|
|
|
30703
31224
|
const manageCall2 = manage2Info.callConstructor({
|
|
30704
31225
|
delegation: true
|
|
30705
31226
|
});
|
|
30706
|
-
const STEP3_ID = "multiply_vesu" /* MULTIPLY_VESU
|
|
31227
|
+
const STEP3_ID = getVesuLegId("multiply_vesu" /* MULTIPLY_VESU */, vesuAdapter1.config.debt.symbol);
|
|
30707
31228
|
const manage3Info = this.getProofs(STEP3_ID);
|
|
30708
31229
|
const multiplyParams = params.isIncrease ? {
|
|
30709
31230
|
isIncrease: true,
|
|
@@ -30769,6 +31290,7 @@ function VaultDescription(lstSymbol, underlyingSymbol) {
|
|
|
30769
31290
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { style: { fontSize: "14px", lineHeight: "1.5", marginBottom: "16px" }, children: [
|
|
30770
31291
|
"This vault uses Vesu for lending and borrowing. The oracle used by this pool is a ",
|
|
30771
31292
|
highlightTextWithLinks("conversion rate oracle", [{ highlight: "conversion rate oracle", link: "https://docs.pragma.build/starknet/development#conversion-rate" }]),
|
|
31293
|
+
" ",
|
|
30772
31294
|
"which is resilient to liquidity issues and price volatility, hence reducing the risk of liquidation. However, overtime, if left un-monitored, debt can increase enough to trigger a liquidation. But no worries, our continuous monitoring systems look for situations with reduced health factor and balance collateral/debt to bring it back to safe levels. With Troves, you can have a peaceful sleep."
|
|
30773
31295
|
] }),
|
|
30774
31296
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { backgroundColor: "#222", padding: "10px", borderRadius: "8px", marginBottom: "20px", border: "1px solid #444" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { style: { fontSize: "13px", color: "#ccc" }, children: [
|
|
@@ -30779,17 +31301,19 @@ function VaultDescription(lstSymbol, underlyingSymbol) {
|
|
|
30779
31301
|
] }) }),
|
|
30780
31302
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { backgroundColor: "#222", padding: "10px", borderRadius: "8px", marginBottom: "20px", border: "1px solid #444" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { style: { fontSize: "13px", color: "#ccc" }, children: [
|
|
30781
31303
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "Debt limits:" }),
|
|
30782
|
-
" Pools on Vesu have debt caps that are gradually increased over time. Until caps are raised, deposited LSTs remain in the vault, generating a shared net return for all depositors."
|
|
30783
|
-
] }) }),
|
|
30784
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { backgroundColor: "#222", padding: "10px", borderRadius: "8px", marginBottom: "20px", border: "1px solid #444" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { style: { fontSize: "13px", color: "#ccc" }, children: [
|
|
30785
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "APY assumptions:" }),
|
|
30786
|
-
" APY shown is the max possible value given current LST and borrowing rates. True APY will be subject to the actual leverage, based on above point. More insights on exact APY will be added soon."
|
|
31304
|
+
" Pools on Vesu have debt caps that are gradually increased over time. Until caps are raised, deposited LSTs remain in the vault, generating a shared net return for all depositors. There is no additional fee taken by Troves on LST APY, its only on added gain."
|
|
30787
31305
|
] }) })
|
|
30788
31306
|
] });
|
|
30789
31307
|
}
|
|
30790
31308
|
function getDescription2(tokenSymbol, underlyingSymbol) {
|
|
30791
31309
|
return VaultDescription(tokenSymbol, underlyingSymbol);
|
|
30792
31310
|
}
|
|
31311
|
+
function getAvnuManageIDs(baseID, debtTokenSymbol) {
|
|
31312
|
+
return `${baseID}_${debtTokenSymbol.toLowerCase()}`;
|
|
31313
|
+
}
|
|
31314
|
+
function getVesuLegId(baseID, debtTokenSymbol) {
|
|
31315
|
+
return `${baseID}_${debtTokenSymbol.toLowerCase()}`;
|
|
31316
|
+
}
|
|
30793
31317
|
function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
|
|
30794
31318
|
vaultSettings.leafAdapters = [];
|
|
30795
31319
|
const lstToken = Global.getDefaultTokens().find((token) => token.symbol === lstSymbol);
|
|
@@ -30799,7 +31323,7 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
|
|
|
30799
31323
|
collateral: lstToken,
|
|
30800
31324
|
debt: underlyingToken,
|
|
30801
31325
|
vaultAllocator: vaultSettings.vaultAllocator,
|
|
30802
|
-
id: "vesu_leg1" /* VESU_LEG1
|
|
31326
|
+
id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, underlyingToken.symbol)
|
|
30803
31327
|
});
|
|
30804
31328
|
const commonAdapter = new CommonAdapter({
|
|
30805
31329
|
manager: vaultSettings.manager,
|
|
@@ -30808,25 +31332,39 @@ function getLooperSettings2(lstSymbol, underlyingSymbol, vaultSettings, pool1) {
|
|
|
30808
31332
|
vaultAddress: vaultSettings.vaultAddress,
|
|
30809
31333
|
vaultAllocator: vaultSettings.vaultAllocator
|
|
30810
31334
|
});
|
|
30811
|
-
const { isV2, addr: poolAddr } = getVesuSingletonAddress(pool1);
|
|
30812
|
-
const VESU_MULTIPLY = isV2 ? vesuAdapterLST.VESU_MULTIPLY : vesuAdapterLST.VESU_MULTIPLY_V1;
|
|
30813
|
-
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, VESU_MULTIPLY, "multiple_approve" /* MULTIPLE_APPROVE */).bind(commonAdapter));
|
|
30814
|
-
vaultSettings.leafAdapters.push(vesuAdapterLST.getMultiplyAdapter("multiply_vesu" /* MULTIPLY_VESU */).bind(vesuAdapterLST));
|
|
30815
|
-
vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_on" /* SWITCH_DELEGATION_ON */).bind(vesuAdapterLST));
|
|
30816
|
-
vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_off" /* SWITCH_DELEGATION_OFF */).bind(vesuAdapterLST));
|
|
30817
31335
|
vaultSettings.adapters.push(...[{
|
|
30818
|
-
id: "
|
|
31336
|
+
id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, underlyingToken.symbol),
|
|
30819
31337
|
adapter: vesuAdapterLST
|
|
30820
31338
|
}, {
|
|
30821
31339
|
id: "common_adapter" /* COMMON */,
|
|
30822
31340
|
adapter: commonAdapter
|
|
30823
31341
|
}]);
|
|
30824
|
-
|
|
30825
|
-
|
|
30826
|
-
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address,
|
|
30827
|
-
vaultSettings.leafAdapters.push(
|
|
30828
|
-
vaultSettings.leafAdapters.push(
|
|
30829
|
-
vaultSettings.leafAdapters.push(
|
|
31342
|
+
const { isV2, addr: poolAddr } = getVesuSingletonAddress(pool1);
|
|
31343
|
+
const VESU_MULTIPLY = isV2 ? vesuAdapterLST.VESU_MULTIPLY : vesuAdapterLST.VESU_MULTIPLY_V1;
|
|
31344
|
+
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, VESU_MULTIPLY, "multiple_approve" /* MULTIPLE_APPROVE */).bind(commonAdapter));
|
|
31345
|
+
vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_on" /* SWITCH_DELEGATION_ON */).bind(vesuAdapterLST));
|
|
31346
|
+
vaultSettings.leafAdapters.push(vesuAdapterLST.getVesuModifyDelegationAdapter("switch_delegation_off" /* SWITCH_DELEGATION_OFF */).bind(vesuAdapterLST));
|
|
31347
|
+
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, AVNU_EXCHANGE, "avnu_mul_approve_withdr" /* AVNU_MULTIPLY_APPROVE_WITHDRAW */).bind(commonAdapter));
|
|
31348
|
+
for (let borrowableAsset of vaultSettings.borrowable_assets) {
|
|
31349
|
+
const debtAsset = borrowableAsset;
|
|
31350
|
+
const approve_debt_token_id = getAvnuManageIDs("avnu_mul_approve_dep" /* AVNU_MULTIPLY_APPROVE_DEPOSIT */, debtAsset.symbol);
|
|
31351
|
+
const swap_debt_token_id = getAvnuManageIDs("avnu_mul_swap_dep" /* AVNU_MULTIPLY_SWAP_DEPOSIT */, debtAsset.symbol);
|
|
31352
|
+
const swap_lst_token_id = getAvnuManageIDs("avnu_mul_swap_withdr" /* AVNU_MULTIPLY_SWAP_WITHDRAW */, debtAsset.symbol);
|
|
31353
|
+
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(debtAsset.address, AVNU_EXCHANGE, approve_debt_token_id).bind(commonAdapter));
|
|
31354
|
+
vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(debtAsset.address, lstToken.address, swap_debt_token_id, false).bind(commonAdapter));
|
|
31355
|
+
vaultSettings.leafAdapters.push(commonAdapter.getAvnuAdapter(lstToken.address, debtAsset.address, swap_lst_token_id, false).bind(commonAdapter));
|
|
31356
|
+
const vesuAdapter = new VesuAdapter({
|
|
31357
|
+
poolId: pool1,
|
|
31358
|
+
collateral: lstToken,
|
|
31359
|
+
debt: debtAsset,
|
|
31360
|
+
vaultAllocator: vaultSettings.vaultAllocator,
|
|
31361
|
+
id: getVesuLegId("vesu_leg1" /* VESU_LEG1 */, debtAsset.symbol)
|
|
31362
|
+
});
|
|
31363
|
+
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, poolAddr, "approve_token1" /* APPROVE_TOKEN1 */).bind(commonAdapter));
|
|
31364
|
+
vaultSettings.leafAdapters.push(vesuAdapter.getModifyPosition.bind(vesuAdapter));
|
|
31365
|
+
const multiplID = getVesuLegId("multiply_vesu" /* MULTIPLY_VESU */, debtAsset.symbol);
|
|
31366
|
+
vaultSettings.leafAdapters.push(vesuAdapter.getMultiplyAdapter(multiplID).bind(vesuAdapter));
|
|
31367
|
+
}
|
|
30830
31368
|
vaultSettings.leafAdapters.push(commonAdapter.getApproveAdapter(lstToken.address, vaultSettings.vaultAddress, "approve_bring_liquidity" /* APPROVE_BRING_LIQUIDITY */).bind(commonAdapter));
|
|
30831
31369
|
vaultSettings.leafAdapters.push(commonAdapter.getBringLiquidityAdapter("bring_liquidity" /* BRING_LIQUIDITY */).bind(commonAdapter));
|
|
30832
31370
|
vaultSettings.leafAdapters.push(vesuAdapterLST.getDefispringRewardsAdapter("defispring_rewards" /* DEFISPRING_REWARDS */).bind(vesuAdapterLST));
|
|
@@ -30904,7 +31442,8 @@ var hyperxSTRK = {
|
|
|
30904
31442
|
adapters: [],
|
|
30905
31443
|
targetHealthFactor: 1.1,
|
|
30906
31444
|
minHealthFactor: 1.05,
|
|
30907
|
-
borrowable_assets: Global.getDefaultTokens().filter((token) => token.symbol === "STRK")
|
|
31445
|
+
borrowable_assets: Global.getDefaultTokens().filter((token) => token.symbol === "STRK"),
|
|
31446
|
+
underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "STRK")
|
|
30908
31447
|
};
|
|
30909
31448
|
var hyperxWBTC = {
|
|
30910
31449
|
vaultAddress: ContractAddr.from("0x2da9d0f96a46b453f55604313785dc866424240b1c6811d13bef594343db818"),
|
|
@@ -30916,7 +31455,8 @@ var hyperxWBTC = {
|
|
|
30916
31455
|
adapters: [],
|
|
30917
31456
|
targetHealthFactor: 1.1,
|
|
30918
31457
|
minHealthFactor: 1.05,
|
|
30919
|
-
borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
|
|
31458
|
+
borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
|
|
31459
|
+
underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "WBTC")
|
|
30920
31460
|
};
|
|
30921
31461
|
var hyperxtBTC = {
|
|
30922
31462
|
vaultAddress: ContractAddr.from("0x47d5f68477e5637ce0e56436c6b5eee5a354e6828995dae106b11a48679328"),
|
|
@@ -30928,7 +31468,8 @@ var hyperxtBTC = {
|
|
|
30928
31468
|
adapters: [],
|
|
30929
31469
|
targetHealthFactor: 1.1,
|
|
30930
31470
|
minHealthFactor: 1.05,
|
|
30931
|
-
borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
|
|
31471
|
+
borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
|
|
31472
|
+
underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "tBTC")
|
|
30932
31473
|
};
|
|
30933
31474
|
var hyperxsBTC = {
|
|
30934
31475
|
vaultAddress: ContractAddr.from("0x437ef1e7d0f100b2e070b7a65cafec0b2be31b0290776da8b4112f5473d8d9"),
|
|
@@ -30940,7 +31481,8 @@ var hyperxsBTC = {
|
|
|
30940
31481
|
adapters: [],
|
|
30941
31482
|
targetHealthFactor: 1.1,
|
|
30942
31483
|
minHealthFactor: 1.05,
|
|
30943
|
-
borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
|
|
31484
|
+
borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
|
|
31485
|
+
underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "solvBTC")
|
|
30944
31486
|
};
|
|
30945
31487
|
var hyperxLBTC = {
|
|
30946
31488
|
vaultAddress: ContractAddr.from("0x64cf24d4883fe569926419a0569ab34497c6956a1a308fa883257f7486d7030"),
|
|
@@ -30952,7 +31494,8 @@ var hyperxLBTC = {
|
|
|
30952
31494
|
adapters: [],
|
|
30953
31495
|
targetHealthFactor: 1.1,
|
|
30954
31496
|
minHealthFactor: 1.05,
|
|
30955
|
-
borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset))
|
|
31497
|
+
borrowable_assets: borrowableAssets.map((asset) => Global.getDefaultTokens().find((token) => token.symbol === asset)),
|
|
31498
|
+
underlyingToken: Global.getDefaultTokens().find((token) => token.symbol === "LBTC")
|
|
30956
31499
|
};
|
|
30957
31500
|
function getInvestmentSteps(lstSymbol, underlyingSymbol) {
|
|
30958
31501
|
return [
|
|
@@ -30984,7 +31527,7 @@ function getStrategySettings(lstSymbol, underlyingSymbol, addresses, isPreview =
|
|
|
30984
31527
|
faqs: getFAQs2(lstSymbol, underlyingSymbol),
|
|
30985
31528
|
investmentSteps: getInvestmentSteps(lstSymbol, underlyingSymbol),
|
|
30986
31529
|
isPreview,
|
|
30987
|
-
apyMethodology: "Current annualized APY in terms of base asset of the LST"
|
|
31530
|
+
apyMethodology: "Current annualized APY in terms of base asset of the LST. There is no additional fee taken by Troves on LST APY. We charge a 10% performance fee on the additional gain which is already accounted in the APY shown."
|
|
30988
31531
|
};
|
|
30989
31532
|
}
|
|
30990
31533
|
var HyperLSTStrategies = [
|
|
@@ -31655,6 +32198,7 @@ var Deployer = {
|
|
|
31655
32198
|
var deployer_default = Deployer;
|
|
31656
32199
|
// Annotate the CommonJS export names for ESM import in node:
|
|
31657
32200
|
0 && (module.exports = {
|
|
32201
|
+
APYType,
|
|
31658
32202
|
AUMTypes,
|
|
31659
32203
|
AVNU_EXCHANGE,
|
|
31660
32204
|
AVNU_MIDDLEWARE,
|