Lending Market

Passive Pool

Data Structures

  • ERC20 standard - Security Token

  • initExchangeRate (uint256) the fixed interest rate at the start

  • _underlyingToken (address) stable coin token contract address which allowed to deposit to the pool and earn interest

  • pools (IPassivePool[]) contain sub-passive or isolated pools

  • poolMap (address => uint256) map the sub-pool address for the pools array

  • maxUtilization (uint16) LTV for sub pool: sub pool can not borrow exceed this value

  • passivePool (IPassivePool) higher layer passive pool

  • controller (address) HY Controller contract

ValueDescription

0

Open - supply enabled, redeem enabled

1

Closed - supply disabled, redeem enabled

2

Locked - supply disabled, redeem disabled

Interfaces

GET RATE

// @dev calculate exchange rate

function rate() public view returns(uint);

GET POOL CONFIG

// @notice This method return pool config

// @return

// - the max utilization the sub pool can access fund

// - pool status

// - whitelist pool return in array

function poolConfig() view external returns(uint16, PoolStatus, IPassivePool[] memory);

GET AVAILABLE CASH

// @notice get the amount of cash available

function getCashPrior() view public returns (uint);

GET AVAILABLE CASH SUB POOL CAN BORROW

// @notice sub pool can not borrow exceed maxUtilization from passive pool

// @return

// - available cash to borrow

function getAvailableCashCanLoan() view public returns(uint);

GET UNDERLYING TOKEN (ACCEPTED STABLE COIN)

function underlyingToken() external view returns(address);

GET POOL STATE

// @notice return aggregation information

function poolState() view public returns(uint, uint, uint);

GET USER INFO BY ADDRESS

/**

* @notice Get the underlying balance of the `owner`

* @dev This also accrues interest in a transaction

* @param owner The address of the account to query

* @return The amount of underlying owned by `owner`

*/

function balanceOfUnderlying(address owner) view public returns (uint);

SUPPLY

/**

* @notice supply _underlyingToken to the pool to earn interest from various isolated pools

* @param amount_ The amount to supply to the pool

*/

function supply(uint256 amount_) external;

REDEEM

/**

* @notice redeem for underlying token for users own token share in pool

* @param redeemTokens_ The amount of share token to redeem

*/

function redeem(uint256 redeemTokens_) external;

ADMIN UPDATE STATUS

/**

* @notice updateStatus Admin update pool to disable for some features for maintain/upgrade or prevent attacks

*/

function updateStatus(PoolStatus poolStatus_) external onlyRole(DEFAULT_ADMIN_ROLE);

ADMIN UPDATE MAX UTILIZATION

/**

* @notice updateMaxUtilization Admin call this function to update how much sub pool can borrow from passive pool

* @param maxUtilization_ The LTV in range 0 - 10000

*/

function updateMaxUtilization(uint16 maxUtilization_) external onlyRole(DEFAULT_ADMIN_ROLE);

ADMIN ADD POOL

/**

* @notice addPool The function only callable by admin to add new sub-passive or sub pool to Passive pool

* that can access fund from passive pool.

* @param poolAddress_ The pool contract address

*/

function addPool(address poolAddress_) external onlyRole(DEFAULT_ADMIN_ROLE);

ADMIN REMOVE POOL

/**

* @notice removePool The function only callable by admin to remove existing sub-passive or sub pool

* Passive pool will redeem token from sub pool and remove from storage

* @param poolAddress_ The pool contract address

*/

function removePool(address poolAddress_) external onlyRole(DEFAULT_ADMIN_ROLE);

SUB-POOL BORROW

/**

* @notice borrow Triggered by sub pool when sub pool has not enough cash to cover borrow/withdraw requests

* check amount borrow not exceed LTV => call deposit to the sub pool

* @param borrowAmount_ The amount to supply to the pool. Must be in token decimal.

*/

function borrow(uint256 borrowAmount_) external onlyWhitelistPool();

UNWIND REDEEM

function unwindRedeem(address poolAddress_) external;

Workflow Diagrams

This section has a series of diagrams to illustrate the key functions of the Passive Pool

Add Isolated Pool Workflow

Supply Workflow

Redeem Workflow

Borrow Workflow

Isolated Pools

