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

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

StaticMarketAsset

DynamicMarketData

DynamicMarketToken

UserData

UserLock

UserMarket

UserMarketToken

HypotheticalResult

UserMarketSummary


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, collateral, debt, veCVE locks) to minimize RPC calls for frontend dashboards.

Function signature:

Type
Name
Description

address

account

The address of the account to get market data for.

Return data:

Type
Description

Real-time market information including current prices, interest rates, liquidity, and utilization for all tokens across all markets.

The user's veCVE locks and position data across all markets including collateral, debt, health, and token balances.


getStaticMarketData()

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

Function signature:

Return data:

Type
Description

The address of the MarketManager, unique oracle adaptors, the market's cooldown length and tokens involved in the market.


getDynamicMarketData()

Description: Returns real-time data for all markets

Function signature:

Return data:

Type
Description

Real-time market information including current prices, interest rates, liquidity, and utilization for all tokens across all markets.


getUserData()

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

Function signature:

Return data:

Type
Description

uint256

The current outstanding borrows inside Curvance, in WAD (18 decimals)

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:

Type
Name
Description

address[]

tokens

Token addresses to query. The returned balances use the same order as this array.

address

account

Account whose wallet balances should be returned.

Return data:

Type
Name
Description

uint256[]

balances

Wallet balances for account, one per input token. If tokens[i] is Curvance's native-token sentinel, balances[i] is account.balance; otherwise it is the ERC20 balanceOf(account) for tokens[i].

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:

Type
Name
Description

address

asset

Asset address to get prices for

bool

inUSD

Boolean whether to return prices in USD or the native token

bool

getLower

Boolean indicating whether to get the lower or higher price

Return data:

Type
Description

uint256

Asset price in WAD ($1 = 1e18)

uint256

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.


Position Health & Risk Assessment

getPositionHealth()

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

Function signature:

Type
Name
Description

IMarketManager

mm

The MarketManager to pull data from.

address

account

The user address to evaluate inside mm

address

cToken

Optional collateral token for a hypothetical collateral-side action. Pass address(0) when not simulating collateral changes.

address

borrowableCToken

Optional debt token for a hypothetical debt-side action. Pass address(0) when not simulating debt changes.

bool

isDeposit

Whether collateralAssets should be added as a deposit or removed as a redemption.

uint256

collateralAssets

The amount of assets for a hypothetical action with cToken.

bool

isRepayment

Whether debtAssets should be treated as repayment or new borrow. If debtAssets == type(uint256).max, the function uses debtBalanceAtTimestamp(account, borrowableCToken, block.timestamp + bufferTime).

uint256

debtAssets

The amount of assets for a hypothetical action with borrowableCToken

uint256

bufferTime

Any additional time buffer debt accrual is expected before a user's action, in seconds.

Return data:

Type
Description

uint256

positionHealth

The healthiness of account's position inside the market. (positionHealth, errorCodeHit). positionHealth is WAD-scaled and type(uint256).max when debt is zero.

bool

errorCodeHit

Whether an error code was hit or not, which would provide incorrect Position Health


hypotheticalRedemptionOf()

Description: Determine what the account liquidity would be if the given shares were redeemed.

Function signature:

Type
Name
Description

address

account

The account to determine liquidity for.

address

cTokenModified

The address of the market token

uint256

redemptionShares

The number of shares to hypothetically redeem.

uint256

bufferTime

Any additional time buffer debt accrual is expected before a user's action, in seconds.

Return data:

Type
Description

uint256

Hypothetical account liquidity in excess of collateral requirements.

uint256

Hypothetical account liquidity deficit below collateral requirements.

bool

The amount of collateral posted or debt owed by the account.

bool

Whether an error code was hit.


maxRedemptionOf()

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

Function signature:

Type
Name
Description

address

account

The account to determine redemptions for.

address

cTokenRedeemed

The cToken to redeem.

uint256

bufferTime

Any additional time buffer debt accrual is expected before a user's action, in seconds.

Return data:

Type
Description

uint256

The amount of collateralized cTokenModified shares redeemable by account.

uint256

The amount of uncollateralized cTokenModified shares redeemable by account.

bool

Whether an error code was hit.


liquidationValuesOf()

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

Function signature:

Type
Name
Description

IMarketManager

mm

The market manager to pull liquidation values from.

address

account

The address of the account being evaluated for liquidation.

bool

isAuction

Whether the liquidation is an auction or not, if true then applies AUCTION_BUFFER discount to cSoft/cHard indicating a closer/sooner liquidation value.

Return data:

Type
Description

uint256

cSoft

The account's soft collateral value (collateral adjusted by soft requirements).

uint256

cHard

The account's hard collateral value (collateral adjusted by hard requirements).

uint256

debt

The account's total debt value.

uint256

lFactor

WAD-scaled: 0 means no liquidation, WAD means hard liquidation, and values between them represent soft-liquidation severity.

bool

errorCodeHit

Whether an error code was hit.


debtBalanceAtTimestamp()

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:

Type
Name
Description

address

account

The address whose debt balance should be calculated.

address

borrowableCToken

The token that account's debt balance will be checked for.

uint256

timestamp

The unix timestamp to calculate account debt balance with.

