当前位置:网站首页>Compound ratemodel contract analysis

Compound ratemodel contract analysis

2022-06-11 07:24:00 thirty-three thousand three hundred and fifty-seven

The original is published in https://github.com/33357/smartcontract-apps This is a Chinese community , Analyze the architecture and implementation of smart contract application on the market . Welcome to the open source knowledge project !

Compound RateModel Contract analysis

RateModel The contract is used to calculate Compound A contract with a specific token lending rate , By analyzing it, we can know how to calculate the loan interest rate .

Demonstrate the code warehouse :https://github.com/33357/compound-protocol

WhitePaperInterestRateModel.sol

Linear interest rate model

Contract initialization

  • Public function ( Both inside and outside the contract can call )
    • constructor
      • Code overview
        constructor(uint baseRatePerYear, uint multiplierPerYear) public {
                  
            baseRatePerBlock = baseRatePerYear.div(blocksPerYear);
            multiplierPerBlock = multiplierPerYear.div(blocksPerYear);
            emit NewInterestParams(baseRatePerBlock, multiplierPerBlock);
        }
        
      • Parametric analysis
        function constructor The input parameters are 2 individual , Out of ginseng 0 individual , The corresponding explanation is as follows :
        constructor(
            uint baseRatePerYear, //  Annual benchmark interest rate 
            uint multiplierPerYear //  Annual interest rate multiplier 
        ) public {
                  
            ...
        }
        
      • Implementation analysis
        ...
        {
                  
            //  Block benchmark interest rate  =  Annual benchmark interest rate  /  Number of blocks per year 
            baseRatePerBlock = baseRatePerYear.div(blocksPerYear);
            //  Block rate multiplier  =  Annual interest rate multiplier  /  Number of blocks per year 
            multiplierPerBlock = multiplierPerYear.div(blocksPerYear);
            //  Triggering event  NewInterestParams
            emit NewInterestParams(baseRatePerBlock, multiplierPerBlock);
        }
        
      • summary
        The contract needs to be block Calculate interest rates as time units , Therefore, it is necessary to baseRatePerYear and multiplierPerYear Convert to baseRatePerBlock and multiplierPerBlock. there blocksPerYear by 2102400, Is on average 15 second One block Calculated .

Lending rate of funds

  • Public function ( Both inside and outside the contract can call )
    • utilizationRate
      • Code overview
        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));
        }
        
      • Parametric analysis
        function utilizationRate The input parameters are 3 individual , Out of ginseng 1 individual , The corresponding explanation is as follows :
        constructor(
            uint cash, //  Token balance 
            uint borrows, //  Total number of tokens lent by users 
            uint reserves //  Total number of reserve tokens 
        ) public view returns (
            uint //  Lending rate of funds 
        ){
                  
            ...
        }
        
      • Implementation analysis
        ...
        {
                  
            //  If the total number of tokens lent is  0, The lending rate is also  0
            if (borrows == 0) {
                  
                return 0;
            }
            // borrows * 1e18 / (cash + borrows - reserves)
            return borrows.mul(1e18).div(cash.add(borrows).sub(reserves));
        }
        
      • summary
        utilizationRate Used to calculate tokens Lending rate of funds , Lending rate of funds The calculation formula of is Lending rate of funds = Total number of tokens lent / ( Token balance + Total number of tokens lent - Total number of reserve tokens ). Due to the use of unsigned integers Lending rate of funds It's not accurate enough , So it needs to be multiplied by 1e18, Expand the accuracy range .

