skills/stanah/dotagents/solidity-defi

solidity-defi

SKILL.md

solidity-defi: DeFi プロトコル開発スキル

DeFi プロトコル開発における主要パターン(AMM、レンディング、オラクル、Vault)を提供するドメイン特化スキル。

対象

  • AMM / DEX(Uniswap V2/V3 型、Curve 型)
  • レンディングプロトコル(Aave / Compound 型)
  • 価格オラクル統合(Chainlink、TWAP)
  • Vault / yield 戦略(ERC4626)

ワークフロー

Step 1: DeFi ドメイン判定

ユーザーの要件から対象ドメインを判定する:

ユースケース 対応ドメイン リファレンス
トークン交換・流動性提供 AMM / DEX references/amm-patterns.md — Constant Product (Uniswap V2)、Concentrated Liquidity (V3)、StableSwap (Curve) から選択
貸付・借入・清算 レンディング references/lending-patterns.md — 金利モデル、担保管理、清算メカニズムを確認
外部価格データ取得 オラクル references/oracle-patterns.md — Chainlink Data Feed、TWAP、複合オラクルから選択
預入・利回り・戦略 Vault references/vault-patterns.md — ERC4626 標準、inflation attack 防御、マルチ戦略

複数のドメインが関連する場合(例: Vault + オラクル)は、全ての該当リファレンスを読み込む。

ユーザーの要件が不明確な場合は AskUserQuestion で DeFi の具体的なユースケースを確認する。

検証ゲート: 対象ドメインが上記 4 つのいずれかに該当すること。

Step 2: リファレンス読み込み

Step 1 で特定したリファレンスファイルを読み込み、以下を確認する:

  1. 該当パターンの設計思想と制約条件
  2. 必要なインターフェース(ERC4626、Chainlink AggregatorV3 等)
  3. コード例の前提条件(Solidity バージョン、依存ライブラリ)

検証ゲート: リファレンスが正常に読み込め、該当パターンが特定できること。