Return data:

Type
Description

uint256

The debt balance of account at timestamp.

getLiquidationPrice()

Description: Estimates 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:

Type
Name
Description

address

account

The account address to check.

address

cToken

The address of the cToken that is being used as collateral.

bool

long

If the position is long or short.

Return data:

Type
Description

uint256

price

The collateral price to liquidate.

uint256

errorCodeHit

Whether an oracle error code was hit or not.

Hypothetical Simulation Functions

hypotheticalRedemptionOf()

Description: Determine what the account liquidity would be if the given shares were redeemed.

Function signature:

Type
Name
Description

address

account

The account to determine liquidity for.

address

cTokenModified

The cToken to hypothetically redeem.

uint256

redemptionShares

The number of shares to hypothetically redeem.

Return data:

Type
Description

uint256

Hypothetical account liquidity in excess of collateral requirements.

uint256

Hypothetical account liquidity deficit below collateral requirements.

bool

Whether the proposed action is not possible. NOT whether it passes liquidity constraints or not.

bool

Whether an error code was hit or not.


hypotheticalBorrowOf()

Description: Determine what the account liquidity would be if the given assets were borrowed.

Function signature:

Type
Name
Description

address

account

The account to determine liquidity for.

address

borrowableCTokenModified

The borrowableCToken to hypothetically borrow.

uint256

borrowAssets

The number of assets to hypothetically borrow.

Return data:

Type
Description

uint256

Hypothetical account liquidity in excess of collateral requirements.

uint256

Hypothetical account liquidity deficit below collateral requirements.

bool

Whether the proposed action is possible. NOT whether it passes liquidity constraints or not.

bool

Whether the desired loan size is insufficient causing an error.

bool

Whether an error code was hit or not.


hypotheticalLeverageOf()

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:

Type
Name
Description

address

account

The account to query maximum borrow amount for.

address

cToken

The token that account will deposit to leverage against.

address

borrowableCToken

The token that account will borrow assets from to achieve leverage.

uint256

assets

The amount of cToken underlying that account will deposit to leverage against.

uint256

bufferTime

Any additional time buffer debt accrual is expected before a user's action, in seconds.

Return data:

Type
Description

uint256

Returns the current leverage multiplier of account, in WAD.

uint256

Returns the maximum leverage multiplier of account after a hypothetical deposit action, adjusted by liquidity constraints, in WAD.

uint256

Returns the maximum leverage multiplier of account after a hypothetical deposit action, in WAD.

uint256

Returns the maximum remaining borrow amount allowed from borrowableCToken, measured in underlying token amount, after the new hypothetical deposit.

bool

Whether the desired loan size is insufficient causing an error.

bool

Whether an oracle error was hit when pricing assets.


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.

Input data:

Type
Name
Description

address

account

The user address to snapshot.

address

cToken

The collateral cToken. ProtocolReader uses this token's MarketManager for the aggregate position snapshot and prices this token's underlying as the collateral asset.

address

borrowableCToken

The debt cToken used for debt-side price conversion and projected debt-token balance.

uint256

bufferTime

Seconds of debt accrual to project forward when computing aggregate debt and debtTokenBalance.

Return data:

Type
Name
Description

uint256

collateralUsd

Aggregate collateral value for account in the cToken market, in USD WAD.

uint256

debtUsd

Aggregate projected debt value for account in the cToken market, in USD WAD.

uint256

collateralAssetPrice

Lower USD WAD price for the collateral cToken's underlying asset.

uint256

sharePrice

Collateral cToken share price, calculated as collateralAssetPrice * exchangeRate(cToken) / WAD.

uint256

debtAssetPrice

Higher USD WAD price for the debt cToken's underlying asset.

uint256

debtTokenBalance

Projected debt balance for account in borrowableCToken, in underlying token units.

bool

oracleError

Whether the aggregate liquidity snapshot hit an oracle error while pricing account positions.


hypotheticalLiquidityOf()

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

Function signature:

Type
Name
Description

IMarketManager

mm

The market manager to read account liquidity from.

address

account

The user address to evaluate.

address

cTokenModified

The cToken affected by the hypothetical action.

uint256

redemptionShares

The number of cToken shares hypothetically redeemed.

uint256

borrowAssets

The amount of underlying assets hypothetically borrowed.

uint256

bufferTime

The number of seconds of debt accrual to project before the action.

Return data:

Type
Name
Description

result

Hypothetical results for an action.


Market Analysis Functions

marketMultiCooldown()

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:

Type
Name
Description

address[]

markets

The list of market addresses.

address

user

The user address.

Return data:

Type
Description

uint256[]

The list of cooldown periods for each market.


previewAssetImpact()

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:

Type
Name
Description

address

user

The address of the user account to preview asset impact of.

address

collateralCToken

The address of the collateral cToken.

address

debtBorrowableCToken

The address of the debt borrowable cToken.

uint256

newCollateralAssets

The amount of new collateral asset to deposit, in assets.

uint256

newDebtAssets

The amount of new debt asset to borrow, in assets.

Return data:

Type
Description

uint256

The projected supply rate, in WAD seconds.

uint256

The projected borrow amount, in WAD seconds.


Last updated

Was this helpful?