Capital interest rate

  • Public function ( Both inside and outside the contract can call )
    • getBorrowRate
      • Code overview
        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);
        }
        
      • Parametric analysis
        function getBorrowRate The input parameters are 3 individual , Out of ginseng 1 individual , The corresponding explanation is as follows :
        function getBorrowRate(
            uint cash, //  Token balance 
            uint borrows, //  Total number of tokens lent by users 
            uint reserves //  Total number of reserve tokens 
        ) public view returns (
            uint //  Block lending rate 
        ) {
                  
            ...
        }
        
      • Implementation analysis
        ...
        {
                  
            //  Calculate the lending rate 
            uint ur = utilizationRate(cash, borrows, reserves);
            // ur * multiplierPerBlock / 1e18 + baseRatePerBlock
            return ur.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);
        }
        
      • summary
        getBorrowRate Used to calculate tokens Block lending rate , Block lending rate The calculation formula of is Block lending rate = Lending rate of funds * Block rate multiplier + Block benchmark interest rate . because Lending rate of funds The accuracy range is expanded , It needs to be divided by 1e18 Get the actual value .
    • getSupplyRate
      • Code overview
        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);
        }
        
      • Parametric analysis
        function getSupplyRate The input parameters are 4 individual , Out of ginseng 1 individual , The corresponding explanation is as follows :
        getSupplyRate(
            uint cash, //  Token balance 
            uint borrows, //  Total number of tokens lent by users 
            uint reserves, //  Total number of reserve tokens 
            uint reserveFactorMantissa //  Reserve ratio 
        ) public view returns (
            uint //  Block pledge interest rate 
        ) {
                  
            ...
        }
        
      • Implementation analysis
        ...
        {
                  
            // 1 - reserveFactorMantissa
            uint oneMinusReserveFactor = uint(1e18).sub(reserveFactorMantissa);
            //  Get the loan interest rate  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);
        }
        
      • summary
        getSupplyRate Used to calculate tokens Block pledge interest rate , Block pledge interest rate The calculation formula of is Block pledge interest rate = Lending rate of funds * The interest rate for borrowing * (1 - Reserve ratio ) = The interest rate for borrowing * Lending rate of funds * (1 - Reserve ratio ). because Lending rate of funds The accuracy range is expanded , It needs to be divided by 1e18 Get the actual value .

BaseJumpRateModelV2.sol

Inflection point interest rate model

Contract initialization

  • Internal function ( Can only be called within the contract )
    • constructor
      • Code overview
        constructor(uint baseRatePerYear, uint multiplierPerYear, uint jumpMultiplierPerYear, uint kink_, address owner_) internal {
                  
            owner = owner_;
            updateJumpRateModelInternal(baseRatePerYear,  multiplierPerYear, jumpMultiplierPerYear, kink_);
        }
        
      • Parametric analysis
        function constructor The input parameters are 5 individual , Out of ginseng 0 individual , The corresponding explanation is as follows :
        constructor(
            uint baseRatePerYear, //  Annual benchmark interest rate 
            uint multiplierPerYear //  Annual interest rate multiplier 
            uint jumpMultiplierPerYear, //  Inflection point annual interest rate multiplier 
            uint kink_, //  Inflection point capital lending rate 
            address owner_ //  owner 
        ) internal {
                  
            ...
        }
        
      • Implementation analysis
        ...
        {
                  
            //  Record owner 
            owner = owner_;
            //  Update inflection point interest rate model parameters 
            updateJumpRateModelInternal(baseRatePerYear,  multiplierPerYear, jumpMultiplierPerYear, kink_);
        }
        
      • summary
        Inflection point interest rate model Than Linear interest rate model More Inflection point annual interest rate multiplier and Inflection point capital lending rate These two parameters .
    • updateJumpRateModelInternal
      • Code overview
        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);
        }
        
      • Parametric analysis
        function updateJumpRateModelInternal The input parameters are 4 individual , Out of ginseng 0 individual , The corresponding explanation is as follows :
        function updateJumpRateModelInternal(
            uint baseRatePerYear, //  Annual benchmark interest rate 
            uint multiplierPerYear //  Annual interest rate multiplier 
            uint jumpMultiplierPerYear, //  Inflection point annual interest rate multiplier 
            uint kink_, //  Inflection point capital lending rate 
        ) internal {
                  
            ...
        }
        
      • Implementation analysis
        ...
        {
                  
            //  Block benchmark interest rate  =  Annual benchmark interest rate  /  Number of blocks per year 
            baseRatePerBlock = baseRatePerYear.div(blocksPerYear);
            //  Block rate multiplier  =  Annual benchmark interest rate  / ( Number of blocks per year  *  Inflection point capital lending rate )
            multiplierPerBlock = (multiplierPerYear.mul(1e18)).div(blocksPerYear.mul(kink_));
            //  Inflection point block interest rate multiplier  =  Inflection point annual interest rate multiplier  /  Number of blocks per year 
            jumpMultiplierPerBlock = jumpMultiplierPerYear.div(blocksPerYear);
            //  Record the inflection point capital lending rate 
            kink = kink_;
            //  Triggering event  NewInterestParams
            emit NewInterestParams(baseRatePerBlock, multiplierPerBlock, jumpMultiplierPerBlock, kink);
        }
        
      • summary
        Inflection point interest rate model Middle computation Block rate multiplier when , Methods and Linear interest rate model Dissimilarity : Inflection point capital lending rate The higher the , Block rate multiplier The lower the , I am not very clear about its purpose .( It may be that the deeper the token market is, the higher the capital lending rate at the inflection point is , The block rate multiplier can be set lower , You can discuss )

