Links

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. Protocol Lending feature is called “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 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.
The credit limit can be adjusted anytime by the admin multisig with a 2-hour timelock, and the change does not affect current borrowing but prevents 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. 1.
    Install Brownie & Ganache-CLI, if you haven't already.
  2. 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. 1.
      Make a copy of .env.example
    2. 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 on Etherscan. Submit the contract address to Iron Bank for review.

Resources