# What is Brila?

[**Brila**](https://brila.finance/) is modular infrastructure for powering the next generation of decentralized finance from RWA lending to NFT liquidity.

BrilaRWA connects lenders, borrowers, and portfolio managers via smart contracts governed by the [BRLA token](/brila-protocol/brla-token).

Since its launch in November 2020, BrilaRWA (formerly TrueFi) has originated more than $1.7bn in loans to >30 borrowers and paid more than $40mm in interest to protocol participants.

Borrowers include both leading crypto-focused institutions and "real world" firms, such as fintech companies, trading firms, and credit funds.


# Lend

Getting started as a Lender on Brila

### Why lend on Brila?

Transactions on Brila infrastructure are **transparent** and **publicly auditable,** enabling lenders to track every dollar (or token) lent and borrowed, as well as the status and structure of every loan.

Lending opportunities on Brila span multiple sectors and various risk/return profiles.

### How does lending on Brila RWA work?

Brila's smart contract infrastructure helps lenders, managers, and borrowers interact transparently and seamlessly.

For lenders, the process is as follows:

1. **Find opportunities** via [app.brila.finance](https://app.brila.finance/)
2. **Onboard / KYC via Keyring** *(if necessary)*
3. [**Lend funds**](/user-guide/lend/how-to-lend#how-do-i-lend-on-truefi) with instant settlement 24/7
4. **Monitor activity & track returns**
5. [**Redeem / Withdraw funds**](/user-guide/lend/how-to-withdraw) when liquidity is available

### How do I learn about portfolio managers on Brila RWA?

Portfolio Managers ("PMs") are [onboarded through Brila governance](/user-guide/manage/onboarding-for-managers). You can find posts from PMs and additional information on the Brila[ forum](https://forum.truefi.io/).

For the most up-to-date information on PMs, please see the Brila[ app](https://app.truefi.io/) for a list of active managers and links to their materials.

### What types of activity does Brila RWA support?

Brila smart contracts support multiple structures for various market participants.

* [Lines of Credit](/brila-protocol/automated-lines-of-credit) enable borrowers to source capital directly from lenders.
* [Asset Vaults](/brila-protocol/asset-vaults) support off-chain credit, or "Real World Asset" (RWA), activity.
* [Credit Vaults](/brila-protocol/credit-vaults) support unitranche and multi-tranche onchain credit deals.

### What are the fees for using Brila contracts?

Brila vaults pay a protocol fee to the Brila DAO treasury and an optional fee to the portfolio's manager (if applicable).

Fees are stated on a per annum basis, accrued continuously and paid periodically by each vault's smart contract. Read [here](/brila-protocol/automated-lines-of-credit#what-are-the-fees-on-lines-of-credit) for more detail and to see an example.

To find current fee rates, see vaults listed in the [Brila app](https://app.brila.finance/).

### Are Brila contracts ERC-4626 compliant?

Yes. Brila pools follow [ERC-4626 standards](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/).


# How to lend

Once a user is ready to lend, the user is required to complete two transactions:

1. `approve` : approves the vault smart contract to transfer up to a certain allowance of the asset. (Note: This is a typical interaction on the Ethereum network. Read more about the 'approve' function [here](https://metamask.zendesk.com/hc/en-us/articles/6174898326683-What-is-a-token-approval-)).
2. `deposit` : lends funds to the vault. In return, the lender receives lending pool tokens ("LP tokens").

{% hint style="info" %}
Note that for some vaults, lender funds are locked until the pool's maturity date or until sufficient liquid funds are available within the pool. Please review and confirm details on each pool before lending.
{% endhint %}

<figure><img src="/files/xcOLnxfwxmdfYXHsH51h" alt=""><figcaption></figcaption></figure>


# How to withdraw

Lenders can redeem funds once a vault has reached its maturity date (or depending on the vault's configuration, once liquid funds are available).

When redemptions are available, a lender can redeem LP tokens for underlying tokens by calling [`withdraw`](/brila-protocol/other-concepts/other-legacy-contracts/managed-portfolio-legacy#withdraw-uint256-sharesamount-bytes-memory) on the token smart contract.

{% hint style="info" %}
Note that for some vaults, redemptions not be available until the vault's maturity date or may be processed at the manager's discretion.

Please review and confirm details on each vault before lending.
{% endhint %}

<figure><img src="/files/Xk3jyTa9BS6InipLTDll" alt=""><figcaption></figcaption></figure>


# Onboarding / KYC (for permissioned pools)

Portfolio Managers can configure permissioned pools on Brila. Accordingly, some vaults on Brila may require identity verification before lenders can gain access.

{% hint style="info" %}
Brila partner Keyring can help institutional lenders onboard and interact with Brila.

For more info, visit <https://www.keyring.network/keyring-connect>.
{% endhint %}

### How to access permissioned pools

Lenders can get access to permissioned pools by clicking on the **"Get access"** button on the vault's page. This will route the user to verify their identity with an external provider, as defined by the portfolio manager's policy.

<figure><img src="/files/32xtyAEb7Q3YLqhagwyn" alt=""><figcaption><p>Example: How to get access to permissioned portfolios</p></figcaption></figure>

### Why do users need to verify their identity?

In order to be compliant with regulations in certain jurisdictions, Portfolio Managers must verify a user’s identity before and while doing business with them.

This is in an effort to maintain the integrity of the pool. The KYC process is a first line of defense against fraud, sanctions evasion, and terrorist financing. Compliance with global KYC standards helps ensure the pool against reputational risk, regulatory fines, and even cease and desist orders.

Users are required to provide credentials that prove their identity and address. Verification credentials can include ID card verification, face verification, biometric verification, and/or document verification. For proof of address, utility bills and bank statements are examples of acceptable documentation.

This process is important for determining users' risk and whether they can meet the Portfolio Manager’s requirements to use their services. Moreover, it’s also a legal requirement to comply with Anti-Money Laundering (AML) laws in certain jurisdictions.

### Why are some pools for Non-US lenders only?

US regulations specify certain requirements, including licenses, that Portfolio Managers need to meet in order to offer investment opportunities to US persons (citizens or legal residents) and entities.

Failing to comply with such regulations would make Portfolio Managers subject to liability, which would severely impact the pool.


# Borrow

Getting started as a Borrower on TrueFi

### Why borrow on Brila?

Borrowers can find capital at competitive rates from a network of global liquidity on Brila.

Using Brila's infrastructure, borrowers can access capital markets 24/7 with faster settlement than traditional finance systems.

Borrowers on Brila also have an opportunity to build their public "on-chain" financial reputation and position themselves to access more capital at better rates moving forward.

<figure><img src="/files/YbB9ZITGVO7qw8x7vfHM" alt=""><figcaption></figcaption></figure>

### **Who can borrow on Brila?**

Borrowers on Brila include leading institutions in the crypto industry, as well as "real world finance" borrowers, such as fintechs and credit funds.

See below for recent press on Brila borrowers:\
<https://www.pymnts.com/loans/2022/mexican-fintech-uses-defi-to-provide-collateral-free-loans-to-small-businesses/>

### Getting started as a borrower

Borrowers follow a simple process to receive their first loan on TrueFi:

1. **Onboard with a portfolio manager.**
   * Borrowers can communicate with managers directly, or reach out to the team via official channels like X to get connected with potential managers in the Brila ecosystem.
   * Complete KYB and negotiate loan terms with a portfolio manager.
2. [**Receive a loan.**](/user-guide/borrow/receiving-a-loan)
3. [**Repay a loan.**](/user-guide/borrow/repaying-a-loan)


# Receiving a loan

{% hint style="info" %}
If you are a prospective borrower, you can request information or post a borrow request at <https://forum.truefi.io/>.
{% endhint %}

In the typical borrower experience, borrowers in managed vaults follow the steps below:

1. PM and Borrower negotiate loan terms offline. PM then submits terms on-chain for review.
2. Borrower accepts terms by executing an on-chain transaction (see screenshot below).
3. PM disburses funds to borrower's address. The borrower receives funds in their wallet.
4. Borrower [repays loan](/user-guide/borrow/repaying-a-loan) at, or before, time of loan maturity.

<figure><img src="/files/JJMyPdbteBjUf89gg83E" alt=""><figcaption></figcaption></figure>


# Repaying a loan

How to repay a loan:

1. Borrower goes to [app.brila.finance](https://app.brila.finance/)
2. Borrower clicks 'Repay' button shown on loan details

   <figure><img src="/files/M8BtSMaX2QCSAlGHGf9H" alt=""><figcaption></figcaption></figure>
3. Borrower is first prompted to approve transfer of funds (must complete `approve()` on-chain transaction).
4. Borrower is then prompted to [`repay`](/brila-protocol/other-concepts/instruments/bulletloans#repay-uint256-instrumentid-uint256-amount) transaction. This transaction transfers funds back to the portfolio and repays the full amount owed on the loan.
   * Once this transaction is complete, the loan is marked ‘repaid’ automatically and no further action by the borrower is needed.

<figure><img src="/files/Igdlz5phIbKoabS9gMkR" alt=""><figcaption></figcaption></figure>


# Manage

Getting started as a Portfolio Manager on TrueFi

Portfolio Managers ("PMs") can use Brila infrastructure to run their own credit fund on the Ethereum blockchain and additional networks.

In this section, PMs can learn how to launch and manage a fund on Brila. Below is a step-by-step guide to running a fund on TrueFi:

1. [Onboarding for managers](/user-guide/manage/onboarding-for-managers): New managers introduce themselves to the Brila community and are vetted by Brila governance. During this process, potential lenders can communicate with and learn more about PMs.
2. [Creating a vault](/user-guide/manage/creating-a-vault): PMs deploy their fund (called a "vault") via the Brila app.
3. [Disbursing loans](/user-guide/manage/disbursing-loans): Once a vault is live, PMs can disburse funds to borrowers. The Brila app makes it easy for PMs and borrowers to create loans, disburse funds, and repay loans.
4. **Continuous fund management:** Brila smart contracts streamline the processing of lender inflows/outflows, as well as principal and interest payments, in real-time 365/24/7.

{% hint style="info" %}
Brila's partner Keyring can help institutional users onboard and operate on Brila.

For more info, visit [keyring.network/keyring-connect](https://www.keyring.network/keyring-connect).
{% endhint %}

### How does it work?

For a brief overview, see the demo video below:

{% embed url="<https://www.loom.com/share/57de59608b0a480f83d4a08fe4887111>" %}

When [creating a portfolio](/user-guide/manage/creating-a-vault) the PM configures policies for fees, min/maximum portfolio size, portfolio maturity dates/tenor, and other parameters.

Additionally, PMs have the option to run[ permissioned portfolios](/user-guide/manage/managing-kyc-kyb-requirements), where they can enforce KYC/KYB policies for lenders. Read more [here](/user-guide/manage/managing-kyc-kyb-requirements) on how PMs can set such policies.

PMs are able to share information and due diligence materials with lenders via the TrueFi app.

### **Does Brila support "real world" use cases?**

Yes, TrueFi offers infrastructure to support "real world" financing as well as crypto-centric financing deals. TrueFi smart contracts give PMs the ability to create instruments such as fixed rate loans, lines of credit, amortizing loans, and multi-tranche facilities.

For a recent example, read here:\
<https://blockworks.co/news/on-chain-investors-us-treasury>

### What are potential benefits of using Brila?

* **Reduced overhead cost**, by servicing otherwise difficult and expensive components of fund management on-chain.
* **Access Brila's global liquidity network,** leveraging DeFi rails to interact with lenders across the world 24/7/365.
* **Best-in-class infrastructure** enables PMs to configure pools to their specifications.


# Onboarding for managers

Portfolio Managers ("PMs") can launch and run their own funds on Brila, using [Brila credit infrastructure](/brila-protocol/credit-vaults).

### How to onboard (as a Portfolio Manager)

To deploy a portfolio, managers must be approved by TrueFi governance via the following steps:

1. PM posts forum request at <https://forum.truefi.io/>.
   * This forum request should outline the PM's background and plans, along with the PM's Ethereum (Arbitrum or Plume) address.
   * For previous examples, please see [here](https://forum.truefi.io/c/manager-requests/9).
2. After governance approval, TrueFi governance adds the PM's address to an allowlist.
   * This enables the PM to deploy vaults from a factory contract.
3. PM deploys vault
   * Vaults are supported on Ethereum, Arbitrum, Plume, and HyperEVM.
   * For more details on how vaults work, visit [Credit Vaults](/brila-protocol/credit-vaults) and [Asset Vaults](/brila-protocol/asset-vaults).


# Creating a vault

Once successfully [onboarded](/user-guide/manage/onboarding-for-managers), a portfolio manager can launch a new vault.

PMs can easily create a fund by clicking "Create New Portfolio" at <https://app.brila.finance/managers>. To test and demo the product, see the guide here: [Credit Vault tutorial](/brila-protocol/credit-vaults/credit-vault-tutorial).

The TrueFi application walks PMs through the vault creation process, as shown in the demo below:

{% embed url="<https://www.loom.com/share/57de59608b0a480f83d4a08fe4887111>" %}
Demo of vault creation
{% endembed %}

### Vault creation parameters and details

In vault creation, PMs are able to configure the following settings (among others):

* Capital formation rules
  * During the **Capital Formation period**, lenders can commit funds with assurance that the smart contract will return funds (with no fees) if certain requirements are not satisfied. For more details, read [here](/brila-protocol/credit-vaults#what-is-the-capital-formation-period).
    * Example: PM configures a 30 day capital formation period and minimum vault size of 1M USDC. If the fund has not raised ≥1M USDC by day 30, then principal will be returned to lenders with no fees taken. If the fund raises ≥1M USDC within 30 days, then the PM can move the vault to 'Live' status and deploy loans from the vault.
* Tranche configurations
  * Number of tranches: single tranche / 2 tranches / 3 tranches
  * Minimum subordination ratios for each tranche
  * *For more details on tranche mechanics, read* [*here*](/brila-protocol/credit-vaults#how-do-interest-and-repayments-flow-to-lenders)*.*
* Vault duration / maturity date
  * Lender funds will be locked up until the vault's maturity date
  * All loans within the vault must mature before, or on the maturity date
* Fee structure
  * Vault fee: in basis points, on annualized basis
  * *For more details on fees, read* [*here*](/brila-protocol/credit-vaults#what-are-the-fees-on-structured-credit-vaults)*.*
* Lender permissions / restrictions
  * i.e. manager can require KYC or set custom list of allowed lenders
  * *For more details on permissions, read* [*here*](/brila-protocol/credit-vaults#how-are-lender-restrictions-permissions-managed)*.*


# Disbursing loans

### How to disburse a loan

To disburse a loan, click 'Disburse a loan' on the portfolio page and follow the on-screen prompts (see below for more detail):

<figure><img src="/files/O56EFjwRHtC78cEgsGoI" alt=""><figcaption></figcaption></figure>

Parameters required for each loan:

* Borrower address
* Principal Amount
* Loan term (in days)
* [Number of installments](#user-content-fn-1)[^1]
* Interest rate (APR)

Once loan terms are accepted by borrower, the manager can disburse funds to the borrower's address:

<figure><img src="/files/FH2y0jW9H40O3sNwmrKz" alt=""><figcaption></figcaption></figure>

[^1]: L[oans can accomodate multiple periodic interest payments. If bullet loan, set to 1.](#user-content-fn-2)\[^2]


# Managing KYC/KYB requirements

PMs can enforce restrictions on who can lend to their vaults by using TrueFi's [Controllers](/brila-protocol/other-concepts/controllers) architecture. PMs can easily configure permissioned vaults that meet their specs.

Below are some notes on standard configurations available. PMs can also implement their own custom policies (as decribed [here](/brila-protocol/other-concepts/controllers)).

* *KYC users only:* manager delegates access list management to external KYC provider, such as [Archblock](https://app.trusttoken.com/signup-or-signin), [Verite](https://www.circle.com/en/pressroom/circle-and-industry-leaders-have-built-the-first-decentralized-identity-proof-of-concept-for-crypto-finance-using-verite-credentials), or others.
* *Allowlisted lenders only:* manager limits access to a set of allowlisted wallet addresses.
* *Non-US lenders only:* only non-US IP addresses can access portfolio; lenders must attest that they are non-US persons


# Lines of Credit

Automated lending pools governed by supply/demand curve

{% hint style="info" %}
For technical docs, see [Lines of Credit technical details](/brila-protocol/automated-lines-of-credit/lines-of-credit-technical-details)
{% endhint %}

## **What are Lines of Credit?**

**Lines of Credit** (also referred to as Automated Lines of Credit or "ALOCs”) are lending pools for a single borrower, where the interest rate paid by borrowers is determined by a configurable interest rate curve.

### Why use Lines of Credit?

Lines of Credit provide borrowers a flexible way to raise capital and lenders a way to deploy capital while maintaining high liquidity.

Lines of Credit use supply and demand dynamics to set interest rates, giving lenders incentive to supply capital to pools above target utilization rates and borrowers incentive to maintain optimal liquidity ratios in each pool.

### How are interest rates determined?

It’s generally (but not always) the case that as utilization increases, the interest rate increases (but not past a ceiling interest rate, chosen by the borrower) and as utilization decreases, the interest rate decreases (but not past a floor interest rate, chosen by the borrower)

From the borrower’s perspective: Borrower expresses that they are willing to borrow between \[x]% and \[y]%, with an ideal utilization rate of \[90]% so that some amount of instant liquidity is available to lenders.

From the lender’s perspective: Lenders want to deploy capital to loan opportunities without losing the ability to withdraw funds when needed. In return, lenders earn a dynamic rate based on the pool utilization and interest rate curve configuration.

### Do lines of credit have a maturity date?

Yes, each line of credit has a specified maturity date (`endDate`). All debt and interest is due by this maturity date. Once maturity has passed, borrowers cannot draw additional capital and lenders cannot lend additional funds to this line of credit.

### How does lending to a Line of Credit work?

Once a Line of Credit is created, lenders can put funds into the pool if they meet the lender restriction requirements that have been configured (lines of credit can be permissionless, or [permissioned pools](/user-guide/manage/managing-kyc-kyb-requirements)).

Lenders can withdraw from the pool’s idle funds at any time funds are available. As lenders enter or exit the pool, the utilization of the pool changes, and thus, the lender APY changes as the interest rate paid by the borrower changes.

### How does borrowing from a Line of Credit work?

Once a [line of credit has been created](#how-are-truefi-lines-of-credit-created), borrowers can withdraw idle funds at any time before the pool's maturity (`endDate`). After maturity, deposit and borrow actions within the line of credit are disabled, and borrower must repay all principal and interest accrued.

### How is interest accrued?

Interest owed by the borrower is accrued block-by-block. Similarly, lenders accrue interest each block as the pool value increases (pool value = principal + interest accrued).

Note that for borrowers, interest owed is calculated upon the principal borrowed (i.e. interest amount is not compounded, **borrower does not “pay interest on interest”**).

### How are Lines of Credit created?

Borrowers work with DAO governance to create a line of credit. This should be done as a standard proposal to the DAO describing all the parameters involved in the proposal. It is a 2 step process.

1. Borrower requests Line of Credit approval by the DAO and recommends parameters (see section below [What are the parameters for each Line of Credit?](#how-can-alocs-be-configured))
2. If vote passes, then the address requesting creation is allowlisted for line of credit creation. Borrower deploys Line of Credit with approved parameters.

### What are the parameters for each Line of Credit?

1. Borrowers define base parameters:
   * Underlying token: can denominate pool in any ERC20 (including but not limited to USDC, USDT, WETH, etc)
   * protocolFee (const) = 50 bps paid by lender at withdrawal
   * premiumFee \[optional]: = set to 0 by default; can be configured by borrower
   * endDate: all loans must be repaid by end date
   * maxSize: principal in pool cannot exceed this amount
   * “Lender restrictions” (aka deposit strategy): pool can be permissioned, can use whitelist or signature to determine who can lend
2. Configure Interest rate curve (similar to Aave/Compound/other protocols, borrowing rates are defined by a rate curve). *For a worksheet example, see this* [*spreadsheet*](https://docs.google.com/spreadsheets/d/1Y_UA10Mjsu1zYv1E4TeNrhj32sjVtc73X4DYG4UCPzw/edit?usp=sharing)*.*
   * Set Interest rate min/optimum/max
   * Set interest rate curve “kinks”
   * Note: Contributors are happy to consult with borrowers to help set these curves.

### **What are the fees on Lines of Credit?**

Lines of Credit pay a protocol fee to the DAO treasury. Fees are quoted on a per annum basis, accrue block-by-block, and are paid upon each smart contract interaction (lend/withdraw/disburse loan/repay loan).

The example below illustrates how the protocol fee works:

{% hint style="info" %}
**Protocol Fee example**

Take an example line of credit *Verum Fund,* which holds 1,000,000 USDC worth of loans and assume protocol fee = 50 bps per annum (0.50%).

Assuming the value of Verum Fund grows linearly from 1,000,000 USDC to 1,100,000 USDC over the course of 30 days (avg. value of 1,050,000 USDC), the line of credit would pay a protocol fee of 431.51 USDC for this time period:

`Protocol fee = 1,050,000 USDC * 0.50% * (30/365) = 431.51 USDC`
{% endhint %}

For up-to-date fee rates on each vault, please see vault pages at <https://app.brila.finance/>.

### Is the Line of Credit code audited?

Yes, see here:\
<https://github.com/g0-group/Audits/blob/master/TrueFiDec2022.pdf>

### Can I demo Lines of Credit?

Yes, see [Line of Credit tutorial](/brila-protocol/automated-lines-of-credit/line-of-credit-tutorial).

### Where can I find contract addresses and technical details?

See [Lines of Credit technical details](/brila-protocol/automated-lines-of-credit/lines-of-credit-technical-details).


# Line of Credit tutorial

How to create a Line of Credit

To create a Line of Credit, follow the process below:

1. **Go to** [**https://app.truefi.io/vault/aloc/create**](https://app.truefi.io/vault/aloc/create)
2. **Connect your wallet.**
   * ***For demo vaults, make sure you are connected to Optimism Sepolia network.***
   * ***If deploying on mainnet,** make sure your connected address has been allowlisted by DAO* [*governance*](https://www.tally.xyz/gov/truefi/proposals)*. Only allowlisted addresses are able to deploy a Line of Credit. Deployment transaction by non-allowlisted addresses will fail.*
3. **Configure Line of Credit.** See below for descriptions of each parameter:<br>

   * *Deployment Network:* choose between deployment on Ethereum, Arbitrum, or Optimism
   * *Underlying Asset:* select ERC-20 borrow/lend asset
   * *Deposit Controller:* n/a[^1]
   * *Lender Restrictions:* borrower sets KYC/KYB policy to one of following
     * `All lenders allowed`
     * `TrustLabs-managed KYC whitelist`: delegate KYC onboarding to [Archblock](https://www.archblock.com/)/TrustLabs)
     * `Custom whitelist`: borrower manages own whitelist
   * *Withdraw Controller:* for Line of Credit, select `Default`
   * *Transfer Restrictions:* borrower sets policy for whether lenders can transfer LP token
     * `All transfers allowed`
     * `No transfers allowed`

   <figure><img src="/files/FGKRu9AOZcpERUxm1p1R" alt=""><figcaption></figcaption></figure>
4. **Configure interest rate curve**\
   Borrower defines parameters of interest rate curve w/ up to two kinks.

   <figure><img src="/files/ob8EdQaiHLOsNxW0ahht" alt=""><figcaption></figcaption></figure>
5. **Provide token name, token symbol, and borrower description.**\
   The token name and symbol will show onchain and on Etherscan pages, etc.\
   The description will show in the app front end only.<br>

   <figure><img src="/files/ctFwZHPXeDE5Cm5UyU58" alt=""><figcaption></figcaption></figure>
6. **Deploy Line of Credit.**\
   Review and verify all configuration details. Once confirmed, click "Continue" to create onchain transaction and sign in wallet.<br>

   <figure><img src="/files/qYPWAO7l2cmg0AqRTosH" alt=""><figcaption></figcaption></figure>

[^1]: Custom strategies can be created if borrower wishes to impose min. or max. deposit size on each lender


# Lines of Credit technical details

**`AutomatedLineOfCredit`** is a contract that serves as a lending pool of funds managed by the borrower, who is the sole party who can borrow the funds. The borrower can: borrow funds, repay funds, set `AutomatedLineOfCredit` max size, add/remove deposit strategies, add/remove withdraw strategies, and change the transfer strategy. The borrower can also upgrade the AutomatedLineOfCredit implementation.

`AutomatedLineOfCredit` satisfies [ERC-4626](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/) requirements, meaning it meets all features described [here](https://eips.ethereum.org/EIPS/eip-4626).

An audit of `AutomatedLineOfCredit` and `AutomatedLineOfCreditFactory` by g0 Group can be found here: <https://github.com/g0-group/Audits/blob/master/TrueFiDec2022.pdf>

Details on Automated Line of Credit and related contracts can be found in Github below:

{% embed url="<https://github.com/TrueFi-Protocol/contracts-beryllium>" %}

## Deployed Contracts

<table data-full-width="false"><thead><tr><th width="377">Contract name</th><th width="164">Network</th><th>Address</th></tr></thead><tbody><tr><td><code>beryllium_automatedLineOfCredit</code></td><td>Arbitrum One</td><td><a href="https://arbiscan.io/address/0x8626a4234721A605Fc84Bb49d55194869Ae95D98">0x8626a4234721A605Fc84Bb49d55194869Ae95D98</a></td></tr><tr><td><code>beryllium_automatedLineOfCreditFactory</code></td><td>Arbitrum One</td><td><a href="https://arbiscan.io/address/0x24d00e171Da01124052a4B13931631Ba7482cBB5">0x24d00e171Da01124052a4B13931631Ba7482cBB5</a></td></tr><tr><td><code>beryllium_automatedLineOfCreditFactory_proxy</code></td><td>Arbitrum One</td><td><a href="https://arbiscan.io/address/0xCA1353dAB799d87D70E3750c2280205A5c8f62e9">0xCA1353dAB799d87D70E3750c2280205A5c8f62e9</a></td></tr><tr><td><code>beryllium_protocolConfig</code></td><td>Arbitrum One</td><td><a href="https://arbiscan.io/address/0xBC70FE8653D972936507F7306996d8F8E6823482">0xBC70FE8653D972936507F7306996d8F8E6823482</a></td></tr><tr><td><code>beryllium_protocolConfig_proxy</code></td><td>Arbitrum One</td><td><a href="https://arbiscan.io/address/0x5c67531524201D0a774405827BA4c2DE15781dD0">0x5c67531524201D0a774405827BA4c2DE15781dD0</a></td></tr><tr><td><code>beryllium_depositController</code></td><td>Arbitrum One</td><td><a href="https://arbiscan.io/address/0xB4C8bfd082a47c008Ce95DD13314105F6C0fe372">0xB4C8bfd082a47c008Ce95DD13314105F6C0fe372</a></td></tr><tr><td><code>beryllium_allowAllLenderVerifier</code></td><td>Arbitrum One</td><td><a href="https://arbiscan.io/address/0x607CEDb42442E206FAe3E2Cc12AFddD7e12Fdd4F">0x607CEDb42442E206FAe3E2Cc12AFddD7e12Fdd4F</a></td></tr><tr><td><code>beryllium_withdrawController</code></td><td>Arbitrum One</td><td><a href="https://arbiscan.io/address/0xEe3f9Add26de00FCC02d4BC0E6d0DBEe0e3C25E6">0xEe3f9Add26de00FCC02d4BC0E6d0DBEe0e3C25E6</a></td></tr><tr><td><code>beryllium_openTransferController</code></td><td>Arbitrum One</td><td><a href="https://arbiscan.io/address/0xa1259068Ea5252a307ced730d758c2E8D7ae177f">0xa1259068Ea5252a307ced730d758c2E8D7ae177f</a></td></tr></tbody></table>

## Notes

### AutomatedLineOfCreditFactory

`AutomatedLineOfCreditFactory` serves for deploying new AutomatedLinesOfCredit. All of the `AutomatedLineOfCredit` parameters are chosen by the borrower, except for `ProtocolConfig`.

### Interest rate calculations

When a borrower repays a given amount of borrowed funds, they owe interest. This interest is added to their balance of the outstanding debt. The amount of interest they owe is based on the utilization rate of the funds in the `AutomatedLineOfCredit` at the time they repay a given amount of debt. The interest rate that the Borrower pays on their funds is a function of the utilization of the `AutomatedLineOfCredit`. This function is parameterized by six values which are determined by the borrower when the `AutomatedLineOfCredit` is created:

* A (1) minimum interest rate utilization threshold up to which point the interest rate is equal to the (2) minimum interest rate,
* An (3) optimum utilization rate and (4) optimum interest rate. The interest rate is determined by linearly interpolating between the minimum interest rate and the optimum interest rate when the utilization rate is between the minimum interest rate utilization threshold and the optimum utilization rate,
* A (5) maximum interest rate utilization threshold beyond which the interest rate is equal to the (6) maximum interest rate. The interest rate is determined by linearly interpolating between the optimum interest rate and the maximum interest rate when the utilization rate is between the optimum utilization rate and the maximum interest rate utilization threshold.

The `utilization` of an AutomatedLineOfCredit is equal to:

`(borrowed_funds + unpaid_interest) / value`

The `value` of an AutomatedLineOfCredit is equal to:

`liquid_funds_in_ALOC + borrowed_funds + unpaid_interest - unclaimed_fees`

When the *Borrower* borrows from the `AutomatedLineOfCredit`, `utilization` increases. When a Lender deposits into the `AutomatedLineOfCredit`, `utilization` decreases. When a Lender withdraws from the `AutomatedLineOfCredit`, `utilization` increases.

### Fees

Whenever an action that changes `AutomatedLineOfCredit` value is performed (`borrow`/`repay`/`deposit`/`mint`/`withdraw`/`redeem`/`updateAndPayFee`), a fee for the DAO is calculated and immediately transferred to the DAO Treasury address. The fee is deducted from the `AutomatedLineOfCredit` value, so actions like `borrow`/`withdraw`/`redeem` cannot move the funds that are designated as fees. If the accrued fee cannot be repaid at the moment because of the lack of liquidity, additional information about the fee amount is stored in the contract and will be used to make the overdue payment the moment it will be possible.

The `accruedFee` value is equal to:

`(current_timestamp - last_update_timestamp) / YEAR * protocol_fee_rate * portfolio_value`

\*\*`portfolio_value` does not take into account the interest that has been accrued since the last update.

`protocol_fee_rate` is the rate taken from the `ProtocolConfig` contract the last time an update was made. This means that if the DAO decides to increase the fees, the higher rate will be applied for `accruedFee` calculation since the next update, not the current one.

### Deposit / Withdrawal Strategies

Functions enabling Lenders to deposit/withdraw funds to/from the contract can additionally be limited by Deposit/Withdraw Strategy. These strategies (if set), are called with a hook every time a specific action is performed on the contract. The same calldata as for the initial call is passed to them and then the strategy independently decides if this action can or cannot be performed. The strategies might also write some state to themselves on such hooks, but this is not a mandatory behavior.


# Asset Vaults

## What are Asset Vaults?

***Asset Vaults*** facilitate off-chain credit, or "Real World Asset" (RWA), activity.

### Why are Asset Vaults useful?

Asset Vaults represent off-chain instruments by using onchain attestations, or Asset *Reports.*

By using this structure, Asset Vaults can facilitate diverse and complex RWA activities, such as:

* *Deploy capital to off-chain uses:* portfolio managers (PMs) can use Asset Vaults to create representations of off-chain debt instruments, ETFs, etc.
* *Support 100+ loans/instruments in a single vault:* Asset Vaults enable PMs to represent many loans or off-chain instruments with low gas costs.
* *Floating rate loans:* PMs can create loans that reference off-chain benchmark rates (e.g. SOFR + 200).
* *Amortizing loans:* PMs can create loans that support complex repayment schedules, following existing structures found in the traditional finance world.

### How do Asset Vaults work?

Asset Vaults function similarly to [Credit Vaults](/brila-protocol/credit-vaults), with the exception that portfolio managers disburse funds using onchain asset reports, rather than disbursing funds to onchain loans.

Asset Vaults are made up of modular components, enabling PMs to configure vaults to their unique needs.

### Are Asset Vaults audited?

Yes, see here:\
<https://github.com/TrueFi-Protocol/contracts-fluorine/blob/main/audits/ChainSecurity_TrueFi_Fluorine_audit.pdf>

### Can I demo Asset Vaults?

Yes, see [Asset Vault tutorial](/brila-protocol/asset-vaults/asset-vault-tutorial).


# Asset Vault tutorial

### Tutorial / demo

Users can test Asset Vaults by creating their own demo vault on Optimism Sepolia using this [link](https://app.truefi.io/vault/asset/create).

{% hint style="warning" %}
Before beginning, you will need to switch to the Optimism Sepolia test network and ensure your wallet is funded with test ETH and test USDC assets.

To complete these steps, follow this [step-by-step guide](https://scribehow.com/shared/Deploying_TrueFi_vaults_on_testnet_Optimism_Goerli_Copy__4esrcIFrSeiqSuLbx_P7IQ?back_to=browser).
{% endhint %}

Follow the guide below to get started:

{% embed url="<https://scribehow.com/shared/How_to_Create_an_Asset_Vault_on_TrueFi__mBY8ynqKTMKV4JJQXThqow>" %}


# Asset Vault technical details

Asset Vaults share core concepts with Credit Vaults. For detail on how these contracts work, read more in [Credit Vault technical details](/brila-protocol/credit-vaults/credit-vault-technical-details).

For Asset Vaults, also see documentation here:

{% embed url="<https://github.com/TrueFi-Protocol/contracts-fluorine>" %}


# Credit Vaults

## **What are Credit Vaults?**

**Credit Vaults** are smart contracts that coordinate the lending, borrowing, and management of onchain credit.

Credit Vaults enable onchain credit, helping portfolio managers (PMs) configure modular lending pools that meet their specs (single or multiple tranches, permissioned access, etc).

For a brief demo video showing their capabilities, see below:

{% embed url="<https://www.loom.com/share/9fce841543fa426c94cbd10078e7c000>" %}
Demo: Strucuted Credit Vaults
{% endembed %}

Credit Vaults can be made up of a single tranche or multiple tranches, creating the opportunity for lenders to participate in distinct “slices” of a given vault, each with their own risk/return profile. To learn more, see [#05d9](#05d9 "mention") below.

Credit vaults also introduce the concept of a *capital formation period,* in which lenders can commit capital to a smart contract with assurances that if the vault does not meet certain requirements within a given time period, funds will be returned to lenders with no fees incurred. To learn more, see[#what-is-the-capital-formation-period](#what-is-the-capital-formation-period "mention")below.

### How do Credit Vaults work?

For technical docs, see [Credit Vault contract overview](/brila-protocol/credit-vaults/credit-vault-technical-details/credit-vault-contract-overview).

### **What types of activity do Credit Vaults support?**

Credit Vaults support both onchain and off-chain "Real World Asset" ("RWA") credit activity.

PMs can use Credit Vaults to make simple fixed-yield loans to borrowers.

For PMs who want to manage more complex off-chain/RWA activities, please see [Asset Vaults](/brila-protocol/asset-vaults). Asset Vaults are specialized smart contracts that offer more flexibility to support complex off-chain use cases.

### What are tranches? <a href="#id-05d9" id="id-05d9"></a>

A [tranche](https://www.investopedia.com/ask/answers/what-tranche/) (from French, a “*slice*” or “*portion*”) refers to a financial product that can be split into distinct pieces that can be offered to buyers or lenders, each with their own risk-reward profile.

Credit vaults can be created with up to three tranches, meaning they can also support two-tranche or single tranche deals.

### How do interest & repayments flow to lenders?

Let's take a vault with 3 tranches: A/B/C, with A being most senior.

In this example, `Tranche A` has a fixed interest rate of 6%, `Tranche B` has a fixed interest rate of 10%, and `Tranche C` receives any excess funds in the vault after `Tranches A and B` have been paid amounts owed. `Tranche A` has $6mm in principal, subordinated by `Tranche B` ($2.5mm principal), and `Tranche C` ($1.5mm principal).

Over the life of the vault, each tranche linearly accrues interest owed based off its coupon rate. For instance, after 30 days `tranche A` with 6% interest rate is owed $6.03mm `=$6mm*[1+(6%*(30/365))]` and after 365 days it is owed $6.36mm `=$6mm*(1+6%)`.

When funds are repaid to the vault, they are distributed by a waterfall where the most senior tranche's amount owed must be repaid before the subordinated tranche can withdraw. The following illustration shows how such a vault would handle various scenarios:

<figure><img src="/files/1TRUBY2rwcdpbjxVMT2I" alt=""><figcaption><p>Illustrative scenarios for Credit Vaults</p></figcaption></figure>

### What is the capital formation period?

During the capital formation period, lenders can commit funds to one or more tranches of the vault, with assurance that the vault smart contract will return funds if certain requirements are not satisfied. If requirements are not satisfied by the end of the period, then capital is returned to lenders with no additional fees.

In this way, lenders can stipulate that deals must reach a specific minimum size and/or with specific ratios in order to go live.

For example, a credit vault may launch with a capital formation period of 30 days, with requirements that the total deal size is at least $5mm with at least 30% of funds in the junior tranche. If the vault does not meet this criteria at day 30, the vault will return funds to lenders and move to 'Closed' status.

### How are lender restrictions / permissions managed?

Portfolio managers ("PMs") can define lenders access rules / restrictions for each individual tranche. Like other pools on Brila, PMs can set their own policies for [permissioned or permissionless pools](/user-guide/manage/managing-kyc-kyb-requirements).

For example, a PM could make the equity tranche open to only one specific wallet address, while enabling all ID verified addresses to participate in the junior and senior tranches.

Lender restrictions (as well as redemption policies, fee structures, and more) can be configured to a PM's spec by using [Controllers](/brila-protocol/other-concepts/controllers), customizable logic that helps Brila vaults meet the varied needs of financial users.

### **What are the fees on Credit Vaults?**

Vaults pay a protocol fee to the DAO treasury. Fees accrue are quoted on a per annum basis, accrue block-by-block, and are paid upon each smart contract interaction (lend/withdraw/disburse loan/repay loan).

The example below illustrates how the protocol fee works:

{% hint style="info" %}
**Protocol Fee example**

Take an example vault *Verum Fund,* which holds 1,000,000 USDC worth of loans and assume protocol fee = 50 bps per annum (0.50%).

Assuming the value of Verum Fund grows linearly from 1,000,000 USDC to 1,100,000 USDC over the course of 30 days (avg. value of 1,050,000 USDC), the vault would pay a protocol fee of 431.51 USDC for this time period:

`Protocol fee = 1,050,000 USDC * 0.50% * (30/365) = 431.51 USDC`
{% endhint %}

Additionally, PMs can set an optional Portfolio Fee. Portfolio Fees are paid to the PM, and can be configured such that they are accrued linearly over time, or paid as a flat fee at time of deposit and/or withdrawal.

For up-to-date fee rates on each vault, please see vault pages at <https://app.truefi.io/>.

### Are Credit Vaults audited?

Yes, see here:\
<https://github.com/TrueFi-Protocol/contracts-carbon/tree/main/audits>

### Can I demo Credit Vaults?

Yes, see [Credit Vault tutorial](/brila-protocol/credit-vaults/credit-vault-tutorial).


# Credit Vault tutorial

Users can test Credit Vaults by creating their own demo vault on Optimism Sepolia using [this link](https://legacy.truefi.io/structured-credit-portfolio/create).

{% hint style="warning" %}
Before beginning, you will need to switch to the Optimism Sepolia test network and ensure your wallet is funded with test ETH and test USDC assets.

To complete these steps, follow this [step-by-step guide](https://scribehow.com/shared/Deploying_TrueFi_vaults_on_testnet_Optimism_Goerli_Copy__4esrcIFrSeiqSuLbx_P7IQ?back_to=browser).
{% endhint %}

Follow the Scribe tutorial below or view written instructions [here](#instructions).

## Step-by-step walkthrough (using Scribe app)

{% embed url="<https://scribehow.com/shared/Deploying_TrueFi_vaults_on_testnet_Optimism_Goerli__tgLDPMYBR3KfWvC8rLUQJQ>" %}

## Instructions:

1. First, switch network to Optimism Goerli (testnet)
   * To add network to wallet, navigate to <https://chainid.link/?network=optimism-goerli> and click 'Connect'
2. Next, fund your wallet with testnet ETH and testnet USDC
   * Get 0.01 test ETH by using <https://isomorph.loans/faucet> or other faucet
   * Mint "mock" USDC `0x5f1c3c9d42f531975edb397fd4a34754cc8d3b71` via [Etherscan](https://goerli-optimism.etherscan.io/address/0x5f1c3c9d42f531975edb397fd4a34754cc8d3b71#code) to use for lending/borrowing in test vaults
     * Connect wallet and mint desired amount (6 decimals)

       <div align="left"><figure><img src="/files/7iWpM8t0ebnXSTseugzO" alt=""><figcaption></figcaption></figure></div>
3. Finally, navigate to <https://app.truefi.io/structured-credit-portfolio/create> or click 'Create new portfolio' -> select 'Credit Vault' in Brila app and follow the flows:
   * For a demo and more details, see [Creating a vault](/user-guide/manage/creating-a-vault)
   * For technical documentation, see [Credit Vaults](/brila-protocol/credit-vaults)


# Credit Vault technical details

See GitHub for full documentation:

{% embed url="<https://github.com/TrueFi-Protocol/contracts-carbon>" %}

Additionally, see below for overview:

## ✅ Intro

Credit Vaults are multi-vault portfolios allowing different types of investors to deposit into one bucket of funds managed by the portfolio manager, while having different risk-return profiles. There are three tranches:

* A / "Senior" (fixed rate)
* B / "Junior" (fixed rate)
* C / "Equity" (variable rate)

## ✅ Portfolio Life Cycle

Vault (or "Portfolio") can be in one of three states - Capital Formation, Live and Closed.

Portfolio starts its life cycle in the Capital Formation state. From Capital Formation state, Portfolio can be transitioned into Live state or Closed state.

<figure><img src="/files/EKteYLJVDH03XQZ4q94s" alt=""><figcaption></figcaption></figure>

#### ✅ Standard Portfolio Flow

Portfolio can be launched at any time, from Capital Formation - into Live state. While in Live state, the portfolio can only be transitioned into Closed state. Closed state is the final state of the portfolio.

<figure><img src="/files/ubDNZEmOqWme2LOgS1PZ" alt=""><figcaption></figcaption></figure>

**Portfolio Manager can decide to Close the Portfolio before it hits end of Capital Formation.**

<figure><img src="/files/dXdQKk68lx10FSqoY9iO" alt=""><figcaption></figcaption></figure>

#### ✅ Limiting Capital Formation phase

Length of the Capital Formation phase prevents the portfolio from staying in the Capital Formation state forever. If the deadline timestamp is met, the portfolio can be transitioned from Capital Formation state to Closed using a public function. It is a safety mechanism ensuring that funds will not remain stuck in the portfolio i.e. in case of PM losing his private key and not being able to manage the portfolio anymore.

<figure><img src="/files/GryI6VFq8dY6u5z00etm" alt=""><figcaption></figcaption></figure>

#### ✅ Emergency close of Portfolio in Live state

Public transition from Live to Closed should be possible as well. If all loans get repaid or default and the portfolio is past the end date, any address can close the portfolio.

#### ✅ Early closing

Manager can close portfolio anytime, when portfolio is Live. From this time on, essentially anyone can start withdrawing, manager stops earning fees and cannot disburse any more loans. **Additionally the total portfolio value has to consist of 100% cash if it is being closed before maturity date.**

## ✅ Architecture

Portfolio consists of four main smart contracts - Master Portfolio and three ERC4626 Vaults. Master Portfolio is a central contract responsible for most of the calculations. It also serves as a main capital pool and a terminal for portfolio managers to manage capital deployments. ERC4626 Vaults serve as ports for investors to deposit into or withdraw from a particular tranche. They store the capital when the portfolio is NOT in the Live state (so in the Capital Formation state and in the Closed state). In the Live state they only handle interactions between the investors and the portfolio. Additionally each Vault issues a token which represents shares of a particular investor in a particular tranche. These main four smart contracts are most likely going to be supported by a set of auxiliary smart contracts like Portfolio Factory or Protocol Config.

<figure><img src="/files/lc5HjKuxTld2UkcN9tCr" alt=""><figcaption></figcaption></figure>

## ✅ Roles / Actors

There are three main actors in the system:

* Portfolio Manager (PM) - an actor responsible for portfolio configuration and capital deployments. They run an asset management business and earn fees as returns. It’s highly probable that they will also be lenders in the equity tranche.
* Borrower - an actor that is a target of Portfolio Managers’ capital deployment operations. Receives capital on loan disbursement and is obligated to return it in the schedule defined in the used debt instrument.
* Lender - an actor that invests their funds into a portfolio seeking returns. Lenders might have different risk appetite and different return requirements. For the purpose of this document they are divided into three main categories:
  * Senior Lender - is a lender whose priority is safety and high returns are a secondary goal.
  * Junior Lender - is a lender who wants to balance exposure to various risks and opportunity to earn an attractive yield.
  * Equity Lender - is a lender who is comfortable with exposure to highly volatile assets that may present different performance in different market conditions. Their capital will serve as first loss capital in case of default or portfolio underperformance.
* DAO - an entity that oversees all portfolio operations, provides infrastructure and earns fees.

## ✅ Lending

#### ✅ Deposit

Depositing is allowed when a portfolio is in the Capital Formation state or in the Live state.

#### ✅ Capital Formation State Deposits

As the deposits in the Capital Formation state happen only before any capital deployments are made, or any other types of risks applied, for each deposit lender receives a number of LP tokens exactly equal to the number of tokens deposited. Portfolio token has the same number of decimals as the portfolio asset token (important note: there is always only one underlying asset token for each portfolio). For 1 wei of the underlying token deposited, a lender will receive 1 wei of the LP token. By default there are no restrictions on the sizes of the deposits. The only requirement that needs to be met is not depositing more into a particular tranche than is defined in the tranche ceiling parameter.

#### ✅ Capital Formation State Withdrawals

Withdrawals in the Capital Formation state are allowed. LP tokens are burned 1:1 to assets (at least in the vanilla, default strategy)

The default controller should require the withdrawal flag to be on, and funds to not drop below tranche floor level (controller setting).

#### ✅ Live State Deposits

When deposits happen in the Live state, the value of a LP token is dynamic. It changes because of the interest accrual mechanisms, portfolio value fluctuations etc. In order to make a deposit in the Live state the total value of the portfolio and the value of a particular LP token needs to be calculated in the depositing transaction. Because initially the value of one underlying asset wei was set to one LP token wei, very small deposits (deposits worth way below $0.01) may be mispriced. Additionally when making deposits in the Live state, both tranche ceilings and tranche ratios have to be respected.

#### ✅ Live State Withdrawals

When withdrawals happen in the Live state, the total value of the portfolio is dynamic. The total value of the portfolio, and then the value of a particular LP token tranche needs to be calculated in the withdrawing transaction. When withdrawals are made in the Live state, tranche ratios and tranche floors have to be respected.

#### ✅ Closed State Withdrawals

When withdrawals happen in the Closed state, the total value of the portfolio is not subject to any changes anymore, LP tokens have a stable value. This value is calculated when the PM closes the portfolio and might change in case of recovery of any defaulted assets. When withdrawals are made in the closed state, neither tranche ratios, nor tranche floors need to be respected.

## ✅ Portfolio Management

#### ✅ Factory Whitelisting

A PM creates a portfolio by calling a proper method on the Portfolio Factory. In order to create a portfolio a potential PM needs to be on the factory whitelist. In order to be whitelisted a PM needs to go through a process defined by the DAO. DAO is a final decision maker and executor when it comes to the whitelisting logistics.

#### ✅ Alternative Deployments

If the PM wishes to use only 1, or 2 out of 3 available tranches - it is possible. There has to be a way to deploy only the necessary number of contracts. If PM launches a portfolio with only 2 (or 1) tranches, only 2 (or 1) of them should be deployed. This can be solved with a proper parametrisation of factory, different function for portfolio creation in factory or having multiple factories using the same factory whitelist. If portfolio is once deployed as a 1 or 2 tranche portfolio, more tranches cannot be added later on. If PM ultimately wants to run 3 tranches, but wants to start with 1, they still need to deploy all 3 of them, and using controllers block access to the ones that are not needed.

### ✅ Withdraw Lever and Deposit Lever

Each tranche has two flags a.k.a levers \*\*\*\*(they should be inside proper default Controllers) and determine whether deposits or withdrawals are allowed. By default, portfolio is created with the Deposit Lever set to `allowed` and Withdraw Lever set to `disallowed`. Then manager can set the levers as they please. When portfolio exits Capital Formation state and enters Live state, both levers are automatically set to `disallowed`. When portfolio enters Closed state, Deposit Lever is automatically set to `disallowed` and Withdraw Lever is automatically set to `allowed` and manager can no longer change them.

### ✅ Waterfall

At any point of time when the current value of any subsequent tranche needs to be calculated a waterfall calculation needs to be performed. Waterfall calculation first evaluates the total value of the portfolio. Sums up the value of the cash sitting in the portfolio and then assigns chunks of that value to particular tranches in the seniority order.

Structured Credit Vaults support only one type of Waterfall: learn more [here](/brila-protocol/credit-vaults/credit-vault-technical-details/waterfall-details).

### ✅ Portfolio Creation

Once whitelisted, a PM can create a portfolio. In order to create a portfolio they need to pass the following parameters. Some of them are editable (**E**) during the portfolio lifecycle or fixed (**F**) and cannot be changed after the portfolio creation.

* A / Senior tranche parameters
  * Senior tranche name (**F**)
  * Senior tranche symbol (**F**)
  * Senior tranche manager fee (**F**)
  * Target senior interest rate (**F**)
  * First Loss Capital buffer for Senior (**F**)
* B / Junior/Mezzanine tranche parameters
  * Mezzanine tranche name (**F**)
  * Mezzanine tranche symbol (**F**)
  * Mezzanine tranche manager fee (**F**)
  * Target senior interest rate (**F**)
  * First Loss Capital buffer for Mezzanine (**F**)
* C / Equity tranche parameters
  * Equity tranche name (**F**)
  * Equity tranche symbol (**F**)
  * Equity tranche manager fee (**F**)
  * Minimum expected Equity interest rate (**E**)
  * Maximum expected Equity interest rate (**E**)
* Administrative parameters
  * Portfolio name (**F**)
  * Portfolio duration (**E**)
  * Capital formation duration (**E**)
  * Minimum portfolio size (**F**)

There might be a need to pass additional parameters that were not mentioned here.

#### ✅ Capital Formation

Once a portfolio is created it enters the Capital Formation state. In the Capital Formation state deposits of new capital by investors are available, but withdrawals (by default - they can be allowed) and loan disbursements are blocked. Particular deposits do not need to be larger than tranche floor, but they cannot overflow above tranche ceiling. PM is free to change tranche sizes during that period.

#### ✅ Portfolio Start

In order to start the portfolio, or in other words change its state from Capital Formation to Live, the only action that needs to be taken is calling a proper method. This method would only be callable by the PM and would require sum of all tranche sizes to be above defined total minimum portfolio size. Additionally all the tranches need to fulfil the tranche ratio requirements (so the Junior tranche cannot be too large compared to Equity tranche and Senior tranche cannot be too large compared to Junior tranche and Equity tranche combined). Calling this method will enable loan disbursements, start fixed interest accruing.

#### ✅ Capital Deployment

Mechanism of loan disbursement will not be discussed in this doc. Tranched portfolio should use the current Brila state of the art loan mechanism. Most certainly it's going to be based on Fixed Interest Only Loans, which can be configured either in a way that they will force the borrower to repay interest periodically and then principal at the loan end date, or as bullet loans. All issued debt instruments need to have their end date before the end date of the portfolio. Though this is only an UI-enforced requirement. We need to remove this requirement from smart contracts.

#### ✅ Portfolio Closing

In order to close a portfolio before the maturity date, the portfolio cannot have any outstanding assets. Portfolio can always be closed, if it’s after the maturity date. When closing the portfolio a waterfall needs to be calculated and the value of each of the particular tranches set. After the portfolio is closed, deposits are blocked and capital deployments are blocked, but withdrawals are allowed. Withdrawals are made at the LP token price preset in the waterfall calculation. Tranches’ floors are not blocking withdrawals. Default controller flags indicating whether deposits and withdrawals are allowed are set, so deposits are not allowed anymore and withdrawals are allowed - this is being set automatically and cannot be changed by the manager anymore.

#### ✅ Defaulted Assets Recovery

It is possible that some repayments from overdue instruments are gonna be made after the portfolio is officially closed. If this happens, Waterfall needs to be recalculated as the overall value of the portfolio changes.

## ✅ Controllers

For more on the concept of controllers, read more [here](/brila-protocol/other-concepts/controllers).

#### ✅ Deposit Controller

In order to allow utilisation of different lender restriction strategies, without breaking the ERC4626 interface used for tranche vaults, a special mechanism needs to be put in place. Whenever a user would be about to create portfolio LP tokens, a special auxiliary smart contract is asked about the results of a particular deposit or mint. This contract should take all the parameters provided in the `deposit()` or `mint()` call, plus the message sender of the call and return a pair of values - amount of LP tokens that will be minted on deposit, or amount of asset tokens that need to be sent in order to mint desired amount of LP tokens, plus the amount of asset tokens that need to be sent as a fee to the management fee beneficiary address. In the simplest case, this contract might be just a whitelist that only checks its internal state and facilitates standard, proportional deposits or mints, but this interface allows implementation of more sophisticated strategies. If there are any other pieces of data that need to be passed, they would need to be passed directly to the controller contract, before interacting with the vault. So for example the whitelist doesn’t necessarily need to be managed manually by the PM, but might automatically add anyone that provides a signature of some particular piece of data. Each vault has to have its own Deposit Controller.

<figure><img src="/files/wx2c1JAiao7XI0B99Apw" alt=""><figcaption></figcaption></figure>

✅ **Controlled Functions**

**`deposit(assets, receiver)`**

`onDeposit(msg.sender, assets, receiver)`

Returns:

* `shares` - how many shares are gonna be minted to the `receiver`
* `depositFee` - how much is going to be subtracted from `assets` and sent to the manager beneficiary address

**`mint(shares, receiver)`**

`onMint(msg.sender, shares, receiver)`

Returns:

* `assets` - how many assets are going to be sent from `receiver` to the portfolio
* `mintFee` - how many assets are going to be sent from `receiver` to the manager fee beneficiary

Additionally Deposit Controller needs to handle all the necessary view functions. Their interfaces are identical to the original ERC-4626 interfaces.

* `previewDeposit(assets)` - returns how many LP will the depositor get for the assets
* `maxDeposit(receiver)` - returns max amount of assets that can be put into deposit (before fee subtraction)
* `previewMint(shares)` - returns how many assets does user need to send to mint particular number of shares (actually deposited + fee)
* `maxMint(receiver)` - returns max amount of shares that can be minted

#### ✅ Withdrawal Controller

Analogically to the deposits and mints there is a controller, responsible for handling withdrawals and redeems. Withdrawal controller, on each withdrawal or redeem attempt, will receive all call arguments, plus the message sender and determine the amount of assets that is being taken out of the vault, or amount of LP tokens burned, plus fee for the manager.

✅ **Controlled Functions**

**`withdraw(assets, receiver, owner)`**

`onWithdraw(msg.sender, assets, receiver, owner)`

Returns:

* `shares` - how many shares are gonna be burned from the `owner`
* `withdrawFee` - how much is going to withdrawn from the vault on top of the `assets` and sent to the manager beneficiary address

`**redeem(shares, receiver, owner)**`

`onRedeem(msg.sender, shares, receiver, owner)`

Returns:

* `assets` - how many assets are going to be sent from the vault to the `receiver`
* `mintFee` - how many assets are going to be taken from the vault on top of the `assets` and sent to the manager fee beneficiary

Additionally Withdrawal Controller needs to handle all the necessary view functions. Their interfaces are identical to the original ERC-4626 interfaces.

* `previewWithdraw(assets)` - returns how many LP will one need to burn in order to get desired amount of assets
* `maxWithdraw(owner)` - returns max amount of assets that can be withdrawn (after paying fee)
* `previewRedeem(shares)` - returns how many assets will user get (after paying fee) for a particular redeem
* `maxRedeem(receiver)` - returns max amount of shares that can be burned to redeem

#### ✅ Transfer Controller

Transfer controller determines whether particular ERC-20 vault LP token can be transferred. Transfer controller does not reimplement the whole logic of the transfer, but in this case simply returns a boolean determining, whether a particular transfer is allowed or not. In order to return this value transfer controller would receive all parameters of the transfer - sender, recipient, amount and the message sender.

✅ **Controlled Functions**

**`transfer(to, value)`**

**`transferFrom(from, to, value)`**

`onTransfer(msg.sender, from, to, value)`

Returns:

* `isTransferAllowed` - boolean determining whether a particular transfer is allowed or not

## ✅ Fees

Fees can be configured separately for each tranche of the vault. Below are all of the fee types that can be applied to vaults:

1. Block-By-Block continuous fees
   * Protocol fee *(required, set by protocol)*
   * Management fee *(optional, set by PM)*
2. Additional optional fees
   * LP Deposit fees *(optional, set by PM)*
   * LP Redemption fees *(optional, set by PM)*
   * Instrument origination and/or repayment fees *(optional, set by PM)*

### Protocol fees & Management fees *(Block-By-Block continuous)*

**Protocol fees** accrue block-by-block during the Live state and in the Closed state of a vault. **Management fees** also accrue block-by-block, but only during the Live state of a vault.

Protocol fees and Management fees are paid on each interaction with the vault, including lender deposits, lender redemptions, disbursements made by the PM, repayments from borrowers, or updates to the vault value ("NAV updates").

Whenever an interaction happens, the following sequence is executed by the vault smart contract:

1. Check following parameters:
   * Current TVL (before the action is executed)
   * Time elapsed since previous interaction
   * Fee rate (basis points per annum)
2. Calculate fee accrued for the period between the current and previous interaction
3. If there are sufficient funds available in the vault, send fees (incl. any previously unpaid fees) directly to fee beneficiary addresses
   * Protocol fee is sent to Brila protocol treasury
   * Management fee is sent to an address set by the PM
   * If there are not sufficient funds available, save the value of fees that couldn’t be paid as unpaid fees

### Additional fees *(optional, configurable by PM)*

**LP deposit fees and redemption fees** are handled entirely by [Deposit Controller](/brila-protocol/other-concepts/controllers#deposit-controller) and [Withdrawal Controller](/brila-protocol/other-concepts/controllers#withdrawal-controller) contracts, respectively. Vaults can charge custom management fees upon deposit or redemptions if respective [controllers](/brila-protocol/other-concepts/controllers) implement proper logic and return non-zero fee values.

Additionally, instrument origination fees and/or instrument repayment fees can be implemented within the mechanism of an [instrument](/brila-protocol/other-concepts/instruments) itself. The vault smart contract itself does not implement any mechanism that facilitates charging such fees.

## ✅ Interest Accrual

Value of each subsequent tranche can be fetched by calling a proper method on a proper ERC4626 Vault. It works differently for different tranches.

#### ✅ Senior & Junior Tranches

Value of Senior and Junior tranches is flat and remains unchanged when a portfolio is in an Capital Formation or Closed state. When it is in Live state, Senior and Junior tranches’ values increase linearly at the pace defined by the target interest rate parameters. This value should be capped by the value of the tranche assigned to it by the Optimistic Waterfall. So the target interest rate might not be met if the Optimistic Waterfall calculations turn out to assign a smaller value to the tranche.

<figure><img src="/files/JrYVe4Uuop1YxIv2ANdq" alt=""><figcaption></figcaption></figure>

#### ✅ Compounding effect

Whenever the value of the LP token is repriced in the Live state (i.e. because of deposit or withdrawal), already accrued interest is accounted towards the total value of the portfolio and now is also accruing interest. So the interest is compounding with each “tick” of the portfolio. For portfolios that do not last very long or do not have very high interest rates, the compounding effect is insignificant. You can check this [Compounding vs Simple](https://docs.google.com/spreadsheets/d/13YQ6hJFmObdPESLXP9FVPERbdPCOoXrtN3KnXB_evLw/edit#gid=0) doc to see example calculations comparing simple interest versus compounding interest.

#### ✅ Equity Tranche

Equity tranche, similarly to Junior and Senior tranches remains flat in the Capital Formation and Closed states. While a portfolio is in the Live state the value of the Equity tranche might be highly volatile. It is calculated as the remaining value of the total portfolio value after subtracting values of all of the other tranches. It might be the case that for some period of time Equity tranche is going to be losing value (i.e. while the portfolio is underutilized)

<figure><img src="/files/7pDNVhnLXWENS7bb7hT8" alt=""><figcaption></figcaption></figure>

## ✅ Clarifications

In order to make the portfolio more attractive for Senior lenders it is possible to first onboard equity capital (or Equity and Junior capital), deploy it and then, once the PM has proven that they will perform sensible capital deployments, onboard Senior capital. PM can set the ceiling of the Senior tranche to 0 at the beginning and only start gathering Junior and Equity capital. Once enough funds are collected they can switch the Portfolio state to Live, and disburse the first batch of loans. Once Senior lenders can clearly see what PM is investing in, PM opens Senior deposits, by increasing senior tranche ceiling. Now, each newly collected Senior deposit would be deployed into the same instruments PM already used. If implemented, PM can also use the “Warehousing Line” product to seed the Portfolio.


# Credit Vault contract overview

[***Credit Vaults***](/brila-protocol/credit-vaults) are multi-tranche vaults allowing lenders to deposit into one or more specific buckets of funds ("tranches") managed by the portfolio manager. Credit Vaults can have up to 3 tranches, enabling each tranche to deliver unique risk-return profiles.

Below is an overview of Credit Vault contracts.

## Contracts

### StructuredPortfolio

`StructuredPortfolio` is a contract responsible for loan management and Tranche value calculations. It might hold any number of tranches (limited by gas) but at launch, credit vaults are intended to contain 1, 2, or 3 tranches.

`StructuredPortfolio` extends [`LoansManager`](#loansmanager) contract.

`StructuredPortfolio` has 3 states: `CapitalFormation`, `Live` and `Closed`.

The credit vault goes into `Live` state when the `start()` method is called. It transfers all funds from tranches to the credit vault and enables the ability to create and fund loans. Each tranche value is now calculated using the [debt waterfall](#waterfall) algorithm.

Creating and funding loans is only possible in `Live` state.

When the vault's end date passes, anyone can close the vault. Manager can close a vault prematurely if there are no ongoing loans. This will transfer funds back to tranches according to the waterfall algorithm.

### StructuredPortfolioFactory

`StructuredPortfolioFactory` is a factory contract that creates `StructuredPortfolio` contracts along with its `TrancheVault` contracts and controllers.

### TrancheVault

`TrancheVault` is the contract that allows users to deposit/withdraw funds and to manage the vault. `TrancheVault` creates checkpoints on every action that changes total tranche value. This allows the vault to calculate linear growth since the last change in waterfall calculations.

`TrancheVault` handles paying fees to the manager and to the protocol. Fees are calculated continuously but are transferred on every checkpoint update.

`TrancheVault` also manages `DepositController`, `WithdrawController` and `TransferController`. `TrancheVault` supports ERC20, ERC165 and ERC4626 interfaces.

### ProtocolConfig

The `ProtocolConfig` contract holds parameters necessary for fee accruals.

These parameters are:

* `defaultProtocolFeeRate`: the protocol fee (in basis points) that will be charged on each vault
* `protocolAdmin`: the address of the protocol owner
* `protocolTreasury`: the address where all fees are transferred
* `pauserAddress`: address of developer multisig for emergency pausing the protocol
* `customFeeRates`: custom fee model that can be defined by the manager

All of these parameters are settable by the protocol admin.

### LoansManager

`LoansManager` is an abstract contract that is an adapter to [`FixedInterestOnlyLoans`](/brila-protocol/other-concepts/instruments/fixedinterestonlyloan) that allows to add/fund/cancel/repay them.

## Controllers

[Controllers](/brila-protocol/other-concepts/controllers) regulate different aspects of how Brila products work.

### DepositController

`DepositController` checks whether a lender is allowed to deposit and checks maximum deposit amounts for each lender. Managers can choose to enable or disable deposits.

### WithdrawController

`WithdrawController` manages whether a lender can withdraw and checks maximum withdrawal amounts for each lender. Managers can choose to enable or disable withdrawals prior to the vault's maturity date. This controller is similar to `DepositController` but for withdrawals.

### TransferController

`TransferController` has a single method `onTransfer` that is called when a tranche's ERC20 transfer is made.

The basic implementation of this controller always returns true (all transfers enabled). This could be swapped for a different controller to add custom functionality (e.g. only transfers between specific addresses allowed, no transfers allowed, etc).

## Debt Waterfall

In credit vaults, the senior tranches are entitled to receive principal plus accrued interest (fixed rate *target interest*) in higher priority over the more junior tranches.

Thus in a three-tranche credit vault, the waterfall of repayments works as follows:

First, Tranche A receives principal plus target interest, then Tranche B receives principal plus target interest, and then Tranche C receives the remainder of the funds in the vault.

In summary, juniormost tranches absorb performance-based volatility within the vault, while more senior tranches feel losses only if losses exceed the size of subordinated junior tranches.

It is important to note that in `CapitalFormation` and `Closed` states, the vault consists only of idle funds. In `CapitalFormation` and `Closed` states, there are no assumptions about the future performance of deployed capital and thus the vault is only calculating how to split idle funds between different lenders.


# Waterfall details

First, the senior tranche would get its principal plus target interest, then junior would get its principal plus target interest and then equity would get the rest. So basically the equity tranche will absorb most of the performance-based volatility, while the junior tranche will be absorbing default losses if the total losses are going to be larger than the equity tranche.

Important to notice is that in the Open and the Closed states, the portfolio consists only of cash, which means that there are no assumptions about future performance of currently deployed capital, but it’s only a way of calculating how to split the cash between different lenders.

See a few examples below:

<figure><img src="/files/e6TkayLVxX1B0l2dvKNm" alt=""><figcaption><p>Examples of waterfall in well performing portfolios.</p></figcaption></figure>

<figure><img src="/files/1YyWVMaDLSmxkag2xXfa" alt=""><figcaption><p>Examples of waterfall in poorly performing portfolios.</p></figcaption></figure>

<figure><img src="/files/u5GYQzFZu5vJtSPQLXmh" alt=""><figcaption><p>Examples of waterfall in default scenarios.</p></figcaption></figure>


# Index Vaults

Brila's "Fund of Funds"

{% hint style="info" %}
**Index Vaults are currently in** **beta.**

Smart contracts are available for builders to use and experiment with. If you would like to learn more, send a message [here](https://discord.com/channels/768936623684714517/879355527858126879).
{% endhint %}

## What are Index Vaults?

Index Vaults enable "fund of funds" activity on Brila, by allocating capital across multiple underlying Brila products (such as [Asset Vaults](/brila-protocol/asset-vaults), [Credit Vaults](/brila-protocol/credit-vaults), or [Lines of Credit](/brila-protocol/automated-lines-of-credit)).

Index Vaults do not allow managers to disburse funds to themselves, or to make loans directly to borrowers from Index Vault funds.

### How do Index Vaults work?

For technical details, see [Index Vault technical details](/brila-protocol/index-vaults/index-vault-technical-details).

### Can I demo Index Vaults?

Yes, see [Index Vault tutorial](/brila-protocol/index-vaults/index-vault-tutorial).


# Index Vault tutorial

### Tutorial / Demo

Users can test Index Vaults by creating their own demo vault on Optimism Sepolia using [this link](https://app.truefi.io/vault/index/create).

{% hint style="warning" %}
Before beginning, you will need to switch to the Optimism Sepolia test network and ensure your wallet is funded with test ETH and test USDC assets.

To complete these steps, follow this [step-by-step guide](https://scribehow.com/shared/Deploying_TrueFi_vaults_on_testnet_Optimism_Goerli_Copy__4esrcIFrSeiqSuLbx_P7IQ?back_to=browser).
{% endhint %}


# Index Vault technical details

## Technical considerations

Index Vault behavior is very similar to [Credit Vaults](/brila-protocol/credit-vaults), with exceptions in the following areas:

### Capital Deployment

Instead of loans, IVs utilize an instrument called `Investment` to deploy funds.

`Investments` are LP positions at non-IV vaults on Brila.

Because Brila vaults implement the ERC-4626 interface, interactions with all types of Brila vaults work the same way.

### Valuation

Instead of an array of loans, IVs hold an array of `investments`.

When calculating IV valuations, the IV iterates through that array and calls ERC-4626 `totalAssets()` on each of the underlying vaults to fetch the value of each `investment`.

### Investment Flow

#### Allocating Capital

Capital allocation happens through proxying one of the following methods:

* `deposit(assets, receiver)`
* `mint(shares, receiver)`

Allocation is only possible if the target vault’s token is already registered on the `vaultsRegistry`.

#### Adding tokens to the vaultsRegistry

Adding a token as a potential `investment` adds the token to the list of tracked asset balances and values.

In order to `register` a token, the token must:

* Be one of the allowlisted types of Brila products (i.e. [Lines of Credit](/brila-protocol/automated-lines-of-credit), [Credit Vaults](/brila-protocol/credit-vaults), or [Flexible Portfolios](/brila-protocol/other-concepts/other-legacy-contracts/flexible-portfolios-legacy/flexible-portfolio-contracts))
* Not be registered already

#### Removing tokens from the vaultsRegistry

`unregister` removes a token from the tracked assets list.

#### Redeeming / withdrawing

Redeeming and withdrawing happens through proxying one of the following methods:

* `withdraw(assets, receiver, owner)`
* `redeem(shares, receiver, owner)`

## Closing Vaults

Index Vaults cannot be closed while holding any active `investment`. Similar to how vaults cannot close before maturity unless all underlying loans are inactive, IVs cannot close unless all `investments` have closed first.


# BRLA token

<table><thead><tr><th width="144">Token</th><th>Contract</th></tr></thead><tbody><tr><td><strong>BRLA</strong></td><td>0x82790bc500d677101986a696d341a156</td></tr></tbody></table>

### BRLA Token Supply, Distribution & Unlocks

For more information about BRLA supply and distribution, please see the following [link](https://tokenomics.brila.finance).


# Staked BRLA

### To be announced


# How to Get BRLA

{% hint style="info" %}
*The information below is for informational purposes only, it is not investment advice. Please do your own research (DYOR) before using any of the third-party services discussed or linked to below. For more information regarding these third-party services, please review the* [*disclaimer*](#disclaimer) *below.*
{% endhint %}

The Brila Access Portal is now closed for TRU holders (claims ended Q2 2026). Please visit the [link](https://access.brila.finance) for more information, terms and conditions may apply.

## Decentralized exchanges (DEXs)

The token contract address of BRLA is: `TBA`

{% hint style="info" %}
Please make sure to double check the token contract address of TRU before making any transactions. Be aware of price slippage and transaction costs when trading on DEXs.
{% endhint %}

BRLA will be available for trading on Hyperliquid a decentralized exchanges (DEX), please follow official channels for more announcements.

## Disclaimer

{% hint style="info" %}
*The links provided within the “Centralized exchanges (CEXs)” and “Decentralized Exchanges (DEXs)” sections will bring you to third-party websites, owned and operated by independent parties over which we have no control (a "Third-Party Website"). Any link you make to or from a Third-Party Website will be at your own risk.*

*Any use of a Third-Party Website will be subject to and any information you provide will be governed by the terms of the Third-Party Website, including those relating to confidentiality, data privacy and security.*

*Unless otherwise expressly agreed to in writing, TrustToken, Inc. and all of its affiliates (“we”) are not in any way associated with the owner or operator of a Third-Party Website or responsible or liable for the goods and services offered by them or for anything in connection with such Third-Party Website. We do not endorse or approve and make no warranties, representations or undertakings relating to the content of a Third-Party Website.*

*We specifically disclaim liability for any loss, damage and any other consequence resulting directly or indirectly from or relating to your access to a Third-Party Website or any information that you may provide or any transaction conducted on or via a Third-Party Web site or the failure of any information, goods or services posted or offered at a Third-Party Website or any error, omission or misrepresentation on a Third-Party Website or any computer virus arising from or system failure associated with a Third-Party Website.*
{% endhint %}


# Other concepts

Brila infrastructure enables lenders, borrowers, and portfolio managers to deploy capital via lending pools and loans.

Portfolio managers on Brila deploy lending pools (or `vaults`) which in turn can deploy capital to borrowers via loans (`instruments`).

The following smart contracts represent vaults and instruments within the Brila protocol:

{% tabs %}
{% tab title="Vaults" %}
{% content-ref url="/pages/HtaKSp2SuI2JpV5XP27l" %}
[Credit Vault contract overview](/brila-protocol/credit-vaults/credit-vault-technical-details/credit-vault-contract-overview)
{% endcontent-ref %}

{% content-ref url="/pages/GjLMA41JyEyA1X93LcYb" %}
[Flexible Portfolio contracts](/brila-protocol/other-concepts/other-legacy-contracts/flexible-portfolios-legacy/flexible-portfolio-contracts)
{% endcontent-ref %}

{% content-ref url="/pages/7TPIYpow9Ch0vrvFPpec" %}
[Lines of Credit technical details](/brila-protocol/automated-lines-of-credit/lines-of-credit-technical-details)
{% endcontent-ref %}
{% endtab %}

{% tab title="Instruments" %}
{% content-ref url="/pages/1KL8aigycJAAya2fTv0u" %}
[FixedInterestOnlyLoan](/brila-protocol/other-concepts/instruments/fixedinterestonlyloan)
{% endcontent-ref %}

{% content-ref url="/pages/261QbHZxG3LXyz3wrnEL" %}
[BulletLoans](/brila-protocol/other-concepts/instruments/bulletloans)
{% endcontent-ref %}
{% endtab %}

{% tab title="Other contracts" %}

* [`ManagedPortfolioFactory`](#managedportfoliofactory)
* [`ProtocolConfig`](#protocolconfig)
  {% endtab %}
  {% endtabs %}

### Audits & Security

View audits [here](https://github.com/trusttoken/audits/).


# Controllers

## 🚀 Intro

Controllers regulate different aspects of how Brila products work.

They are responsible for key decision-making on how to perform most of the lender-facing operations. There are three Controllers that Brila utilizes:

* Transfer Controller
* Deposit Controller
* Withdrawal Controller

They can implement any logic and freely interact with any external on-chain or off-chain systems.

The details of how these controller work, what are they exactly responsible for and how Vaults interact with them is located below.

### How to read interface notation

**`whenThisFunctionIsCalledOnTheVault(arguments)`**

`vaultCallsThisFunctionOnTheController(msg.sender, arguments)`

Returns:

* `controllersResponse` - description of how the Vault will handle the Controller’s response

Parameters of the Vault’s methods are described in the [ERC-4626 documentation](https://eips.ethereum.org/EIPS/eip-4626).

***

## 🔁 Transfer Controller

Transfer Controller is responsible for setting restrictions around transfers of the share token (LP token). Transfer controller has to be capable of making a binary decision whether a particular transfer is allowed or not.

### Interface

**`transfer(to, value)`**

**`transferFrom(from, to, value)`**

`onTransfer(msg.sender, from, to, value)`

Returns:

`isTransferAllowed` - boolean determining whether a particular transfer is allowed or not (vault will execute the transfer on `true` and block the revert the transfer on `false`)

### Examples

Examples of the most common Transfer Controllers are:

* open - all transfers are allowed
* blocked - all transfers are forbidden and only minting or burning the token is allowed
* restricted - only transfers to farming contract (the one distributing incentives) are allowed

***

## ⤵️ Deposit Controller

Deposit Controller is responsible for handling all deposits. On a high level it can set:

* Lender restrictions (who can deposit into the Vault and when)
* LP token price at the deposit
* Deposit fee paid to the Portfolio Manager
* Maximum amount that can be deposited
* *Potentially many more via implicit manipulation of the response parameters…*

### Interface

**`deposit(assets, receiver)`**

`onDeposit(msg.sender, assets, receiver)`

Returns:

* `shares` - how many shares are gonna be minted to the `receiver`
* `depositFee` - how much is going to be subtracted from `assets` and sent to the manager beneficiary address

**`mint(shares, receiver)`**

`onMint(msg.sender, shares, receiver)`

Returns:

* `assets` - how many assets are going to be sent from `receiver` to the portfolio
* `mintFee` - how many assets are going to be sent from `receiver` to the manager fee beneficiary

Additionally, Deposit Controller needs to handle all the necessary view functions. The Vault calls these functions on the Controller, when they are called on the Vault. Their interfaces are identical to the original ERC-4626 interfaces.

* `previewDeposit(assets)` - returns how many LP will the depositor get for the assets
* `maxDeposit(receiver)` - returns max amount of assets that can be put into deposit (before fee subtraction)
* `previewMint(shares)` - returns how many assets does user need to send to mint particular number of shares (actually deposited + fee)
* `maxMint(receiver)` - returns max amount of shares that can be minted

### Examples

Examples of the most common Deposit Controllers are:

* Simple - deposits are always allowed, setting deposit ceiling
* Simple with lender restrictions - deposits are allowed for KYCed users, setting deposit ceiling
* Almighty - Portfolio Manager can set custom deposit parameters for each user (LP token price, fee, deposit limit)

***

## ⤴️ Withdrawal Controller

Withdrawal Controller is responsible for handling all withdrawals. It can set:

* Who and when can withdraw the Vault
* LP token price at the withdrawal
* Withdrawal fee paid to the Portfolio Manager
* Maximum amount that can be withdrawn
* *Potentially many more via implicit manipulation of the response parameters…*

### Interface

**`withdraw(assets, receiver, owner)`**

`onWithdraw(msg.sender, assets, receiver, owner)`

Returns:

* `shares` - how many shares are gonna be burned from the `owner`
* `withdrawFee` - how much is going to be withdrawn from the vault on top of the `assets` and sent to the manager beneficiary address

`**redeem(shares, receiver, owner)**`

`onRedeem(msg.sender, shares, receiver, owner)`

Returns:

* `assets` - how many assets are going to be sent from the vault to the `receiver`
* `mintFee` - how many assets are going to be taken from the vault on top of the `assets` and sent to the manager fee beneficiary

Additionally, Withdrawal Controller handles necessary view functions. Their interfaces are identical to the original ERC-4626 interfaces.

* `previewWithdraw(assets)` - returns how many LP will one need to burn in order to get desired amount of assets
* `maxWithdraw(owner)` - returns max amount of assets that can be withdrawn (after paying fee)
* `previewRedeem(shares)` - returns how many assets will user get (after paying fee) for a particular redeem
* `maxRedeem(receiver)` - returns max amount of shares that can be burned to redeem

### Examples

Examples of the most common Withdrawal Controllers are:

* Simple - withdrawals are always allowed, setting withdrawal floor
* Almighty - Portfolio Manager can set custom withdrawal parameters for each user (LP token price, fee, deposit limit)

***

## 💡 General Guidelines

### 👮‍♂️ Controller Whitelist

Controllers are approved by DAO Governance. Only approved Controllers are available in the Brila interface. Any new Controller proposal should consist not only of smart contract, but also a json file that would configure the controller UI in Portfolio Manager settings, a UI of actions on redeem / deposit button and so on.

#### Controller Whitelisting Request

A Controller Whitelisting Request should include

* All on-chain addresses necessary to properly integrate the Controller
* Controller source code
* UI JSON file
  * List of fields and options for controller column in the UI
  * Actions to execute upon click on Lender’s UI elements

### 🌗 Portfolio Phases Support

It’s important for Deposit and Withdrawal Controllers to support Portfolio lifecycle phases. Behavior of the Controller should match the intentions expressed in the documentation of a particular Brila product, that the Controller is aiming to serve.

**Examples:**

* A good and predictable Withdrawal Controller would remove all restrictions for withdrawing when the Portfolio goes into Closed state.
* A good and predictable Deposit Controller would ban all deposits when the Portfolio goes into Closed state

### 🗂 State Management

Controllers typically don’t hold any state, so their deployment doesn’t require a separate proxy contract for storage. The easiest and the fastest way to onboard a controller is the one that doesn’t hold any vault-specific state. It can store a general state and delegate decisions to other, state-holding contracts. Generally, Controllers are free to delegate any logic to other, external contracts.

The process of deploying state-holding controllers is a more complicated, as it requires the deployment of a proxy, but it is still possible and if there is a need to do so, builders are welcome and encouraged to do so.

#### Lender restrictions

Lender restrictions could be built within the Controller, but it’s more common for logic on lender restricitions to be delegated outside of the Controller.

A Controller can utilize another contract to check whether a user is allowed to interact with the Vault by checking an allowlist, NFT ownership, SBT ownership, etc.


# Instruments

Instruments are representations of loans and other financial instruments. The initial two instruments on Brila are:

[FixedInterestOnlyLoan](/brila-protocol/other-concepts/instruments/fixedinterestonlyloan)

[BulletLoans](/brila-protocol/other-concepts/instruments/bulletloans) *(deprecated)*


# FixedInterestOnlyLoan

`FixedInterestOnlyLoans` is an ERC-721 contract. Each minted NFT represents a loan that must be paid back to the NFT owner.

{% embed url="<https://github.com/trusttoken/contracts-helium>" %}

### Loan Parameters

Each loan is parametrized by:

* Underlying token with which funds are lent out and repaid (e.g. USDC)
* Principal debt (minting price)
* Period payment (interest paid at each installment)
* Period length (a period when the borrower pays installments)
* Period count (total number of installments)
* End date (date of the last installment to be paid together with the principal, set when the loan is started)
* Recipient’s address
* Grace period (time by which borrower can be late in repayment of each installment)
* A canBeRepaidAfterDefault flag that allows a loan to be repaid after a loan was marked as defaulted

### Loan states & state transitions

A loan can have one of the possible statuses: `Created`, `Accepted`, `Started`, `Repaid`, `Canceled`, or `Defaulted`.

Upon minting the loan status is set to `Created`. In this state, a borrower can accept a loan by calling `acceptLoan(id)` and the loan status is changed to `Accepted`.

The NFT owner can call `start(id)` on loans whose status is `Accepted`. When a loan is started the loan end date is calculated for the loan and the loan status is changed to `Started`.

The NFT owner can mark loans as canceled whose status is `Created` or `Accepted`.

The NFT owner can mark loans as `Defaulted` whose status is `Started` and the current block time is after a current period `endDate + grace`P`eriod` time.

The NFT owner can update the loan's `gracePeriod` at any time by calling `updateInstrument(id)`. The NFT owner must call `repay(id, amount)` to recalculate repaid periods and the current period end date.

The repaid amount must be equal to the period payment or period payment + principal for the last installment. The loan can be repaid after it was marked as defaulted only if the proper `canBeRepaidAfterDefault` flag was set to true.


# BulletLoans

{% hint style="warning" %}
`BulletLoans` is in the process of being sunset.

New Brila Capital Markets portfolios deployed after June 2022 use [`FixedInterestOnlyLoan`](/brila-protocol/other-concepts/instruments/fixedinterestonlyloan)
{% endhint %}

`​​​BulletLoans` is an ERC-721 contract. Each of the tokens represents a single loan.

{% embed url="<https://github.com/trusttoken/contracts-ragnarok/blob/main/contracts/ragnarok/BulletLoans.sol>" %}

All loan parameters can be read from LoanMetadata struct. `BulletLoans` contract enables loan creation, facilitates loan repayment and allows managing the loan's state and parameters.

### Methods

#### `createLoan( IERC20 _underlyingToken, uint256 _principal, uint256 _totalDebt, uint256 _duration, address _recipient )`

Manager can create loan by passing the principal to be lent, the total debt to repaid, duration of the loan, and the address of the recipient. Total debt to be repaid cannot be less than principal amount. ​

#### `repay(uint256 instrumentId, uint256 amount)`

Existing loan can be repaid partially or in full. If loan is paid in full, this function will mark the loan’s status to ‘Fully Repaid’. Note that a loan cannot be overpaid.

#### `markLoanAsDefaulted(uint256 instrumentId)`

Only the portfolio’s manager can mark a loan as defaulted. ​

#### `markLoanAsResolved(uint256 instrumentId)`

​Only the portfolio’s manager can mark a loan as resolved. Intended to be used for situations after partial repayment where a loan workout has been agreed to.

#### `updateLoanParameters( uint256 instrumentId, uint256 newTotalDebt, uint256 newRepaymentDate )`

Manager can modify loan terms, changing maturity date or total debt to be repaid.

#### `updateLoanParameters( uint256 instrumentId, uint256 newTotalDebt, uint256 newRepaymentDate, bytes memory borrowerSignature )`

Manager can modify loan terms, changing maturity date or total debt to be repaid. In order to change the maturity date to an earlier date or increase the repayment value, the borrower must consent and provide a signature.

### View methods

#### `principal(uint256 instrumentId)`

Returns principal amount of loan.

#### `underlyingToken(uint256 instrumentId)`

Returns underlying token (e.g. USDC, USDT) of the loan.

#### `recipient(uint256 instrumentId)`

Returns borrower’s address.

#### `endDate(uint256 instrumentId)`

Returns maturity date of the loan.

#### `unpaidDebt(uint256 instrumentId)`

Returns remaining amount to be paid, i.e. total debt less repaid amount.

#### `getStatus(uint256 instrumentId)`

Returns status of loan (`Issued`, `FullyRepaid`, `Defaulted`, `Resolved`).


# \[Legacy] DAO pools

\[Legacy] Lending pools governed by TRU stakers

{% hint style="info" %}
For developer docs see [Developer docs](/brila-protocol/other-concepts/legacy-dao-pools/developer-docs)
{% endhint %}

**TrueFi DAO-managed lending pools** (tfUSDC, tfUSDT, tfTUSD, tfBUSD) lend to institutional crypto borrowers that request loans from the protocol. Loans must be [approved by the protocol](/brila-protocol/other-concepts/legacy-dao-pools/loan-approval-process) and meet risk / return criteria set by the protocol.

<details>

<summary><strong>For Lenders</strong></summary>

Start [here](/brila-protocol/other-concepts/legacy-dao-pools/pool) to learn how TrueFi DAO pools work.

</details>

<details>

<summary>For Borrowers</summary>

Learn how to borrow from TrueFi DAO pools here: [Broken mention](broken://pages/ghYhJi2a0XlkqgG52A1M)

</details>

<figure><img src="/files/iIQsKXnQo5uun86Q1nMR" alt=""><figcaption><p>TrueFi DAO pool loan lists are available at <a href="https://app.truefi.io/loans">https://app.truefi.io/loans</a></p></figcaption></figure>


# delt.ai loan: Jan 2023 airdrop claiming instructions

Airdrop claiming instructions, provided by Archblock

### Summary

The airdrop comes in the form of an ERC4626 tokenized vault ([0x37C5867ef19DbE096dF8E125F33f895234E02875](https://etherscan.io/address/0x37C5867ef19DbE096dF8E125F33f895234E02875)), with mints and deposits disabled. This contract has undergone an internal security review and an [external audit by ChainSecurity](https://github.com/trusttoken/audits/blob/master/PortfolioDebtToken/2023-02-22%20ChainSecurity%20Audit%20-%20PortfolioDebtToken.pdf).

Shares of the airdrop are proportional to token holders of the tfUSDC lending pool as of January 9, 2023, the original end date of the delt.ai loan. This includes lenders who farmed their tfUSDC holdings, as well as claimable tfUSDC rewards from the stkTRU contract.

In order to prevent locked funds in the contract, you will have until a deadline of July 8, 2023, to redeem your shares of the interest airdrop.

After this date, TrueTrading will recover the remainder of funds.

NOTE: You may want to wait until gas prices are low before calling the `redeem()` function.

### Step-by-step instructions

1. **Check your balance of shares** [**here**](https://etherscan.io/token/0x37C5867ef19DbE096dF8E125F33f895234E02875#balances)**:**

<figure><img src="https://lh6.googleusercontent.com/8_lH4MTifre1anE2NRjoF2SGQjhbBDprpuuy-I3E22gp1DoeKWmveCU0Zldjc23OGBp-jd4gyZhza31ND9jkdT0iebJkAAfjso_kp70VHTJwVnaVUex-5q9N9gnY_IcXNruyLyA-JOire5Tm370WUxI" alt=""><figcaption></figcaption></figure>

In this screenshot example above, the address `0x168151` has a balance of `73,990.677577`, which means it can claim 73,990.677577 USDC. There should be six digits after the decimal point.

2. **Connect your wallet to Etherscan on** [**this page**](https://etherscan.io/address/0x37C5867ef19DbE096dF8E125F33f895234E02875#writeProxyContract) **by clicking the “Connect to Web3” button as indicated below:**

<figure><img src="https://lh3.googleusercontent.com/ZN0vZdHAj7qZXZXGJpJf_Atlhfa2tUVgwqu4pxJ-swMVmMTAd14RnHRfzgUoHYaokwGAYOwKcC480j3M4DkoJzZsGgy6-M-nRNEi31OJmb_qrVq9rs3kHN6cjmwCCm5jHlbbhh787ZlS6ByKNHR2NJM" alt=""><figcaption></figcaption></figure>

3. **Click, “Contract” and “Write as Proxy”, then call the redeem() function (#9, 0xba087652):**
   * For both receiver and owner, enter your wallet address from #1: `0x168151e53210Bbb08Fa6AfAC15E3da185e66069F`
   * For shares, enter your balance found in step #1, but using 6 decimals
     * Following the example from #1, the shares would be `73990677577`
     * Note: This number should contain no decimal point and no commas. There should be six digits after the decimal point from #1.

<div align="center"><figure><img src="https://lh3.googleusercontent.com/RxmxrrkO_tt-GzxOmJgT95BN8D2ERHd4SmVs_vD7Ijy8l8E9ufOdGSa4-yT03Ltm8TxLHYr3iJC-Ty6c0Enms6ntSisiYoqHbp1YDw0IpJm3ms_grgAkm2-dgIaJOFedzP172YSt8I9t7M6SeIvMdpc" alt=""><figcaption></figcaption></figure></div>

4. **Review this transaction carefully, click Write, and then confirm via your wallet.**

### Support

Please reach out to <support@archblock.com> if you have a smart contract with claimable airdrop balance, but no ability to call redeem(). If you can prove ownership of the contract, then Archblock may be able to work out a way for you to receive your share.

If you have any questions or need assistance, please contact <support@archblock.com>.


# delt.ai loan: July 2023 airdrop claiming instructions

Airdrop claiming instructions, provided by Archblock

### Summary

The airdrop comes in the form of an ERC4626 tokenized vault ([00xfBc33285d9f58d34fE239bFA3732036d5c53a1665](https://etherscan.io/address/0xfBc33285d9f58d34fE239bFA3732036d5c53a166)), with mints and deposits disabled. This contract has undergone an internal security review and an [external audit by ChainSecurity](https://github.com/trusttoken/audits/blob/master/PortfolioDebtToken/2023-02-22%20ChainSecurity%20Audit%20-%20PortfolioDebtToken.pdf).

Shares of the airdrop are proportional to token holders of the tfUSDC lending pool as of January 9, 2023, the original end date of the delt.ai loan. This includes lenders who farmed their tfUSDC holdings, as well as claimable tfUSDC rewards from the stkTRU contract.

**In order to prevent locked funds in the contract, users will have until a deadline of January 21, 2024, to redeem your shares of the interest airdrop.**

After this date, TrueTrading will recover the remainder of funds.

{% hint style="info" %}
You may want to wait until gas prices are low before calling the `redeem( )` function.
{% endhint %}

### Step-by-step instructions

1. **Check your balance of shares** [**here**](https://etherscan.io/token/0xfBc33285d9f58d34fE239bFA3732036d5c53a166#balances)**:**

<figure><img src="https://lh5.googleusercontent.com/pPYsG2WkyEe4kj7ytRxoVM5UUGmk5qq5WhTpJFuA4FlWlTGULV4G7uHOm9kAsgJkr-OcbLBP5GtiQaztdJHcaPHZBjsTfhotuEbbtozvklKqTPezrPv3RaeD9HJOF_1Z5M8Z0TVIU_Oa1OX29UyDATM" alt=""><figcaption></figcaption></figure>

In this example, the address `0x168151e53210Bbb08Fa6AfAC15E3da185e66069F` has a balance of 73,990.677577, which means it can claim 73,990.677577 USDC. There should be six digits after the decimal point.

2. **Connect your wallet to Etherscan on** [**this page**](https://etherscan.io/address/0xfBc33285d9f58d34fE239bFA3732036d5c53a166#writeProxyContract) **by clicking the “Connect to Web3” button as indicated below**

   <figure><img src="https://lh3.googleusercontent.com/DkxUqPAkYeM3IFvwvbYxRkrL5kp8TxbAFVsa4gku_-gMeNS6-5E0G9wlV00zUoSEI2bMVezt5IYE-9M2W1ZKq4FPaEwFKvVKW5bUI5iE68gjUfSU6GCJOrzghcz1JLD47uyWohfv1pu6SuG4_6xeBpQ" alt=""><figcaption></figcaption></figure>
3. **Click, “Contract” and “Write as Proxy”, then call the redeem() function (#9, 0xba087652):**

<figure><img src="https://lh6.googleusercontent.com/uaFp9Q-RsI7H6TI1hse2p0gwi3QZh6bDmlie6Oa8aLJaJZMghfd992waLWtf3pmK7Z5t3GmkFtbgunChtAuNG4mg3SgiPmp_ODF8OrdYi7dhR4PogUHGzSwN-94EosSPVC8Bxya2WkOLBW1BWO4XkYI" alt="" width="375"><figcaption></figcaption></figure>

For shares, enter your balance from #1 (but drop the decimal point and any commas): `73990677577` in the example.

For both receiver and owner, enter your wallet address from #1: `0x168151e53210Bbb08Fa6AfAC15E3da185e66069F` in the example

4. **Review this transaction carefully, click Write, and then confirm via your wallet.**

### Support

If you have any questions or need assistance, please contact <support@archblock.com>.

Please reach out to <support@archblock.com> if you have a smart contract with claimable airdrop balance, but no ability to call `redeem()`. If you can prove ownership of the contract, they may be able to work out a way for you to receive your share.


# delt.ai loan: October 2023 airdrop claiming instructions

Airdrop claiming instructions, provided by Archblock

### Summary

The airdrop comes in the form of an ERC4626 tokenized vault ([0x044e3e0a83453d6F673170953fdA6Ed725adB286](https://etherscan.io/address/0x044e3e0a83453d6F673170953fdA6Ed725adB286)), with mints and deposits disabled. This contract has undergone an internal security review and an [external audit by ChainSecurity](https://github.com/trusttoken/audits/blob/master/PortfolioDebtToken/2023-02-22%20ChainSecurity%20Audit%20-%20PortfolioDebtToken.pdf).

Shares of the airdrop are proportional to token holders of the tfUSDC lending pool as of January 9, 2023, the original end date of the delt.ai loan. This includes lenders who farmed their tfUSDC holdings, as well as claimable tfUSDC rewards from the stkTRU contract.

**In order to prevent locked funds in the contract, you will have until a deadline of April 10, 2024, to redeem your shares of the interest airdrop.**

After this date, TrueTrading will recover the remainder of funds.

{% hint style="info" %}
You may want to wait until gas prices are low before calling the `redeem( )` function.
{% endhint %}

### Step-by-step

1. **Check your balance of shares** [**here**](https://etherscan.io/token/0x044e3e0a83453d6F673170953fdA6Ed725adB286#balances)**:**

![](https://lh5.googleusercontent.com/ylKpBn6ikLXBnPIEHwxKaLM1MbC21VRoUvradOyzTg9oAgY0_WLqwEUa_HXUhJobCDQor43c7892dX0NbF_PAf6YOpcAvlYnBBzKl_izHek0v8Kgpevie6pQp5GIex5Rp8G064_Oy5tOTNYjuyxxKDg)

In this example, the address `0x168151e53210Bbb08Fa6AfAC15E3da185e66069F` has a balance of `73,990.677577`, which means it can claim 73,990.677577 USDC. There should be six digits after the decimal point.

2. **Connect your wallet to Etherscan on** [**this page**](https://etherscan.io/address/0x044e3e0a83453d6F673170953fdA6Ed725adB286#writeProxyContract) **by clicking the “Connect to Web3” button as indicated below:**

   <figure><img src="https://lh6.googleusercontent.com/DQDJmKCGDMwbEZD_gp7QXujSyHu8lIc1WNf7N5F2BWUkCxuBIZh95W8CjgcRKerORn8oBgV4cMEK7QuseWSAf90kXL8cr_-ATCzcJBZ8BBDHKwBCBr1urs55gw1fxzaeSYebnnDbhoAxx9m3vQ6VJ4Y" alt=""><figcaption></figcaption></figure>
3. **Click, “Contract” and “Write as Proxy”, then call the `redeem()` function (#9, 0xba087652):**

![](https://lh5.googleusercontent.com/GvHHTfmtOtSdRgzxgBMqAfk-naYdZ4ghi1cTJxU54Pd8yguOUSSl0SBtOQTtJcQPwr-a2lf97WCDtoPPUSoXfvxVpuV7H2qHgEHICUn2eoLc88AUuuqlKe1Qb-VWqD4jFWcT2gG_WqQNJP3zLNWWVTo)

For shares, enter your balance from #1 (but drop the decimal point and any commas): 73990677577 in the example.

For both receiver and owner, enter your wallet address from #1: 0x168151e53210Bbb08Fa6AfAC15E3da185e66069F in the example.

4. **Review this transaction carefully, click Write, and then confirm via your wallet.**

### Support

If you have any questions or need assistance, please contact <support@archblock.com>.

Please reach out to <support@archblock.com> if you have a smart contract with claimable airdrop balance, but no ability to call `redeem()`. If you can prove ownership of the contract, they may be able to work out a way for you to receive your share.


# delt.ai loan: Jan 2024 airdrop claiming instructions

Airdrop claiming instructions, provided by Archblock

### Summary

The airdrop comes in the form of an ERC4626 tokenized vault ([0xaAab06b81dA17A11E4Ada38a9DBa1D090D95253a](https://etherscan.io/address/0xaAab06b81dA17A11E4Ada38a9DBa1D090D95253a)), with mints and deposits disabled. This contract has undergone an internal security review and an [external audit by ChainSecurity](https://github.com/trusttoken/audits/blob/master/PortfolioDebtToken/2023-02-22%20ChainSecurity%20Audit%20-%20PortfolioDebtToken.pdf).

Shares of the airdrop are proportional to token holders of the tfUSDC lending pool as of January 9, 2023, the original end date of the delt.ai loan. This includes lenders who farmed their tfUSDC holdings, as well as claimable tfUSDC rewards from the stkTRU contract.

**In order to prevent locked funds in the contract, you will have until a deadline of July 9, 2024 to redeem your shares of the interest airdrop.**

After this date, TrueTrading will recover the remainder of funds.

{% hint style="info" %}
You may want to wait until gas prices are low before calling the `redeem( )` function.
{% endhint %}

### Step-by-step

1. **Check your balance of shares** [**here**](https://etherscan.io/token/0xaAab06b81dA17A11E4Ada38a9DBa1D090D95253a#balances)**:**

![](https://lh7-us.googleusercontent.com/4e0fZv-iN3-UxEng1nRWPFKcffCThGPvRmbKRGUz_kgGSvG_eYZg99LDHujWsucSbnn6Zoo9QM0oXnSNdDp_GJSuQQ39-aZTYaWh7GNQnPwxbe3nfqodxPp0j13vWiL5QwfnmcgMz9KU3OMoTW8yShw)

In this example, the address `0x168151e53210Bbb08Fa6AfAC15E3da185e66069F` has a balance of 73,990.677577, which means it can claim 73,990.677577 USDC. There should be six digits after the decimal point.

![](https://lh5.googleusercontent.com/GvHHTfmtOtSdRgzxgBMqAfk-naYdZ4ghi1cTJxU54Pd8yguOUSSl0SBtOQTtJcQPwr-a2lf97WCDtoPPUSoXfvxVpuV7H2qHgEHICUn2eoLc88AUuuqlKe1Qb-VWqD4jFWcT2gG_WqQNJP3zLNWWVTo)

For shares, enter your balance from #1 (but drop the decimal point and any commas): `73990677577` in the example.

For both receiver and owner, enter your wallet address from #1: `0x168151e53210Bbb08Fa6AfAC15E3da185e66069F` in the example.

2. **Connect your wallet to Etherscan on** [**this page**](https://etherscan.io/address/0xaAab06b81dA17A11E4Ada38a9DBa1D090D95253a#writeProxyContract) **by clicking the “Connect to Web3”** button as indicated below:![](https://lh7-us.googleusercontent.com/b6wepIRYEUVDsBSeIdh3duHWWlWR90NUp_Xp7crV1WZmLag-7OFYM-q4SjFSCW1lxIC4rY2CsM6s6V_6s2cxOOI-oEvWY9WeoTKuXb2ayyaoTDvyIvp7YeYmTa8cinh1mSWt7VcLNn1a-_wHuP7mwh0)
3. **Click, “Contract” and “Write as Proxy”, then call the `redeem()` function (#9, `0xba087652`):**\
   ![](https://lh7-us.googleusercontent.com/hhND50qJQ-Y5uVqIJc-RYVmhZyjPoQm0ZuojjaXjGSUo3jUAIl3NSBWbssb1yRV74zsHmQ3ybq5KVynW-Qhc_xyINCySpN--mrKSdr7rJnkIBYADiMuROqJ0mezQcxsewVhrjkI5OfFlh7S1rnkr6SM)

   For shares, enter your balance from #1 (but drop the decimal point and any commas): `73990677577`.

   For both receiver and owner, enter your wallet address from #1: `0x168151e53210Bbb08Fa6AfAC15E3da185e66069F`
4. **Review this transaction carefully, click Write, and then confirm via your wallet.**

### Support

If you have any questions or need assistance, please contact <support@archblock.com>.

Please reach out to <support@archblock.com> if you have a smart contract with claimable airdrop balance, but no ability to call `redeem()`. If you can prove ownership of the contract, they may be able to work out a way for you to receive your share.


# delt.ai loan: Apr 2024 airdrop claiming instructions

Airdrop claiming instructions, provided by Archblock

### Summary

The airdrop comes in the form of an ERC4626 tokenized vault ([0xCfaC5fDFa94aD0de96979ae9Fb1A5b747588f954](https://etherscan.io/address/0xCfaC5fDFa94aD0de96979ae9Fb1A5b747588f954)), with mints and deposits disabled. This contract has undergone an internal security review and an [external audit by ChainSecurity](https://github.com/trusttoken/audits/blob/master/PortfolioDebtToken/2023-02-22%20ChainSecurity%20Audit%20-%20PortfolioDebtToken.pdf).

Shares of the airdrop are proportional to token holders of the tfUSDC lending pool as of January 9, 2023, the original end date of the delt.ai loan. This includes lenders who farmed their tfUSDC holdings, as well as claimable tfUSDC rewards from the stkTRU contract.

In order to prevent locked funds in the contract, you will have until a deadline of October 04, 2024 to redeem your shares of the interest airdrop.

After this date, TrueTrading will recover the remainder of funds.

NOTE: You may want to wait until gas prices are low before calling the `redeem()` function.

### Step-by-step

1. **Check your balance of shares** [**here**](https://etherscan.io/token/0xCfaC5fDFa94aD0de96979ae9Fb1A5b747588f954#balances)**:**

<figure><img src="https://lh7-us.googleusercontent.com/EqkNf8VSNLazvu1Rqm1I_-ZpSRhY8l4IkQN0g8KQhR2XG5ab7azotb60q6ud3BlrgIlO8kgXmXkJ2R-NiKKi74ktNscu_Jhh3no7_vf46DTpLgyMsMR7fIIQvXwl_p5UJ_tu8quL3mBCB4paDeTJFKs" alt=""><figcaption></figcaption></figure>

In this example, the address 0x168151e53210Bbb08Fa6AfAC15E3da185e66069F has a balance of 73,990.677577, which means it can claim 73,990.677577 USDC. There should be six digits after the decimal point.

2. **Connect your wallet to Etherscan on** [**this page**](https://etherscan.io/address/0xCfaC5fDFa94aD0de96979ae9Fb1A5b747588f954#writeProxyContract) **by clicking the “Connect to Web3” button as indicated below:**<br>

   <figure><img src="https://lh7-us.googleusercontent.com/IWQODpTMh_M-3qSDrlEwK8MTIPTHc6HfinYaODhK7NpVTq88yYzbzJv-tSBaQ2uCrVK2uJBq-dwiZs7bCPwwXH2Jfh-jkHUfkFIYxpHa1_zuxcgxhnPXY8l9dMmLLx-5EdIEHvPNfMNCiA0PT6-GEas" alt=""><figcaption></figcaption></figure>
3. **Click, “Contract” and “Write as Proxy”, then call the `redeem()` function (#9, 0xba087652):**

<figure><img src="https://lh7-us.googleusercontent.com/1rSaG_EMoTjw-B3xfdJrCNHDGSsK7JFJBeZ9kvK8PXPeelsNLDar3gtBlDa7Sw8Ug-w1mx7V6GauEQgvACC7vP3TzO8KSk7BzFPLhUAnCPWRjQKXnwyu2ooulrvRqPPnjATnfXp-xO21VBPFY4cCByQ" alt=""><figcaption></figcaption></figure>

For shares, enter your balance from #1 (but drop the decimal point and any commas): e.g. 73990677577.

For both receiver and owner, enter your wallet address from #1:\
e.g. 0x168151e53210Bbb08Fa6AfAC15E3da185e66069F

4. **Review this transaction carefully, click Write, and then confirm via your wallet.**

### Support

If you have any questions or need assistance, please contact <support@archblock.com>.

Please reach out to <support@archblock.com> if you have a smart contract with claimable airdrop balance, but no ability to call `redeem()`. If you can prove ownership of the contract, they may be able to work out a way for you to receive your share.


# delt.ai loan: Nov 2024 airdrop claiming instructions

Airdrop claiming instructions, provided by Archblock

### Summary

The airdrop comes in the form of an ERC4626 tokenized vault ([0x4ed292bc0A5A411c6BFE436a3617835B94077F44](https://etherscan.io/address/0x4ed292bc0A5A411c6BFE436a3617835B94077F44)), with mints and deposits disabled. This contract has undergone an internal security review and an [external audit by ChainSecurity](https://github.com/trusttoken/audits/blob/master/PortfolioDebtToken/2023-02-22%20ChainSecurity%20Audit%20-%20PortfolioDebtToken.pdf).

Shares of the airdrop are proportional to token holders of the tfUSDC lending pool as of January 9, 2023, the original end date of the delt.ai loan. This includes lenders who farmed their tfUSDC holdings, as well as claimable tfUSDC rewards from the stkTRU contract.

In order to prevent locked funds in the contract, you will have until a deadline of May 22, 2025 to redeem your shares of the interest airdrop.

After this date, TrueTrading will recover the remainder of funds.

NOTE: You may want to wait until gas prices are low before calling the redeem( ) function.

### Step-by-step

1. **Check your balance of shares** [**here**](https://etherscan.io/token/0x4ed292bc0A5A411c6BFE436a3617835B94077F44#balances)**:**

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXcM0bOl9pj5g9x7FyFYtvj2TxzQO9s72js_QswOwEhTsAOzCHlKUMni1Ncp9D8l67_-G3evXeL426WPxW94H4A8Ov7vmVh1gn6sZqh8jdRTcXCP6r9Qst-W9uT2Sm_zGVcfM0Pk-g?key=PaKFTykrN9Vw4bmfC_r_zQwE)

In this example, the address 0x168151e53210Bbb08Fa6AfAC15E3da185e66069F has a balance of 73,990.677577, which means it can claim 73,990.677577 USDC. There should be six digits after the decimal point.

2. **Connect your wallet to Etherscan on** [**this page**](https://etherscan.io/address/0x4ed292bc0A5A411c6BFE436a3617835B94077F44#writeProxyContract) **by clicking the “Connect to Web3” button as indicated below:**

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXd2Zw8hH2XntUJxlu3TZR2Mfiybc8Zpa_bHBMloscWl9-03vdDckKune6IntJ-eX2mLxe5A9vWOo1Vl1Frb29W3GhmTK7MRBTeCXClJQ7iCgkAvf6l0KkcqUt3A2RU7ij2AJXkvTg?key=PaKFTykrN9Vw4bmfC_r_zQwE)

3. **Click, “Contract” and “Write as Proxy”, then call the redeem() function (#9, 0xba087652):**

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXdAIG5GXegirJekFwYiNfLtQKiTybBKFwjhs_GACpGKux7GGYHFzYaNZGEmckrIBaZHmLr4f4souQvIt0Ypl-tkgk9RWSV4BbDGHeYVj5jazBQGc3uT2-dUan33-TRA87y3nPfvfw?key=PaKFTykrN9Vw4bmfC_r_zQwE)

For shares, enter your balance from #1 (but drop the decimal point and any commas): 73990677577.

For both receiver and owner, enter your wallet address from #1: 0x168151e53210Bbb08Fa6AfAC15E3da185e66069F

4. **Review this transaction carefully, click Write, and then confirm via your wallet.**

### Support

Please reach out to us if you have a smart contract with claimable airdrop balance, but no ability to call redeem(). If you can prove ownership of the contract, then we may be able to work out a way for you to receive your share.

If you have any questions or need assistance, please contact us at <support@archblock.com>.


# Loan approval process

### Voting on loan applications

To vote on loan applications, you need stkTRU. To learn more about how to acquire stkTRU please view the section on [Staking](/brila-protocol/brla-token/stake). Once you have stkTRU you can visit the [Stake](https://app.truefi.io/stake) page and vote on the loan applications listed on the page.

The stkTRU balance with which you can vote on loan applications is equal to the stkTRU balance held by your wallet when the loan application was created. You will not be able to vote on loan applications with any stkTRU balance acquired after a loan application was created.

Stakers can either vote YES or NO with stkTRU on a loan application. Voting YES means you are predicting that the loan is not likely to default, and voting NO means you are predicting that the loan is likely to default. Stakers can vote with the entire stkTRU balance of their wallet, including the stkTRU balance delegated to their wallet address.

Voting on loan applications does not lock stkTRU, stakers can use their stkTRU balance to vote on multiple loan applications.

### What’s the voting period for voting on loan applications?

There is no specific time period for stkTRU holders to vote on loan applications. After a loan application is live on the TrueFi platform, stkTRU holders can start voting on the loan until the loan application is funded by the lending pool or cancelled by the borrower.

However, there is a minimum time period that must pass before a loan can be funded by the lending pool. This time period is called the minimum voting period which corresponds to the votingPeriod parameter set in the TrueLender smart contract.

Visit the etherscan link to the TrueLender (proxy) smart contract, click on Contract, then click on Read as Proxy. You will find the parameter votingPeriod in seconds.

stkTRU holders can modify or cancel their votes any number of times before the loan has been funded by the lending pool or cancelled by the borrower.

### How are loan applications approved?

stkTRU holders vote YES or NO on whether to approve a loan request. A loan is approved if it satisfies two conditions.

1. Minimum # of votes (15 million as of Sept 2022)
2. Minimum ratio of YES-to-NO votes (at least 80% of votes YES, as of Sept 2022)

Only whitelisted borrowers can submit their loan applications to the `TrueRatingAgencyV2` contract. Whitelisted addresses will return true when queried against `allowedSubmitters` in the `TrueRatingAgencyV2` contract.

Loans are approved or rejected based on conditions set in three smart contracts: TrueFi lending pool contract (`tfUSDC` et al), `TrueRatingAgencyV2`, and `TrueLender2`.

<table><thead><tr><th width="217">Contract</th><th>Address</th></tr></thead><tbody><tr><td>TrueLender2</td><td><a href="https://etherscan.io/address/0xa606dd423dF7dFb65Efe14ab66f5fDEBf62FF583">0xa606dd423dF7dFb65Efe14ab66f5fDEBf62FF583</a></td></tr><tr><td>TrueRatingAgencyV2</td><td><a href="https://etherscan.io/address/0x05461334340568075bE35438b221A3a0D261Fb6b">0x05461334340568075bE35438b221A3a0D261Fb6b</a></td></tr></tbody></table>

### Incentive for voting on loan applications

stkTRU holders receive rewards in the form of TRU tokens for voting on loan requests. The rewards become claimable as soon as the loan is withdrawn by the borrower and the status of the loan becomes active. Rewards are distributed to voters based on their share of the total votes received:

`TRU Reward for voting = (# TRU voted by user / # total TRU votes) * (Total TRU Reward)`, where

* `Total TRU Reward = (Loan interest * TRU distribution factor * rewardMultiplier)`
  * where `Loan interest = (loan APR * term in days * principal) /365`. Loan APR, term, and principal can be obtained from the respective loan token contract
  * `rewardMultiplier` can be found from the [TrueRatingAgencyV2](https://etherscan.io/address/0x05461334340568075bE35438b221A3a0D261Fb6b#readProxyContract#F18) contract
  * `TRU distribution factor` is calculated as `remaining` divided by `amount` from the [RatingAgencyV2Distributor](https://etherscan.io/address/0x6151570934470214592AA051c28805cF4744BCA7#readProxyContract) contract


# Lender FAQs

### How does TrueFi generate yield? <a href="#how-does-truefi-achieve-its-apys" id="how-does-truefi-achieve-its-apys"></a>

TrueFi lending pools fund loans to borrowers who request loans from the protocol. Loans must be [approved by the protocol](/brila-protocol/other-concepts/legacy-dao-pools/loan-approval-process) and meet risk / return criteria set by the protocol. Uncollateralized lending has a higher risk profile than other markets and thus should provide higher returns.

### How does lending on TrueFi work?

Lenders can lend stablecoins to TrueFi lending pools, which use predefined strategies to lend to creditworthy borrowers. See below for a brief demo:

{% embed url="<https://www.youtube.com/watch?v=VV8QUU9PCFQ&feature=youtu.be>" %}

TrueFi lending pools are controlled by TrueTrading, an affiliate company of TrustToken, Inc. The TrueFi lending pools only lend to a whitelist of trusted borrowers, and any excess capital that is not actively loaned out may be deployed in a DeFi protocol.

Lenders who lend to the TrueFi lending pool receive [TrueFi lending pool tokens](https://app.gitbook.com/o/-MN4YY-ASH9_7pmGzotY/s/-MOBxBNTVTribg0rlJSW/~/changes/ZDnvDwmhlTQsmMdTrS4V/how-it-works/lending-on-truefi/pool/lending-and-monitoring-positions#what-are-lending-pool-tfi-lp-tokens-1) ("LP tokens"), which represent their proportion of lent capital in the TrueFi lending pool.

### Is there a lockup period for lenders?

No. Lenders can redeem LP tokens any time idle funds are available in the pool. Lenders pay an [*exit fee*](/brila-protocol/other-concepts/legacy-dao-pools/pool/withdrawing-funds#what-is-liquid-exit) in order to withdraw instant liquidity from the pool. This fee is calculated dynamically, depending on what proportion of the pool is idle vs. lent to borrowers.

Additionally, [LP tokens can be traded on secondary markets](/brila-protocol/other-concepts/legacy-dao-pools/pool/how-lending-pool-lp-tokens-work#why-is-there-a-difference-between-the-calculated-tfi-lp-price-and-its-price-on-uniswap), such as Uniswap.

### Are there any fees for lending to the Lending Pools?

There are no fees for lending funds into lending pools. To withdraw funds, lenders may pay an [*exit fee*](/brila-protocol/other-concepts/legacy-dao-pools/pool/withdrawing-funds#what-is-liquid-exit)*.*

### What are the risks involved in lending to the TrueFi lending pool? <a href="#what-are-the-risks-involved-in-lending-to-the-truefi-lending-pool" id="what-are-the-risks-involved-in-lending-to-the-truefi-lending-pool"></a>

While borrowers are usually willing to pay higher rates for uncollateralized loans, these higher yields do not come without risks. Compared with collateralized lending, uncollateralized lending has two major risks:

* Potentially increased risk of loss: Protocols that require collateral are protected by that collateral in case of default. While this allows such platforms to be less selective in approving loans, uncollateralized loans come with a much higher standard of trust that must be met by a borrower. In case of default on an uncollateralized loan, a delinquent borrower will have been assessed for creditworthiness before the loan was made and will face both reputational damage and legal action.
* Potentially lower liquidity: While instant withdrawals are becoming a norm for new protocols, uncollateralized lending may not offer the same flexibility. Most borrowers for uncollateralized loans are interested in fixed-rate, fixed-term loans for predictable repayment. This means lenders who fund such loans need to be comfortable locking up their assets for the duration of the loan. TrueFi offers an alternative: the ability to withdraw their proportion of the pool tokens which would consist of stablecoins and loan tokens that you hold to maturity. You can redeem the loan tokens for the stablecoin at the end of loan terms.

You can learn more about how TrueFi mitigates risk [here](/brila-protocol/other-concepts/legacy-dao-pools/pool/risk-mitigation#how-truefi-mitigates-risk).

### Who is responsible for taking legal actions against delinquent borrowers? <a href="#who-is-responsible-for-taking-legal-actions-against-delinquent-borrowers" id="who-is-responsible-for-taking-legal-actions-against-delinquent-borrowers"></a>

TrueTrading is currently responsible for pursuing legal recourse if a borrower defaults and may be replaced by another non-profit entity in the future as TrueFi progressively decentralizes.

### How can lending pool token holders farm TRU? <a href="#how-can-lenders-or-tfi-lp-token-holders-farm-tru" id="how-can-lenders-or-tfi-lp-token-holders-farm-tru"></a>

Lending pool token holders can farm TRU by staking their lending pool tokens (tfTUSD, tfUSDC, tfUSDT, or tfBUSD) on the [Farm](https://app.truefi.io/farm) page.


# Lending to DAO pools

### How do I lend? <a href="#what-are-lending-pool-tfi-lp-tokens" id="what-are-lending-pool-tfi-lp-tokens"></a>

Users can lend to TrueFi DAO pools at <https://app.truefi.io/lend>.

Once a user is ready to lend, the user will need to complete two transactions:

1\) `approve()`: User must approve the lending pool smart contract to transfer up to a certain allowance of the asset. Read more [here](https://metamask.zendesk.com/hc/en-us/articles/6174898326683-What-is-a-token-approval-).

![](/files/lr7Ct26QEAW6gTfmzAmr)

2\) `lend()`: User lends funds to the lending pool. In return, the lender [receives lending pool tokens](/brila-protocol/other-concepts/legacy-dao-pools/pool/how-lending-pool-lp-tokens-work#what-are-lending-pool-tfi-lp-tokens) ("LP tokens").

​![](/files/O0n8xwl8iNCNoABp5vE2)

The lender can optionally [stake their LP tokens to farm TRU rewards](/brila-protocol/other-concepts/legacy-dao-pools/pool/farming-liquidity-mining), which generate additional yield on top of underlying returns in the pool.

### Why do I see two options after I click 'Lend'? <a href="#why-do-i-see-two-options-when-i-click-lend" id="why-do-i-see-two-options-when-i-click-lend"></a>

The TrueFi app helps to find lenders the best price when they lend to the pool.

Lenders can choose between (i) lending funds directly to the pool and minting LP tokens, or (ii) buying LP tokens on a secondary market (Uniswap).

In the example shown in the screenshot below, the UI shows that the user may be able to get a better price and incur lower gas costs by going directly to Uniswap to get tfUSDC.

![](/files/kJ5uGTwe0j0vfkusf543)

### TrueFi Lending Pool smart contracts

<table><thead><tr><th width="205.04059574152853">Pool</th><th>Address</th></tr></thead><tbody><tr><td>tfTUSD</td><td><a href="https://etherscan.io/address/0x97cE06c3e3D027715b2d6C22e67D5096000072E5">0x97cE06c3e3D027715b2d6C22e67D5096000072E5</a></td></tr><tr><td>tfUSDC</td><td><a href="https://etherscan.io/address/0xA991356d261fbaF194463aF6DF8f0464F8f1c742">0xA991356d261fbaF194463aF6DF8f0464F8f1c742</a></td></tr><tr><td>tfUSDT</td><td><a href="https://etherscan.io/address/0x6002b1dcB26E7B1AA797A17551C6F487923299d7">0x6002b1dcB26E7B1AA797A17551C6F487923299d7</a></td></tr><tr><td>tfBUSD</td><td><a href="https://etherscan.io/address/0x1Ed460D149D48FA7d91703bf4890F97220C09437">0x1Ed460D149D48FA7d91703bf4890F97220C09437</a></td></tr><tr><td>Legacy tfTUSD</td><td><a href="https://etherscan.io/address/0xa1e72267084192db7387c8cc1328fade470e4149">0xa1e72267084192db7387c8cc1328fade470e4149</a></td></tr></tbody></table>


# Farming TRU rewards

In addition to earning yield from loan activity in DAO pools, **lenders can also earn additional yield in the form of TRU rewards** ("yield farming").

### How do I farm TRU rewards?

TrueFi DAO Pool lenders begin accruing TRU rewards as soon as their LP tokens have been staked.

Lenders can stake lending pool tokens in the liquidity gauge via the [Farm](https://app.truefi.io/farm) page, or via the [`stake()`](https://etherscan.io/address/0xec6c3FD795D6e6f202825Ddb56E01b3c128b0b10#writeProxyContract#F6) function on the `TrueMultiFarm` contract.

<figure><img src="/files/10NnnQJXbARxfhCwylmX" alt=""><figcaption><p>How to stake LP tokens via <a href="https://app.truefi.io/farm">https://app.truefi.io/farm</a></p></figcaption></figure>

### How do I check and claim my farm rewards?

At any given time, a lender can check the # of accrued rewards and claim rewards by visiting <https://app.truefi.io/farm>.

Additionally, lenders can find the # of TRU rewards by checking [`claimable()`](https://etherscan.io/address/0xec6c3FD795D6e6f202825Ddb56E01b3c128b0b10#readProxyContract#F1) on the `TrueMultiFarm` contract below:

<table><thead><tr><th width="221">Name</th><th>Contract</th></tr></thead><tbody><tr><td>TrueMultiFarm</td><td><a href="https://etherscan.io/address/0xec6c3FD795D6e6f202825Ddb56E01b3c128b0b10">0xec6c3FD795D6e6f202825Ddb56E01b3c128b0b10</a></td></tr></tbody></table>

Lenders can claim TRU rewards by calling [`claim()`](https://etherscan.io/address/0xec6c3FD795D6e6f202825Ddb56E01b3c128b0b10#writeProxyContract#F1) on this contract.

Additionally, lenders can call [`exit()`](https://etherscan.io/address/0xec6c3FD795D6e6f202825Ddb56E01b3c128b0b10#writeProxyContract#F3) to unstake LP tokens and claim rewards within the same transaction.

### How are TRU rewards distributed?

To find the current emissions rate for a farm, users can divide the totalAmount by duration. Visit the etherscan link to the smart contract, click on Contract, then click on Read as Proxy. You will find the two parameters totalAmount and duration. The duration is in seconds.

`TRU distribution per day = (totalAmount/10^8) / (duration/(24*3600))`

### Liquidity Gauge TRU Distributor Smart contract

<table><thead><tr><th width="222">Name</th><th>Contract</th></tr></thead><tbody><tr><td>LinearTrueDistributor</td><td><a href="https://etherscan.io/address/0xc7AB606e551bebD69f7611CdA1Fc473f8E5b8f70">0xc7AB606e551bebD69f7611CdA1Fc473f8E5b8f70</a></td></tr></tbody></table>

### Are there additional economic risks involved in farming? <a href="#what-is-the-distribution-schedule-of-tru-for-liquidity-providers" id="what-is-the-distribution-schedule-of-tru-for-liquidity-providers"></a>

Farming on TrueFi lending pools involves no additional economic risk beyond risks involved as a lender. Users are inherently exposed to borrower default risk as a lender.

### What is TRU?

Read more about TRU, TrueFi's governance token [here](/brila-protocol/brla-token).


# Withdrawing funds

Liquid Exit and other FAQs

### How can I exit the lending pools? <a href="#how-can-i-exit-the-lending-pools" id="how-can-i-exit-the-lending-pools"></a>

You can exit the pool by selling your lending pool tokens to the TrueFi lending pools for the stablecoin if there is enough liquid asset in the pool to support the transaction. This feature is also called liquid exit.

### **What is Liquid Exit?**

**‌**Liquid exit addresses a key community request which is the ability to exit the TrueFi Lending Pool directly into the underlying stablecoin. Lending pool token holders can redeem their LP tokens for the stablecoin for an exit fee.

The exit fee is inversely proportional to the amount of available idle liquidity in the pool. For example, when there is a large amount of liquid assets in the pool, the fee is low. When there is a small amount of liquid asset in the pool, the fee is high. This fee is earned by the pool for the existing lending pool token holders.

The exit fee charged to you for an exit would be made available to you in the UI. If you feel that the fee charged is too high then you can wait till the pool is more liquid and try again later. ![](/files/SVUOSCcXSnxIqI1GWN48)

1\) If there is no liquid asset in the lending pool and no liquid exit is deployed in Curve.

2\) If the pool needs to liquidate its position in Curve and will incur a loss of more than 10 basis points.

Click [here](https://docs.google.com/spreadsheets/d/1ZXGRxunIwe0eYPu7j4QjCwXxe63tNKtpCvRiJnqK0jo/edit?usp=sharing) to view the relationship between Pool utilization and exit fees.


# How lending pool (LP) tokens work

After [lending to the pool](/brila-protocol/other-concepts/legacy-dao-pools/pool/lending-to-dao-pools), a lender receives lending pool tokens ("LP tokens"). Read further to find how users can track the value of their LP tokens and trade LP tokens.

### What are Lending Pool tokens ("LP tokens")? <a href="#what-are-lending-pool-tfi-lp-tokens" id="what-are-lending-pool-tfi-lp-tokens"></a>

Lending Pool tokens (or "LP tokens") are tradable ERC-20 tokens that represent a lender’s proportional representation in the pool.

In the beginning, when no loans have been disbursed by the TrueFi lending pool, lenders will receive one TrueFi Lending Pool Token (tfTUSD, tfUSDC, tfUSDT, or tfBUSD) for every stablecoin lent to the pool.

As the pool starts earning yields and disbursing loans, the value of the pool tokens may increase or decrease depending on returns within the pool. The value of the pool represents the present value of all its underlying tokens (stablecoins, loan tokens, and other tokens earned).

### How do I calculate LP token prices? <a href="#how-many-tfi-lp-tokens-will-i-get-for-lending-to-the-truefi-lending-pool" id="how-many-tfi-lp-tokens-will-i-get-for-lending-to-the-truefi-lending-pool"></a>

We can calculate LP token price by checking the `poolValue()` and `totalSupply()` read functions on the lending pool smart contract:

`LP token price = poolValue() / totalSupply()`

We can use this LP token price to find how many LP tokens a lender will receive in return for lending tokens to the pool.

{% hint style="info" %}
**Example**:

Bob lends 2,000,000 USDC to the tfUSDC pool.

Given that tfUSDC [`poolValue()`](https://etherscan.io/address/0xA991356d261fbaF194463aF6DF8f0464F8f1c742#readProxyContract#F27)`=` 46226887530770 and [`totalSupply()`](https://etherscan.io/address/0xA991356d261fbaF194463aF6DF8f0464F8f1c742#readProxyContract#F34)

42405680290948 at the time of lending, we calculate *tfUSDC LP price = 1.0901*.

Bob will thus receive 2,000,000 / 1.0901 = **1,834,675.99 tfUSDC LP tokens**
{% endhint %}

Additionally, we can calculate the value of a lender's position at any point in time:

`Lender's position value = (# of LP tokens held) * (LP token price)`

### Are LP tokens tradable on secondary markets? <a href="#why-is-there-a-difference-between-the-calculated-tfi-lp-price-and-its-price-on-uniswap" id="why-is-there-a-difference-between-the-calculated-tfi-lp-price-and-its-price-on-uniswap"></a>

Yes, LP tokens can be traded on secondary markets. There are existing markets on Uniswap v3 today.

* tfUSDC/USDC: <https://info.uniswap.org/#/pools/0xd7c13ee6699833b6641d3c5a4d842a4548030a82>
* tfUSDT/USDT:\
  <https://info.uniswap.org/#/pools/0x5cc644472ed7d3198eeb23353bd9236ca578a895>

### Why is there a difference between calculated LP token price and its price on Uniswap? <a href="#why-is-there-a-difference-between-the-calculated-tfi-lp-price-and-its-price-on-uniswap" id="why-is-there-a-difference-between-the-calculated-tfi-lp-price-and-its-price-on-uniswap"></a>

LP token prices calculated by the lending pool assume that loans will be repaid successfully within the term, among other assumptions.

Other market participants may have use different assumptions in their calculation of LP token prices. There are several market factors that may govern the price of lending pool tokens and the TrueFi platform does not have any control over them.


# How loan tokens work

### What are loan tokens? <a href="#what-are-loan-tokens" id="what-are-loan-tokens"></a>

Loan tokens are non-tradable ERC-20 tokens which represent the lender’s proportional representation in a loan that is issued from the Lending Pool.

Each loan issued from the Lending Pool will create a unique loan token used to track the present value of each loan. Loan tokens form an important building block of TrueFi, as they can operate independently from the TrueFi lending pools. Tokenized loans open up opportunities for calculating and tracking the value to the individual loans within the Lending Pool. TrueFi does not allow for the transfer of Loan tokens and will not create a secondary market for loan tokens. It is important to note that all Loan tokens are unique and can be tracked on the [Loans](https://app.truefi.io/loans) page of the TrueFi website.

Creating a Loan token requires a borrower’s wallet address, principal amount, term, and interest rate or APR associated with a loan. When a loan is [approved by the pool](/brila-protocol/other-concepts/legacy-dao-pools/loan-approval-process), loan tokens are minted by funding the loan token contract with the principal amount. The minted loan tokens represent a share in the total amount payable at the end of the term which is the sum of principal and interest.

Loan tokens are minted at a discounted rate, meaning that loan tokens paid back in full will converge to a price of 1.000:

`# of loan tokens minted = principal + interest owed at loan maturity`

Once a loan is funded, the borrower can call a function which allows them to borrow the funds from the smart contract. At the end of the term, once the borrower pays back the loan, loan token holders can exchange their loan tokens for an equivalent number of stablecoins.

{% hint style="success" %}
**Example**:

When a loan with *principal = 1,000,000 USDC, term = 30 days, APR = 12%* is approved, 1,009,863.013 ( `= 1,000,000 + 1,000,000 x 12% x 30/365`) loan tokens are minted.

At maturity, if the borrower repays the entire loan amount along with interest, the lending pool can exchange 1 loan token for 1 USDC.
{% endhint %}

### What is the value of a loan token at any point of time? <a href="#what-is-the-value-of-a-loan-token-at-any-point-of-time" id="what-is-the-value-of-a-loan-token-at-any-point-of-time"></a>

The theoretical present value of a loan token is calculated by assuming the loan is repaid in full by the end of the loan term.

The following formulas walk through how lending pools value loan tokens (*where loan token \`0xabc\` represents a single loan, and \`t\` represents time since loan origination):*

**`Value of all 0xabc loan tokens minted`**` `` ``= principal + (t / term ) x interest `

**`Value of a single 0xabc loan token`**` `` ``= (Value of all 0xabc loan tokens) / (supply of 0xabc loan tokens) `

**`Value of a single 0xabc loan token`**` `` ``= (principal + (t / term ) x interest)/(principal + interest) `

{% hint style="success" %}
**Example**:

When a loan with *principal = 1,000,000 USDC, term = 30 days, APR = 12%* is approved, 1,009,863.013 ( `= 1,000,000 + 1,000,000 x 12% x 30/365`) loan tokens are minted.

The value of a single loan token at `n` days (where `n` is less than or equal to 30) is **1,009,863.013 USDC** `(=1,000,000 + (n/30) x 9,863.013)`).
{% endhint %}


# SAFU (Secure Asset Fund for Users)

## What is the SAFU?

The SAFU is an overhaul of how TrueFi handles borrower defaults. The SAFU smart contract is responsible for all bad debt accrued by the protocol. The SAFU has been initially [funded by TrustToken](https://blog.trusttoken.com/truefis-tru-token-economics-7facea6651c0) and the funds will help cover defaults.

In case of a loan default, TrueFi lending pools will transfer all bad debt assets to the SAFU in exchange for the full expected value of those assets. Then, the SAFU will slash staked TRU tokens, up to 10% of the defaulted amount. If the value of these slashed tokens is not enough to cover the default, the SAFU will use its funds to help repay the affected lending pool for lost funds.

### **SAFU default handling**

In the event of a default, the following occurs:

1. Up to 10% of TRU is slashed from the staking pool and transferred to the SAFU to cover the defaulted amount, equal to the principal amount plus the full amount of expected interest (“Defaulted Amount”)
2. All the defaulted LoanTokens will be transferred from the lending pool to the SAFU
3. If the current SAFU funds are insufficient to cover the defaulted loan; the SAFU can sell TRU for the respective borrowed asset at its manager’s discretion
4. If the value of the SAFU funds can not satisfy the defaulted loan:
   1. The difference between the defaulted loan and the SAFU is calculated (“Uncovered Amount”).
   2. The SAFU will issue ERC-20 tokens representing a claim for the Uncovered Amount (“Deficiency Claim”).
   3. Then, the affected lending pool will receive a Deficiency Claim for the Uncovered Amount, assuming its successful recovery.
   4. The affected lending pool will have a first-priority claim on the funds recouped through arbitration for the Deficiency Claim amount.
5. If a debt is repaid:
   1. The recouped funds will be used to purchase the asset that the Loan Token was originally denominated in, which will be transferred to the LoanToken contract.
   2. The SAFU will burn the Loan Tokens for the underlying value of those tokens (“Recovered Amount”)
   3. The SAFU is going to repurchase the issued Deficiency Claim tokens from the lending pool up to the Recovered Amount.
   4. If there is a remainder of the recovered funds after repurchasing the lending pool’s Deficiency Claim, the SAFU keeps those funds.
6. If any portion of the original loan amount is not repaid after the completion of the legal recovery process; the lending pool’s remaining Deficiency Claim tokens are going to be burned thus reducing the LP token price.

### **Smart Contract Architecture**

The SAFU replaces what was called “Liquidator” in previous TrueFi versions. Therefore, it will have permission to slash TRU from the staked TRU pool.

The funds in the SAFU will be managed by an approved address, automating as much capital management as possible through DeFi. In the initial version, the funds' management will be somewhat centralized to maximize the capital efficiency when making exchanges between tokens. For example, the price impact of exchanging TRU on decentralized exchanges is much higher than the impact of OTC or centralized exchange opportunities.

Nevertheless, following the ethos of progressive decentralization, future unlocks will include updates to the SAFU which will further decentralize the management of the SAFU funds.


# Risk Mitigation

## Has TrueFi been audited?

Yes, please see TrueFi's technical audits [here](https://github.com/trusttoken/audits/tree/master/TrueFi).

## How does TrueFi mitigate risk?

TrueFi takes multiple measures to help protect lenders:

* [Staked TRU](/brila-protocol/brla-token/stake) provides default protection for lenders and governs the [loan approval process](/brila-protocol/other-concepts/legacy-dao-pools/loan-approval-process)
* Borrowers on TrueFi follow a thorough Know Your Business (“KYB”) workflow and credit review which incorporates both on-chain and off-chain data, such as company background, repayment history, operating & trading history, assets under management, and credit metrics.
* TrueFi handles bad debt via a [Secure Asset Fund for Users (“SAFU”)](/brila-protocol/other-concepts/legacy-dao-pools/pool/safu-secure-asset-fund-for-users) smart contract.
* TrueFi lenders can also purchase [smart contract cover](https://app.nexusmutual.io/cover/buy/get-quote?address=0x7a9701453249e84fd0D5AfE5951e9cBe9ed2E90f) through Nexus Mutual to hedge risks when lending on TrueFi. Coverage is paid out at the discretion of mutual members but has covered technical exploits in the past.

*This is not investment advice. Please Do Your Own Research.*


# Developer docs

\[Legacy] TrueFi DAO pools contracts

Below is a brief guide to TrueFi lending pool contracts.

For detailed questions, please reach out to the [Discord #dev](https://discord.com/channels/768936623684714517/881223601657901077) channel.

## Lending pool addresses

<table><thead><tr><th width="216">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>tfUSDC</td><td><a href="https://etherscan.io/address/0xA991356d261fbaF194463aF6DF8f0464F8f1c742">0xA991356d261fbaF194463aF6DF8f0464F8f1c742</a></td></tr><tr><td>tfUSDT</td><td><a href="https://etherscan.io/address/0x6002b1dcB26E7B1AA797A17551C6F487923299d7">0x6002b1dcB26E7B1AA797A17551C6F487923299d7</a></td></tr><tr><td>tfTUSD</td><td>​<a href="https://etherscan.io/address/0x97cE06c3e3D027715b2d6C22e67D5096000072E5">0x97cE06c3e3D027715b2d6C22e67D5096000072E5</a></td></tr><tr><td>tfBUSD</td><td><a href="https://etherscan.io/address/0x1Ed460D149D48FA7d91703bf4890F97220C09437">0x1Ed460D149D48FA7d91703bf4890F97220C09437</a></td></tr></tbody></table>

## ***TrueFi DAO Pool*****&#x20;contracts**

* [**TrueFiPool2**](#truefipool2-contract): lenders provide and withdraw liquidity to the pool, and can get lending pool details, such as pool value, pool token price, etc. from this contract
* [**TrueLender2**](#truelender2-contract): implements the lending strategy for the TrueFi pool, i.e. how loans are approved and funded
* [**LoanFactory2**](#what-are-loan-tokens): deploys LoanTokens, which represent details of each loan on-chain
* [**TrueRatingAgencyV2**](#trueratingagencyv2): loan applications are rated and approved by TRU stakers
* [**TrueMultiFarm**](#truemultifarm): lenders can stake lending pool tokens to earn TRU rewards (read more [here](/brila-protocol/other-concepts/legacy-dao-pools/pool/farming-liquidity-mining))
* **SAFU:** handles bad debt in TrueFi lending pools (read more [here](/brila-protocol/other-concepts/legacy-dao-pools/pool/safu-secure-asset-fund-for-users))

## TrueFiPool2 contract

The `TrueFiPool2` contract is used by TrueFi DAO lending pools -- tfUSDC / tfUSDT / tfBUSD / tfTUSD. This contract enables accounts to pool tokens with the goal of earning yields on underlying tokens.

<table><thead><tr><th width="216">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>TrueFiPool2</td><td><a href="https://etherscan.io/address/0x8d35372ea3e85c49a60f0a72edeff8629da3999a#code">0x8d35372ea3e85c49a60f0a72edeff8629da3999a</a></td></tr></tbody></table>

### **Lending & Withdrawing methods**

<table><thead><tr><th width="227">Method</th><th>Notes</th></tr></thead><tbody><tr><td><h4><code>join(uint256 amount)</code></h4></td><td>Lends a certain amount of underlying tokens to the portfolio, and mints and transfers corresponding amount of ERC-20 lending pool ("LP") tokens to the lender.</td></tr><tr><td><h4><code>liquidExit(uint256 amount)</code></h4></td><td><p>Withdraws liquidity from the lending pool. Lender transfers pool tokens to pool and receives underlying token, but with a small penalty for liquidity as calculated by</p><p><code>liquidExitPenalty()</code> described below.</p></td></tr></tbody></table>

### **Determining pool values**

#### Calculating LP token price

To calculate the price of the lending pool token ("LP token"), take `poolValue()` divided by `totalSupply()` .

#### Calculating pool APY

To calculate yield for a pool, one must calculate the weighted average of rates across each active loan in the pool and idle funds held in the pool.

`pool_apy = SUM(loan_1_amount`\*`loan_1_apy + ... + loan_n_amount*loan_n_value) / poolValue()`

For an example of how this can be done via SQL, see [this Dune query](https://dune.com/queries/1325629).

<table><thead><tr><th width="235">Method</th><th>Notes</th></tr></thead><tbody><tr><td><h4><code>poolValue()</code></h4></td><td><p>Returns pool value in underlying token.</p><p>This is the virtual price of the entire pool, including values for loan tokens and liquid underlying tokens held by the pool.</p><p><em>Note: this assumes defaulted loans are worth their full value.</em></p></td></tr><tr><td><h4><code>liquidValue()</code></h4></td><td>Returns virtual value of liquid assets in the pool.</td></tr><tr><td><strong><code>totalSupply()</code></strong></td><td>Returns total number of pool LP tokens.</td></tr><tr><td><strong><code>liquidRatio()</code></strong></td><td>Ratio of liquid assets in the pool to the pool value, in basis points. For example, 4683 => 46.83%.</td></tr><tr><td><strong><code>utilization()</code></strong></td><td><p>Returns utilization in basis points. For example, 5316 => 53.16%.</p><p>Calculated as <code>1 - liquidRatio()</code>.</p></td></tr><tr><td><h4><code>liquidExitPenalty( uint256 amount )</code></h4></td><td><p>Calculates lender will pay to withdraw liquid funds from the pool. This returns a proportion to be applied if <code>liquidExit()</code> is performed with the given amount of LP tokens.</p><p>For example, when a pool is at ~75% utilization a small withdrawal would return <code>liquidExitPenalty</code> = ~0.9980, meaning that the lender would pay an exit penalty of ~0.20% (20 bps) to withdraw from the pool.</p><p>For more detail on liquid exit and how the penalty is calculated, see <a href="/pages/-MQDBhiIJ2VHHGRglR85#what-is-liquid-exit">here</a>.</p></td></tr><tr><td><strong><code>averageExitPenalty(uint256 from, uint256 to)</code></strong></td><td>Internal function for calculating exit penalty.</td></tr></tbody></table>

### **Default handling**

Read more about default handling in [SAFU (Secure Asset Fund for Users)](/brila-protocol/other-concepts/legacy-dao-pools/pool/safu-secure-asset-fund-for-users#safu-default-handling)

<table><thead><tr><th width="312">Method</th><th>Notes</th></tr></thead><tbody><tr><td><h4><strong><code>liquidate(</code></strong><code>ILoanToken2 loan)</code></h4></td><td>Calls SAFU function to liquidate bad debt. Liquidates a defaulted Loan, withdraws a portion of TRU from staking pool then tries to cover the loan with own funds, to compensate lending pool. Loan must be in <code>defaulted</code> state. If SAFU does not have enough funds, deficit is saved to be redeemed later.</td></tr><tr><td><strong><code>reclaimDeficit(ILoanToken2 loan, uint256 amount)</code></strong></td><td>After a defaulted loan's debt has been redeemed by the <a href="/pages/-MhNd7uchx-T7X8vI1c3#safu-default-handling">SAFU</a>, the lending pool can reclaim call this function to redeem "deficiency claim" tokens for underlying tokens held in the SAFU.</td></tr></tbody></table>

## TrueLender2 contract

Implements the lending strategy for the TrueFi pool, i.e. how loans are approved and funded.

<table><thead><tr><th width="216">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>TrueLender2</td><td><a href="https://etherscan.io/address/0xa606dd423dF7dFb65Efe14ab66f5fDEBf62FF583">0xa606dd423dF7dFb65Efe14ab66f5fDEBf62FF583</a></td></tr></tbody></table>

<table><thead><tr><th width="312">Method</th><th>Notes</th></tr></thead><tbody><tr><td><h4><code>fund()</code></h4></td><td>When called, sends funds from the pool to the loan token contract. Pool receives and holds loan tokens. Must be called by the loan borrower.</td></tr><tr><td><strong><code>loanIsCredible(uint256 yesVotes, uint256 noVotes)</code></strong></td><td>Checks whether loan receives sufficient votes via <a href="/pages/-MTtub3T5anZRR1hXJck">stkTRU rating</a> to be funded. Checks whether loan receives minimum ratio of yes to no votes and hits threshold of minimum votes set by owner.</td></tr><tr><td><strong><code>reclaim(ILoanToken2 loanToken, bytes calldata data)</code></strong></td><td>Redeems LoanTokens held by the pool for underlying funds held in the loan token. Loan token must be settled before calling this function.</td></tr><tr><td><strong><code>reclaimDeficit(ILoanToken2 loan, uint256 amount)</code></strong></td><td>After a defaulted loan's debt has been redeemed by the <a href="/pages/-MhNd7uchx-T7X8vI1c3#safu-default-handling">SAFU</a>, the lending pool can reclaim call this function to redeem "deficiency claim" tokens for underlying tokens held in the SAFU.</td></tr></tbody></table>

## Loan Token contracts <a href="#what-are-loan-tokens" id="what-are-loan-tokens"></a>

Loan tokens are created by [LoanFactory2](https://etherscan.io/address/0x69d844fB5928d0e7Bc530cC6325A88e53d6685BC).

<table><thead><tr><th width="216">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>LoanFactory2</td><td><a href="https://etherscan.io/address/0x69d844fB5928d0e7Bc530cC6325A88e53d6685BC">0x69d844fB5928d0e7Bc530cC6325A88e53d6685BC</a></td></tr></tbody></table>

Each LoanToken has the following parameters:

* `borrower()`: address of borrower
* `amount()`: principal amount of fixed term loan
* `term()`: loan term in seconds
* `apy()`: loan APR in basis points (i.e. 971 = 9.71%)
* `status()`: returns loan's status, which progresses through the following states:
  * `0` --> `Awaiting:` Waiting for funding to meet capital requirements
  * `1` -->`Funded:` Capital requirements met, borrower can withdraw
  * `2` -->`Withdrawn:` Borrower withdraws money, loan waiting to be repaid
  * `3` -->`Settled:` Loan has been paid back in full with interest
  * `4` -->`Defaulted:` Loan has not been paid back in full
  * `5` -->`Liquidated:` Loan has Defaulted and stakers have been Liquidated
* `canTransfer()`: returns LoanTokens are non-transferable except for whitelisted addresses
* `debt()`: returns `amount` + `interest`. Note that this does not take into account whether the loan has been repaid.
* `isRepaid()`: returns boolean value, indicating whether a loan has been repaid in full.
* `profit()`: returns difference between `debt()` and `amount()`, the anticipated interest to be paid on the loan<br>

<table><thead><tr><th width="312">Method</th><th>Notes</th></tr></thead><tbody><tr><td><strong><code>fund()</code></strong></td><td>Transfers tokens to loan token contract from pool. Can be called only by lender contract. Sets status to Funded, start time, lender.</td></tr><tr><td><strong><code>withdraw(address _beneficiary)</code></strong></td><td>Borrower calls this function to withdraw funds to address provided. This sets the status of the loan to <code>Withdrawn</code>.</td></tr><tr><td><strong><code>repayInFull(address _sender)</code></strong></td><td>Function for borrower to repay all of the remaining loan balance. Borrower should use this to ensure full repayment.</td></tr><tr><td><strong><code>_repay(address _sender, uint256 _amount)</code></strong></td><td>Internal function for loan repayment. If <code>_amount</code> is sufficient, then this also settles the loan.</td></tr><tr><td><strong><code>settle()</code></strong></td><td>Moves loan to status = 'settled' if loan is fully repaid.</td></tr><tr><td><strong><code>reclaim()</code></strong></td><td>Function for borrower to reclaim any underlying currency stuck in the loan token contract. Only the borrower can call this function after the loan has been settled, defaulted, or liquidated.</td></tr></tbody></table>

Repaying loans to lending pools has two steps:

1. Borrower repays funds to loan token
2. `reclaim()` function is called on loan token, which burns the loan token and pays out fees to stkTRU.

## TrueRatingAgencyV2

As described [here](/brila-protocol/other-concepts/legacy-dao-pools/loan-approval-process), the `TrueRatingAgencyV2` contract determines whether a loan request should be funded by `TrueLender2`.

<table><thead><tr><th width="231">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>TrueRatingAgencyV2</td><td><a href="https://etherscan.io/address/0x05461334340568075bE35438b221A3a0D261Fb6b">0x05461334340568075bE35438b221A3a0D261Fb6b</a></td></tr></tbody></table>

stkTRU holders can vote `yes()` or `no()` on each loan. The `TrueLender2` contract then checks to see if each loan satisfies threshold conditions in order to be funded.

stkTRU voters receive rewards in the form of TRU tokens for voting on loan requests. `claimable()` reward tokens are calculated as follows:

`claimable() = (# TRU voted by user / # total TRU votes) * (Total TRU Reward)`, where

* `Total TRU Reward = (Loan interest * TRU distribution factor * rewardMultiplier)`
  * where `Loan interest = (loan APR * term in days * principal) /365`. Loan APR, term, and principal can be obtained from the respective loan token contract
  * `rewardMultiplier` can be found from the [TrueRatingAgencyV2](https://etherscan.io/address/0x05461334340568075bE35438b221A3a0D261Fb6b#readProxyContract#F18) contract
  * `TRU distribution factor` is calculated as `remaining` divided by `amount` from the [RatingAgencyV2Distributor](https://etherscan.io/address/0x6151570934470214592AA051c28805cF4744BCA7#readProxyContract) contract

## **TrueMultiFarm**

As described [here](/brila-protocol/other-concepts/legacy-dao-pools/pool/farming-liquidity-mining), lenders can stake LP tokens into the TrueMultiFarm contract to get TRU rewards.

<table><thead><tr><th width="231">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>TrueMultiFarm</td><td><a href="https://etherscan.io/address/0xec6c3FD795D6e6f202825Ddb56E01b3c128b0b10#readProxyContract">0xec6c3FD795D6e6f202825Ddb56E01b3c128b0b10</a></td></tr><tr><td>LinearTrueDistributor</td><td><a href="https://etherscan.io/address/0xc7AB606e551bebD69f7611CdA1Fc473f8E5b8f70">0xc7AB606e551bebD69f7611CdA1Fc473f8E5b8f70</a></td></tr></tbody></table>

#### How to calculate lender emissions per day

* Total TRU emissions per day can be calculated using `totalAmount()` and `duration()` found on the [distributor contract](https://etherscan.io/address/0xc7AB606e551bebD69f7611CdA1Fc473f8E5b8f70):
  * `TRU distribution per day = (totalAmount/10^8) / (duration/(24*3600))`
* To calculate farm rates for each token, use the formula below:
  * `TRU rewards per farm per day = TRU distribution per day * getShare(IERC20 token) / shares()` as described below

<table><thead><tr><th width="312">Method</th><th>Notes</th></tr></thead><tbody><tr><td><strong><code>stake(IERC20 token, uint256 amount)</code></strong></td><td>Stake tokens to the farm. Upon staking, this will claim any claimable rewards.</td></tr><tr><td><strong><code>unstake(IERC20 token, uint256 amount)</code></strong></td><td>Remove staked tokens</td></tr><tr><td><strong><code>claim(IERC20[] calldata tokens)</code></strong></td><td>Claim TRU rewards</td></tr><tr><td><strong><code>exit(IERC20[] calldata tokens)</code></strong></td><td>Unstake amount and claim rewards</td></tr><tr><td><strong><code>claimable(IERC20 token, address account)</code></strong></td><td>Returns the claimable TRU reward for an account that is staking tokens.</td></tr><tr><td><strong><code>shares()</code></strong></td><td>Returns denominator for total farm rewards rate</td></tr><tr><td><strong><code>getShare(IERC20 token)</code></strong></td><td>Returns numerator for LP token's share of farm rewards</td></tr></tbody></table>


# Other legacy contracts


# Managed Portfolio \[legacy]

{% hint style="warning" %}
`ManagedPortfolio` is in the process of being sunset.

New TrueFi Capital Markets portfolios deployed after June 2022 use contract[`FlexiblePortfolio`](/brila-protocol/other-concepts/other-legacy-contracts/flexible-portfolios-legacy/flexible-portfolio-contracts)
{% endhint %}

`ManagedPortfolio` represents a portfolio of BulletLoans. Lenders put funds into the portfolio, the manager uses funds to issue loans to borrowers, and borrowers repay principal and interest back into the portfolio. `ManagedPortfolio` issues ERC-20 Liquidity Provider tokens to lenders in proportion to the amount they lend. These tokens represent a lender's share of the funds in the pool, including the interest accumulated from loans repaid by borrowers.

{% embed url="<https://github.com/trusttoken/contracts-ragnarok/blob/main/contracts/ragnarok/ManagedPortfolio.sol>" %}

All of the portfolio operations are up to the manager's discretion. The Portfolio Manager makes decisions about issuing new loans, marking them as defaulted, altering portfolio params and so on. Manager also specifies an `ILenderVerifier` contract that is responsible for handling the permissions to join the portfolio (portfolios might be permissionless, but typically are not and only offer entrance to a defined group of lenders).

Portfolio tokens represent lenders' share in the pooled funds. Lenders put funds into the portfolio if they trust the manager is going to abide by a reasonable policy. Funds from the portfolio are only available for withdrawal after the portfolio's close date.

### **Methods**​

| Method                                                                                                                             | Notes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| ---------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <h4><code>deposit(uint256 depositAmount, bytes memory metadata)</code></h4>                                                        | Lends a certain amount of underlying tokens to the portfolio. If the portfolio has lender restrictions enabled, this function requires metadata to validate the lender’s address is allowed to lend.                                                                                                                                                                                                                                                                                                                                                                                                              |
| <h4><code>withdraw(uint256 sharesAmount, bytes memory)</code></h4>                                                                 | After the portfolio’s close date, lender can withdraw funds, i.e. redeeming the portfolio token for underlying pool tokens.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| <h4><code>createBulletLoan( uint256 loanDuration, address borrower, uint256 principalAmount, uint256 repaymentAmount )</code></h4> | Creates bullet loan token using BulletLoans contract.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| <h4><code>markLoanAsDefaulted(uint256 instrumentId)</code></h4>                                                                    | Only the portfolio’s manager can mark a loan as defaulted.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| <h4><code>markLoanAsResolved(uint256 instrumentId)</code></h4>                                                                     | Only the portfolio’s manager can mark a loan as resolved. Intended to be used for situations after partial repayment where a loan workout has been agreed to.                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| <h4><code>setEndDate(uint256 newEndDate)</code></h4>                                                                               | Manager can change portfolio’s close date, or `EndDate`. Note that the portfolio’s close date can only be decreased. Close date can NOT be moved further into the future, nor can it be decreased to a date earlier than any active loan’s maturity date.                                                                                                                                                                                                                                                                                                                                                         |
| <h4><code>setLenderVerifier(ILenderVerifier \_lenderVerifier)</code></h4>                                                          | <p>Manager can set the lender verifier contract to enforce lender restrictions. Manager can leverage three different types of restrictions:</p><ul><li><em>Whitelist:</em> contract that implements simple, universal whitelist.</li><li><em>WhitelistLenderVerifier:</em> contract that implements a unique whitelist for each of the portfolios, which are using this verifier. Managers of particular portfolios have the authority to manage respective whitelists.</li><li><em>SignatureOnlyLenderVerifier:</em> contract that requires the lender to provide a signature of a predefined message.</li></ul> |
| <h4><code>setManagerFee(uint256 \_managerFee)</code></h4>                                                                          | Manager can set the portfolio fee, or managerFee, in basis points. Portfolio fee is charged on deployed capital                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| <h4><code>setMaxSize(uint256 \_maxSize)</code></h4>                                                                                | Manager sets a cap, or `maxSize`, for a portfolio. Lenders can not put more funds into the portfolio if it would cause the total principal amount lent into the portfolio to exceed the `maxSize`.                                                                                                                                                                                                                                                                                                                                                                                                                |
| <h4><code>updateLoanParameters( uint256 instrumentId, uint256 newTotalDebt, uint256 newRepaymentDate )</code></h4>                 | Manager can modify loan terms, changing maturity date or total debt to be repaid. In order to change the maturity date to an earlier date or increase the repayment value, the borrower must consent and provide a signature.                                                                                                                                                                                                                                                                                                                                                                                     |

**View Methods**

| Method                                                | Notes                                                                                                                                                                            |
| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <h4><code>getStatus()</code></h4>                     | Returns status of the portfolio. If current date is past the portfolio’s close date, will return ‘Closed’. If portfolio holds defaulted loans, will return ‘Frozen’.             |
| <h4><code>getAmountToMint(uint256 amount)</code></h4> | Returns the amount of portfolio tokens that would be minted for a given amount of tokens to be lent (e.g. if 1000 USDC are lent, 995 tfExamplePortfolio tokens would be minted). |
| **`getOpenLoanIds()`**                                | Returns list of open loan tokens.                                                                                                                                                |
| **`illiquidValue()`**                                 | Returns estimated value of active, illiquid loans. Calculated on straight-line basis.                                                                                            |
| <h4><code>liquidValue()</code></h4>                   | Returns balance of idle underlying tokens held by portfolio.                                                                                                                     |
| **`value()`**                                         | Returns total estimated value of portfolio (`liquidValue` + `illiquidValue`).                                                                                                    |

### Typical Flows 🌊

Below are examples of typical flows in TrueFi Capital Markets pools:

* `Manager` creates `ManagedPortfolio` using `ManagedPortfolioFactory`.
* `Lender` lends funds into the `ManagedPortfolio`.
* `Manager` issues a `BulletLoans` token to the `ManagedPortfolio` (portfolio sends funds to the `Borrower`).
* `Borrower` repays `BulletLoans` an owed amount (`BulletLoans` will send funds to the debt owner - in this case the `ManagedPortfolio`).
* `Lender` withdraws funds from the `ManagedPortfolio`.

Additional actions that might happen:

* `Manager` can change loan parameters (with a `Borrower`'s approval if necessary).
* `Manager` can set loan status to `Defaulted` if `Borrower` does not return funds on time (and eventually set loan status to `Resolved` once the debt is settled).
* `Manager` can change various `ManagedPortfolio` properties.

### [BulletLoans](/brila-protocol/other-concepts/instruments/bulletloans)

BulletLoans is an ERC-721 contract. Each of the tokens represents a single loan. All the loan parameters can be read from LoanMetadata struct. BulletLoans contract enables loan creation, facilitates loan repayment and allows managing the loan's state and parameters.

### [ManagedPortfolio](/brila-protocol/other-concepts/other-legacy-contracts/managed-portfolio-legacy)

ManagedPortfolio is an ERC-20 token facilitates funds management and allows loan issuance. Portfolio tokens represent lenders' share in the pooled funds. All of the portfolio operations are up to the managers discretion. Manager makes the decisions about issuing new loans, marking them as defaulted, altering portfolios params and so on. Lenders only lend funds into the portfolio if they trust the manager is going to abide by a reasonable policy. Manager also specifies an ILenderVerifier contract that is responsible for handling the permissions to join the portfolio (portfolios might be permissionless, but typically are not and only offer entrance to a defined group of lenders). Funds from the portfolio are only available for the withdrawal after the final closing date.

### ManagedPortfolioFactory

Contract that allows easy portfolio configuration and creation. A particular instance of the factory can only be accessed by whitelisted addresses.

### ProtocolConfig

Contract holding key system params.

### BorrowerSignatureVerifier

A contract that verifies borrower's consent to change the loan parameters. Manager can freely change the loan parameters in borrower's favour (reduce owned amount, increase time), but needs an explicit, borrower's approval to do the opposite.

### ILenderVerifier

#### Whitelist

A contract that implements simple, universal whitelist.

#### WhitelistLenderVerifier

A contract that implements a unique whitelist for each of the portfolios, which are using this verifier. Managers of particular portfolios have the authority to manage respective whitelists.

#### SignatureOnlyLenderVerifier

A contract that requires lender to provide a signature of a predefined message.


# Flexible Portfolios \[legacy]

Configurable lending pools governed by 3rd party PMs

{% hint style="info" %}
For technical docs, see [Flexible Portfolio contracts](/brila-protocol/other-concepts/other-legacy-contracts/flexible-portfolios-legacy/flexible-portfolio-contracts)
{% endhint %}

**Flexible Portfolios** are configurable lending pools run by independent managers on TrueFi infrastructure. [Portfolio Managers ("PMs")](broken://pages/Ar3hMBb8gIk5o6COI8H7) have discretion over loan terms, as well as other items such as the pool's maximum size, maturity date, and lender access/restrictions.

Portfolios can serve real world financing borrowers and use cases, as covered by PYMNTS [here](https://www.pymnts.com/loans/2022/mexican-fintech-uses-defi-to-provide-collateral-free-loans-to-small-businesses/), as well as crypto-focused borrowers (institutions, DAOs, etc., as covered by Bloomberg [here](https://www.bloomberg.com/news/articles/2022-02-24/one-of-biggest-crypto-traders-is-tapping-defi-loans-for-funding)).

<figure><img src="/files/5ZEk4MtOASa0ACkjoiNu" alt=""><figcaption><p>Portfolio on TrueFi</p></figcaption></figure>

### Who can lend to portfolios on TrueFi?

Portfolio managers define who can lend into each portfolio (i.e. whether portfolios are permissioned or permissionless).

For [permissioned portfolios](/user-guide/manage/managing-kyc-kyb-requirements), lenders can gain access to the portfolio by completing onboarding per the manager's instruction (ex. completing KYC process directed by the portfolio manager).

### How are portfolios managed?

[Portfolio Managers (PMs)](broken://pages/Ar3hMBb8gIk5o6COI8H7) make decisions on underwriting loans, managing relationships with borrowers, and configuring portfolios. Lenders are responsible for conducting diligence on PMs and portfolios before lending.

### When can lenders withdraw?

Lenders can [withdraw](broken://pages/5CJqcD2A4QIo9dR74kN0) funds only after the portfolio's maturity date. Funds are locked up in the portfolio until the portfolio’s maturity is reached.

### Can lenders transfer portfolio tokens?

No, portfolio tokens are non-transferrable by default.

Managers can enable transfers if desired.

### **What are the fees on portfolios?**

Portfolios pay a protocol fee per annum to the TrueFi DAO treasury. Fees accrue block-by-block and are paid upon each smart contract interaction (lend/withdraw/disburse loan/repay loan).

The example below illustrates how the protocol fee works:

{% hint style="info" %}
**Protocol Fee example**

Take an example portfolio *Verum Fund,* which holds 1,000,000 USDC worth of loans and assume protocol fee = 50 bps per annum (0.50%).

Assuming the value of Verum Fund grows linearly from 1,000,000 USDC to 1,100,000 USDC over the course of 30 days (avg. value of 1,050,000 USDC), the portfolio would pay a protocol fee of 431.51 USDC for this time period:

`Protocol fee = 1,050,000 USDC * 0.50% * (30/365) = 431.51 USDC`
{% endhint %}

Additionally, PMs can set an optional Portfolio Fee. Portfolio Fees are paid to the PM, and can be configured such that they are accrued linearly over time, or paid as a flat fee at time of deposit and/or withdrawal.


# Flexible Portfolio contracts

**`FlexiblePortfolio`** is a contract that serves as a portfolio of funds managed by the portfolio manager.

`FlexiblePortfolio` allows the portfolio manager to define allowed debt instruments that the portfolio will handle. This is the latest iteration of the previous portfolio contract version (called `ManagedPortfolio`).

<table><thead><tr><th width="260">Contract Name</th><th>Address</th></tr></thead><tbody><tr><td>FlexiblePortfolio</td><td><a href="https://etherscan.io/address/0x5c6b0d8070ddc0a6a85c460819c3a91c628070ec">0x5c6b0d8070ddc0a6a85c460819c3a91c628070ec</a></td></tr><tr><td>FlexiblePortfolioFactory</td><td><a href="https://etherscan.io/address/0x122d3ba54975bdeb7579938fb0ffc54f8baefd2a#readProxyContract">0x122d3ba54975bdeb7579938fb0ffc54f8baefd2a</a></td></tr></tbody></table>

{% embed url="<https://github.com/trusttoken/contracts-helium>" %}

`FlexiblePortfolio` satisfies [ERC-4626](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/) requirements, meaning it meets all features described [here](https://eips.ethereum.org/EIPS/eip-4626).

`FlexiblePortfolio` supports loans that yield both principal and interest amounts on repayments. That is, the principal amount goes straight to portfolio liquid funds and can be withdrawn/lent at any moment. Interest is split between all lenders proportionally to the amount of portfolio tokens they hold. This implies that if the tokens are held in a contract (e.g. Uniswap pool), the interest will be frozen in the portfolio.

### Valuation

`FlexiblePortfolio` valuation is handled by the `ValuationStrategy`, which is a contract that holds information on all the loans the portfolio holds and can evaluate them properly. This requires the portfolio to call `onInstrumentFunded` when a loan is funded and `onInstrumentUpdated` when a loan might change its status (e.g. is repaid or gets defaulted). Valuation strategies cannot be switched as they hold the state of the portfolio loans.

### Fees

Whenever an action that changes `FlexiblePortfolio` value is performed (`fundInstrument`/`repay`/`deposit`/`mint`/`withdraw`/`redeem`/`updateAndPayFee`), a fee for the TrueFi DAO is calculated and immediately transferred to the TrueFi DAO Treasury address. The fee is deducted from the `FlexiblePortfolio` value, so actions like borrow/withdraw/redeem cannot move the funds that are designated as fees. If the accrued fee cannot be repaid at the moment because of the lack of liquidity, additional information about the fee amount is stored in the contract and will be used to make the overdue payment the moment it will be possible. The same behavior is followed by the fee of the manager.

The `protocolAccruedFee` value is equal to:

`(current_timestamp - last_update_timestamp) / YEAR * protocol_fee_rate * portfolio_value`

The `managerAccruedFee` value is equal to:

`(current_timestamp - last_update_timestamp) / YEAR * manager_fee_rate * portfolio_value`

\*\*`protocol_fee_rate` is the rate taken from the Protocol Config contract the last time an update was made. The same goes for `manager_fee_rate`, which is taken from Fee Strategy

### Deposit / Withdrawal Strategies

Functions enabling Lenders to deposit/withdraw funds to/from the contract can additionally be limited by Deposit/Withdraw Strategy. These strategies (if set), are called with a hook every time a specific action is performed on the contract. The same calldata as for the initial call is passed to them, and then the strategy independently decides if this action can or cannot be performed. The strategies might also write some state to themselves on such hooks, but this is not a mandatory behavior. Additionally, these hooks can return a fee that would be applied for the action that is being performed. The fees are calculated independently by the strategy and have to be returned as absolute values and always in assets(not shares).

Here we present a few examples to better understand this process:

* `deposit(assets: 100)` is being called, the strategy `onDeposit()` returns `(true, fee: 10).` This means that 10 would be transferred to the manager, and the shares would be minted to the Lender based on the remaining 90.
* `mint(shares: 100)` is being called, the strategy `onMint()` returns `(true, fee: 10)`

Let’s assume shares:assets are 1:1. 100 has to be transferred to the portfolio and 10 to the manager to satisfy the fee and the Lender’s desire to have 100 shares minted. We calculate the fees for withdraw/redeem the same way.

### FlexiblePortfolioFactory

This contract serves for deploying a new Flexible Portfolio. All of the `FlexiblePortfolio` parameters are chosen by the portfolio manager, except for `ProtocolConfig`.


# Audits

* Asset Vault: <https://github.com/TrueFi-Protocol/contracts-fluorine/tree/main/audits>
* Credit Vaults: <https://github.com/TrueFi-Protocol/contracts-carbon/tree/main/audits>
* Lines of Credit: <https://github.com/g0-group/Audits/blob/master/TrueFiDec2022.pdf>


# Overview

Brila DAT user guides, explanations, contract reference, and deployment details

Brila DAT (`$DAT`) is an **elastic-supply token on HyperEVM that targets a price of $1.00**. It is *not* collateralised like a typical stablecoin: instead, the protocol expands and contracts every holder's balance ("rebases") to push DAT's market price back toward $1, and harvests the USD appreciation of its HYPE liquidity into a treasury along the way.

If you are new here, start with the [first-position guide](/brila-dat/how-to/first-position). If you know what you want, jump to a section below.

## How this documentation is organised

This documentation follows the [Diátaxis](https://diataxis.fr/) framework — four kinds of material, each serving a different need. They are kept deliberately separate.

| If you want to…                     | Go to                                                   | These are                                                                       |
| ----------------------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------- |
| **Learn** by doing, start to finish | [First position](/brila-dat/how-to/first-position)      | A guided first experience with DAT.                                             |
| **Accomplish a specific task**      | [How-to guides](/brila-dat/how-to/provide-and-stake-lp) | Recipes for users and LPs. (Operator runbooks live in the protocol repository.) |
| **Look up exact facts**             | [Reference](/brila-dat/reference/contracts)             | Contracts, parameters, addresses — dry and precise.                             |
| **Understand how & why**            | [Explanation](/brila-dat/explanation/elastic-supply)    | The peg, rebasing, liquidity strategy, governance.                              |

## The one-paragraph mental model

You hold DAT. During twice-daily windows, a keeper can trigger a **rebase**: the protocol reads DAT's price in USD (the DAT/WHYPE pool's time-weighted price, multiplied by a WHYPE→USD oracle), and if that price is outside a ±5% band around $1.00, it changes *everyone's* balance proportionally to nudge the price back. Above peg, balances grow; below peg, they shrink. Scaling-factor changes are proportional; positive-rebase treasury mints can dilute holders' percentage ownership. See [Elastic supply](/brila-dat/explanation/elastic-supply).

> **Status:** the production peg mode is **USD ($1.00)**. The codebase also supports a RATIO mode (1 DAT ≈ 1 reserve token); these guides describe the USD-mode launch. The peg mode is fixed immutably at deployment.


# User guide

Practical guides for using Brila DAT

Practical guides for acquiring DAT, understanding your balance, and providing liquidity.

* [Open your first DAT position](/brila-dat/how-to/first-position)
* [Provide liquidity and stake LP](/brila-dat/how-to/provide-and-stake-lp)
* [Read your rebasing balance](/brila-dat/how-to/read-your-rebasing-balance)


# Open your first DAT position

This guide walks you from holding HYPE to holding DAT and observing how rebasing affects its displayed balance. The [explanation pages](/brila-dat/explanation/elastic-supply) cover the mechanics in depth.

> You will need: a wallet (MetaMask/Rabby/OKX) with **HyperEVM** added (chain `999`, RPC `https://rpc.hyperliquid.xyz/evm`), and a small amount of **HYPE** for gas and to buy with.

## 1. Add HyperEVM and connect

Add the HyperEVM network to your wallet using the details above, then open the [DAT app](https://dat.brila.finance) and click **Connect**. You should see the network indicator show **HYPEREVM** and your address appear.

## 2. Acquire some DAT

On the dashboard, select **Ape In** to open the Swap page. Swap an amount of HYPE appropriate for you into DAT. Review the quote and transaction before confirming. When the swap confirms, return to the Dashboard; **Your Bag** shows your DAT balance.

You now hold DAT. Notice it's a normal token in your wallet — it just behaves differently at rebase time, which you'll see next.

## 3. Read your two balances

Look at two numbers:

* **Your Bag** (the big number) — this is `balanceOf`, what changes on a rebase.
* **Underlying** — this is `balanceOfInternal`, your rebase-invariant internal balance.

Write both down. If a later rebase changes the scaling factor, the first changes while the second does not. A treasury mint can still dilute your percentage ownership by increasing total internal supply. See [Elastic supply](/brila-dat/explanation/elastic-supply).

## 4. Watch a rebase

The dashboard shows **Next Rebase In**. With current defaults, one-hour execution windows begin at 08:00 and 20:00 UTC. Opening a window does not guarantee a rebase transaction; an allowlisted keeper must commit and reveal.

After a successful reveal:

* If the protocol price is outside the ±5% deadband, the **DAT Scaling Factor** changes.
* **Your Bag** changes with it: up above the upper boundary, down below the lower boundary.
* Inside the deadband, the epoch advances but the scaling factor and your balance do not change.
* Your **Underlying** is unchanged.

That is a rebase attempt: the protocol measures its TWAP-based USD signal and, when outside the deadband, resizes existing balances to create pressure toward **$1.00**.

## 5. (Optional) Put your DAT to work

To earn DAT rewards, provide DAT/WHYPE liquidity and stake the LP token in the genesis farm. That's a task in its own right — follow [Provide and stake LP](/brila-dat/how-to/provide-and-stake-lp).

## What you learned

You acquired DAT and compared the displayed balance with its internal-unit basis. Next, read [The peg](/brila-dat/explanation/the-peg) to understand what a rebase responds to.


# Provide liquidity and stake LP

Goal: create DAT/WHYPE LP tokens and stake them in `BrilaDATIncentivizer` to earn DAT rewards. Addresses are listed in [Networks & addresses](/brila-dat/reference/addresses).

## 1. Create DAT/WHYPE LP tokens

### App: zap one asset into LP

In the [DAT app](https://dat.brila.finance):

1. Connect on HyperEVM and open **Farms**.
2. In **Zap into LP**, choose HYPE, WHYPE, or DAT and enter an amount.
3. Review estimated LP output and the slippage floor.
4. Approve the input token when requested, then confirm the zap.

The ownerless `BrilaDATZap` swaps part of the input, adds liquidity directly to the DAT/WHYPE pair, sends LP tokens to your wallet, and returns token dust.

### DEX: provide both assets

Alternatively, acquire DAT and WHYPE in the pool's current value ratio, then add both to the existing DAT/WHYPE pool on Project X. Use the canonical pair—not only the factory address. You receive the pair's LP token.

## 2. Stake the LP token

In the app's **Farms** page, enter the LP amount and select **Stake**. The first transaction approves the incentivizer; the next stakes.

For direct contract interaction, amounts use 18 decimals:

```bash
LP_TOKEN=0x3E0B18bD621304Df40485428eCd20765cF692432
INCENTIVIZER=0x3e9E18f5944B2d95571d68b9e74627aa9dAb2cc0

# approve the incentivizer to pull your LP token
cast send $LP_TOKEN "approve(address,uint256)" $INCENTIVIZER <amount> \
  --rpc-url https://rpc.hyperliquid.xyz/evm --private-key $PK

# stake it
cast send $INCENTIVIZER "stake(uint256)" <amount> \
  --rpc-url https://rpc.hyperliquid.xyz/evm --private-key $PK
```

Never expose a production private key in shell history or shared logs; use a secure signer where possible.

## 3. Read and claim rewards

```bash
cast call $INCENTIVIZER "earned(address)(uint256)" $YOU --rpc-url https://rpc.hyperliquid.xyz/evm
cast send $INCENTIVIZER "getReward()" --rpc-url https://rpc.hyperliquid.xyz/evm --private-key $PK
```

`earned()` returns pre-scaling reward units. `getReward()` transfers:

```
earned(you) × current brilaDatScalingFactor / 1e18
```

The app applies this scaling when displaying earned DAT.

To withdraw your entire nonzero stake and claim in one transaction:

```bash
cast send $INCENTIVIZER "exit()" --rpc-url https://rpc.hyperliquid.xyz/evm --private-key $PK
```

## Things to know

* After a reward period ends, the next `stake` or `getReward` triggers the halving rollover. It is not automatic at the period-end timestamp.
* The incentivizer must retain the token's minting role for rollover to succeed.
* You are a liquidity provider: you carry **impermanent-loss** exposure on the DAT/WHYPE pair in addition to the DAT rewards.
* This is the only deployed farm; see [Liquidity strategy](/brila-dat/explanation/liquidity-strategy) for why.


# Read your rebasing balance

Goal: know your true position when the displayed balance moves every rebase. This assumes you already hold DAT.

## See your two balances

```bash
# display balance (fragments, 18 dec) — changes every rebase
cast call $DAT "balanceOf(address)(uint256)" $YOU --rpc-url https://rpc.hyperliquid.xyz/evm

# internal balance (1e24 precision) — unchanged by scaling-factor rebases
cast call $DAT "balanceOfInternal(address)(uint256)" $YOU --rpc-url https://rpc.hyperliquid.xyz/evm

# total internal supply
cast call $DAT "initSupply()(uint256)" --rpc-url https://rpc.hyperliquid.xyz/evm
```

* **`balanceOf`** is what wallets and the app show. It is `underlying × brilaDatScalingFactor / 1e24`.
* **`balanceOfInternal`** isolates transfers and rewards from scaling-factor changes.
* Your ownership fraction is approximately `balanceOfInternal(you) / initSupply`. A treasury mint increases `initSupply` and can dilute that fraction even though your internal balance is unchanged.

## Check whether your share actually grew

To verify that a transfer or farm claim increased your position, compare `balanceOfInternal` before and after it. A scaling-factor-only rebase leaves this value unchanged.

## Estimate USD value

In USD mode the protocol targets **$1.00 per DAT**, so a quick estimate is:

```
USD value ≈ balanceOf(you) / 1e18   ×   $1.00
```

For the rebaser's current TWAP-based signal, call `getCurrentExchangeRate()` and divide by `1e18` for USD per DAT:

```bash
cast call $REBASER "getCurrentExchangeRate()(uint256)" --rpc-url https://rpc.hyperliquid.xyz/evm
```

This is not a spot-market quote. The view uses the primary reserve/USD feed and can return zero when no time has elapsed since the last TWAP sample. The actual USD-mode rebase path additionally checks the mandatory secondary reserve/USD feed.

## See rebase history

Each rebase increments `epoch` and emits `RebaseExecuted(epoch, exchangeRate, targetRate, supplyDelta, timestampSec)` (USD mode also emits `UsdPegPriceComputed`). Query those events, or read the current `epoch` and `brilaDatScalingFactor`:

```bash
cast call $REBASER "epoch()(uint256)" --rpc-url https://rpc.hyperliquid.xyz/evm
cast call $DAT     "brilaDatScalingFactor()(uint256)" --rpc-url https://rpc.hyperliquid.xyz/evm
```


# Explanation

How Brila DAT's elastic supply, peg, liquidity, and governance work

Conceptual guides to DAT's elastic supply, peg mechanism, liquidity strategy, and governance.

* [Elastic supply](/brila-dat/explanation/elastic-supply)
* [The peg](/brila-dat/explanation/the-peg)
* [Liquidity strategy](/brila-dat/explanation/liquidity-strategy)
* [Governance and security](/brila-dat/explanation/governance-and-security)


# Elastic supply

This page explains what it *means* to hold a rebasing token, so the balance changes you see don't surprise you. For the exact formulas and bounds, see the [token reference](/brila-dat/reference/contracts); for *why* the protocol rebases at all, see [The peg](/brila-dat/explanation/the-peg).

## Your balance is a view, not a ledger entry

Most ERC-20s store your displayed balance directly. DAT instead stores **internal units** at `1e24` precision. Your internal balance changes when DAT is transferred or minted to or from you. Your visible ERC-20 balance is computed from that amount and a global scaling factor:

```
balanceOf(you) = balanceOfInternal(you) × brilaDatScalingFactor / 1e24
```

At genesis the scaling factor is `1e18`. A rebase multiplies it, changing `balanceOf` for every holder at once without a transfer or a change to their internal balance.

## What a rebase changes — and what it doesn't

A scaling-factor change is **proportional**: it moves every existing balance by the same ratio. Negative rebases only change the scaling factor. On a positive rebase, the rebaser first calculates the damped rebase delta, then diverts `rebaseMintPerc` of that delta (10% by default) to a separate treasury mint. The remaining delta changes the scaling factor. That mint increases `initSupply` and therefore dilutes existing holders' percentage ownership.

* **Positive rebase** (price above peg): the scaling factor goes up; your balance goes up.
* **Negative rebase** (price below peg): the scaling factor goes down; your balance goes down.

A positive rebase is not guaranteed profit, and a negative rebase is not by itself a targeted loss. The mechanism changes token quantity to create market pressure toward the peg; it does not guarantee the resulting market price or your USD value. Farm rewards can increase your internal balance. The [treasury harvest](/brila-dat/explanation/the-peg#the-dat-mechanism) accrues assets to the protocol treasury, not directly to individual holders.

## Two balances you can read

| Reading                                   | Function                 | Changes on a rebase?                   |
| ----------------------------------------- | ------------------------ | -------------------------------------- |
| Display balance (what wallets show)       | `balanceOf(you)`         | **Yes**, when the scaling factor moves |
| Internal balance (rebase-invariant units) | `balanceOfInternal(you)` | **No**                                 |

Internal units isolate transfers and rewards from scaling-factor changes. They are not, alone, your percentage ownership: positive-rebase treasury mints increase total internal supply (`initSupply`). For an approximate ownership fraction, compare `balanceOfInternal(you)` with `initSupply`. See [Read your rebasing balance](/brila-dat/how-to/read-your-rebasing-balance).

## Bounds

Rebases cannot run away. The scaling factor is capped above (`maxScalingFactor()`, which shrinks as supply grows) and floored below (`MIN_SCALING_FACTOR = 1e15`, i.e. 0.001×). A single rebase is also dampened — see `rebaseLag` in [The peg](/brila-dat/explanation/the-peg#why-rebases-are-gradual).


# The peg

DAT is launched in **USD peg mode**: the protocol's job is to keep DAT's market price near **$1.00**. This page explains how it measures that price and what it does about deviations. For exact parameter values and bounds, see the [parameters reference](/brila-dat/reference/parameters).

## The price signal

DAT trades in a Uniswap-V2-style pool against **WHYPE** (wrapped HYPE) — there is no direct DAT/USD market. So the protocol composes two measurements:

```
exchangeRate (USD per DAT) = TWAP(WHYPE per DAT) × (USD per WHYPE)
                             └─ from the pool ─┘   └─ from an oracle ─┘
```

* **`TWAP(WHYPE per DAT)`** — a 1-hour-minimum time-weighted average of the pool price. Using a TWAP (not the spot price) is the primary defense against someone manipulating a single block to force a rebase.
* **`USD per WHYPE`** — because this leg is on the critical path, it is **dual-sourced** from two native HyperCore price precompiles wrapped in Chainlink-style adapters: the **perp oracle price** (a validator-weighted median of external CEX prices) as primary, bracketed by **Hyperliquid's own spot-book price** as secondary — two independent data pipelines with zero third-party oracle dependencies. Every rebase checks the two agree within `maxOracleDeviation` (default 10%) or reverts.

The `$1.00` target itself is **immutable** in USD mode (`setTargetRate` reverts) — it was pinned at deployment and cannot be moved by the owner. (This was hardened as audit finding F20.)

## The deadband and rebase direction

The protocol does **not** rebase on every tiny wobble. It only acts when the price leaves a band around $1.00 set by `deviationThreshold` (default **±5%**):

| DAT price                | Action                                                   |
| ------------------------ | -------------------------------------------------------- |
| **$1.05 or higher**      | **positive rebase** — expand supply (and harvest, below) |
| above $0.95, below $1.05 | nothing — inside the deadband                            |
| **$0.95 or lower**       | **negative rebase** — contract supply                    |

Expanding supply adds sell-side pressure to push the price down toward $1; contracting does the reverse. See [Elastic supply](/brila-dat/explanation/elastic-supply) for what this does to your balance.

## Why rebases are gradual

A rebase never closes the whole gap at once. The off-peg percentage is divided by `rebaseLag` (default **10**) before it is applied. With default timing, execution is allowed at most once per 12-hour interval, during one-hour windows beginning at 08:00 and 20:00 UTC.

A 10% deviation therefore produces a 1% damped delta. On a negative rebase, the whole delta changes the scaling factor. On a positive rebase, `rebaseMintPerc` diverts 10% of that delta by default to the treasury mint path, leaving about 0.9% for the scaling-factor increase.

## The DAT mechanism

*Harvesting HYPE's upside into the treasury.*

This is the distinctive part of USD mode. Because DAT is **priced in WHYPE** but **pegged to USD**, anything that makes WHYPE worth more in dollars makes DAT read *above* $1 — even if DAT's value in WHYPE did not change. Outside the deadband this triggers a **positive rebase**. The protocol diverts `rebaseMintPerc` of the damped delta (10% by default) to a treasury mint budget. `maxSlippageFactor` controls how much of that budget is used in the DAT→WHYPE swap (90% by default); the balance is retained as DAT.

The intended effect is to accumulate WHYPE and DAT in the rebase treasury while the supply mechanism targets a dollar-denominated unit. The mechanism does not guarantee that DAT trades at $1 or that treasury assets accrue directly to token holders.

## Keeper controls: commit/reveal + oracle drift

Rebases are driven by allowlisted **keepers** through a two-step **commit/reveal** (25 blocks apart), where the commit binds the keeper, salt, and `minReserveOut`. In USD mode the commit also snapshots the primary reserve/USD price, and reveal reverts (`"oracle drift"`) if that price has moved more than `maxCommitRevealOracleDrift` (default 2%).

This prevents changing the floor after commit and limits timing discretion, but it does not validate that the committed floor is economically safe. A compromised keeper can commit a weak floor. It cannot redirect the swap output, which always goes to `treasuryAddress`.

## The liveness trade-off (read this)

The dual oracle and timelocks buy safety at a real cost: **both reserve/USD feeds are load-bearing — the secondary bracket read is mandatory in every USD-mode rebase — so a failure in either halts&#x20;*****all*****&#x20;rebases, including the owner's emergency `forceRebase`.** With the launch adapters, staleness cannot trigger (they report `updatedAt = block.timestamp`); the fail-stop conditions are a precompile call failure or an answer outside the adapter's absolute band — including the price *legitimately* exiting the band, in which case reads pause until governance rotates in re-centered adapters. Rotation is itself **timelocked 24h** (`ORACLE_ROTATION_DELAY`) so observers can react to a hostile rotation. Monitor both adapters as launch-critical infrastructure. This is the main availability risk of USD mode and it is deliberate — the protocol prefers to *stop* rebasing over rebasing on a bad price.


# Liquidity strategy

The peg can only be as stable as the liquidity behind it. A thin DAT/WHYPE pool means small trades move the price a lot, which forces frequent rebases; a deep pool absorbs flow and keeps DAT near $1. This page explains how the protocol bootstraps that depth and why it does so the way it does.

## One farm, by design: the LP incentivizer

The live deployment has one reward farm, `BrilaDATIncentivizer`:

* You provide **DAT/WHYPE liquidity** on the pool, receive the pool's LP token, and **stake the LP token** in the incentivizer.
* You earn **DAT** rewards on a **halving emission schedule**. After a period ends, the first `stake` or `getReward` interaction halves `initreward`, mints the next tranche, and starts a new period. The rollover is interaction-triggered, not an autonomous timed transaction.
* The farm must remain registered as the token's `incentivizer` to mint each new tranche. Removing that role makes a rollover revert.
* Because DAT itself rebases, the pool **scales reward accounting by the scaling factor at payout**, so `earned()` reports pre-scaling reward units while `getReward()` transfers scaled DAT fragments.

See [Provide and stake LP](/brila-dat/how-to/provide-and-stake-lp) for the steps.

## Why there is no single-sided "stake HYPE, earn DAT" farm

The repository still contains the generic `BrilaDATDistributionPool` implementation, which can distribute pre-funded DAT rewards for an arbitrary staking token and enforces a minimum block delay before claims. Its deployment address is zero on mainnet: it is **not a live farm**.

A single-sided HYPE/WHYPE farm was not deployed because it would emit DAT without requiring users to add DAT/WHYPE liquidity. It would therefore add reward sell pressure without directly deepening the peg pool.

The LP farm instead requires DAT/WHYPE LP tokens. Acquiring or zapping into those LP tokens creates two-sided liquidity in the same pool used by the rebaser. Emissions can still become sell pressure when claimed, and LP providers retain price and impermanent-loss risk.

## Where the treasury fits

On a positive rebase, `rebaseMintPerc` diverts part of the damped delta to the treasury path. `maxSlippageFactor` (90% by default) determines the portion used for a DAT→WHYPE pool swap; the remaining amount is retained as DAT. The swap uses existing treasury DAT first and mints any shortfall. Both the WHYPE proceeds and retained DAT go to the **rebase treasury**.

Those assets can later be used for liquidity or other treasury actions, but the contracts do not automatically add treasury-owned liquidity. Treasury custody is a trust boundary described in [Governance & security](/brila-dat/explanation/governance-and-security).


# Governance and security

DAT is a **strongly owner-centric** system. Most of the risk is not in permissionless attack surface — it's in what the privileged keys can do. Being honest about that is the point of this page. For the exact role-by-role function list, see the [contracts reference](/brila-dat/reference/contracts).

> **Current ownership status.** The token, rebaser, and incentivizer are owned by the **deployer EOA** (`0x2f8771…`), not a governance multisig. The token and rebaser have no pending owner. See [networks & addresses](/brila-dat/reference/addresses). The intended hand-off has not completed.

## The roles

| Role                        | Current holder         | Capabilities                                                                                                       |
| --------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------ |
| **DAT owner**               | deployer EOA           | UUPS-upgrade the token; set `rebaser` and `incentivizer`; initiate two-step ownership transfer.                    |
| **Rebaser owner**           | deployer EOA           | Set keepers, treasury, timing and policy parameters; rotate USD feeds after 24h; call `forceRebase`.               |
| **Incentivizer owner**      | deployer EOA           | Set `rewardDistribution`; recover unrelated tokens; transfer ownership in one step.                                |
| **Reward distributor**      | deployer EOA           | Call `notifyRewardAmount`; it cannot directly withdraw staked LP or DAT rewards.                                   |
| **Keeper**                  | allowlisted bot key(s) | Commit and reveal rebases inside the configured window.                                                            |
| **Rebase treasury**         | 2-of-3 Safe            | Receive and move treasury DAT/WHYPE; approve DAT spending by the rebaser. It has no admin power unless made owner. |
| **Zap and oracle adapters** | no owner               | Immutable contracts; no admin or recovery functions.                                                               |

In USD mode, the rebaser owner cannot change the peg mode, change the `$1.00` target, or unset the two reserve/USD feeds. A UUPS token upgrade remains capable of changing token behavior without those rebaser-level restrictions.

## The capability that matters most: UUPS upgrade

The DAT owner can replace the token implementation **with no timelock**. An upgrade can change balances, minting, transfers, or authorization. This is the most powerful capability in the system. The current owner is an EOA; moving it to a properly configured multisig is an outstanding trust reduction.

## What commit/reveal does—and does not—protect

A rebase is a two-step **commit/reveal** flow. Reveal is allowed 25–50 blocks after commit. The commit binds the keeper, salt, and `minReserveOut`, so that floor cannot be changed after observing later reserves. In USD mode, commit also snapshots the primary reserve/USD price; reveal reverts when drift exceeds 2% by default.

This limits keeper discretion but does not make a keeper trustless. A compromised keeper can commit an intentionally weak `minReserveOut`, exposing the treasury swap to poor execution or a sandwich. It cannot redirect proceeds: reserve output always goes to `treasuryAddress`. `forceRebase` bypasses commit/reveal and is owner-only, but still enforces activation, window, interval, TWAP, and oracle checks.

## Oracle rotation is timelocked

In USD mode the owner can rotate the reserve/USD feeds but **cannot unset them**, and any rotation takes effect only **24h** after it's proposed (`ORACLE_ROTATION_DELAY`). That window lets observers react to a hostile or fat-fingered rotation. The trade-off is the [liveness risk](/brila-dat/explanation/the-peg#the-liveness-trade-off-read-this): a dead feed can't be fixed faster than the timelock.

## Two-step ownership, and the launch hand-off

DAT and the rebaser use **two-step ownership** (`Ownable2Step`): transfer sets `pendingOwner`, and the recipient must call `acceptOwnership()`. Until acceptance, the old owner remains fully privileged. The incentivizer uses single-step `Ownable`; its transfer takes effect immediately.

The intended hand-off must also separate operational roles: owner, keeper, and reward distributor are independent permissions. The operator runbooks in the repository cover the transfer and verification procedure; the current deployment has not completed it.

## Risks to hold in view

* **Upgrade power, no timelock** — mitigated only by the multisig being trustworthy.
* **Current EOA ownership** — compromise controls upgrades and all owner-set policy.
* **Parameter latitude** — the rebaser owner can retune policy within hard caps, change the treasury, and change keepers.
* **Oracle liveness** — failure of either mandatory USD feed halts rebases until a timelocked rotation completes.
* **Keeper execution quality** — commit/reveal binds a floor but does not enforce that the chosen floor is economically safe.
* **Treasury custody** — the Safe controls received DAT and WHYPE; token holders have no direct claim on those assets.


# Reference

Brila DAT contracts, parameters, networks, and deployment addresses

Exact contract behavior, protocol parameters, networks, and deployment addresses.

* [Contracts](/brila-dat/reference/contracts)
* [Protocol parameters](/brila-dat/reference/parameters)
* [Networks and addresses](/brila-dat/reference/addresses)


# Contracts

This catalog covers every non-test protocol contract under `contracts/` and the launch-only pair seeder under `script/`. Deployment addresses are in [Networks and addresses](/brila-dat/reference/addresses).

| Contract                   | Source                                           | Mainnet status               | Purpose                           |
| -------------------------- | ------------------------------------------------ | ---------------------------- | --------------------------------- |
| `BrilaDAT`                 | `contracts/BrilaDAT.sol`                         | Deployed behind proxy        | Rebasing DAT token                |
| `BrilaDATRebaser`          | `contracts/BrilaDATRebaser.sol`                  | Deployed                     | TWAP/oracle rebase policy         |
| `BrilaDATIncentivizer`     | `contracts/rewards/BrilaDATIncentivizer.sol`     | Deployed                     | DAT/WHYPE LP farm                 |
| `BrilaDATDistributionPool` | `contracts/rewards/BrilaDATDistributionPool.sol` | Not deployed                 | Generic pre-funded reward pool    |
| `LPTokenWrapper`           | `contracts/rewards/LPTokenWrapper.sol`           | Inherited, not standalone    | Shared staking accounting         |
| `HyperCoreOracleAdapter`   | `contracts/oracles/HyperCoreOracleAdapter.sol`   | Two instances deployed       | HyperCore price to `IPriceOracle` |
| `BrilaDATZap`              | `contracts/zaps/BrilaDATZap.sol`                 | Deployed                     | Single-asset DAT/WHYPE LP entry   |
| `UniswapV2OracleLibrary`   | `contracts/libraries/UniswapV2OracleLibrary.sol` | Embedded in rebaser bytecode | Cumulative-price helper           |
| `BrilaDATPairSeeder`       | `script/CreateAndSeedBrilaDATPair.s.sol`         | Deployed launch helper       | Create and seed the initial pair  |

## `BrilaDAT` — DAT token

UUPS-upgradeable rebasing ERC-20. It uses `Ownable2StepUpgradeable` and is deployed behind an ERC-1967 proxy.

| Function                                  | Access                  | Notes                                                                     |
| ----------------------------------------- | ----------------------- | ------------------------------------------------------------------------- |
| `balanceOf(account)`                      | View                    | Display balance in 18-decimal fragments; changes with the scaling factor. |
| `balanceOfInternal(account)`              | View                    | Stored, rebase-invariant balance in 1e24 internal units.                  |
| `initSupply()`                            | View                    | Sum of internal units; increases when DAT is minted.                      |
| `totalSupply()`                           | View                    | `initSupply × brilaDatScalingFactor / 1e24`.                              |
| `brilaDatScalingFactor()`                 | View                    | Global multiplier; starts at `1e18`.                                      |
| `maxScalingFactor()`                      | View                    | Overflow bound derived from current `initSupply`.                         |
| `transfer` / `transferFrom` / `approve`   | Public                  | Standard ERC-20 behavior, denominated in fragments.                       |
| `increaseAllowance` / `decreaseAllowance` | Public                  | Allowance helpers.                                                        |
| `mint(to, amount)`                        | Rebaser or incentivizer | Mints fragments and increases `initSupply`.                               |
| `rebase(epoch, indexDelta, positive)`     | Rebaser                 | Changes the scaling factor within its bounds.                             |
| `setRebaser(address)`                     | Owner                   | Sets a nonzero rebaser.                                                   |
| `setIncentivizer(address)`                | Owner                   | Sets or clears the incentivizer.                                          |
| `upgradeToAndCall(implementation, data)`  | Owner                   | UUPS upgrade; no protocol timelock.                                       |

Because minting increases `initSupply`, `balanceOfInternal(account) / initSupply` is the useful ownership fraction and can be diluted by later mints.

## `BrilaDATRebaser` — rebase policy

`Ownable2Step` policy contract with immutable DAT, reserve token, DAT/WHYPE pair, token ordering, and peg mode. Mainnet uses USD mode: pool TWAP in WHYPE per DAT multiplied by WHYPE/USD.

### Reads

| Function                   | Notes                                                                                                                 |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `getCurrentTWAP()`         | Reserve-token units per DAT. Returns zero when no time has elapsed since the stored sample.                           |
| `getReserveUsdPrice()`     | Reads and validates the primary reserve/USD feed.                                                                     |
| `getCurrentExchangeRate()` | TWAP × primary reserve/USD price in USD mode. This view does not run the secondary-feed bracket used during a rebase. |
| `computeOffPegPerc(rate)`  | Returns capped deviation and direction relative to `targetRate`.                                                      |
| `inRebaseWindow()`         | Reports whether the current timestamp is inside the configured window.                                                |

### Execution

| Function                               | Access             | Notes                                                                         |
| -------------------------------------- | ------------------ | ----------------------------------------------------------------------------- |
| `init_twap()`                          | Owner              | Initializes the TWAP snapshot once.                                           |
| `activate_rebasing()`                  | Anyone             | Activates after the configured warmup; one-way.                               |
| `commitRebase(hash)`                   | Keeper             | Commits `keccak256(abi.encodePacked(keeper, salt, minReserveOut))` in-window. |
| `revealAndRebase(salt, minReserveOut)` | Keeper             | Reveals 25–50 blocks later and executes if all checks pass.                   |
| `cancelCommit()`                       | Committer or owner | Cancels the current commitment.                                               |
| `cancelExpiredCommit()`                | Anyone             | Clears an expired commitment.                                                 |
| `forceRebase(minReserveOut)`           | Owner              | Bypasses commit/reveal, but still requires timing and policy checks.          |

The caller supplies `minReserveOut`. Commit/reveal prevents changing that floor after commitment, but does not guarantee the keeper chose a strong floor.

Owner setters cover keepers, treasury, rebase parameters, timing, optional TWAP-leg oracle checks, and oracle age/deviation bounds. USD feed replacement uses `proposeReserveUsdOracles` → `applyReserveUsdOracles` after 24 hours. `setTargetRate` reverts in USD mode.

## `BrilaDATIncentivizer` — live LP farm

`Ownable` staking pool for the DAT/WHYPE LP token. It inherits `LPTokenWrapper`.

| Function                                          | Access             | Notes                                                                                         |
| ------------------------------------------------- | ------------------ | --------------------------------------------------------------------------------------------- |
| `stake(amount)`                                   | Public             | Stakes LP; also starts the next halved reward period if the prior period ended.               |
| `withdraw(amount)`                                | Public             | Withdraws LP; does not trigger period rollover.                                               |
| `exit()`                                          | Public             | Withdraws the full stake, then calls `getReward()`. A zero stake makes the withdrawal revert. |
| `earned(account)`                                 | View               | Pending reward in pre-scaling accounting units.                                               |
| `getReward()`                                     | Public             | Pays `earned × current scaling factor / 1e18`; also triggers overdue rollover.                |
| `notifyRewardAmount(reward)`                      | Reward distributor | Bootstraps or updates a reward period.                                                        |
| `setRewardDistribution(address)`                  | Owner              | Sets the authorized notifier.                                                                 |
| `governanceRecoverUnsupported(token, amount, to)` | Owner              | Recovers tokens other than DAT and the staked LP token.                                       |

At rollover, `initreward` halves and the pool mints the scaling-adjusted DAT backing it needs. DAT must therefore keep this contract assigned as `incentivizer`; otherwise rollover transactions revert.

## `BrilaDATDistributionPool` — generic reward pool

Source exists, but no mainnet deployment is recorded. Unlike the incentivizer, this contract never mints DAT: it must be pre-funded before `notifyRewardAmount`, which applies a rebase-aware solvency check.

It adds `MIN_STAKED_BLOCKS`: `getReward()` requires that many blocks after the account's latest stake, and every new stake resets the account's `depositBlock`. A direct `withdraw()` is not block-gated. `exit()` withdraws then claims, so the whole transaction reverts when the reward gate is not satisfied.

## `LPTokenWrapper` — staking base

Abstract accounting and custody base inherited by both reward pools. It stores one immutable staking token, total staked supply, and per-account stake; `stake` transfers tokens in and `withdraw` transfers them out. It is not deployed independently.

## `HyperCoreOracleAdapter` — native price adapter

Ownerless, immutable adapter exposing a HyperCore price precompile through `IPriceOracle`. `latestRoundData()` scales the raw value to 8 decimals and rejects zero, malformed, or out-of-band answers. It reports the current block timestamp because it reads current precompile state on every call. Mainnet uses separate perp and spot instances.

## `BrilaDATZap` — single-asset LP entry

Ownerless, immutable, pair-direct helper accepting native HYPE, WHYPE, or DAT. It synchronizes the pair, swaps an optimal portion, adds liquidity, sends LP directly to the recipient, and returns dust.

| Function                                           | Notes                                              |
| -------------------------------------------------- | -------------------------------------------------- |
| `zapInHYPE(minLpOut, deadline, to)`                | Wraps native HYPE, then enters the DAT/WHYPE pool. |
| `zapIn(tokenIn, amountIn, minLpOut, deadline, to)` | Accepts DAT or WHYPE after approval.               |
| `pair()` / `whype()` / `brilaDat()`                | Immutable address getters.                         |

`minLpOut = 0` disables the caller's LP-output protection.

## `UniswapV2OracleLibrary`

Internal library used by the rebaser to read current cumulative Uniswap V2 prices, including the counterfactual update since the pair's last reserve timestamp. It has no standalone address.

## `BrilaDATPairSeeder` — launch helper

Contract defined in the launch script. `createAndSeed` creates or resolves the DAT/WHYPE pair, wraps the supplied HYPE, transfers both assets to the pair, and mints LP to the chosen recipient. It is not part of ongoing protocol operation.

## Interfaces

The production interfaces are `IBrilaDAT`, `IBrilaDATRebaser`, `IBrilaDATIncentivizer`, `IBrilaDATDistributionPool`, `ILPTokenWrapper`, `IPriceOracle`, `IRewardDistributionRecipient`, and `IUniswapV2Pair`, all under `contracts/interfaces/`.


# Protocol parameters

This page separates constructor defaults from mainnet values read on **2026-07-23**. Owner-mutable values can change later. Values are 1e18 fixed-point unless noted. Source of truth: `contracts/BrilaDATRebaser.sol`.

## Rebase policy

| Parameter                   | Constructor default | Live mainnet        | Cap / constraint                                    | Meaning                                                                              |
| --------------------------- | ------------------- | ------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `targetRate`                | `1e18`              | `1e18`              | `> 0`; **immutable in USD mode** (= $1.00/DAT, F20) | The peg target.                                                                      |
| `deviationThreshold`        | `5e16` (5%)         | `5e16` (5%)         | `<= 5e17` (50%)                                     | No supply change when deviation is strictly below this; exactly 5% is actionable.    |
| `rebaseLag`                 | `10`                | `10`                | `> 0`                                               | Off-peg % is divided by this per rebase (damping).                                   |
| `rebaseMintPerc`            | `1e17` (10%)        | `1e17` (10%)        | `<= 1e18`                                           | Share of a positive rebase minted toward the treasury.                               |
| `maxSlippageFactor`         | `9e17` (90%)        | `9e17` (90%)        | `(0, 1e18]`                                         | Share of the positive-rebase mint budget sold; existing treasury DAT funds it first. |
| `minRebaseTimeIntervalSec`  | `12h`               | `43200` (`12h`)     | window must fit interval                            | Minimum spacing between rebases.                                                     |
| `rebaseWindowOffsetSec`     | `28800` (08:00 UTC) | `28800` (08:00 UTC) | `< minInterval`                                     | Start of the twice-daily rebase window (08:00 and 20:00 UTC at the 12h interval).    |
| `rebaseWindowLengthSec`     | `1h`                | `3600` (`1h`)       | `(0, minInterval]`                                  | Length of the rebase window.                                                         |
| `rebaseDelay` (TWAP warmup) | `12h`               | `3600` (`1h`)       | unbounded                                           | Delay after `init_twap` before `activate_rebasing`.                                  |

## Oracles

| Parameter                    | Constructor default                | Live mainnet  | Cap / constraint                                              | Meaning                                                                     |
| ---------------------------- | ---------------------------------- | ------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `usdPegMode`                 | constructor                        | `true`        | **immutable**                                                 | True iff a reserve/USD oracle was set at deploy.                            |
| `reserveUsdOracle`           | constructor                        | Perp adapter  | USD mode: rotatable via 24h timelock; never unsettable        | Primary reserve→USD feed; see [addresses](/brila-dat/reference/addresses).  |
| `secondaryReserveUsdOracle`  | constructor                        | Spot adapter  | USD mode: **required**, distinct from primary; 24h-timelocked | Independent reserve→USD feed; bracketed every rebase.                       |
| `maxReserveOracleAge`        | `1h`                               | `3600` (`1h`) | USD mode: `[1m, 2h]`                                          | Staleness bound for both reserve/USD feeds.                                 |
| `maxCommitRevealOracleDrift` | `2e16` (2%)                        | `2e16` (2%)   | USD mode: `[5e15, 1e17]` (0.5%–10%)                           | Max reserve/USD move tolerated between commit and reveal.                   |
| `secondaryOracleEnabled`     | `false`                            | `false`       | owner toggle; not required to activate                        | Optional Chainlink bracket on the **pool-TWAP** leg.                        |
| `secondaryOracle`            | `0` (set via `setSecondaryOracle`) | `0`           | —                                                             | The TWAP-leg sanity oracle (both modes).                                    |
| `maxOracleDeviation`         | `1e17` (10%)                       | `1e17` (10%)  | `[5e15, 2e17]` (0.5%–20%)                                     | Tolerance for the oracle brackets (TWAP-leg and the USD dual-feed bracket). |
| `maxSecondaryOracleAge`      | `1h`                               | `3600` (`1h`) | `[1m, 2h]`                                                    | Staleness bound for the TWAP-leg oracle.                                    |

## Constants (not configurable)

| Constant                | Value   | Meaning                                                      |
| ----------------------- | ------- | ------------------------------------------------------------ |
| `MIN_TWAP_WINDOW`       | `1h`    | `_getTWAP()` reverts on a shorter sample window.             |
| `COMMIT_BLOCKS`         | `25`    | Min blocks between `commitRebase` and `revealAndRebase`.     |
| `REVEAL_BLOCKS`         | `50`    | Reveal may land through commit block + 50; it expires after. |
| `MAX_RATE`              | `10e18` | Off-peg percentage cap (1000%).                              |
| `ORACLE_ROTATION_DELAY` | `24h`   | Timelock on reserve/USD feed rotations.                      |

## Token constants (`DAT`)

| Constant                                             | Value                                                      |
| ---------------------------------------------------- | ---------------------------------------------------------- |
| `BASE` (fragment precision / genesis scaling factor) | `1e18`                                                     |
| `INTERNAL_DECIMALS` (underlying precision)           | `1e24`                                                     |
| `MIN_SCALING_FACTOR`                                 | `1e15` (0.001×)                                            |
| `maxScalingFactor()`                                 | `type(uint256).max / initSupply` (shrinks as supply grows) |
| storage gap                                          | `uint256[45] __gap`                                        |

## Reward contracts

| Parameter           | Contract          | Constraint / behavior                                                                  |
| ------------------- | ----------------- | -------------------------------------------------------------------------------------- |
| `DURATION`          | Both pools        | Immutable and nonzero.                                                                 |
| `START_TIME`        | Both pools        | Immutable and nonzero.                                                                 |
| `initreward`        | Incentivizer      | Starts nonzero, then halves when `stake` or `getReward` rolls an ended period forward. |
| `MIN_STAKED_BLOCKS` | Distribution pool | Immutable and nonzero; every stake resets the account's claim timer.                   |

`BrilaDATIncentivizer` is deployed. `BrilaDATDistributionPool` is present in source but has no recorded deployment, so it has no live parameter values.

### Live incentivizer

| Parameter      | Mainnet value                                         |
| -------------- | ----------------------------------------------------- |
| `DURATION`     | `7776000` seconds (90 days)                           |
| `START_TIME`   | `1781987792` (2026-06-20 20:36:32 UTC)                |
| `initreward`   | `1353256939035094796632` pre-scaling units            |
| `rewardRate`   | `174029956151632` pre-scaling units per second        |
| `periodFinish` | `1789763792` (2026-09-18 20:36:32 UTC, launch period) |

## Oracle adapter and zap constants

| Constant                          | Value  | Meaning                                              |
| --------------------------------- | ------ | ---------------------------------------------------- |
| `HyperCoreOracleAdapter.DECIMALS` | `8`    | Decimal precision returned through `IPriceOracle`.   |
| `BrilaDATZap.MIN_RESERVE`         | `1000` | Private per-side reserve floor used before zap math. |

### Mainnet oracle adapters

| Role | Precompile                                   | Index | Scale exponent | Inclusive answer band (8 decimals) |
| ---- | -------------------------------------------- | ----- | -------------- | ---------------------------------- |
| Perp | `0x0000000000000000000000000000000000000807` | `159` | `4`            | `8e8`–`480e8` ($8–$480)            |
| Spot | `0x0000000000000000000000000000000000000808` | `107` | `2`            | `8e8`–`480e8` ($8–$480)            |


# Networks and addresses

> Brila DAT launched on HyperEVM mainnet (chain 999) on **2026-06-19**. The protocol contract addresses below are the live deployment recorded across `deployments/999.json`, package configuration, and contract role reads verified on **2026-07-23**. The `DAT` token address is the one to add to wallets, explorers, and DEX listings.

## Networks

| Network          | Chain ID | RPC                                       | Explorer                      |
| ---------------- | -------- | ----------------------------------------- | ----------------------------- |
| HyperEVM mainnet | `999`    | `https://rpc.hyperliquid.xyz/evm`         | `https://hyperevmscan.io`     |
| HyperEVM testnet | `998`    | `https://rpc.hyperliquid-testnet.xyz/evm` | `https://testnet.purrsec.com` |

## Standing infrastructure (HyperEVM mainnet)

Chain-level addresses shared by every HyperEVM deployment — the same for Brila DAT.

| What                           | Address                                      |
| ------------------------------ | -------------------------------------------- |
| WHYPE (reserve token)          | `0x5555555555555555555555555555555555555555` |
| Project X — Uniswap V2 factory | `0xb0D032B6cC82e37488497781338f359cE8CC40e0` |
| Multicall3                     | `0xcA11bde05977b3631167028862bE2a173976CA11` |

## Protocol contracts (HyperEVM mainnet, chain 999)

> The `DAT` token (the ERC-1967 proxy) is the canonical contract address. The implementation lives behind the proxy and is replaced on upgrades; the proxy address never changes.

**DAT token CA (mainnet):** `0x9C45701620d8cE4eBd5213FAa2B4BF725fe2BD9c`

| Contract                                 | Address                                      |
| ---------------------------------------- | -------------------------------------------- |
| `DAT` token (ERC-1967 proxy)             | `0x9C45701620d8cE4eBd5213FAa2B4BF725fe2BD9c` |
| `DAT` implementation                     | `0x0f5175FC7dc72cB8D72b80a506dAD4C714c01d29` |
| `BrilaDATRebaser`                        | `0xF2E417252FFc6d9355BC2d90EFcdD53c057844Ee` |
| `BrilaDATIncentivizer` (LP staking farm) | `0x3e9E18f5944B2d95571d68b9e74627aa9dAb2cc0` |
| `BrilaDATZap`                            | `0xD3661eAb84fF93d3e2D9cFdDc6Bd74f231488AE6` |
| DAT/WHYPE Uniswap V2 pair                | `0x3E0B18bD621304Df40485428eCd20765cF692432` |

> The `BrilaDATIncentivizer` is live: it stakes the DAT/WHYPE LP token and emits DAT rewards on a fixed schedule (the launch emission period runs through **2026-09-18**).

> Verify on the explorer: [DAT token](https://hyperevmscan.io/address/0x9C45701620d8cE4eBd5213FAa2B4BF725fe2BD9c) · [BrilaDATRebaser](https://hyperevmscan.io/address/0xF2E417252FFc6d9355BC2d90EFcdD53c057844Ee) · [BrilaDATIncentivizer](https://hyperevmscan.io/address/0x3e9E18f5944B2d95571d68b9e74627aa9dAb2cc0) · [BrilaDATZap](https://hyperevmscan.io/address/0xD3661eAb84fF93d3e2D9cFdDc6Bd74f231488AE6) · [DAT/WHYPE pair](https://hyperevmscan.io/address/0x3E0B18bD621304Df40485428eCd20765cF692432)

## Ownership & treasuries

| Role                                    | Address                                      | Notes                                                                                                                                                                                                                                                                                                     |
| --------------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Owner (token, rebaser, incentivizer)    | `0x2f8771644015447D9b2946f580f76f9fd5C2C75D` | The deployer **EOA** at the time of writing. The token and rebaser use two-step ownership (`Ownable2Step`); the incentivizer uses single-step `Ownable`. Transfer to a governance multisig is the intended launch hand-off — see [Governance & security](/brila-dat/explanation/governance-and-security). |
| Rebase treasury (rebase-skim recipient) | `0xF6D4E0365c910b7225502ABD485C88e52B9dcB49` | A 2-of-3 Safe; receives the WHYPE proceeds and any DAT minted by positive-rebase mint-and-sell.                                                                                                                                                                                                           |
| Launch treasury / LP custody            | `0x367a0316302D609A5C2408386f1E7675fF79cFE2` | Holds the 5% launch DAT allocation and custody of the seeded LP; distinct from the rebase treasury.                                                                                                                                                                                                       |

## Launch helper

| Contract             | Address                                      |
| -------------------- | -------------------------------------------- |
| `BrilaDATPairSeeder` | `0x32373ff1b1994d7A4a79cd3Bfed61f15e0Bafe15` |

This helper created and seeded the pair. It is not required for ongoing protocol operation.

## Contract without a recorded deployment

| Contract                   | Status                                   |
| -------------------------- | ---------------------------------------- |
| `BrilaDATDistributionPool` | Source only; no mainnet address recorded |

`LPTokenWrapper` and `UniswapV2OracleLibrary` are inherited/embedded code and do not have standalone deployment addresses.

## USD-mode oracle feeds (HyperEVM mainnet)

USD mode requires two **independent** reserve→USD (WHYPE/USD) feeds. The launch ships two `HyperCoreOracleAdapter`s, each wrapping a native HyperCore price precompile. The precompiles, indices, and scale exponents are protocol constants (they match `script/brila-launch-params.sh`).

| Role                                  | Adapter                  | Source precompile                                                                           | Address                                      |
| ------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------- | -------------------------------------------- |
| Primary `reserveUsdOracle`            | `HyperCoreOracleAdapter` | Perp oracle `0x0000000000000000000000000000000000000807` (HYPE perp index 159, scale exp 4) | `0x97Cbf8AB394c7BaB4E26883E9Fc1791b8D9Ab999` |
| Secondary `secondaryReserveUsdOracle` | `HyperCoreOracleAdapter` | Spot `0x0000000000000000000000000000000000000808` (HYPE/USDC pair @107, scale exp 2)        | `0x366338122acE94a3835511b81387A2C807172e95` |

> The rebaser is in USD-peg mode (`usdPegMode = true`, `targetRate = 1e18` = **$1.00 per DAT**).

## Testnet (998)

No Brila DAT testnet deployment is recorded here, so contract addresses and peg mode are not specified.


