# Protocol - Lending Pro

### Introduction

This protocol implements a peer-to-peer lending system for ERC20 tokens. It allows ERC20 token owners to use their assets as collateral to borrow cryptocurrency, while lenders can provide loans and earn interest. The protocol is designed to be trustless, efficient, and flexible, with support for various ERC20 tokens as collateral. It also includes features for dynamic collateral management, partial liquidations, and loan refinancing. The protocol introduces a robust vault system for enhanced compliance and isolated collateral management.

### Overview

The protocol is implemented in Vyper 0.4.3. The main component is the `P2PLendingErc20` contract, which supports peer-to-peer lending backed by ERC20 collateral. It utilizes `P2PLendingBase` for shared state and common logic, `P2PLendingRefinance` as a facet for complex refinancing operations, `P2PLendingLiquidation` as a facet for liquidation operations, and interacts with a `KYCValidator` contract for compliance checks, and finally, a `P2PLendingVault` contract for collateral handling.

Defining a "market" as the pair `<CollateralToken, PrincipalToken>` , each market has its own set of smart contracts to isolate risk and enhance compliance. For the latter, the protocol introduces a novel dedicated vault system where, for each market and each borrower, the collateral tokens of all that borrower's loans are placed inside a dedicated vault. The vault is a smart contract that acts as an escrow for the collateral tokens during loans.

The lending in the context of this protocol means that:

1. A lender provides a loan offer with specific terms
2. A borrower creates a loan using their ERC20 tokens as collateral
3. The loan is created when the borrower accepts an offer
4. The borrower repays the loan within the specified term
5. If the borrower defaults, the lender or a liquidator can trigger a full liquidation to claim the ERC20 collateral
6. The loan can be partially liquidated if the Loan-to-Value (LTV) ratio exceeds a certain threshold
7. The lender can "call" a loan, initiating a repayment window before maturity
8. Borrowers can add or remove collateral from an ongoing loan
9. A loan may be replaced by the borrower while still ongoing, by accepting a new offer (refinancing)
10. The lender may replace a loan while it is still ongoing, under certain defined conditions (lender-initiated refinancing)

### Core Contracts

The protocol consists of the following core contracts:

* `P2PLendingErc20.vy`: The main entry point for users to interact with the lending protocol, incorporating the vault system.
* `P2PLendingBase.vy`: An abstract base contract that holds core state variables and implements common internal logic, including vault interactions.
* `P2PLendingRefinance.vy`: A facet contract (called via `delegatecall`) handling loan refinancing logic.
* `P2PLendingLiquidation.vy`: A facet contract (called via `delegatecall`) handling loan liquidation logic.
* `P2PLendingVault.vy`: A minimal proxy factory and implementation for individual borrower collateral vaults, deployed via CREATE2. Each vault holds the collateral for a borrower's loans and provides isolated management.
* `KYCValidator.vy`: A contract responsible for validating signed KYC attestations for borrowers and lenders.

### General considerations

The current status of the protocol follows certain assumptions:

1. Support for any ERC20 token as collateral, specified at deployment
2. Use of an ERC20 token (e.g., USDC) as a payment token, defined at deployment time for each instance of `P2PLendingErc20`&#x20;
3. Integration with an oracle (Chainlink AggregatorV3) for collateral valuation
4. All participants (borrower and lender) must have valid KYC attestations signed by a whitelisted KYC validator.
5. Loan terms are part of the lender's offers, which are signed and kept off-chain
6. Offers have an expiration timestamp and can be revoked on-chain
7. Loans can be callable by the lender after a specified `call_eligibility` period, starting a `call_window` for repayment before default
8. Loans can be partially liquidated if the LTV exceeds a `partial_liquidation_ltv`  threshold
9. Dynamic collateral management (add/remove collateral tokens) is supported
10. Additional fees are supported for both the protocol (upfront and settlement) and for the lender (origination)
11. A vault system (`P2PLendingVault`) to hold collateral. Each borrower in each market has a unique vault, deployed via CREATE2, enhancing collateral isolation and compliance

### Architecture

<div data-full-width="true"><figure><img src="https://1501474167-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUjrjglbdIn7XDGXWmDdN%2Fuploads%2FxxwfWFC1b6EX1ZQc3iV0%2Fimage.png?alt=media&#x26;token=047d8ac2-0300-402b-a196-45e2054d42ef" alt=""><figcaption></figcaption></figure></div>

