DaiのDev版、Saiを完全理解してみる その2

DaiのDev版、Saiを完全理解してみる その2

今回は管理者が利用可能なFab.sol、Mom.sol、Top.solを見ていきます。

下の写真の上三つです。

 

まずはFab.solから。これは初期設定を担うコントラクトです。こいつがいることでFab.solと矢印で繋がっているコントラクトがデプロイされます。特にGemFabという関数では、DSToken(ERC-20をカスタマイズしたもの)のコントラクトをデプロイすることで各種トークンを作成して、そのアドレスをTubFab(Cup→CDPの動作を規定するコントラクト)のデプロイに利用しています。

またDadFabという関数では、msg.sender(このコントラクトをデプロイしたアカウント)をownerに設定しています。

また下部では各種数値を設定しています。

Gap(売買や貸し借りの差額)以外は27桁で定義され、Gapも18桁で定義されています。

この理由としてEVM(コントラクトを実行する仮想マシン)は小数点を計算できない(小数点の扱いはマシンごとによって変わるのでブロックチェーンで小数点を利用するのはリスキーになるための配慮)ため、このように非常に大きい桁の数に設定し、1 = 10の27乗と定義することで実質的に小数点の扱いを可能にしています。例えば、0.3を実装したかったら3×10の26乗と入力すれば、1 = 10の27乗の世界観では0.3となります。

設定される数値は以下のようになります。

全体の負債の合計額の限度・・・0(あとで再設定される)

流動性比率(借りた額の何%を担保として用意しなければならないか)・・・150%

流動性ペナルティ(担保が不足し没収される際のペナルティ)・・・13%

ガバナンスフィー(MKRで支払う手数料の額)・・・365×24×3600乗したら(一年の間、毎秒その数をかけて行ったら)0.05%になる数

スタイブルフィー(Daiのドル固定制を維持するためのフィー)・・・0

売買価格のギャップ・・・-3%(売るときに3%損する)

貸し借りのギャップ・・・0


function configParams() public auth {
require(step == 3);

tub.mold("cap", 0);
tub.mold("mat", ray(1.5 ether));
tub.mold("axe", ray(1.13 ether));
tub.mold("fee", 1000000000158153903837946257); // 0.5% / year
tub.mold("tax", ray(1 ether));
tub.mold("gap", 1 ether);

tap.mold("gap", 0.97 ether);

step += 1;
}

 

最後にMom.solに一部の関数の実行許可を出すとともにauthorityアドレスを指定し、このDai全体のOwner0アドレス(アドレスのNull値だと思えば良い)に指定しています。Mom.solは管理者が数値をいじるためのコントラクトなのでできる動作を固定しているのです。それについては後ほど解説します。この辺はできる限りの分散性を担保したDAOを作ろうとするMakerの理念が見えて楽しいですね。

次にMom.solを解説します。

これは冒頭の図のようにいろんなコントラクトを継承していますが、管理者があれこれ設定をいじくる為の設定用コントラクトです。逆にここで規定されていないことは勝手に変更することができません。

設定できるのは主に

1. 売買のギャップ

2. ETH/USD、MKR/ETHの価格(本来はオラクルを参照している)

3. Gemの担保率と担保没収の際の罰金の率(ただし1 < 罰金率 =< 担保率)

4. Daiの貸し借りの際のギャップ(-5%から+5%までの間しか設定できない)

5. Daiの価格調整コントラクトにおける価格調整率(どれくらいの幅で価格を変動させるか)→ 10%/day以下

6. Daiの発行限度額、ガバナンスフィーや流動性フィー

 

今回はシンプル化したDaiということで、担保率決定の際に使われるETHの価格やガバナンスフィー支払いのためのMKRの価格は管理者が独断で決める感じです。本来のDaiはここをオラクルで決めています。また確実に罰金を取れるよう、担保率は罰金より大きくなっています。

 

最後にTop.solについて解説します。

これは問題が起きた時にシャットダウンを安全に行うためのコントラクトです。Tab.sol、Tub.sol、つまりはトークン・担保の情報をもつコントラクト全てを継承していることからもわかるように、担保の精算・トークンのレート固定を行うのが役割です。

シャットダウンの流れとしては

1.トークンや担保・負債総額の情報を最新にする

次回詳しくは紹介しますが、現在のトークン情報や負債・担保に関する最新の状況をキャッチします。基本的にはこの情報を用いた値で全体をフィックスするのがこのシャットダウンで行うことです

2. DaiおよびSkrの価格をフィックスする

先ほど最新化した情報を用いてDaiおよびSkr(WETHを変換した担保用のトークン)の価格を固定します。

価格の式としてはDai価格はDaiのETHだて価格の逆数(Dai価格はETH/Daiなのに対しDaiのETHだて価格はDai/ETHのため)か(Gemのデポジット総額/Daiの発行総額)のうち小さい方です。

Skrの価格はETH/USD×Dai/USD×USD/Dai×担保されたETHの総量/Skrの総量となります。端的に言えばETHの量/Skrの量のドル建て価格という感じになります。これをトークンの動きを司るコントラクト(Tub.sol、Tab.sol)に送り、この価格で固定するように命令します。

3. 市場機能をオフにする

最後に市場機能(価格の需給変動)が働いているかどうかのフラッグをオフ(False)にします。これによって他のコントラクトも「シャットダウンした後なんだ」というのが理解できるようになります。そして一定期間状態を動かせないようにすることで事故るのを防ぎます。