@strkfarm/sdk 1.0.56 → 1.0.57
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 +260 -83
- package/dist/index.browser.mjs +255 -66
- package/dist/index.d.ts +55 -9
- package/dist/index.js +255 -69
- package/dist/index.mjs +255 -69
- package/package.json +1 -1
- package/src/notifs/telegram.ts +0 -2
- package/src/strategies/base-strategy.ts +3 -23
- package/src/strategies/sensei.ts +13 -6
- package/src/strategies/universal-adapters/baseAdapter.ts +2 -1
- package/src/strategies/universal-adapters/vesu-adapter.ts +80 -10
- package/src/strategies/universal-strategy.ts +183 -31
- package/src/utils/cacheClass.ts +29 -0
- package/src/utils/oz-merkle.ts +0 -9
package/dist/index.js
CHANGED
|
@@ -2066,7 +2066,6 @@ var import_bytes = require("@ericnordelo/strk-merkle-tree/dist/bytes");
|
|
|
2066
2066
|
var import_core = require("@ericnordelo/strk-merkle-tree/dist/core");
|
|
2067
2067
|
var import_hashes = require("@ericnordelo/strk-merkle-tree/dist/hashes");
|
|
2068
2068
|
var import_merkletree = require("@ericnordelo/strk-merkle-tree/dist/merkletree");
|
|
2069
|
-
var import_errors = require("@ericnordelo/strk-merkle-tree/src/utils/errors");
|
|
2070
2069
|
var import_starknet4 = require("starknet");
|
|
2071
2070
|
|
|
2072
2071
|
// ../node_modules/@noble/hashes/esm/_assert.js
|
|
@@ -4124,13 +4123,6 @@ var StandardMerkleTree = class _StandardMerkleTree extends import_merkletree.Mer
|
|
|
4124
4123
|
});
|
|
4125
4124
|
return new _StandardMerkleTree(tree, indexedValues, leafEncoding);
|
|
4126
4125
|
}
|
|
4127
|
-
static load(data) {
|
|
4128
|
-
(0, import_errors.validateArgument)(data.format === "standard-v1", `Unknown format '${data.format}'`);
|
|
4129
|
-
(0, import_errors.validateArgument)(data.leafEncoding !== void 0, "Expected leaf encoding");
|
|
4130
|
-
const tree = new _StandardMerkleTree(data.tree, data.values, data.leafEncoding);
|
|
4131
|
-
tree.validate();
|
|
4132
|
-
return tree;
|
|
4133
|
-
}
|
|
4134
4126
|
static verify(root, leafEncoding, leaf, proof) {
|
|
4135
4127
|
return (0, import_bytes.toHex)(root) === (0, import_core.processProof)((0, import_hashes.standardLeafHash)(leafEncoding, leaf), proof);
|
|
4136
4128
|
}
|
|
@@ -5888,23 +5880,10 @@ var vesu_rebalance_abi_default = [
|
|
|
5888
5880
|
}
|
|
5889
5881
|
];
|
|
5890
5882
|
|
|
5891
|
-
// src/
|
|
5892
|
-
var
|
|
5893
|
-
constructor(
|
|
5883
|
+
// src/utils/cacheClass.ts
|
|
5884
|
+
var CacheClass = class {
|
|
5885
|
+
constructor() {
|
|
5894
5886
|
this.cache = /* @__PURE__ */ new Map();
|
|
5895
|
-
this.config = config;
|
|
5896
|
-
}
|
|
5897
|
-
async getUserTVL(user) {
|
|
5898
|
-
throw new Error("Not implemented");
|
|
5899
|
-
}
|
|
5900
|
-
async getTVL() {
|
|
5901
|
-
throw new Error("Not implemented");
|
|
5902
|
-
}
|
|
5903
|
-
async depositCall(amountInfo, receiver) {
|
|
5904
|
-
throw new Error("Not implemented");
|
|
5905
|
-
}
|
|
5906
|
-
async withdrawCall(amountInfo, receiver, owner) {
|
|
5907
|
-
throw new Error("Not implemented");
|
|
5908
5887
|
}
|
|
5909
5888
|
setCache(key, data, ttl = 6e4) {
|
|
5910
5889
|
const timestamp = Date.now();
|
|
@@ -5925,6 +5904,27 @@ var BaseStrategy = class {
|
|
|
5925
5904
|
}
|
|
5926
5905
|
};
|
|
5927
5906
|
|
|
5907
|
+
// src/strategies/base-strategy.ts
|
|
5908
|
+
var BaseStrategy = class extends CacheClass {
|
|
5909
|
+
constructor(config) {
|
|
5910
|
+
super();
|
|
5911
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
5912
|
+
this.config = config;
|
|
5913
|
+
}
|
|
5914
|
+
async getUserTVL(user) {
|
|
5915
|
+
throw new Error("Not implemented");
|
|
5916
|
+
}
|
|
5917
|
+
async getTVL() {
|
|
5918
|
+
throw new Error("Not implemented");
|
|
5919
|
+
}
|
|
5920
|
+
async depositCall(amountInfo, receiver) {
|
|
5921
|
+
throw new Error("Not implemented");
|
|
5922
|
+
}
|
|
5923
|
+
async withdrawCall(amountInfo, receiver, owner) {
|
|
5924
|
+
throw new Error("Not implemented");
|
|
5925
|
+
}
|
|
5926
|
+
};
|
|
5927
|
+
|
|
5928
5928
|
// src/node/headless.browser.ts
|
|
5929
5929
|
var import_axios5 = __toESM(require("axios"));
|
|
5930
5930
|
async function getAPIUsingHeadlessBrowser(url) {
|
|
@@ -20394,9 +20394,8 @@ var SenseiVault = class extends BaseStrategy {
|
|
|
20394
20394
|
}
|
|
20395
20395
|
async getPositionInfo() {
|
|
20396
20396
|
const CACHE_KEY = "positionInfo";
|
|
20397
|
-
|
|
20398
|
-
|
|
20399
|
-
}
|
|
20397
|
+
const existingCacheData = this.getCache(CACHE_KEY);
|
|
20398
|
+
if (existingCacheData) return existingCacheData;
|
|
20400
20399
|
const resp = await fetch(
|
|
20401
20400
|
`${getTrovesEndpoint()}/vesu/positions?walletAddress=${this.address.address}`
|
|
20402
20401
|
);
|
|
@@ -20440,9 +20439,8 @@ var SenseiVault = class extends BaseStrategy {
|
|
|
20440
20439
|
}
|
|
20441
20440
|
async getSecondaryTokenPriceRelativeToMain(retry = 0) {
|
|
20442
20441
|
const CACHE_KEY = "xSTRKPrice";
|
|
20443
|
-
|
|
20444
|
-
|
|
20445
|
-
}
|
|
20442
|
+
const existingCacheData = this.getCache(CACHE_KEY);
|
|
20443
|
+
if (existingCacheData) return existingCacheData;
|
|
20446
20444
|
const params = {
|
|
20447
20445
|
sellTokenAddress: this.metadata.additionalInfo.secondaryToken.address.address,
|
|
20448
20446
|
buyTokenAddress: this.metadata.additionalInfo.mainToken.address.address,
|
|
@@ -20596,7 +20594,7 @@ function toBigInt(value) {
|
|
|
20596
20594
|
}
|
|
20597
20595
|
|
|
20598
20596
|
// src/strategies/universal-adapters/baseAdapter.ts
|
|
20599
|
-
var BaseAdapter = class {
|
|
20597
|
+
var BaseAdapter = class extends CacheClass {
|
|
20600
20598
|
constructSimpleLeafData(params) {
|
|
20601
20599
|
const { id, target, method, packedArguments } = params;
|
|
20602
20600
|
return {
|
|
@@ -22971,7 +22969,6 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
22971
22969
|
constructor(config) {
|
|
22972
22970
|
super();
|
|
22973
22971
|
this.VESU_SINGLETON = ContractAddr.from("0x000d8d6dfec4d33bfb6895de9f3852143a17c6f92fd2a21da3d6924d34870160");
|
|
22974
|
-
this.cache = {};
|
|
22975
22972
|
this.getModifyPosition = () => {
|
|
22976
22973
|
const positionData = [0n];
|
|
22977
22974
|
const packedArguments = [
|
|
@@ -23000,17 +22997,19 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
23000
22997
|
denomination: this.formatAmountDenominationEnum(params.collateralAmount.denomination),
|
|
23001
22998
|
value: {
|
|
23002
22999
|
abs: import_starknet14.uint256.bnToUint256(params.collateralAmount.value.abs.toWei()),
|
|
23003
|
-
is_negative: params.collateralAmount.value.is_negative
|
|
23000
|
+
is_negative: params.collateralAmount.value.abs.isZero() ? false : params.collateralAmount.value.is_negative
|
|
23004
23001
|
}
|
|
23005
23002
|
};
|
|
23003
|
+
logger.verbose(`VesuAdapter::ConstructingModify::Collateral::${JSON.stringify(_collateral)}`);
|
|
23006
23004
|
const _debt = {
|
|
23007
23005
|
amount_type: this.formatAmountTypeEnum(params.debtAmount.amount_type),
|
|
23008
23006
|
denomination: this.formatAmountDenominationEnum(params.debtAmount.denomination),
|
|
23009
23007
|
value: {
|
|
23010
23008
|
abs: import_starknet14.uint256.bnToUint256(params.debtAmount.value.abs.toWei()),
|
|
23011
|
-
is_negative: params.debtAmount.value.is_negative
|
|
23009
|
+
is_negative: params.debtAmount.value.abs.isZero() ? false : params.debtAmount.value.is_negative
|
|
23012
23010
|
}
|
|
23013
23011
|
};
|
|
23012
|
+
logger.verbose(`VesuAdapter::ConstructingModify::Debt::${JSON.stringify(_debt)}`);
|
|
23014
23013
|
const singletonContract = new import_starknet14.Contract(vesu_singleton_abi_default, this.VESU_SINGLETON.toString(), new import_starknet14.RpcProvider({ nodeUrl: "" }));
|
|
23015
23014
|
const call = singletonContract.populate("modify_position", {
|
|
23016
23015
|
params: {
|
|
@@ -23079,20 +23078,22 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
23079
23078
|
}
|
|
23080
23079
|
async getLTVConfig(config) {
|
|
23081
23080
|
const CACHE_KEY = "ltv_config";
|
|
23082
|
-
|
|
23083
|
-
|
|
23081
|
+
const cacheData = this.getCache(CACHE_KEY);
|
|
23082
|
+
if (cacheData) {
|
|
23083
|
+
return cacheData;
|
|
23084
23084
|
}
|
|
23085
23085
|
const output2 = await this.getVesuSingletonContract(config).call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address]);
|
|
23086
|
-
this.
|
|
23087
|
-
return this.
|
|
23086
|
+
this.setCache(CACHE_KEY, Number(output2.max_ltv) / 1e18, 3e5);
|
|
23087
|
+
return this.getCache(CACHE_KEY);
|
|
23088
23088
|
}
|
|
23089
23089
|
async getPositions(config) {
|
|
23090
23090
|
if (!this.pricer) {
|
|
23091
23091
|
throw new Error("Pricer is not initialized");
|
|
23092
23092
|
}
|
|
23093
23093
|
const CACHE_KEY = "positions";
|
|
23094
|
-
|
|
23095
|
-
|
|
23094
|
+
const cacheData = this.getCache(CACHE_KEY);
|
|
23095
|
+
if (cacheData) {
|
|
23096
|
+
return cacheData;
|
|
23096
23097
|
}
|
|
23097
23098
|
const output2 = await this.getVesuSingletonContract(config).call("position_unsafe", [
|
|
23098
23099
|
this.config.poolId.address,
|
|
@@ -23115,9 +23116,65 @@ var VesuAdapter = class _VesuAdapter extends BaseAdapter {
|
|
|
23115
23116
|
usdValue: debtAmount.multipliedBy(token2Price.price).toNumber(),
|
|
23116
23117
|
remarks: "Debt"
|
|
23117
23118
|
}];
|
|
23118
|
-
this.
|
|
23119
|
+
this.setCache(CACHE_KEY, value, 6e4);
|
|
23120
|
+
return value;
|
|
23121
|
+
}
|
|
23122
|
+
async getCollateralization(config) {
|
|
23123
|
+
if (!this.pricer) {
|
|
23124
|
+
throw new Error("Pricer is not initialized");
|
|
23125
|
+
}
|
|
23126
|
+
const CACHE_KEY = "collateralization";
|
|
23127
|
+
const cacheData = this.getCache(CACHE_KEY);
|
|
23128
|
+
if (cacheData) {
|
|
23129
|
+
return cacheData;
|
|
23130
|
+
}
|
|
23131
|
+
const output2 = await this.getVesuSingletonContract(config).call("check_collateralization_unsafe", [
|
|
23132
|
+
this.config.poolId.address,
|
|
23133
|
+
this.config.collateral.address.address,
|
|
23134
|
+
this.config.debt.address.address,
|
|
23135
|
+
this.config.vaultAllocator.address
|
|
23136
|
+
]);
|
|
23137
|
+
const collateralAmount = Web3Number.fromWei(output2["1"].toString(), 18);
|
|
23138
|
+
const debtAmount = Web3Number.fromWei(output2["2"].toString(), 18);
|
|
23139
|
+
const value = [{
|
|
23140
|
+
token: this.config.collateral,
|
|
23141
|
+
usdValue: collateralAmount.toNumber(),
|
|
23142
|
+
remarks: "Collateral"
|
|
23143
|
+
}, {
|
|
23144
|
+
token: this.config.debt,
|
|
23145
|
+
usdValue: debtAmount.toNumber(),
|
|
23146
|
+
remarks: "Debt"
|
|
23147
|
+
}];
|
|
23148
|
+
this.setCache(CACHE_KEY, value, 6e4);
|
|
23119
23149
|
return value;
|
|
23120
23150
|
}
|
|
23151
|
+
async getAssetPrices() {
|
|
23152
|
+
const collateralizationProm = this.getCollateralization(this.networkConfig);
|
|
23153
|
+
const positionsProm = this.getPositions(this.networkConfig);
|
|
23154
|
+
const ltvProm = this.getLTVConfig(this.networkConfig);
|
|
23155
|
+
const output2 = await Promise.all([collateralizationProm, positionsProm, ltvProm]);
|
|
23156
|
+
const [collateralization, positions, ltv] = output2;
|
|
23157
|
+
const collateralTokenAmount = positions[0].amount;
|
|
23158
|
+
const collateralUSDAmount = collateralization[0].usdValue;
|
|
23159
|
+
const collateralPrice = collateralUSDAmount / collateralTokenAmount.toNumber();
|
|
23160
|
+
const debtTokenAmount = positions[1].amount;
|
|
23161
|
+
const debtUSDAmount = collateralization[1].usdValue;
|
|
23162
|
+
const debtPrice = debtUSDAmount / debtTokenAmount.toNumber();
|
|
23163
|
+
return {
|
|
23164
|
+
collateralTokenAmount,
|
|
23165
|
+
collateralUSDAmount,
|
|
23166
|
+
collateralPrice,
|
|
23167
|
+
debtTokenAmount,
|
|
23168
|
+
debtUSDAmount,
|
|
23169
|
+
debtPrice,
|
|
23170
|
+
ltv
|
|
23171
|
+
};
|
|
23172
|
+
}
|
|
23173
|
+
async getHealthFactor() {
|
|
23174
|
+
const ltv = await this.getLTVConfig(this.networkConfig);
|
|
23175
|
+
const collateralisation = await this.getCollateralization(this.networkConfig);
|
|
23176
|
+
return collateralisation[0].usdValue * ltv / collateralisation[1].usdValue;
|
|
23177
|
+
}
|
|
23121
23178
|
static async getVesuPools(retry = 0) {
|
|
23122
23179
|
const CACHE_KEY = "VESU_POOLS";
|
|
23123
23180
|
const cacheValue = Global.getGlobalCache(CACHE_KEY);
|
|
@@ -25489,19 +25546,32 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
|
|
|
25489
25546
|
const debtAsset1 = pool1.assets.find((a) => a.symbol === vesuAdapter1.config.debt.symbol)?.stats;
|
|
25490
25547
|
const collateralAsset2 = pool2.assets.find((a) => a.symbol === vesuAdapter2.config.collateral.symbol)?.stats;
|
|
25491
25548
|
const debtAsset2 = pool2.assets.find((a) => a.symbol === vesuAdapter2.config.debt.symbol)?.stats;
|
|
25492
|
-
const collateral1APY = Number(collateralAsset1.supplyApy.value) / 1e18
|
|
25549
|
+
const collateral1APY = Number(collateralAsset1.supplyApy.value) / 1e18;
|
|
25493
25550
|
const debt1APY = Number(debtAsset1.borrowApr.value) / 1e18;
|
|
25494
|
-
const collateral2APY = Number(collateralAsset2.supplyApy.value) / 1e18
|
|
25551
|
+
const collateral2APY = Number(collateralAsset2.supplyApy.value) / 1e18;
|
|
25495
25552
|
const debt2APY = Number(debtAsset2.borrowApr.value) / 1e18;
|
|
25496
|
-
const apys = [collateral1APY, debt1APY, collateral2APY, debt2APY];
|
|
25497
25553
|
const positions = await this.getVaultPositions();
|
|
25498
|
-
|
|
25499
|
-
const
|
|
25500
|
-
|
|
25501
|
-
|
|
25502
|
-
const
|
|
25503
|
-
const
|
|
25504
|
-
|
|
25554
|
+
const weights = positions.map((p, index) => p.usdValue * (index % 2 == 0 ? 1 : -1));
|
|
25555
|
+
const baseAPYs = [collateral1APY, debt1APY, collateral2APY, debt2APY];
|
|
25556
|
+
assert(positions.length == baseAPYs.length, "Positions and APYs length mismatch");
|
|
25557
|
+
const rewardAPYs = [Number(collateralAsset1.defiSpringSupplyApr.value) / 1e18, 0, Number(collateralAsset2.defiSpringSupplyApr.value) / 1e18, 0];
|
|
25558
|
+
const baseAPY = this.computeAPY(baseAPYs, weights);
|
|
25559
|
+
const rewardAPY = this.computeAPY(rewardAPYs, weights);
|
|
25560
|
+
const apys = [...baseAPYs, ...rewardAPYs];
|
|
25561
|
+
const netAPY = baseAPY + rewardAPY;
|
|
25562
|
+
return { net: netAPY, splits: [{
|
|
25563
|
+
apy: baseAPY,
|
|
25564
|
+
id: "base"
|
|
25565
|
+
}, {
|
|
25566
|
+
apy: rewardAPY,
|
|
25567
|
+
id: "defispring"
|
|
25568
|
+
}] };
|
|
25569
|
+
}
|
|
25570
|
+
computeAPY(apys, weights) {
|
|
25571
|
+
assert(apys.length === weights.length, "APYs and weights length mismatch");
|
|
25572
|
+
const weightedSum = apys.reduce((acc, apy, i) => acc + apy * weights[i], 0);
|
|
25573
|
+
const totalWeight = weights.reduce((acc, weight) => acc + weight, 0);
|
|
25574
|
+
return weightedSum / totalWeight;
|
|
25505
25575
|
}
|
|
25506
25576
|
/**
|
|
25507
25577
|
* Calculates the total TVL of the strategy.
|
|
@@ -25524,22 +25594,48 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
|
|
|
25524
25594
|
};
|
|
25525
25595
|
}
|
|
25526
25596
|
async getAUM() {
|
|
25597
|
+
const currentAUM = await this.contract.call("aum", []);
|
|
25598
|
+
const lastReportTime = await this.contract.call("last_report_timestamp", []);
|
|
25599
|
+
const token1Price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
|
|
25527
25600
|
const [vesuAdapter1, vesuAdapter2] = this.getVesuAdapters();
|
|
25528
25601
|
const leg1AUM = await vesuAdapter1.getPositions(this.config);
|
|
25529
25602
|
const leg2AUM = await vesuAdapter2.getPositions(this.config);
|
|
25530
|
-
const token1Price = await this.pricer.getPrice(vesuAdapter1.config.collateral.symbol);
|
|
25531
25603
|
const aumToken = leg1AUM[0].amount.plus(leg2AUM[0].usdValue / token1Price.price).minus(leg1AUM[1].usdValue / token1Price.price).minus(leg2AUM[1].amount);
|
|
25532
|
-
|
|
25604
|
+
logger.verbose(`${this.getTag()} Actual AUM: ${aumToken}`);
|
|
25605
|
+
const netAPY = await this.netAPY();
|
|
25606
|
+
const defispringAPY = netAPY.splits.find((s) => s.id === "defispring")?.apy || 0;
|
|
25607
|
+
if (!defispringAPY) throw new Error("DefiSpring APY not found");
|
|
25608
|
+
const timeDiff = Math.round(Date.now() / 1e3) - Number(lastReportTime);
|
|
25609
|
+
const growthRate = timeDiff * defispringAPY / (365 * 24 * 60 * 60);
|
|
25610
|
+
const prevAum = Web3Number.fromWei(currentAUM.toString(), this.asset().decimals);
|
|
25611
|
+
const rewardAssets = prevAum.multipliedBy(growthRate);
|
|
25612
|
+
logger.verbose(`${this.getTag()} DefiSpring AUM time difference: ${timeDiff}`);
|
|
25613
|
+
logger.verbose(`${this.getTag()} Current AUM: ${currentAUM}`);
|
|
25614
|
+
logger.verbose(`${this.getTag()} Net APY: ${JSON.stringify(netAPY)}`);
|
|
25615
|
+
logger.verbose(`${this.getTag()} rewards AUM: ${rewardAssets}`);
|
|
25616
|
+
const newAUM = aumToken.plus(rewardAssets);
|
|
25617
|
+
logger.verbose(`${this.getTag()} New AUM: ${newAUM}`);
|
|
25618
|
+
const net = {
|
|
25533
25619
|
tokenInfo: this.asset(),
|
|
25534
|
-
amount:
|
|
25535
|
-
usdValue:
|
|
25620
|
+
amount: newAUM,
|
|
25621
|
+
usdValue: newAUM.multipliedBy(token1Price.price).toNumber()
|
|
25536
25622
|
};
|
|
25623
|
+
const splits = [{
|
|
25624
|
+
id: "finalised",
|
|
25625
|
+
aum: aumToken
|
|
25626
|
+
}, {
|
|
25627
|
+
id: "defispring",
|
|
25628
|
+
aum: rewardAssets
|
|
25629
|
+
}];
|
|
25630
|
+
return { net, splits, prevAum };
|
|
25537
25631
|
}
|
|
25538
25632
|
getVesuAdapters() {
|
|
25539
25633
|
const vesuAdapter1 = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
|
|
25540
25634
|
const vesuAdapter2 = this.getAdapter("vesu_leg2_adapter" /* VESU_LEG2 */);
|
|
25541
25635
|
vesuAdapter1.pricer = this.pricer;
|
|
25542
25636
|
vesuAdapter2.pricer = this.pricer;
|
|
25637
|
+
vesuAdapter1.networkConfig = this.config;
|
|
25638
|
+
vesuAdapter2.networkConfig = this.config;
|
|
25543
25639
|
return [vesuAdapter1, vesuAdapter2];
|
|
25544
25640
|
}
|
|
25545
25641
|
async getVaultPositions() {
|
|
@@ -25581,12 +25677,14 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
|
|
|
25581
25677
|
}));
|
|
25582
25678
|
const output2 = [{
|
|
25583
25679
|
proofs: manage5Info.proofs,
|
|
25584
|
-
manageCall: manageCall5
|
|
25680
|
+
manageCall: manageCall5,
|
|
25681
|
+
step: STEP2_ID
|
|
25585
25682
|
}];
|
|
25586
25683
|
if (approveAmount.gt(0)) {
|
|
25587
25684
|
output2.unshift({
|
|
25588
25685
|
proofs: manage4Info.proofs,
|
|
25589
|
-
manageCall: manageCall4
|
|
25686
|
+
manageCall: manageCall4,
|
|
25687
|
+
step: STEP1_ID
|
|
25590
25688
|
});
|
|
25591
25689
|
}
|
|
25592
25690
|
return output2;
|
|
@@ -25594,9 +25692,96 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
|
|
|
25594
25692
|
getTag() {
|
|
25595
25693
|
return `${_UniversalStrategy.name}:${this.metadata.name}`;
|
|
25596
25694
|
}
|
|
25695
|
+
async getVesuHealthFactors() {
|
|
25696
|
+
return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor()));
|
|
25697
|
+
}
|
|
25698
|
+
async computeRebalanceConditionAndReturnCalls() {
|
|
25699
|
+
const vesuAdapters = this.getVesuAdapters();
|
|
25700
|
+
const healthFactors = await this.getVesuHealthFactors();
|
|
25701
|
+
const leg1HealthFactor = healthFactors[0];
|
|
25702
|
+
const leg2HealthFactor = healthFactors[1];
|
|
25703
|
+
logger.verbose(`${this.getTag()}: HealthFactorLeg1: ${leg1HealthFactor}`);
|
|
25704
|
+
logger.verbose(`${this.getTag()}: HealthFactorLeg2: ${leg2HealthFactor}`);
|
|
25705
|
+
const minHf = this.metadata.additionalInfo.minHealthFactor;
|
|
25706
|
+
const isRebalanceNeeded1 = leg1HealthFactor < minHf;
|
|
25707
|
+
const isRebalanceNeeded2 = leg2HealthFactor < minHf;
|
|
25708
|
+
if (!isRebalanceNeeded1 && !isRebalanceNeeded2) {
|
|
25709
|
+
return [];
|
|
25710
|
+
}
|
|
25711
|
+
if (isRebalanceNeeded1) {
|
|
25712
|
+
const amount = await this.getLegRebalanceAmount(vesuAdapters[0], leg1HealthFactor, false);
|
|
25713
|
+
const leg2HF = await this.getNewHealthFactor(vesuAdapters[1], amount, true);
|
|
25714
|
+
assert(leg2HF > minHf, `Rebalance Leg1 failed: Leg2 HF after rebalance would be too low: ${leg2HF}`);
|
|
25715
|
+
return [await this.getRebalanceCall({
|
|
25716
|
+
isLeg1toLeg2: false,
|
|
25717
|
+
amount
|
|
25718
|
+
})];
|
|
25719
|
+
} else {
|
|
25720
|
+
const amount = await this.getLegRebalanceAmount(vesuAdapters[1], leg2HealthFactor, true);
|
|
25721
|
+
const leg1HF = await this.getNewHealthFactor(vesuAdapters[0], amount, false);
|
|
25722
|
+
assert(leg1HF > minHf, `Rebalance Leg2 failed: Leg1 HF after rebalance would be too low: ${leg1HF}`);
|
|
25723
|
+
return [await this.getRebalanceCall({
|
|
25724
|
+
isLeg1toLeg2: true,
|
|
25725
|
+
amount
|
|
25726
|
+
})];
|
|
25727
|
+
}
|
|
25728
|
+
}
|
|
25729
|
+
async getNewHealthFactor(vesuAdapter, newAmount, isWithdraw) {
|
|
25730
|
+
const {
|
|
25731
|
+
collateralTokenAmount,
|
|
25732
|
+
collateralUSDAmount,
|
|
25733
|
+
collateralPrice,
|
|
25734
|
+
debtTokenAmount,
|
|
25735
|
+
debtUSDAmount,
|
|
25736
|
+
debtPrice,
|
|
25737
|
+
ltv
|
|
25738
|
+
} = await vesuAdapter.getAssetPrices();
|
|
25739
|
+
if (isWithdraw) {
|
|
25740
|
+
const newHF = (collateralTokenAmount.toNumber() - newAmount.toNumber()) * collateralPrice * ltv / debtUSDAmount;
|
|
25741
|
+
logger.verbose(`getNewHealthFactor:: HF: ${newHF}, amoutn: ${newAmount.toNumber()}, isDeposit`);
|
|
25742
|
+
return newHF;
|
|
25743
|
+
} else {
|
|
25744
|
+
const newHF = collateralUSDAmount * ltv / ((debtTokenAmount.toNumber() + newAmount.toNumber()) * debtPrice);
|
|
25745
|
+
logger.verbose(`getNewHealthFactor:: HF: ${newHF}, amoutn: ${newAmount.toNumber()}, isRepay`);
|
|
25746
|
+
return newHF;
|
|
25747
|
+
}
|
|
25748
|
+
}
|
|
25749
|
+
/**
|
|
25750
|
+
*
|
|
25751
|
+
* @param vesuAdapter
|
|
25752
|
+
* @param currentHf
|
|
25753
|
+
* @param isDeposit if true, attempt by adding collateral, else by repaying
|
|
25754
|
+
* @returns
|
|
25755
|
+
*/
|
|
25756
|
+
async getLegRebalanceAmount(vesuAdapter, currentHf, isDeposit) {
|
|
25757
|
+
const {
|
|
25758
|
+
collateralTokenAmount,
|
|
25759
|
+
collateralUSDAmount,
|
|
25760
|
+
collateralPrice,
|
|
25761
|
+
debtTokenAmount,
|
|
25762
|
+
debtUSDAmount,
|
|
25763
|
+
debtPrice,
|
|
25764
|
+
ltv
|
|
25765
|
+
} = await vesuAdapter.getAssetPrices();
|
|
25766
|
+
if (debtTokenAmount.isZero()) {
|
|
25767
|
+
return Web3Number.fromWei(0, 0);
|
|
25768
|
+
}
|
|
25769
|
+
assert(collateralPrice > 0 && debtPrice > 0, "getRebalanceAmount: Invalid price");
|
|
25770
|
+
const targetHF = this.metadata.additionalInfo.targetHealthFactor;
|
|
25771
|
+
if (currentHf > targetHF - 0.01)
|
|
25772
|
+
throw new Error("getLegRebalanceAmount: Current health factor is healthy");
|
|
25773
|
+
if (isDeposit) {
|
|
25774
|
+
const newAmount = targetHF * debtUSDAmount / (collateralPrice * ltv) - collateralTokenAmount.toNumber();
|
|
25775
|
+
logger.verbose(`${this.getTag()}:: getLegRebalanceAmount: addCollateral, currentHf: ${currentHf}, targetHF: ${targetHF}, collAmount: ${collateralTokenAmount.toString()}, collUSD: ${collateralUSDAmount}, collPrice: ${collateralPrice}, debtAmount: ${debtTokenAmount.toString()}, debtUSD: ${debtUSDAmount}, debtPrice: ${debtPrice}, ltv: ${ltv}, newAmount: ${newAmount}`);
|
|
25776
|
+
return new Web3Number(newAmount.toFixed(8), collateralTokenAmount.decimals);
|
|
25777
|
+
} else {
|
|
25778
|
+
const newAmount = debtTokenAmount.toNumber() - collateralUSDAmount * ltv / (targetHF * debtPrice);
|
|
25779
|
+
logger.verbose(`${this.getTag()}:: getLegRebalanceAmount: repayDebt, currentHf: ${currentHf}, targetHF: ${targetHF}, collAmount: ${collateralTokenAmount.toString()}, collUSD: ${collateralUSDAmount}, collPrice: ${collateralPrice}, debtAmount: ${debtTokenAmount.toString()}, debtUSD: ${debtUSDAmount}, debtPrice: ${debtPrice}, ltv: ${ltv}, newAmount: ${newAmount}`);
|
|
25780
|
+
return new Web3Number(newAmount.toFixed(8), debtTokenAmount.decimals);
|
|
25781
|
+
}
|
|
25782
|
+
}
|
|
25597
25783
|
async getVesuMultiplyCall(params) {
|
|
25598
|
-
const vesuAdapter1 = this.
|
|
25599
|
-
const vesuAdapter2 = this.getAdapter("vesu_leg2_adapter" /* VESU_LEG2 */);
|
|
25784
|
+
const [vesuAdapter1, vesuAdapter2] = this.getVesuAdapters();
|
|
25600
25785
|
const leg1LTV = await vesuAdapter1.getLTVConfig(this.config);
|
|
25601
25786
|
const leg2LTV = await vesuAdapter2.getLTVConfig(this.config);
|
|
25602
25787
|
logger.verbose(`${this.getTag()}: LTVLeg1: ${leg1LTV}`);
|
|
@@ -25605,7 +25790,7 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
|
|
|
25605
25790
|
const token2Price = await this.pricer.getPrice(vesuAdapter2.config.collateral.symbol);
|
|
25606
25791
|
logger.verbose(`${this.getTag()}: Price${vesuAdapter1.config.collateral.symbol}: ${token1Price.price}`);
|
|
25607
25792
|
logger.verbose(`${this.getTag()}: Price${vesuAdapter2.config.collateral.symbol}: ${token2Price.price}`);
|
|
25608
|
-
const TARGET_HF =
|
|
25793
|
+
const TARGET_HF = this.metadata.additionalInfo.targetHealthFactor;
|
|
25609
25794
|
const k1 = token1Price.price * leg1LTV / token2Price.price / TARGET_HF;
|
|
25610
25795
|
const k2 = token1Price.price * TARGET_HF / token2Price.price / leg2LTV;
|
|
25611
25796
|
const borrow2Amount = new Web3Number(
|
|
@@ -25663,14 +25848,14 @@ var UniversalStrategy = class _UniversalStrategy extends BaseStrategy {
|
|
|
25663
25848
|
});
|
|
25664
25849
|
if (params.isLeg1toLeg2) {
|
|
25665
25850
|
const manageCall = this.getManageCall([
|
|
25666
|
-
|
|
25667
|
-
|
|
25851
|
+
...callSet1.map((i) => i.step),
|
|
25852
|
+
...callSet2.map((i) => i.step)
|
|
25668
25853
|
], [...callSet1.map((i) => i.manageCall), ...callSet2.map((i) => i.manageCall)]);
|
|
25669
25854
|
return manageCall;
|
|
25670
25855
|
} else {
|
|
25671
25856
|
const manageCall = this.getManageCall([
|
|
25672
|
-
|
|
25673
|
-
|
|
25857
|
+
...callSet2.map((i) => i.step),
|
|
25858
|
+
...callSet1.map((i) => i.step)
|
|
25674
25859
|
], [...callSet2.map((i) => i.manageCall), ...callSet1.map((i) => i.manageCall)]);
|
|
25675
25860
|
return manageCall;
|
|
25676
25861
|
}
|
|
@@ -25738,14 +25923,18 @@ var usdcVaultSettings = {
|
|
|
25738
25923
|
vaultAllocator: ContractAddr.from("0x228cca1005d3f2b55cbaba27cb291dacf1b9a92d1d6b1638195fbd3d0c1e3ba"),
|
|
25739
25924
|
redeemRequestNFT: ContractAddr.from("0x906d03590010868cbf7590ad47043959d7af8e782089a605d9b22567b64fda"),
|
|
25740
25925
|
leafAdapters: [],
|
|
25741
|
-
adapters: []
|
|
25926
|
+
adapters: [],
|
|
25927
|
+
targetHealthFactor: 1.3,
|
|
25928
|
+
minHealthFactor: 1.25
|
|
25742
25929
|
};
|
|
25743
25930
|
var wbtcVaultSettings = {
|
|
25744
25931
|
manager: ContractAddr.from("0xef8a664ffcfe46a6af550766d27c28937bf1b77fb4ab54d8553e92bca5ba34"),
|
|
25745
25932
|
vaultAllocator: ContractAddr.from("0x1e01c25f0d9494570226ad28a7fa856c0640505e809c366a9fab4903320e735"),
|
|
25746
25933
|
redeemRequestNFT: ContractAddr.from("0x4fec59a12f8424281c1e65a80b5de51b4e754625c60cddfcd00d46941ec37b2"),
|
|
25747
25934
|
leafAdapters: [],
|
|
25748
|
-
adapters: []
|
|
25935
|
+
adapters: [],
|
|
25936
|
+
targetHealthFactor: 1.3,
|
|
25937
|
+
minHealthFactor: 1.25
|
|
25749
25938
|
};
|
|
25750
25939
|
var UniversalStrategies = [
|
|
25751
25940
|
{
|
|
@@ -25795,13 +25984,10 @@ var TelegramNotif = class {
|
|
|
25795
25984
|
this.subscribers = [
|
|
25796
25985
|
// '6820228303',
|
|
25797
25986
|
"1505578076",
|
|
25798
|
-
// '5434736198', // maaza
|
|
25799
25987
|
"1356705582",
|
|
25800
25988
|
// langs
|
|
25801
25989
|
"1388729514",
|
|
25802
25990
|
// hwashere
|
|
25803
|
-
"6020162572",
|
|
25804
|
-
//minato
|
|
25805
25991
|
"985902592"
|
|
25806
25992
|
];
|
|
25807
25993
|
this.bot = new import_node_telegram_bot_api.default(token, { polling: shouldPoll });
|