当前位置:网站首页>Compound RateModel合約解析
Compound RateModel合約解析
2022-06-11 07:22:00 【33357】
原文發布在 https://github.com/33357/smartcontract-apps這是一個面向中文社區,分析市面上智能合約應用的架構與實現的倉庫。歡迎關注開源知識項目!
Compound RateModel合約解析
RateModel合約是用來計算 Compound 上特定代幣借貸利率的合約,分析它可以知道借貸利率的計算方法。
演示代碼倉庫:https://github.com/33357/compound-protocol
WhitePaperInterestRateModel.sol
直線型利率模型
合約初始化
- 公共函數(合約內外部都可以調用)
- constructor
- 代碼速覽
constructor(uint baseRatePerYear, uint multiplierPerYear) public { baseRatePerBlock = baseRatePerYear.div(blocksPerYear); multiplierPerBlock = multiplierPerYear.div(blocksPerYear); emit NewInterestParams(baseRatePerBlock, multiplierPerBlock); } - 參數分析
函數constructor的入參有 2 個,出參有 0 個,對應的解釋如下:constructor( uint baseRatePerYear, // 年基准利率 uint multiplierPerYear // 年利率乘數 ) public { ... } - 實現分析
... { // 塊基准利率 = 年基准利率 / 年塊數 baseRatePerBlock = baseRatePerYear.div(blocksPerYear); // 塊利率乘數 = 年利率乘數 / 年塊數 multiplierPerBlock = multiplierPerYear.div(blocksPerYear); // 觸發事件 NewInterestParams emit NewInterestParams(baseRatePerBlock, multiplierPerBlock); } - 總結
合約需要按block作為時間單比特來計算利率,因此需要將baseRatePerYear和multiplierPerYear轉換為baseRatePerBlock和multiplierPerBlock。這裏的blocksPerYear為2102400,是按照平均15秒一個block計算的。
- 代碼速覽
- constructor
資金借出率
- 公共函數(合約內外部都可以調用)
- utilizationRate
- 代碼速覽
function utilizationRate(uint cash, uint borrows, uint reserves) public pure returns (uint) { if (borrows == 0) { return 0; } return borrows.mul(1e18).div(cash.add(borrows).sub(reserves)); } - 參數分析
函數utilizationRate的入參有 3 個,出參有 1 個,對應的解釋如下:constructor( uint cash, // 代幣餘額 uint borrows, // 用戶借出代幣總數 uint reserves // 儲備代幣總數 ) public view returns ( uint // 資金借出率 ){ ... } - 實現分析
... { // 如果借出代幣總數為 0,資金借出率也為 0 if (borrows == 0) { return 0; } // borrows * 1e18 / (cash + borrows - reserves) return borrows.mul(1e18).div(cash.add(borrows).sub(reserves)); } - 總結
utilizationRate用於計算代幣的資金借出率,資金借出率的計算公式為資金借出率 = 借出代幣總數 / (代幣餘額 + 借出代幣總數 - 儲備代幣總數)。由於使用無符號整數計算資金借出率會精度不够,所以需要乘以1e18,擴大精度範圍。
- 代碼速覽
- utilizationRate
資金利率
- 公共函數(合約內外部都可以調用)
- getBorrowRate
- 代碼速覽
function getBorrowRate(uint cash, uint borrows, uint reserves) public view returns (uint) { uint ur = utilizationRate(cash, borrows, reserves); return ur.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock); } - 參數分析
函數getBorrowRate的入參有 3 個,出參有 1 個,對應的解釋如下:function getBorrowRate( uint cash, // 代幣餘額 uint borrows, // 用戶借出代幣總數 uint reserves // 儲備代幣總數 ) public view returns ( uint // 塊借出利率 ) { ... } - 實現分析
... { // 計算資金借出率 uint ur = utilizationRate(cash, borrows, reserves); // ur * multiplierPerBlock / 1e18 + baseRatePerBlock return ur.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock); } - 總結
getBorrowRate用於計算代幣的塊借出利率,塊借出利率的計算公式為塊借出利率 = 資金借出率 * 塊利率乘數 + 塊基准利率。由於資金借出率擴大了精度範圍,需要除以1e18得到實際值。
- 代碼速覽
- getSupplyRate
- 代碼速覽
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); } - 參數分析
函數getSupplyRate的入參有 4 個,出參有 1 個,對應的解釋如下:getSupplyRate( uint cash, // 代幣餘額 uint borrows, // 用戶借出代幣總數 uint reserves, // 儲備代幣總數 uint reserveFactorMantissa // 儲備金率 ) public view returns ( uint // 塊質押利率 ) { ... } - 實現分析
... { // 1 - reserveFactorMantissa uint oneMinusReserveFactor = uint(1e18).sub(reserveFactorMantissa); // 獲取借款利率 borrowRate uint borrowRate = getBorrowRate(cash, borrows, reserves); // borrowRate * (1 - reserveFactorMantissa) uint rateToPool = borrowRate.mul(oneMinusReserveFactor).div(1e18); // utilizationRate * borrowRate * (1 - reserveFactorMantissa) return utilizationRate(cash, borrows, reserves).mul(rateToPool).div(1e18); } - 總結
getSupplyRate用於計算代幣的塊質押利率,塊質押利率的計算公式為塊質押利率 = 資金借出率 * 借款利率 * (1 - 儲備金率) = 借款利率 * 資金借出率 * (1 - 儲備金率)。由於資金借出率擴大了精度範圍,需要除以1e18得到實際值。
- 代碼速覽
- getBorrowRate
BaseJumpRateModelV2.sol
拐點型利率模型
合約初始化
- 內部函數(僅合約內可以調用)
- constructor
- 代碼速覽
constructor(uint baseRatePerYear, uint multiplierPerYear, uint jumpMultiplierPerYear, uint kink_, address owner_) internal { owner = owner_; updateJumpRateModelInternal(baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink_); } - 參數分析
函數constructor的入參有 5 個,出參有 0 個,對應的解釋如下:constructor( uint baseRatePerYear, // 年基准利率 uint multiplierPerYear // 年利率乘數 uint jumpMultiplierPerYear, // 拐點年利率乘數 uint kink_, // 拐點資金借出率 address owner_ // 所有者 ) internal { ... } - 實現分析
... { // 記錄所有者 owner = owner_; // 更新拐點利率模型參數 updateJumpRateModelInternal(baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink_); } - 總結
拐點型利率模型比直線型利率模型多了拐點年利率乘數和拐點資金借出率這兩個參數。
- 代碼速覽
- updateJumpRateModelInternal
- 代碼速覽
function updateJumpRateModelInternal(uint baseRatePerYear, uint multiplierPerYear, uint jumpMultiplierPerYear, uint kink_) internal { baseRatePerBlock = baseRatePerYear.div(blocksPerYear); multiplierPerBlock = (multiplierPerYear.mul(1e18)).div(blocksPerYear.mul(kink_)); jumpMultiplierPerBlock = jumpMultiplierPerYear.div(blocksPerYear); kink = kink_; emit NewInterestParams(baseRatePerBlock, multiplierPerBlock, jumpMultiplierPerBlock, kink); } - 參數分析
函數updateJumpRateModelInternal的入參有 4 個,出參有 0 個,對應的解釋如下:function updateJumpRateModelInternal( uint baseRatePerYear, // 年基准利率 uint multiplierPerYear // 年利率乘數 uint jumpMultiplierPerYear, // 拐點年利率乘數 uint kink_, // 拐點資金借出率 ) internal { ... } - 實現分析
... { // 塊基准利率 = 年基准利率 / 年塊數 baseRatePerBlock = baseRatePerYear.div(blocksPerYear); // 塊利率乘數 = 年基准利率 / (年塊數 * 拐點資金借出率) multiplierPerBlock = (multiplierPerYear.mul(1e18)).div(blocksPerYear.mul(kink_)); // 拐點塊利率乘數 = 拐點年利率乘數 / 年塊數 jumpMultiplierPerBlock = jumpMultiplierPerYear.div(blocksPerYear); // 記錄拐點資金借出率 kink = kink_; // 觸發事件 NewInterestParams emit NewInterestParams(baseRatePerBlock, multiplierPerBlock, jumpMultiplierPerBlock, kink); } - 總結
拐點型利率模型中計算塊利率乘數時,方法和直線型利率模型不一樣:拐點資金借出率越高,塊利率乘數越低,其目的我不是很清楚。(可能是拐點資金借出率越高的代幣市場深度越好,塊利率乘數可以設置的更低,大家可以討論一下)
- 代碼速覽
- constructor
資金借出率
- 公共函數(合約內外部都可以調用)
- utilizationRate
- 代碼速覽
function utilizationRate(uint cash, uint borrows, uint reserves) public pure returns (uint) { if (borrows == 0) { return 0; } return borrows.mul(1e18).div(cash.add(borrows).sub(reserves)); } - 參數分析
函數utilizationRate的入參有 3 個,出參有 1 個,對應的解釋如下:constructor( uint cash, // 代幣餘額 uint borrows, // 用戶借出代幣總數 uint reserves // 儲備代幣總數 ) public view returns ( uint // 資金借出率 ){ ... } - 實現分析
... { // 如果借出代幣總數為 0,資金借出率也為 0 if (borrows == 0) { return 0; } // 資金借出率 = borrows * 1e18 / (cash + borrows - reserves) return borrows.mul(1e18).div(cash.add(borrows).sub(reserves)); } - 總結
拐點型利率模型中計算資金借出率和直線型利率模型相同。
- 代碼速覽
- utilizationRate
資金利率
- 內部函數(僅合約內部可以調用)
- getBorrowRate
- 代碼速覽
function getBorrowRateInternal(uint cash, uint borrows, uint reserves) internal 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); } } - 參數分析
函數getBorrowRateInternal的入參有 3 個,出參有 1 個,對應的解釋如下:function getBorrowRate( uint cash, // 代幣餘額 uint borrows, // 用戶借出代幣總數 uint reserves // 儲備代幣總數 ) internal view returns ( uint // 塊借出利率 ) { ... } - 實現分析
{ // 獲取資金借出率 util uint util = utilizationRate(cash, borrows, reserves); // 如果 util < kink if (util <= kink) { // return util * multiplierPerBlock + baseRatePerBlock return util.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock); } else { // 拐點前塊借出利率 = kink * multiplierPerBlock + baseRatePerBlock uint normalRate = kink.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock); // 超出拐點資金借出率 = util - kink uint excessUtil = util.sub(kink); // 塊借出利率 = (util - kink) * jumpMultiplierPerBlock + kink * multiplierPerBlock + baseRatePerBlock return excessUtil.mul(jumpMultiplierPerBlock).div(1e18).add(normalRate); } } - 總結
拐點型利率模型中計算塊借出利率的計算公式分為兩部份:在資金借出率低於拐點資金借出率時,計算公式為:塊借出利率 = 資金借出率 * 塊利率乘數 + 塊基准利率;在資金借出率高於拐點資金借出率時,計算公式為:塊借出利率 = (資金借出率 - 拐點資金借出率) * 拐點塊利率乘數 + 拐點資金借出率 * 塊利率乘數 + 塊基准利率。
- 代碼速覽
- getSupplyRate
- 代碼速覽
function getSupplyRate(uint cash, uint borrows, uint reserves, uint reserveFactorMantissa) public view returns (uint) { uint oneMinusReserveFactor = uint(1e18).sub(reserveFactorMantissa); uint borrowRate = getBorrowRateInternal(cash, borrows, reserves); uint rateToPool = borrowRate.mul(oneMinusReserveFactor).div(1e18); return utilizationRate(cash, borrows, reserves).mul(rateToPool).div(1e18); } - 參數分析
函數getSupplyRate的入參有 4 個,出參有 1 個,對應的解釋如下:getSupplyRate( uint cash, // 代幣餘額 uint borrows, // 用戶借出代幣總數 uint reserves, // 儲備代幣總數 uint reserveFactorMantissa // 儲備金率 ) public view returns ( uint // 塊質押利率 ) { ... } - 實現分析
... { // 1 - reserveFactorMantissa uint oneMinusReserveFactor = uint(1e18).sub(reserveFactorMantissa); // 獲取借款利率 borrowRate uint borrowRate = getBorrowRateInternal(cash, borrows, reserves); // rateToPool = borrowRate * (1 - reserveFactorMantissa) uint rateToPool = borrowRate.mul(oneMinusReserveFactor).div(1e18); // 塊質押利率 = utilizationRate * borrowRate * (1 - reserveFactorMantissa) return utilizationRate(cash, borrows, reserves).mul(rateToPool).div(1e18); } - 總結
拐點型利率模型中計算資金質押利率和直線型利率模型相同。
- 代碼速覽
- getBorrowRate
边栏推荐
- 二、用户登录和注册
- Android和iOS逆向分析/安全检测/渗透测试框架
- Leetcode-9. Palindrome Numbber
- Regular Expression Matching
- Calculate the day of the week for a specific month, year and day
- 一、SQLServer2008安裝(帶密碼)、創建數據庫、C#窗體項目測試
- 【CF#654 (Div. 2)】A. Magical Sticks
- Web API、DOM
- [STL source code analysis] summary notes (10): hashtable exploration
- JVM Learning record (7) - - class Loading Process and parent delegation Model
猜你喜欢

2022 low voltage electrician operation certificate test question simulation test platform operation

Directrix of ellipse

1、 Sqlserver2008 installation (with password), database creation, C form project test

教育专家王中泽老师多年经验分享:家庭教育不是附庸品

2、 User login and registration

Detailed explanation of mutationobserver

Gobang interface of mobile console (C language)

QT interface nested movement based on qscrollarea

Leetcode-141. Linked List Cycle

Building a full-featured NAS server with raspberry pie (05): playing with video and audio & sorting out movies
随机推荐
Crmeb/v4.4 Standard Version open version mall source code applet official account h5+app mall source code
2022年熔化焊接与热切割考试练习题及答案
Error occurred in pycharm DeprecatedEnv: Env FrozenLake-v0 not found (valid versions include [‘FrozenLake-v1‘])
P5431 [template] multiplicative inverse 2
Mistakes in Niuke JS exercise
资深OpenStacker - 彭博、Vexxhost升级为OpenInfra基金会黄金成员
Decimal to binary
【CF#262 (Div. 2)】 A. Vasya and Socks
Leetcode-9. Palindrome Numbber
[STL source code analysis] summary notes (7): ingenious deque
Atomicinteger atomic operation class
[advanced concurrency] - thread pool summary
模块化笔记
[deploy private warehouse based on harbor] 3 deploy harbor
Janus feature草稿
Promises/a+ standard Chinese Translation
[deploy private warehouse based on harbor] 4 push image to harbor
[并发进阶]——线程池总结
MS office level II wrong question record [8]
[analysis of STL source code] summary note (4): behind the scenes hero allocator