Curvance
  • Protocol Overview
    • Click Less, Earn More
    • Protocol Architecture
    • Asset Types
    • Liquidity Markets
      • Borrowing
      • Liquidations
      • Interest Rates
      • Oracles
      • Collateral Caps
      • Bad Debt Socialization
    • Application Specific Sequencing
    • New Age Liquidity Mining
      • Protocols
    • How Are New Assets Integrated
    • Plugin System
    • Universal Account Balance
    • Token Approval Management
    • Lending Risks
  • Security
    • Security and Audits
  • Miscellaneous
    • RPCs and Testnet Stability
    • Glossary
    • TL;DR
      • Customer Types and Benefits
    • Brand Assets
    • Weblinks
    • Disclaimer
    • Frequently Asked Questions
  • Developer Docs
    • Overview
    • Quick Start Guides
      • Atlas Fastlane Auctions (coming soon)
      • Plugin Integration
        • List of Delegable Actions
      • Loans & Collateral
        • Lend Assets
        • Deposit into pTokens
        • Withdraw Loans
        • Withdraw pTokens
      • Borrowing & Repayment
        • Borrow
        • Repaying Debt
      • Leverage
        • Leveraging
        • Deleveraging
    • Lending Protocol
      • Market Manager
      • Position Tokens (pToken)
      • Earn Tokens (eTokens)
      • Dynamic Interest Rate Model
      • Universal Balance
    • Position Management
      • Leverage
      • Deleverage / Fold
    • Dynamic Liquidation Engine (DLE)
      • Orderflow Auction System
      • Bad Debt Socialization
    • Plugin & Delegation System
      • Transfer Lock Mechanism
      • Delegable Actions
    • Cross-Chain Functionality
      • Messaging Hub
      • Fee Manager
      • Reward Manager
    • Auxiliary Functionality
Powered by GitBook
On this page
  • Overview
  • Architecture
  • Data Flow
  • Risk Management
  • Interest Rate Model
  • Security Measures
  • Cross vs Isolated Market Managers
  • Market Manager Design Philosophy
  • Cross-Contract Interactions
  • User Interaction Functions
  • Core Data Query Functions
  • Status and Liquidity
  • Collateral Management
  • Permission and Validation
  • Market State Mappings
  • Paused States
  • Collateral Invariants
Export as PDF
  1. Developer Docs
  2. Lending Protocol

Market Manager

PreviousLending ProtocolNextPosition Tokens (pToken)

Last updated 27 days ago

Overview

The Market Manager is a core component of the Curvance protocol, responsible for risk management and orchestrating interactions between various protocol modules. Market Managers are designed as thesis-driven micro-ecosystems, each focusing on specific asset types (e.g., interest-bearing stablecoins, bluechip assets, volatile LP tokens), which helps minimize systemic risk across the protocol.

Architecture

  • Liquidity Manager: Calculates account liquidity across positions.

  • Liquidation Manager: Manages liquidation queues and OEV auction integration.

  • Position Management: Handles position creation, modification, and leverage.

  • Dynamic Interest Rate Model: Manages borrow and supply interest rates for Curvance debt tokens.

  • Market Tokens: Tokens in Curvance that represent collateral, and debt.

  • .

Market Tokens

Two primary token types exist within Curvance markets:

  • Position Tokens (pTokens): Represent collateral positions.

  • Debt Tokens (eTokens): Represent borrowed assets.

Together, these are collectively called Market Tokens (mTokens).

Data Flow

Collateral Management Flow

  1. Users deposit assets into pToken contracts.

  2. pTokens can be posted as collateral (subject to collateral caps).

  3. Posted collateral enables borrowing capacity.

  4. Market Manager tracks all collateral positions.

OEV (Optimal Extractable Value) Auction Flow

When OEV is enabled, the system prioritizes auction winners for liquidations:

  1. Block N:Oracle update lands on-chain

    1. Auctioneer/bundler (Fastlane) submits winning liquidation bids.

    2. OEV liquidations execute immediately if caller is whitelisted.

  2. Fallback Mechanism:

    1. If OEV auctions are offline or fail, system falls back to queued liquidations.

    2. Liquidators must call queueLiquidation() to enter the queue.

    3. Liquidations proceed through priority → regular → end phases.

Risk Management

Dynamic Liquidation Engine (DLE)

The Market Manager implements a three-tiered liquidation threshold system:

  1. Soft Liquidation Threshold (collReqSoft)

    1. Initiates partial liquidations with base incentives.

    2. Minimal disruption to user positions.

  2. Hard Liquidation Threshold (collReqHard)

    1. Permits complete position liquidation.

    2. Maximum liquidation incentives.

  3. Bad Debt Threshold

    1. Triggered when collateral value falls below total debt.

    2. Bad debt is socialized among lenders.

Collateral Cap System

  • Every collateral asset has a Collateral Cap measured in shares.

  • As collateral is posted, the collateralPosted invariant increases.

  • Caps can be decreased without forcing unwinding of existing positions.

  • Prevents excessive concentration of risky assets.

