> For the complete documentation index, see [llms.txt](https://docs.nftfi.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nftfi.com/overview/v3-protocol-upgrade.md).

# V3 Protocol Upgrade

### Overview

The purpose of this upgrade is to:

* Introduce flexible (pro-rata) asset and collection loans
* Improve ergonomics for approving NFT and ERC20 transfers
* Enhance gas efficiency

### Key Changes

#### Offer Schema Modifications

* **Fields Removed:**
  * `loanAdminFeeInBasisPoints`
  * `referrer`
  * `LoanContract`
* **Fields Added:**
  * `bool isProRata`
  * `uint16 originationFeeInBasisPoints`
  * `OfferType: "Regular" | "Collection"`

#### Pro Rata Interest (`isProRata`)

* **False:** Fixed interest is paid on repayment (standard NFTfi loans).
* **True:** Interest is pro-rated; less interest is charged the earlier the loan is repaid.

#### Origination Fee (`originationFeeInBasisPoints`)

* **Purpose:** Balances the risk for lenders in pro-rata loans.
* **Application:** Subtracted from the loan principal before transferring funds from the lender to the borrower.
* **Effective APR:** A new APR concept that calculates based on the principal plus the origination fee.
* **Note:** Origination Fee is independent of the `isProRata` setting.

#### Admin Fee Handling

* **Removal from Offer Schema:** The `adminFee` is no longer part of the `Offer`.
* **Loan Contract Admin Fee:**
  * Captured when the loan starts and applied upon repayment.
  * This change implies that lenders are no longer guaranteed a specific adminFee, but this is now managed by the NFTfi Foundation's smart contracts.

#### Removal of Referrer

* The `referrer` field was underutilized and is now removed from the `Offer` schema and smart contract logic.

#### Offer Types

* **New Association:** Offers are now associated with an `OfferType` rather than a `Loan Contract`.
* **Loan Coordinator Role:**
  * Specifies which Loan Contract handles a given `OfferType`.
  * Supports multiple Loan Contracts, though one default handler is specified.

#### Optional Promissory Note

* **Prom Note Flexibility:**
  * The Promissory Note (Prom Note) is now optional, similar to the existing Obligation Receipt.
* **Loan Lender Definition:**
  * If no Prom Note exists, the original lender remains the lender.
  * If a Prom Note is minted, the current owner of the Prom Note is considered the lender.
  * Only the original lender can mint a Prom Note.

#### New Loan Coordinator

* **Reason for Change:** Modifications, such as the optional Prom Note, required changes to the loan coordinator.
* **Unique IDs:** Compound loan IDs can be considered unique across loan coordinators.
* **New Contracts:** New ERC721 contracts have been introduced for the Prom Note and Obligation Receipt.

### Detailed Schema Comparison

#### Previous Offer Schema

```solidity
struct Offer {
    uint256 loanPrincipalAmount;
    uint256 maximumRepaymentAmount;
    uint256 nftCollateralId;
    address nftCollateralContract;
    uint32 loanDuration;
    uint16 loanAdminFeeInBasisPoints;
    address loanERC20Denomination;
    address referrer;
}
```

#### Updated Offer Schema

```solidity
struct Offer {
    uint256 loanPrincipalAmount;
    uint256 maximumRepaymentAmount;
    uint256 nftCollateralId;
    address nftCollateralContract;
    uint32 loanDuration;
    address loanERC20Denomination;
    bool isProRata;
    uint16 originationFeeInBasisPoints;
}
```

#### Lender signatures

In the previous protocol version (V2), lender signatures included a combination of:

* Offer
* Loan Contract

In the updated protocol version (V3), lender signatures now encompass a combination of:

* Offer
* Offer Type

The process of constructing a lender signature in protocol V3 is as follows:

```javascript
function getLenderSignature(
 lender: SignerWithAddress,
 loanPrincipalAmount: bigint,
 isProRata: boolean,
 maximumRepaymentAmount: bigint,
 nftCollateralId: bigint,
 loanDuration: bigint,
 nonce: bigint,
 nftCollateralContract: string,
 loanERC20Denomination: string,
 expiry: bigint,
 offerType: string,
 originationFee: bigint,
) {
 const chainId = mainnet;
 return lender.signMessage(
   ethers.getBytes(
     ethers.solidityPackedKeccak256(
       [
         'address',
         'uint256',
         'uint256',
         'address',
         'uint256',
         'uint32',
         'bool',
         'uint256',
         'address',
         'uint256',
         'uint256',
         'bytes32',
         'uint256',
       ],
       [
         loanERC20Denomination,
         loanPrincipalAmount,
         maximumRepaymentAmount,
         nftCollateralContract,
         nftCollateralId,
         loanDuration,
         isProRata,
         originationFee,
         lender.address,
         nonce,
         expiry,
         offerType,
         chainId,
       ],
     ),
   ),
 );
}
```

### Implementation Considerations

#### For Developers

* **Migration:** Ensure that offers are compatible with the new schema.
* **Promissory notes** We can no longer assume that a Prom Note exists for a loan, the lender has to mint it on demand

#### For Lenders

* **New Origination Fee:** Understand the implications of the origination fee, especially when offering pro-rata loans. The fee will be automatically deducted from the principal
* **Effective APR:** Be aware of the new APR calculation that considers the origination fee, which could affect your returns.

#### For Borrowers

* **Pro Rata Loans:** If opting for a pro-rata loan, note that early repayment will minimize interest costs.
* **Origination Fee:** Note that the origination fee will be deducted from the loan amount you receive.