Data Structures

  • ERC20 standard - Security Token

  • stopAccruing (bool) stop accruing flag

  • interestRateModel (InterestRateModel) model which tells what the current interest rate should be

  • reserveFactorMantissa (uint) fraction of interest currently set aside for reserves

  • accrualTimeStamp (uint) block number that interest was last accrued at

  • borrowIndex (uint) accumulator of the total earned interest rate since the opening of the market

  • totalBorrows (uint) total amount of outstanding borrows of the underlying in this market

  • totalReserves (uint) total amount of reserves of the underlying held in this market

  • underlyingToken (address) stable coin token contract address which allowed to deposit to the pool and earn interest

  • hyController (address) HY Controller contract

  • passivePool (IPassivePool) higher layer passive pool

  • badDebt (uint) higher layer passive pool

  • claims (address => bool) tracking user claimed collateral or not

  • totalCanClaim (uint) total collateral can claim from borrowers

  • rewards (RewardsInterface) reward contract address for borrowers claim their reward from collaterals

  • unwindClaimedCollateral (uint) tracking total reward claim

  • grantBorrows (address => mapping(address => uint)) mapping which track grant permission to borrow token

Interfaces

GET USER UNDERLYING TOKEN BALANCE BY ADDRESS

/**

* @notice Get the underlying balance of the `owner`

* @dev This also accrues interest in a transaction

* @param owner The address of the account to query

* @return The amount of underlying owned by `owner`

*/

function balanceOfUnderlying(address owner) virtual view external returns (uint);

GET USER SNAPSHOT

/**

* @notice Get a snapshot of the account's balances, and the cached exchange rate

* @dev This is used by comptroller to more efficiently perform liquidity checks.

* @param account Address of the account to snapshot

* @return (token balance, borrow balance, exchange rate mantissa)

*/

function getAccountSnapshot(address account) virtual external view returns (uint, uint, uint);

GET BORROW RATE FOR EACH SECOND

* @notice Returns the current per-second borrow interest rate for this HYToken

* @return The borrow interest rate per second, scaled by 1e18

*/

function borrowRatePerSecond() virtual external view returns (uint);

GET SUPPLY RATE FOR EACH SECOND

/**

* @notice Returns the current per-second supply interest rate for this HYToken

* @return The supply interest rate per second, scaled by 1e18

*/

function supplyRatePerSecond() virtual external view returns (uint);

GET TOTAL BORROWED

/**

* @notice Returns the current total borrows plus accrued interest

* @return The total borrows with interest

*/

function totalBorrowsCurrent() virtual external returns (uint);

GET USER BORROWED

/**

* @notice Accrue interest to updated borrowIndex and then calculate account's borrow balance using the updated borrowIndex

* @param account The address whose balance should be calculated after updating borrowIndex

* @return The calculated balance

*/

function borrowBalanceCurrent(address account) virtual external returns (uint);

GET USER BORROWED BASED ON STORED DATA

/**

* @notice Return the borrow balance of account based on stored data

* @param account The address whose balance should be calculated

* @return The calculated balance

*/

function borrowBalanceStored(address account) virtual external view returns (uint);

GET LATEST POOL TOKEN RATE

/**

* @notice Accrue interest then return the up-to-date exchange rate

* @return Calculated exchange rate scaled by 1e18

*/

function exchangeRateCurrent() virtual external returns (uint);

GET STORED POOL TOKEN RATE

/**

* @notice Calculates the exchange rate from the underlying to the HYToken

* @dev This function does not accrue interest before calculating the exchange rate

* @return Calculated exchange rate scaled by 1e18

*/

function exchangeRateStored() virtual external view returns (uint);

GET TOTAL UNDERLYING TOKEN THIS POOL OWNED

/**

* @notice Get cash balance of this HYToken in the underlying asset

* @return The quantity of underlying asset owned by this contract

*/

function getCash() virtual external view returns (uint);

MAKE CONTRACT STORED DATA UP TO DATE WITH LATEST INTEREST

/**

* @notice Applies accrued interest to total borrows and reserves

* @dev This calculates interest accrued from the last check pointed block timestamp

* up to the current block timestamp and writes new checkpoint to storage.

*/

