解读 DAI 架构流程图 —— Core模块
免责声明:本文不构成投资建议,仅研究技术为主,祝玩得开心 ^_^
上一节回顾
上个章节主要讲解了DAI 合约模块的细节,其中,包括 DAI 代币合约和所有的 DaiJoin 适配器。本章节,我们来解读Core模块的细节。
核心模块介绍
核心模块由Vat和Spot两个合约组成,该模块对系统至关重要,因为它包含了 Maker 协议的完整状态,并在系统正常运行状态下控制着系统的核心机制。
Vat-Vat是核心金库,Dai和抵押品状态都保存在Vat中。Vat合约没有外部依赖关系,并维护Dai的中心“会计不变量”。Spot-poke是现货中唯一的非认证函数。该函数接收一个32字节(bytes32)“poke”的ilk。poke调用两个外部函数,分别是peek和file。
需要注意的问题(潜在的用户错误来源)
Vat中的方法被编写得尽可能通用,因此它们的接口可能相当冗长。应注意确保您没有混淆参数的顺序。任何经过Vat身份验证的模块都具有完整的根访问权限,因此可以窃取系统中的所有抵押品。这意味着添加新的抵押品类型(以及相关的适配器)具有相当的风险。- 当
Cat升级时,必须同时更新多个对其的引用(End,Vat.rely,Vow.rely)。它还必须依赖于End和系统的pause.proxy()。更多的注意点,等后续讲到Cat合约时,再次展开。 - 与
dss的其他大部分部分相比,spotter中的方法相对基本。单个未认证方法poke中用户错误的余地不大。如果提供了错误的bytes32,则调用将失败。任何经过spot身份验证的模块都具有完整的根访问权限,因此可以添加和删除可以被“poke”的ilks。虽然这并没有完全破坏系统,但可能会导致相当的风险。
故障模式(操作条件范围和外部风险因素)
- 编码错误风险
Vat-Vat中的错误可能是灾难性的,可能导致系统中所有Dai和抵押品的丢失(或锁定)。这将使得无法修改金库或转移Dai。拍卖可能会停止运作。关机可能会失败。Spot-Spot中的错误很可能导致抵押品价格不再更新。在这种情况下,系统需要授权一个新的Spot,然后该Spot将能够更新价格。总的来说,这不是一种灾难性的故障,因为这只会在某段时间内暂停所有价格波动。
- 数据源风险
Vat和Spot都依赖一组可信任的预言机来提供价格数据。如果这些价格数据源失败,将可能允许创建无支持的Dai,或者不公平地清算安全的金库。
- 治理风险
Vat- 治理可以授权Vat对新的模块。这使得他们可以窃取抵押品(slip)或铸造无支持的 Dai(suck或添加无价值的抵押品类型)。如果使这样做变得代价高昂的加密经济保护措施失败,系统可能会受到攻击并被不良行为者榨取抵押品。
Vat合约详细介绍
Vat是dss的核心Vault引擎。它存储Vault并跟踪所有相关的Dai和抵押品余额。它还定义了可以通过操作Vault和余额的规则。Vat中定义的规则是不可变的,因此在某种程度上,可以将Vat中的规则视为dss的宪法。

