@strkfarm/sdk 2.0.0-dev.5 → 2.0.0-dev.51

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.
Files changed (80) hide show
  1. package/dist/cli.js +190 -36
  2. package/dist/cli.mjs +188 -34
  3. package/dist/index.browser.global.js +118889 -92229
  4. package/dist/index.browser.mjs +13381 -11153
  5. package/dist/index.d.ts +2284 -1938
  6. package/dist/index.js +13794 -11360
  7. package/dist/index.mjs +14253 -11843
  8. package/package.json +59 -60
  9. package/src/data/avnu.abi.json +840 -0
  10. package/src/data/ekubo-price-fethcer.abi.json +265 -0
  11. package/src/data/redeem-request-nft.abi.json +752 -0
  12. package/src/data/universal-vault.abi.json +8 -7
  13. package/src/dataTypes/_bignumber.ts +13 -4
  14. package/src/dataTypes/bignumber.browser.ts +10 -1
  15. package/src/dataTypes/bignumber.node.ts +10 -1
  16. package/src/dataTypes/index.ts +3 -2
  17. package/src/dataTypes/mynumber.ts +141 -0
  18. package/src/global.ts +280 -233
  19. package/src/index.browser.ts +2 -1
  20. package/src/interfaces/common.tsx +229 -6
  21. package/src/modules/apollo-client-config.ts +28 -0
  22. package/src/modules/avnu.ts +21 -12
  23. package/src/modules/ekubo-pricer.ts +99 -0
  24. package/src/modules/ekubo-quoter.ts +48 -30
  25. package/src/modules/erc20.ts +17 -0
  26. package/src/modules/harvests.ts +43 -29
  27. package/src/modules/index.ts +2 -1
  28. package/src/modules/pragma.ts +23 -8
  29. package/src/modules/pricer-avnu-api.ts +114 -0
  30. package/src/modules/pricer-from-api.ts +159 -15
  31. package/src/modules/pricer-lst.ts +1 -1
  32. package/src/modules/pricer-quote-utils.ts +54 -0
  33. package/src/modules/pricer.ts +157 -54
  34. package/src/modules/pricerBase.ts +2 -1
  35. package/src/modules/zkLend.ts +3 -2
  36. package/src/node/deployer.ts +36 -1
  37. package/src/node/pricer-redis.ts +3 -1
  38. package/src/strategies/base-strategy.ts +168 -16
  39. package/src/strategies/constants.ts +8 -3
  40. package/src/strategies/ekubo-cl-vault.tsx +1048 -355
  41. package/src/strategies/factory.ts +199 -0
  42. package/src/strategies/index.ts +5 -3
  43. package/src/strategies/registry.ts +262 -0
  44. package/src/strategies/sensei.ts +354 -10
  45. package/src/strategies/svk-strategy.ts +292 -31
  46. package/src/strategies/token-boosted-xstrk-carry-strategy.tsx +1261 -0
  47. package/src/strategies/types.ts +4 -0
  48. package/src/strategies/universal-adapters/adapter-utils.ts +4 -1
  49. package/src/strategies/universal-adapters/avnu-adapter.ts +196 -272
  50. package/src/strategies/universal-adapters/baseAdapter.ts +263 -251
  51. package/src/strategies/universal-adapters/common-adapter.ts +206 -203
  52. package/src/strategies/universal-adapters/index.ts +10 -8
  53. package/src/strategies/universal-adapters/svk-troves-adapter.ts +511 -0
  54. package/src/strategies/universal-adapters/token-transfer-adapter.ts +200 -0
  55. package/src/strategies/universal-adapters/vesu-adapter.ts +120 -82
  56. package/src/strategies/universal-adapters/vesu-modify-position-adapter.ts +525 -0
  57. package/src/strategies/universal-adapters/vesu-multiply-adapter.ts +866 -860
  58. package/src/strategies/universal-adapters/vesu-position-common.ts +258 -0
  59. package/src/strategies/universal-adapters/vesu-supply-only-adapter.ts +18 -3
  60. package/src/strategies/universal-lst-muliplier-strategy.tsx +895 -416
  61. package/src/strategies/universal-strategy.tsx +1332 -1173
  62. package/src/strategies/vesu-rebalance.tsx +254 -153
  63. package/src/strategies/yoloVault.ts +1096 -0
  64. package/src/utils/cacheClass.ts +11 -2
  65. package/src/utils/health-factor-math.ts +33 -1
  66. package/src/utils/index.ts +3 -1
  67. package/src/utils/logger.browser.ts +22 -4
  68. package/src/utils/logger.node.ts +259 -24
  69. package/src/utils/starknet-call-parser.ts +1036 -0
  70. package/src/utils/strategy-utils.ts +61 -0
  71. package/src/modules/ExtendedWrapperSDk/index.ts +0 -62
  72. package/src/modules/ExtendedWrapperSDk/types.ts +0 -311
  73. package/src/modules/ExtendedWrapperSDk/wrapper.ts +0 -395
  74. package/src/strategies/universal-adapters/extended-adapter.ts +0 -662
  75. package/src/strategies/universal-adapters/unused-balance-adapter.ts +0 -109
  76. package/src/strategies/vesu-extended-strategy/services/operationService.ts +0 -34
  77. package/src/strategies/vesu-extended-strategy/utils/config.runtime.ts +0 -77
  78. package/src/strategies/vesu-extended-strategy/utils/constants.ts +0 -49
  79. package/src/strategies/vesu-extended-strategy/utils/helper.ts +0 -372
  80. package/src/strategies/vesu-extended-strategy/vesu-extended-strategy.tsx +0 -1140
