Path: blob/main/docs/versioned_docs/version-v0.25/guide/06-loan.md
1007 views
---
---
DeFi loan module
As a rapidly growing industry in the blockchain ecosystem, (decentralized finance) DeFi is spurring innovation and revolution in spending, sending, locking, and loaning cryptocurrency tokens.
One of the many goals of blockchain is to make financial instruments available to everyone. A loan in blockchain DeFi can be used in combination with lending, borrowing, spot trading, margin trading, and flash loans.
With DeFi, end users can quickly and easily access loans without having to submit their passports or background checks like in the traditional banking system.
In this tutorial, you learn about a basic loan system as you use Ignite CLI to build a loan module.
You will learn how to
Scaffold a blockchain
Scaffold a Cosmos SDK loan module
Scaffold a list for loan objects
Create messages in the loan module to interact with the loan object
Interact with other Cosmos SDK modules
Use an escrow module account
Add application messages for a loan system
Request loan
Approve loan
Repay loan
Liquidate loan
Cancel loan
Note: The code in this tutorial is written specifically for this learning experience and is intended only for educational purposes. This tutorial code is not intended to be used in production.
Module design
A loan consists of:
An
id
The
amount
that is being lentA
fee
as cost for the loanThe borrowing party provides a
collateral
to request a loanA loan has a
deadline
for repayment, after which the loan can be liquidatedA loan has a
state
that describes the status as:requested
approved
paid
cancelled
liquidated
The two accounts involved in the loan are:
borrower
lender
The borrower
A borrower posts a loan request with loan information such as:
amount
fee
collateral
deadline
The borrower must repay the loan amount and the loan fee to the lender by the deadline risk losing the collateral.
The lender
A lender can approve a loan request from a borrower.
After the lender approves the loan, the loan amount is transferred to the borrower.
If the borrower is unable to pay the loan, the lender can liquidate the loan.
Loan liquidation transfers the collateral and the fees to the lender.
Scaffold the blockchain
Use Ignite CLI to scaffold a fully functional Cosmos SDK blockchain app named loan
:
The --no-module
flag prevents scaffolding a default module. Don't worry, you will add the loan module later.
Change into the newly created loan
directory:
Scaffold the module
Scaffold the module to create a new loan
module. Following the Cosmos SDK convention, all modules are scaffolded inside the x
directory:
Use the --dep
flag to specify that this module depends on and is going to interact with the Cosmos SDK bank
module.
Scaffold a list
Use the ignite scaffold list
command to scaffold code necessary to store loans in an array-like data structure:
Use the --no-message
flag to disable CRUD messages in the scaffold.
The data you store in an array-like data structure are the loans, with these parameters that are defined in the Loan
message in proto/loan/loan.proto
:
Later, you define the messages to interact with the loan list.
Now it is time to use messages to interact with the loan module. But first, make sure to store your current state in a git commit:
Scaffold the messages
In order to create a loan app, you need the following messages:
Request loan
Approve loan
Repay loan
Liquidate loan
Cancel loan
You can use the ignite scaffold message
command to create each of the messages.
You define the details of each message when you scaffold them.
Create the messages one at a time with the according application logic.
Request loan message
For a loan, the initial message handles the transaction when a username requests a loan.
The username wants a certain amount
and is willing to pay fees
as well as give collateral
. The deadline
marks the time when the loan has to be repaid.
The first message is the request-loan
message that requires these input parameters:
amount
fee
collateral
deadline
For the sake of simplicity, define every parameter as a string.
The request-loan
message creates a new loan object and locks the tokens to be spent as fee and collateral into an escrow account. Describe these conditions in the module keeper x/loan/keeper/msg_server_request_loan.go
:
Since this function is using the bankKeeper
with the function SendCoinsFromAccountToModule
, you must add the SendCoinsFromAccountToModule
function to x/loan/types/expected_keepers.go
like this:
Validate the input
When a loan is created, a certain message input validation is required. You want to throw error messages in case the end user tries impossible inputs.
You can describe message validation errors in the modules types
directory.
Add the following code to the ValidateBasic()
function in the x/loan/types/message_request_loan.go
file:
Congratulations, you have created the request-loan
message.
Run and test your first message
You can run the chain and test your first message.
Start the blockchain:
Add your first loan:
Query your loan:
The loan shows in the list:
You can stop the blockchain again with CTRL+C.
Save iterative changes
This is a good time to add your advancements to git:
Approve loan message
After a loan request has been published, another account can approve the loan and agree to the terms of the borrower.
The message approve-loan
has one parameter, the id
. Specify the type of id
as uint
. By default, ids are stored as uint
.
This message must be available for all loan types that are in "requested"
status.
The loan approval sends the requested coins for the loan to the borrower and sets the loan state to "approved"
.
Modify the x/loan/keeper/msg_server_approve_loan.go
to implement this logic:
This module uses the SendCoins
function of bankKeeper
. Add this SendCoins
function to the x/loan/types/expected_keepers.go
file:
Now, define the ErrWrongLoanState
new error type by adding it to the errors definitions in x/loan/types/errors.go
:
Start the blockchain and use the two commands you already have available:
Use the -r
flag to reset the blockchain state and start with a new database.
Now, request a loan from bob
:
Query your loan request:
Approve the loan:
This approve loan transaction sends the balances according to the loan request.
Check for the loan list again to verify that the loan state is now approved
.
You can query for alice's balance to see the loan in effect. Take the lender address from above, this is alice address:
In case everything works as expected, this is a good time to save the state with a git commit:
Repay Loan Message
After the loan has been approved, the username must be able to repay an approved loan.
Scaffold the message repay-loan
that a borrower uses to return tokens that were borrowed from the lender:
Repaying a loan requires that the loan is in "approved"
status.
The coins as described in the loan are collected and sent from the borrower to the lender, along with the agreed fees.
The collateral
is released from the escrow module account.
Only the borrower
can repay the loan.
This loan repayment logic is defined in x/loan/keeper/msg_server_repay_loan.go
:
After the coins have been successfully exchanged, the state of the loan is set to repayed
.
To release tokens with the SendCoinsFromModuleToAccount
function of bankKeepers
, you need to add the SendCoinsFromModuleToAccount
function to the x/loan/types/expected_keepers.go
:
Start the blockchain and use the two commands you already have available:
Use the -r
flag to reset the blockchain state and start with a new database:
Query your loan request:
Approve the loan:
You can query for alice's balance to see the loan in effect.
Take the lender address from above, this is alice address:
Now repay the loan:
The loan status is now repayed
:
The alice balance reflects the repayed amount plus fees:
Good job!
Update your git with the changes you made:
Liquidate Loan Message
After the deadline is passed, a lender can liquidate a loan when the borrower does not repay the tokens. The message to liquidate-loan
refers to the loan id
:
The
liquidate-loan
message must be able to be executed by thelender
.The status of the loan must be
approved
.The
deadline
block height must have passed.
When these properties are valid, the collateral shall be liquidated from the borrower
.
Add this liquidate loan logic to the keeper
in x/loan/keeper/msg_server_liquidate_loan.go
:
Add the new error ErrDeadline
to the error messages in x/loan/types/errors.go
:
These changes are required for the liquidate-loan
message.
Test liquidation message
You can test the liquidation message now. Start your chain and reset the state of the app:
Set the deadline for the loan request to 1 block:
Query your loan request:
Approve the loan:
You can query for alice's balances to see the loan in effect.
Take the lender address from above, this is alice address.
Now, liquidate the loan:
Query the loan:
The loan status is now liquidated
:
And alice balance reflects the repayed amount plus fees:
Add the changes to your local repository:
Cancel loan message
After a loan request has been made and not been approved, the borrower
must be able to cancel a loan request.
Scaffold the message for cancel-loan
:
Only the
borrower
can cancel a loan request.The state of the request must be
requested
.Then the collateral coins can be released from escrow and the status set to
cancelled
.
Add this functionality to the keeper
in x/loan/keeper/msg_server_cancel_loan.go
:
Test cancelling a loan
Test the changes for cancelling a loan request:
Query your loan request:
Query your loan request:
Now the collateral coins can be released from escrow and the status set to cancelled
.
Consider again updating your local repository with a git commit. After you test and use your loan module, consider publishing your code to a public repository for others to see your accomplishments.
Complete
Congratulations. You have completed the loan module tutorial.
You executed commands and updated files to:
Scaffold a blockchain
Scaffold a module
Scaffold a list for loan objects
Create messages in your module to interact with the loan object
Interact with other modules in your module
Use an escrow module account
Add application messages for a loan system
Request Loan
Approve Loan
Repay Loan
Liquidate Loan
Cancel Loan