Vat-Vault引擎术语解析gem: collateral tokens.dai: stablecoin tokens.sin: unbacked stablecoin (system debt, not belonging to any urn).ilks: a mapping of Ilk types.Ilk: a collateral type.Art: total normalized stablecoin debt.rate: stablecoin debt multiplier (accumulated stability fees).spot: collateral price with safety margin, i.e. the maximum stablecoin allowed per unit of collateral.line: the debt ceiling for a specific collateral type.dust: the debt floor for a specific collateral type.
urns: a mapping of Urn types.Urn: a specific Vault.ink: collateral balance.art: normalized outstanding stablecoin debt.
init: create a new collateral type.slip: modify a user’s collateral balance.flux: transfer collateral between users.move: transfer stablecoin between users.grab: liquidate a Vault.heal: create / destroy equal quantities of stablecoin and system debt (vice).fold: modify the debt multiplier, creating / destroying corresponding debt.suck: mint unbacked stablecoin (accounted for with vice).Line: the total debt ceiling for all collateral types.frob: modify a Vault.lock: transfer collateral into a Vault.free: transfer collateral from a Vault.draw: increase Vault debt, creating Dai.wipe: decrease Vault debt, destroying Dai.dink: change in collateral.dart: change in debt.
fork: to split a Vault - binary approval or splitting/merging Vaults.dink: amount of collateral to exchange.dart: amount of stablecoin debt to exchange.
wish: check whether an address is allowed to modify another address’s gem or dai balance.hope: enable wish for a pair of addresses.nope: disable wish for a pair of addresses.
注意:
art和Art代表标准化债务,即当乘以正确的利率时,可以得到最新的、当前的稳定币债务。
Accounting
debtis the sum of all dai (the total quantity of dai issued).viceis the sum of all sin (the total quantity of system debt).Ilk.Artthe sum of all art in the urns for that Ilk.debtis vice plus the sum ofIlk.Art * Ilk.rateacross allilks.
Collateral
gemcan always be transferred to any address by it’s owner.
Dai
daican only move with the consent of it’s owner.daican always be transferred to any address by it’s owner.
Vat合约的核心机制和概念
Vat中的核心Vault、Dai和抵押状态由Vat维护。Vat合约没有外部依赖关系,并维护Dai的中央“会计不变量”。适用于Vat的核心原则如下:Dai不能没有抵押品存在:
Ilk是一种特殊类型的抵押品。- 抵押品
gem分配给具有slip的用户。 - 抵押品
gem在用户之间转移flux。
Vault数据结构是Urn:
- has
ink- 负担的抵押品 - has
art- 负担、标准化债务
- 类似地,一个抵押品是一个
Ilk:
- has
Art- 负担、标准化债务 - has
rate- 债务缩放因子(下面进一步讨论) - has
spot- 带安全余量的价格 - has
line- 债务上限 - has
dust- 债务下限
注意:在上面的使用“encumbered”一词时,这是指“被锁定在Vault中”。
Vault管理Vault通过frob(i, u, v, w, dink, dart)进行管理,它使用用户van的gem修改用户u的Vault,并为用户w创建dai。- 通过调用
grab(i, u, v, w, dink, dart),修改用户u的Vault,将gem给用户v并为用户w创建sin。grab是Vault变现的手段,将债务从Vault转移到用户的sin余额。 Sin代表“被查获”或“不良”债务,可以使用heal(uint rad where msg.sender is used as the address for the dai and sin balances)使用相等数量的 Dai 进行抵消。- 注意:只有
Vow才会有sin,因此只有Vow能成功调用heal。这是因为每当调用grab和suck时,将Vow的地址作为sin的接收方传递。需要注意的是,这取决于当前系统的设计和实现。 - 注意:heal 只能用正数(
uint)调用,并将sub(dai[u])以及sub掉sin。
- 注意:只有
dai的数量可以通过move在用户之间转移。
通过
fold(bytes32 ilk, address u, int rate)更新利率
Spot合约详细介绍
Spot是负责连接预言机(Oracles)与核心合约的现货接口。作为一个接口合约,它只存储当前的ilk列表。

Spot合约的核心机制和概念
Poke是spot中唯一的非认证函数。该函数接收一个要poked的ilk的bytes32。Poke调用两个外部函数:
Peek调用给定ilk的OSM并将val(值)和has(布尔值,如果OSM中发生错误则为false)作为返回值。只有在has == true时才会发生第二次外部调用。- 在计算现货价格时,
par(基本价格单位)对于计算DAI与价格中的 1 个单位的关系至关重要。然后将val(值)除以par(得到val与DAI的比率),再将结果除以ilk.mat。这给我们提供了给定ilk的当前现货价格。- 在计算
spot后调用file。这个函数用于ilk的当前清算价格更新vat。