Position Cooldown Mechanism

Curvance employs a 20-minute minimum duration requirement for:

  • Posting pToken collateral.

  • Lending/borrowing eTokens.

This cooldown period:

  • Improves protocol security.

  • Prevents flash loan attacks.

  • Enables more sophisticated interest rate models.

  • Reduces market manipulation opportunities.

The state transition looks like:

Interest Rate Model

The Dynamic Interest Rate Model adjusts rates based on market conditions:

  • Base rate increases linearly until vertex point is reached.

  • Includes dynamic Vertex Multiplier that adjusts based on liquidity utilization.

  • Higher utilization increases borrowing costs to incentivize repayments and new lenders.

  • Decay mechanism balances rate reversion during normal conditions.

Security Measures

  • 20-minute minimum duration for posting collateral and lending.

  • No rehypothecation of user deposits.

  • Isolation of market risks through market-specific tokens.

  • Bad debt socialization system to protect protocol solvency.

Cross vs Isolated Market Managers

Market Manager Design Philosophy

Curvance implements two distinct types of market managers to address different risk models and use cases: Cross Market Managers and Isolated Market Managers.

Cross Market Manager

The Cross MarketManager contract supports multiple collateral assets and debt positions within a single market environment. This design enables users to post various types of collateral against different debt positions, thereby creating a diverse risk portfolio under a single manager. Cross market managers are well-suited for ecosystems with complementary assets that share similar risk characteristics, enabling efficient capital utilization across the entire portfolio. The protocol can optimize risk management at a holistic level, with liquidation and collateralization requirements balanced across all positions.

Isolated Market Manager

The MarketManagerIsolated contract focuses on a single position token type as collateral. This design creates a thesis-driven micro-ecosystem that isolates risk to specific asset classes or strategies. Isolated markets are ideal for specialized use cases, such as interest-bearing stablecoins, volatile LP tokens, or other assets with unique risk profiles that shouldn't contaminate other markets. This separation prevents contagion between different risk profiles while still enabling the protocol to support diverse asset types across separate, isolated markets. Each isolated market can be configured with parameters specifically tailored to its underlying asset's volatility and liquidity characteristics.

Both designs contribute to Curvance's approach of minimizing systemic risk while maximizing the range of supportable assets, allowing the protocol to safely incorporate nearly any ERC20 token into its ecosystem through the appropriate market manager structure.

Cross-Contract Interactions

The Market Manager interacts with multiple other components:

  • Central Registry for protocol parameters and permissions.

  • Oracle Manager for price feeds.

  • Token contracts for position management.

  • Position Management contracts for leveraging operations.

  • External bundlers/auctioneers for OEV liquidations.

Through these interactions, the Market Manager maintains the integrity and stability of each market while optimizing capital efficiency and risk management.

User Interaction Functions

Core Data Query Functions

isListed()

Contract: MarketManager

Description: Checks if an mToken (pToken or eToken) is listed in the lending market.

Function signature:

function isListed(address mToken) external view returns (bool)
Type
Name
Description

address

mToken

Address of the pToken or eToken.

Return data:

Type
Description

bool

Whether the token is an mToken (true), or not (false).


queryTokensListed()

Contract: MarketManager

Description: Returns an array of all mToken addresses that are listed in the market.

Function signature:

function queryTokensListed() external view returns (address[] memory)

Return Data:

Type
Description

address[]

Array of all mToken addresses listed in the market.


assetsOf()

Contract: MarketManager

Description: Returns all assets that an account has entered.

Function signature:

function assetsOf(address account) external view returns (IMToken[] memory)
Type
Name
Description

address

account

The address of the account to query.

Return data:

Type
Description

IMToken[]

Array of mTokens that the account has entered.


tokenDataOf()

Contract: MarketManager

Description: Returns detailed information about an account's position in a specific market token, including whether they have an active position, their balance, and collateral posted.

Function signature:

function tokenDataOf(address account, address mToken) external view returns (bool hasPosition, uint256 balanceOf, uint256 collateralPostedOf)
Type
Name
Description

address

account

The address of the account to check.

address

mToken

The address of the market token.

Return data:

Type
Description

bool

Whether the account has an active position in the specified market token.

uint256

The account's balance of the specified market token.

uint256

The amount of collateral posted by the account in the specified market token.


Status and Liquidity

statusOf()

Contract: MarketManagerCross

Description: Determine the account's current status between collateral and additional liquidity in USD.

Function signature:

function statusOf(address account) external view returns (uint256, uint256, uint256)
Type
Name
Description

address

account

The account to determine liquidity for.

Return data:

Type
Description

uint256

Total value of account collateral.

uint256

The maximum amount of debt the account could take on based on an account's collateral.

uint256

Total value of an account's debt.


hypotheticalLiquidityOf()

Contract: MarketManager

Description: Calculates what an account's liquidity would be after a hypothetical action such as redeeming or borrowing. Will natively revert if a hypothetical borrow will result in a loan less than MIN_ACTIVE_LOAN_SIZE, set in LiquidityManager.

