Motivations

The motivation for this project started with an introduction to one of the developers I met at Fodl who explained to me the concept of folded leverage. Folded leverage is where a user deposits collateral on a lending platform, borrows against their collateral, re-deposits what they borrowed as additional collateral, borrows against the newly added collateral etc etc until the desired leverage is achieved. Due to my interest in Scrypto and the Radix Engine which I've written a few articles about, I was curious to know how much easier it would be to design a similar protocol in an asset-oriented approach. Being that I didn't have any developer experience, I was hoping someone would build a prototype of this where I can study the process. When I didn't find anyone, I decided to take it into my own hands. My Rust was rusty (no pun intended), although some of the syntax was still familiar to me when I began this project. I spent a couple of months learning Rust (and Scrypto a few months after) as a personal project last year at the start of the pandemic but have yet to touch it for over a year. While this project took a couple of months to build, much of the hurdle was me learning Rust & Scrypto along the way. I faced a lot of design questions I had no experience in when architecting the system. Should depositors receive LP tokens? Should it be fungible or non-fungible? Should the liquidity supply and collateral be in the same pool or in a shared pool? What access controls should be implemented to prevent any mishaps? My perspective was attempting to solve it from a user's perspective. Is it easy to use the features? How much do they have to think? What is the experience like? While some of the design questions have still been left unanswered, I feel like I've built a pretty interesting prototype to continue tinkering with and exploring the mechanics and design to be iterated. Suffice to say, for someone like me who couldn't get past the "Hello World" chapter when I attempted to learn C++ a few years ago to be able to build something remotely close to this, I think this is a testament to how powerful Scrypto and the Radix Engine is.

Basic Features:

  • Create user - Allows people to create users to use the protocol. An SBT will be received which will track interactions of the protocol.
  • Multi collateral support - Allows for the creation of multiple pools and borrow against multiple collaterals.
  • Deposit - Allows users to deposit liquidity into the lending pool and earn protocol fees.
  • Add collateral - Allows users to deposit collateral into the pool to be (currently) locked away and used to overcollaterize their loan(s).
  • Add additional collateral - Allows users to top off on collateral towards their open loan position.
  • Borrow - Allows users to borrow from the liquidity pool with a (currently) static max borrow of 75%.
  • Borrow additional - Allows users to top off on their open loan position.
  • Repay - Allows users to repay their loan in partial or in full.
  • Flash loan borrow - Allows users to perform flash loans.
  • Floash loan repay - Allows users to complete their flash loan transaction by having the transient tokens burnt after repaying the flash loan within one transaction.
  • Convert deposit to collateral - Allows user to convert their deposits to be collateralized for their loans. User (currently) do not earn protocol fees for any collateral deposited.
  • Convert collateral to deposit - Allows user to convert their unused collateral to be used as supply liquidity to earn protocol fees.
  • Liquidate - Allows users to liquidate any loans that have a Health Factor of 1 or below.
  • Find bad loans - Allows users to query loans that have below a Health Factor of 1 or below.
  • Check liquidity - Allows users to view the liquidity available to borrow or withdraw deposits from the protocol.
  • Check total supply - Allows users to check the total that's been supplied to the pool.
  • Check total borrowed - Allows users to check the total that's been borrowed from the pool.
  • Check utilization rate - Allows users to check the rate that has been borrowed against the total supply of the pool.
  • Check total collaterization supply - Allows user to check the total collaterization that's been supplied in the pool.
  • Check SBT information - Allows users to review their own SBT data info.
  • Check loan information - Allows users to view loan information of the given loan ID.

The new transaction model introduced with v0.3.0 of Scrypto allows for the creation of composable transactions; this means that a concept such flash loans no longer needs to be implemented in the smart contract itself and that it can instead be an assertion in the transaction manifest file that performs the flash loan. In the case of DegenFi, flash loan compatible methods are implemented on the lending pool components so that users have the choice of how they wish to use flash loans: either by using these dedicated methods in a later section or by writing their transaction manifest files for their flash loans.

