UNPKG

@lidofinance/lido-ethereum-sdk

Version:

<div style="display: flex;" align="center"> <h1 align="center">Lido Ethereum SDK</h1> </div>

831 lines 55.1 kB
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) { var useValue = arguments.length > 2; for (var i = 0; i < initializers.length; i++) { value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); } return useValue ? value : void 0; }; var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); var _, done = false; for (var i = decorators.length - 1; i >= 0; i--) { var context = {}; for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; for (var p in contextIn.access) context.access[p] = contextIn.access[p]; context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); if (kind === "accessor") { if (result === void 0) continue; if (result === null || typeof result !== "object") throw new TypeError("Object expected"); if (_ = accept(result.get)) descriptor.get = _; if (_ = accept(result.set)) descriptor.set = _; if (_ = accept(result.init)) initializers.unshift(_); } else if (_ = accept(result)) { if (kind === "field") initializers.unshift(_); else descriptor[key] = _; } } if (target) Object.defineProperty(target, contextIn.name, descriptor); done = true; }; import { encodeFunctionData, isAddressEqual, zeroAddress } from 'viem'; import { BusModule } from './bus-module.js'; import { ERROR_CODE, NOOP } from '../common/index.js'; import { Multicall3AbiUtils, } from './abi/index.js'; import { Cache, ErrorHandler, Logger } from '../common/decorators/index.js'; import { getVaultReport } from './utils/report.js'; import { PROXY_CODE_PAD_LEFT, PROXY_CODE_PAD_RIGHT } from './consts/index.js'; import { calculateHealth, } from './utils/overview/calculate-health.js'; import { bigIntCeilDiv, bigIntMax, bigIntMin, } from '../common/utils/bigint-math.js'; let LidoSDKVaultEntity = (() => { var _a; let _classSuper = BusModule; let _instanceExtraInitializers = []; let _parseProps_decorators; let _getDashboardContract_decorators; let _getDashboardAddress_decorators; let _fund_decorators; let _fundPopulateTx_decorators; let _fundSimulateTx_decorators; let _withdraw_decorators; let _withdrawSimulateTx_decorators; let _withdrawPopulateTx_decorators; let _mintShares_decorators; let _mintSharesSimulateTx_decorators; let _mintSharesPopulateTx_decorators; let _mint_decorators; let _mintSimulateTx_decorators; let _mintPopulateTx_decorators; let __mintStETH_decorators; let __mintStETHSimulateTx_decorators; let __mintWstETH_decorators; let __mintWstETHSimulateTx_decorators; let _burnShares_decorators; let _burnSharesSimulateTx_decorators; let _burnSharesPopulateTx_decorators; let _approve_decorators; let _burn_decorators; let _burnSimulateTx_decorators; let __burnStETHSimulateTx_decorators; let __burnWstETHSimulateTx_decorators; let _burnPopulateTx_decorators; let _grantRoles_decorators; let _grantRolesSimulateTx_decorators; let _grantRolesPopulateTx_decorators; let _revokeRoles_decorators; let _revokeRolesSimulateTx_decorators; let _revokeRolesPopulateTx_decorators; let _disburseNodeOperatorFee_decorators; let _disburseNodeOperatorFeeSimulateTx_decorators; let _disburseNodeOperatorFeePopulateTx_decorators; let _submitLatestReport_decorators; let _submitLatestReportSimulateTx_decorators; let _submitLatestReportPopulateTx_decorators; let _getRoleMembers_decorators; let _isDashboard_decorators; let _getLatestReport_decorators; let _getVaultOverviewData_decorators; let _calculateOverview_decorators; let _calculateHealth_decorators; return _a = class LidoSDKVaultEntity extends _classSuper { constructor(props) { super(props); Object.defineProperty(this, "dashboardAddress", { enumerable: true, configurable: true, writable: true, value: __runInitializers(this, _instanceExtraInitializers) }); Object.defineProperty(this, "vaultAddress", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "skipDashboardCheck", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.vaultAddress = props.vaultAddress; this.dashboardAddress = props.dashboardAddress; this.skipDashboardCheck = !!props.skipDashboardCheck; } async parseProps(props) { const dashboard = await this.getDashboardContract(); return { ...props, dashboard, callback: props.callback ?? NOOP, account: await this.bus.core.useAccount(props.account), }; } getVaultContract() { return this.bus.contracts.getContractVault(this.vaultAddress); } async getDashboardContract() { const dashboardAddress = await this.getDashboardAddress(); if (!dashboardAddress) { throw this.bus.core.error({ code: ERROR_CODE.READ_ERROR, message: 'Dashboard address is not found.', }); } return this.bus.contracts.getContractVaultDashboard(dashboardAddress); } getVaultAddress() { return this.vaultAddress; } async getDashboardAddress() { if (this.dashboardAddress) { return this.dashboardAddress; } const vaultHub = await this.bus.contracts.getContractVaultHub(); const isVaultConnected = await vaultHub.read.isVaultConnected([ this.vaultAddress, ]); const vaultConnection = await vaultHub.read.vaultConnection([ this.vaultAddress, ]); const vaultOwner = await (await this.getVaultContract()).read.owner(); const supposedDashboardAddress = !isAddressEqual(vaultConnection.owner, zeroAddress) ? vaultConnection.owner : vaultOwner; const isOwnerDashboard = await this.isDashboard(supposedDashboardAddress); if (!isOwnerDashboard && isVaultConnected && !this.skipDashboardCheck) { throw this.bus.core.error({ code: ERROR_CODE.NOT_SUPPORTED, message: 'Owner of vault is not dashboard contract', }); } this.dashboardAddress = supposedDashboardAddress; return this.dashboardAddress; } // fund methods async fund(props) { const parsedProps = await this.parseProps(props); return this.bus.core.performTransaction({ ...parsedProps, getGasLimit: (options) => parsedProps.dashboard.estimateGas.fund({ ...options, value: props.value, }), sendTransaction: (options) => parsedProps.dashboard.write.fund({ ...options, value: props.value }), }); } async fundPopulateTx(props) { const parsedProps = await this.parseProps(props); return { from: parsedProps.account.address, to: parsedProps.dashboard.address, value: props.value, data: encodeFunctionData({ abi: parsedProps.dashboard.abi, functionName: 'fund', args: [], }), }; } async fundSimulateTx(props) { const { dashboard, account } = await this.parseProps(props); return await dashboard.simulate.fund({ account, value: props.value, }); } // withdraw methods async withdraw(props) { const parsedProps = await this.parseProps(props); return this.bus.core.performTransaction({ ...parsedProps, getGasLimit: (options) => parsedProps.dashboard.estimateGas.withdraw([props.address, props.amount], options), sendTransaction: (options) => parsedProps.dashboard.write.withdraw([props.address, props.amount], options), }); } async withdrawSimulateTx(props) { const parsedProps = await this.parseProps(props); return await parsedProps.dashboard.simulate.withdraw([props.address, props.amount], { account: parsedProps.account }); } async withdrawPopulateTx(props) { const parsedProps = await this.parseProps(props); return { from: parsedProps.account.address, to: parsedProps.dashboard.address, data: encodeFunctionData({ abi: parsedProps.dashboard.abi, functionName: 'withdraw', args: [props.address, props.amount], }), }; } // mint methods async mintShares(props) { const parsedProps = await this.parseProps(props); return this.bus.core.performTransaction({ ...parsedProps, getGasLimit: (options) => parsedProps.dashboard.estimateGas.mintShares([props.recipient, props.amountOfShares], options), sendTransaction: (options) => parsedProps.dashboard.write.mintShares([props.recipient, props.amountOfShares], options), }); } async mintSharesSimulateTx(props) { const parsedProps = await this.parseProps(props); return await parsedProps.dashboard.simulate.mintShares([props.recipient, props.amountOfShares], { account: parsedProps.account }); } async mintSharesPopulateTx(props) { const parsedProps = await this.parseProps(props); return { from: parsedProps.account.address, to: parsedProps.dashboard.address, data: encodeFunctionData({ abi: parsedProps.dashboard.abi, functionName: 'mintShares', args: [props.recipient, props.amountOfShares], }), }; } async mint(props) { if (props.token === 'wsteth') { return this._mintWstETH(props); } else if (props.token === 'steth') { return this._mintStETH(props); } throw new Error('Unsupported token'); } async mintSimulateTx(props) { if (props.token === 'wsteth') { return this._mintWstETHSimulateTx(props); } else if (props.token === 'steth') { return this._mintStETHSimulateTx(props); } throw new Error('Unsupported token'); } _validateToken(token) { if (!['wsteth', 'steth'].includes(token)) { throw this.bus.core.error({ code: ERROR_CODE.INVALID_ARGUMENT, message: `Invalid token ${token}.`, }); } } async mintPopulateTx(props) { this._validateToken(props.token); const parsedProps = await this.parseProps(props); const functionName = props.token === 'steth' ? 'mintStETH' : 'mintWstETH'; return { from: parsedProps.account.address, to: parsedProps.dashboard.address, data: encodeFunctionData({ abi: parsedProps.dashboard.abi, functionName, args: [props.recipient, props.amount], }), }; } async _mintStETH(props) { const parsedProps = await this.parseProps(props); return this.bus.core.performTransaction({ ...parsedProps, getGasLimit: (options) => parsedProps.dashboard.estimateGas.mintStETH([props.recipient, props.amount], options), sendTransaction: (options) => parsedProps.dashboard.write.mintStETH([props.recipient, props.amount], options), }); } async _mintStETHSimulateTx(props) { const parsedProps = await this.parseProps(props); return await parsedProps.dashboard.simulate.mintStETH([props.recipient, props.amount], { account: parsedProps.account }); } async _mintWstETH(props) { const parsedProps = await this.parseProps(props); return this.bus.core.performTransaction({ ...parsedProps, getGasLimit: (options) => parsedProps.dashboard.estimateGas.mintWstETH([props.recipient, props.amount], options), sendTransaction: (options) => parsedProps.dashboard.write.mintWstETH([props.recipient, props.amount], options), }); } async _mintWstETHSimulateTx(props) { const parsedProps = await this.parseProps(props); return await parsedProps.dashboard.simulate.mintWstETH([props.recipient, props.amount], { account: parsedProps.account }); } // burn methods async burnShares(props) { const parsedProps = await this.parseProps(props); return this.bus.core.performTransaction({ ...parsedProps, getGasLimit: (options) => parsedProps.dashboard.estimateGas.burnShares([props.amountOfShares], options), sendTransaction: (options) => parsedProps.dashboard.write.burnShares([props.amountOfShares], options), }); } async burnSharesSimulateTx(props) { const parsedProps = await this.parseProps(props); return await parsedProps.dashboard.simulate.burnShares([props.amountOfShares], { account: parsedProps.account }); } async burnSharesPopulateTx(props) { const parsedProps = await this.parseProps(props); return { from: parsedProps.account.address, to: parsedProps.dashboard.address, data: encodeFunctionData({ abi: parsedProps.dashboard.abi, functionName: 'burnShares', args: [props.amountOfShares], }), }; } async approve(props) { const isSteth = props.token === 'steth'; const tokenContract = isSteth ? this.bus.steth : this.bus.wsteth; const dashboardAddress = await this.getDashboardAddress(); return await tokenContract.approve({ to: dashboardAddress, amount: props.amount, }); } async _validateAllowance(props) { const isSteth = props.token === 'steth'; const tokenContract = isSteth ? this.bus.steth : this.bus.wsteth; const dashboardAddress = await this.getDashboardAddress(); const allowance = await tokenContract.allowance({ to: dashboardAddress, }); if (allowance < props.amount) { throw this.bus.core.error({ code: ERROR_CODE.INVALID_ARGUMENT, message: `Allowance less then amount. Required to populate approve for ${props.token}`, }); } } async burn(props) { await this._validateAllowance(props); if (props.token === 'wsteth') { return this._burnWstETH(props); } else if (props.token === 'steth') { return this._burnStETH(props); } throw new Error('Unsupported token'); } async _burnStETH(props) { const parsedProps = await this.parseProps(props); return this.bus.core.performTransaction({ ...parsedProps, getGasLimit: (options) => parsedProps.dashboard.estimateGas.burnStETH([props.amount], options), sendTransaction: (options) => parsedProps.dashboard.write.burnStETH([props.amount], options), }); } async _burnWstETH(props) { const parsedProps = await this.parseProps(props); return this.bus.core.performTransaction({ ...parsedProps, getGasLimit: (options) => parsedProps.dashboard.estimateGas.burnWstETH([props.amount], options), sendTransaction: (options) => parsedProps.dashboard.write.burnWstETH([props.amount], options), }); } async burnSimulateTx(props) { if (props.token === 'wsteth') { return this._burnWstETHSimulateTx(props); } else if (props.token === 'steth') { return this._burnStETHSimulateTx(props); } throw new Error('Unsupported token'); } async _burnStETHSimulateTx(props) { const parsedProps = await this.parseProps(props); return await parsedProps.dashboard.simulate.burnStETH([props.amount], { account: parsedProps.account, }); } async _burnWstETHSimulateTx(props) { const parsedProps = await this.parseProps(props); return await parsedProps.dashboard.simulate.burnWstETH([props.amount], { account: parsedProps.account, }); } async burnPopulateTx(props) { this._validateToken(props.token); const parsedProps = await this.parseProps(props); const functionName = props.token === 'steth' ? 'burnStETH' : 'burnWstETH'; return { from: parsedProps.account.address, to: parsedProps.dashboard.address, data: encodeFunctionData({ abi: parsedProps.dashboard.abi, functionName, args: [props.amount], }), }; } async _validateRoles(roles) { const ROLES = await this.bus.constants.ROLES(); for (const role of roles) { if (!Object.values(ROLES).includes(role.role)) { throw this.bus.core.error({ code: ERROR_CODE.TRANSACTION_ERROR, message: `Invalid role "${role.role}" found.`, }); } } } // set role methods async grantRoles(props) { await this._validateRoles(props.roles); const parsedProps = await this.parseProps(props); return this.bus.core.performTransaction({ ...parsedProps, getGasLimit: (options) => parsedProps.dashboard.estimateGas.grantRoles([props.roles], options), sendTransaction: (options) => parsedProps.dashboard.write.grantRoles([props.roles], options), }); } async grantRolesSimulateTx(props) { await this._validateRoles(props.roles); const parsedProps = await this.parseProps(props); return parsedProps.dashboard.simulate.grantRoles([props.roles], { account: parsedProps.account, }); } async grantRolesPopulateTx(props) { await this._validateRoles(props.roles); const parsedProps = await this.parseProps(props); return { from: parsedProps.account.address, to: parsedProps.dashboard.address, data: encodeFunctionData({ abi: parsedProps.dashboard.abi, functionName: 'grantRoles', args: [props.roles], }), }; } // set role methods async revokeRoles(props) { await this._validateRoles(props.roles); const parsedProps = await this.parseProps(props); return this.bus.core.performTransaction({ ...parsedProps, getGasLimit: (options) => parsedProps.dashboard.estimateGas.revokeRoles([props.roles], options), sendTransaction: (options) => parsedProps.dashboard.write.revokeRoles([props.roles], options), }); } async revokeRolesSimulateTx(props) { await this._validateRoles(props.roles); const parsedProps = await this.parseProps(props); return parsedProps.dashboard.simulate.revokeRoles([props.roles], { account: parsedProps.account, }); } async revokeRolesPopulateTx(props) { await this._validateRoles(props.roles); const parsedProps = await this.parseProps(props); return { from: parsedProps.account.address, to: parsedProps.dashboard.address, data: encodeFunctionData({ abi: parsedProps.dashboard.abi, functionName: 'revokeRoles', args: [props.roles], }), }; } // disburseNodeOperatorFee methods async disburseNodeOperatorFee(props) { const parsedProps = await this.parseProps(props); return this.bus.core.performTransaction({ ...parsedProps, getGasLimit: (options) => parsedProps.dashboard.estimateGas.disburseFee(options), sendTransaction: (options) => parsedProps.dashboard.write.disburseFee(options), }); } async disburseNodeOperatorFeeSimulateTx(props) { const parsedProps = await this.parseProps(props); return parsedProps.dashboard.simulate.disburseFee({ account: parsedProps.account, }); } async disburseNodeOperatorFeePopulateTx(props) { const parsedProps = await this.parseProps(props); return { from: parsedProps.account.address, to: parsedProps.dashboard.address, data: encodeFunctionData({ abi: parsedProps.dashboard.abi, functionName: 'disburseFee', args: [], }), }; } async submitLatestReport(props) { return this.bus.lazyOracle.submitLatestReport({ ...props, vaultAddress: this.vaultAddress, }); } async submitLatestReportSimulateTx(props) { return this.bus.lazyOracle.submitLatestReportSimulateTx({ ...props, vaultAddress: this.vaultAddress, }); } async submitLatestReportPopulateTx(props) { return this.bus.lazyOracle.submitLatestReportPopulateTx({ ...props, vaultAddress: this.vaultAddress, }); } async getRoleMembers(props) { const address = await this.getDashboardAddress(); const dashboardContract = await this.bus.contracts.getContractVaultDashboard(address); return dashboardContract.read.getRoleMembers([props.role]); } async isDashboard(address) { const dashboardCode = await this.bus.core.publicClient.getCode({ address }); const vaultFactory = await this.bus.contracts.getContractVaultFactory(); const implementation = await vaultFactory.read.DASHBOARD_IMPL(); const proxyCode = PROXY_CODE_PAD_LEFT + implementation.slice(2).toLowerCase() + PROXY_CODE_PAD_RIGHT; return dashboardCode?.startsWith(proxyCode) || false; } async getLatestReport(props) { const vaultAddress = this.getVaultAddress(); const [lazyOracle, hub] = await Promise.all([ this.bus.contracts.getContractLazyOracle(), this.bus.contracts.getContractVaultHub(), ]); const [latestVaultReport, latestHubReport] = await Promise.all([ hub.read.latestReport([vaultAddress]), lazyOracle.read.latestReportData(), ]); const latestHubReportTimestamp = latestHubReport[0]; const latestHubReportCID = latestHubReport[3]; const isReportAvailable = latestHubReportTimestamp > latestVaultReport.timestamp; const report = latestHubReportCID ? await getVaultReport({ cid: latestHubReportCID, vault: vaultAddress, ...props, }) : null; return { report, isReportAvailable }; } async getVaultOverviewData(props) { const vaultAddress = this.getVaultAddress(); const blockNumber = props.blockNumber ?? (await this.bus.core.toBlockNumber({ block: 'latest' })); const report = props.report ?? (await this.getLatestReport()).report?.data; const [dashboard, vaultContract, hub, operatorGrid, lazyOracle, lidoContract, // eslint-disable-next-line @typescript-eslint/await-thenable ] = await Promise.all([ this.getDashboardContract(), this.getVaultContract(), this.bus.contracts.getContractVaultHub(), this.bus.contracts.getContractOperatorGrid(), this.bus.contracts.getContractLazyOracle(), this.bus.core.getLidoContract(), ]); const nodeOperator = await vaultContract.read.nodeOperator(); const withdrawalCredentials = await vaultContract.read.withdrawalCredentials(); const vaultConnection = await hub.read.vaultConnection([vaultAddress]); const reportLiabilityShares = typeof report?.liabilityShares === 'string' ? BigInt(report?.liabilityShares) : report?.liabilityShares ?? 0n; const [balance, totalValue, nodeOperatorUnclaimedFee, withdrawableEther, feeRate, totalMintingCapacityShares, mintableShares, tier, group, vaultQuarantineState, obligationsShortfallValue, [sharesToBurn, feesToSettle], rebalanceShares, vaultRecord, lockedEth, stagedBalanceWei, beaconChainDepositsPaused, // eslint-disable-next-line @typescript-eslint/await-thenable ] = await this.bus.readWithLatestReport({ vaultAddress, blockNumber, preparedMethods: [ { abi: Multicall3AbiUtils, address: this.bus.core.publicClient.chain?.contracts?.multicall3 ?.address, functionName: 'getEthBalance', args: [vaultAddress], }, dashboard.prepare.totalValue(), dashboard.prepare.accruedFee(), dashboard.prepare.withdrawableValue(), dashboard.prepare.feeRate(), dashboard.prepare.totalMintingCapacityShares(), dashboard.prepare.remainingMintingCapacityShares([0n]), operatorGrid.prepare.vaultTierInfo([vaultAddress]), operatorGrid.prepare.group([nodeOperator]), lazyOracle.prepare.vaultQuarantine([vaultAddress]), dashboard.prepare.obligationsShortfallValue(), dashboard.prepare.obligations(), hub.prepare.healthShortfallShares([vaultAddress]), hub.prepare.vaultRecord([vaultAddress]), hub.prepare.locked([vaultAddress]), vaultContract.prepare.stagedBalance(), vaultContract.prepare.beaconChainDepositsPaused(), ], }); // split call because of TS2589: Type instantiation is excessively deep and possibly infinite const [isVaultConnected, isPendingDisconnect, vaultOwner] = // eslint-disable-next-line @typescript-eslint/await-thenable await this.bus.readWithLatestReport({ vaultAddress, blockNumber, preparedMethods: [ hub.prepare.isVaultConnected([vaultAddress]), hub.prepare.isPendingDisconnect([vaultAddress]), vaultContract.prepare.owner(), ], }); const { liabilityShares, inOutDelta: inOutDeltaArray, settledLidoFees, cumulativeLidoFees, redemptionShares, ...restVaultRecord } = vaultRecord; const inOutDelta = inOutDeltaArray[1].value; const [, tierId, tierShareLimit] = tier; const { shareLimit: groupShareLimit } = group; const [liabilityStETH, mintableStETH, stETHLimit, totalMintingCapacityStETH, tierStETHLimit, stETHToBurn, rebalanceStETH, redemptionStETH, reportLiabilitySharesStETH, lidoTVLSharesLimit, // eslint-disable-next-line @typescript-eslint/await-thenable ] = await Promise.all([ lidoContract.read.getPooledEthBySharesRoundUp([liabilityShares]), lidoContract.read.getPooledEthByShares([mintableShares]), lidoContract.read.getPooledEthByShares([vaultConnection.shareLimit]), lidoContract.read.getPooledEthByShares([totalMintingCapacityShares]), lidoContract.read.getPooledEthByShares([tierShareLimit]), lidoContract.read.getPooledEthBySharesRoundUp([sharesToBurn]), lidoContract.read.getPooledEthBySharesRoundUp([rebalanceShares]), lidoContract.read.getPooledEthBySharesRoundUp([redemptionShares]), lidoContract.read.getPooledEthBySharesRoundUp([reportLiabilityShares]), lidoContract.read.getMaxMintableExternalShares(), ]); const supposedDashboardAddress = vaultConnection.owner !== zeroAddress ? vaultConnection.owner : vaultOwner; const isDashboard = await this.isDashboard(supposedDashboardAddress); return { address: vaultAddress, nodeOperator, totalValue, liabilityStETH, mintableStETH, mintableShares, stETHLimit, totalMintingCapacityShares, totalMintingCapacityStETH, inOutDelta, nodeOperatorUnclaimedFee, withdrawableEther, balance, reportLiabilitySharesStETH, feeRate, liabilityShares, withdrawalCredentials, settledLidoFees, cumulativeLidoFees, vaultQuarantineState, lockedEth, tierId, tierShareLimit, tierStETHLimit, lidoTVLSharesLimit, groupShareLimit, stagedBalanceWei, obligationsShortfallValue, stETHToBurn, feesToSettle, rebalanceShares, rebalanceStETH, redemptionShares, redemptionStETH, beaconChainDepositsPaused, isVaultConnected, isPendingDisconnect, isVaultDisconnected: !isDashboard, ...vaultConnection, ...restVaultRecord, }; } calculateOverview(args) { const BASIS_POINTS = 10000n; const { totalValue, reserveRatioBP, liabilitySharesInStethWei, forceRebalanceThresholdBP, withdrawableEther, balance, locked, nodeOperatorDisbursableFee, totalMintingCapacityStethWei, unsettledLidoFees, minimalReserve, reportLiabilitySharesStETH, } = args; const { healthRatio, isHealthy } = calculateHealth({ totalValue, liabilitySharesInStethWei, forceRebalanceThresholdBP, }); const availableToWithdrawal = withdrawableEther; const idleCapital = balance; const totalLocked = locked + nodeOperatorDisbursableFee + unsettledLidoFees; const RR = BigInt(reserveRatioBP); const oneMinusRR = BASIS_POINTS - RR; const collateral = bigIntMax(minimalReserve, bigIntCeilDiv(liabilitySharesInStethWei * BASIS_POINTS, oneMinusRR)); const recentlyRepaid = bigIntMax(0n, reportLiabilitySharesStETH - liabilitySharesInStethWei); const reservedByFormula = oneMinusRR === 0n ? 0n : bigIntCeilDiv(liabilitySharesInStethWei * BASIS_POINTS, oneMinusRR) - liabilitySharesInStethWei; const reserved = bigIntMin(totalValue - liabilitySharesInStethWei, reservedByFormula); // Prevent division by 0 const utilizationRatio = totalMintingCapacityStethWei === 0n ? 0 : Number(((liabilitySharesInStethWei * BASIS_POINTS) / totalMintingCapacityStethWei) * 100n) / Number(BASIS_POINTS); return { healthRatio, isHealthy, availableToWithdrawal, idleCapital, totalLocked, collateral, recentlyRepaid, utilizationRatio, reserved, totalMintingCapacityStethWei, }; } calculateHealth(props) { const { totalValue, liabilitySharesInStethWei, forceRebalanceThresholdBP } = props; const { healthRatio, isHealthy } = calculateHealth({ totalValue, liabilitySharesInStethWei, forceRebalanceThresholdBP, }); return { healthRatio, isHealthy }; } }, (() => { const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0; _parseProps_decorators = [Logger('Utils:')]; _getDashboardContract_decorators = [Logger('Utils:'), Cache(30 * 60 * 1000, ['dashboardAddress']), ErrorHandler()]; _getDashboardAddress_decorators = [Logger('Utils:'), Cache(30 * 60 * 1000, ['dashboardAddress']), ErrorHandler()]; _fund_decorators = [Logger('Call:'), ErrorHandler()]; _fundPopulateTx_decorators = [Logger('Utils:'), ErrorHandler()]; _fundSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; _withdraw_decorators = [Logger('Call:'), ErrorHandler()]; _withdrawSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; _withdrawPopulateTx_decorators = [Logger('Utils:'), ErrorHandler()]; _mintShares_decorators = [Logger('Call:'), ErrorHandler()]; _mintSharesSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; _mintSharesPopulateTx_decorators = [Logger('Utils:'), ErrorHandler()]; _mint_decorators = [Logger('Call:'), ErrorHandler()]; _mintSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; _mintPopulateTx_decorators = [Logger('Utils:'), ErrorHandler()]; __mintStETH_decorators = [Logger('Call:'), ErrorHandler()]; __mintStETHSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; __mintWstETH_decorators = [Logger('Call:'), ErrorHandler()]; __mintWstETHSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; _burnShares_decorators = [Logger('Call:'), ErrorHandler()]; _burnSharesSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; _burnSharesPopulateTx_decorators = [Logger('Utils:'), ErrorHandler()]; _approve_decorators = [Logger('Call:'), ErrorHandler()]; _burn_decorators = [Logger('Call:'), ErrorHandler()]; _burnSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; __burnStETHSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; __burnWstETHSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; _burnPopulateTx_decorators = [Logger('Utils:'), ErrorHandler()]; _grantRoles_decorators = [Logger('Call:'), ErrorHandler()]; _grantRolesSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; _grantRolesPopulateTx_decorators = [Logger('Utils:'), ErrorHandler()]; _revokeRoles_decorators = [Logger('Call:'), ErrorHandler()]; _revokeRolesSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; _revokeRolesPopulateTx_decorators = [Logger('Utils:'), ErrorHandler()]; _disburseNodeOperatorFee_decorators = [Logger('Call:'), ErrorHandler()]; _disburseNodeOperatorFeeSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; _disburseNodeOperatorFeePopulateTx_decorators = [Logger('Utils:'), ErrorHandler()]; _submitLatestReport_decorators = [Logger('Call:'), ErrorHandler()]; _submitLatestReportSimulateTx_decorators = [Logger('Call:'), ErrorHandler()]; _submitLatestReportPopulateTx_decorators = [Logger('Utils:'), ErrorHandler()]; _getRoleMembers_decorators = [Logger('Views:'), ErrorHandler()]; _isDashboard_decorators = [Logger('Utils:'), ErrorHandler()]; _getLatestReport_decorators = [Logger('Views:'), ErrorHandler()]; _getVaultOverviewData_decorators = [Logger('Views:'), ErrorHandler()]; _calculateOverview_decorators = [Logger('Utils:'), ErrorHandler()]; _calculateHealth_decorators = [Logger('Utils:'), ErrorHandler()]; __esDecorate(_a, null, _parseProps_decorators, { kind: "method", name: "parseProps", static: false, private: false, access: { has: obj => "parseProps" in obj, get: obj => obj.parseProps }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _getDashboardContract_decorators, { kind: "method", name: "getDashboardContract", static: false, private: false, access: { has: obj => "getDashboardContract" in obj, get: obj => obj.getDashboardContract }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _getDashboardAddress_decorators, { kind: "method", name: "getDashboardAddress", static: false, private: false, access: { has: obj => "getDashboardAddress" in obj, get: obj => obj.getDashboardAddress }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _fund_decorators, { kind: "method", name: "fund", static: false, private: false, access: { has: obj => "fund" in obj, get: obj => obj.fund }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _fundPopulateTx_decorators, { kind: "method", name: "fundPopulateTx", static: false, private: false, access: { has: obj => "fundPopulateTx" in obj, get: obj => obj.fundPopulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _fundSimulateTx_decorators, { kind: "method", name: "fundSimulateTx", static: false, private: false, access: { has: obj => "fundSimulateTx" in obj, get: obj => obj.fundSimulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _withdraw_decorators, { kind: "method", name: "withdraw", static: false, private: false, access: { has: obj => "withdraw" in obj, get: obj => obj.withdraw }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _withdrawSimulateTx_decorators, { kind: "method", name: "withdrawSimulateTx", static: false, private: false, access: { has: obj => "withdrawSimulateTx" in obj, get: obj => obj.withdrawSimulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _withdrawPopulateTx_decorators, { kind: "method", name: "withdrawPopulateTx", static: false, private: false, access: { has: obj => "withdrawPopulateTx" in obj, get: obj => obj.withdrawPopulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _mintShares_decorators, { kind: "method", name: "mintShares", static: false, private: false, access: { has: obj => "mintShares" in obj, get: obj => obj.mintShares }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _mintSharesSimulateTx_decorators, { kind: "method", name: "mintSharesSimulateTx", static: false, private: false, access: { has: obj => "mintSharesSimulateTx" in obj, get: obj => obj.mintSharesSimulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _mintSharesPopulateTx_decorators, { kind: "method", name: "mintSharesPopulateTx", static: false, private: false, access: { has: obj => "mintSharesPopulateTx" in obj, get: obj => obj.mintSharesPopulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _mint_decorators, { kind: "method", name: "mint", static: false, private: false, access: { has: obj => "mint" in obj, get: obj => obj.mint }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _mintSimulateTx_decorators, { kind: "method", name: "mintSimulateTx", static: false, private: false, access: { has: obj => "mintSimulateTx" in obj, get: obj => obj.mintSimulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _mintPopulateTx_decorators, { kind: "method", name: "mintPopulateTx", static: false, private: false, access: { has: obj => "mintPopulateTx" in obj, get: obj => obj.mintPopulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, __mintStETH_decorators, { kind: "method", name: "_mintStETH", static: false, private: false, access: { has: obj => "_mintStETH" in obj, get: obj => obj._mintStETH }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, __mintStETHSimulateTx_decorators, { kind: "method", name: "_mintStETHSimulateTx", static: false, private: false, access: { has: obj => "_mintStETHSimulateTx" in obj, get: obj => obj._mintStETHSimulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, __mintWstETH_decorators, { kind: "method", name: "_mintWstETH", static: false, private: false, access: { has: obj => "_mintWstETH" in obj, get: obj => obj._mintWstETH }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, __mintWstETHSimulateTx_decorators, { kind: "method", name: "_mintWstETHSimulateTx", static: false, private: false, access: { has: obj => "_mintWstETHSimulateTx" in obj, get: obj => obj._mintWstETHSimulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _burnShares_decorators, { kind: "method", name: "burnShares", static: false, private: false, access: { has: obj => "burnShares" in obj, get: obj => obj.burnShares }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _burnSharesSimulateTx_decorators, { kind: "method", name: "burnSharesSimulateTx", static: false, private: false, access: { has: obj => "burnSharesSimulateTx" in obj, get: obj => obj.burnSharesSimulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _burnSharesPopulateTx_decorators, { kind: "method", name: "burnSharesPopulateTx", static: false, private: false, access: { has: obj => "burnSharesPopulateTx" in obj, get: obj => obj.burnSharesPopulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _approve_decorators, { kind: "method", name: "approve", static: false, private: false, access: { has: obj => "approve" in obj, get: obj => obj.approve }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _burn_decorators, { kind: "method", name: "burn", static: false, private: false, access: { has: obj => "burn" in obj, get: obj => obj.burn }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _burnSimulateTx_decorators, { kind: "method", name: "burnSimulateTx", static: false, private: false, access: { has: obj => "burnSimulateTx" in obj, get: obj => obj.burnSimulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, __burnStETHSimulateTx_decorators, { kind: "method", name: "_burnStETHSimulateTx", static: false, private: false, access: { has: obj => "_burnStETHSimulateTx" in obj, get: obj => obj._burnStETHSimulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, __burnWstETHSimulateTx_decorators, { kind: "method", name: "_burnWstETHSimulateTx", static: false, private: false, access: { has: obj => "_burnWstETHSimulateTx" in obj, get: obj => obj._burnWstETHSimulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _burnPopulateTx_decorators, { kind: "method", name: "burnPopulateTx", static: false, private: false, access: { has: obj => "burnPopulateTx" in obj, get: obj => obj.burnPopulateTx }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _grantRoles_decorators, { kind: "method", name: "grantRoles", static: false, private: false, access: { has: obj => "grantRoles" in obj, get: obj => obj.grantRoles }, metadata: _metadata }, null, _instanceExtraInitializers); __esDecorate(_a, null, _grantRolesSimulateTx_decorators, { kind: "method", name: "grantRolesSimulateTx", static: false, private: false, access: { has: obj => "grantRolesSimulateTx" in obj, get: obj => obj.gran