Step 3: コード生成

  1. solidity-corelanguage-patterns.md に従い NatSpec・コーディング規約を適用する。
  2. DeFi 固有のセキュリティ対策を組み込む:
    • 全ての state-changing 関数に nonReentrant 修飾子
    • スリッページ保護パラメータ(minAmountOut, deadline
    • 適切な数値精度(WAD / RAY / BPS)
  3. テストコードを同時に生成する:
    • 正常系(swap、deposit、withdraw)
    • 異常系(スリッページ超過、残高不足、権限不足)
    • Fuzz テスト(数値入力のある関数)
    • Invariant テスト(プールの不変条件: k >= kBefore

検証ゲート: forge build がエラーなく完了すること。

Step 4: DeFi セキュリティ確認

DeFi 特有のセキュリティリスクを solidity-coresecurity-checklist.md と合わせて確認する:

  1. フラッシュローン攻撃: 1 トランザクション内での価格操作に耐性があるか。TWAP を使用しているか。
  2. 価格操作: オラクルがスポット価格のみに依存していないか。Chainlink の latestRoundData で stale check をしているか。
  3. Reentrancy: CEI パターン + nonReentrant を遵守しているか。特に withdraw / redeem 関数。
  4. スリッページ保護: ユーザーが minAmountOut を指定でき、フロントランニングから保護されているか。
  5. MEV 対策: deadline パラメータでサンドイッチ攻撃のウィンドウを制限しているか。
  6. Inflation Attack(ERC4626): 初回デポジットのシェア膨張攻撃に対して virtual shares / virtual assets で防御しているか。

検証ゲート: CRITICAL レベルのセキュリティ問題が 0 件であること。

使用例

例 1: Uniswap V2 型 AMM の実装

ユーザー入力: 「シンプルな AMM を作りたい。流動性追加とトークンスワップができるようにして」

アクション:

  1. Step 1: AMM / DEX と判定 → references/amm-patterns.md を選択
  2. Step 2: Constant Product AMM パターンを読み込み
  3. Step 3: 以下を生成:
    • src/ConstantProductAMM.sol — Pair コントラクト(x * y = k ロジック、nonReentrant、スリッページ保護)
    • src/interfaces/IAMM.sol — インターフェース定義
    • test/ConstantProductAMM.t.sol — addLiquidity / swap / removeLiquidity のテスト + K 値 invariant テスト
  4. Step 4: セキュリティ確認 → Reentrancy 防止、スリッページ保護、K 値検証を確認

結果: スリッページ保護・Reentrancy 防止を備えた AMM とテストスイートが生成される。

例 2: ERC4626 Vault の実装

ユーザー入力: 「ERC4626 の Vault を作りたい。ETH ステーキングの利回りを分配するもの」

アクション:

  1. Step 1: Vault と判定 → references/vault-patterns.md を選択
  2. Step 2: ERC4626 標準 + inflation attack 防御パターンを読み込み
  3. Step 3: 以下を生成:
    • src/StakingVault.sol — OpenZeppelin ERC4626 を継承。virtual shares / virtual assets で inflation attack を防御。deposit / withdraw / redeem 実装
    • test/StakingVault.t.sol — デポジット・引出のテスト + 初回デポジット攻撃の防御テスト + share 計算の Fuzz テスト
  4. Step 4: inflation attack 防御の確認、Reentrancy 確認

結果: Inflation attack に耐性のある ERC4626 Vault がテスト付きで生成される。

例 3: Chainlink オラクル統合

ユーザー入力: 「ETH/USD の価格を Chainlink で取得して、USD 建ての計算をしたい」

アクション:

  1. Step 1: オラクルと判定 → references/oracle-patterns.md を選択
  2. Step 2: Chainlink Data Feed パターンを読み込み
  3. Step 3: 以下を生成:
    • src/PriceConsumer.solAggregatorV3Interface を使用。stale price チェック(updatedAt + 閾値)、negative price チェック、decimals 正規化
    • test/PriceConsumer.t.sol — モックオラクルでテスト。stale price / negative price / decimals 変換のテスト
  4. Step 4: stale check の閾値(heartbeat 設定に基づく)、フォールバックオラクルの有無を確認

結果: Stale / negative price に対するガードを備えた Chainlink オラクル統合が生成される。

トラブルシューティング

1. K 値 invariant テストが失敗する

症状: AMM の require(k >= kBefore) でリバート

原因と対策:

  • 丸め誤差: Solidity の整数除算による丸めで K 値が微小に減少する。require(k >= kBefore - 1) で許容誤差を設定するか、mulDiv 関数で精度を向上させる。
  • 手数料計算の順序: 手数料を差し引いてからスワップ計算を行っているか確認する。手数料を考慮した K 値検証にする。

2. Chainlink オラクルが stale 価格を返す

症状: require(updatedAt > block.timestamp - STALE_THRESHOLD) でリバート

原因と対策:

  • heartbeat 設定の不一致: Chainlink の Data Feed ごとに heartbeat(更新間隔)が異なる。ETH/USD(Mainnet)は 3600 秒。対象 feed の heartbeat を確認し、STALE_THRESHOLD を heartbeat + バッファ(例: 3600 + 300)に設定する。
  • テストネットの挙動: テストネットの Chainlink feed は本番より更新が遅い場合がある。テストではモックオラクルを使用する。
  • フォールバック: Chainlink が応答しない場合に備え、TWAP 等のフォールバックオラクルを設定する。

3. ERC4626 の share 計算がゼロになる

症状: deposit 後に balanceOf(user) がゼロ

原因と対策:

  • Inflation attack: 攻撃者が最初に 1 wei をデポジット後、大量のトークンを直接 Vault に送信して share 価値を膨張させた。OpenZeppelin の ERC4626 は v5.x でデフォルトで virtual shares/assets(オフセット = 1)を使用するため、最新版を使用する。
  • decimals の不一致: 基礎トークンと Vault の decimals が異なる。decimalsOffset() を確認する。

4. swap トランザクションがフロントランされる

症状: 予想よりも不利なレートでスワップが実行される

原因と対策:

  • スリッページ保護の不足: minAmountOut パラメータが 0 に設定されている。フロントエンドで適切なスリッページ(0.5-1%)を計算して設定する。
  • deadline 未設定: deadline パラメータでトランザクションの有効期限を設定する。block.timestamp + 300(5分)が一般的。
  • Private mempool: Flashbots Protect 等のプライベート RPC を使用し、パブリック mempool にトランザクションを公開しない。

5. Reentrancy による資金流出

症状: withdraw 関数が繰り返し呼び出され、想定以上の資金が引き出される

原因と対策:

  • CEI パターン違反: 外部呼び出し(token.transfer)の前に状態を更新(残高減算)しているか確認する。Checks-Effects-Interactions の順序を厳守する。
  • nonReentrant 未使用: 全ての資金移動関数に OpenZeppelin の ReentrancyGuard.nonReentrant を適用する。
  • コールバック関数: ERC777 や receive() / fallback() からの再帰呼び出しに注意する。

注意事項

  • DeFi プロトコルは攻撃対象になりやすいため、セキュリティを最優先にする。
  • 数値計算は精度が重要。WAD(1e18)、RAY(1e27)、BPS(1e4)を一貫して使用する。
  • 基盤的なパターン(アクセス制御、ガス最適化等)は solidity-core を参照する。
  • フロントエンド統合は web3-frontend を参照する。
  • 本番デプロイ前に外部監査を推奨する。
  • OpenZeppelin コントラクト(ERC4626, ReentrancyGuard 等)の利用を推奨し、独自実装は避ける。
Weekly Installs
2
First Seen
Feb 21, 2026
Installed on
opencode2
gemini-cli2
claude-code2
github-copilot2
codex2
kimi-cli2