Advanced Features:

  • Folded leverage - Folded leverage is where a user deposits collateral on a lending platform, borrows against their collateral, re-deposits what they borrowed as additional collateral, borrows against the newly added collateral etc etc until the desired leverage is achieved. Users are able to open a long position or short position
  • Flash liquidation - Users can liquidate a position even if they do not have the funds to repay the loan by using flash loans.
  • Credit Score System - Users can earn a credit rating by continuously showing good borrowing habits by paying off their loans. Borrowers who demonstrate a proven borrowing track record can earn interest rate coupons and collateralization adjustments.
  • Loan Auctioning - Users can auction their loan NFT to open up liquidity. User can set the conditions of their sale agreement.

Folded Leverage

As mentioned Folded leverage is where a user deposits collateral on a lending platform, borrows against their collateral, re-deposits what they borrowed as additional collateral, borrows against the newly added collateral etc etc until the desired leverage is achieved.

This is possible through flash loans which are capable of opening the folded leveraged position in a single transaction, effectively allowing the users to leverage their principal beyond the limits of the underlying lending platform.

Here are the steps to open a leveraged position:

  1. You have 1,000 XRD
  2. You do a flash loan to borrow 3,000 XRD
  3. You deposit 4,000 XRD as collateral
  4. You borrow 3,000 USD (75% of XRD collateral assuming XRD is $1)
  5. You swap 3,000 USD for 3,000 XRD using Radiswap
  6. You pay back your 3,000 XRD flash loan you took out in step 2.

Users do this to earn a multiple of COMP tokens than they would have if they used the protocol normally. I've immitated this mechanic by creating a supply of protocol tokens called "Degen Tokens" with a similar mechanic of how COMP tokens are rewarded to users by interacting with the protocol.

To close your position

  1. You take out a flash loan to cover the USD your entire loan balance.
  2. You repay all your 3,000 USD loan balance (+ plus fees).
  3. You redeem your 4,000 XRD collateral.
  4. You swap your XRD to USD just enough to repay the flash loan in step 1.
  5. You've now exited your position.

Flash Liquidation

In the event that there is a loan with a Health Factor below 1 that you may wish to liquidate but do not have the funds to liquidate the position. You may use flash loans to compose together a series of transaction in which repays the loan the loan, receive that value + liquidation fee, and repay the flash loan within one transaction.

To perform a flash loan liquidation:

  1. You do a flash loan to borrow the amount you wish to repay back the loan.
  2. You liquidate the loan
  3. You receive the collateral value + liquidation fee.
  4. You swap enough of the collateral asset to the asset you repaid the loan with.
  5. You pay back the flash loan you took in step 1.

Loan Auction

The loan auction design has not been fully thought out yet so there are certainly a lot of outstanding questions to consider. Nonetheless, the design requires the seller of the loan NFT to instantitate the LoanAuction blueprint to deposit their loan NFT.

The seller needs to determine the conditions of the sale (how much the minimum collateral is requested by the seller). The buyer is then allowed to withdraw the loan NFT from the vault, but a transient token is minted along the way the must satisfy the conditions of the sale before the loan NFT can be retrieved.

Misc. features:

  • Get price - Retrieves the price of a given asset using a pseudo price oracle.
  • Set price - Sets the price of a given asset to demonstrate how liquidations work.
  • Set credit score - Sets the desired credit score to demonstrate how the credit score system works.
  • Instantiate Radiswap - Supplies liquidity for two assets to be swapped.
  • Swap - Allows users to swap between two assets.

Design details

