@strkfarm/sdk 1.0.56 → 1.0.58
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 +265 -84
- package/dist/index.browser.mjs +260 -67
- package/dist/index.d.ts +56 -9
- package/dist/index.js +261 -71
- package/dist/index.mjs +261 -71
- package/package.json +1 -1
- package/src/node/deployer.ts +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 +190 -31
- package/src/utils/cacheClass.ts +29 -0
- package/src/utils/oz-merkle.ts +0 -9
|
@@ -27510,19 +27510,19 @@ ${r2}}` : "}", l2;
|
|
|
27510
27510
|
}
|
|
27511
27511
|
};
|
|
27512
27512
|
exports.InvariantError = InvariantError;
|
|
27513
|
-
var
|
|
27513
|
+
var InvalidArgumentError = class extends Error {
|
|
27514
27514
|
constructor(message) {
|
|
27515
27515
|
super(message);
|
|
27516
27516
|
this.name = "InvalidArgumentError";
|
|
27517
27517
|
}
|
|
27518
27518
|
};
|
|
27519
|
-
exports.InvalidArgumentError =
|
|
27520
|
-
function
|
|
27519
|
+
exports.InvalidArgumentError = InvalidArgumentError;
|
|
27520
|
+
function validateArgument(condition, message) {
|
|
27521
27521
|
if (!condition) {
|
|
27522
|
-
throw new
|
|
27522
|
+
throw new InvalidArgumentError(message);
|
|
27523
27523
|
}
|
|
27524
27524
|
}
|
|
27525
|
-
exports.validateArgument =
|
|
27525
|
+
exports.validateArgument = validateArgument;
|
|
27526
27526
|
function invariant(condition, message) {
|
|
27527
27527
|
if (!condition) {
|
|
27528
27528
|
throw new InvariantError(message);
|
|
@@ -49908,19 +49908,6 @@ ${indent}}` : "}";
|
|
|
49908
49908
|
var import_hashes = __toESM(require_hashes());
|
|
49909
49909
|
var import_merkletree = __toESM(require_merkletree());
|
|
49910
49910
|
|
|
49911
|
-
// node_modules/.pnpm/@ericnordelo+strk-merkle-tree@1.0.0/node_modules/@ericnordelo/strk-merkle-tree/src/utils/errors.ts
|
|
49912
|
-
var InvalidArgumentError = class extends Error {
|
|
49913
|
-
constructor(message) {
|
|
49914
|
-
super(message);
|
|
49915
|
-
this.name = "InvalidArgumentError";
|
|
49916
|
-
}
|
|
49917
|
-
};
|
|
49918
|
-
function validateArgument(condition, message) {
|
|
49919
|
-
if (!condition) {
|
|
49920
|
-
throw new InvalidArgumentError(message);
|
|
49921
|
-
}
|
|
49922
|
-
}
|
|
49923
|
-
|
|
49924
49911
|
// ../node_modules/@noble/hashes/esm/_assert.js
|
|
49925
49912
|
function number3(n) {
|
|
49926
49913
|
if (!Number.isSafeInteger(n) || n < 0)
|
|
@@ -51975,13 +51962,6 @@ ${indent}}` : "}";
|
|
|
51975
51962
|
});
|
|
51976
51963
|
return new _StandardMerkleTree(tree, indexedValues, leafEncoding);
|
|
51977
51964
|
}
|
|
51978
|
-
static load(data) {
|
|
51979
|
-
validateArgument(data.format === "standard-v1", `Unknown format '${data.format}'`);
|
|
51980
|
-
validateArgument(data.leafEncoding !== void 0, "Expected leaf encoding");
|
|
51981
|
-
const tree = new _StandardMerkleTree(data.tree, data.values, data.leafEncoding);
|
|
51982
|
-
tree.validate();
|
|
51983
|
-
return tree;
|
|
51984
|
-
}
|
|
51985
51965
|
static verify(root, leafEncoding, leaf, proof) {
|
|
51986
51966
|
return (0, import_bytes.toHex)(root) === (0, import_core.processProof)((0, import_hashes.standardLeafHash)(leafEncoding, leaf), proof);
|
|
51987
51967
|
}
|
|
@@ -53734,23 +53714,10 @@ ${indent}}` : "}";
|
|
|
53734
53714
|
}
|
|
53735
53715
|
];
|
|
53736
53716
|
|
|
53737
|
-
// src/
|
|
53738
|
-
var
|
|
53739
|
-
constructor(
|
|
53717
|
+
// src/utils/cacheClass.ts
|
|
53718
|
+
var CacheClass = class {
|
|
53719
|
+
constructor() {
|
|
53740
53720
|
this.cache = /* @__PURE__ */ new Map();
|
|
53741
|
-
this.config = config2;
|
|
53742
|
-
}
|
|
53743
|
-
async getUserTVL(user) {
|
|
53744
|
-
throw new Error("Not implemented");
|
|
53745
|
-
}
|
|
53746
|
-
async getTVL() {
|
|
53747
|
-
throw new Error("Not implemented");
|
|
53748
|
-
}
|
|
53749
|
-
async depositCall(amountInfo, receiver) {
|
|
53750
|
-
throw new Error("Not implemented");
|
|
53751
|
-
}
|
|
53752
|
-
async withdrawCall(amountInfo, receiver, owner) {
|
|
53753
|
-
throw new Error("Not implemented");
|
|
53754
53721
|
}
|
|
53755
53722
|
setCache(key, data, ttl = 6e4) {
|
|
53756
53723
|
const timestamp = Date.now();
|
|
@@ -53771,6 +53738,27 @@ ${indent}}` : "}";
|
|
|
53771
53738
|
}
|
|
53772
53739
|
};
|
|
53773
53740
|
|
|
53741
|
+
// src/strategies/base-strategy.ts
|
|
53742
|
+
var BaseStrategy = class extends CacheClass {
|
|
53743
|
+
constructor(config2) {
|
|
53744
|
+
super();
|
|
53745
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
53746
|
+
this.config = config2;
|
|
53747
|
+
}
|
|
53748
|
+
async getUserTVL(user) {
|
|
53749
|
+
throw new Error("Not implemented");
|
|
53750
|
+
}
|
|
53751
|
+
async getTVL() {
|
|
53752
|
+
throw new Error("Not implemented");
|
|
53753
|
+
}
|
|
53754
|
+
async depositCall(amountInfo, receiver) {
|
|
53755
|
+
throw new Error("Not implemented");
|
|
53756
|
+
}
|
|
53757
|
+
async withdrawCall(amountInfo, receiver, owner) {
|
|
53758
|
+
throw new Error("Not implemented");
|
|
53759
|
+
}
|
|
53760
|
+
};
|
|
53761
|
+
|
|
53774
53762
|
// src/node/headless.browser.ts
|
|
53775
53763
|
async function getAPIUsingHeadlessBrowser(url) {
|
|
53776
53764
|
const res = await axios_default.get(url);
|
|
@@ -68232,9 +68220,8 @@ ${indent}}` : "}";
|
|
|
68232
68220
|
}
|
|
68233
68221
|
async getPositionInfo() {
|
|
68234
68222
|
const CACHE_KEY = "positionInfo";
|
|
68235
|
-
|
|
68236
|
-
|
|
68237
|
-
}
|
|
68223
|
+
const existingCacheData = this.getCache(CACHE_KEY);
|
|
68224
|
+
if (existingCacheData) return existingCacheData;
|
|
68238
68225
|
const resp = await fetch(
|
|
68239
68226
|
`${getTrovesEndpoint()}/vesu/positions?walletAddress=${this.address.address}`
|
|
68240
68227
|
);
|
|
@@ -68278,9 +68265,8 @@ ${indent}}` : "}";
|
|
|
68278
68265
|
}
|
|
68279
68266
|
async getSecondaryTokenPriceRelativeToMain(retry = 0) {
|
|
68280
68267
|
const CACHE_KEY = "xSTRKPrice";
|
|
68281
|
-
|
|
68282
|
-
|
|
68283
|
-
}
|
|
68268
|
+
const existingCacheData = this.getCache(CACHE_KEY);
|
|
68269
|
+
if (existingCacheData) return existingCacheData;
|
|
68284
68270
|
const params = {
|
|
68285
68271
|
sellTokenAddress: this.metadata.additionalInfo.secondaryToken.address.address,
|
|
68286
68272
|
buyTokenAddress: this.metadata.additionalInfo.mainToken.address.address,
|
|
@@ -68431,7 +68417,7 @@ ${indent}}` : "}";
|
|
|
68431
68417
|
}
|
|
68432
68418
|
|
|
68433
68419
|
// src/strategies/universal-adapters/baseAdapter.ts
|
|
68434
|
-
var BaseAdapter = class {
|
|
68420
|
+
var BaseAdapter = class extends CacheClass {
|
|
68435
68421
|
constructSimpleLeafData(params) {
|
|
68436
68422
|
const { id, target, method, packedArguments } = params;
|
|
68437
68423
|
return {
|
|
@@ -70802,7 +70788,6 @@ ${indent}}` : "}";
|
|
|
70802
70788
|
constructor(config2) {
|
|
70803
70789
|
super();
|
|
70804
70790
|
this.VESU_SINGLETON = ContractAddr.from("0x000d8d6dfec4d33bfb6895de9f3852143a17c6f92fd2a21da3d6924d34870160");
|
|
70805
|
-
this.cache = {};
|
|
70806
70791
|
this.getModifyPosition = () => {
|
|
70807
70792
|
const positionData = [0n];
|
|
70808
70793
|
const packedArguments = [
|
|
@@ -70831,17 +70816,19 @@ ${indent}}` : "}";
|
|
|
70831
70816
|
denomination: this.formatAmountDenominationEnum(params.collateralAmount.denomination),
|
|
70832
70817
|
value: {
|
|
70833
70818
|
abs: uint256_exports.bnToUint256(params.collateralAmount.value.abs.toWei()),
|
|
70834
|
-
is_negative: params.collateralAmount.value.is_negative
|
|
70819
|
+
is_negative: params.collateralAmount.value.abs.isZero() ? false : params.collateralAmount.value.is_negative
|
|
70835
70820
|
}
|
|
70836
70821
|
};
|
|
70822
|
+
logger.verbose(`VesuAdapter::ConstructingModify::Collateral::${JSON.stringify(_collateral)}`);
|
|
70837
70823
|
const _debt = {
|
|
70838
70824
|
amount_type: this.formatAmountTypeEnum(params.debtAmount.amount_type),
|
|
70839
70825
|
denomination: this.formatAmountDenominationEnum(params.debtAmount.denomination),
|
|
70840
70826
|
value: {
|
|
70841
70827
|
abs: uint256_exports.bnToUint256(params.debtAmount.value.abs.toWei()),
|
|
70842
|
-
is_negative: params.debtAmount.value.is_negative
|
|
70828
|
+
is_negative: params.debtAmount.value.abs.isZero() ? false : params.debtAmount.value.is_negative
|
|
70843
70829
|
}
|
|
70844
70830
|
};
|
|
70831
|
+
logger.verbose(`VesuAdapter::ConstructingModify::Debt::${JSON.stringify(_debt)}`);
|
|
70845
70832
|
const singletonContract = new Contract(vesu_singleton_abi_default, this.VESU_SINGLETON.toString(), new RpcProvider2({ nodeUrl: "" }));
|
|
70846
70833
|
const call = singletonContract.populate("modify_position", {
|
|
70847
70834
|
params: {
|
|
@@ -70910,20 +70897,22 @@ ${indent}}` : "}";
|
|
|
70910
70897
|
}
|
|
70911
70898
|
async getLTVConfig(config2) {
|
|
70912
70899
|
const CACHE_KEY = "ltv_config";
|
|
70913
|
-
|
|
70914
|
-
|
|
70900
|
+
const cacheData = this.getCache(CACHE_KEY);
|
|
70901
|
+
if (cacheData) {
|
|
70902
|
+
return cacheData;
|
|
70915
70903
|
}
|
|
70916
70904
|
const output4 = await this.getVesuSingletonContract(config2).call("ltv_config", [this.config.poolId.address, this.config.collateral.address.address, this.config.debt.address.address]);
|
|
70917
|
-
this.
|
|
70918
|
-
return this.
|
|
70905
|
+
this.setCache(CACHE_KEY, Number(output4.max_ltv) / 1e18, 3e5);
|
|
70906
|
+
return this.getCache(CACHE_KEY);
|
|
70919
70907
|
}
|
|
70920
70908
|
async getPositions(config2) {
|
|
70921
70909
|
if (!this.pricer) {
|
|
70922
70910
|
throw new Error("Pricer is not initialized");
|
|
70923
70911
|
}
|
|
70924
70912
|
const CACHE_KEY = "positions";
|
|
70925
|
-
|
|
70926
|
-
|
|
70913
|
+
const cacheData = this.getCache(CACHE_KEY);
|
|
70914
|
+
if (cacheData) {
|
|
70915
|
+
return cacheData;
|
|
70927
70916
|
}
|
|
70928
70917
|
const output4 = await this.getVesuSingletonContract(config2).call("position_unsafe", [
|
|
70929
70918
|
this.config.poolId.address,
|
|
@@ -70946,9 +70935,65 @@ ${indent}}` : "}";
|
|
|
70946
70935
|
usdValue: debtAmount.multipliedBy(token2Price.price).toNumber(),
|
|
70947
70936
|
remarks: "Debt"
|
|
70948
70937
|
}];
|
|
70949
|
-
this.
|
|
70938
|
+
this.setCache(CACHE_KEY, value, 6e4);
|
|
70950
70939
|
return value;
|
|
70951
70940
|
}
|
|
70941
|
+
async getCollateralization(config2) {
|
|
70942
|
+
if (!this.pricer) {
|
|
70943
|
+
throw new Error("Pricer is not initialized");
|
|
70944
|
+
}
|
|
70945
|
+
const CACHE_KEY = "collateralization";
|
|
70946
|
+
const cacheData = this.getCache(CACHE_KEY);
|
|
70947
|
+
if (cacheData) {
|
|
70948
|
+
return cacheData;
|
|
70949
|
+
}
|
|
70950
|
+
const output4 = await this.getVesuSingletonContract(config2).call("check_collateralization_unsafe", [
|
|
70951
|
+
this.config.poolId.address,
|
|
70952
|
+
this.config.collateral.address.address,
|
|
70953
|
+
this.config.debt.address.address,
|
|
70954
|
+
this.config.vaultAllocator.address
|
|
70955
|
+
]);
|
|
70956
|
+
const collateralAmount = Web3Number.fromWei(output4["1"].toString(), 18);
|
|
70957
|
+
const debtAmount = Web3Number.fromWei(output4["2"].toString(), 18);
|
|
70958
|
+
const value = [{
|
|
70959
|
+
token: this.config.collateral,
|
|
70960
|
+
usdValue: collateralAmount.toNumber(),
|
|
70961
|
+
remarks: "Collateral"
|
|
70962
|
+
}, {
|
|
70963
|
+
token: this.config.debt,
|
|
70964
|
+
usdValue: debtAmount.toNumber(),
|
|
70965
|
+
remarks: "Debt"
|
|
70966
|
+
}];
|
|
70967
|
+
this.setCache(CACHE_KEY, value, 6e4);
|
|
70968
|
+
return value;
|
|
70969
|
+
}
|
|
70970
|
+
async getAssetPrices() {
|
|
70971
|
+
const collateralizationProm = this.getCollateralization(this.networkConfig);
|
|
70972
|
+
const positionsProm = this.getPositions(this.networkConfig);
|
|
70973
|
+
const ltvProm = this.getLTVConfig(this.networkConfig);
|
|
70974
|
+
const output4 = await Promise.all([collateralizationProm, positionsProm, ltvProm]);
|
|
70975
|
+
const [collateralization, positions, ltv] = output4;
|
|
70976
|
+
const collateralTokenAmount = positions[0].amount;
|
|
70977
|
+
const collateralUSDAmount = collateralization[0].usdValue;
|
|
70978
|
+
const collateralPrice = collateralUSDAmount / collateralTokenAmount.toNumber();
|
|
70979
|
+
const debtTokenAmount = positions[1].amount;
|
|
70980
|
+
const debtUSDAmount = collateralization[1].usdValue;
|
|
70981
|
+
const debtPrice = debtUSDAmount / debtTokenAmount.toNumber();
|
|
70982
|
+
return {
|
|
70983
|
+
collateralTokenAmount,
|
|
70984
|
+
collateralUSDAmount,
|
|
70985
|
+
collateralPrice,
|
|
70986
|
+
debtTokenAmount,
|
|
70987
|
+
debtUSDAmount,
|
|
70988
|
+
debtPrice,
|
|
70989
|
+
ltv
|
|
70990
|
+
};
|
|
70991
|
+
}
|
|
70992
|
+
async getHealthFactor() {
|
|
70993
|
+
const ltv = await this.getLTVConfig(this.networkConfig);
|
|
70994
|
+
const collateralisation = await this.getCollateralization(this.networkConfig);
|
|
70995
|
+
return collateralisation[0].usdValue * ltv / collateralisation[1].usdValue;
|
|
70996
|
+
}
|
|
70952
70997
|
static async getVesuPools(retry = 0) {
|
|
70953
70998
|
const CACHE_KEY = "VESU_POOLS";
|
|
70954
70999
|
const cacheValue = Global.getGlobalCache(CACHE_KEY);
|
|
@@ -73317,19 +73362,32 @@ ${indent}}` : "}";
|
|
|
73317
73362
|
const debtAsset1 = pool1.assets.find((a) => a.symbol === vesuAdapter1.config.debt.symbol)?.stats;
|
|
73318
73363
|
const collateralAsset2 = pool2.assets.find((a) => a.symbol === vesuAdapter2.config.collateral.symbol)?.stats;
|
|
73319
73364
|
const debtAsset2 = pool2.assets.find((a) => a.symbol === vesuAdapter2.config.debt.symbol)?.stats;
|
|
73320
|
-
const collateral1APY = Number(collateralAsset1.supplyApy.value) / 1e18
|
|
73365
|
+
const collateral1APY = Number(collateralAsset1.supplyApy.value) / 1e18;
|
|
73321
73366
|
const debt1APY = Number(debtAsset1.borrowApr.value) / 1e18;
|
|
73322
|
-
const collateral2APY = Number(collateralAsset2.supplyApy.value) / 1e18
|
|
73367
|
+
const collateral2APY = Number(collateralAsset2.supplyApy.value) / 1e18;
|
|
73323
73368
|
const debt2APY = Number(debtAsset2.borrowApr.value) / 1e18;
|
|
73324
|
-
const apys = [collateral1APY, debt1APY, collateral2APY, debt2APY];
|
|
73325
73369
|
const positions = await this.getVaultPositions();
|
|
73326
|
-
|
|
73327
|
-
const
|
|
73328
|
-
|
|
73329
|
-
|
|
73330
|
-
const
|
|
73331
|
-
const
|
|
73332
|
-
|
|
73370
|
+
const weights = positions.map((p, index) => p.usdValue * (index % 2 == 0 ? 1 : -1));
|
|
73371
|
+
const baseAPYs = [collateral1APY, debt1APY, collateral2APY, debt2APY];
|
|
73372
|
+
assert3(positions.length == baseAPYs.length, "Positions and APYs length mismatch");
|
|
73373
|
+
const rewardAPYs = [Number(collateralAsset1.defiSpringSupplyApr.value) / 1e18, 0, Number(collateralAsset2.defiSpringSupplyApr.value) / 1e18, 0];
|
|
73374
|
+
const baseAPY = this.computeAPY(baseAPYs, weights);
|
|
73375
|
+
const rewardAPY = this.computeAPY(rewardAPYs, weights);
|
|
73376
|
+
const apys = [...baseAPYs, ...rewardAPYs];
|
|
73377
|
+
const netAPY = baseAPY + rewardAPY;
|
|
73378
|
+
return { net: netAPY, splits: [{
|
|
73379
|
+
apy: baseAPY,
|
|
73380
|
+
id: "base"
|
|
73381
|
+
}, {
|
|
73382
|
+
apy: rewardAPY,
|
|
73383
|
+
id: "defispring"
|
|
73384
|
+
}] };
|
|
73385
|
+
}
|
|
73386
|
+
computeAPY(apys, weights) {
|
|
73387
|
+
assert3(apys.length === weights.length, "APYs and weights length mismatch");
|
|
73388
|
+
const weightedSum = apys.reduce((acc, apy, i) => acc + apy * weights[i], 0);
|
|
73389
|
+
const totalWeight = weights.reduce((acc, weight) => acc + weight, 0);
|
|
73390
|
+
return weightedSum / totalWeight;
|
|
73333
73391
|
}
|
|
73334
73392
|
/**
|
|
73335
73393
|
* Calculates the total TVL of the strategy.
|
|
@@ -73352,22 +73410,50 @@ ${indent}}` : "}";
|
|
|
73352
73410
|
};
|
|
73353
73411
|
}
|
|
73354
73412
|
async getAUM() {
|
|
73413
|
+
const currentAUM = await this.contract.call("aum", []);
|
|
73414
|
+
const lastReportTime = await this.contract.call("last_report_timestamp", []);
|
|
73415
|
+
const token1Price = await this.pricer.getPrice(this.metadata.depositTokens[0].symbol);
|
|
73355
73416
|
const [vesuAdapter1, vesuAdapter2] = this.getVesuAdapters();
|
|
73356
73417
|
const leg1AUM = await vesuAdapter1.getPositions(this.config);
|
|
73357
73418
|
const leg2AUM = await vesuAdapter2.getPositions(this.config);
|
|
73358
|
-
const
|
|
73359
|
-
|
|
73360
|
-
|
|
73419
|
+
const balance = await new ERC20(this.config).balanceOf(this.asset().address, this.metadata.additionalInfo.vaultAllocator, this.asset().decimals);
|
|
73420
|
+
logger.verbose(`${this.getTag()} unused balance: ${balance}`);
|
|
73421
|
+
const aumToken = leg1AUM[0].amount.plus(leg2AUM[0].usdValue / token1Price.price).minus(leg1AUM[1].usdValue / token1Price.price).minus(leg2AUM[1].amount).plus(balance);
|
|
73422
|
+
logger.verbose(`${this.getTag()} Actual AUM: ${aumToken}`);
|
|
73423
|
+
const netAPY = await this.netAPY();
|
|
73424
|
+
const defispringAPY = netAPY.splits.find((s) => s.id === "defispring")?.apy || 0;
|
|
73425
|
+
if (!defispringAPY) throw new Error("DefiSpring APY not found");
|
|
73426
|
+
const timeDiff = Math.round(Date.now() / 1e3) - Number(lastReportTime);
|
|
73427
|
+
const growthRate = timeDiff * defispringAPY / (365 * 24 * 60 * 60);
|
|
73428
|
+
const prevAum = Web3Number.fromWei(currentAUM.toString(), this.asset().decimals);
|
|
73429
|
+
const rewardAssets = prevAum.multipliedBy(growthRate);
|
|
73430
|
+
logger.verbose(`${this.getTag()} DefiSpring AUM time difference: ${timeDiff}`);
|
|
73431
|
+
logger.verbose(`${this.getTag()} Current AUM: ${currentAUM}`);
|
|
73432
|
+
logger.verbose(`${this.getTag()} Net APY: ${JSON.stringify(netAPY)}`);
|
|
73433
|
+
logger.verbose(`${this.getTag()} rewards AUM: ${rewardAssets}`);
|
|
73434
|
+
const newAUM = aumToken.plus(rewardAssets);
|
|
73435
|
+
logger.verbose(`${this.getTag()} New AUM: ${newAUM}`);
|
|
73436
|
+
const net = {
|
|
73361
73437
|
tokenInfo: this.asset(),
|
|
73362
|
-
amount:
|
|
73363
|
-
usdValue:
|
|
73438
|
+
amount: newAUM,
|
|
73439
|
+
usdValue: newAUM.multipliedBy(token1Price.price).toNumber()
|
|
73364
73440
|
};
|
|
73441
|
+
const splits = [{
|
|
73442
|
+
id: "finalised",
|
|
73443
|
+
aum: aumToken
|
|
73444
|
+
}, {
|
|
73445
|
+
id: "defispring",
|
|
73446
|
+
aum: rewardAssets
|
|
73447
|
+
}];
|
|
73448
|
+
return { net, splits, prevAum };
|
|
73365
73449
|
}
|
|
73366
73450
|
getVesuAdapters() {
|
|
73367
73451
|
const vesuAdapter1 = this.getAdapter("vesu_leg1_adapter" /* VESU_LEG1 */);
|
|
73368
73452
|
const vesuAdapter2 = this.getAdapter("vesu_leg2_adapter" /* VESU_LEG2 */);
|
|
73369
73453
|
vesuAdapter1.pricer = this.pricer;
|
|
73370
73454
|
vesuAdapter2.pricer = this.pricer;
|
|
73455
|
+
vesuAdapter1.networkConfig = this.config;
|
|
73456
|
+
vesuAdapter2.networkConfig = this.config;
|
|
73371
73457
|
return [vesuAdapter1, vesuAdapter2];
|
|
73372
73458
|
}
|
|
73373
73459
|
async getVaultPositions() {
|
|
@@ -73409,12 +73495,14 @@ ${indent}}` : "}";
|
|
|
73409
73495
|
}));
|
|
73410
73496
|
const output4 = [{
|
|
73411
73497
|
proofs: manage5Info.proofs,
|
|
73412
|
-
manageCall: manageCall5
|
|
73498
|
+
manageCall: manageCall5,
|
|
73499
|
+
step: STEP2_ID
|
|
73413
73500
|
}];
|
|
73414
73501
|
if (approveAmount.gt(0)) {
|
|
73415
73502
|
output4.unshift({
|
|
73416
73503
|
proofs: manage4Info.proofs,
|
|
73417
|
-
manageCall: manageCall4
|
|
73504
|
+
manageCall: manageCall4,
|
|
73505
|
+
step: STEP1_ID
|
|
73418
73506
|
});
|
|
73419
73507
|
}
|
|
73420
73508
|
return output4;
|
|
@@ -73422,9 +73510,96 @@ ${indent}}` : "}";
|
|
|
73422
73510
|
getTag() {
|
|
73423
73511
|
return `${_UniversalStrategy.name}:${this.metadata.name}`;
|
|
73424
73512
|
}
|
|
73513
|
+
async getVesuHealthFactors() {
|
|
73514
|
+
return await Promise.all(this.getVesuAdapters().map((v) => v.getHealthFactor()));
|
|
73515
|
+
}
|
|
73516
|
+
async computeRebalanceConditionAndReturnCalls() {
|
|
73517
|
+
const vesuAdapters = this.getVesuAdapters();
|
|
73518
|
+
const healthFactors = await this.getVesuHealthFactors();
|
|
73519
|
+
const leg1HealthFactor = healthFactors[0];
|
|
73520
|
+
const leg2HealthFactor = healthFactors[1];
|
|
73521
|
+
logger.verbose(`${this.getTag()}: HealthFactorLeg1: ${leg1HealthFactor}`);
|
|
73522
|
+
logger.verbose(`${this.getTag()}: HealthFactorLeg2: ${leg2HealthFactor}`);
|
|
73523
|
+
const minHf = this.metadata.additionalInfo.minHealthFactor;
|
|
73524
|
+
const isRebalanceNeeded1 = leg1HealthFactor < minHf;
|
|
73525
|
+
const isRebalanceNeeded2 = leg2HealthFactor < minHf;
|
|
73526
|
+
if (!isRebalanceNeeded1 && !isRebalanceNeeded2) {
|
|
73527
|
+
return [];
|
|
73528
|
+
}
|
|
73529
|
+
if (isRebalanceNeeded1) {
|
|
73530
|
+
const amount = await this.getLegRebalanceAmount(vesuAdapters[0], leg1HealthFactor, false);
|
|
73531
|
+
const leg2HF = await this.getNewHealthFactor(vesuAdapters[1], amount, true);
|
|
73532
|
+
assert3(leg2HF > minHf, `Rebalance Leg1 failed: Leg2 HF after rebalance would be too low: ${leg2HF}`);
|
|
73533
|
+
return [await this.getRebalanceCall({
|
|
73534
|
+
isLeg1toLeg2: false,
|
|
73535
|
+
amount
|
|
73536
|
+
})];
|
|
73537
|
+
} else {
|
|
73538
|
+
const amount = await this.getLegRebalanceAmount(vesuAdapters[1], leg2HealthFactor, true);
|
|
73539
|
+
const leg1HF = await this.getNewHealthFactor(vesuAdapters[0], amount, false);
|
|
73540
|
+
assert3(leg1HF > minHf, `Rebalance Leg2 failed: Leg1 HF after rebalance would be too low: ${leg1HF}`);
|
|
73541
|
+
return [await this.getRebalanceCall({
|
|
73542
|
+
isLeg1toLeg2: true,
|
|
73543
|
+
amount
|
|
73544
|
+
})];
|
|
73545
|
+
}
|
|
73546
|
+
}
|
|
73547
|
+
async getNewHealthFactor(vesuAdapter, newAmount, isWithdraw) {
|
|
73548
|
+
const {
|
|
73549
|
+
collateralTokenAmount,
|
|
73550
|
+
collateralUSDAmount,
|
|
73551
|
+
collateralPrice,
|
|
73552
|
+
debtTokenAmount,
|
|
73553
|
+
debtUSDAmount,
|
|
73554
|
+
debtPrice,
|
|
73555
|
+
ltv
|
|
73556
|
+
} = await vesuAdapter.getAssetPrices();
|
|
73557
|
+
if (isWithdraw) {
|
|
73558
|
+
const newHF = (collateralTokenAmount.toNumber() - newAmount.toNumber()) * collateralPrice * ltv / debtUSDAmount;
|
|
73559
|
+
logger.verbose(`getNewHealthFactor:: HF: ${newHF}, amoutn: ${newAmount.toNumber()}, isDeposit`);
|
|
73560
|
+
return newHF;
|
|
73561
|
+
} else {
|
|
73562
|
+
const newHF = collateralUSDAmount * ltv / ((debtTokenAmount.toNumber() + newAmount.toNumber()) * debtPrice);
|
|
73563
|
+
logger.verbose(`getNewHealthFactor:: HF: ${newHF}, amoutn: ${newAmount.toNumber()}, isRepay`);
|
|
73564
|
+
return newHF;
|
|
73565
|
+
}
|
|
73566
|
+
}
|
|
73567
|
+
/**
|
|
73568
|
+
*
|
|
73569
|
+
* @param vesuAdapter
|
|
73570
|
+
* @param currentHf
|
|
73571
|
+
* @param isDeposit if true, attempt by adding collateral, else by repaying
|
|
73572
|
+
* @returns
|
|
73573
|
+
*/
|
|
73574
|
+
async getLegRebalanceAmount(vesuAdapter, currentHf, isDeposit) {
|
|
73575
|
+
const {
|
|
73576
|
+
collateralTokenAmount,
|
|
73577
|
+
collateralUSDAmount,
|
|
73578
|
+
collateralPrice,
|
|
73579
|
+
debtTokenAmount,
|
|
73580
|
+
debtUSDAmount,
|
|
73581
|
+
debtPrice,
|
|
73582
|
+
ltv
|
|
73583
|
+
} = await vesuAdapter.getAssetPrices();
|
|
73584
|
+
if (debtTokenAmount.isZero()) {
|
|
73585
|
+
return Web3Number.fromWei(0, 0);
|
|
73586
|
+
}
|
|
73587
|
+
assert3(collateralPrice > 0 && debtPrice > 0, "getRebalanceAmount: Invalid price");
|
|
73588
|
+
const targetHF = this.metadata.additionalInfo.targetHealthFactor;
|
|
73589
|
+
if (currentHf > targetHF - 0.01)
|
|
73590
|
+
throw new Error("getLegRebalanceAmount: Current health factor is healthy");
|
|
73591
|
+
if (isDeposit) {
|
|
73592
|
+
const newAmount = targetHF * debtUSDAmount / (collateralPrice * ltv) - collateralTokenAmount.toNumber();
|
|
73593
|
+
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}`);
|
|
73594
|
+
return new Web3Number(newAmount.toFixed(8), collateralTokenAmount.decimals);
|
|
73595
|
+
} else {
|
|
73596
|
+
const newAmount = debtTokenAmount.toNumber() - collateralUSDAmount * ltv / (targetHF * debtPrice);
|
|
73597
|
+
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}`);
|
|
73598
|
+
return new Web3Number(newAmount.toFixed(8), debtTokenAmount.decimals);
|
|
73599
|
+
}
|
|
73600
|
+
}
|
|
73425
73601
|
async getVesuMultiplyCall(params) {
|
|
73426
|
-
const vesuAdapter1 = this.
|
|
73427
|
-
const vesuAdapter2 = this.getAdapter("vesu_leg2_adapter" /* VESU_LEG2 */);
|
|
73602
|
+
const [vesuAdapter1, vesuAdapter2] = this.getVesuAdapters();
|
|
73428
73603
|
const leg1LTV = await vesuAdapter1.getLTVConfig(this.config);
|
|
73429
73604
|
const leg2LTV = await vesuAdapter2.getLTVConfig(this.config);
|
|
73430
73605
|
logger.verbose(`${this.getTag()}: LTVLeg1: ${leg1LTV}`);
|
|
@@ -73433,7 +73608,7 @@ ${indent}}` : "}";
|
|
|
73433
73608
|
const token2Price = await this.pricer.getPrice(vesuAdapter2.config.collateral.symbol);
|
|
73434
73609
|
logger.verbose(`${this.getTag()}: Price${vesuAdapter1.config.collateral.symbol}: ${token1Price.price}`);
|
|
73435
73610
|
logger.verbose(`${this.getTag()}: Price${vesuAdapter2.config.collateral.symbol}: ${token2Price.price}`);
|
|
73436
|
-
const TARGET_HF =
|
|
73611
|
+
const TARGET_HF = this.metadata.additionalInfo.targetHealthFactor;
|
|
73437
73612
|
const k1 = token1Price.price * leg1LTV / token2Price.price / TARGET_HF;
|
|
73438
73613
|
const k2 = token1Price.price * TARGET_HF / token2Price.price / leg2LTV;
|
|
73439
73614
|
const borrow2Amount = new Web3Number(
|
|
@@ -73491,14 +73666,14 @@ ${indent}}` : "}";
|
|
|
73491
73666
|
});
|
|
73492
73667
|
if (params.isLeg1toLeg2) {
|
|
73493
73668
|
const manageCall = this.getManageCall([
|
|
73494
|
-
|
|
73495
|
-
|
|
73669
|
+
...callSet1.map((i) => i.step),
|
|
73670
|
+
...callSet2.map((i) => i.step)
|
|
73496
73671
|
], [...callSet1.map((i) => i.manageCall), ...callSet2.map((i) => i.manageCall)]);
|
|
73497
73672
|
return manageCall;
|
|
73498
73673
|
} else {
|
|
73499
73674
|
const manageCall = this.getManageCall([
|
|
73500
|
-
|
|
73501
|
-
|
|
73675
|
+
...callSet2.map((i) => i.step),
|
|
73676
|
+
...callSet1.map((i) => i.step)
|
|
73502
73677
|
], [...callSet2.map((i) => i.manageCall), ...callSet1.map((i) => i.manageCall)]);
|
|
73503
73678
|
return manageCall;
|
|
73504
73679
|
}
|
|
@@ -73565,15 +73740,21 @@ ${indent}}` : "}";
|
|
|
73565
73740
|
manager: ContractAddr.from("0xf41a2b1f498a7f9629db0b8519259e66e964260a23d20003f3e42bb1997a07"),
|
|
73566
73741
|
vaultAllocator: ContractAddr.from("0x228cca1005d3f2b55cbaba27cb291dacf1b9a92d1d6b1638195fbd3d0c1e3ba"),
|
|
73567
73742
|
redeemRequestNFT: ContractAddr.from("0x906d03590010868cbf7590ad47043959d7af8e782089a605d9b22567b64fda"),
|
|
73743
|
+
aumOracle: ContractAddr.from("0x6faf45ed185dec13ef723c9ead4266cab98d06f2cb237e331b1fa5c2aa79afe"),
|
|
73568
73744
|
leafAdapters: [],
|
|
73569
|
-
adapters: []
|
|
73745
|
+
adapters: [],
|
|
73746
|
+
targetHealthFactor: 1.3,
|
|
73747
|
+
minHealthFactor: 1.25
|
|
73570
73748
|
};
|
|
73571
73749
|
var wbtcVaultSettings = {
|
|
73572
73750
|
manager: ContractAddr.from("0xef8a664ffcfe46a6af550766d27c28937bf1b77fb4ab54d8553e92bca5ba34"),
|
|
73573
73751
|
vaultAllocator: ContractAddr.from("0x1e01c25f0d9494570226ad28a7fa856c0640505e809c366a9fab4903320e735"),
|
|
73574
73752
|
redeemRequestNFT: ContractAddr.from("0x4fec59a12f8424281c1e65a80b5de51b4e754625c60cddfcd00d46941ec37b2"),
|
|
73753
|
+
aumOracle: ContractAddr.from("0x2edf4edbed3f839e7f07dcd913e92299898ff4cf0ba532f8c572c66c5b331b2"),
|
|
73575
73754
|
leafAdapters: [],
|
|
73576
|
-
adapters: []
|
|
73755
|
+
adapters: [],
|
|
73756
|
+
targetHealthFactor: 1.3,
|
|
73757
|
+
minHealthFactor: 1.25
|
|
73577
73758
|
};
|
|
73578
73759
|
var UniversalStrategies = [
|
|
73579
73760
|
{
|