Lending rate of funds

  • Public function ( Both inside and outside the contract can call )
    • utilizationRate
      • Code overview
        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));
        }
        
      • Parametric analysis
        function utilizationRate The input parameters are 3 individual , Out of ginseng 1 individual , The corresponding explanation is as follows :
        constructor(
            uint cash, //  Token balance 
            uint borrows, //  Total number of tokens lent by users 
            uint reserves //  Total number of reserve tokens 
        ) public view returns (
            uint //  Lending rate of funds 
        ){
                  
            ...
        }
        
      • Implementation analysis
        ...
        {
                  
            //  If the total number of tokens lent is  0, The lending rate is also  0
            if (borrows == 0) {
                  
                return 0;
            }
            //  Lending rate of funds  = borrows * 1e18 / (cash + borrows - reserves)
            return borrows.mul(1e18).div(cash.add(borrows).sub(reserves));
        }
        
      • summary
        Inflection point interest rate model Middle computation Lending rate of funds and Linear interest rate model identical .

Capital interest rate

  • Internal function ( Can only be called inside the contract )
    • getBorrowRate
      • Code overview
        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);
            }
        }
        
      • Parametric analysis
        function getBorrowRateInternal The input parameters are 3 individual , Out of ginseng 1 individual , The corresponding explanation is as follows :
        function getBorrowRate(
            uint cash, //  Token balance 
            uint borrows, //  Total number of tokens lent by users 
            uint reserves //  Total number of reserve tokens 
        ) internal view returns (
            uint //  Block lending rate 
        ) {
                  
            ...
        }
        
      • Implementation analysis
        {
                  
            //  Obtain the lending rate of funds  util
            uint util = utilizationRate(cash, borrows, reserves);
            //  If  util < kink
            if (util <= kink) {
                  
                // return util * multiplierPerBlock + baseRatePerBlock
                return util.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);
            } else {
                  
                //  The lending rate before the inflection point  = kink * multiplierPerBlock + baseRatePerBlock
                uint normalRate = kink.mul(multiplierPerBlock).div(1e18).add(baseRatePerBlock);
                //  The lending rate of funds beyond the inflection point  = util - kink
                uint excessUtil = util.sub(kink);
                //  Block lending rate  = (util - kink) * jumpMultiplierPerBlock + kink * multiplierPerBlock + baseRatePerBlock
                return excessUtil.mul(jumpMultiplierPerBlock).div(1e18).add(normalRate);
            }
        }
        
      • summary
        Inflection point interest rate model Middle computation Block lending rate The calculation formula of is divided into two parts : stay Lending rate of funds lower than Inflection point capital lending rate when , The formula is : Block lending rate = Lending rate of funds * Block rate multiplier + Block benchmark interest rate ; stay Lending rate of funds higher than Inflection point capital lending rate when , The formula is : Block lending rate = ( Lending rate of funds - Inflection point capital lending rate ) * Inflection point block interest rate multiplier + Inflection point capital lending rate * Block rate multiplier + Block benchmark interest rate .
    • getSupplyRate
      • Code overview
        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);
        }
        
      • Parametric analysis
        function getSupplyRate The input parameters are 4 individual , Out of ginseng 1 individual , The corresponding explanation is as follows :
        getSupplyRate(
            uint cash, //  Token balance 
            uint borrows, //  Total number of tokens lent by users 
            uint reserves, //  Total number of reserve tokens 
            uint reserveFactorMantissa //  Reserve ratio 
        ) public view returns (
            uint //  Block pledge interest rate 
        ) {
                  
            ...
        }
        
      • Implementation analysis
        ...
        {
                  
            // 1 - reserveFactorMantissa
            uint oneMinusReserveFactor = uint(1e18).sub(reserveFactorMantissa);
            //  Get the loan interest rate  borrowRate
            uint borrowRate = getBorrowRateInternal(cash, borrows, reserves);
            // rateToPool = borrowRate * (1 - reserveFactorMantissa)
            uint rateToPool = borrowRate.mul(oneMinusReserveFactor).div(1e18);
            //  Block pledge interest rate  = utilizationRate * borrowRate * (1 - reserveFactorMantissa)
            return utilizationRate(cash, borrows, reserves).mul(rateToPool).div(1e18);
        }
        
      • summary
        Inflection point interest rate model Middle computation Capital pledge interest rate and Linear interest rate model identical .
原网站

版权声明
本文为[thirty-three thousand three hundred and fifty-seven]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206110721573325.html