compound-finance compound-protocol 存和借利率合约分析
计算每块供应率
(github)
/**
* @notice Returns the current per-block supply interest rate for this cToken
* @return The supply interest rate per block, scaled by 1e18
*/
function supplyRatePerBlock() external view returns (uint) {
return interestRateModel.getSupplyRate(getCashPrior(), totalBorrows, totalReserves, reserveFactorMantissa);
}
返回-每块的供应利率,按1e18缩放
跟一下关键参数
getCashPrior()
(github)
/**
* @notice Gets balance of this contract in terms of the underlying
* @dev This excludes the value of the current message, if any
* @return The quantity of underlying tokens owned by this contract
*/
function getCashPrior() internal view returns (uint) {
EIP20Interface token = EIP20Interface(underlying);
return token.balanceOf(address(this));
}
代码逻辑为,获取当前合约地址拥有的基础代币余额数量
totalBorrows
借出的代币总数
totalReserves
存入的代币总数(储备金)
reserveFactorMantissa
市场的当前储备系数
getSupplyRate
(github)
/**
* @notice Calculates the current supply rate per block
* @param cash The amount of cash in the market
* @param borrows The amount of borrows in the market
* @param reserves The amount of reserves in the market
* @param reserveFactorMantissa The current reserve factor for the market
* @return The supply rate percentage per block as a mantissa (scaled by 1e18)
*/
function getSupplyRate(uint cash, uint borrows, uint reserves, uint reserveFactorMantissa) public view returns (uint) {
uint oneMinusReserveFactor = uint(1e18).sub(reserveFactorMantissa); // 单量减去储备的系数
uint borrowRate = getBorrowRate(cash, borrows, reserves); // 获取借出的利率
uint rateToPool = borrowRate.mul(oneMinusReserveFactor).div(1e18); // 将借出的利率缩小储备系数倍数
return utilizationRate(cash, borrows, reserves).mul(rateToPool).div(1e18); // 市场利用率/缩小储备系数后的借出利率
}
附加
add sub mul div
来自SafeMath
库,对等是加减乘除
utilizationRate 计算市场利用率
(github)
/**
* @notice Calculates the utilization rate of the market: `borrows / (cash + borrows - reserves)`
* @param cash The amount of cash in the market
* @param borrows The amount of borrows in the market
* @param reserves The amount of reserves in the market (currently unused)
* @return The utilization rate as a mantissa between [0, 1e18]
*/
function utilizationRate(uint cash, uint borrows, uint reserves) public pure returns (uint) {
// Utilization rate is 0 when there are no borrows
if (borrows == 0) {
return 0;
}
return borrows.mul(1e18).div(cash.add(borrows).sub(reserves)); // 借出/(账户剩余+借出-存入)
// 借出,就是发币合约把代币转给其他的账户,当其他账户存币时,再转回发币合约账户
}
getBorrowRate 获取每个块的当前借入利率
/**
* @notice Calculates the current borrow rate per block, with the error code expected by the market
* @param cash The amount of cash in the market
* @param borrows The amount of borrows in the market
* @param reserves The amount of reserves in the market
* @return The borrow rate percentage per block as a mantissa (scaled by 1e18)
*/
function getBorrowRate(uint cash, uint borrows, uint reserves) public view returns (uint) {
uint util = utilizationRate(cash, borrows, reserves); //计算市场利用率
if (util <= kink) {
return util.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);
} else {
uint normalRate = kink.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);
uint excessUtil = util.sub(kink);
return excessUtil.mul(jumpMultiplierPerBlock).div(1e18).add(normalRate);
}
}
kink
应用跳转乘数的利用率点,当利用率小于这个配置值时,走相应逻辑
multiplierPerBlock
利用率乘数,得出利率的斜率
multiplierPerYear
利用率的利率增长率(按1e18缩放
multiplierPerBlock = multiplierPerYear.div(blocksPerYear);
jumpMultiplierPerBlock
jumpMultiplierPerBlock = jumpMultiplierPerYear.div(blocksPerYear);
baseRatePerYear
初始值,每年的基础利率
blocksPerYear
利率模型假设的每年大约的块数
baseRatePerBlock
基本利率是利用率为0时的y截距,
baseRatePerBlock = baseRatePerYear.div(blocksPerYear);
jumpMultiplierPerBlock
达到指定的利用率点后的multiplierPerBlock
总结
稍后补充