There are a few notable Non Fungible Tokens ("Non Fungible Token) and Soul Bounded Tokens ("SBT") that are implemented in this prototype. I've went back and forth to how loans and users should be represented in this lending protocol and even still, I don't think I've arrived at a final conclusion yet. Albeit, this is current approach to how I envisioned it in my head.

User/Credit Report/SBT

User NFT is an NFT that represents users for this protocol. This NFT contains all the records of the user interacting with this protocol. It can be seen as a credit report for the user. It is also used for authorization that this user belongs to the protocol and access protocol features. Users themselves do not have permission to change the data contained within the NFT. It is a non-transferable token or otherwise known as a "Soul Bound Token" or "SBT" for short. I've implemented HashMaps to contain deposit, collateral, and borrow balance is for better flexibility and user experience. I'd like to have the user be able to view all their loans, deposit, borrow balance, etc. easily. Also, especially when it comes to repaying loans. When a loan is paid off, users do not have to worry about sending the wrong NFT, the protocol will simply look at the SBT token and find the loan that the user wants to pay off.

Loan NFT

This is an NFT that represents the loan terms. We can consider this NFT as loan documents and hopefully in the future can be represented as legal documents or a digital representation of a legal document. This NFT is given to the borrower. For now its purpose is to simply tract the health factor of the loan, collaterization, etc. If the loan is in bad health, liquidators can query the liquidation component to evaluate bad loans and liquidate the loan's collateral. Another purpose is to track the status of the loan to update the user's credit report. In the future, given the nature that, unlike the SBT; these loan NFTs can be transferrable to which there may be interesting use cases that we can explore to securitize the loans or package them together.

Liquidation

The liquidation mechanic in this protocol is a simplified imitaiton of AAVE's liquidation mechanics which can be viewed here.

A liquidation is a process that occurs when a borrower's health factor goes below 1 due to their collateral value not properly covering their loan/debt value. This might happen when the collateral decreases in value or the borrowed debt increases in value against each other. This collateral vs loan value ratio is shown in the health factor.

In a liquidation, up to 50% of a borrower's debt is repaid and that value + liquidation fee is taken from the collateral available, so after a liquidation that amount liquidated from your debt is repaid.

In the even that the loan reaches a Health Factor of 0.5 or below, liquidators can now pay up to 100% of a borrower's debt and that value + liquidation fee is taken from the collateral available.

The liquidation fee or liquidation bonus is currently a static 5% attirubtion to the liquidator.

Pool Design

Each asset supported has two pools, one to provide liquidity supply and one to lock collateral. In this way, this design can support multiple assets while risk between assets should be contained within each pool(s). I have yet to research different pool designs or develop or a way to model risk. This was just something I thought was intuitive.

Credit Report System Design

The credit report design is quite primitive. The basic gestalt is that, users can earn credit scores by repaying back their loan. Users need to borrow a minimum of 1,000 of value to begin earning credit.

Here is the credit score calculation:

  • Repay > 25% of the remaining balance & a minimum of 1,000 principal loan value = 25 credit score.
  • Repay > 50% of the remaining balance & a minimum of 1,000 principal loan value = 35 credit score.
  • Repay > 75% of the remaining balance & a minimum of 1,000 principal loan value = 45 credit score.
  • Repay > 100% of the remaining balance & a minimum of 1,000 in remaining balance = 60 credit score.

Users who have achieved 100, 200, or 300 credit score are rewarded with the following:

1%, 2%, or 3% interest rate coupons, respectively.

3%, 6%, or 9% increase in max borrow allowed, respectively.

Blueprints Overview

The DegenFi Protocol is made up of 6 core blueprints. These blueprints are DegenFi, LendingPool, CollateralPool, UserManagement, Radiswap, and PseudoPriceOracle.

DegenFi Blueprint

The DegenFi blueprint is acts more as a registry of all of the liquidity pools that belong to the protocol where it keeps a HashMap of all the pools and maps them to the correct lending and collateral pools. When a user requests the creation of a new lending pool, DegenFi checks to ensure that the lending pool does not already exist in the HashMap before it is created. This design is inspired by Omar's RaDEX submission in the DEX challenge.

DegenFi can essentially be thought of as an interface for users to interact through in which it will route the method calls to the other blueprints. Because DegenFi has visibility of all the pools it can assist in facilitating liquidation, ensuring the liquidations are handled seamlessly (repayments are sent back to the correct lending pool and collateral is redeemed from the correct collateral pool). Thus, DegenFi also has a registry of (at least) all the bad loans that are fed through from each respective lending pools.

LendingPool Blueprint

The LendingPool as the name suggest is where the lending market can be managed. All the method calls to add deposit, withdraw deposit, converting deposits to collateral, borrowing funds, redeeming deposits, and calculation of fees are contained here.

The purpose of the LendingPool blueprint are:

  • Managing the liquidity supply of the pool.
  • Tracks the supply, liquidity, borrowing amounts, fees, and health of the loans.
  • Mints Loan NFT and manage its data as users interact with the pool.
  • Manages the data of the loans being lent from the lending pool.
  • Facilitates the conversion between the deposit supply to collateral supply.

Majority of the methods here are enforced by Access Rules and can only be accessed through in the DegenFi blueprint.

CollateralPool Blueprint

Similarly, the CollateralPool blueprint has identical responsibilities as the LendingPool blueprint, but much more limited in functionality as it does not currently perform any other responsibilities other than to manage the collateral and perform liquidations.

  • Managing the collateral supply of the pool.
  • Tracks the collateral supply.
  • Facilitates the conversion between collateral supply to deposit supply.
  • Liquidates the collateral in the pool.

The majority of the methods in this blueprint are also enforced by Access Rules and can only be accessed by the DegenFi blueprint.

UserManagement Blueprint

The UserManagement blueprint plays a unique role in the protocol. Because SBT's plays such a critical role in the protocol it has its own component that manages User SBT data in the protocol.

The role of the UserManagement blueprint are to:

  • Manage User SBT data. LendingPool and CollateralPool performs permissioned method calls to increase deposit balance, decrease deposit balance, increase collateral balance, decrease collateral balance, increase borrow balance, decrease borrow balance, increase credit score, decrease credit score,

Radiswap Blueprint

While not as performative as Omar's RaDEX, the Radiswap blueprint provides a simple and straightforward set of methods to show case extended use of flash loans in this protocol. Its functions are simple and its role is to simply facilitate swapping of assets.

PseudoPriceOracle Blueprint

The PseudoPriceOracle blueprint is a very primitive blueprint, mainly serving as a function to have a basic way of pulling price data and calculating time for interest accruals.

LoanAuction Blueprint

The LoanAuction blueprint serves as a way for users to deposit their loan NFT to put up for sale. It contains four vaults:

  1. The vault where collateral will be deposited to be claimed by the seller of the NFT.
  2. The vault where the NFT will be contained.
  3. The vault of where the transient token badge that has authority to mint/burn/update transient tokens.
  4. The vault that containse the access badge to allow components to do permissioned calls.

The LoanAuction blueprint has methods that faciliates the loan NFT transaction and the change of ownership of that loan NFT.

Future work and improvements

This prototype is not production ready yet. While there needs to be many more testing and iterations to do for this to be prototype (I can definitely see some areas of improvements after the fact of building this lending protocol), I certainly would not get anywhere this close without the ease of Scrypto, the Radix Engine, and the Transaction Manifest. Here are a few things I have in mind that I'd like to explore more with this prototype:

  • Researching risk analysis tools to quantify the risk of the protocol with various lending markets.
  • Researching a better user experience for the liquidation mechanism (and user experience overall).
  • Implement a more robust price oracle.
  • Design better calculation mechanics to ensure accuracy.
  • Research, implement, and experiment with securitization designs.
  • Research and experiment more clever usage of flash loans.
  • Research & design protocol economics
  • Interest accrual calculations.

Conclusion

This is my first attempt of developing a lending protocol or developing anything at all for that matter on my own; carrying out from design to implementation. It was a tremendous learning experience and incredibly fun visualizing assets being moved around in this protocol due its asset-orientedness. There may have been different parts of this design that could have been implemented better. I suppose you live and you learn. Major thanks to Florian, Omar, Peter Kim, Rock Howard, Clement, and Miso for talking out ideas with me and helping me out along the way.

For a tutorial on how to test this protocol please visit the GitHub repo: https://github.com/PostNutCIarity/scrypto-challenges/tree/DegenFi/3-lending/degenfi

Built With

Share this project:

Updates