import { type Address, type Hex } from "viem"; import { type RoundingDirection } from "../../math/index.js"; import { type IToken, WrappedToken } from "../../token/index.js"; import type { BigIntish, Hash } from "../../types.js"; import { type CapacityLimit } from "../../utils.js"; import type { IAccrualVaultV2Adapter } from "./VaultV2Adapter.js"; /** Plain input shape for one Vault V2 liquidity allocation. */ export interface IVaultV2Allocation { id: Hash; absoluteCap: bigint; relativeCap: bigint; allocation: bigint; } /** Plain input shape for a Morpho Vault V2. */ export interface IVaultV2 extends IToken { asset: Address; /** * Stored total assets at `lastUpdate`, excluding virtually accrued interest. */ _totalAssets: bigint; /** * The total supply of shares. */ totalSupply: bigint; virtualShares: bigint; maxRate: bigint; lastUpdate: bigint; adapters: Address[]; liquidityAdapter: Address; liquidityData: Hex; liquidityAllocations: IVaultV2Allocation[] | undefined; performanceFee: bigint; managementFee: bigint; performanceFeeRecipient: Address; managementFeeRecipient: Address; /** Whether the performance fee recipient can receive vault shares. Defaults to `true`. */ performanceFeeRecipientCanReceiveShares?: boolean; /** Whether the management fee recipient can receive vault shares. Defaults to `true`. */ managementFeeRecipientCanReceiveShares?: boolean; } /** Represents a Morpho Vault V2 and its fee, adapter, and accounting state. */ export declare class VaultV2 extends WrappedToken implements IVaultV2 { readonly asset: Address; _totalAssets: bigint; totalSupply: bigint; virtualShares: bigint; maxRate: bigint; lastUpdate: bigint; adapters: `0x${string}`[]; liquidityAdapter: `0x${string}`; liquidityData: `0x${string}`; liquidityAllocations: IVaultV2Allocation[] | undefined; performanceFee: bigint; managementFee: bigint; performanceFeeRecipient: `0x${string}`; managementFeeRecipient: `0x${string}`; /** Whether the performance fee recipient can receive vault shares. */ performanceFeeRecipientCanReceiveShares: boolean; /** Whether the management fee recipient can receive vault shares. */ managementFeeRecipientCanReceiveShares: boolean; constructor({ asset, _totalAssets, totalSupply, virtualShares, maxRate, lastUpdate, adapters, liquidityAdapter, liquidityData, liquidityAllocations, performanceFee, managementFee, performanceFeeRecipient, managementFeeRecipient, performanceFeeRecipientCanReceiveShares, managementFeeRecipientCanReceiveShares, ...config }: IVaultV2); /** * Converts Vault V2 shares to underlying assets using the stored pre-accrual totals. * * Pairs `_totalAssets` with `totalSupply` and rounds down. Accrue the vault first when a * post-accrual conversion is required. * * @param shares - Vault shares to convert, in the share token's smallest unit. * @returns The equivalent underlying assets, rounded down to the asset token's smallest unit. * @throws {DivisionByZeroError} when `totalSupply + virtualShares` is zero. * @example * ```ts * import { fetchVaultV2 } from "@morpho-org/blue-sdk-viem"; * import { createPublicClient, http } from "viem"; * import { base } from "viem/chains"; * * const client = createPublicClient({ chain: base, transport: http() }); * const vaultV2Address = "0xfDE48B9B8568189f629Bc5209bf5FA826336557a"; * const vault = await fetchVaultV2(vaultV2Address, client); * const assets = vault.toAssets(1_000_000_000_000_000_000n); * // assets satisfies bigint * ``` */ toAssets(shares: BigIntish): bigint; /** * Converts underlying assets to Vault V2 shares using the stored pre-accrual totals. * * Pairs `_totalAssets` with `totalSupply`. Accrue the vault first when a post-accrual conversion * is required. * * @param assets - Underlying assets to convert, in the asset token's smallest unit. * @param rounding - Optional rounding direction. Defaults to `"Down"`. * @returns The equivalent amount of Vault V2 shares, rounded in the requested direction. * @example * ```ts * import { fetchVaultV2 } from "@morpho-org/blue-sdk-viem"; * import { createPublicClient, http } from "viem"; * import { base } from "viem/chains"; * * const client = createPublicClient({ chain: base, transport: http() }); * const vaultV2Address = "0xfDE48B9B8568189f629Bc5209bf5FA826336557a"; * const vault = await fetchVaultV2(vaultV2Address, client); * const shares = vault.toShares(1_000_000n, "Up"); * // shares satisfies bigint * ``` */ toShares(assets: BigIntish, rounding?: RoundingDirection): bigint; protected _wrap(amount: BigIntish, rounding: RoundingDirection): bigint; protected _unwrap(amount: BigIntish, rounding: RoundingDirection): bigint; } /** Plain input shape for a Morpho Vault V2 paired with accrued adapter state. */ export interface IAccrualVaultV2 extends Omit { } /** Represents a Morpho Vault V2 with accrued adapter and liquidity state. */ export declare class AccrualVaultV2 extends VaultV2 implements IAccrualVaultV2 { accrualLiquidityAdapter: IAccrualVaultV2Adapter | undefined; accrualAdapters: IAccrualVaultV2Adapter[]; assetBalance: bigint; /** * The force deallocate penalty for each adapter, keyed by adapter address. */ forceDeallocatePenalties: Record; constructor(vault: IAccrualVaultV2, accrualLiquidityAdapter: IAccrualVaultV2Adapter | undefined, accrualAdapters: IAccrualVaultV2Adapter[], assetBalance: bigint, /** * The force deallocate penalty for each adapter, keyed by adapter address. */ forceDeallocatePenalties: Record); /** * Returns the vault's deposit capacity for a requested underlying asset amount. * * Returns the requested amount when no liquidity adapter is configured. Otherwise, applies the * liquidity adapter's capacity and every hydrated absolute and relative allocation cap. * * @param assets - Maximum underlying assets to deposit, in the asset token's smallest unit. * @returns A capacity limit containing the depositable asset amount and its binding reason. * @throws {VaultV2Errors.UnsupportedLiquidityAdapter} when a nonzero liquidity adapter lacks * hydrated adapter state or allocation-cap state. * @example * ```ts * import { fetchAccrualVaultV2 } from "@morpho-org/blue-sdk-viem"; * import { createPublicClient, http } from "viem"; * import { base } from "viem/chains"; * * const client = createPublicClient({ chain: base, transport: http() }); * const vaultV2Address = "0xfDE48B9B8568189f629Bc5209bf5FA826336557a"; * const vault = await fetchAccrualVaultV2(vaultV2Address, client); * const limit = vault.maxDeposit(1_000_000n); * // limit satisfies CapacityLimit * ``` */ maxDeposit(assets: BigIntish): CapacityLimit; /** * Returns the underlying assets withdrawable for a requested Vault V2 share amount. * * Caps the converted assets by the vault's asset balance plus its hydrated liquidity adapter's * withdrawal capacity. A Vault V1 liquidity adapter with zero parent allocation contributes * zero, even when it still holds residual Vault V1 shares. * * @param shares - Maximum Vault V2 shares to redeem, in the share token's smallest unit. * @returns A capacity limit containing the withdrawable asset amount and either the `balance` or * `liquidity` limiting reason. * @throws {DivisionByZeroError} when `totalSupply + virtualShares` is zero. * @throws {InvalidMarketParamsError} when a configured Morpho Blue market liquidity adapter's * liquidity data cannot be decoded. * @example * ```ts * import { fetchAccrualVaultV2 } from "@morpho-org/blue-sdk-viem"; * import { createPublicClient, http } from "viem"; * import { base } from "viem/chains"; * * const client = createPublicClient({ chain: base, transport: http() }); * const vaultV2Address = "0xfDE48B9B8568189f629Bc5209bf5FA826336557a"; * const vault = await fetchAccrualVaultV2(vaultV2Address, client); * const limit = vault.maxWithdraw(1_000_000_000_000_000_000n); * // limit satisfies CapacityLimit * ``` */ maxWithdraw(shares: BigIntish): CapacityLimit; /** * Projects the vault's interest and fee accounting to a timestamp without mutating this instance. * * Sums the vault's asset balance and every adapter's projected real assets, caps asset growth by * `maxRate`, and mints projected performance and management fee shares. A fee share amount is * zero when its recipient cannot receive vault shares. * Timestamps at or before this vault's `lastUpdate` return an unchanged copy and zero fee * shares without accruing nested adapters. Forward accrual also accrues every adapter * implementing `accrueInterest` to `timestamp`, so contributing nested markets and positions * share the vault's `lastUpdate`; when registered among `accrualAdapters`, the liquidity adapter * reuses that accrued instance, while an unregistered liquidity adapter remains unchanged. * Adapters without `accrueInterest`, zero-allocation or zero-share Vault V1 adapters, and nested * markets already ahead of `timestamp` keep their snapshots. * * @param timestamp - Accrual timestamp in seconds. * @returns An object containing the accrued `AccrualVaultV2`, projected performance fee shares, * and projected management fee shares. * @throws {UnknownMarketAllocationError} when a nested Vault V1 withdraw queue references a * market without matching allocation state. * @throws {UnsupportedMarketIrmError} when forward projection of an underlying market with positive * debt requires an unsupported IRM. * @example * ```ts * import { fetchAccrualVaultV2 } from "@morpho-org/blue-sdk-viem"; * import { createPublicClient, http } from "viem"; * import { base } from "viem/chains"; * * const client = createPublicClient({ chain: base, transport: http() }); * const vaultV2Address = "0xfDE48B9B8568189f629Bc5209bf5FA826336557a"; * const block = await client.getBlock(); * const vault = await fetchAccrualVaultV2(vaultV2Address, client, { * blockNumber: block.number, * }); * const result = vault.accrueInterest(block.timestamp); * // result satisfies { * // vault: AccrualVaultV2; * // performanceFeeShares: bigint; * // managementFeeShares: bigint; * // } * ``` */ accrueInterest(timestamp: BigIntish): { vault: AccrualVaultV2; performanceFeeShares: bigint; managementFeeShares: bigint; }; }