计算每块供应率
(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

总结

稍后补充

参考

https://www.jinse.com/blockchain/485426.html