Create a Collateralized Loan Smart Contract

Posted By : Suchit

Jan 31, 2024

This article explores collateralized loans, a financial frontier where traditional borrowing meets the cutting-edge brilliance of blockchain technology. You'll gain insights into how smart contract development revolutionizes borrowing and lending by creating your own collateralized loan smart contract.

 

Understanding Collateralized Loans

 

At the heart of collateralized loans lies a fundamental concept: mitigating risk through collateral. Imagine you need funds, and lenders seek assurance. This is where collateral swoops in as the financial guardian. It's not merely a precautionary measure; it's a strategic tool ensuring a trustless secure relationship between borrowers and lenders. 

 

Collateralized loans elevate security that redefines the borrowing and lending landscape. For lenders, these loans inherently offer greater safety than non-collateralized alternatives, leading to lower interest rates.

 

Smart Contract Implementation: CryptoCollateralizedLoan

 

In the following section, we go through a collateralized loan smart contract named "CryptoCollateralizedLoan" that facilitates the issuance and repayment of loans using ERC-20 tokens as collateral and Ether as borrowed assets. Borrowers can request loans by locking up a specified amount of collateral, and repay the loan along with accrued interest at a later time.

 

Also, Check | Top 5 Smart Contract Development Companies

 

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract CryptoCollateralizedLoan {
    struct LoanInfo {
        address borrower;
        uint256 borrowedAmount;
        uint256 collateralAmount;
        uint256 requestedAt;
        bool paid;
    }

    ERC20 public collateralToken;
    uint256 public interestRate;
    uint256 public minCollateralizationRatio;
    mapping(address => LoanInfo) public loans;

    event LoanGranted(
        address borrower,
        uint256 borrowedAmount,
        uint256 collateralAmount
    );
    event LoanRepaid(address borrower, uint256 repaidAmount);

    constructor(
        ERC20 _collateralToken,
        uint256 _interestRate,
        uint256 _minCollateralizationRatio
    ) {
        collateralToken = _collateralToken;
        interestRate = _interestRate;
        minCollateralizationRatio = _minCollateralizationRatio;
    }

    function requestLoan(
        uint256 _borrowedAmount,
        uint256 _collateralAmount
    ) public {
        LoanInfo storage initialLoanInfo = loans[msg.sender];

        require(
            initialLoanInfo.collateralAmount == 0 ||
                (initialLoanInfo.collateralAmount > 0 &&
                    initialLoanInfo.paid == true),
            "Active loan"
        );
        uint256 extraAmountToliquidate = (_borrowedAmount *
            minCollateralizationRatio) / 100;
        require(
            _collateralAmount >= (_borrowedAmount + extraAmountToliquidate),
            "Insufficient collateral"
        );

        collateralToken.transferFrom(
            msg.sender,
            address(this),
            _collateralAmount
        );

        LoanInfo memory loanInfo = LoanInfo({
            borrower: msg.sender,
            borrowedAmount: _borrowedAmount,
            collateralAmount: _collateralAmount,
            requestedAt: block.timestamp,
            paid: false
        });

        _sendEthersTo(msg.sender, loanInfo.borrowedAmount);

        loans[msg.sender] = loanInfo;

        emit LoanGranted(msg.sender, _borrowedAmount, _collateralAmount);
    }

    function repayLoan() public payable {
        LoanInfo storage loanInfo = loans[msg.sender];
        require(loanInfo.borrowedAmount > 0, "No active loan");
        uint256 collateralizationRatio = _calculateCollateralizationRatio(
            loanInfo
        );
        require(
            collateralizationRatio < minCollateralizationRatio,
            "Collateralization ratio above minimum"
        );
        uint256 outstandingAmount = _calculateOutstandingAmount(loanInfo);

        require(msg.value >= outstandingAmount, "Insufficient funds");

        collateralToken.transfer(msg.sender, loanInfo.collateralAmount);

        loanInfo.paid = true;

        emit LoanRepaid(msg.sender, loanInfo.borrowedAmount);
    }

    function _sendEthersTo(
        address _receiver,
        uint256 _amount
    ) private returns (bool) {
        (bool sent, ) = payable(_receiver).call{value: _amount}("");
        require(sent, "Ether transfer failed");
        return sent;
    }

    function _calculateOutstandingAmount(
        LoanInfo storage loanInfo
    ) private view returns (uint256) {
        uint256 timeElapsed = block.timestamp - loanInfo.requestedAt;
        uint256 interestAccrued = (loanInfo.borrowedAmount *
            interestRate *
            timeElapsed) / (100 * 365 days);
        return loanInfo.borrowedAmount + interestAccrued;
    }

    function _calculateCollateralizationRatio(
        LoanInfo storage loanInfo
    ) private view returns (uint256) {
        uint256 outstandingAmount = _calculateOutstandingAmount(loanInfo);
        uint256 diff = outstandingAmount - loanInfo.borrowedAmount;

        return
            (diff * 100) /
            loanInfo.borrowedAmount;
    }

    receive() external payable {}
}

 

