Skip to main content

LendController

The LendController is the primary user-facing contract for each lending market. Borrowers interact with it to create loans, manage collateral, borrow more, repay, and get liquidated. It wraps the core controller.vy module — which contains all shared loan logic — and extends it with lending-specific features: borrow caps, vault token transfers, and available balance tracking.

Each lending market gets its own LendController instance, deployed by the LendFactory.

LendController.vy

The source code for the LendController.vy contract can be found on GitHub. The core module is controller.vy. The contract is written in Vyper version 0.4.3.

Deployment addresses will be added once contracts are finalized.

info

The LendController exports most of its functions from the controller.vy module. Functions documented below include both module-exported functions and lending-specific extensions. The module pattern means the core loan logic is shared with MintController (used for crvUSD mint markets).


Loan Management

create_loan

LendController.create_loan(_collateral: uint256, _debt: uint256, _N: uint256)

Creates a new loan by depositing collateral and borrowing tokens. The collateral is distributed across _N bands in the AMM.

InputTypeDescription
_collateraluint256Amount of collateral to deposit
_debtuint256Amount of borrowed tokens to receive
_Nuint256Number of bands to distribute collateral across (4–50)

Emits: Borrow event.

<>Source code
Example

borrow_more

LendController.borrow_more(_d_collateral: uint256, _d_debt: uint256)

Adds additional collateral and/or borrows more tokens against an existing loan.

InputTypeDescription
_d_collateraluint256Additional collateral to deposit (can be 0)
_d_debtuint256Additional debt to take on (can be 0)

Emits: Borrow event.

<>Source code
Example

add_collateral

LendController.add_collateral(_d_collateral: uint256, _for: address)

Adds collateral to an existing loan without borrowing more. Can be called by anyone on behalf of a borrower.

InputTypeDescription
_d_collateraluint256Amount of collateral to add
_foraddressAddress of the borrower to add collateral for

Emits: Borrow event.

<>Source code
Example

remove_collateral

LendController.remove_collateral(_d_collateral: uint256)

Removes collateral from an existing loan. Reverts if the resulting health would be too low.

InputTypeDescription
_d_collateraluint256Amount of collateral to remove

Emits: RemoveCollateral event.

<>Source code
Example

repay

LendController.repay(_d_debt: uint256, _for: address)

Repays debt for a loan. If _d_debt exceeds the current debt, only the outstanding debt is repaid. Can be called by anyone on behalf of a borrower.

InputTypeDescription
_d_debtuint256Amount of debt to repay (use max_value(uint256) to repay all)
_foraddressAddress of the borrower to repay for

Emits: Repay event.

<>Source code
Example

liquidate

LendController.liquidate(_user: address, _min_x: uint256)

Liquidates an unhealthy loan (health < 0). The caller repays the debt and receives the remaining collateral. Supports partial liquidation if the position is partially in soft liquidation.

InputTypeDescription
_useraddressAddress of the borrower to liquidate
_min_xuint256Minimum amount of collateral to receive (slippage protection)

Emits: Liquidate event.

<>Source code
Example

Loan Info

debt

LendController.debt(_user: address) -> uint256: view

Returns the current debt of a user, including accrued interest.

InputTypeDescription
_useraddressBorrower address

Returns: current debt (uint256).

<>Source code
Example

health

LendController.health(_user: address, _full: bool) -> int256: view

Returns the health of a user's loan. Health > 0 means the loan is safe; health < 0 means it can be liquidated. If _full is true, returns health assuming the worst-case scenario where all collateral has been soft-liquidated.

InputTypeDescription
_useraddressBorrower address
_fullboolIf true, use full (pessimistic) health calculation

Returns: health value (int256).

<>Source code
Example

loan_exists

LendController.loan_exists(_user: address) -> bool: view

Returns whether a loan exists for the given user.

InputTypeDescription
_useraddressBorrower address

Returns: whether the loan exists (bool).

<>Source code
Example

user_state

LendController.user_state(_user: address) -> uint256[4]: view

Returns the full state of a user's loan: [collateral, stablecoin, debt, N].

InputTypeDescription
_useraddressBorrower address

Returns: [collateral, stablecoin, debt, N] (uint256[4]).

<>Source code
Example

user_prices

LendController.user_prices(_user: address) -> uint256[2]: view

Returns the upper and lower price bounds of a user's collateral bands in the AMM.

InputTypeDescription
_useraddressBorrower address

Returns: [price_upper, price_lower] (uint256[2]).

<>Source code
Example

users_to_liquidate

LendController.users_to_liquidate(_from: uint256, _limit: uint256) -> IController.Position[]: view

Returns a list of user positions that can be liquidated, paginated.

