Search
Duplicate

compound protocol

Created
2021/10/26 12:34
Tags
일시
작성자
포스팅 종류
✅ main

+etc

index
oraclePrice

references

Overview

공급자와 차입자는 컨트랙트를 통해 직접 거래
이더리움 기반이며 각 자산 당 하나의 마켓이 존재함
컨트랙트가 수요-공급곡선을 기반으로한 알고리즘에 따라 이자율 조정하므로 유동성에 영향
예금(mint), 출금(redeem), 대출(borrow), 상환(repay borrow), 청산(liquidation)이 가능함
수시 입출금 가능
예금시 cToken으로 교환, 담보로 사용 가능
블록마다 예금이자와 대출이자 계산됨
예금, 대출 진행시 COMP 토큰 제공 (거버넌스 토큰)
예치한 자산을 하나의 자산 풀로 합쳐서 담보 가치를 계산함

Utilization rate

수요, 공급을 이용률로 표현함.
자산a 마켓에 공급된 총액(cTokenSupply) 중에서 대출한 금액의 비율
Ua=Borrowsa/(Casha+ Borrows a Reserves a)\mathrm{U}{\mathrm{a}}=\mathrm{Borrows}{\mathrm{a}} /\left(\mathrm{Cash}{\mathrm{a}}+\text { Borrows }{\mathrm{a}}-\text { Reserves }_{\mathrm{a}}\right)
Borrows_a: 대출받은 a의 양
Cash_a: 마켓에 남은 a의 양
Reserves_a: 준비금. 차입금이자중 일부. 거버넌스에 이용되거나 공급자의 예금에대한 보험으로 사용됨
WhitePaperInterestRateModel.sol
수요-공급은 유동성에 영향
이용률이 높을수록 대출이 많이 일어나고 있음을 의미하므로 유동성을 더 높이기 위해 이자율이 높아진다.
낮은 이용율은 대출 수요가 낮다는 것을 의미하므로 이자율이 낮아진다.

Interest rate model

이자율모델에 따라 마켓의 차입 및 공급 이자율이 달라진다.

Standard interest rate model

대부분의 코인에서 사용됨(Ethereum, ZRT, BAT)
이자는 블록단위로 증가함
BorrowInterestRate=MultiplierUa+BaseRateBorrow Interest Rate=Multiplier∗ U_a+Base Rate
BaseRate: (초기20%)
baseRatePerBlock=baseAPR/blockPerYear
Multiplier: (초기2.5%)
multiplierPerBlock=multiplierPerYear/blockPerYear
승수, 이용률대비 이자상승률
uint public constant blocksPerYear = 2102400;
Plain Text
WhitePaperInterestRateModel
아래에서
검은선: Utilization rate
초록선이 Supply APY로 U의 제곱에 비례
보라선이 Borrow APY로 U에 선형비례
$$\text { Supply Interest Rate }{a}=\text { Borrowing Interest Rate }{a} * U_{a} *(1-Reserve Factor_a)$$
U=4.68%
위의식에 대입
0.11%=2.85%4.68%(1-20%)

The Jump Rate modelV2

 Borrow Interest Rate = Multiplier min(Ua, Kink )+ Jump Multiplier max(0,UaKink)+Base Rate \begin{aligned} \text { Borrow Interest Rate } &=\text { Multiplier } * \min \left(\mathrm{U}{\mathrm{a}}, \text { Kink }\right) \\ &+\text { Jump Multiplier } * \max \left(0, \mathrm{U}{\mathrm{a}}-\mathrm{Kink}\right) \\ &+\mathrm{Base} \text { Rate } \end{aligned}
추가 파라미터
Kink, the point in the model in which the model follows the jump multiplier
Jump Multiplier per year, the rate of increase in interest rate with respect to utilization after the "kink"

Market States

1.
Unsupported: 지원하지않는 자산
2.
Listed: listedAssets에 포함, 담보x, 대출x, 예금,출금,상환 가능
3.
Borrow: listedAssets에 포함, 담보x, 대출o
4.
Collateral: listedAssets에 포함, 담보o, 대출o

Code Architecture

cToken

CEther/CErc20 두가지 유형
initialize를 통해 자산풀 생성,
mint, redeem, redeemUnderlying, borrow, repayBorrow, liquidateBorrow 기능
CToken: 기능 구현
CErc20: 실제 실행
CEther: 실제 실행

Comptroller

담보의 양과 청산 여부 결정
Unitroller : Comptroller의 Storage가 저장되어있으며 CToken도 comptroller로 이 주소를 참조함
ComptrollerStorage

InterestRate Model

1.
WhitePaperInterestRateModel (InterestRateModel)
JumpRateModel (InterestRateModel)
2.
JumpRateModelV2 (BaseJumpRateModelV2, InterestRateModel)
LegacyJumpRateModelV2(BaseJumpRateModelV2, LegacyInterestRateModel)
Oracle

5가지 기능

1. mint

