Protocol Lending

Protocol Lending is the feature that enables protocols and developers to leverage liquidity in Iron Bank without direct collateralization.

Overview

Protocol Lending allows protocols and developers to borrow assets without direct collateralization. The liquidity comes from the shared markets where users supply and borrow. That is, the same Interest Rate Model, Utilization Rate and Borrow APY apply to a Protocol Lending user. For more information about market stats, visit Iron Bank Markets.

Currently, the Protocol Lending feature is by permission only. The Iron Bank team reviews borrower's contracts and protocol model to come up with a risk assessment report, and the report is made public to the Iron Bank community. As mentioned, the Protocol Lending user borrows from the shared markets where normal users supply. Therefore, it is necessary to evaluate the Protocol Lending risk from all perspectives.

The Protocol Lending feature is called a "Credit Loan" as a dev shorthand.

Risk Assessment

Besides contract security, the Iron Bank team also reviews the protocol model to evaluate and confirm the following:

  • The borrower is a contract

  • The destination of fund is deterministic

  • Iron Bank is senior debt

To elaborate, the borrower must be a contract deployed on the chain of which it wishes to borrow, the borrowed funds go to where the contract predefines without exception, and Iron Bank must be the top priority for the contract to repay before the funds are distributed or utilized for other purposes. This is how we review the Protocol Lending requests, and also how we ensure the funds come back to Iron Bank eventually.

For risk assessment example, visit Alpha Homora Risk Assessment (Optimism).

Credit Limit

By having a credit limit, a Protocol Lending user can borrow to the limit from the designated market. It is decided by the Iron Bank team, depending on the risk assessment report.

A credit limit is set for a designated market. Meaning, a Protocol Lending user may not borrow more than their limit and they may only borrow predetermined tokens. For now, the Iron Bank team decides these settings depending on the risk assessment report.

Credit limit can be adjusted anytime by the admin multisig with a 2-hour timelock. If credit limit is decreased to the level lower than current borrowing, it would not affect the current borrowing but prevent Protocol Lending users from borrowing more than the new limit.

In times of emergency, the guardian can reduce the credit limit of any Protocol Lending address to $1 for a specific account without timelock, preventing the account from borrowing further.

Installation

Protocol Lending is an advanced concept aimed at protocol developers. You must have a good understanding of EVM, programming, and smart contracts to be able to proceed.

Installation and Setup

  1. Install Brownie & Ganache-CLI, if you haven't already.

  2. Sign up for Infura and generate an API key. Store it in the WEB3_INFURA_PROJECT_ID environment variable.

export WEB3_INFURA_PROJECT_ID=YourProjectID
  • Optional Use network-config.yaml provided in the repo. NOTE: This will replace your network config globally

cp network-config.yaml ~/.brownie/

3. Sign up for Etherscan and generate an API key. This is required for fetching source codes of the mainnet contracts we will be interacting with. Store the API key in the ETHERSCAN_TOKEN environment variable.

export ETHERSCAN_TOKEN=YourApiToken
  • Optional Use .env file

    1. Make a copy of .env.example

    2. Add the values for ETHERSCAN_TOKEN or OPSCAN_TOKEN according to the network you are going to develop on.

4. Download the mix.

git clone [email protected]:ibdotxyz/ib-creditloan-mix.git

Basic Use

To perform a simple credit loan in a development environment:

1. Run scripts/setup_playground.py to create an officer for our credit borrower and launch the console. This automatically launches Ganache on a forked mainnet.

$ brownie run scripts/setup_playground.py --network mainnet-fork --interactive

2. Deploy the CreditBorrower.sol contract.

>>> token = credit_officer.borrowToken()
>>> credit_borrower = CreditBorrower.deploy(accounts[0], token, credit_officer, {"from": accounts[0]})
Transaction sent: 0xb173db83eeee9b35abe557f963543e0579bd3e79f710ece407e763428a0aeea1
  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 6
  CreditBorrower.constructor confirmed   Block: 15547377   Gas used: 395321 (3.29%)
  CreditBorrower deployed at: 0x9E4c14403d7d9A8A782044E86a93CAE09D7B2ac9

3. Set the borrower to the newly deployed contract. We must do this because we only approved borrower contract that has been reviewed.

>>> credit_officer.setBorrower(credit_borrower, {"from": ib_admin})
Transaction sent: 0xe1a4b986f14d62ad7c71e3528af8fce41eb6a4560af423ecb50db23e6e5f304c
  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 3
  CreditOfficer.setBorrower confirmed   Block: 15547378   Gas used: 43452 (0.36%)

4. Borrow some DAI from Iron Bank.

>>> credit_borrower.borrow(100_000 * 10 ** 18, {"from": accounts[0]})
Transaction sent: 0xa24bed673ed9eb23ce1cecae261394c73cba518aeecb6aa3730f331d26111d2a
  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 7
  CreditBorrower.borrow confirmed   Block: 15547379   Gas used: 346029 (2.88%)

5. Now we are ready to put our borrower into work!

>>> credit_borrower.work({"from": accounts[0]})
Transaction sent: 0x7c6bdd7f0b80547ca81583de4cdca92b240a2014b4732114140ddc074fe8b7ca
  Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 8
  CreditBorrower.work confirmed   Block: 15547380   Gas used: 22115 (0.18%)

Implementing Credit Loan Logic

contracts/CreditBorrower.sol is where you implement your own logic for credit loans. In particular:

  • Fill in a way to calculate the total balance of the asset that are able to be repaid via CreditBorrower.totalBalance()

  • Unwind enough of your position to payback debt via CreditBorrower.askForRepay()

  • The destination of fund should be deterministic.

  • Iron Bank should be senior debt.

  • Decentralized oracle should be used to evaluate assets that are not the borrowed token.

  • All operations and roles will be reviewed by Iron Bank.

See the Iron Bank documentation on Credit Limit Assessment for more information.

Testing

To run the tests:

brownie test

See the Brownie documentation for more detailed information on testing your project.

Debugging Failed Transactions

Use the --interactive flag to open a console immediatly after each failing test:

brownie test --interactive

Within the console, transaction data is available in the history container:

>>> history
[<Transaction '0x50f41e2a3c3f44e5d57ae294a8f872f7b97de0cb79b2a4f43cf9f2b6bac61fb4'>,
 <Transaction '0xb05a87885790b579982983e7079d811c1e269b2c678d99ecb0a3a5104a666138'>]

Examine the TransactionReceipt for the failed test to determine what went wrong. For example, to view a traceback:

>>> tx = history[-1]
>>> tx.traceback()

To view a tree map of how the transaction executed:

>>> tx.call_trace()

See the Brownie documentation for more detailed information on debugging failed transactions.

Deployment

You should write your own deployment script and verify it on Etherscan. Submit the contract address to Iron Bank for review.

Resources

Last updated