function accrueInterest() virtual external;

UPDATE BORROW ALLOWANCE

/**

* @notice Sender borrows assets from user granted borrow permission

* @param to The granted address to do borrow

* @param amount Allow the spender borrow amount

*/

function grantBorrow(address to, uint amount) virtual external;

BORROWER CLAIM UNDERLYING AND REWARDS WHEN COLLATERAL MATURED

function claim() virtual external;

SUPPLY

/**

* @notice Sender supplies assets into the market and receives cTokens in exchange

* @dev Accrues interest whether or not the operation succeeds, unless reverted

* @param mintAmount The amount of the underlying asset to supply

*/

function supply(uint amount) virtual external;

SUPPLY FOR ANOTHER ADDRESS

function supplyFor(address minter, uint amount) virtual external;

BORROW

/**

* @notice Sender borrows assets from the protocol to their own address

* @param borrowAmount The amount of the underlying asset to borrow

*/

function borrow(uint borrowAmount) virtual external;

BORROW FROM ANOTHER ADDRESS THAT GAVE ALLOWANCE

function borrowFrom(address from, uint borrowAmount) virtual external;

REPAY

/**

* @notice Sender repay debt

* @dev Accrues interest whether or not the operation succeeds, unless reverted

* @param repayAmount The amount to repay

*/

function repay(uint amount) virtual external;

REPAY FOR ANOTHER ADDRESS

function repayOnBehalf(address to, uint amount) virtual external;

REDEEM

/**

* @notice Sender redeems hyToken in exchange for the underlying asset

* @dev Accrues interest whether or not the operation succeeds, unless reverted

* @param redeemTokens The number of hyToken to redeem into underlying

*/

function redeem(uint redeemTokens) virtual external;

ADMIN SET RESERVE FACTOR

/**

* @notice accrues interest and sets a new reserve factor for the protocol using _setReserveFactorFresh

* @dev Admin function to accrue interest and set a new reserve factor

*/

function _setReserveFactor(uint newReserveFactorMantissa) virtual external;

ADMIN REDUCE RESERVE

/**

* @notice Accrues interest and reduces reserves by transferring to admin

* @param reduceAmount Amount of reduction to reserves

*/

function _reduceReserves(uint reduceAmount) virtual external;

ADMIN SET INTEREST RATE MODEL

/**

* @notice accrues interest and updates the interest rate model using _setInterestRateModelFresh

* @dev Admin function to accrue interest and update the interest rate model

* @param newInterestRateModel the new interest rate model to use

*/

function _setInterestRateModel(InterestRateModel newInterestRateModel) virtual external;

ADMIN SET PASSIVE POOL

/**

* @notice Sets a new passive pool for pool

* @dev Admin function to set a new passive pool

*/

function _setPassivePool(IPassivePool newPassivePool) virtual external;

ADMIN SET CONTROLLER

/**

* @notice Sets a new hi-yield controller

* @dev Admin function to set a new hi-yield controller

*/

function _setHYController(ControllerInterface newController) virtual external;

CONTROLLER UNWIND COLLATERAL

/**

* @notice Let controller withdraw when user has collateral is AI pool which is already unwind

* @dev only controller trigger this function

*/

function unwindCollateral(uint unwindAmount_, uint badDebt_) virtual external;

CONTROLLER HALT ACCRUING INTEREST

function stopAccruingInterest() virtual external;

Workflow Diagrams

This section has a series of diagrams to illustrate the key functions of the Isolated Pools

Accrue Interest Workflow

Supply Workflow

Redeem Workflow

Borrow Workflow

Claim Workflow

Controller

Data Structures

  • collateralHolder (address) the admin wallet that hold unsold debt token

  • oracle (IOracle) contract to query latest exchange rate

  • accountAssets (address => mapping(address => uint)) mapping of account -> HY pool -> collateral state

  • status (PoolStatus) contract status

ValueDescription

0

Default - deposit disabled, withdraw disabled

1

Open - deposit enabled, withdraw enabled

2

Closed - deposit disabled, withdraw disabled

  • poolStates (address => PoolState) mapping of hyPools -> Pool State (which is present detail info of each pool)

Collateral status:

ValueDescription

0

Default - not supported on the market

1

