> For the complete documentation index, see [llms.txt](https://docs.curvance.com/app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.curvance.com/app/developer-docs/protocol-reader.md).

# Protocol Reader

## Overview

ProtocolReader is a read-only auxiliary contract for querying market, account, pricing, liquidation, leverage, and balance data from Curvance. It lets frontends, SDKs, data indexers, and external systems batch common reads into fewer calls.

ProtocolReader stores only immutable configuration through `centralRegistry` and exposes view-only public functions. It is not a protocol write path and does not modify market state.

## Key Features

* **Data Consolidation:** Consolidates multiple variable fetches into single view functions, significantly reducing the number of EVM calls needed for comprehensive protocol queries.
* **Pure View Interface:** Contains no active storage values beyond immutable configuration and consists entirely of view functions, making it seamlessly upgradeable to support new data formats or query requirements.
* **Comprehensive Data Access**: Provides three main categories of data:
  * **Static Market Data:** Token configurations, collateral requirements, liquidation parameters.
  * **Dynamic Market Data:** returned from view calls. Oracle prices, IRM rates, utilization, liquidity, and balances are current reads, but cToken exchange rates and snapshots use non-mutating view paths such as `exchangeRate()` and `getSnapshot()`. They do not accrue state the way write paths or `exchangeRateUpdated()` / `getSnapshotUpdated()` do. Helpers with `bufferTime` can project debt forward through `debtBalanceAtTimestamp(...)`.
  * **User Data:** Individual positions, collateral balances, debt positions, and veCVE locks.

## Data Structures

#### StaticMarketData

```solidity
struct StaticMarketData {
    address _address; // MarketManager address for this market.
    uint256[] adapters; // Unique oracle adaptor type IDs used by tokens in this market (0 means empty/unsupported slot).
    uint256 cooldownLength; // Market action cooldown length in seconds (see `MARKET_COOLDOWN_LENGTH`).
    StaticMarketToken[] tokens; // Static configuration for each listed cToken in this market.
}
```

#### StaticMarketToken

```solidity
struct StaticMarketToken {
    address _address; // cToken address.
    string name; // cToken name.
    string symbol; // cToken symbol.
    uint8 decimals; // cToken decimals, matching the underlying token decimals.
    StaticMarketAsset asset; // Underlying ERC20 metadata for this cToken.
    uint256 collateralCap; // Market-wide collateral cap for this cToken, in cToken shares.
    uint256 debtCap; // Market-wide debt cap for this cToken, in underlying assets.
    bool isListed; // Whether this cToken is listed in the market.
    bool mintPaused; // Whether minting/depositing is paused for this cToken.
    bool collateralizationPaused; // Whether enabling collateral is paused for this cToken.
    bool borrowPaused; // Whether borrowing is paused for this cToken.
    bool isBorrowable; // Whether the cToken contract reports `isBorrowable()`.
    uint256 collRatio; // Collateral borrow ratio, in BPS.
    uint256 maxLeverage; // Maximum leverage derived from `collRatio`, in BPS.
    uint256 collReqSoft; // Soft liquidation collateral requirement, in BPS.
    uint256 collReqHard; // Hard liquidation collateral requirement, in BPS.
    uint256 liqIncBase; // Base liquidation incentive, in BPS.
    uint256 liqIncCurve; // Liquidation incentive curve length from soft to hard liquidation, in BPS.
    uint256 liqIncMin; // Minimum liquidation incentive during auction, in BPS.
    uint256 liqIncMax; // Maximum liquidation incentive during auction, in BPS.
    uint256 closeFactorBase; // Base close factor for soft liquidation, in BPS.
    uint256 closeFactorCurve; // Close factor curve length from soft to hard liquidation, in BPS.
    uint256 closeFactorMin; // Minimum close factor during auction, in BPS.
    uint256 closeFactorMax; // Maximum close factor during auction, in BPS.
    uint256[2] adapters; // Oracle adaptor type IDs used for pricing. `0` means an empty or unsupported slot.
    uint256 irmTargetRate; // Annualized target borrow rate derived from the token IRM.
    uint256 irmMaxRate; // Annualized max borrow rate derived from the token IRM.
    uint256 irmTargetUtilization; // IRM target utilization, in WAD.
    uint256 interestFee; // Borrow interest fee charged by the cToken, in BPS.
}
```

#### StaticMarketAsset

```solidity
struct StaticMarketAsset {
    address _address; // Underlying ERC20 address.
    string name; // Underlying token name.
    string symbol; // Underlying token symbol.
    uint8 decimals; // Underlying token decimals.
    uint256 totalSupply; // Underlying token totalSupply() (native decimals).
}
```

#### DynamicMarketData

```solidity
struct DynamicMarketData {
    address _address; // MarketManager address for this market.
    DynamicMarketToken[] tokens; // Dynamic state for each listed cToken in this market.
}
```

#### DynamicMarketToken

```solidity
struct DynamicMarketToken {
    address _address; // cToken address.
    uint256 totalSupply; // Total cToken shares outstanding.
    uint256 exchangeRate; // Share to underlying exchange rate, in WAD.
    uint256 totalAssets; // Total underlying assets reported by the cToken.
    uint256 collateral; // Total cToken shares posted as collateral in the market.
    uint256 debt; // Total outstanding market debt, in underlying assets. `0` if not borrowable.
    uint256 sharePrice; // Higher oracle price for the cToken share token, in USD WAD.
    uint256 assetPrice; // Higher oracle price for the underlying asset, in USD WAD.
    uint256 sharePriceLower; // Lower oracle price for the cToken share token, in USD WAD.
    uint256 assetPriceLower; // Lower oracle price for the underlying asset, in USD WAD.
    uint256 borrowRate; // Current borrow rate per second, in WAD. `0` if not borrowable.
    uint256 predictedBorrowRate; // Predicted borrow rate per second after IRM adjustment, in WAD. `0` if not borrowable.
    uint256 utilizationRate; // Utilization rate from `0` to `WAD`. `0` if not borrowable.
    uint256 supplyRate; // Current supply rate per second, in WAD. `0` if not borrowable.
    uint256 liquidity; // Underlying assets currently held in the borrowable pool. `0` if not borrowable.
}
```

#### UserData

```solidity
struct UserData {
    UserLock[] locks; // veCVE locks for `account` (empty if veCVE not configured).
    UserMarket[] markets; // Per-market position summary for `account` across all markets.
}
```

#### UserLock

```solidity
struct UserLock {
    uint256 lockIndex; // Index into the user's veCVE lock arrays.
    uint256 amount; // Locked amount (token units as returned by veCVE).
    uint256 unlockTime; // Lock unlock timestamp, in seconds since epoch.
}
```

#### UserMarket

```solidity
struct UserMarket {
    address _address; // MarketManager address for this market.
    uint256 collateral; // Total collateral value across positions, in USD WAD (1e18).
    uint256 maxDebt; // Max borrowable debt value based on current collateral, in USD WAD (1e18).
    uint256 debt; // Total outstanding debt value across positions, in USD WAD (1e18).
    uint256 positionHealth; // Position health ratio (collateral requirement coverage), in WAD (1e18).
    uint256 cooldown; // Account cooldown end timestamp, in seconds since epoch.
    bool errorCodeHit; // Whether an oracle error was hit while computing values.
    UserMarketToken[] tokens; // Per-token balances/collateral/debt data for this market.
}
```

#### UserMarketToken

```solidity
struct UserMarketToken {
    address _address; // cToken address.
    uint256 userAssetBalance; // Underlying assets represented by `userShareBalance` through `convertToAssets`.
    uint256 userShareBalance; // User's cToken wallet balance, in shares.
    uint256 userUnderlyingBalance; // User's underlying ERC20 wallet balance.
    uint256 userCollateral; // User's collateral posted in this cToken, in cToken shares.
    uint256 userDebt; // User's outstanding debt for this cToken, in underlying assets. `0` if not borrowable.
    uint256 liquidationPrice; // Approx liquidation trigger price, in USD WAD. May be `type(uint256).max` if not applicable.
}
```

#### HypotheticalResult

```solidity
struct HypotheticalResult {
    uint256 collateral; // Total value of `account`'s collateral across all positions.
    uint256 maxDebt; // The maximum amount of debt `account` could take on based on `collateral`.
    uint256 debt; // Total value of `account`'s current outstanding debt across all positions.
    uint256 collateralSurplus; // Excess collateral when adjusted for debt obligations.
    uint256 liquidityDeficit; // Liquidity deficit when adjusted for debt obligations.
    bool loanSizeError; // Whether the desired loan size is insufficient causing an error.
    bool oracleError; // Whether an oracle error was hit when pricing assets.
}
```

#### UserMarketSummary

```solidity
struct UserMarketSummary {
    address _address; // MarketManager address for this market.
    uint256 collateral; // Total collateral value for `account`, in USD WAD.
    uint256 maxDebt; // Maximum debt value supported by current collateral, in USD WAD.
    uint256 debt; // Total outstanding debt value for `account`, in USD WAD.
    uint256 positionHealth; // Pessimistic position health ratio, in WAD. `type(uint256).max` when debt is zero.
    uint256 cooldown; // Cooldown expiry timestamp. Compare to `block.timestamp`.
    bool errorCodeHit; // Whether an oracle error was hit while computing values.
}
```

***

## User Interaction Functions

### Data Aggregation

#### **getAllDynamicState()**

**Description:** Returns both real-time market data across all markets and comprehensive user position data in a single call. It combines `getDynamicMarketData()` (current prices, interest rates, liquidity) with `getUserData()` (user's positions,&#x20;collateral, debt, veCVE locks) to minimize RPC calls for frontend dashboards.

**Function signature:**

```solidity
function getAllDynamicState(
    address account
) external view returns (
    DynamicMarketData[] memory market,
UserData memory user
 );
```

<table><thead><tr><th width="108">Type</th><th width="102">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The address of the account to get market data for.</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="214">Type</th><th>Description</th></tr></thead><tbody><tr><td><a href="#dynamicmarketdata">DynamicMarketData[]</a></td><td>Real-time market information including current prices, interest rates, liquidity, and utilization for all tokens across all markets.</td></tr><tr><td><a href="#userdata">UserData</a></td><td>The user's veCVE locks and position data across all markets including collateral, debt, health, and token balances.</td></tr></tbody></table>

***

#### getStaticMarketDat&#x61;**()**

**Description:** Returns immutable configuration data for all markets including token details, collateral requirements, debt caps, liquidation parameters, and oracle adapter types.

**Function signature:**

```solidity
function getStaticMarketData() public view returns (StaticMarketData[] memory data);
```

Return data:

<table><thead><tr><th width="185">Type</th><th>Description</th></tr></thead><tbody><tr><td><a href="#staticmarketdata">StaticMarketData[]</a></td><td>The address of the MarketManager, unique oracle adaptors, the market's cooldown length and tokens involved in the market.</td></tr></tbody></table>

***

#### getDynamicMarketDat&#x61;**()**

**Description:** Returns real-time data for all markets

**Function signature:**

```solidity
function getDynamicMarketData() external view returns (DynamicMarketData[] memory data)
```

**Return data:**

<table><thead><tr><th width="197">Type</th><th>Description</th></tr></thead><tbody><tr><td><a href="#dynamicmarketdata">DynamicMarketData[]</a></td><td>Real-time market information including current prices, interest rates, liquidity, and utilization for all tokens across all markets.</td></tr></tbody></table>

***

#### getUserDat&#x61;**()**

**Description:** Returns the current outstanding borrows across all Curvance markets.

**Function signature:**

```solidity
function getUserData(address account) public view returns (UserData memory data)
```

**Return data:**

<table><thead><tr><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>The current outstanding borrows inside Curvance, in WAD (18 decimals)</td></tr></tbody></table>

#### getBalancesOf()

**Description:** returns wallet balances for each token in order. If a token address is Curvance's native-token sentinel, it returns `account.balance`; otherwise it returns the ERC20 balance.

**Input data:**

<table><thead><tr><th width="142">Type</th><th width="112">Name</th><th>Description</th></tr></thead><tbody><tr><td><code>address[]</code></td><td><code>tokens</code></td><td>Token addresses to query. The returned balances use the same order as this array.</td></tr><tr><td><code>address</code></td><td><code>account</code></td><td>Account whose wallet balances should be returned.</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="109">Type</th><th width="107">Name</th><th>Description</th></tr></thead><tbody><tr><td><code>uint256[]</code></td><td><code>balances</code></td><td>Wallet balances for <code>account</code>, one per input token. If <code>tokens[i]</code> is Curvance's native-token sentinel, <code>balances[i]</code> is <code>account.balance</code>; otherwise it is the ERC20 <code>balanceOf(account)</code> for <code>tokens[i]</code>.</td></tr></tbody></table>

### Price Oracle

#### **getPrice()**

**Description:** Returns `(price, errorCode)` from the Oracle Manager. When `inUSD` is true, `price` is USD-denominated WAD. When `inUSD` is false, `price` is quoted against the native token in WAD terms. \
Error code `0` means no oracle error. Error code `1` means the price should be treated with caution. Error code `2` means `BAD_SOURCE`; ProtocolReader returns `price = 0` for this case.

**Function signature:**

```solidity
function getPrice(
    address asset, 
    bool inUSD, 
    bool getLower) 
    public view returns(
    uint256 price, 
    uint256 errorCode
);
```

<table><thead><tr><th width="123">Type</th><th width="112">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>asset</td><td>Asset address to get prices for</td></tr><tr><td>bool</td><td>inUSD</td><td>Boolean whether to return prices in USD or the native token</td></tr><tr><td>bool</td><td>getLower</td><td>Boolean indicating whether to get the lower or higher price</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>Asset price in WAD ($1 = 1e18)</td></tr><tr><td>uint256</td><td>The reported error code, 0 if there is no error, 1 if there's a moderate oracle issue that blocks new borrowing, or 2 if there's a severe oracle issue that pauses all actions involving that asset.</td></tr></tbody></table>

***

### Position Health & Risk Assessment

#### **getPositionHealth()**

**Description:** Gets the Position health of `account` inside a market.

Function signature:

```solidity
function getPositionHealth(
    IMarketManager mm,
    address account,
    address cToken,
    address borrowableCToken,
    bool isDeposit,
    uint256 collateralAssets,
    bool isRepayment,
    uint256 debtAssets, 
    uint256 bufferTime
) public view returns (uint256 positionHealth, bool errorCodeHit) {
```

<table><thead><tr><th width="165">Type</th><th width="168">Name</th><th>Description</th></tr></thead><tbody><tr><td>IMarketManager</td><td>mm</td><td>The MarketManager to pull data from.</td></tr><tr><td>address</td><td>account</td><td>The user address to evaluate inside <code>mm</code></td></tr><tr><td>address</td><td>cToken</td><td>Optional collateral token for a hypothetical collateral-side action. Pass <code>address(0)</code> when not simulating collateral changes.</td></tr><tr><td>address</td><td>borrowableCToken</td><td>Optional debt token for a hypothetical debt-side action. Pass <code>address(0)</code> when not simulating debt changes.</td></tr><tr><td>bool</td><td>isDeposit</td><td>Whether <code>collateralAssets</code> should be added as a deposit or removed as a redemption.</td></tr><tr><td>uint256</td><td>collateralAssets</td><td>The amount of assets for a hypothetical action with <code>cToken</code>.</td></tr><tr><td>bool</td><td>isRepayment</td><td>Whether <code>debtAssets</code> should be treated as repayment or new borrow. If <code>debtAssets == type(uint256).max</code>, the function uses <code>debtBalanceAtTimestamp(account, borrowableCToken, block.timestamp + bufferTime)</code>.</td></tr><tr><td>uint256</td><td>debtAssets</td><td>The amount of assets for a hypothetical action with <code>borrowableCToken</code></td></tr><tr><td>uint256</td><td>bufferTime</td><td>Any additional time buffer debt accrual is expected before a user's action, in seconds.</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="117">Type</th><th width="148"></th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>positionHealth</td><td>The healthiness of <code>account</code>'s position inside the market. <code>(positionHealth, errorCodeHit)</code>. <code>positionHealth</code> is WAD-scaled and <code>type(uint256).max</code> when debt is zero.</td></tr><tr><td>bool</td><td>errorCodeHit</td><td>Whether an error code was hit or not, which would provide incorrect Position Health</td></tr></tbody></table>

***

#### **hypotheticalRedemptionOf()**

**Description:** Determine what the account liquidity would be if&#x20;the given shares were redeemed.

Function signature:

```solidity
function hypotheticalRedemptionOf(
    address account,
    address cTokenModified,
    uint256 redemptionShares,
    uint256 bufferTime
) external view returns (uint256, uint256, bool, bool);
```

<table><thead><tr><th width="108">Type</th><th width="168">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account to determine liquidity for.</td></tr><tr><td>address</td><td>cTokenModified</td><td>The address of the market token</td></tr><tr><td>uint256</td><td>redemptionShares</td><td>The number of shares to hypothetically redeem.</td></tr><tr><td>uint256</td><td>bufferTime</td><td>Any additional time buffer debt accrual is expected before a user's action, in seconds.</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="117">Type</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>Hypothetical account liquidity in excess of collateral requirements.</td></tr><tr><td>uint256</td><td>Hypothetical account liquidity deficit below collateralrequirements.</td></tr><tr><td>bool</td><td>The amount of collateral posted or debt owed by the account.</td></tr><tr><td>bool </td><td>Whether an error code was hit.</td></tr></tbody></table>

***

#### maxRedemptionO&#x66;**()**

**Description:** Determine the maximum amount of `cTokenRedeemed` that `account` can redeem.

**Function signature:**

```solidity
function maxRedemptionOf(
    address account,
    address cTokenRedeemed,
    uint256 bufferTime
) public view returns (
    uint256 collateralizedSharesRedeemable,
    uint256 uncollateralizedShares,
    bool errorHit
);
```

<table><thead><tr><th width="113">Type</th><th width="198">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account to determine redemptions for.</td></tr><tr><td>address</td><td>cTokenRedeemed</td><td>The cToken to redeem.</td></tr><tr><td>uint256</td><td>bufferTime</td><td>Any additional time buffer debt accrual is expected before a user's action, in seconds.</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="117">Type</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>The amount of collateralized <code>cTokenModified</code> shares redeemable by <code>account</code>.</td></tr><tr><td>uint256</td><td>The amount of uncollateralized <code>cTokenModified</code> shares redeemable by <code>account</code>.</td></tr><tr><td>bool</td><td>Whether an error code was hit.</td></tr></tbody></table>

***

#### **liquidationValuesOf()**

**Description:** Evaluates collateral and debt positions to determine account health and liquidation parameters.

Function signature:

```solidity
function liquidationValuesOf(
    IMarketManager mm,
    address account,
    bool isAuction
) public view returns (
    uint256 cSoft, uint256 cHard, uint256 debt, uint256 lFactor, bool) {
```

<table><thead><tr><th width="159">Type</th><th width="168">Name</th><th>Description</th></tr></thead><tbody><tr><td>IMarketManager</td><td>mm</td><td>The market manager to pull liquidation values from.</td></tr><tr><td>address</td><td>account</td><td>The address of the account being evaluated for liquidation.</td></tr><tr><td>bool</td><td>isAuction</td><td>Whether the liquidation is an auction or not, if true then applies <code>AUCTION_BUFFER</code> discount to cSoft/cHard indicating a closer/sooner liquidation value.</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="117">Type</th><th width="134"></th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>cSoft</td><td>The account's soft collateral value (collateral adjusted by soft requirements).</td></tr><tr><td>uint256</td><td>cHard</td><td>The account's hard collateral value (collateral adjusted by hard requirements).</td></tr><tr><td>uint256</td><td>debt</td><td>The account's total debt value.</td></tr><tr><td>uint256 </td><td>lFactor</td><td>WAD-scaled: <code>0</code> means no liquidation, <code>WAD</code> means hard liquidation, and values between them represent soft-liquidation severity.</td></tr><tr><td>bool </td><td>errorCodeHit</td><td>Whether an error code was hit.</td></tr></tbody></table>

***

#### debtBalanceAtTimestam&#x70;**()**

**Description:** Returns the projected debt balance for `account` in `borrowableCToken` at `timestamp`. If the supplied timestamp is before the current block timestamp, the function uses the current block timestamp instead. This helper is intended for frontend data querying and sizing, not onchain execution.

**Function signature:**

```solidity
function debtBalanceAtTimestamp(
    address account,
    address borrowableCToken,
    uint256 timestamp
) public view returns (uint256 debtBalance);
```

<table><thead><tr><th width="109">Type</th><th width="174">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The address whose debt balance should be calculated.</td></tr><tr><td>address</td><td>borrowableCToken</td><td>The token that <code>account</code>'s debt balance will be checked for.</td></tr><tr><td>uint256</td><td>timestamp</td><td>The unix timestamp to calculate account debt balance with.</td></tr></tbody></table>

Return data:

<table><thead><tr><th width="111">Type</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>The debt balance of <code>account</code> at <code>timestamp</code>.</td></tr></tbody></table>

#### **getLiquidationPrice()**

**Description: E**stimates the price at which the account would reach liquidation for a collateral-side (`long = true`) or debt-side (`long = false`) exposure. It returns `type(uint256).max` when there is no usable exposure, the token is unlisted, debt is zero, or the amount rounds to zero. It returns `errorHit = true` when a severe oracle error is hit while computing the value.

Function signature:

```solidity
function getLiquidationPrice(
    address account,
    address cToken,
    bool long
) public view returns (uint256 price, bool errorHit) {
```

<table><thead><tr><th width="165">Type</th><th width="168">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account address to check.</td></tr><tr><td>address</td><td>cToken</td><td>The address of the cToken that is being used as collateral.</td></tr><tr><td>bool</td><td>long</td><td>If the position is long or short.</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="117">Type</th><th width="148"></th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>price</td><td>The collateral price to liquidate.</td></tr><tr><td>uint256</td><td>errorCodeHit</td><td>Whether an oracle error code was hit or not.</td></tr></tbody></table>

### Hypothetical Simulation Functions

#### hypotheticalRedemptionO&#x66;**()**

**Description:** Determine what the account liquidity would be if&#x20;the given shares were redeemed.

**Function signature:**

```solidity
function hypotheticalRedemptionOf(
    address account,
    address cTokenModified,
    uint256 redemptionShares
) public view returns (uint256, uint256, bool, bool)
```

<table><thead><tr><th width="99">Type</th><th width="166">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account to determine liquidity for.</td></tr><tr><td>address</td><td>cTokenModified</td><td>The cToken to hypothetically redeem.</td></tr><tr><td>uint256</td><td>redemptionShares</td><td>The number of shares to hypothetically redeem.</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="159">Type</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>Hypothetical account liquidity in excess of collateral requirements.</td></tr><tr><td>uint256</td><td>Hypothetical account liquidity deficit below collateral requirements.</td></tr><tr><td>bool</td><td>Whether the proposed action is not possible. NOT whether it passes liquidity constraints or not.</td></tr><tr><td>bool</td><td>Whether an error code was hit or not.</td></tr></tbody></table>

***

#### hypotheticalBorrowO&#x66;**()**

**Description:** Determine what the account liquidity would be if&#x20;the given assets were borrowed.

**Function signature:**

```solidity
function hypotheticalBorrowOf(
    address account,
    address borrowableCTokenModified,
    uint256 borrowAssets,
    uint256 bufferTime
) external view returns (uint256, uint256, bool, bool, bool);
```

<table><thead><tr><th width="126">Type</th><th width="237">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account to determine liquidity for.</td></tr><tr><td>address</td><td>borrowableCTokenModified</td><td>The borrowableCToken to hypothetically borrow.</td></tr><tr><td>uint256</td><td>borrowAssets</td><td>The number of assets to hypothetically borrow.</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="132">Type</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>Hypothetical account liquidity in excess of collateral requirements.</td></tr><tr><td>uint256</td><td>Hypothetical account liquidity deficit below collateral requirements.</td></tr><tr><td>bool</td><td>Whether the proposed action is possible. NOT whether it passes liquidity constraints or not.</td></tr><tr><td>bool</td><td>Whether the desired loan size is insufficient causing an error.</td></tr><tr><td>bool</td><td>Whether an error code was hit or not.</td></tr></tbody></table>

***

#### hypotheticalLeverageO&#x66;**()**

**Description:** Estimates leverage capacity from current account state, a new collateral deposit, oracle prices, caps, available borrow liquidity, and projected debt. It can overestimate executable leverage when the actual route pays AMM fees or suffers slippage. It can revert if either token is not listed in the relevant market or if the collateral token has no collateral ratio.

**Function signature:**

```solidity
function hypotheticalLeverageOf(
    address account,
    address cToken,
    address borrowableCToken,
    uint256 assets,
    uint256 bufferTime
) public view returns (
    uint256 currentLeverage,
    uint256 adjustedMaxLeverage,
    uint256 maxLeverage,
    uint256 maxDebtBorrowable,
    bool loanSizeError,
    bool oracleError
    )
```

<table><thead><tr><th width="123">Type</th><th width="184">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account to query maximum borrow amount for.</td></tr><tr><td>address</td><td>cToken</td><td>The token that <code>account</code> will deposit to leverage against.</td></tr><tr><td>address</td><td>borrowableCToken</td><td>The token that <code>account</code> will borrow assets from to achieve leverage.</td></tr><tr><td>uint256</td><td>assets</td><td>The amount of <code>cToken</code> underlying that <code>account</code> will deposit to leverage against.</td></tr><tr><td>uint256</td><td>bufferTime</td><td>Any additional time buffer debt accrual is expected before a user's action, in seconds.</td></tr></tbody></table>

Return data:

<table><thead><tr><th width="164">Type</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>Returns the current leverage multiplier of <code>account</code>, in <code>WAD</code>.</td></tr><tr><td>uint256</td><td>Returns the maximum leverage multiplier of <code>account</code> after a hypothetical deposit action, adjusted by liquidity constraints, in <code>WAD</code>.</td></tr><tr><td>uint256</td><td>Returns the maximum leverage multiplier of <code>account</code> after a hypothetical deposit action, in <code>WAD</code>.</td></tr><tr><td>uint256</td><td>Returns the maximum remaining borrow amount allowed from <code>borrowableCToken</code>, measured in underlying token amount, after the new hypothetical deposit.</td></tr><tr><td>bool</td><td>Whether the desired loan size is insufficient causing an error.</td></tr><tr><td>bool</td><td>Whether an oracle error was hit when pricing assets.</td></tr></tbody></table>

***

#### getLeverageSnapshot()

**Description:** Returns the account's projected aggregate collateral and debt values, the collateral underlying price, the collateral share price, the debt underlying price, the projected debt token balance, and an oracle-error flag. It is designed for leverage and deleverage sizing flows.

```solidity
function getLeverageSnapshot(
    address account,
    address cToken,
    address borrowableCToken,
    uint256 bufferTime
) external view returns (
    uint256 collateralUsd,
    uint256 debtUsd,
    uint256 collateralAssetPrice,
    uint256 sharePrice,
    uint256 debtAssetPrice,
    uint256 debtTokenBalance,
    bool oracleError
);
```

**Input data:**

<table><thead><tr><th width="118">Type</th><th width="172">Name</th><th>Description</th></tr></thead><tbody><tr><td><code>address</code></td><td><code>account</code></td><td>The user address to snapshot.</td></tr><tr><td><code>address</code></td><td><code>cToken</code></td><td>The collateral cToken. ProtocolReader uses this token's MarketManager for the aggregate position snapshot and prices this token's underlying as the collateral asset.</td></tr><tr><td><code>address</code></td><td><code>borrowableCToken</code></td><td>The debt cToken used for debt-side price conversion and projected debt-token balance.</td></tr><tr><td><code>uint256</code></td><td><code>bufferTime</code></td><td>Seconds of debt accrual to project forward when computing aggregate debt and <code>debtTokenBalance</code>.</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="113">Type</th><th width="217">Name</th><th>Description</th></tr></thead><tbody><tr><td><code>uint256</code></td><td><code>collateralUsd</code></td><td>Aggregate collateral value for <code>account</code> in the <code>cToken</code> market, in USD WAD.</td></tr><tr><td><code>uint256</code></td><td><code>debtUsd</code></td><td>Aggregate projected debt value for <code>account</code> in the <code>cToken</code> market, in USD WAD.</td></tr><tr><td><code>uint256</code></td><td><code>collateralAssetPrice</code></td><td>Lower USD WAD price for the collateral cToken's underlying asset.</td></tr><tr><td><code>uint256</code></td><td><code>sharePrice</code></td><td>Collateral cToken share price, calculated as <code>collateralAssetPrice * exchangeRate(cToken) / WAD</code>.</td></tr><tr><td><code>uint256</code></td><td><code>debtAssetPrice</code></td><td>Higher USD WAD price for the debt cToken's underlying asset.</td></tr><tr><td><code>uint256</code></td><td><code>debtTokenBalance</code></td><td>Projected debt balance for <code>account</code> in <code>borrowableCToken</code>, in underlying token units.</td></tr><tr><td><code>bool</code></td><td><code>oracleError</code></td><td>Whether the aggregate liquidity snapshot hit an oracle error while pricing account positions.</td></tr></tbody></table>

***

#### hypotheticalLiquidityO&#x66;**()**

**Description:** Calculates the hypothetical maximum amount of `borrowableCToken` assets `account` can borrow for maximum leverage based on a new `cToken` collateralized deposit.

**Function signature:**

```solidity
function hypotheticalLiquidityOf(
    IMarketManager mm,
    address account,
    address cTokenModified,
    uint256 redemptionShares,
    uint256 borrowAssets,
    uint256 bufferTime
) public view returns (HypotheticalResult memory result) {
```

<table><thead><tr><th width="164">Type</th><th width="183">Name</th><th>Description</th></tr></thead><tbody><tr><td>IMarketManager</td><td>mm</td><td>The market manager to read account liquidity from.</td></tr><tr><td>address</td><td>account</td><td>The user address to evaluate.</td></tr><tr><td>address</td><td>cTokenModified</td><td>The cToken affected by the hypothetical action.</td></tr><tr><td>uint256</td><td>redemptionShares</td><td>The number of cToken shares hypothetically redeemed.</td></tr><tr><td>uint256</td><td>borrowAssets</td><td>The amount of underlying assets hypothetically borrowed.</td></tr><tr><td>uint256</td><td>bufferTime</td><td>The number of seconds of debt accrual to project before the action.</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="189">Type</th><th width="194">Name</th><th>Description</th></tr></thead><tbody><tr><td><a href="#hypotheticalresult">HypotheticalResult</a></td><td>result</td><td>Hypothetical results for an action.</td></tr></tbody></table>

***

### Market Analysis Functions

#### marketMultiCooldow&#x6E;**()**

**Description:** Returns cooldown expiry timestamps for each market, not durations or remaining seconds. Each value is `accountAssets(user) + MARKET_COOLDOWN_LENGTH`. Compare the returned timestamp to the current block timestamp; if it is in the past, the account is not currently cooling down in that market.

**Function signature:**

```solidity
function marketMultiCooldown(
    address[] calldata markets,
    address user
) public view returns (uint256[] memory)
```

<table><thead><tr><th width="110">Type</th><th width="117">Name</th><th>Description</th></tr></thead><tbody><tr><td>address[]</td><td>markets</td><td>The list of market addresses.</td></tr><tr><td>address</td><td>user</td><td>The user address.</td></tr></tbody></table>

Return data:

<table><thead><tr><th width="119">Type</th><th>Description</th></tr></thead><tbody><tr><td>uint256[]</td><td>The list of cooldown periods for each market.</td></tr></tbody></table>

***

#### previewAssetImpac&#x74;**()**

**Description:** previews projected IRM rates after a potential deposit or borrow. It returns `(supply, borrow)`, where both values are per-second rates in WAD.

The `supply` value is populated only when `collateralCToken.isBorrowable()` is true. The `borrow` value is populated only when `user` already has debt in `debtBorrowableCToken`; otherwise it remains zero in the current implementation.

**Function signature:**

```solidity
function previewAssetImpact(
    address user,
    address collateralCToken,
    address debtBorrowableCToken,
    uint256 newCollateralAssets,
    uint256 newDebtAssets
) public view returns (uint256 supply, uint256 borrow);
```

<table><thead><tr><th width="112">Type</th><th width="213">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>user</td><td>The address of the user account to preview asset impact of.</td></tr><tr><td>address</td><td>collateralCToken</td><td>The address of the collateral cToken.</td></tr><tr><td>address</td><td>debtBorrowableCToken</td><td>The address of the debt borrowable cToken.</td></tr><tr><td>uint256</td><td>newCollateralAssets</td><td>The amount of new collateral asset to deposit, in assets.</td></tr><tr><td>uint256</td><td>newDebtAssets</td><td>The amount of new debt asset to borrow, in assets.</td></tr></tbody></table>

**Return data:**

<table><thead><tr><th width="115">Type</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>The projected supply rate, in <code>WAD</code> seconds.</td></tr><tr><td>uint256</td><td>The projected borrow amount, in <code>WAD</code> seconds.</td></tr></tbody></table>

***


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.curvance.com/app/developer-docs/protocol-reader.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