에서 시작
mintInternal
마켓의 대출량과 이자율 체크
accrueInterest : 이자율을 계산함. mint, redeem, borrow, repayBorrow 진행시마다 실행
mintFresh
comptroller.mintAllowed
updateCompSupplyIndex
listed된 마켓인지 확인
cToken의 발행 가능 여부 확인
distributeSupplierComp
공급자에게 제공해야 할 COMP 토큰의 수 계산
모든 로직에 포함: 이자율을 가장 최신 블록 시점으로 업데이트했는지 확인
accrualBlockNumber가 getBlockNumber()와 같은지 확인
accrualBlockNumber: 마지막으로 이자를 갱신한 시점의 블록 넘버
현재 교환 비율에 따른 cToken 발행량 계산
doTransferIn
actualMintAmount: 공급자가 예치할 암호화폐의 개수
exchangeRate: cToken의 개수를 결정하는 교환 비율
exchangeRate = (underlyingBalance + totalBorrowBalance − reserve)/cTokenSupply
underlyingBalance: cToken 컨트랙트에 남아있는 암호화폐 개수
totalBorrowBalance: cToken 컨트랙트에서 대출한 토큰의 개수(대출 이자 포함)
cTokenSupply: 예금자에게 공급한 cToken의 개수
mintTokens: 사용자가 예금한 자산의 수에 따라 받는 cToken의 개수
mintToken = actualMintAmount/exchangeRate
사용자의 cToken 보유량과 컨트랙트의 cToken 발행량 업데이트
토큰 양 업데이트
totalSupply: 예금자에게 공급한 cToken의 개수
accountToken: 사용자가 보유한 cToken의 개수

2. redeem

redeemUnderlyingInternal: 출금하고 싶은 암호화폐의 수를 입력
redeemAllowed
reddemAllowedInternal
사용자의 계좌 유동성 확인
총 담보가치 > 이전 대출과 현재 출금시 감소하는 담보금 계산
getHypotheticalAccountLiquidityInternal(account,cTokenModify,redeemTokens,borrowAmount)
파라미터
cTokenModify: (가상으로) 상환 및 대출할 market
account: 유동성을 결정하는 계정주소
redeemTokens: 사용자가 Compound에 전송하는 cToken의 개수
대출인 경우 0
borrowAmount: 가상으로 대출하는 기초 암호화폐 수
출금하는경우 0
sumCollateral>sumBorrowPlusEffects
예금 자산을 통한 담보금 >이전 대출과 현재 출금요청을 통해 감소하게되는 담보금
collateralFactor: 자산의 담보비율
합산된 계좌 유동성을 구하기 위해 각 자산의 잔액, 차입액, 담보 비율, 교환 비율, 기초 암호화폐의 가격을 통해 전체 유동성을 계산
tokensToDenom: cToken 한 개의 가격
tokensToDenom = (collateralFactor * exchangeRate) * oraclePrice
합산 담보금 sumCollateral = tokensToDenom * cTokenBalance
sumBorrowPlusEffects
sumBorrowPlusEffects1 = oraclePrice * borrowBalance
sumBorrowPlusEffects2 = sumBorrowPlusEffects1 + (tokensToDenom * redeemTokens)
sumBorrowPlusEffects1 : 이전 대출로 사용한 담보금
sumBorrowPlusEffects2 : 과거 대출과 현재 출금으로 인해 사용하는 담보금
redeemTokens: 출금에 사용되는 cToken의 개수)
cToken이 마켓에 리스팅 되어있는지 여부
COMP토큰 개수 계산
redeemFresh
redeemTokens = redeemAmountIn/exchangeRateCurrent
redeemAmountIn = redeemAmounts
exchageRateCurrent = exchageRate
redeemAmount: 사용자가 돌려받는 자산의 개수

3. borrow

borrowInternal, borrowFresh
기존 대출금과 새로운 차입금의 합을 계산함
accountBorrowsNew = accountBorrows + borrowAmount
totalBorrowsNew = totalBorrows + borrowAmount
totalBorrows: 컨트랙트의 전체 대출량(기초자산)
borrowAmount: 대출하려는 차입금
accountBorrows: 차입자가 과거에 차입한 자산의 양
recentBorrowBalance
accountBorrowsNew = accountBorrows + borrowAmount
totalBorrowsNew = totalBorrows + borrowAmount
totalBorrows: 컨트랙트의 전체 대출량(기초자산)
borrowAmount: 대출하려는 차입금
accountBorrows: 차입자가 과거에 차입한 자산의 양
recentBorrowBalance

4. repayBorrow

repayBorrowFresh
차입금을 상환하고 남은 차입금을 갱신
accountBorrowsNew = accountBorrows - actualRepayAmount totalBorrowsNew = totalBorrows - actualRepayAmount

5. liquidation

Predicting accrued interest

t일동안의 원금P에 대한 총 이자 계산
 Total Interest =P(1+rBy)Byt\text { Total Interest }=\mathrm{P}\left(1+\frac{\mathrm{r}}{\mathrm{B}{\mathrm{y}}}\right)^{\mathrm{B}{\mathrm{y}} * \mathrm{t}}
t: t days
P: principal balance
B_y: 2102400 (1년 동안의 블록 수, 블록생성시간이 15초라 가정)
r: 주어진 기간동안 이자APR의 예상가치