Compound 101-利率模型

WhitePaperInterestModel

基本的数据:

  • cash:资金池余额
  • borrows:总借款数
  • reserves:储备金

在此基础之上,衍生出的费率:

  • utilizationRate:资金利用率
  • borrowRate:借款利率
  • supplyRate:存款利率

资金利用率

$$ utilizationRate = borrows / ( cash + borrows - reserves ) $$

借款利率

这里借款利率与资金利用率成正比,即资金利用率越高,说明资金池中被借出的资金占比越高,需要通过提升借款利率来抑制借款需求

$$ borrowRate = k * utilizationRate + b $$

具体看这里的k和b怎么计算,以及分别代表什么含义

  • 当资金里利用率为0时,借款利率=b,则说明b代表的是基准利率,后续随着资金利用率提升,整体的借款利率都将大于这个数
  • k这里代表的是斜率,由协议方控制

值得注意的是,这里的所有数据和费率都是以区块为单位的,即这里可以理解为区块单位的借款/存款利率,因为以太坊一年的区块数量是基本固定的,可以推算出年借款利率等数据

function getBorrowRate(uint cash, uint borrows, uint reserves) override public view returns (uint) {
        uint ur = utilizationRate(cash, borrows, reserves);
        return (ur * multiplierPerBlock / BASE) + baseRatePerBlock;
}

存款利率

存款利率和资金利用率是成正比的,即资金利用率越高,说明资金池中被借出的资金占比越高,需要提升存款利率来鼓励用户存款

$$ supplyRate = utilizationRate * borrowRate * (1-reserveFactor) $$

function getSupplyRate(uint cash, uint borrows, uint reserves, uint reserveFactorMantissa) override public view returns (uint) {
        // reserveFactorMantissa 储备金率
        // 存款利率=资金利用率*借款利率*(1-储备金率)
        uint oneMinusReserveFactor = BASE - reserveFactorMantissa;
        uint borrowRate = getBorrowRate(cash, borrows, reserves);
        uint rateToPool = borrowRate * oneMinusReserveFactor / BASE;
        return utilizationRate(cash, borrows, reserves) * rateToPool / BASE;
  }

看一下以太坊主网上部署的利率模型的实际例子: (这里数字都是*18次方的,便于统一计算)

WhitePaper baseRate=50000000000000000 multiplier=150000000000000000

处理一下:base=0.005 multiplier=0.015

JumpRateModel

拐点型利率模型的特点就是在不同阶段,直线的斜率会变化(这里是立刻提高,以抑制借款)

因此模型由两部分组成:

  • y=k1x+b1 (x<x0)
  • y=k2x+b2 (x>x0)

其中最核心的就是两部分斜率k1 k2,以及临界值x0

和基础的利率模型一样,x代表资金利用率,在JumpRateModel合约中各参数分别对应的变量名如下:

  • k1: multiplierPerYear
  • k2: jumpMultiplierPerYear
  • x0: kink
  • b: baseRatePerYear

两部分直线都过点(kink, multiplierPerYear*kink+baseRatePerYear),带入到y=k2x+b2中,

得到 b2=multiplierPerYear*kink+baseRatePerYear-jumpMultiplierPerYear*kink

理解了这几个对应的变量后,第二部分的曲线公式可以整合为:

$$ borrowRate = jumpMultiplierPerYear * (x-kink) + multiplierPerYear*kink+baseRatePerYear $$

具体的实现代码如下:

function getBorrowRate(uint cash, uint borrows, uint reserves) override public view returns (uint) {
      uint util = utilizationRate(cash, borrows, reserves);

      if (util <= kink) {
          return (util * multiplierPerBlock / BASE) + baseRatePerBlock;
      } else {
          uint normalRate = (kink * multiplierPerBlock / BASE) + baseRatePerBlock;
          uint excessUtil = util - kink;
          return (excessUtil * jumpMultiplierPerBlock/ BASE) + normalRate;
      }
  }

存款利率的计算方式则和基础的保持一致

comments powered by Disqus