@@ -1,109 +0,0 @@
1
- import { ContractAddr, Web3Number } from "@/dataTypes";
2
- import { APYType, BaseAdapter, BaseAdapterConfig, DepositParams, ManageCall, PositionAmount, PositionAPY, PositionInfo, SupportedPosition, WithdrawParams } from "./baseAdapter";
3
- import { Contract, uint256 } from "starknet";
4
- import erc20Abi from "@/data/erc20.abi.json";
5
- import { ERC20, TokenMarketData } from "@/modules";
6
- import { Protocols } from "@/interfaces";
7
-
8
- export interface UnusedBalanceAdapterConfig extends BaseAdapterConfig {}
9
-
10
- export class UnusedBalanceAdapter extends BaseAdapter<DepositParams, WithdrawParams> {
11
- readonly config: UnusedBalanceAdapterConfig;
12
- readonly tokenMarketData: TokenMarketData;
13
-
14
- constructor(config: UnusedBalanceAdapterConfig) {
15
- super(config, UnusedBalanceAdapter.name, Protocols.NONE);
16
- this.config = config;
17
- this.tokenMarketData = new TokenMarketData(this.config.pricer, this.config.networkConfig);
18
- }
19
-
20
- protected async getAPY(_supportedPosition: SupportedPosition): Promise<PositionAPY> {
21
- const isSupported = this.tokenMarketData.isAPYSupported(this.config.baseToken);
22
- const apy = isSupported ? await this.tokenMarketData.getAPY(this.config.baseToken) : 0;
23
- return { apy: apy, type: isSupported ? APYType.LST : APYType.BASE };
24
- }
25
-
26
- protected async getPosition(supportedPosition: SupportedPosition): Promise<PositionAmount> {
27
- try {
28
- const balance = await (new ERC20(this.config.networkConfig)).balanceOf(supportedPosition.asset.address, this.config.vaultAllocator.address, supportedPosition.asset.decimals);
29
- return {
30
- amount: balance,
31
- remarks: "Unused balance"
32
- }
33
- } catch (_e) {
34
- throw new Error(`${UnusedBalanceAdapter.name}: Failed to get position for ${supportedPosition.asset.symbol}`);
35
- }
36
- }
37
-
38
- async maxDeposit(amount?: Web3Number): Promise<PositionInfo> {
39
- const baseToken = this.config.baseToken;
40
- if (!amount) {
41
- const infinite = new Web3Number('999999999999999999999999999', baseToken.decimals);
42
- return {
43
- tokenInfo: baseToken,
44
- amount: infinite,
45
- usdValue: Number.POSITIVE_INFINITY,
46
- remarks: "Max deposit (infinity)",
47
- apy: await this.getAPY({ asset: baseToken, isDebt: false }),
48
- protocol: this.protocol
49
- };
50
- }
51
- const usdValue = await this.getUSDValue(baseToken, amount);
52
- return {
53
- tokenInfo: baseToken,
54
- amount,
55
- usdValue,
56
- remarks: "Deposit amount",
57
- apy: await this.getAPY({ asset: baseToken, isDebt: false }),
58
- protocol: this.protocol
59
- };
60
- }
61
-
62
- async maxWithdraw(): Promise<PositionInfo> {
63
- const baseToken = this.config.baseToken;
64
- const current = await this.getPosition({ asset: baseToken, isDebt: false });
65
- const usdValue = await this.getUSDValue(baseToken, current.amount);
66
- return {
67
- tokenInfo: baseToken,
68
- amount: current.amount,
69
- usdValue,
70
- remarks: "Max withdraw",
71
- apy: await this.getAPY({ asset: baseToken, isDebt: false }),
72
- protocol: this.protocol
73
- };
74
- }
75
-
76
- protected _getDepositLeaf(): {
77
- target: ContractAddr,
78
- method: string,
79
- packedArguments: bigint[];
80
- sanitizer: ContractAddr,
81
- id: string
82
- }[] {
83
- return [];
84
- }
85
-
86
- protected _getWithdrawLeaf(): {
87
- target: ContractAddr,
88
- method: string,
89
- packedArguments: bigint[];
90
- sanitizer: ContractAddr,
91
- id: string
92
- }[] {
93
- return [];
94
- }
95
-
96
- async getHealthFactor(): Promise<number> {
97
- return Promise.resolve(10);
98
- }
99
-
100
- getDepositCall(params: DepositParams): Promise<ManageCall[]> {
101
- return Promise.resolve([]);
102
- }
103
-
104
- getWithdrawCall(params: WithdrawParams): Promise<ManageCall[]> {
105
- return Promise.resolve([]);
106
- }
107
- }
108
-
109
-
@@ -1,34 +0,0 @@
1
- import { Web3Number } from "@/dataTypes";
2
- import { TokenInfo } from "@/interfaces";
3
- import { ExtendedAdapter } from "@/strategies/universal-adapters/extended-adapter";
4
- import { VesuMultiplyAdapter } from "../../universal-adapters/vesu-multiply-adapter";
5
- import { Call } from "starknet";
6
- export abstract class Operations {
7
- abstract shouldMoveAssets(
8
- extendedAmount: Web3Number,
9
- vesuAmount: Web3Number
10
- ): Promise<Call[]>;
11
- abstract shouldInvest(): Promise<{
12
- shouldInvest: boolean;
13
- vesuAmount: Web3Number;
14
- extendedAmount: Web3Number;
15
- extendedLeverage: number;
16
- vesuLeverage: number;
17
- }>;
18
- abstract moveAssets(
19
- params: { from: string; to: string; amount: Web3Number },
20
- extendedAdapter: ExtendedAdapter,
21
- vesuAdapter: VesuMultiplyAdapter
22
- ): Promise<{
23
- calls: Call[];
24
- status: boolean;
25
- }>;
26
- abstract handleDeposit(): Promise<{
27
- extendedAmountInBTC: Web3Number;
28
- calls: Call[];
29
- }>;
30
- abstract handleWithdraw(amount: Web3Number): Promise<{
31
- calls: Call[];
32
- status: boolean;
33
- }> ;
34
- }
@@ -1,77 +0,0 @@
1
- import {
2
- AVNU_API,
3
- USDC_TOKEN_ADDRESS,
4
- USDC_TOKEN_DECIMALS,
5
- WBTC_TOKEN_ADDRESS,
6
- WBTC_TOKEN_DECIMALS,
7
- WALLET_ADDRESS,
8
- EXTEND_CONTRACT_ADDRESS,
9
- MULTIPLY_CONTRACT_ADDRESS,
10
- EXTENDED_BASE_URL,
11
- EXTEND_MARKET_NAME,
12
- EXTENDED_QTY_PRECISION,
13
- EXTENDED_FEES,
14
- MAINTENANCE_MARGIN,
15
- VESU_POOL_ID,
16
- MAX_LTV_BTC_USDC,
17
- MAX_LIQUIDATION_RATIO,
18
- TARGET_HF,
19
- EKUBO_ENDPOINT,
20
- PRICE_MAX_SLIPPAGE_EKUBO,
21
- MINIMUM_DEBT_AMOUNT_VESU_FOR_REBALANCING,
22
- MINIMUM_EXTENDED_POSITION_SIZE
23
- } from "./constants"
24
- import VesuPoolV2Abi from '@/data/vesu-pool-v2.abi.json';
25
- import ExtendedDepositAbi from '@/data/extended-deposit.abi.json';
26
- import VesuMultiplyAbi from '@/data/vesu-multiple.abi.json';
27
-
28
- // Grouped, readable configuration (no behavior change). Consumers can migrate gradually.
29
-
30
- export const AddressesConfig = {
31
- tokens: {
32
- USDC: { address: USDC_TOKEN_ADDRESS, decimals: USDC_TOKEN_DECIMALS },
33
- WBTC: { address: WBTC_TOKEN_ADDRESS, decimals: WBTC_TOKEN_DECIMALS },
34
- },
35
- contracts: {
36
- EXTENDED: EXTEND_CONTRACT_ADDRESS,
37
- MULTIPLY: MULTIPLY_CONTRACT_ADDRESS,
38
- },
39
- wallet: {
40
- address: WALLET_ADDRESS,
41
- },
42
- } as const;
43
-
44
- export const ExtendedConfig = {
45
- baseUrl: EXTENDED_BASE_URL,
46
- marketName: EXTEND_MARKET_NAME,
47
- maintenanceMargin: MAINTENANCE_MARGIN,
48
- precision: EXTENDED_QTY_PRECISION,
49
- fees: EXTENDED_FEES,
50
- minPositionSize: MINIMUM_EXTENDED_POSITION_SIZE,
51
- } as const;
52
-
53
- export const VesuConfig = {
54
- poolId: VESU_POOL_ID,
55
- maxLtv: MAX_LTV_BTC_USDC,
56
- maxLiquidationRatio: MAX_LIQUIDATION_RATIO,
57
- targetHealthFactor: TARGET_HF,
58
- ekubo: {
59
- endpoint: EKUBO_ENDPOINT,
60
- priceMaxSlippage: PRICE_MAX_SLIPPAGE_EKUBO,
61
- },
62
- avnu: {
63
- api: AVNU_API,
64
- },
65
- minDebtForVesuRebalacing:MINIMUM_DEBT_AMOUNT_VESU_FOR_REBALANCING
66
- } as const;
67
-
68
- export const AbisConfig = {
69
- vesu: {
70
- multiply: VesuMultiplyAbi,
71
- pool: VesuPoolV2Abi,
72
- },
73
- extended: {
74
- contract: ExtendedDepositAbi,
75
- },
76
- } as const;
77
-
@@ -1,49 +0,0 @@
1
- export const AVNU_API = "https://starknet.api.avnu.fi/swap/v2/quotes";
2
- export const SLIPPAGE = 0.01;
3
- export const USDC_TOKEN_DECIMALS = 6;
4
- export const USDC_TOKEN_ADDRESS =
5
- "0x053C91253BC9682c04929cA02ED00b3E423f6710D2ee7e0D5EBB06F3eCF368A8";
6
- export const BUFFER_USDC_IN_WITHDRAWAL=5;
7
- export const WBTC_TOKEN_ADDRESS = "0x3fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac";
8
- export const WBTC_TOKEN_DECIMALS = 8;
9
- export const MAINTENANCE_MARGIN = 0.01;
10
- export const MAX_PRICE_DROP_PERCENTAGE = Number(process.env.MAX_PRICE_DROP_PERCENTAGE ?? 0.25);
11
- export const MAX_LTV_BTC_USDC = 0.8428;
12
- export const MAX_LIQUIDATION_RATIO = 0.86;
13
- export const VAULT_ID_EXTENDED= process.env.VAULT_ID_EXTENDED ?? 220774;
14
- export const WALLET_ADDRESS =
15
- process.env.WALLET_ADDRESS ?? "0x07b84bb6E87588BdAde0bfe6173A615b3C220F9C3803456aE183C50EA1d15Ba1";
16
- export const TESTNET_WALLET_ADDRESS =
17
- process.env.TESTNET_WALLET_ADDRESS ?? "0x07b84bb6E87588BdAde0bfe6173A615b3C220F9C3803456aE183C50EA1d15Ba1";
18
- export const TEST_WALLET_2 =
19
- process.env.TEST_WALLET_2 ?? "0x004C1bdC61DAc7947F3C93d0163d660012E2aB0521567f7155fcf502848791A7";
20
- export const STRK_API_TEST_RPC = process.env.STRK_API_TEST_RPC ?? "https://sepolia.starknet.a5a.ch";
21
- export const STRK_API_RPC = process.env.STRK_API_RPC ?? "https://mainnet.starknet.a5a.ch";
22
- export const MAX_RETRIES = Number(process.env.MAX_RETRIES ?? 3);
23
- export const MAX_DELAY = Number(process.env.MAX_DELAY ?? 100);
24
- export const EXTEND_MARKET_NAME = "BTC-USD";
25
- export const LIMIT_BALANCE = Number(process.env.LIMIT_BALANCE ?? 10);
26
- export const REBALANCER_INTERVAL = Number(process.env.REBALANCER_INTERVAL ?? 180000); //3 mins
27
- export const WITHDRAWAL_INTERVAL = Number(process.env.WITHDRAWAL_INTERVAL ?? 18000000); //5 hours
28
- export const INVESTING_INTERVAL = Number(process.env.INVESTING_INTERVAL ?? 180000); //3 mins
29
- export const MAXIMUM_DELTA = Number(process.env.MAXIMUM_DELTA ?? 5);
30
- export const EXTENDED_BASE_URL = process.env.EXTENDED_BASE_URL ?? "https://api.starknet.extended.exchange";
31
- export const VESU_POOL_ID = "0x02eef0c13b10b487ea5916b54c0a7f98ec43fb3048f60fdeedaf5b08f6f88aaf";
32
- export const EKUBO_ENDPOINT = "https://quoter-mainnet-api.ekubo.org/{{AMOUNT}}/{{TOKEN_FROM_ADDRESS}}/{{TOKEN_TO_ADDRESS}}"; // e.g. ETH/USDC'
33
- export const TARGET_HF = Number(process.env.TARGET_HF ?? 1.4);
34
- export const MULTIPLY_CONTRACT_ADDRESS = "0x07964760e90baa28841ec94714151e03fbc13321797e68a874e88f27c9d58513";
35
- export const EXTEND_CONTRACT_ADDRESS = "0x062da0780fae50d68cecaa5a051606dc21217ba290969b302db4dd99d2e9b470";
36
- export const EXTENDED_QTY_PRECISION = 5;
37
- export const EXTENDED_FEES= Number(process.env.EXTENDED_FEES ?? 0.006);
38
- export const REBALANCE_PRICE_DROP_PERCENTAGE = Number(process.env.REBALANCE_PRICE_DROP_PERCENTAGE ?? 3);
39
- export const PRICE_MAX_SLIPPAGE_EKUBO = Number(process.env.PRICE_MAX_SLIPPAGE_EKUBO ?? 0.005);
40
- export const MINIMUM_DEBT_AMOUNT_VESU_FOR_REBALANCING = Number(process.env.MINIMUM_DEBT_AMOUNT_VESU_FOR_REBALANCING ?? 1);
41
- export const MINIMUM_EXTENDED_POSITION_SIZE = 0.0001;
42
- export const MINIMUM_WBTC_DIFFERENCE_FOR_AVNU_SWAP = 0.00001;
43
- export const MAX_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED = 700;
44
- export const MIN_PRICE_DIFFERENCE_BETWEEN_AVNU_AND_EXTENDED = -100;
45
-
46
- //STATUS CODES
47
- export const SUCCESS_STATUS_CODE = 200;
48
- export const ERROR_STATUS_CODE = 500;
49
- export const BAD_REQUEST_STATUS_CODE = 400;
@@ -1,372 +0,0 @@
1
- import {
2
- MAINTENANCE_MARGIN,
3
- MAX_LTV_BTC_USDC,
4
- MAX_PRICE_DROP_PERCENTAGE,
5
- TARGET_HF,
6
- WBTC_TOKEN_ADDRESS,
7
- USDC_TOKEN_ADDRESS,
8
- WBTC_TOKEN_DECIMALS,
9
- USDC_TOKEN_DECIMALS,
10
- MAX_LIQUIDATION_RATIO,
11
- } from "./constants";
12
- import { Web3Number } from "@/dataTypes";
13
- import { Position } from "@/modules/ExtendedWrapperSDk";
14
- // import { getAllOpenPositionsExtended } from "../services/extendedService";
15
- import ExtendedWrapper from "@/modules/ExtendedWrapperSDk";
16
- import { logger } from "@/utils";
17
- // import {
18
- // calculatePositionOnVesu,
19
- // getAssetPrice,
20
- // } from "../services/vesuService";
21
- /**
22
- * Function to return formatted amount to BigInt
23
- * Converts a decimal amount to the proper format for blockchain transactions
24
- * @param {number} amount - The decimal amount to convert
25
- * @param {number} fromTokenDecimals - The decimal precision of the token
26
- * @returns {string} The formatted amount as a hexadecimal string
27
- */
28
- export const returnFormattedAmount = (
29
- amount: number,
30
- toTokenDecimals: number
31
- ) => {
32
- const formattedAmount =
33
- "0x" + BigInt(Math.floor(amount * 10 ** toTokenDecimals)).toString(16);
34
- return formattedAmount;
35
- };
36
-
37
- /**
38
- * calculates the amount to distribute to Extend and Vesu
39
- * Determines how much to allocate to each platform based on leverage calculations
40
- * @param {number} amount - The total amount to distribute
41
- * @returns {object} Object containing avnu_amount, extended_amount, and extended_leverage
42
- */
43
- export const calculateAmountDistribution = async (
44
- amount: number,
45
- client: ExtendedWrapper,
46
- marketName: string,
47
- collateralPrice: number,
48
- debtPrice: number,
49
- collateralUnits: Web3Number,
50
- extendedPosition: Position[] | null
51
- ): Promise<{
52
- vesu_amount: Web3Number;
53
- extended_amount: Web3Number;
54
- extended_leverage: number;
55
- vesu_leverage: number;
56
- }> => {
57
- try {
58
- const extended_leverage = calculateExtendedLevergae();
59
- const vesu_leverage = calculateVesuLeverage();
60
- if (extendedPosition === null) {
61
- logger.error("error getting extended positions");
62
- return {
63
- vesu_amount: new Web3Number(0, 0),
64
- extended_amount: new Web3Number(0, 0),
65
- extended_leverage: 0,
66
- vesu_leverage: 0,
67
- };
68
- }
69
- const extendedBTCExposure =
70
- extendedPosition.length > 0
71
- ? new Web3Number(extendedPosition[0].size, WBTC_TOKEN_DECIMALS)
72
- : new Web3Number(0, WBTC_TOKEN_DECIMALS);
73
- const extendedExposureUSD =
74
- extendedBTCExposure.multipliedBy(collateralPrice);
75
- const vesuBTCExposureUSD = collateralUnits.multipliedBy(collateralPrice);
76
- const numerator1 = vesu_leverage * amount + vesuBTCExposureUSD.toNumber();
77
- const numerator2 = extendedExposureUSD.toNumber();
78
- const denominator = vesu_leverage + extended_leverage;
79
- const ExtendedAmount = new Web3Number(
80
- ((numerator1 - numerator2) / denominator).toFixed(2),
81
- USDC_TOKEN_DECIMALS
82
- );
83
-
84
- const VesuAmount = new Web3Number(
85
- amount.toFixed(2),
86
- USDC_TOKEN_DECIMALS
87
- ).minus(ExtendedAmount);
88
-
89
- return {
90
- vesu_amount: VesuAmount,
91
- extended_amount: ExtendedAmount,
92
- extended_leverage,
93
- vesu_leverage,
94
- };
95
- } catch (err) {
96
- return {
97
- vesu_amount: new Web3Number(0, 0),
98
- extended_amount: new Web3Number(0, 0),
99
- extended_leverage: 0,
100
- vesu_leverage: 0,
101
- };
102
- }
103
- };
104
-
105
- /**
106
- * calculate the amount distribution for withdrawal
107
- * @param amount - The amount to withdraw
108
- * @param client - The client
109
- * @param marketName - The market name
110
- * @returns {object} Object containing avnu_amount and extended_amount
111
- */
112
- export const calculateAmountDistributionForWithdrawal = async (
113
- amountInUsdc: Web3Number,
114
- collateralPrice: number,
115
- collateralUnits: Web3Number,
116
- extendedPosition: Position[] | null
117
- ): Promise<{
118
- vesu_amount: Web3Number;
119
- extended_amount: Web3Number;
120
- extended_leverage: number;
121
- vesu_leverage: number;
122
- } | null> => {
123
- try {
124
- const extended_leverage = calculateExtendedLevergae();
125
- const vesu_leverage = calculateVesuLeverage();
126
- if (extendedPosition === null) {
127
- logger.error("error getting extended positions");
128
- return null;
129
- }
130
- const extendedExposureUSD =
131
- extendedPosition.length > 0
132
- ? new Web3Number(extendedPosition[0].value, USDC_TOKEN_DECIMALS)
133
- : new Web3Number(0, USDC_TOKEN_DECIMALS);
134
- const vesuExposureUSD = collateralUnits.multipliedBy(collateralPrice);
135
- if (vesuExposureUSD.lessThan(0)) {
136
- return {
137
- vesu_amount: new Web3Number(0, USDC_TOKEN_DECIMALS),
138
- extended_amount: amountInUsdc,
139
- extended_leverage,
140
- vesu_leverage,
141
- };
142
- }
143
- if (extendedExposureUSD.lessThan(0)) {
144
- return {
145
- vesu_amount: amountInUsdc,
146
- extended_amount: new Web3Number(0, USDC_TOKEN_DECIMALS),
147
- extended_leverage,
148
- vesu_leverage,
149
- };
150
- }
151
- console.log("the vesu exposure usd is", vesuExposureUSD.toNumber());
152
- console.log("the extended exposure usd is", extendedExposureUSD.toNumber());
153
- console.log("the amount in usdc is", amountInUsdc.toNumber());
154
- console.log("the extended leverage is", extended_leverage);
155
- console.log("the vesu leverage is", vesu_leverage);
156
- const numerator1 = amountInUsdc.multipliedBy(extended_leverage);
157
- const numerator2 = vesuExposureUSD;
158
- const numerator3 = extendedExposureUSD
159
- .multipliedBy(-1);
160
- const finalNumerator = numerator1.plus(numerator2).plus(numerator3);
161
- const denominator = extended_leverage + vesu_leverage;
162
- const vesuAmountInUSDC = finalNumerator.dividedBy(denominator);
163
- console.log("the vesu amount in usdc is", vesuAmountInUSDC.toNumber());
164
- const extendedAmountInUSDC = amountInUsdc.minus(vesuAmountInUSDC);
165
- console.log(
166
- "the extended amount in usdc is",
167
- extendedAmountInUSDC.toNumber()
168
- );
169
- //console.log("the vesu amount in usdc is", vesuAmountInUSDC.toNumber());
170
- //console.log("the extended amount in usdc is", extendedAmountInUSDC.toNumber());\
171
- await new Promise((resolve) => setTimeout(resolve, 10000));
172
- return {
173
- vesu_amount: vesuAmountInUSDC,
174
- extended_amount: extendedAmountInUSDC,
175
- extended_leverage,
176
- vesu_leverage,
177
- };
178
- } catch (err) {
179
- logger.error(`error calculating amount distribution for withdrawal: ${err}`);
180
- return null;
181
- }
182
- };
183
- /**
184
- * calculate the leverage required for Avnu
185
- * calculates the optimal leverage for Avnu based on LTV ratios and price drop protection
186
- * @returns {number} The calculated leverage value
187
- */
188
- export const calculateVesuLeverage = () => {
189
- const max_ltv_ratio = (1 - MAX_PRICE_DROP_PERCENTAGE) * MAX_LIQUIDATION_RATIO; //0.75
190
- const our_ltv_ratio = Math.floor(max_ltv_ratio * 100) - 5; //buffer of 5% to prevent liquidation
191
- const leverage = 1 / (1 - our_ltv_ratio / 100);
192
- return Math.ceil(leverage * 10) / 10;
193
- };
194
-
195
- /**
196
- * calculate leverage for extended
197
- * calculates the maximum safe leverage for Extended based on maintenance margin and price drop protection
198
- * @returns {number} The calculated leverage value
199
- */
200
- export const calculateExtendedLevergae = () => {
201
- const extended_leverage_max =
202
- 1 / (MAINTENANCE_MARGIN + MAX_PRICE_DROP_PERCENTAGE);
203
- return Math.floor(extended_leverage_max);
204
- };
205
-
206
- /**
207
- * calculates the debt amount for leverage operations
208
- * Determines how much debt to add or remove based on collateral changes and target health factor
209
- * @param {Web3Number} collateralAmount - Current collateral amount
210
- * @param {Web3Number} debtAmount - Current debt amount
211
- * @param {number} debtPrice - Current price of the debt token
212
- * @param {number} maxLtv - Maximum loan-to-value ratio (default: MAX_LTV_BTC_USDC)
213
- * @param {number} addedAmount - Amount being added to collateral
214
- * @param {number} collateralPrice - Current price of the collateral token
215
- * @param {boolean} isDeposit - Whether this is a deposit (true) or withdrawal (false)
216
- * @returns {object} Object containing deltadebtAmountUnits and isIncrease flag
217
- */
218
- // In case BTC_PRICE DROPS the added amount will be zero, and use this formula to calculated the debt that needs to be paid to maintain the ltv
219
- export const calculateDebtAmount = (
220
- collateralAmount: Web3Number,
221
- debtAmount: Web3Number,
222
- debtPrice: number,
223
- maxLtv: number = MAX_LIQUIDATION_RATIO,
224
- addedAmount: Web3Number, // this is in btc
225
- collateralPrice: number,
226
- isDeposit: boolean
227
- ) => {
228
- try {
229
- // => X = (((collateral + legDepositAmount) * collateralPrice * ltv) - (debt * debtPrice * target hf)) / (target hf - ltv)
230
- const addedCollateral = addedAmount.multipliedBy(isDeposit ? 1 : -1);
231
- const numerator1 = (collateralAmount
232
- .plus(addedCollateral))
233
- .multipliedBy(collateralPrice)
234
- .multipliedBy(maxLtv);
235
- const numerator2 = debtAmount
236
- .multipliedBy(debtPrice)
237
- .multipliedBy(TARGET_HF);
238
- const denominator = TARGET_HF - maxLtv;
239
- const x_debt_usd = numerator1.minus(numerator2).dividedBy(denominator);
240
- let deltadebtAmountUnits = new Web3Number(
241
- x_debt_usd.dividedBy(debtPrice).toFixed(2),
242
- 2
243
- );
244
- let isIncrease = x_debt_usd.greaterThan(0);
245
- return { deltadebtAmountUnits, isIncrease };
246
- } catch (err) {
247
- return { deltadebtAmountUnits: null, isIncrease: null };
248
- }
249
- };
250
-
251
- /**
252
- * calculate the debt amount to be repaid for withdrawal
253
- * @param debtAmount in debt units
254
- * @param collateralAmount in collateral units
255
- * @param maxLtv in percentage
256
- * @param withdrawalAmount in collateral units
257
- * @param collateralPrice in usd
258
- * @param debtPrice in usd
259
- * @returns deltadebtAmountUnits in debt units
260
- * isIncrease: true if the debt amount is increasing, false if it is decreasing
261
- */
262
- export const calculateDebtReductionAmountForWithdrawal = (
263
- debtAmount: Web3Number,
264
- collateralAmount: Web3Number,
265
- maxLtv: number = MAX_LTV_BTC_USDC,
266
- withdrawalAmount: Web3Number,
267
- collateralPrice: number,
268
- debtPrice: number,
269
- usdcDecimals: number
270
- ) => {
271
- try {
272
- const vesuLeverage = calculateVesuLeverage();
273
- const numerator1 = collateralAmount
274
- .multipliedBy(collateralPrice)
275
- .multipliedBy(maxLtv)
276
- .multipliedBy(-1);
277
- withdrawalAmount = withdrawalAmount.multipliedBy(vesuLeverage);
278
- const numerator2 = debtAmount
279
- .multipliedBy(debtPrice)
280
- .multipliedBy(TARGET_HF);
281
- const numerator3 = withdrawalAmount
282
- .multipliedBy(collateralPrice)
283
- .multipliedBy(maxLtv);
284
- const numeratorTotal = numerator1.plus(numerator2).plus(numerator3);
285
- const denominator = debtPrice * TARGET_HF;
286
- const x_debt_usdc = numeratorTotal.dividedBy(denominator);
287
- let deltadebtAmountUnits = x_debt_usdc
288
- .multipliedBy(-1)
289
- .toFixed(usdcDecimals); // means we are paying debt
290
- return { deltadebtAmountUnits };
291
- } catch (err) {
292
- return { deltadebtAmountUnits: null };
293
- }
294
- };
295
-
296
- /**
297
- * calculate the amount to deposit on extended when incurring losses
298
- * @param client - The client
299
- * @returns The amount to deposit on extended when incurring losses
300
- */
301
- export const calculateAmountDepositOnExtendedWhenIncurringLosses = async (
302
- client: ExtendedWrapper
303
- ) => {
304
- try {
305
- const extendedHoldings = await client.getHoldings();
306
- const extended_leverage = calculateExtendedLevergae();
307
- const latestPosition = (await client.getPositions()).data.pop();
308
- if (!extendedHoldings || !latestPosition) {
309
- logger.error(`error getting extended position: extendedHoldings=${extendedHoldings}, latestPosition=${latestPosition}`);
310
- return null;
311
- }
312
- const positionValueInUSD = new Web3Number(latestPosition.value, USDC_TOKEN_DECIMALS);
313
- const equity = extendedHoldings.data.equity;
314
- const deposit = positionValueInUSD.dividedBy(extended_leverage).minus(equity).toFixed(2);
315
- return new Web3Number(deposit, USDC_TOKEN_DECIMALS);
316
- } catch (err) {
317
- logger.error(`error calculating amount deposit on extended when incurring losses: ${err}`);
318
- return null;
319
- }
320
- };
321
-
322
- export const calculateExposureDelta = (
323
- exposure_extended: number,
324
- exposure_vesu: number
325
- ) => {
326
- const exposure_delta = new Web3Number(exposure_extended - exposure_vesu, 2);
327
- return exposure_delta.absoluteValue().toNumber();
328
- };
329
-
330
- /// In case BTC PRICE DROPS
331
- // 1. calculate the ltv on vesu
332
- // 2. Find the debt that needs to be paid to maintain the ltv
333
-
334
- /**
335
- * calculate the delta percentage between the current btc price and the last btc price
336
- * @param {number} btcPrice - The current btc price
337
- * @param {number} lastBtcPrice - The last btc price
338
- * @returns {number} The delta percentage
339
- */
340
- export const calculateBTCPriceDelta = (
341
- btcPrice: number,
342
- lastBtcPrice: number
343
- ) => {
344
- return ((btcPrice - lastBtcPrice) / lastBtcPrice) * 100;
345
- };
346
-
347
- export const calculateVesUPositionSizeGivenExtended = (
348
- extendedPositonValue: number,
349
- extendedHoldingAmount: Web3Number,
350
- collateralAmount: Web3Number,
351
- collateralPrice: number
352
- ) => {
353
- const extendedLeverage = calculateExtendedLevergae();
354
- const vesuLeverage = calculateVesuLeverage();
355
- const extendedAmount = extendedHoldingAmount;
356
- const extendedAmountInBTC = extendedAmount
357
- .dividedBy(collateralPrice)
358
- const numerator1 = extendedAmount.multipliedBy(extendedLeverage)
359
- .plus(extendedPositonValue)
360
- const numerator2 = collateralAmount
361
- .multipliedBy(collateralPrice)
362
- .multipliedBy(-1);
363
- const vesuAmountInUsd = numerator1.plus(numerator2).dividedBy(vesuLeverage);
364
- const vesuAmountInBTC = vesuAmountInUsd
365
- .dividedBy(collateralPrice)
366
- .toFixed(WBTC_TOKEN_DECIMALS);
367
- return {
368
- vesuAmountInUsd: vesuAmountInUsd.toFixed(2),
369
- vesuAmountInBTC: new Web3Number(vesuAmountInBTC, WBTC_TOKEN_DECIMALS),
370
- extendedAmountInBTC: extendedAmountInBTC,
371
- };
372
- };