Open - deposit enabled, withdraw enabled

2

Processing - Unwind: processing borrower batches

3

Unwind - the collateral is matured

Interfaces

GET COLLATERAL AMOUNT OF AN USER IN AN ISOLATED POOL

/**

* @notice Returns the collateral amount user deposit to the pool

* @param account The address of the account to pull assets for

* @param hyPool The pool contract address which user deposited assets into

* @return an amount of token deposited

*/

function getCollateralAmount(address account, address hyPool) virtual external view returns (uint);

GET COLLATERAL VALUE OF AN USER IN AN ISOLATED POOL

/**

* @notice Returns the value of collateral account deposited

* @param account The address of the account to pull assets for

* @param hyPool The pool contract address which user deposited assets into

* @return the value of collateral

*/

function getCollateralValue(address account, address hyPool) virtual external view returns (uint);

GET TOTAL COLLATERAL OF AN ISOLATED POOL

function getCollateralTotal(address hyPool) virtual external view returns (uint);

GET STATUS OF AN ISOLATED POOL

function getCollateralStatus(address hyPool) virtual external view returns (CollateralStatus);

GET THE EXCHANGE RATE OF A TOKEN VIA ORACLE

/**

* @return the exchange rate of input token (scaled by 18)

*/

function getExchangeRate(address token) virtual external view returns (uint);

GET USER LIQUIDITY

/**

* @notice Determine the current account liquidity wrt collateral requirements

* @param account The account to determine liquidity for

* @param hyPool The HY pool contract address user wanna get liquidity from

* @return (possible error code (semi-opaque),

account liquidity in excess of collateral requirements,

* account shortfall below collateral requirements)

*/

function getAccountLiquidity(address account, address hyPool) public view returns (uint, uint);

GET USER HYPOTHETICAL LIQUIDITY

/**

* @notice Determine what the account liquidity would be if the given amounts were redeemed/borrowed

* @param hyPoolModify The market to hypothetically redeem/borrow in

* @param collateral The collateral address which user used to borrow against

* @param account The account to determine liquidity for

* @param redeemTokens The number of tokens to hypothetically redeem

* @param borrowAmount The amount of underlying to hypothetically borrow

* @return (possible error code (semi-opaque),

hypothetical account liquidity in excess of collateral requirements,

* hypothetical account shortfall below collateral requirements)

*/

function getHypotheticalAccountLiquidity(address account, address hyPoolModify, address collateral, uint redeemTokens, uint borrowAmount) public view returns (uint, uint);

USER DEPOSIT COLLATERAL TO AN ISOLATED POOL

/**

* @notice Add assets to be included in account liquidity calculation

* @param hyPool The HY pool which user want to deposit collateral and borrow assets

* @param amount The collateral amount deposit to the market

*/

function depositCollateral(address hyPool, uint amount) virtual external;

USER DEPOSIT COLLATERAL FOR ANOTHER ADDRESS TO AN ISOLATED POOL

**

* @notice Add assets to be included in another account liquidity calculation

* @param hyPool The HY pool which user want to deposit collateral and borrow assets

* @param amount The collateral amount deposit to the market

* @param to The receiver of collateral

*/

function depositCollateralTo(address hyPool, uint amount, address to) virtual external;

USER WITHDRAW HIS COLLATERAL

/**

* @notice Checks if the account should be allowed to withdraw collateral tokens

* @dev Sender must not have an outstanding borrow balance in the asset,

* or be providing necessary collateral for an outstanding borrow.

* @param hyPool The HY pool which user want to withdraw collateral

* @param amount The collateral amount to remove from market

*/

function withdrawCollateral(address hyPool, uint amount) virtual external;

AI POOL WITHDRAW COLLATERAL HOLDER (ADMIN) COLLATERAL

/**

* @notice AI Pool withdraw debt token collateral tokens from admin account

* @param hyPool The HY pool which user want to withdraw collateral

* @param amount The collateral amount to remove from market

*/

function withdrawAdminCollateral(address hyPool, uint amount, address to) virtual external;

ISOLATED POOL CHECK IF USER IS ALLOWED TO MINT