Function signature:

    function hypotheticalLiquidityOf(
        address account,
        address mTokenModified,
        uint256 redeemTokens, // in Shares.
        uint256 borrowAmount // in Assets.
    ) external view returns (uint256, uint256, bool[] memory) 
Type
Name
Description

address

account

The account to determine liquidity for.

address

mTokenModified

The market to hypothetically redeem/borrow in.

uint256

redeemTokens

The number of tokens to hypothetically redeem in shares.

uint256

borrowAmount

The amount of underlying to hypothetically borrow in assets.

Return data:

Type
Description

uint256

Hypothetical account liquidity in excess of collateral requirements.

uint256

Hypothetical account liquidity deficit below collateral requirements.

bool[]

An array of whether the positions should be closed or not.


Collateral Management

postCollateral()

Contract: MarketManager

Description: Posts tokens as collateral in the market (subject to cooldown period). Caller must be the same as account or the pToken contract associated. The account must have sufficient pTokens to post as collateral. The pToken configuration must have collateralization enabled.

Function signature:

function postCollateral(
    address account, 
    address pToken, 
    uint256 tokens) external
Type
Name
Description

address

account

The address of the account posting collateral.

address

pToken

The address of the position token to use as collateral.

uint256

tokens

The amount of tokens to post as collateral, in shares.


removeCollateral()

Contract: MarketManager

Description: Removes collateral from the market (subject to cooldown period). Only called by a user's address. Can only succeed if the account has no active loan, if the removal does not cause a liquidity deficit, or past the 20 minute hold period. Also clears inactive positions in the MarketManager's internal accounting.

Function signature:

function removeCollateral(address pToken, uint256 tokens) external
Type
Name
Description

address

pToken

The address of the position token to remove collateral for.

uint256

tokens

The number of tokens to remove from collateral, in shares.


Permission and Validation

canMint()

Contract: MarketManager

Description: Checks if an account is allowed to mint tokens in the specified market, validating system parameters and account state. Transaction succeeds if true, reverts if false. Used by mTokens to check if minting is paused.

Function signature:

function canMint(
    address mToken, 
    address account, 
    uint256 amount) external view
Type
Name
Description

address

mToken

The market token address to verify minting for.

address

account

The account which would mint the tokens.

uint256

amount

The amount of underlying asset the account would deposit.


canRedeem()

Contract: MarketManagerCross and MarketManagerIsolated

Description: Checks if an account is allowed to redeem their tokens in the given market. Verifies that redeeming is not paused, and transfers aren't disabled in the CentralRegistry.

Function signature:

function canRedeem(address mToken,
    address account, 
    uint256 amount) external view returns (uint256, bool[] memory)
Type
Name
Description

address

mToken

The market token to verify redemption for.

address

account

The account which would redeem the tokens.

uint256

amount

The number of tokens to redeem for the underlying asset.

Return data:

Return Type
Description

uint256

Flag indicating if positions need to be closed after redemption.

bool[]

Array indicating which positions should be closed.


canRepay()

Contract: MarketManager

Description: Checks if a loan repayment is allowed for an account in the given market. Reverts if false, succeeds if true.

Function signature:

function canRepay(address mToken, address account) external view
Type
Name
Description

address

mToken

The market token to verify the repayment for.

address

account

The account who will have their loan repaid.


Market State Mappings

Important market states are stored in variables, but can still be called using a contract interface

Paused States

mintPaused()

Contract: MarketManagerCross and MarketManagerIsolated

Description: Checks if minting of a particular mToken is paused or not.

mapping(address => uint256) public mintPaused;

Inputs:

Type
Description

address

Address of the mToken to check the minting status of.

Return data:

Type
Description

uint256

Return value of 0 or 1 indicates minting is not paused. A value of 2 or greater indicates it is paused.


borrowPaused()

Contract: MarketManagerCross and MarketManagerIsolated

Description: Checks if borrowing for a particular eToken is paused or not.

mapping(address => uint256) public borrowPaused;

Inputs:

Type
Description

address

Address of the eToken to check the borrowing status of.

Return data:

Type
Description

uint256

Return value of 0 or 1 indicates borrowing is not paused. A value of 2 or greater indicates it is paused.


Collateral Invariants

Contract: MarketManagerCross and MarketManagerIsolated

Description: Returns the amount of pTokens that has been posted as collateral in shares.

mapping(address => uint256) public collateralPosted;

Inputs:

Type
Description

address

Address of the pToken to check the amount of collateral posted.

Return data:

Type
Description

uint256

amount of pTokens that has been posted as collateral in shareA.


collateralCaps()

Contract: MarketManagerCross and MarketManagerIsolated

Description: Returns the amount of pToken that can be posted of collateral, in shares.

mapping(address => uint256) public collateralCaps;

Inputs:

Type
Description

address

Address of the pToken to check the max amount of shares that can be posted as collateral.

Return data:

Type
Description

uint256

amount of pTokens that has can be posted as collateral.