The `P2PLendingErc20.vy` contract serves as the main entry point. It uses `P2PLendingBase.vy` for common logic and state, which has been updated to interact with the `P2PLendingVault` system. Each borrower has a unique, minimal proxy vault deployed via CREATE2 (`P2PLendingVault`), which securely holds their collateral. Refinancing and liquidation logic are handled by `P2PLendingRefinance.vy` and `P2PLendingLiquidation.vy` facets, respectively, which also interact with the vaults. The `KYCValidator.vy` remains an external dependency.

Users and other protocols should primarily interact with the `P2PLendingErc20.vy` contract. This contract is responsible for:

* Creating loans based on signed offers and collateral tokens, including KYC validation (collateral deposited into the borrower's dedicated vault)
* Settling loans and distributing funds (collateral withdrawn from the vault and returned to the borrower)
* Handling defaulted loans by allowing lenders to claim collateral (collateral transferred from the borrower's vault to the lender)
* Performing partial liquidations based on LTV thresholds (collateral transferred from the borrower's vault to the liquidator/lender)
* Initiating loan calls by lenders
* Allowing borrowers to add or remove collateral from existing loans (collateral deposited into/withdrawn from the borrower's vault)
* Facilitating loan refinancing for both borrowers and lenders via the `P2PLendingRefinance` facet.
* Managing protocol fees and authorized proxies
* Revoking unused offers
* Supporting loan transfers to new borrowers, including transferring collateral ownership in their respective vaults

#### Offers

Loans are created based on the borrower's acceptance of offers from lenders, which specify the loan terms. The general features of an offer are:

1. **Offer Structure**: An offer is defined by the `Offer` structure (from `P2PLendingBase`), which includes:
   * `principal`: Principal amount of the loan (optional, can be 0 for borrower-defined)
   * `apr`: Annual Percentage Rate
   * `payment_token`: Address of the payment ERC20 token
   * `collateral_token`: Address of the collateral ERC20 token
   * `duration`: Duration of the loan in seconds
   * `origination_fee_bps`: Origination fee percentage (in basis points) paid to the lender
   * `min_collateral_amount`: Minimum amount of collateral required (optional)
   * `max_iltv`: Maximum Initial Loan-to-Value (optional, used if `min_collateral_amount` isn't specified)
   * `available_liquidity`: The total principal amount the lender has allocated to this offer
   * `call_eligibility`: Time in seconds after loan start when the lender can call the loan (0 if not callable)
   * `call_window`: Time in seconds after a loan is called for the borrower to repay before default (0 if not callable)
   * `partial_liquidation_ltv`: LTV threshold (in basis points) for partial liquidation (0 if not applicable)
   * `oracle_addr`: Address of the oracle contract for collateral valuation
   * `expiration`: Expiration timestamp of the offer
   * `lender`: Address of the lender
   * `borrower`: Specific borrower address for the offer (empty address for general offers)
   * `tracing_id`: A unique identifier for tracking offers, enabling multiple loans from one offer
2. **Signed Offers**: Lenders create and sign offers off-chain. These signed offers (`SignedOffer`) combine the `Offer` structure with an EIP-712 signature.
3. **Offer Validation**: When a borrower wants to create a loan using an offer, the protocol verifies the offer's signature, checks if it's still valid (not expired), and if the `payment_token` and `collateral_token` match the contract's configuration, and if the `oracle_addr` is valid.
4. **Offer Utilization**: Offers track `available_liquidity` and `commited_liquidity` (per `tracing_id`). When an offer is used to create a loan, the loan's principal is deducted from the offer's `available_liquidity` (via `commited_liquidity`), preventing overuse beyond the specified limit.
5. **Offer Revocation**: Lenders can revoke their offers before they expire or are fully utilized. This is a one-time revocation per offer ID.

As offers are kept off-chain, to prevent abusive usage, several on-chain validations are in place:

* Each offer has an `expiration` timestamp, after which it cannot be used
* Offers can be revoked before expiration by calling `revoke_offer` in `P2PLendingErc20`
* Each offer has `available_liquidity` to define the maximum total principal that can be lent through it

#### Loans

1. **Loan Creation (`create_loan`)**: The process involves verifying the offer's signature and validity, along with KYC validation for both borrower and lender. The principal amount, minus upfront fees, is then transferred from the lender to the borrower. Upfront fees are distributed, and a loan record is created (`base.Loan` struct). Initial LTV is checked against `max_iltv`. The ERC20 collateral is transferred to a dedicated `P2PLendingVault`  for the borrower. If a vault doesn't exist for the borrower, it's created via CREATE2.
2. **Loan Settlement (`settle_loan`)**: To settle a loan, the contract calculates the total repayment amount (principal + accrued interest + protocol settlement fee). The borrower transfers this amount to the contract, which then distributes the funds to the lender and the protocol wallet. The ERC20 collateral is transferred from the borrower's `P2PLendingVault`  back to the borrower.
3. **Defaulted Loan Collateral Claim (`liquidate_loan`)**: If a loan defaults (either by reaching `maturity` or failing to repay within `call_window` after a `call_loan`), the lender or any other party (3rd party liquidator) can trigger a full liquidation via `liquidate_loan` (handled by the `P2PLendingLiquidation` facet). The collateral is transferred to the lender (or liquidator for a fee) without any fund transfers. The collateral is transferred from the borrower's `P2PLendingVault`.
4. **Partial Liquidation (`partially_liquidate_loan`)**: If the current Loan-to-Value (LTV) ratio of an active loan exceeds the `partial_liquidation_ltv` threshold defined in the offer, any address can trigger a partial liquidation via `partially_liquidate_loan` (handled by the `P2PLendingLiquidation` facet). In this process:
   * A portion of the outstanding debt is "written off" (reduced).
   * A corresponding amount of collateral is claimed from the loan.
   * A `partial_liquidation_fee` (in collateral tokens) is applied and sent to the liquidator. The remaining claimed collateral (if any) is sent to the lender.
   * The loan's `accrual_start_time` is reset to the current `block.timestamp`.
   * The goal is to bring the LTV back to the `initial_ltv` ratio, thereby "healing" the loan.
   * Collateral is claimed from the borrower's `P2PLendingVault`.
5. **Call Loan (`call_loan`)**: Lenders can initiate a loan call if the `call_eligibility` period has passed and the loan is not yet called or defaulted. This sets a `call_time` timestamp, and the borrower then has `call_window` seconds to repay the loan before it automatically defaults.
6. **Add Collateral (`add_collateral_to_loan`)**: Borrowers can add more ERC20 collateral to an ongoing loan at any time, which reduces the loan's LTV. The collateral is deposited into the borrower's `P2PLendingVault`.
7. **Remove Collateral (`remove_collateral_from_loan`)**: Borrowers can remove collateral from an ongoing loan as long as the remaining collateral is at least `min_collateral_amount` and the LTV does not exceed the `initial_ltv` (to prevent immediately increasing risk beyond the initial agreement). The collateral is withdrawn from the borrower's `P2PLendingVault`.
8. **Loan Replacement by Borrower (`replace_loan`)**: A borrower can refinance an existing loan by accepting a new offer (which might be from the same or a different lender). The function, handled by the `P2PLendingRefinance` facet, effectively settles the old loan and creates a new one using the same collateral. Liquidity adjustments are made for both borrower and lender, and any difference in collateral amount is transferred. KYC for the new lender is required. The collateral remains within the borrower's vault, with only internal adjustments if the amount changes.
9. **Loan Replacement by Lender (`replace_loan_lender`)**: A lender can initiate a replacement of an existing loan, effectively selling it to a new lender or refinancing it themselves. This is handled by the `P2PLendingRefinance` facet. The borrower's terms are protected, ensuring:
   * No additional liquidity is required from the borrower.
   * The borrower's repayment obligations (principal, interest, call eligibility, LTV thresholds) under the new conditions are not worse than the original loan's conditions up until the original loan's maturity.
   * Any necessary compensation is calculated and handled by the protocol.
10. **Loan Borrower Transfer (`transfer_loan`)**: The `transfer_loan` function allows a privileged `transfer_agent` to change the borrower of an existing loan. This is designed to support special cases (e.g., death, lost keys, or legal transfers). When a loan is transferred, the collateral is also moved from the old borrower's `P2PLendingVault` to the new borrower's `P2PLendingVault` (creating it if necessary).

#### Fees

The protocol supports several types of fees:

* **Protocol Upfront Fee**: A percentage (in basis points) of the principal, paid to the `protocol_wallet` when the loan is created. Configurable by the owner.
* **Protocol Settlement Fee**: A percentage (in basis points) of the interest, paid to the `protocol_wallet` during loan settlement. Configurable by the owner.
* **Origination Fee**: An upfront fee (in basis points of the principal) paid to the lender when a loan is created. It is part of the loan terms defined in the `Offer` structure.
* **Partial Liquidation Fee**: A percentage (in basis points) of the claimed collateral value, paid to the liquidator during a partial liquidation. Configurable by the owner.
* **Full Liquidation Fee**: A percentage (in basis points) of the claimed collateral value, paid to the liquidator during a full liquidation. Configurable by the owner.

All upfront fees are paid during loan creation, while settlement fees are paid as a fraction of the interest amount during loan settlement.

#### Roles

The protocol defines the following key roles:

* `Owner`: The privileged address that can update protocol-wide parameters (e.g., protocol fees, partial/full liquidation fees), manage authorized proxies, and propose/claim ownership.
* `Borrower`: The recipient of the loan, identified by `loan.borrower`. Can settle loans, add/remove collateral, and initiate loan replacements.
* `Lender`: The provider of the loan, identified by `loan.lender`. Can initiate loan replacements and claim collateral for defaulted loans, and call loans.
* `Liquidator`: Any address that can trigger a `partially_liquidate_loan` or `liquidate_loan` if the LTV conditions are met. Receives the `partial_liquidation_fee` or `full_liquidation_fee` for performing this action.
* `KYC Validator`: An external address registered in the `KYCValidator` contract that signs wallet attestations, ensuring compliance.
* `Transfer Agent`: A privileged address that can transfer a loan's ownership to a new borrower, primarily for compliance and recovery scenarios.

#### **Proxy Support**

The `P2PLendingErc20` contract includes support for authorized proxies, allowing for more flexible interaction with the protocol. This feature is particularly useful for integrations with other protocols or for implementing advanced user interfaces.

Key aspects of proxy support include:

1. **Authorized Proxies**: The contract maintains a mapping of `authorized_proxies: public(HashMap[address, bool])`. The contract owner can set or revoke proxy authorization using `set_proxy_authorization`.
2. **User Checks**: An internal function `_check_user` verifies if the `msg.sender` is the expected user or an `authorized_proxies[msg.sender]` acting on behalf of `tx.origin`. This is used for user-specific actions (e.g., settling loans, revoking offers).
3. **Proxy Usage**: When an authorized proxy calls a function, `tx.origin` is used to identify the actual user, allowing proxies to perform actions on behalf of users while maintaining access control.
4. **Security Considerations**: Only the contract owner can authorize or deauthorize proxies. `tx.origin` is only considered when the `msg.sender` is an authorized proxy; otherwise, `msg.sender` is used for authentication.

#### Oracles

Zharta uses [Chainlink's industry-standard decentralized oracles](https://docs.chain.link/data-feeds) as its primary data source, providing highly secure, reliable, and tamper-resistant data feeds across crypto and RWA.&#x20;

Chainlink oracles are used across our Ethereum Mainnet instance:

| BTC   | USD  |
| ----- | ---- |
| cbBTC | USD  |
| USDC  | WETH |

***

### Key Innovations

1. **Partial Liquidation**: Protects against market volatility without full liquidation.
2. **Callable Loans**: Provides flexibility for lenders while protecting borrowers.
3. **Dynamic Collateral Management**: Allows borrowers to adjust collateral levels.
4. **KYC Integration**: Ensures regulatory compliance through signed validations.
5. **Gas Optimization**: Externalized state design reduces transaction costs.
6. **Refinancing Support**: Both borrowers and lenders can replace existing loans.
7. **Vault Collateral System (v2)**: Individualized, minimal proxy vaults for each borrower's collateral, improving security, compliance, and asset segregation.

The protocol represents a significant advancement in DeFi lending by providing sophisticated risk management tools while maintaining user-friendly operations.

### Future Enhancements

Potential future developments include:

* Support for multiple collateral types.
* Cross-chain functionality.
* Advanced risk management features.
* Governance mechanisms for protocol upgrades.
* Insurance integration options.
