+etc
index
oraclePrice
references
Overview
공급자와 차입자는 컨트랙트를 통해 직접 거래
이더리움 기반이며 각 자산 당 하나의 마켓이 존재함
컨트랙트가 수요-공급곡선을 기반으로한 알고리즘에 따라 이자율 조정하므로 유동성에 영향
예금(mint), 출금(redeem), 대출(borrow), 상환(repay borrow), 청산(liquidation)이 가능함
수시 입출금 가능
예금시 cToken으로 교환, 담보로 사용 가능
블록마다 예금이자와 대출이자 계산됨
예금, 대출 진행시 COMP 토큰 제공 (거버넌스 토큰)
예치한 자산을 하나의 자산 풀로 합쳐서 담보 가치를 계산함
Utilization rate
수요, 공급을 이용률로 표현함.
자산a 마켓에 공급된 총액(cTokenSupply) 중에서 대출한 금액의 비율
•
Borrows_a: 대출받은 a의 양
•
Cash_a: 마켓에 남은 a의 양
•
Reserves_a: 준비금. 차입금이자중 일부. 거버넌스에 이용되거나 공급자의 예금에대한 보험으로 사용됨
WhitePaperInterestRateModel.sol
수요-공급은 유동성에 영향
•
이용률이 높을수록 대출이 많이 일어나고 있음을 의미하므로 유동성을 더 높이기 위해 이자율이 높아진다.
•
낮은 이용율은 대출 수요가 낮다는 것을 의미하므로 이자율이 낮아진다.
Interest rate model
이자율모델에 따라 마켓의 차입 및 공급 이자율이 달라진다.
Standard interest rate model
대부분의 코인에서 사용됨(Ethereum, ZRT, BAT)
이자는 블록단위로 증가함
•
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
추가 파라미터
•
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
•
저장된 잔액을 불러옴 borrowBalanceStoredInternal
interest index로 borrowBalance를 계산
recentBorrowBalance = borrower.borrowBalance * market.borrowIndex / borrower.borrowIndex
•
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에 대한 총 이자 계산
•
t: t days
•
P: principal balance
•
B_y: 2102400 (1년 동안의 블록 수, 블록생성시간이 15초라 가정)
•
r: 주어진 기간동안 이자APR의 예상가치