owned this note
owned this note
Published
Linked with GitHub
Tinlake revolving pool (v3) documentation
===
[toc]
## Introduction
### What is Tinlake
[Tinlake](https://tinlake.centrifuge.io/) is an open, smart-contract based marketplace of asset pools bringing together Asset Originators and Investors which seeks to utilize the full potential of Decentralized Finance (DeFi).
Asset Originators can responsibly bridge real-world assets, such as invoices, mortgages or streaming royalties into DeFi and access bankless liquidity. They do this by tokenizing their financial assets into [Non-Fungible Tokens](https://developer.centrifuge.io/nfts/overview/introduction/) (“NFTs”) and use these NFTs as collateral in Tinlake.
![](https://storage.googleapis.com/centrifuge-hackmd/upload_1f05da3e573b6e0b07b6ea716cb59dc7.png)
### Tinlake's two tranche structure
Investors can earn attractive yields on [TIN and DROP](https://medium.com/centrifuge/a-tale-of-two-tokens-introducing-tin-drop-our-two-investment-tokens-d4c7342c799a), Tinlake’s two investment tokens that are minted in exchange. TIN, known as the “risk token,” takes the risk of defaults first but also receives higher returns. DROP, known as the “yield token,” is protected against defaults by the TIN token and receives stable (but usually lower) returns. This is similar to Junior/Senior investment structures common in traditional finance.
Please find more general information about Tinlake on our [website](https://centrifuge.io/products/tinlake) and in the [developer documentation](https://developer.centrifuge.io/tinlake/overview/introduction/).
### What is a revolving pool
An openend-ended pool where investors can join and leave at any time and the provided capital can be continuously re-deployed by the Asset Originator unless it is redeemed by the investors.
## Executive Summary - How Revolving pools work
### Intro
Revolving pools allow investors to invest/redeem independently at any time once whitelisted. A decentralized solver mechanism matches investments and redemptions and ensures that certain preferences (e.g. DROP redeem seniority) are considered and the pool's risk metrics are intact. This ensures that Asset Originators have a constant source of liquidity.
### Spinning up a pool
Asset Originators spin up a pool visible at https://tinlake.centrifuge.io/ with certain set parameters such as the DROP APR, the Min TIN risk buffer (share of the Pool that is protected by TIN) and the Max Reserve Amount (see below for more details on all Tinlake variables). An external admin is only required for legal reasons to whitelist the accredited list of investors. Then investors can provide the capital independently by investing into the pool.
### Investing into Tinlake
Investors can be whitelisted for either one (or both) of Tinlake's two tranches. To invest into TIN or DROP Investors lock their investment in DAI into the Tinlake pool. A decentralized, automatic mechanism matches investments and redemptions making sure the pools risk metrics remain intact. Once these investments are executed the investors can collect TIN or DROP token at the current token price in exchange. The token prices reflect the accrued value over time. The DROP token accrues interest at the DROP rate on the deployed capital. The TIN token additionally captures the spread betwee DROP rate and Financing Fee but also bears potential losses in the form of write-ffs. To redeem TIN/DROP tokens Investors lock these tokens into Tinlake and after the execution of the order they can collect the corresponding amount in DAI based on the current token price.
### Financing an asset
The Asset Orginiator can use the capital provided to finance assets. To do this, he locks an NFT representing a tokenized "Real-World Asset" into the set of smart contract as collateral. The NFT is minted based on a document created and shared through Centrifuge's P2P protocol. Financing fees and Principal/Maximum Financing amounts for these NFTs/tokenized assets are provided by an on-chain pricing scorecard and going forward determined by external service providers through "Pricing Oracles". Once the NFT is priced the Asset Originator can draw down the financing. Upon repayment of the financing, the NFT is unlocked and transferred back into the Asset Originator's wallet.
## Pool Variables
### Assets/Portfolio
#### Total Debt
Currently outstanding debt of the pool (~financed assets incl. accrued interest). Every financing accruess secondly compounded interest at the `Financing Fee`. `Total Debt` is the sum of all currently outstanding Debts per assets.
#### NAV
The `NAV` (Net asset value) reflects the present value of the outstanding portfolio of financings. It is basically the sum of present values of the risk-adjusted expected repayments of all outstanding financings. It is calulated through Tinlake's Pricing and Valuation Smart contract ("NAV feed") at every `Epoch` based on an on-chain a fair value valuation (“marked to model”). Valuation parameters are also provided by the document underlying the NFT, which is created and shared through Centrifuge's p2p Protocol. The NAV ultimately determines the tranches values and thus token prices at which investors invest and redeem at every epoch. Please find more details about Tinlake's valuation approch, including simplified examples [here](https://centrifuge.hackmd.io/PgKrCfcUT3Ot63d_YfeNYw).
#### Reserve
The `Reserve` is the current liquidity in the pool that is not deployed to finance assets ("~cash" in traditional finance). It is available for redemption by investors and asset orginations by the Asset Originator and limited by the "Max reserve amount".
#### Senior Debt
The share of `Total Debt` that accrues interest at the `DROP APR` for the DROP tranche. The "Senior Debt" is rebalanced at every epoch to reflect the share of DROP invested into the pool. Please find more information on the rebalancing mechanism below.
#### Senior Balance
Share of the DROP tranche that is currently not deployed in financings and thus does not accrue interest at the `DROP APR`.
### Investments/Token
#### Senior Value
The Senior Value represents the value of the senior/DROP tranche. It is calculated as
$$
seniorValue = min(Senior Debt + Senior Balance, NAV + Reserve)
$$
If NAV + Reserve are smaller then the Senior Value or in other words the sum of senior Debt + Senior Balance , TIN's risk cusion would be worthless (e.g. taken all losses). Then the entire NAV and the currency left in Reserve belong to the senior tranche. The senior value is used to calculate the DROP tokenprice.
#### Junior Value
Junior Value denominates the current value of the junior/TIN tranche. It is mainly driven by the NAV and Reserve and calculated as:
$$
juniorValue = max(NAV + Reserve - Senior Value,0)
$$
The Junior value is used to calculate the TIN token price.
#### Pool Value
The Pool Value is the sum of Senior and Junior Value:
$$
Pool Value = Junior Value + Senior Value = NAV + reserve
$$
Note that it is equivalent to the sum of NAV and reserve.
#### TIN/DROP Token Supply
TIN/DROP Token Supply denote the amount of outstanding TIN and DROP tokens per pool.
#### TIN/DROP Price
The price per TIN/DROP token is calculated by:
$$
DROP Token Price=\frac{senior Value}{DROP Token Supply}
$$
and
$$
TIN Token Price =\frac{juniorAssetValue}{TINTokenSupply}
$$
### Pool risk metrics and restrictions
#### Current TIN risk buffer
The `Current tin risk buffer` describes the extend of TIN protection for the DROP tranche. It is calulated as
$$
Current TIN risk buffer = \frac{Junior Value}{Junior Value + Senior Value} = \frac{Junior Value}{Pool Value}
$$
The higher the `Current TIN Ratio` the higher the TIN risk protection for DROP.
#### Min TIN risk buffer
The Min TIN risk buffer is the lower limit of the `Current TIN risk buffer`. It ensures that DROP investors are protected by a certain amount of TIN invested in the pool at any time.
If the `Current TIN risk buffer` is below the Min TIN risk buffer DROP Investments, TIN Redemptions and Asset Originations are not possible any more until the the min TIN risk buffer is restored e.g. through further TIN investments. Correspondingly no DROP Investments or TIN redemptions would be accepted that would break the ratio.
#### Max TIN risk buffer
Tinlake pools also allow to set an upper limit for the `Current TIN risk buffer`. This limits the amount of TIN that can be invested in relation to DROP. While a certain amount of TIN is required to protect DROP investors at any time, a large TIN ratio may drag down the return for existing TIN investors. The default value for the Max TIN risk buffer is 100% but it can be activated if the share if TIN investments is too high
The follwong graph describes the relation of tranche values and TIN ratio's:
![](https://storage.googleapis.com/centrifuge-hackmd/upload_ec399a370af54ec35459f9c40f34a0f1.png =400x)
#### TIN risk buffer smart contract implementation
Note, that the smart contracts use a `DROP ratio `for their calculations which is defined as `1-current TIN risk buffer`:
Min TIN risk buffer 10% --> Max DROP ratio 90%
Current TIN risk buffer 20% --> Current DROP ratio 80%
Max TIN ratio 30% --> Min TIN risk buffer 70%
#### Current reserve ratio
The current reserve ratio denotes the level of cash/reserve that is currently held in the pool.
It is calculated as
$$
Current Reserve Ratio = \frac{Current Reserve}{Pool Value}
$$
A high reserve ratio drags down the DROP and TIN returns as this capital is not generating interest income.
#### MAX Reserve amount
This is why the AO can limit the amount of investments it is willing accept with the `Maximum reserve amount`. No investments will be accepted if the current `Reserve` is larger than the `Max reserve amount`. The `Max reserve amount` can be set and adjusted by the Asset Originator on a constant basis to manage the investments allowed into the pool based on their need for liquidity.
#### Total epoch investment capacity
This is the differents between the `Maximum reserve amount` and the current reserve and describes how much liquidity can be accepted for the next epoch mechanism.
### Interest rates
#### Financing Fee
This is the rate at which the Debt of an indiviual Financings accrues interest. It is expressed as an APR and compounds interest every second. Different assets can have different Financing Rates depending on their individual `Risk Score`.
The Financing Fee per risk score is stored in a `Risk Scorecard` in a smart contract. A pricing oracle determines the risk score and value of every NFT locked into Tinlake based on the underlying document and NFT shared/minted via the Centrifuge p2p Protocol. The `Financing Fee` per Financing is determined automatically based on the set `Risk score` of the underlying NFT. Please find more information how pricing based ona Scorecard works [here](TODO link blogpost).
#### DROP APR
This is the rate at which the `Senior Debt` accrues interest per second. Note, that this is only applied on deployed Senior tranche capital but not on the `Senior Reserve`. The actual DROP return may thus differ from the DROP APR.
#### Interest rate implementation
Note that the input format for Tinlake's smart contract is an APR. Tinlake then transforms all interest rates into a fee variable `Fee = 1 + Interest rate / Seconds per year` to perform calculatins in the smart contract.
#### TIN return
The `Junior Tranche` does not have a pre-defined fixed or variable interest rate. TIN tokens capture the increasing value of the portfolio and the spread between `Financing rates` and `DROP APRs`.
## The epoch - How investments and redemptions are managed and executed
### Overview
A decentralized pool where investor can invest/redeem and AOs originate/repay financings at anytime needs a (decentralized) mechanism to coordinate investments, redemptions, originations and repayments. Welcome the `Epoch`.
For Tinlake's Revolving Pools all investment inflows/outflows are locked over a defined period of time ("Epoch") and automatically executed at the and of this period following predetermined priorities and risk metrics. The Asset Originator can use the available reserve after the invest/redeem transactions have been executed to finance Asset Originations throught the next epoch. Repayments can also happen at any time throughout the epoch, but are collected in a seperated reserve and can only be used for financings in the next epoch.
To summarize: The following types of inflos/outflows of the asset side can happen during an Epoch by the Asset Originator:
- Financing repayments
- Asset Originations / Financing Drawdowns
The following types of inflows/outflows on the investment side are locked during the epoch and exected at the end of the epoch:
- DROP redemptions
- TIN redemptions
- DROP investments
- TIN investments
![](https://storage.googleapis.com/centrifuge-hackmd/upload_a1131708d212d1636b73dbc4dc094bf2.png)
The above inflows/outflows impact the pool variables as follows:
![](https://storage.googleapis.com/centrifuge-hackmd/upload_c6b77fddde0799b97f966f619547d5ad.png)
### Length of an Epoch
On the smart contract level, Tinlake epochs have a minimum length that the smart contracts will enforce. Thus an epoch cannot be closed before the minimum length has passed. An epoch does not have a maximum length. After the minimum length has passed the contracts can be called to close the current epoch. So if e.g. the minimum length of an epoch is set at 24h, an epoch will have to last at least 24h but can also last longer. This allows for a flexible set-up to have longer more flexible epochs at the start of a pool to ramp up funding or to allow for more effecient transaction costs e.g. in times of high gas prices or ensures that a pool can start slower at the beginning. A mature, liquid pool can have a service added that limits the epochs to a certain length by closing the epoch at a pre-defined interval. Once the epoch is closed the smart contracts start to process the current state of the pool and process all locked orders (see more details below).
### The invest/redeem process
Investors can supply more liquidity at any point in time during the epoch. The supplied Dai would be locked in the Tinlake contracts until the end of the epoch. The investor can cancel his lock as long as the current epoche is active. In that case, the locked DAI will be transferred back to his wallet. At the end of the epoch, all locked orders will be processed and executed at the current TIN/DROP prices considering the max reserve amount and min TIN risk buffer. After the epoch turn, investors can collect the executed orders in the UI. If part of the investment/redemption could not be executed, it will be rolled over into the next epoch, thus the DAI remain locked. This locked order can be cancelled at any time.
![](https://storage.googleapis.com/centrifuge-hackmd/upload_2140edba6c574b9178bce08ef24e097a.png)
The redeem process works similarly. If Existing TIN/DROP investors want to redeem (part of their) TIN/DROP tokens they can lock this Tokens into Tinlake at any point during the epoch. At the end of the epoch, all locked orders will be processed and executed at the current TIN/DROP prices considering the max reserve amount and min TIN risk buffer. After the epoch turn, investors can collect the DAI from the executed orders in the UI. If part of the investment/redemption could not be executed, it will be rolled over into the next epoch, thus these tokens remain locked. This locked order can be cancelled at any time.
### The turn of the Epoch
Once the minimum length of an epoch has passed anyone can call the contracts to "close" the epoch. Once the epoch is closed investor's can't unlock their orders anymore. All Orders locked after the close will be collected and processed. If an epoch close is called without any locked invest/redeem transactions the epoch number will be bumped but the process described below will not be started.
At the Epoch turn, the contracts first process the current state of the pool:
- Total Debt
- NAV
- Reserve
- Senior Debt
- Senior Balance
- Senior Value
- Junior Value
- TIN/DROP Token prices
- TIN risk buffer
Then the contracts check whether all set orders can be executed with the capital available and without breaking the TIN risk buffer or the Max reserve restrictions. If this is the case all orders are immediately executed and the contracts process the new state of the pool. Please find a simple model that illustrates the processing of orders and calulation of the pool state [here](https://docs.google.com/spreadsheets/d/1mkIbWzhD7IXbnbYXKreTMYuaZJEzyTVqllhJnP4YdPs/edit#gid=161507348)
If not all orders can be executed, e.g. because there is not enough capital available in the Reserve (plus new investments) to serve all redemption orders or executing all DROP investments would break the Min TIN risk buffer the Tinlake "Solver mechanism" would be initiated.
### The Solver mechanism
#### Why introduce a solver mechanism?
If not all orders can be executed a mechanism is required to find the optimal solution to ensure as many transactions as possible are executed while adhering to certain restrictions such as the Max Reserve amount, min TIN risk buffer, DROP sovereignity etc. Finding the optimal solution for the four invest redeem transactions type of transactions (DROP redemptions, TIN redemptionsm, DROP investments, TIN investments) under a defined set of restrictions depicts a classic maximization problem that can be solved with linear programming.
#### How it works
Implementating linear programming in smart contracts is theoretically possible but in practice very complex and expensive in terms of gas fees paid. Tinlake smart contracts thus have a decentralized approach where anyone can run a solver and submit the solution for executed orders four invest/redeem transaction types via a simple contract call. The smart contracts check that the state resulting by this submission adheres to all restrictions described above. If this is the case, a 30min challenging period starts in which anyone can submit a superior solution. The superiority of solutions is determined by a "max weight function" multiplying the amount of orders executed with weights. The weights for this function can differ between pools but usually, e.g. DROP redemption would contain the highgest weight to ensure DROP senority.
If a competing viable solution is submitted resulting in a higher "max function" a new 30min challenging period starts. If no superior solution is submitted anyone can call the "Epoch execute" function after the 30min challenging period to execute the pending transactions according to the accepted solution.
![](https://storage.googleapis.com/centrifuge-hackmd/upload_31a6106286b18c78f8edce05d8f223f0.png)
#### The solver optimization
The linear programming of the Tinlake solver maximizes the execution of the four invest/redeem orders (all in DAI values)
- TINInvestOrder
- DROPInvestOrder
- DROPRedeemOrder
- TINRedeemOrder
according to a max function that allocates a weight to each of the executed order types. Sample weights to ensure a waterfall-like priority focused on DROP seniority could e.g.
- DROP redemptions: 100,000,000,000 [Ensure seniority]
- TIN investments: 100,000,000 [Build up risk buffer]
- DROP investments: 100,000
- TIN redemptions: 100 [Ensure Min TIN risk buffer stability]
The according sample max function could e.g. be
$$
Maxfunctionresult = DROP redemptions * 100,000,000,000 + TIN investments * 100,000,000 + DROP investments * 100,000 + TIN redemptions * 100
$$
The restrictions for this optimization problem are:
- Executed order needs to be smaller or equal to the submitted order [e.g. Total executed TIN invest <= Total locked TIN invest]
- All executed orders need to be larger than or equal to zero [e.g. Total TIN invest > 0]
- The Reserve is larger than zero and smaller smaller than the `max Reserve amount` after all transactions are executed [0 < Reserve < Maximum Reserve Amount]
- The Tin ratio of the resulting state is larger than the MIN TIN ratio and smaller than the Max TIN ratio [Min TIN risk buffer < Current TIN risk buffer]
Please find a sample solver model [here](https://docs.google.com/spreadsheets/d/1PkZV6K8QnGSRpnj-O4a7iAWdLBDMFJHoAOrpdixau_s/edit#gid=1606412041).
### Senior Debt Rebalancing
With every epoch that has executed invest/redeem transactions the relation between Senior and Junior Tranche changes. This also needs to be reflected in `Senior Debt` to ensure that interest accrued on Senior Debt is in line with the Junior/Senior relation and the Senior Tranche does not accrue too much or too little interest. To ensure this, Senior Debt is rebalanced in line with the relation between the `Senior Value = (Senior Debt + Senior Balance)` and the `Pool Value = (NAV + Reserve)`. This relation is called `Global Senior ratio`.
$$
Global Senior ratio = \frac{Senior Debt + Senior Balance}{NAV + Reserve}
$$
The global Senior Ratio is multiplied with the NAV to calculated the `Target Senior Debt` and the Senior Debt and Senior balanced are re-balanced to set the 'Senior Debt' equal to `Target Senior Debt`. Note that the `Senior value` remains unchanged. Please find a simple model that illustrates the re-balancing mechanism [here](https://docs.google.com/spreadsheets/d/1mkIbWzhD7IXbnbYXKreTMYuaZJEzyTVqllhJnP4YdPs/edit#gid=880740688)
### Process Overview
The following graphs summarizes the entire flow of the turn of an Epoch:
![](https://storage.googleapis.com/centrifuge-hackmd/upload_d6542d189d59e641b0a7a235be2d303d.png)
## Smart Contracts architecture
The set of smart contracts are divided into a Asset and Investment side:
![](https://storage.googleapis.com/centrifuge-hackmd/upload_049631b2544c34827d059568a18d5956.png)
![](https://storage.googleapis.com/centrifuge-hackmd/upload_75bb34a68656ebb8b043c9b66c0cad01.png)
For more information: [Detailed contract spec ](https://centrifuge.hackmd.io/4RV___V4RMWq30lrx4BkAA)
## Further References
### Documentation
- [Tinlake v3 Audit Kick-off](https://docs.google.com/presentation/d/1X8U0ya3XMiSHkpmpsKIVkVsrWyXzMQZkKwHqitcysYg/edit?usp=sharing)
- [Tinlake v3 slide collection](https://docs.google.com/presentation/d/19vKtsJ0hvXHVrnUUYcCY50--PCXBPErfOuERc1y2MjI/edit?usp=sharing)
- [Two Token Structure blog post](https://medium.com/centrifuge/a-tale-of-two-tokens-introducing-tin-drop-our-two-investment-tokens-d4c7342c799a)
- [Asset Pricing blog post](https://medium.com/centrifuge/tinlake-pricing-and-valuation-series-part-1-how-to-price-real-world-assets-cf6655132bef)
- [Portfolio Valuation blog post](https://medium.com/centrifuge/tinlake-pricing-and-valuation-series-part-2-valuing-an-asset-portfolio-247d8f2f0d5)
- [System Diagram](https://app.diagrams.net/#G1yPN8RChmKb30wmnZlp-7YPOPsooE-kCq)
### Fincancial models
- [Lifecycle of a sample Financing (Debt & Present value)](https://docs.google.com/spreadsheets/d/11JfL1_euOCEDmSCmiH97pP_1XlMOE4kJj1XbuhbYQMQ/edit#gid=2010255613)
- [Invoice Portfolio NAV calculation](https://docs.google.com/spreadsheets/d/11JfL1_euOCEDmSCmiH97pP_1XlMOE4kJj1XbuhbYQMQ/edit#gid=2126451691)
- [Epoch Solver mechanism](https://drive.google.com/file/d/1i3DsavaqJeMStXF4V2pcr3Xp0zrtG7cq/view?usp=sharing) [!EXCEL FILE! Needs to be downloaded]
- [Rebalancing mechanism](https://docs.google.com/spreadsheets/d/1mkIbWzhD7IXbnbYXKreTMYuaZJEzyTVqllhJnP4YdPs/edit#gid=880740688)
- [Daily Revolving Pool Model](https://docs.google.com/spreadsheets/d/1OLOfIWnZrsyn0VdGUpCubBYG39XBAu4TUFpw7OGsid8/edit?pli=1#gid=0)[CURRENTLY BEING UPDATED TO INCLUDE SOLVER]
## Annex
### Why do we need a revolving pool
#### Current pool structure: Static pools
Currently all our use cases are based on static pools. Static pools allow for one invest/redeem and asset origination cycle:
- An admin whitelists all Investors and Investment amounts
- TIN and DROP Investors invest their capital
- Capital is deployed to finance assets by the Asset Originators
- Asset Originator repays the financings
- Repayments proceeds (Principal plus interest) are distributed to the Investors
- An Admin sets redemption amounts per investor
- DROP receives Investment + DROP rate on deployed capital
- TIN receives remaining returns and takes potential losses
- Pool is closed
#### Problems with the current pools structure:
- Scalability
- Asset Originators want constant access to liquidity. Investors also want longer term investments. Rolling over static pools doesn't scale well. Especially for short term assets the fixed costs for spinning up static pools are relatively high.
- External Authority (Admin) required
- An external authority (admin) needs to define the redeem and invest amounts to prevent first come, first serve redeem or over-supply. This is operationally cumbersome and scales badly
- First come, first served Redeem
- All investors have to redeem at the end, otherwise, if repayments are available for redemption, the investor who redeems first gets the available liquidity earlier yielding a higher IRR