Crypto OS
Technical Crypto OS第4段階 · DeFi 開発

T22 · レンディングプロトコル

清算エンジンは、いつ市場より速く動く必要があるか?

この章を 3D で体験する →
練習する能力
BuilderFinancial Literacy
実践
最小限のレンディングプールと清算関数を実装し、価格急落を起こして清算が間に合うか確認する。
AI Lab
AI に金利曲線を設計させ、資金利用率が 50% から 99% に上がると何が起きるか自分でシミュレーションする。

現実の問題

借貸プールは一か月、正常に動いています。

最も誇る金利曲線は区分線形で、折れ点も美しく、高利用率で急上昇します。借り手と預け手の曲線も対称で、全傾きを小数点以下六桁までテストしました。

ある午後、担保が 20 分で 25% 下落します。

翌日の照合で、清算後の換金額が債務に足りず、プロトコルが負う不良債務を見つけます。

調べます。

  • 健全度の誤りか?手計算と一致します。
  • 清算関数のバグか?数百回テスト済みです。
  • 価格源か?T21 の四確認は正常で、価格も追随しました。
  • 担保率か?75% で通常の値です。

全部品が正常でも、不良債務です。

チェーンでは、14:32 に清算可能となり、初回の成功清算は 14:36でした。

4 分間に、さらに 12% 下落しました。

一か月金利を磨いても、安全性を決めたのは 4 分でした。

思考実験

金利を置き、質屋として考えます。

100 の物に 75 を貸します。

価格 80 なら安全でも、70 なら損失です。

全担保を常時見られないので、市場へ任せます。入口へ掲示します。

80 を下回った担保を、誰でも現在価格の 95% で買い、代金で返済できます。

雇用者ではなく、給与も義務もありません。 利益がある時だけ来ます。

四つに分解します。

第一は、なぜ来るかです。 5% 割引だけです。価値 200 なら 10 で、手数料後は割に合わないかもしれません。

第二は、速さです。 発見、190 の準備か借入、送信、収録を待ちます。

第三は、競争です。 同じ機会を全員が見て、一人だけ勝ちます。敗者は手数料を失い、次は高く入札し、費用は最終的にユーザーへ移ります。

第四は、25% の余裕の意味です。

安全クッションでなく、時間予算です。

下落開始から清算完了まで、最大 25% しか下がれないという意味です。速い下落か遅い清算なら、質屋が不足を負います。

本当の問いは率でなく、価格と清算のどちらが速いかです。

あなたが決める

急落で多くが閾値へ近付くとき、どのレバーを動かしますか?

結果を観察する

すべて、時間を買っています。

レバー買うもの支払者副作用
担保率低下下落予算全借り手、効率低下既存清算を起こす
報酬増速い応答清算される人積極的清算
部分清算ユーザーの余裕プロトコル、遅延小口不参加
増加報酬正確な値付け清算者とユーザー固有遅延

不等式にします。

不良債務の条件:

    清算遅延中の担保下落
                >
    清算閾値の余裕と、報酬が使う部分

余裕 = 1 - 債務 / (担保価値 * 清算閾値)       ← 設計可能
遅延 = 発見 + 判断 + 資金準備 + 収録          ← 制御不能

左は市場の速度、右は設計です。比較で安全性が決まります。

設定や金利の連続性という右側へ注目しがちでも、事故は変動の激しさと清算の遅さという左から来ます。

安全の境界は清算速度で、金利モデルの美しさではありません。

金利は収益、清算は生存を決めます。

モデルを作る

遅延を分けます。

  1. 価格下落
  2. 閾値割れ
  3. 発見
  4. 資金準備と送信
  5. 収録
  6. 清算完了
第二から最後までが清算遅延で、各区間を個別に測定、改善できます。
段階時間改善者方法
価格がチェーンへ入る更新周期次第プロトコルT21 の設定
発見ミリ秒〜分周辺参加者イベント、公開照会
資金準備借入でほぼゼロプロトコル清算取引内の借入
収録一〜複数ブロック清算者高 Gas
競争失敗の再試行全段の数倍もプロトコル部分清算、報酬

