dai
dai
合约学习
从github上克隆下来源码。目录结构为
1 | src |
合约词汇表
常用
guy
,usr
:一些地址wad
:一些数量的标记,通常作为一个固定点整数,十进制位数为10 ^ 18。ray
:一个固定位数整数,十进制位数为10 ^ 27。rad
:一个固定位数整数,十进制位数为10 ^ 45。file
:管理一些配置值
认证(auth)
auth
:检查地址是否可以调用此方法ward
:允许调用authed方法的地址rely
:允许一个地址调用authed方法,或将一个地址添加到ward中deny
:禁止一个地址调用authed方法,或将一个地址从ward中移除
CDP引擎 vat
CDP
:抵押债务位置gem
:抵押代币,数据类型为map(byte32)map(address)uint256, 某类型抵押代币下某地址的抵押个数dai
:稳定代币sin
:antioin令牌(系统债务,不属于任何urn
)ilk
:抵押品类型rate
:稳定债务乘数(累计稳定费)take
:抵押余额乘数Ink
:抵押品总余额 ?代码里好像没了Art
:总稳定债务spot
:具有安全边际的抵押品价格,即每单位抵押品允许的最大稳定币line
:特定抵押品类型的债务上限dust
:CDP的最低可能债务
Line
:所有抵押品类型的总债务上限init
:创建一个新的抵押品类型urn
:一个特定的CDPink
:抵押品余额art
:未偿还稳定债务
debt
:发行的稳定币总量vice
:系统债务总量slip
:修改用户的抵押品余额(操作gem)flux
:在用户之间转移抵押品(操作gem)move
:在用户之间转移stablecoingrab
:清算CDP,(只做记录,记录为抵押物减少(增加),抵押品余额增加(减少)?)1
2
3
4
5
6
7
8
9
10
11
12
13
14function grab(bytes32 i, address u, address v, address w, int dink, int dart) external note auth {
Urn storage urn = urns[i][u];
Ilk storage ilk = ilks[i];
urn.ink = add(urn.ink, dink);
urn.art = add(urn.art, dart);
ilk.Art = add(ilk.Art, dart);
int dtab = mul(ilk.rate, dart);
gem[i][v] = sub(gem[i][v], dink);
sin[w] = sub(sin[w], dtab);
vice = sub(vice, dtab);
}heal
:创建/销毁等量的稳定币和系统债务(vice
)fold
:修改债务乘数,创造/销毁相应的债务?1
2
3
4
5
6
7
8function fold(bytes32 i, address u, int rate) external note auth {
require(live == 1);
Ilk storage ilk = ilks[i];
ilk.rate = add(ilk.rate, rate);
int rad = mul(ilk.Art, rate);
dai[u] = add(dai[u], rad);
debt = add(debt, rad);
}toll
:修改抵押品乘数,创建/销毁相应的抵押品suck
:铸造稳定币(占比vice
)frob
:修改CDPlock
:将抵押品转移到CDPfree
:从CDP转移抵押品draw
:增加CDP债务,创造Daiwipe
:减少CDP债务,摧毁Daidink
:抵押品的变化dart
:债务变动calm
:当CDP仍处于抵押品和总债务上限时,这是真的cool
:当稳定债务没有增加时,这是真的firm
:当抵押品余额没有减少时为真safe
:当CDP的抵押品与债务比率高于抵押品的清算比率时为真
fork
:拆分CDP - 二进制批准或拆分/合并CDPdink
:交换抵押品的数量dart
:交换的稳定债务金额
wish
:检查地址是否允许修改另一个地址的gem或dai余额hope
:启用wish
一对地址nope
:禁用wish
一对地址
稳定费用 jug
duty
:稳定费base
:全球稳定费rho
:最后一次收集这种抵押品时间drip
:确定增加
清算 cat
mat
:清算比率chop
:清算罚款lump
:清算数量,即任何一次清算事件所涵盖的固定债务数量bite
:开始清算CDPflip
:清算CDP的抵押品以支付固定数额的债务
结算 vow
sin
:债务队列Sin
:队列中的总债务Woe
:非排队的非拍卖债务总额Ash
:拍卖总债务Awe
:债务总额Joy
:总盈余fess
:向队列添加债务flog
:从队列中实现债务wait
:队列的长度heal
:取消盈余和债务kiss
:取消盈余和拍卖债务sump
:债务拍卖手数,即任何一次债务拍卖所涵盖的固定债务数量bump
:剩余拍卖手数,即任何一次剩余拍卖所出售的固定剩余数量hump
:在剩余拍卖可能之前必须超过剩余缓冲
拍卖 flop flip flap
flip
:抵押品拍卖(使用稳定币进行交易?)flop
:债务拍卖(通过膨胀MKR和出售稳定币来偿还债务)(以稳定币购买MKR?)flap
:剩余拍卖(出售MKR的稳定币)(以MKR来购买稳定币)lot
:拍卖数量bid
:提供的数量lot
tab
:总dai将被提高(flip
拍卖中)guy
:高出价者gal
:拍卖收入的获得者ttl
:出价终身beg
:最低出价增加tau
:最长拍卖时间end
:拍卖结束时kick
:开始拍卖tick
:重新开始拍卖tend
:出价,增加出价大小dent
:出价,减少手数deal
:要求中标
全球结算 end
when
:结算时间wait
:处理冷却时间长度(允许不足的CDP为skim
med)debt
:在系统盈余/赤字被吸收后,出色的稳定供应量tag
:结算时每种抵押品的价格gap
:考虑到不合标准的CDP,每个抵押品的差额fix
:现金价格ilk
(每稳定金额)bag
:无法转移的稳定币准备交换抵押品out
:已交换的给定地址的稳定币的数量cage
:冻结系统,取消flip
/flop
拍卖,开始冷却期cage(ilk)
:设定结算价格skim
:取消CDP债务,取得抵押担保,但留下过剩skip
:可选择取消现场拍卖free
:从CDP中删除抵押品thaw
:修复了稳定币的总供应量flow
:计算fix
同类产品的价格,可能cage
用盈余/赤字调整价格pack
:把一些稳定的金币放入bag
准备中cash
cash
:交换一些bag
给定的稳定币gem
,与bag
大小成比例的份额
基本知识点
用户类型
Maker 主要有三种 user case。作为普通想使用稳定货币的人,他们可以在交易所用美元或者人民币购买 DAI,然后用来交易、支付甚至竞猜。
第二个是比较高级的用户,他们锁定自己的抵押资产,借 DAI 进行杠杆交易。
第三个是更深参与系统中的用户,他们持有 MKR 管理型货币,维护系统,同时如果管理得当获益。
货币
在 Maker 体系中有两种主要的货币。第一个是 DAI,稳定货币。他是一种有资产背书的硬通货,在无需准许的信贷系统中生成。也就是说,任何用户可以锁定他们有价值的数字资产,然后生成 DAI。系统用动态的目标利率去调节 DAI 的价格。在第一版 DAI 里,我们会保持 DAI 的价格在 1:1 美元左右浮动。
第二种代币是 MKR,也就是 Maker。MKR 是管理型代币。拥有 MKR 的用户组成一个去中心化的管理社区,他们决定哪种有价值的数字资产可以作为抵押资产,清算比例等等。作为对他们服务的回报,当用户赎回抵押物的时候,他们不仅要返还 DAI,还要加上一小部分费用,其中一部分费用会被用来购买并销毁 MKR 以关闭抵押债仓。也就是说 MKR 是信贷系统的燃料。
信贷系统
用户如果要借 DAI,他们首先要建立一个抵押债仓(CDP),然后将数字资产作为抵押物,生成 DAI。然后他可以用 DAI 去做多他看好的资产。最后买回 DAI,偿还 DAI 和一部分费用拿回抵押资产。
我们在这张图中可以看到,抵押物的价值始终大于 DAI 的价值。这是因为抵押物的价值会有波动,我们要确保 DAI 有足够的抵押。如果抵押物升值并没有太大影响,意味着 DAI 有更足够的抵押。但是如果抵押物减值,系统需要对此做出反应。
当抵押物价值低于清算值,CDP 会被清算。抵押物会被强制平仓,用来回购 DAI,以保证 DAI 的偿付能力。可以想象为 margin call(追加保证金)。
那么,在这一次的发布中,我们会用什么作为抵押资产呢。我们叫做 pooled-ETH,以太池。在之后的发布中,我们会引入多重资产抵押。目前我们还在开发多重资产抵押的过程中,在这一次的发布中,我们用以太池作为抵押代币。
他的运行机制是:用户首先将 ETH 放入合同中,然后回收到相应比例的 ETH 兑换凭证,PETH。起初,PETH 和 ETH 的比例是一比一。但是这一比例会随着系统的表现而改变。
如果系统运行良好,所有的 CDP 在偿还时会不断产生费用。一部分费用会被用来回购和销毁 PETH。销毁 PETH 意味着剩下的 PETH 可以兑换更多的 ETH。对于大多数用户来说,他们也许会抵押 PETH,用来借 DAI,然后做多资产。用户也可以选择持有 PETH,获得费用收益。
当黑天鹅时间发生时,抵押物的价格大幅度下降,甚至低于 DAI 的价格,清算机制都来不及应对。这时候系统会通过增发 PETH 来回购 DAI 以支撑抵押不足的 DAI。
当用户关闭 CDP 时,一部分费用会用来回购销毁 PETH,另一部分费用会用来购买 MKR,作为管理费用。
清算操作
触发发生清算
预言机根据现在 PETH 的价格反馈给 Maker 平台。Maker平台需要抵押资产的实时价格信息以决定何时触动清算。也就是说需要看户机拿到这个价格,根据这个价格是否发生清算。
发生清算
当此时发生清算了,预言机触发反馈给看户机,看护机在 CDP 清算的时候参与债务拍卖和抵押资产拍卖 。看护机也会围绕目标价格交易 Dai。当市场价格高于目标价格的时候,看护机将出售 Dai 。同理,当市场价格低于目标价格的时候,看护机将买入 Dai。这样做的是为了从市场长期价格趋同目标价格中获益。注:看户机只是做一个策略,它决定什么时候进行出售。当出售的时候他会根据系统喂价直接与以太坊使用者和看护机进行交易的智能合约。当 CDP 被清算,系统会立即回收其抵押品。CDP 持有者会收到去除债务、稳定费用和清算罚金后的剩余抵押资产。这里分两种情况:
第一种,正常情况
PETH 抵押资产将会在流动性供给合约中出售,看护机可以自动交易 Dai 购买 PETH。所有支付的 Dai会从流通中立即销毁,直到 CDP 债务数量被消除。如果在去除 CDP 债务后还有剩余的 Dai,这部分 Dai会被用来购买并销毁 PETH,从而提高 PETH 可兑换 ETH 的比例。这对 PETH 持有者来说将会是收益。
第二种,非正常的情况下
如果出售的 PETH 未能募集到足够的 Dai 以偿付整个债务,系统会连续增发并出售 PETH。以这种方式新创造出来的 PETH 会降低 PETH 可兑换ETH 的比例,从而使得 PETH 持有者收益减少。
在清算发生时,Maker 平台会购买 CDP 中的抵押物并逐渐通过自动竞卖的方式售出。竞卖的机制可以让系统即使在无法获得价格信息的时候,处理 CDP。为了能够回购 CDP 中的抵押资产并用来出售,系统会首先募集足够的 Dai 以偿付 CDP 的债务。这一过程叫做债务竞卖,通过增发 MKR的供给并以竞卖的方式出售给竞卖参与者。
与此同时,CDP 中的抵押资产会以抵押资产竞卖的方式出售,CDP 债务和清算罚金的部分会用来回购并销毁 MKR。这可以直接抵销在债务竞卖中增发的MKR。如果有足够的 Dai 用来偿付 CDP 中的债务加上清算罚金,那么抵押竞卖会转换到反向竞卖机制,竞卖最少的抵押品 - 任何剩余的抵押品都会归还给CDP 的原所有者。
流动性供给合约 (单一抵押阶段过渡性机制)
在单一抵押资产 Dai 的阶段,清算的过程叫做流动性供给合约。根据系统喂价直接与以太坊使用者和看护机进行交易的智能合约。当 CDP被清算,系统会立即回收其抵押品。CDP 持有者会收到去除债务、稳定费用和清算罚金后的剩余抵押资产。
PETH 抵押资产将会在流动性供给合约中出售,看护机可以自动交易 Dai 购买 PETH。所有支付的 Dai 会从流通中立即销毁,直到 CDP债务数量被消除。如果在去除 CDP 债务后还有剩余的 Dai,这部分 Dai 会被用来购买并销毁 PETH ,从而提高 PETH 可兑换 ETH的比例。这对 PETH 持有者来说将会是收益。
如果出售的 PETH 未能募集到足够的 Dai 以偿付整个债务,系统会连续增发并出售 PETH。以这种方式新创造出来的 PETH 会降低 PETH 可兑换ETH 的比例,从而使得 PETH 持有者收益减少。
债务竞卖和抵押资产竞卖(多种抵押阶段机制)
在清算发生时,Maker 平台会购买 CDP 中的抵押物并逐渐通过自动竞卖的方式售出。
竞卖的机制可以让系统即使在无法获得价格信息的时候,处理 CDP。为了能够回购 CDP 中的抵押资产并用来出售,系统会首先募集足够的 Dai 以偿付 CDP 的债务。这一过程叫做债务竞卖,通过增发 MKR的供给并以竞卖的方式出售给竞卖参与者。与此同时,CDP 中的抵押资产会以抵押资产竞卖的方式出售,CDP 债务和清算罚金的部分会用来回购并销毁 MKR 。这可以直接抵销在债务竞卖中增发的 MKR。如果有足够的 Dai 用来偿付 CDP 中的债务加上清算罚金,那么抵押竞卖会转换到反向竞卖机制,竞卖最少的抵押品 - 任何剩余的抵押品都会归还给 CDP的原所有者。
清算期间会发生什么
当 Keeper 关闭 CDP 并将其发送到流动性提供合同(LPC)时,清算就会发生,而 LPC 又会在 Dai Dashboard 上提供 CDP资产。一旦履行了债务义务,未售出的 PETH 抵押品将返还给 CDP 所有者。
操作顺序如下:
- 违约的 CDP 已关闭。
- 罚款费用适用于 DAI 债务。
- LPC 移除了足够的 PETH 抵押品以满足当前 Oracle 价格的债务。
- CDP 所有者现在能够从关闭位置移除他们的剩余抵押品。
- 被扣押的 PETH 在 dai.makerdao.com 上出售,其激励折扣称为 Boom / Bust Spread ,适用于该值。
- 出售 PETH 所赚取的 DAI 被烧毁以消灭 CDP 债务。
- 如果销售中存在过量的 DAI ,那么它将被 PETH 出售,然后燃烧,从而增加剩余 PETH 的价值。
- 如果出售的 DAI 不足,那么 PETH 将被发行并出售以弥补不足。这会稀释池的总价值。
清算后剩余多少抵押品
简化公式
1
(抵押品 × Oracle 价格 × PETH / ETH 比率) - (清算罚款 × 稳定性债务) - 稳定性债务 =(剩余抵押品 ×Oracle 价格) DAI
假设:
一个 ETH 的 Oracle 价格是 350USD
锁定 PETH 总数为 10 ETH
PETH / ETH 的比率为 1.012
清算罚款为 13%
CDP 的稳定债务为 1000 DAI
计算为(10 × 350 × 1.012) − (13% × 1000) − 1000 = 2412 DAI 或 6.891428571 ETH
清算价格
可以使用以下简化公式来确定抵押品的价值必须达到多远才能触发结算:
1
(稳定债务 × 清算比率)/(抵押品 × PETH / ETH 比率)= 清算价格
例如:
一个 ETH 的值是 350 USD
总赌注 PETH 为 12
PETH / ETH 的比率为 1.012
清算比率为 150%
稳定债务是 1000 DAI
计算为(1000 × 1.5) ÷ (12 × 1.012) = 123.51 USD
在 CDP 被认为不安全并且有被清算的风险之前,ETH 的价格需要降至 123.51 美元。
计算抵押比率
如果希望通过查看抵押品与债务的比率来确定抵押物的健康状况,与清算价格相反,可以使用以下简化公式:
1
(锁定 PETH × ETH 价格 × PETH / ETH 比率)÷ 稳定性债务 × 100 = 抵押比率
举例:
- 一个 ETH 的值是 350 USD
- 总赌注 PETH 为 12
- PETH / ETH 的比率为 1.012
- 稳定债务是 1000 DAI
计算为(12 × 350 × 1.012) ÷ 1000 × 100 = 425.04%
CDP 的抵押比率为 425.04%。
降低清算价格
CDP 所有者面临的主要挑战是在高度不可预测的市场中保持安全的杠杆状态。如果 CDP 接近清算价格,用户可以添加更多抵押品或返回 DAI以降低风险。如果用户坚信基础抵押品的未来价值,用户可以决定为他的抵押物增加更多。或者,如果用户希望降低价格波动的风险,他可以通过将 DAI 返还给自己的CDP 来偿还债务。降低清算风险的最佳方法是偿还 DAI ,因为清算价格会更有效地降低。
假设:
- 一个 ETH 的值是 350 USD
- 总赌注 PETH 为 12
- PETH / ETH 的比率为 1.012
- 清算比率为 150%
- 稳定债务是 1000 DAI
目前的清算价格:
(1000 × 1.5 ) ÷ (12 × 1.012) = 123.51 USD
清算价格变动,增加 700 美元的抵押品:
(1000 × 1.5 ) ÷ (14 × 1.012) = 105.87 USD
清算价格变动,取消 700 美元的债务:
(300 × 1.5 ) ÷ (12 × 1.012) = 37.05 USD
我们可以看到,通过返还 DAI 而不是增加更多抵押品,显着降低了清算价格。
如何出售抵押品
当 Keeper 清算不安全的 CDP 时,流动性提供合同(LPC)确保在 Dai Dashboard 上出售抵押品。销售价格由应用了特殊修饰符的Oracle Feed确定。此修饰符通常采用折扣的形式,然后应用于必须回收的未偿还债务。这种额外的“差价”旨在通过向抵押品买方提供优于市场价格来激励系统的快速资本重组。用户可以在仪表板上购买已被 LPC 占用的 PETH 。出售的任何 DAI 盈余都可以用 PETH 购买。