Query collateral factor via comptroller.markets():
Account Liquidity
How much can I borrow? We can query the maximal amount we can borrow via comptroller.getAccountLiquidity():
shortfall > 0 means borrowing amount exceeds limit and the collateral is facing liquidation. Under normal circumstances we want liquidity > 0 and shortfall == 0.
_liquidity is in USD.
Price Feed
USD price for borrowing token can be queried via priceFeed.getUnderlyingPrice():
We need this function to compute how many cTokens we can borrow, since _liquidity divided by price gives us the amount of cTokens we can borrow.
borrow() - borrower enters market and borrows loan
We are going to build the borrow() function on top of the helper functions we just wrote. Here is the plan:
Step 1: enter market
Step 2: check account liquidity (how much we can borrow in USD)
Step 3: calculate max amount of cTokens that we can borrow
Step 4: borrow 50% of max borrow
Step 1: enter market
Step 2: check account liquidity (how much we can borrow in USD)
Step 3: calculate max amount of cTokens that we can borrow
Step 4: borrow 50% of max borrow
Here is the complete implementation of borrow():
Two utility functions related to borrow:
repay() - borrower repays loan
Repay the borrowed cTokens via CErc20.repayBorrow():
// borrow and repay //
Comptroller public comptroller = Comptroller(0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B);
PriceFeed public priceFeed = PriceFeed(0x922018674c12a7F0D394ebEEf9B58F186CdE13c1);
// collateral
function getCollateralFactor() external view returns (uint) {
(bool isListed, uint colFactor, bool isComped) = comptroller.markets(
address(cToken)
);
return colFactor; // divide by 1e18 to get in %
}
// account liquidity - calculate how much can I borrow?
// sum of (supplied balance of market entered * col factor) - borrowed
function getAccountLiquidity()
external
view
returns (uint liquidity, uint shortfall)
{
// liquidity and shortfall in USD scaled up by 1e18
(uint error, uint _liquidity, uint _shortfall) = comptroller.getAccountLiquidity(
address(this)
);
// error == 0 means no error
require(error == 0, "error");
// normal circumstance - liquidity > 0 and shortfall == 0
// liquidity > 0 means account can borrow up to `liquidity`
// shortfall > 0 is subject to liquidation, you borrowed over limit
return (_liquidity, _shortfall);
}
// open price feed - USD price of token to borrow
function getPriceFeed(address _cToken) external view returns (uint) {
// scaled up by 1e18
return priceFeed.getUnderlyingPrice(_cToken);
}
// enter market
// enter the supply market so you can borrow another type of asset
address[] memory cTokens = new address[](1);
cTokens[0] = address(cToken);
uint[] memory errors = comptroller.enterMarkets(cTokens);
require(errors[0] == 0, "Comptroller.enterMarkets failed.");