InputTypeDescription
_fromuint256Starting index
_limituint256Maximum number of positions to return

Returns: array of liquidatable positions (IController.Position[]).

<>Source code
Example

tokens_to_liquidate

LendController.tokens_to_liquidate(_user: address) -> uint256: view

Returns the amount of borrowed tokens needed to fully liquidate a user's position.

InputTypeDescription
_useraddressBorrower address

Returns: tokens needed for liquidation (uint256).

<>Source code
Example

total_debt

LendController.total_debt() -> uint256: view

Returns the total outstanding debt across all loans in this market, including accrued interest.

Returns: total debt (uint256).

<>Source code
Example

n_loans

LendController.n_loans() -> uint256: view

Returns the total number of active loans.

Returns: number of loans (uint256).

<>Source code
Example

loans

LendController.loans(_index: uint256) -> address: view

Returns the borrower address at a given loan index.

InputTypeDescription
_indexuint256Loan index

Returns: borrower address (address).

<>Source code
Example

loan_ix

LendController.loan_ix(_user: address) -> uint256: view

Returns the index of a user's loan in the loans array.

InputTypeDescription
_useraddressBorrower address

Returns: loan index (uint256).

<>Source code
Example

Health Previews

These functions allow UIs to show the health impact of operations before the user submits a transaction.

create_loan_health_preview

LendController.create_loan_health_preview(_user: address, _collateral: uint256, _debt: uint256, _N: uint256, _full: bool) -> int256: view

Previews the health of a loan that would result from calling create_loan.

InputTypeDescription
_useraddressBorrower address
_collateraluint256Collateral amount
_debtuint256Debt amount
_Nuint256Number of bands
_fullboolFull (pessimistic) health

Returns: predicted health (int256).

<>Source code
Example

borrow_more_health_preview

LendController.borrow_more_health_preview(_user: address, _d_collateral: uint256, _d_debt: uint256, _full: bool) -> int256: view

Previews the health after borrowing more.

InputTypeDescription
_useraddressBorrower address
_d_collateraluint256Additional collateral
_d_debtuint256Additional debt
_fullboolFull (pessimistic) health

Returns: predicted health (int256).

<>Source code
Example

add_collateral_health_preview

LendController.add_collateral_health_preview(_user: address, _d_collateral: uint256, _full: bool) -> int256: view

Previews the health after adding collateral.

InputTypeDescription
_useraddressBorrower address
_d_collateraluint256Collateral to add
_fullboolFull (pessimistic) health

Returns: predicted health (int256).

<>Source code
Example

remove_collateral_health_preview

LendController.remove_collateral_health_preview(_user: address, _d_collateral: uint256, _full: bool) -> int256: view

Previews the health after removing collateral.

InputTypeDescription
_useraddressBorrower address
_d_collateraluint256Collateral to remove
_fullboolFull (pessimistic) health

Returns: predicted health (int256).

<>Source code
Example

repay_health_preview

LendController.repay_health_preview(_user: address, _d_debt: uint256, _full: bool) -> int256: view

Previews the health after repaying debt.

InputTypeDescription
_useraddressBorrower address
_d_debtuint256Debt to repay
_fullboolFull (pessimistic) health

Returns: predicted health (int256).

<>Source code
Example

liquidate_health_preview

LendController.liquidate_health_preview(_user: address, _full: bool) -> int256: view

Previews what a user's health would be after liquidation.

InputTypeDescription
_useraddressBorrower address
_fullboolFull (pessimistic) health

Returns: predicted health (int256).

<>Source code
Example

Lending-Specific

These functions are unique to LendController and not part of the shared controller.vy module.

available_balance

LendController.available_balance() -> uint256: view

Returns the amount of borrowed tokens currently available for new loans — i.e., the tokens deposited by lenders minus what's already lent out.

Returns: available balance (uint256).

<>Source code
Example

borrow_cap

LendController.borrow_cap() -> uint256: view

Returns the maximum total debt allowed for this market. If 0, there is no cap.

Returns: borrow cap (uint256).

<>Source code
Example

vault

LendController.vault() -> address: view

Returns the address of the associated ERC4626 vault.

Returns: vault address (address).

<>Source code
Example

set_borrow_cap

LendController.set_borrow_cap(_borrow_cap: uint256)
Guarded Method

This function is only callable by the factory admin.

Sets the maximum total debt cap for this market.

InputTypeDescription
_borrow_capuint256New borrow cap (0 = unlimited)

Emits: SetBorrowCap event.

<>Source code
Example

set_admin_percentage

LendController.set_admin_percentage(_admin_percentage: uint256)
Guarded Method

This function is only callable by the factory admin.

Sets the percentage of interest that goes to the protocol (admin fees) rather than lenders.