最後が漏れやすく、混雑で急増します。 10 人中 9 人が失敗し、再計算、再送する間も下がります。

中心の三関数です。

第一は健全度です。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// 比率は bps で、浮動小数点を避ける
uint256 constant BPS = 10_000;

struct Account {
    uint256 collateral;   // 担保数量
    uint256 debt;         // 指数で利息を累積した債務
}

/// 1 以上は安全、1 未満は清算可能
/// BPS 倍なので、10_000 は 1.0
function healthFactor(
    uint256 collateral,
    uint256 price,              // 担保単価
    uint256 liquidationLtv,     // 清算閾値。通常 7000–8500 bps、資産別設定
    uint256 debt
) pure returns (uint256) {
    if (debt == 0) return type(uint256).max;
    uint256 adjusted = collateral * price * liquidationLtv / BPS;
    return adjusted * BPS / debt;
}

二点あります。

  • 清算閾値と担保率は別です。 借入上限と清算地点で、後者を高くし、その差がユーザーが救済する唯一の余地です。
  • 利息を累積してから計算します。 価格が同じでも、放置ポジションは利息だけで割れます。

第二は金利です。 二傾斜が一般的です。

/// 利用率 = 借出総額 / 預入総額
function utilization(uint256 borrowed, uint256 supplied) pure returns (uint256) {
    if (supplied == 0) return 0;
    return borrowed * BPS / supplied;
}

/// 折れ点前は緩く、後は急
function borrowRate(
    uint256 u,           // 利用率 bps
    uint256 base,        // 基本金利
    uint256 slope1,      // 前半の傾き
    uint256 slope2,      // 後半。通常 slope1 より一桁大きい
    uint256 kink         // 折れ点、通常 8000–9000 bps、設定可能
) pure returns (uint256) {
    if (u <= kink) {
        return base + u * slope1 / kink;
    }
    uint256 excess = u - kink;
    return base + slope1 + excess * slope2 / (BPS - kink);
}

急傾斜は利益より流動性の保護です。100% 近くでは預け手が引き出せず、高金利で返済を促します。

価格による制限です。 傾きと、即時返済能力で効果が決まります。

第三は清算です。 最も注意が必要です。

error NotLiquidatable(uint256 health);
error TooMuchDebt();

function liquidate(
    address user,
    uint256 repayAmount        // 清算者の返済額
) external {
    Account storage a = accounts[user];
    _accrueInterest(user);

    uint256 price = priceGuard.readPrice();          // T21 の四確認
    uint256 health = healthFactor(a.collateral, price, liquidationLtv, a.debt);
    if (health >= BPS) revert NotLiquidatable(health);

    // closeFactor は通常 5000 bps 前後で設定可能
    uint256 maxRepay = a.debt * closeFactor / BPS;
    if (repayAmount > maxRepay) revert TooMuchDebt();

    // 同価値の担保と報酬
    uint256 seized = repayAmount * BPS / price;
    seized = seized * (BPS + liquidationBonus) / BPS;

    // 担保不足は不良債務の発生箇所
    if (seized > a.collateral) {
        seized = a.collateral;
        // 未返済を消さず、明示記帳
        _recordBadDebt(user, a.debt - repayAmount);
    }

    a.debt -= repayAmount;
    a.collateral -= seized;

    _pullDebtToken(msg.sender, repayAmount);
    _pushCollateral(msg.sender, seized);
}

if は不良債務の発生点で、明示して記帳します。

担保不足で revert すると、永久に清算不能になります。利息は増え、担保は不足したままで、既知の損失が増え続ける穴へ変わります。

不良債務は避け切れなくても、可視化します。 準備金、比例分担、開示で対応でき、隠すと引き出し失敗時に集中して表れます。

何と呼ぶか

Collateral Factor / LTV担保率

担保一単位から借りられる最大割合です。

借入上限と清算地点は別で、間の隙間が唯一の救済時間です。ゼロなら開始から閾値に接します。

