T22 · レンディングプロトコル
清算エンジンは、いつ市場より速く動く必要があるか?
- 練習する能力
- 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 - 債務 / (担保価値 * 清算閾値) ← 設計可能
遅延 = 発見 + 判断 + 資金準備 + 収録 ← 制御不能左は市場の速度、右は設計です。比較で安全性が決まります。
設定や金利の連続性という右側へ注目しがちでも、事故は変動の激しさと清算の遅さという左から来ます。
安全の境界は清算速度で、金利モデルの美しさではありません。
金利は収益、清算は生存を決めます。
モデルを作る
遅延を分けます。
- 価格下落
- 閾値割れ
- 発見
- 資金準備と送信
- 収録
- 清算完了
| 段階 | 時間 | 改善者 | 方法 |
|---|---|---|---|
| 価格がチェーンへ入る | 更新周期次第 | プロトコル | 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 すると、永久に清算不能になります。利息は増え、担保は不足したままで、既知の損失が増え続ける穴へ変わります。
不良債務は避け切れなくても、可視化します。 準備金、比例分担、開示で対応でき、隠すと引き出し失敗時に集中して表れます。
何と呼ぶか
担保一単位から借りられる最大割合です。
借入上限と清算地点は別で、間の隙間が唯一の救済時間です。ゼロなら開始から閾値に接します。
清算閾値で調整した担保価値を、債務で割ります。
1 以上は安全、未満は清算可能です。金額でなく比率なので、同値でも大きいほど失敗の影響が大きく、両方監視します。
借出と預入の比、および傾きが変わる地点です。
急傾斜は流動性保護で、返済を促し引き出しを可能にします。低利用率の形より、100% 近くで十分厳しいかを見ます。
割引で担保を取得する部分です。
清算を起こす唯一の理由です。低ければ不参加、高ければ過剰罰と積極清算になり、速度に値付けします。
一回で返せる債務割合です。
ユーザー保護とプロトコル保護の調整です。小さいほど穏やかでも遅く、極端時に緩和する実装があります。
清算後も補えない債務です。
問題は記帳されたかです。見えれば吸収、分担でき、隠せば取り付けになります。
実践
最小プールを作ります。 担保と借出を一種類ずつ、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 価格 702 で即清算しません。 3、4、5 でそれぞれ試します。
| 清算時点 | 清算者の取得 | ユーザー残余 | 不良債務 |
|---|---|---|---|
| 3、1 ブロック遅延 | |||
| 4、2 ブロック遅延 | |||
| 5、3 ブロック遅延 |
初めて不良債務が出る行が、最大許容遅延です。
第三は清算者が来ない場合です。
小口にし、利益を計算します。
純利益 = 清算額 * 報酬 - Gas - 担保換金のスリッページ
0 以下なら、合理的な清算者は来ない境目の規模を求めます。 未満は動かず、細かな不良債務を蓄積します。
Gas を十倍にして再計算します。混雑時に集中する理由です。
設定の失敗境界を求めます。
遅延と期間内の下落の二次元表にします。
1 ブロック 3 ブロック 10 ブロック
5% 下落 安全 安全 安全
15% 下落 安全 安全 不良債務
30% 下落 安全 不良債務 不良債務
50% 下落 不良債務 不良債務 不良債務担保率、閾値、報酬から、実際の境界を測ります。
三問に答えます。
- 歴史的な一時間の最大下落は?
- その時の Gas と清算遅延は?
- 表のどのセルか?
不良債務なら設定を変えます。通常、変えるべきは金利ではありません。
ローカルだけで実資金は使いません。 卒業課題でも第五段階の安全性確認後です。
AI Lab
三段階です。
第 1 段階:
二傾斜の金利の設定、式、Solidity を示し、折れ点と有効な傾きを説明してください。
第 2 段階:
二時間で 50% から 99% へ進む過程を模擬し、
借入金利、預入金利、返済と預入の動機を示してください。
市場が戻し始める利用率はどこですか?
第 3 段階:
100% のままなら、預け手、借り手、プロトコルはどうなりますか?
介入と代償を列挙してください。曲線設計は簡単でも、自力回復の説明は難しいものです。 返済可能か、ロックされた資金ならどうか、同時返済の購入で価格が上がらないか追問します。
第三で、預け手は引き出せず、高金利も使える資金にならないと気付くか確認します。続けば取り付けです。
実数字のスクリプトとグラフで確認し、美しい式だけを見ません。
AI の回答後、自分で必ず検証すること
- 50%、80%、95%、99%、100% を自分で代入し、金利が一致する
- 99% で即返済を促すほど高い。比較的高いだけでは足りない
- 預入金利からプロトコル取り分を差し引く
- 折れ点の両側が同じ値で、連続する
- 100% の引き出し不能と、金利上昇の可能性を説明する
- 具体値を事実でなく設定の開始点として扱う
実例
急落時は全員が取引し、Gas が数十倍になります。固定割合の利益で競争します。
最も必要な時に割に合いません。 Gas 未満は実行せず、落ち着く頃には不足です。
遅延は定数でなく、市場圧力と正に相関します。平穏時の測定で設計しません。
極端相場や回線問題で参加がなく、ほぼゼロまで下がり、ほぼ無料で取得されました。
担保が消え、債務が残りました。
最低価格と、参加者不在時の動作が必要です。
大量借入で残高がなく、引き出しは失敗します。
金利が高くても、借り手の投資先がロックされていれば返せず、債務を増やすだけです。
金利は遅れた調整で、固定された資金を動かせません。 急傾斜が不十分な理由です。
小口の報酬が Gas 未満で、清算されません。
利息が増え続け、数か月で大きくなります。
最低借入額と、一取引で複数を処理する一括清算で費用を分散します。
変数を一つ変える
速くなり、小口も有利になって不良債務が減ります。
ユーザーの追加 10% の損失に加え、積極的清算が増えます。市場価格を下げて対象を増やす動機も生まれ、事後処理者が出来事を作る人になります。
大きな報酬は行動を変えます。
効率、魅力、借出、収益が増えます。
時間予算は 25% から 10% へ減り、安全セルの多くが不良債務へ移ります。
安定かつ深い資産だけへ高率を使います。上限は好みでなく、変動と遅延から計算します。
理論上は数十倍速くなります。
競争の失敗費用が増すことと、ブロック数設定の再計算に注意します。10 ブロックが 2 分から 4 秒でも、混雑時に成立するとは限りません。
時間関連はコピーせず再導出します。 T21 と同じです。
全体を一回で処理し、倍の利益で速くなり、プロトコルを守ります。
短い価格の下振れでも全担保を失い、数分後の回復を待てず、ユーザーに厳しくなります。
通常は段階分けし、半分を標準に、健全度が低い極端時だけ全額を許します。
持ち帰る問い
誰が支払いますか?借り手の利息を預け手とプロトコルへ分け、清算者へ追加報酬を払います。三つの流れが商業モデルです。
誰が流動性を提供しますか?預け手に加え、担保を即買う清算者も提供します。市場が浅いと完了できず、T21 と同じです。
誰がリスクを負いますか?準備金と預け手です。清算者に最悪時のサービス義務はありません。不参加へ備えます。
動機は何ですか?報酬から費用を引いた数です。文書より、その取引の利益を計算します。
章末チェック
完了前の下落が余裕を超えると不良債務だからです。
金利は収益、利用率、参加意欲に重要でも、急落の破綻を決めません。
美しい曲線でも高率と遅い清算なら損失で、粗い曲線でも保守的な率と速い清算なら耐えます。
開く上限と閉じる条件で、後者を高くします。
間に返済や追加の救済時間を作ります。
同値なら開始から境界で、微小変動や利息だけで清算します。
利益不足、換金困難、競争失敗の三つです。
最低額、一括清算、時間増加報酬、同取引借入で対応します。
不参加を、例外でなく必ず起きる状態として設計します。
いいえ。永久に清算不能で、利息が不足を増やします。
残担保を処理し、残債を明示記帳し、イベントで知らせます。
不可避でも可視化します。 隠せば引き出し失敗時に集中し、取り付けになります。
唯一の正解はありません。次を含めます。
- 歴史的な一時間最大下落と頻度。
- その時の実際の清算遅延をチェーンから測る。
- 遅延中の下落と報酬が使う余裕。
- 市場深度と、換金のずれが報酬を消すか。
- 全体のエクスポージャー上限で、集中が全体問題にならないか。
第二、第四が省略されやすく、実データが必要で、成否を決めます。
要点
レンディングプロトコルの安全性を決めるのは清算の速さであり、金利モデルの美しさではない。