InputTypeDescription
_admin_percentageuint256Admin fee percentage (scaled, max 50%)

Emits: SetAdminPercentage event.

<>Source code
Example

Calculations

max_borrowable

LendController.max_borrowable(_d_collateral: uint256, _N: uint256, _user: address) -> uint256: view

Returns the maximum amount that can be borrowed given a collateral amount and number of bands, respecting the borrow cap and available balance.

InputTypeDescription
_d_collateraluint256Collateral amount
_Nuint256Number of bands
_useraddressBorrower address (for existing loan context)

Returns: max borrowable amount (uint256).

<>Source code
Example

min_collateral

LendController.min_collateral(_d_debt: uint256, _N: uint256) -> uint256: view

Returns the minimum collateral required for a given debt amount and number of bands.

InputTypeDescription
_d_debtuint256Desired debt amount
_Nuint256Number of bands

Returns: minimum collateral required (uint256).

<>Source code
Example

calculate_debt_n1

LendController.calculate_debt_n1(_collateral: uint256, _debt: uint256, _N: uint256) -> int256: view

Calculates the upper band number (n1) for a loan with the given parameters. Used to determine where collateral will be placed in the AMM.

InputTypeDescription
_collateraluint256Collateral amount
_debtuint256Debt amount
_Nuint256Number of bands

Returns: upper band number (int256).

<>Source code
Example

Configuration

set_amm_fee

LendController.set_amm_fee(_fee: uint256)
Guarded Method

This function is only callable by the factory admin.

Sets the swap fee on the associated AMM.

InputTypeDescription
_feeuint256New fee value
<>Source code
Example

set_borrowing_discounts

LendController.set_borrowing_discounts(_loan_discount: uint256, _liquidation_discount: uint256)
Guarded Method

This function is only callable by the factory admin.

Sets the loan discount and liquidation discount. The loan discount determines the maximum LTV, and the liquidation discount determines the threshold for liquidation.

InputTypeDescription
_loan_discountuint256New loan discount
_liquidation_discountuint256New liquidation discount

Emits: SetBorrowingDiscounts event.

<>Source code
Example

set_monetary_policy

LendController.set_monetary_policy(_monetary_policy: address)
Guarded Method

This function is only callable by the factory admin.

Sets the monetary policy contract that determines the borrow rate.

InputTypeDescription
_monetary_policyaddressNew monetary policy address

Emits: SetMonetaryPolicy event.

<>Source code
Example

set_price_oracle

LendController.set_price_oracle(_price_oracle: address)
Guarded Method

This function is only callable by the factory admin.

Sets the price oracle for this market.

InputTypeDescription
_price_oracleaddressNew price oracle address
<>Source code
Example

set_callback

LendController.set_callback(_callback: address)
Guarded Method

This function is only callable by the factory admin.

Sets the liquidity mining callback (gauge) for the AMM.

InputTypeDescription
_callbackaddressLiquidity mining callback address

Emits: SetLMCallback event.

<>Source code
Example

Other Methods

amm

LendController.amm() -> address: view

Returns the AMM (LLAMMA) address for this market.

Returns: AMM address (address).

<>Source code
Example

amm_price

LendController.amm_price() -> uint256: view

Returns the current price from the AMM's internal oracle.

Returns: AMM price (uint256).

<>Source code
Example

monetary_policy

LendController.monetary_policy() -> address: view

Returns the current monetary policy address.

Returns: monetary policy address (address).

<>Source code
Example

liquidation_discount

LendController.liquidation_discount() -> uint256: view

Returns the current liquidation discount.

Returns: liquidation discount (uint256).

<>Source code
Example

loan_discount

LendController.loan_discount() -> uint256: view

Returns the current loan discount.

Returns: loan discount (uint256).

<>Source code
Example

admin_fees

LendController.admin_fees() -> uint256: view

Returns the amount of uncollected admin fees.

Returns: admin fees (uint256).

<>Source code
Example

admin_percentage

LendController.admin_percentage() -> uint256: view

Returns the current admin fee percentage.

Returns: admin percentage (uint256).

<>Source code
Example

collect_fees

LendController.collect_fees()

Collects accumulated admin fees and sends them to the fee receiver set in the factory.

Emits: CollectFees event.

<>Source code
Example

save_rate

LendController.save_rate()

Updates the stored interest rate from the monetary policy. This is called automatically during loan operations but can also be called externally to keep the rate fresh.

<>Source code
Example

version

LendController.version() -> String[10]: view

Returns the contract version string (e.g., "2.0.0-lend").

Returns: version string (String[10]).

<>Source code
Example

factory

LendController.factory() -> address: view

Returns the factory that deployed this controller.

Returns: factory address (address).

<>Source code
Example