/**

* @notice Checks if the account should be allowed to mint tokens in the given market

* @param hyPool The market to verify the mint against

* @param minter The account which would get the minted tokens

* @param mintAmount The amount of underlying being supplied to the market in exchange for tokens

*/

function mintAllowed(address hyPool, address minter, uint mintAmount) virtual external;

ISOLATED POOL CHECK IF USER IS ALLOWED TO BORROW

/**

* @notice Checks if the account should be allowed to borrow the underlying asset of the given market

* @param hyPool The market to verify the borrow against

* @param borrower The account which would borrow the asset

* @param borrowAmount The amount of underlying the account would borrow

*/

function borrowAllowed(address hyPool, address borrower, uint borrowAmount) virtual external;

ISOLATED POOL CHECK IF USER IS ALLOWED TO REPAY

/**

* @notice Checks if the account should be allowed to repay

* @param hyPool The market to verify the repay request

* @param payer The account which would repay the asset

* @param repayAmount The amount of underlying the account would borrow

* @param currentDebt The debt after repay of borrower

* @param interestIndex The borrow interest index

*/

function repayBorrowVerify(address hyPool, address payer, uint repayAmount, uint currentDebt, uint interestIndex) virtual external;

ISOLATED POOL CHECK IF USER IS ALLOWED TO REDEEM

/**

* @notice Validates redeem and reverts on rejection. May emit logs.

* @param hyPool Asset being redeemed

* @param redeemer The address redeeming the tokens

* @param redeemAmount The amount of the underlying asset being redeemed

* @param redeemTokens The number of tokens being redeemed

*/

function redeemVerify(address hyPool, address redeemer, uint redeemAmount, uint redeemTokens) virtual external;

ADMIN SET THE LTV OF AN ISOLATED POOL

/**

* @notice Sets the _setLTV for Pool in market

* @dev Admin function to set per-market collateralFactor

* @param hyPool The market to set the factor on

* @param ltv The loan to value, range 0 - 1e4

*/

function _setLTV(address hyPool, uint16 ltv) virtual external;

ADMIN SUPPORT A NEW MARKET (AI - ISOLATED POOL PAIR)

/**

* @notice Add the market to the markets mapping and set it as listed

* @dev Admin function to set isListed and add support for the market

* @param hyPool The address of the market (token) to list - (HY token share)

* @param ltv Init loan to value

* @param collateral_ Init list collateral

*/

function _supportMarket(address hyPool, uint16 ltv, address collateral_) virtual external;

ADMIN UPDATE CONTRACT STATUS

/**

* @notice Admin update lending market status for some emergency cases or maintenance

* @dev Admin input new state for lending market

*/

function _updateLendingMarketStatus(PoolStatus newStatus) virtual external;

ADMIN UPDATE A MARKET STATUS

/**

* @notice Admin update pool status for some emergency cases or maintenance or pool matured

* @dev Admin input new state for HY pool

*/

function _updateHYPool(address pool, PoolStatus newStatus) virtual external;

ADMIN UPDATE ORACLE CONTRACT

/**

* @notice Admin update pool status for some emergency cases or maintenance or pool matured

* @dev Admin input new state for HY pool

*/

function _updateOracle(IOracle newOracle) virtual external;

ADMIN UPDATE COLLATERAL HOLDER ADDRESS

/**

* @notice set new collateral address. Please make sure old admin does not hodl any collateral

* @dev set new address to hodl collaterals

* @param collateralHolder_ new holder address

*/

function _setCollateralHolder(address collateralHolder_) virtual external;

UNWIND PROCESS

// @notice LM will redeem token from AI pool and mark collateral is already unwind

// @dev this function only handle AI pool ATM

function unwind(address hyPool, bytes memory borrowers) external;

Workflow Diagrams

This section has a series of diagrams to illustrate the key functions of the Controller

Deposit Collateral Workflow

Withdraw Collateral Workflow

Unwind Workflow

Leverage Processor

Interfaces

LEVERAGE

/**

* @dev Leverage by looping purchases using the Accrued Interest Pool and Lending Market

*

*/

function leverage(IERC20 token, uint amount, AccruedInterestPool aiPool, uint n) external;

Workflow Diagrams

This section has a series of diagrams to illustrate the key functions of the Leverage Processor

Leverage Processor Workflow

Last updated