Health Factor健全度

清算閾値で調整した担保価値を、債務で割ります。

1 以上は安全、未満は清算可能です。金額でなく比率なので、同値でも大きいほど失敗の影響が大きく、両方監視します。

Utilization / Kink利用率/折れ点

借出と預入の比、および傾きが変わる地点です。

急傾斜は流動性保護で、返済を促し引き出しを可能にします。低利用率の形より、100% 近くで十分厳しいかを見ます。

Liquidation Bonus清算報酬

割引で担保を取得する部分です。

清算を起こす唯一の理由です。低ければ不参加、高ければ過剰罰と積極清算になり、速度に値付けします。

Close Factor一回の清算上限

一回で返せる債務割合です。

ユーザー保護とプロトコル保護の調整です。小さいほど穏やかでも遅く、極端時に緩和する実装があります。

Bad Debt不良債務

清算後も補えない債務です。

問題は記帳されたかです。見えれば吸収、分担でき、隠せば取り付けになります。

実践

実践最小借貸と清算を作り、急落で間に合うか検証するSolidity + 任意のコントラクトテストフレームワーク0 円、すべてローカルネットワーク

最小プールを作ります。 担保と借出を一種類ずつ、supply、borrow、repay、withdraw、liquidate を実装します。

利息は全体指数を時間で進め、債務を開始時指数で割った元本として保存し、ユーザー数によらず O(1) にします。

T21 の PriceGuard の全確認を残します。

第一は数値の正確性です。

  • 担保 100、価格 100、率 7500 なら最大 7500、7501 は拒否。
  • 30 日後に利率通り増え、手計算と一致。
  • 健全度 1 ちょうどは清算不可、未満だけ可能。

以上か大なりかが、境界ポジションを決めます。

第二は急落を作ります。

制御可能なオラクルで模擬します。

ブロック 0    価格 100、健全度 1.33
ブロック 1    価格 92
ブロック 2    価格 85    ← 清算線を割る
ブロック 3    価格 79
ブロック 4    価格 74
ブロック 5    価格 70

2 で即清算しません。 3、4、5 でそれぞれ試します。

清算時点清算者の取得ユーザー残余不良債務
3、1 ブロック遅延
4、2 ブロック遅延
5、3 ブロック遅延

初めて不良債務が出る行が、最大許容遅延です。

第三は清算者が来ない場合です。

小口にし、利益を計算します。

純利益 = 清算額 * 報酬 - Gas - 担保換金のスリッページ

0 以下なら、合理的な清算者は来ない

境目の規模を求めます。 未満は動かず、細かな不良債務を蓄積します。

Gas を十倍にして再計算します。混雑時に集中する理由です。

設定の失敗境界を求めます。

遅延と期間内の下落の二次元表にします。

             1 ブロック   3 ブロック   10 ブロック
5% 下落        安全        安全         安全
15% 下落       安全        安全         不良債務
30% 下落       安全        不良債務     不良債務
50% 下落       不良債務    不良債務     不良債務

担保率、閾値、報酬から、実際の境界を測ります。

三問に答えます。

  1. 歴史的な一時間の最大下落は?
  2. その時の Gas と清算遅延は?
  3. 表のどのセルか?

不良債務なら設定を変えます。通常、変えるべきは金利ではありません。

ローカルだけで実資金は使いません。 卒業課題でも第五段階の安全性確認後です。

AI Lab

AI LabAI に金利を設計させ、利用率が 50% から 99% へ上がる場合を模擬するLevel 2 · AI Copilot

三段階です。

第 1 段階:
二傾斜の金利の設定、式、Solidity を示し、折れ点と有効な傾きを説明してください。

第 2 段階:
二時間で 50% から 99% へ進む過程を模擬し、
借入金利、預入金利、返済と預入の動機を示してください。
市場が戻し始める利用率はどこですか?

第 3 段階:
100% のままなら、預け手、借り手、プロトコルはどうなりますか?
介入と代償を列挙してください。

