Overview
Contracts
We have four main contracts in our Protocol, and they are SavingAccount, Accounts, Bank, TokenRegistry, and GlobalConfig.
The first three contracts are upgradable contracts, and they contain the main business logic of our Protocol. The overall structure of our Protocol is monolithic, which means that SavingAccount, Accounts, and Bank contracts work closely with each other. We decoupled this into three contracts only for code size limit reasons. The naming here maybe a little counter intuitive. Normally when we want to deposit money to a bank, we first go to the bank and open a saving account, then we deposit money to this account. Here, SavingAccount contract behaves like a traditional bank, which is the entry point for you to deposit or borrow money from DeFiner. The Bank contract records the state of the pool of DeFiner's protocol, like the total deposit, total borrow, and the current rate. The Accounts contract records the deposit and borrow balances for each specific user.
The workflow of a transaction to DeFiner works as the following diagram. The user sends transactions by calling functions on SavingAccount contract, then the SavingAccount contract will call the Bank contract to create a rate index checkpoint, which is used to compute the accumulated interests for all the user. Then the Bank contract will call the functions in Account contract to compute the balance change in the user account.
The TokenRegistry and GlobalConfig contracts are used to save data that will be used among the three main contracts. Like all three contracts' addresses, so in these three contract, they only need to keep global config's address in contract's memory space.
SavingAccount
This is the interface contract that our users will mainly interact with. Users will send transactions to this contract to do deposit, withdraw, borrow, repay, withdrawAll, and liquidate functions to this contract to interact with our protocol. For each operation, this contract is the contract that receives and sends out the tokens. Whenever there is a transaction sent to SavingAccount contract, it will emit an event to log this transaction.
Borrowing Power
The borrowing power of a user is related to the collateral that the user deposited into our system. The price is obtained from Chainlink's oracle. If the LTV of a user is too large then it is at the risk of being liquidated. Currently, the liquidation threshold is set to around 0.8.
Bank
This contract is used to create rate indexes whenever there is an interaction with our SavingAccount contract. We are using rate indexes to compute the borrow and deposit interests. Given the different indexes, we compute the user balances here. Whenever an index is created, this contract will emit an event.
Rate Index
i and j here represent two different blocks.
Balance
i and j here represent two different blocks.
Borrow balances and deposit balances both use this method to compute.
Accounts
This contract is used to record the balances of each user account for different tokens. This contract also contains a BitMap which will quickly show whether a user has depositings/borrowings for each token while costs less gas.
GlobalConfig
This contract is used to store all the contract's addresses, so all other contracts can only keep GlobalConfig's address to call functions of other contracts. It also used to config the reserve ratio and community fund ratio of the protocol.
TokenRegistry
This contract records the meta-data about each contract supported token. We can add new supported tokens using this contract.
Current Supported Tokens
DAI
Token Address: 0x6b175474e89094c44da98b954eedeac495271d0f
cToken Address: 0x5d3a536e4d6dbd6114cc1ead35777bab948e3643
USDC
Token Address: 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
cToken Address: 0x39aa39c021dfbae8fac545936693ac917d5e7563
USDT
Token Address: 0xdac17f958d2ee523a2206206994597c13d831ec7
cToken Address: 0xf650c3d88d12db855b8bf7d11be6c55a4e07dcc9
TUSD
Token Address: 0x0000000000085d4780B73119b644AE5ecd22b376
cToken Address: Not Compound supported.
MKR
Token Address: 0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2
cToken Address: Not Compound supported.
BAT
Token Address: 0x0d8775f648430679a709e98d2b0cb6250d2887ef
cToken Address: 0x6c8c6b02e7b2be14d4fa6022dfd6d75921d90e4e
ZRX
Token Address: 0xe41d2489571d322189246dafa5ebde1f4699f498
cToken Address: 0xb3319f5d18bc0d84dd1b4825dcde5d5f7266d407
REP
Token Address: 0x1985365e9f78359a9B6AD760e32412f4a445E862
cToken Address: 0x158079ee67fce2f58472a96584a73c7ab9ac95c1
WBTC
Token Address: 0x2260fac5e5542a773aa44fbcfedf7c193bc2c599
cToken Address: 0xc11b1268c1a384e55c48c2391d8d480264a3a7f4
FIN
Token Address: 0x054f76beED60AB6dBEb23502178C52d6C5dEbE40
cToken Address: Not Compound supported
FIN LPToken
Token Address: 0x054f76beED60AB6dBEb23502178C52d6C5dEbE40
cToken Address: Not Compound supported
Upgradability
For SavingAccount, Accounts, and Bank contracts, we are using OpenZeppelin proxies to conduct the upgrading process. So other than the contracts, we also have an OpenZeppelin proxy contract for each of these three main contracts. The proxy contract addresses can never be changed, but the contract of the underlying implementation is changeable.
For the GlobalConfig and TokenRegistry contracts, we can deploy a new contract and call the setter function in three main contracts to point to the new contracts, since they don't save any transactional data.
Last updated