This contract, named CryptoCollateralizedLoan, utilizes the Ethereum blockchain to implement a secure, transparent, and efficient framework for collateralized loans. 

 

Let's dissect the variables, events, and functions embedded within this smart contract to gain a comprehensive understanding of its inner workings and the advantages it offers to both borrowers and lenders alike.

 

State Variables

 

  • collateralToken: An instance of the ERC20 token used as collateral.
  • interestRate: The annual interest rate applied to outstanding loans.
  • minCollateralizationRatio: The minimum collateralization ratio required for a loan to avoid liquidation.
  • loans: A mapping of borrower addresses to their respective loan information.

 

Struct

 

  • LoanInfo: Represents the details of a loan, including the borrower's address, borrowed amount, collateral amount, request timestamp, and loan status.

 

Events

 

  • LoanGranted(address indexed borrower, uint256 borrowedAmount, uint256 collateralAmount): Emitted when a loan is successfully granted.
  • LoanRepaid(address indexed borrower, uint256 repaidAmount): Emitted when a borrower repays their loan.

 

Constructor

 

  • constructor(ERC20 _collateralToken, uint256 _interestRate, uint256 _minCollateralizationRatio): Initializes the contract with the specified ERC20 collateral token, interest rate, and minimum collateralization ratio.

 

Functions

 

  • requestLoan(uint256 _borrowedAmount, uint256 _collateralAmount) external: It allows a borrower to request a loan by providing a borrowed amount and collateral amount. The collateral is transferred to the contract, and the borrower receives the borrowed amount. This function ensures there is no active loan for the user. It validates that the collateral provided meets the required threshold.

 

  • repayLoan() external payable: This function allows a borrower to repay their outstanding loan along with accrued interest. The borrower must send sufficient Ether to cover the outstanding amount. The function verifies the existence of an active loan, checks if the collateralization ratio is below the minimum threshold, and requires sufficient funds to cover the outstanding amount.

 

Also, Read | Code Analysis Tools for Solidity Smart Contracts

 

Private Functions

 

  • _sendEthersTo(address _receiver, uint256 _amount) private returns (bool): Internal function to send Ether to a specified address.
  • _calculateOutstandingAmount(LoanInfo storage loanInfo) private view returns (uint256): Computes the outstanding amount considering the borrowed amount, time elapsed, and accrued interest.
  • _calculateCollateralizationRatio(LoanInfo storage loanInfo) private view returns (uint256): Calculates the collateralization ratio based on the outstanding and borrowed amounts.

 

Receive Function

 

  • receive() external payable: Allows the contract to receive Ether.

 

You may also like | Best Practices for Smart Contract Development

 

Conclusion

 

By leveraging the power of blockchain technology, this contract introduces a secure and transparent platform for collateralized loans. By leveraging collateral as a key feature, this contract establishes a trustless framework that empowers borrowers and lenders.

 

Looking for smart contract development services? Get in touch with our smart contract developers to discuss your project requirements. 

Leave a

Comment

Name is required

Invalid Name

Comment is required

Recaptcha is required.

blog-detail

April 4, 2024 at 08:00 am

Your comment is awaiting moderation.

By using this site, you allow our use of cookies. For more information on the cookies we use and how to delete or block them, please read our cookie notice.

Chat with Us
Contact Us

Oodles | Blockchain Development Company

Name is required

Please enter a valid Name

Please enter a valid Phone Number

Please remove URL from text