曲線設計は簡単でも、自力回復の説明は難しいものです。 返済可能か、ロックされた資金ならどうか、同時返済の購入で価格が上がらないか追問します。

第三で、預け手は引き出せず、高金利も使える資金にならないと気付くか確認します。続けば取り付けです。

実数字のスクリプトとグラフで確認し、美しい式だけを見ません。

AI の回答後、自分で必ず検証すること

  • 50%、80%、95%、99%、100% を自分で代入し、金利が一致する
  • 99% で即返済を促すほど高い。比較的高いだけでは足りない
  • 預入金利からプロトコル取り分を差し引く
  • 折れ点の両側が同じ値で、連続する
  • 100% の引き出し不能と、金利上昇の可能性を説明する
  • 具体値を事実でなく設定の開始点として扱う

実例

混雑で清算がブロックから押し出された2020 年以降の急変

急落時は全員が取引し、Gas が数十倍になります。固定割合の利益で競争します。

最も必要な時に割に合いません。 Gas 未満は実行せず、落ち着く頃には不足です。

遅延は定数でなく、市場圧力と正に相関します。平穏時の測定で設計しません。

入札がなく、極低価格で落札された複数回

極端相場や回線問題で参加がなく、ほぼゼロまで下がり、ほぼ無料で取得されました。

担保が消え、債務が残りました。

最低価格と、参加者不在時の動作が必要です。

利用率 100% で引き出せなかった持続的リスク

大量借入で残高がなく、引き出しは失敗します。

金利が高くても、借り手の投資先がロックされていれば返せず、債務を増やすだけです。

金利は遅れた調整で、固定された資金を動かせません。 急傾斜が不十分な理由です。

小口の不良債務が蓄積したすべての借貸

小口の報酬が Gas 未満で、清算されません。

利息が増え続け、数か月で大きくなります。

最低借入額と、一取引で複数を処理する一括清算で費用を分散します。

変数を一つ変える

もし報酬を 5% から 15% へ増やす

速くなり、小口も有利になって不良債務が減ります。

ユーザーの追加 10% の損失に加え、積極的清算が増えます。市場価格を下げて対象を増やす動機も生まれ、事後処理者が出来事を作る人になります。

大きな報酬は行動を変えます。

もし担保率を 75% から 90% へ上げる

効率、魅力、借出、収益が増えます。

時間予算は 25% から 10% へ減り、安全セルの多くが不良債務へ移ります。

安定かつ深い資産だけへ高率を使います。上限は好みでなく、変動と遅延から計算します。

もし0.4 秒生成でも、頻繁に混雑するチェーンへ変える

理論上は数十倍速くなります。

競争の失敗費用が増すことと、ブロック数設定の再計算に注意します。10 ブロックが 2 分から 4 秒でも、混雑時に成立するとは限りません。

時間関連はコピーせず再導出します。 T21 と同じです。

もし一回の上限を 50% から 100% にする

全体を一回で処理し、倍の利益で速くなり、プロトコルを守ります。

短い価格の下振れでも全担保を失い、数分後の回復を待てず、ユーザーに厳しくなります。

通常は段階分けし、半分を標準に、健全度が低い極端時だけ全額を許します。

持ち帰る問い

5
誰が支払っているか?

誰が支払いますか?借り手の利息を預け手とプロトコルへ分け、清算者へ追加報酬を払います。三つの流れが商業モデルです。

8
誰が流動性を提供するか?

誰が流動性を提供しますか?預け手に加え、担保を即買う清算者も提供します。市場が浅いと完了できず、T21 と同じです。

9
誰がリスクを負うか?

誰がリスクを負いますか?準備金と預け手です。清算者に最悪時のサービス義務はありません。不参加へ備えます。

10
インセンティブは何か?

動機は何ですか?報酬から費用を引いた数です。文書より、その取引の利益を計算します。

章末チェック

要点

レンディングプロトコルの安全性を決めるのは清算の速さであり、金利モデルの美しさではない。

この章の実践課題を終えたらチェックしてください進捗をすべて見る

このページの内容