<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Lending on Jeongseup Blog</title><link>https://jeongseup.github.io/tags/lending/</link><description>Recent content in Lending on Jeongseup Blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Fri, 27 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jeongseup.github.io/tags/lending/index.xml" rel="self" type="application/rss+xml"/><item><title>DefiDash</title><link>https://jeongseup.github.io/project/defidash/</link><pubDate>Thu, 22 Jan 2026 00:00:00 +0000</pubDate><guid>https://jeongseup.github.io/project/defidash/</guid><description>&lt;img src="https://jeongseup.github.io/img/thumbs/project_defidash.jpeg" alt="Featured image of post DefiDash" /&gt;&lt;h2 id="role"&gt;Role
&lt;/h2&gt;&lt;p&gt;Owner &amp;amp; Team Lead (curg-13)&lt;/p&gt;
&lt;h2 id="description"&gt;Description
&lt;/h2&gt;&lt;p&gt;DefiDash is a DeFi leverage lending aggregator built on the Sui ecosystem. It aggregates multiple lending protocols on Sui to provide optimized leverage strategies for consumer users. The project consists of three repositories: a TypeScript SDK for protocol integration, a frontend DApp, and a marketing website.&lt;/p&gt;
&lt;h2 id="tech-stack"&gt;Tech Stack
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Sui Move&lt;/li&gt;
&lt;li&gt;React / Next.js&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Building a Leverage Position Preview for DeFi on Sui</title><link>https://jeongseup.github.io/project/defidash/defidash-preview-leverage/</link><pubDate>Fri, 27 Feb 2026 00:00:00 +0000</pubDate><guid>https://jeongseup.github.io/project/defidash/defidash-preview-leverage/</guid><description>&lt;img src="https://jeongseup.github.io/defidash-logo.jpeg" alt="Featured image of post Building a Leverage Position Preview for DeFi on Sui" /&gt;&lt;blockquote&gt;
&lt;p&gt;How I built &lt;code&gt;previewLeverage&lt;/code&gt; — a read-only preview engine that calculates leveraged lending position metrics across Suilend, Navi, and Scallop, without executing any on-chain transaction.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Team:&lt;/strong&gt; &lt;a class="link" href="https://github.com/curg-13" target="_blank" rel="noopener"
&gt;curg-13&lt;/a&gt; | &lt;strong&gt;SDK:&lt;/strong&gt; &lt;a class="link" href="https://github.com/curg-13/defidash-sdk" target="_blank" rel="noopener"
&gt;defidash-sdk&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="why-preview-before-leverage"&gt;Why Preview Before Leverage?
&lt;/h2&gt;&lt;p&gt;In DeFi lending, &lt;strong&gt;leverage&lt;/strong&gt; means borrowing against your collateral to amplify your position. A 2x leverage on $100 of SUI gives you $200 total exposure — potentially doubling your returns, but also your risk.&lt;/p&gt;
&lt;p&gt;Before users click &amp;ldquo;Confirm&amp;rdquo;, they need to know:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How much will be borrowed via flash loan?&lt;/li&gt;
&lt;li&gt;What&amp;rsquo;s the liquidation price?&lt;/li&gt;
&lt;li&gt;What&amp;rsquo;s the expected annual return (Net APY)?&lt;/li&gt;
&lt;li&gt;How far can the price drop before liquidation?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s what &lt;code&gt;previewLeverage&lt;/code&gt; computes — entirely off-chain, using real-time protocol data.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;preview&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;previewLeverage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;protocol&lt;/span&gt;: &lt;span class="kt"&gt;LendingProtocol.Suilend&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;depositAsset&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;SUI&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;depositValueUsd&lt;/span&gt;: &lt;span class="kt"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;multiplier&lt;/span&gt;: &lt;span class="kt"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// preview.netApy → 2.33%
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// preview.liquidationPrice → $0.63
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// preview.priceDropBuffer → 33%
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="glossary-lending-protocol-concepts"&gt;Glossary: Lending Protocol Concepts
&lt;/h2&gt;&lt;p&gt;If you&amp;rsquo;re a developer without DeFi background, here&amp;rsquo;s what you need to know. I&amp;rsquo;m also studying these concepts in depth — check the &lt;strong&gt;Lending Protocol Study&lt;/strong&gt; series for worked examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://jeongseup.github.io/p/lending-protocol-study-day1/" &gt;Day 1: DeFi 렌딩의 핵심 개념과 아키텍처&lt;/a&gt; — Pool-based 중개, Share-Based Accounting, Scaled Balance 패턴&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://jeongseup.github.io/p/lending-protocol-study-day2/" &gt;Day 2: Compound V2 Deep Dive와 Aave V3 아키텍처&lt;/a&gt; — Fresh 패턴, Mantissa 연산, 비트맵 스토리지 최적화&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ltv-loan-to-value"&gt;LTV (Loan-to-Value)
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;LTV&lt;/strong&gt; is the maximum percentage of your collateral&amp;rsquo;s value that you can borrow.&lt;/p&gt;
$$\text{LTV} = \frac{\text{Borrowed Value}}{\text{Collateral Value}}$$&lt;p&gt;If SUI has a 70% LTV on Suilend, depositing $100 of SUI lets you borrow up to $70 of USDC. Each protocol sets different LTV ratios per asset — riskier assets get lower LTV.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;SUI LTV&lt;/th&gt;
&lt;th&gt;XBTC LTV&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Suilend&lt;/td&gt;
&lt;td&gt;70%&lt;/td&gt;
&lt;td&gt;60%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Navi&lt;/td&gt;
&lt;td&gt;75%&lt;/td&gt;
&lt;td&gt;67%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scallop&lt;/td&gt;
&lt;td&gt;85%&lt;/td&gt;
&lt;td&gt;75%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;For more details on how Health Factor works with LTV, see &lt;a class="link" href="https://jeongseup.github.io/p/lending-protocol-study-day1/" &gt;Lending Protocol Study Day 1&lt;/a&gt; — the &amp;ldquo;Share-Based Accounting&amp;rdquo; section explains why each protocol tracks collateral differently.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="liquidation-threshold-lt"&gt;Liquidation Threshold (LT)
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Liquidation Threshold&lt;/strong&gt; is the LTV level at which your position gets liquidated. It&amp;rsquo;s always higher than the borrow LTV, creating a safety buffer.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Borrow LTV: 70% → You can borrow up to 70%
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Liq. Threshold: 75% → Liquidation triggers at 75%
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Safety buffer: 5%
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;When the market price drops and your position&amp;rsquo;s actual LTV exceeds the liquidation threshold, a liquidator can repay part of your debt and claim your collateral at a discount.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Liquidation mechanics are a deep topic — the &lt;a class="link" href="https://jeongseup.github.io/p/lending-protocol-study-day2/" &gt;Lending Protocol Study&lt;/a&gt; series covers Compound V2&amp;rsquo;s &lt;code&gt;liquidateBorrowFresh()&lt;/code&gt; and Aave V3&amp;rsquo;s architecture in detail.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="max-multiplier"&gt;Max Multiplier
&lt;/h3&gt;&lt;p&gt;Derived directly from LTV:&lt;/p&gt;
$$\text{Max Multiplier} = \frac{1}{1 - \text{LTV}}$$&lt;p&gt;With 70% LTV → max 3.33x leverage. With 85% LTV → max 6.67x. This is a hard protocol limit — you physically cannot borrow more than what the collateral factor allows.&lt;/p&gt;
&lt;h3 id="flash-loan"&gt;Flash Loan
&lt;/h3&gt;&lt;p&gt;A flash loan is an &lt;strong&gt;uncollateralized loan that must be borrowed and repaid within a single atomic transaction&lt;/strong&gt;. If you don&amp;rsquo;t repay, the entire transaction reverts as if it never happened.&lt;/p&gt;
&lt;p&gt;In our leverage strategy, the flow is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Flash loan USDC from Scallop&lt;/li&gt;
&lt;li&gt;Swap USDC → deposit asset (e.g., SUI)&lt;/li&gt;
&lt;li&gt;Deposit all collateral to lending protocol&lt;/li&gt;
&lt;li&gt;Borrow USDC from protocol (using deposited collateral)&lt;/li&gt;
&lt;li&gt;Repay flash loan&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All 5 steps happen in one Sui &lt;a class="link" href="https://docs.sui.io/concepts/transactions/prog-txn-blocks" target="_blank" rel="noopener"
&gt;Programmable Transaction Block (PTB)&lt;/a&gt;. If step 5 fails, everything reverts.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For more on why Sui&amp;rsquo;s PTB model is ideal for this — see &lt;a class="link" href="https://jeongseup.github.io/p/defidash-technical-journal-day1/" &gt;DefiDash Journal Day 1&lt;/a&gt; where we compare PTB-based atomic leverage vs EVM Flash Loan patterns.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="supply-apy--borrow-apy"&gt;Supply APY &amp;amp; Borrow APY
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Supply APY&lt;/strong&gt;: What you earn by depositing assets. Composed of base interest + reward tokens (e.g., sSUI, DEEP).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Borrow APY&lt;/strong&gt;: What you pay for borrowing. Some protocols give borrowing incentives (rebates).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Net APY&lt;/strong&gt;: The leveraged return on your equity.&lt;/li&gt;
&lt;/ul&gt;
$$\text{Net APY} = \frac{\text{Total Position} \times \text{Supply APY} - \text{Debt} \times \text{Borrow APY}}{\text{Initial Equity}}$$&lt;p&gt;With 2x leverage: if supply APY &amp;gt; borrow APY, your returns are amplified. If not, you&amp;rsquo;re paying more than you earn (negative Net APY).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The interest rate models behind these APYs (JumpRateModel, utilization curves) are covered in &lt;a class="link" href="https://jeongseup.github.io/p/lending-protocol-study-day1/" &gt;Lending Protocol Study Day 1&lt;/a&gt; and &lt;a class="link" href="https://jeongseup.github.io/p/lending-protocol-study-day2/" &gt;Day 2&lt;/a&gt;. Especially the Mantissa-based fixed-point arithmetic in Day 2 is directly relevant to how we parse on-chain rate data.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="liquidation-price"&gt;Liquidation Price
&lt;/h3&gt;&lt;p&gt;The asset price at which your position hits the liquidation threshold:&lt;/p&gt;
$$\text{Liquidation Price} = \frac{\text{Total Debt}}{\text{Total Collateral Amount} \times \text{Liquidation Threshold}}$$&lt;p&gt;For a $100 SUI position at 2x leverage on Suilend (LT = 75%):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Debt = $100, Total collateral = ~52.6 SUI (at $3.80)&lt;/li&gt;
&lt;li&gt;Liquidation Price = $100 / (52.6 × 0.75) ≈ $2.53&lt;/li&gt;
&lt;li&gt;That&amp;rsquo;s a ~33% price drop buffer from current price&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="how-its-built"&gt;How It&amp;rsquo;s Built
&lt;/h2&gt;&lt;h3 id="architecture"&gt;Architecture
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;previewLeverage(params)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ 1. Resolve coin type (&amp;#39;SUI&amp;#39; → &amp;#39;0x2::sui::SUI&amp;#39;)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ 2. Fetch risk params from protocol adapter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ └─ getAssetRiskParams(coinType) → { ltv, liquidationThreshold, maxMultiplier }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ 3. Validate multiplier ≤ maxMultiplier
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ 4. Fetch current price from 7k Protocol aggregator
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ 5. Position calculation
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ flashLoanUsdc = equity × (multiplier − 1) × 1.02 buffer
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ totalPositionUsd = equity × multiplier
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ └─ ltvPercent = debt / totalPosition × 100
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ 6. Liquidation calculation
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ liquidationPrice = debt / (collateralAmount × LT)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ └─ priceDropBuffer = (1 − liqPrice / currentPrice) × 100
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ 7. APY calculation
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ Supply APY: base + reward (per protocol adapter)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ ├─ Borrow APY: gross − rebate (per protocol adapter)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ └─ Net APY = (position × supplyAPY − debt × borrowAPY) / equity
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 8. Swap slippage estimation via 7k DEX aggregator quote
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="multi-protocol-adapter-pattern"&gt;Multi-Protocol Adapter Pattern
&lt;/h3&gt;&lt;p&gt;Each lending protocol (Suilend, Navi, Scallop) implements the &lt;code&gt;ILendingProtocol&lt;/code&gt; interface, and the preview engine queries them through a unified API:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ILendingProtocol&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;getAssetRiskParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;coinType&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;ltv&lt;/span&gt;: &lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;liquidationThreshold&lt;/span&gt;: &lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;maxMultiplier&lt;/span&gt;: &lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;getAssetApy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;coinType&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;supplyApy&lt;/span&gt;: &lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;rewardApy&lt;/span&gt;: &lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;borrowApy&lt;/span&gt;: &lt;span class="kt"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// ... deposit, borrow, withdraw, etc.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;The same &lt;code&gt;previewLeverage&lt;/code&gt; call works across all three protocols — just change the &lt;code&gt;protocol&lt;/code&gt; parameter:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Compare leverage across protocols
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;protocol&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;suilend&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;navi&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;scallop&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;preview&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;previewLeverage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;depositAsset&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;SUI&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;depositValueUsd&lt;/span&gt;: &lt;span class="kt"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;multiplier&lt;/span&gt;: &lt;span class="kt"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;protocol&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;: Net APY &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;preview&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;netApy&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;%`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;This adapter pattern follows the same principle as Aave V3&amp;rsquo;s modular architecture — separation of concerns with a thin routing layer. The &lt;a class="link" href="https://jeongseup.github.io/p/lending-protocol-study-day2/" &gt;Day 2 study&lt;/a&gt; covers how Aave V3 uses &lt;code&gt;delegatecall + Library pattern&lt;/code&gt; to achieve a similar pluggable design.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="data-sources"&gt;Data Sources
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Asset price&lt;/td&gt;
&lt;td&gt;7k Protocol &lt;code&gt;getTokenPrice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Real-time DEX aggregated price&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LTV / LT&lt;/td&gt;
&lt;td&gt;Protocol on-chain state&lt;/td&gt;
&lt;td&gt;Suilend &lt;code&gt;RateLimiterConfig&lt;/code&gt;, Navi &lt;code&gt;ReserveData&lt;/code&gt;, Scallop &lt;code&gt;risk_models&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supply/Borrow APY&lt;/td&gt;
&lt;td&gt;Protocol SDK + on-chain query&lt;/td&gt;
&lt;td&gt;Includes reward token APY&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flash loan fee&lt;/td&gt;
&lt;td&gt;Scallop &lt;code&gt;FLASHLOAN_FEES_TABLE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Currently 0% for USDC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Swap slippage&lt;/td&gt;
&lt;td&gt;7k Protocol &lt;code&gt;quote()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Real-time DEX routing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="challenges--bugs-fixed"&gt;Challenges &amp;amp; Bugs Fixed
&lt;/h2&gt;&lt;h3 id="reward-apy-showing-3700-instead-of-146"&gt;Reward APY showing 3700% instead of 1.46%
&lt;/h3&gt;&lt;p&gt;Suilend stores reward coin types without the &lt;code&gt;0x&lt;/code&gt; prefix internally (e.g., &lt;code&gt;deeb7a4...::deep::DEEP&lt;/code&gt;). When we passed this to the 7k price API, it returned 0. The fallback code then used the deposit asset&amp;rsquo;s price ($67,987 for LBTC) as a proxy for the reward token (DEEP at $0.027), inflating the reward APY to 3700%.&lt;/p&gt;
&lt;p&gt;Fix: normalize the coin type with &lt;code&gt;0x&lt;/code&gt; prefix before price lookup, and skip the reward if price is still unavailable.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Before (broken)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rewardPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getTokenPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rewardCoinType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// returns 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Fallback: uses LBTC price → 3700% APY
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// After (fixed)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;normalizedReward&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;normalizeCoinType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rewardCoinType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchedPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;getTokenPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;normalizedReward&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetchedPrice&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// skip this reward
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="scallop-risk-params-not-accessible-via-sdk"&gt;Scallop risk params not accessible via SDK
&lt;/h3&gt;&lt;p&gt;Scallop&amp;rsquo;s TypeScript SDK doesn&amp;rsquo;t expose &lt;code&gt;risk_models&lt;/code&gt; data. We had to query the on-chain &lt;code&gt;risk_models&lt;/code&gt; dynamic fields directly using &lt;code&gt;suiClient.getDynamicFieldObject()&lt;/code&gt; to extract LTV and liquidation threshold values.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="verified-results-2026-02-26-mainnet"&gt;Verified Results (2026-02-26, Mainnet)
&lt;/h2&gt;&lt;h3 id="sui-2x-leverage"&gt;SUI 2x Leverage
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Suilend&lt;/th&gt;
&lt;th&gt;Navi&lt;/th&gt;
&lt;th&gt;Scallop&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Asset LTV&lt;/td&gt;
&lt;td&gt;70%&lt;/td&gt;
&lt;td&gt;75%&lt;/td&gt;
&lt;td&gt;85%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Liq. Threshold&lt;/td&gt;
&lt;td&gt;75%&lt;/td&gt;
&lt;td&gt;70%&lt;/td&gt;
&lt;td&gt;90%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Max Multiplier&lt;/td&gt;
&lt;td&gt;3.33x&lt;/td&gt;
&lt;td&gt;4.00x&lt;/td&gt;
&lt;td&gt;6.67x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Liq. Price&lt;/td&gt;
&lt;td&gt;$0.63&lt;/td&gt;
&lt;td&gt;$0.68&lt;/td&gt;
&lt;td&gt;$0.53&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Price Drop Buffer&lt;/td&gt;
&lt;td&gt;33%&lt;/td&gt;
&lt;td&gt;29%&lt;/td&gt;
&lt;td&gt;44%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supply APY&lt;/td&gt;
&lt;td&gt;2.89%&lt;/td&gt;
&lt;td&gt;2.97%&lt;/td&gt;
&lt;td&gt;2.98%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Borrow Net APY&lt;/td&gt;
&lt;td&gt;3.45%&lt;/td&gt;
&lt;td&gt;4.57%&lt;/td&gt;
&lt;td&gt;5.80%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Net APY&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.33%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.37%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.15%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="xbtc-2x-leverage"&gt;XBTC 2x Leverage
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Suilend&lt;/th&gt;
&lt;th&gt;Navi&lt;/th&gt;
&lt;th&gt;Scallop&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Asset LTV&lt;/td&gt;
&lt;td&gt;60%&lt;/td&gt;
&lt;td&gt;67%&lt;/td&gt;
&lt;td&gt;75%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supply APY&lt;/td&gt;
&lt;td&gt;3.78%&lt;/td&gt;
&lt;td&gt;6.73%&lt;/td&gt;
&lt;td&gt;0.00%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Net APY&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4.10%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8.88%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-5.80%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The negative Net APY on Scallop XBTC means borrowing costs exceed supply earnings — leverage actually loses money in that case.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="whats-next"&gt;What&amp;rsquo;s Next
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;leverage()&lt;/code&gt; — Actually execute the leveraged position on-chain&lt;/li&gt;
&lt;li&gt;&lt;code&gt;deleverage()&lt;/code&gt; — Close/reduce a leveraged position (flash loan → repay debt → withdraw → swap → repay)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;previewDeleverage()&lt;/code&gt; — Preview the unwinding process&lt;/li&gt;
&lt;li&gt;Cross-protocol position comparison dashboard&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="links"&gt;Links
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://github.com/curg-13/defidash-sdk" target="_blank" rel="noopener"
&gt;DefiDash SDK Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://jeongseup.github.io/p/lending-protocol-study-day1/" &gt;Lending Protocol Study Day 1&lt;/a&gt; — Core lending concepts (LTV, Health Factor, Share-Based Accounting)&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://jeongseup.github.io/p/lending-protocol-study-day2/" &gt;Lending Protocol Study Day 2&lt;/a&gt; — Compound V2 internals, Aave V3 architecture&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://docs.sui.io/concepts/transactions/prog-txn-blocks" target="_blank" rel="noopener"
&gt;Sui PTB Documentation&lt;/a&gt; — Programmable Transaction Blocks&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://suilend.fi" target="_blank" rel="noopener"
&gt;Suilend&lt;/a&gt; | &lt;a class="link" href="https://naviprotocol.io" target="_blank" rel="noopener"
&gt;Navi Protocol&lt;/a&gt; | &lt;a class="link" href="https://scallop.io" target="_blank" rel="noopener"
&gt;Scallop&lt;/a&gt; — The three protocols supported&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;DefiDash의 전체 코드는 &lt;a class="link" href="https://github.com/curg-13" target="_blank" rel="noopener"
&gt;curg-13&lt;/a&gt; 조직에서 확인할 수 있다.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>DefiDash Technical Journal Day 1: 프로젝트 킥오프와 Sui 렌딩 생태계 분석</title><link>https://jeongseup.github.io/project/defidash/defidash-technical-journal-day1/</link><pubDate>Fri, 27 Feb 2026 00:00:00 +0000</pubDate><guid>https://jeongseup.github.io/project/defidash/defidash-technical-journal-day1/</guid><description>&lt;blockquote&gt;
&lt;p&gt;DefiDash 개발 과정을 기록하는 테크니컬 저널 시리즈. Day 1에서는 프로젝트의 동기와 목표, Sui 생태계의 렌딩 프로토콜 현황, 그리고 레버리지 렌딩 어그리게이터의 아키텍처 설계를 다룬다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Team:&lt;/strong&gt; &lt;a class="link" href="https://github.com/curg-13" target="_blank" rel="noopener"
&gt;curg-13&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="왜-defidash인가"&gt;왜 DefiDash인가
&lt;/h2&gt;&lt;p&gt;DeFi 렌딩 시장은 이미 성숙해있다. Ethereum에는 Aave, Compound, MakerDAO가 있고, 다른 체인에도 포크된 프로토콜들이 넘쳐난다. 그런데 &lt;strong&gt;Sui 생태계&lt;/strong&gt;는 다르다.&lt;/p&gt;
&lt;p&gt;Sui는 Move 기반의 Object-centric 모델을 사용한다. EVM의 Account-based 모델과 근본적으로 다른 패러다임이다. 이 차이는 DeFi 프로토콜 설계에도 영향을 미친다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Object Ownership&lt;/strong&gt;: 자산이 계정이 아닌 오브젝트로 관리된다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parallel Execution&lt;/strong&gt;: 독립적인 오브젝트 간 트랜잭션은 병렬 실행 가능&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PTB (Programmable Transaction Blocks)&lt;/strong&gt;: 하나의 트랜잭션에서 여러 DeFi 연산을 원자적으로 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;특히 PTB는 레버리지 렌딩에 결정적이다. EVM에서는 Flash Loan으로 여러 트랜잭션을 하나로 묶지만, Sui에서는 PTB로 &lt;strong&gt;네이티브하게&lt;/strong&gt; 복합 연산이 가능하다.&lt;/p&gt;
&lt;p&gt;문제는 Sui의 렌딩 프로토콜들이 아직 파편화되어 있다는 것이다. 각 프로토콜마다 다른 인터페이스, 다른 이자율 모델, 다른 담보 비율. 일반 사용자가 최적의 레버리지 전략을 찾는 것은 사실상 불가능하다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DefiDash는 이 문제를 해결한다.&lt;/strong&gt; Sui 생태계의 렌딩 프로토콜들을 하나의 인터페이스로 어그리게이트하여, 사용자에게 최적의 레버리지 전략을 제공한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="프로젝트-구조"&gt;프로젝트 구조
&lt;/h2&gt;&lt;p&gt;curg-13 팀으로 3개의 레포지토리를 구성했다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curg-13/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── defidash-sdk # 핵심 SDK - 프로토콜 통합 레이어
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── defidash-frontend # 사용자 facing DApp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── defidash-website # 랜딩 페이지 &amp;amp; 문서
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="defidash-sdk"&gt;defidash-sdk
&lt;/h3&gt;&lt;p&gt;프로토콜 어그리게이션의 핵심이다. 각 렌딩 프로토콜의 인터페이스를 추상화하고, 통합된 API를 제공한다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;주요 책임:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;각 프로토콜의 온체인 데이터 조회 (이자율, 담보 비율, 유동성)&lt;/li&gt;
&lt;li&gt;레버리지 포지션 시뮬레이션&lt;/li&gt;
&lt;li&gt;PTB 구성 및 트랜잭션 빌딩&lt;/li&gt;
&lt;li&gt;최적 경로 계산 (어떤 프로토콜 조합이 가장 유리한지)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="defidash-frontend"&gt;defidash-frontend
&lt;/h3&gt;&lt;p&gt;일반 사용자를 위한 DApp이다. 복잡한 레버리지 전략을 직관적인 UI로 제공한다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;핵심 UX 목표:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;원클릭 레버리지 포지션 오픈/클로즈&lt;/li&gt;
&lt;li&gt;실시간 Health Factor 모니터링&lt;/li&gt;
&lt;li&gt;프로토콜 간 이자율 비교 대시보드&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="defidash-website"&gt;defidash-website
&lt;/h3&gt;&lt;p&gt;프로젝트 소개와 문서를 담는 마케팅 사이트다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="sui-렌딩-생태계-현황"&gt;Sui 렌딩 생태계 현황
&lt;/h2&gt;&lt;p&gt;현재 Sui에서 활동 중인 주요 렌딩 프로토콜들을 정리했다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Key Feature&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scallop&lt;/td&gt;
&lt;td&gt;Pool-based&lt;/td&gt;
&lt;td&gt;Sui 최초의 렌딩 프로토콜, sCoin 모델&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NAVI Protocol&lt;/td&gt;
&lt;td&gt;Pool-based&lt;/td&gt;
&lt;td&gt;Dynamic interest rate, Flash Loan 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Suilend&lt;/td&gt;
&lt;td&gt;Pool-based&lt;/td&gt;
&lt;td&gt;Solend 팀의 Sui 버전, Obligation 기반&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bucket Protocol&lt;/td&gt;
&lt;td&gt;CDP-based&lt;/td&gt;
&lt;td&gt;BUCK 스테이블코인 발행&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;EVM 생태계와 비교하면 아직 초기 단계지만, 각 프로토콜이 Sui의 특성을 살린 독자적인 설계를 가지고 있다. 이 차이점이 곧 어그리게이션의 가치다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="아키텍처-설계-어그리게이션-레이어"&gt;아키텍처 설계: 어그리게이션 레이어
&lt;/h2&gt;&lt;p&gt;레버리지 렌딩 어그리게이터의 핵심은 &lt;strong&gt;Protocol Adapter Pattern&lt;/strong&gt;이다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;사용자 → DefiDash Frontend
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; DefiDash SDK
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ┌─────────┼─────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ ↓ ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Scallop NAVI Suilend ← Protocol Adapters
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Adapter Adapter Adapter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓ ↓ ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─────────┼─────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ↓
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Sui Network
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;각 프로토콜 Adapter는 동일한 인터페이스를 구현한다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;LendingProtocolAdapter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 프로토콜 상태 조회
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;getMarkets&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;Market&lt;/span&gt;&lt;span class="err"&gt;[]&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;getInterestRates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;market&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;InterestRate&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;getUserPosition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;: &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;Position&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 트랜잭션 빌딩
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="nx"&gt;buildSupplyTx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;: &lt;span class="kt"&gt;SupplyParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TransactionBlock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;buildBorrowTx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;: &lt;span class="kt"&gt;BorrowParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TransactionBlock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;buildLeverageTx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;: &lt;span class="kt"&gt;LeverageParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TransactionBlock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;이 패턴의 장점은 새로운 프로토콜 추가가 Adapter 하나만 구현하면 된다는 것이다. SDK의 코어 로직이나 프론트엔드를 수정할 필요 없다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="레버리지-렌딩의-원리"&gt;레버리지 렌딩의 원리
&lt;/h2&gt;&lt;p&gt;일반 사용자를 위해 레버리지 렌딩이 어떻게 작동하는지 정리한다.&lt;/p&gt;
&lt;h3 id="기본-개념"&gt;기본 개념
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;담보 예치&lt;/strong&gt;: 1,000 USDC를 렌딩 프로토콜에 담보로 예치&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;대출&lt;/strong&gt;: 담보 대비 700 SUI를 대출 (LTV 70%)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;재예치&lt;/strong&gt;: 대출받은 SUI를 다시 담보로 예치&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;반복&lt;/strong&gt;: 이 과정을 반복하면 실효 레버리지가 증가&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;초기 자본: 1,000 USDC
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1차 대출: 700 SUI → 재예치
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2차 대출: 490 SUI → 재예치
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3차 대출: 343 SUI → 재예치
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;실효 노출: ~3,333 USDC 상당 (약 3.3x 레버리지)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="sui-ptb의-이점"&gt;Sui PTB의 이점
&lt;/h3&gt;&lt;p&gt;EVM에서는 이 과정을 Flash Loan + 여러 컨트랙트 호출로 구현해야 한다. 가스비도 높고 실패 리스크도 있다.&lt;/p&gt;
&lt;p&gt;Sui의 PTB에서는 &lt;strong&gt;하나의 트랜잭션 블록 안에서&lt;/strong&gt; 모든 단계를 원자적으로 실행할 수 있다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;txb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;TransactionBlock&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 1. 담보 예치
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;receipt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;txb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moveCall&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PROTOCOL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;::deposit`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...]&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 2. 대출
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;borrowed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;txb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moveCall&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PROTOCOL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;::borrow`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...]&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 3. 재예치 (대출 결과를 바로 사용)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="nx"&gt;txb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moveCall&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PROTOCOL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;::deposit`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;borrowed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...]&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 하나의 트랜잭션으로 실행
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signAndExecuteTransactionBlock&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;transactionBlock&lt;/span&gt;: &lt;span class="kt"&gt;txb&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Flash Loan 없이도 원자적 레버리지가 가능하다. 이것이 Sui에서 렌딩 어그리게이터를 만드는 핵심 이유다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="day-1-정리"&gt;Day 1 정리
&lt;/h2&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;결정 사항&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;프로젝트명&lt;/td&gt;
&lt;td&gt;DefiDash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;팀&lt;/td&gt;
&lt;td&gt;curg-13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;타겟 체인&lt;/td&gt;
&lt;td&gt;Sui&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;핵심 기술&lt;/td&gt;
&lt;td&gt;PTB 기반 레버리지 렌딩 어그리게이션&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SDK 언어&lt;/td&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;아키텍처&lt;/td&gt;
&lt;td&gt;Protocol Adapter Pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;첫 통합 대상&lt;/td&gt;
&lt;td&gt;Scallop, NAVI, Suilend&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="next-day-2"&gt;Next: Day 2
&lt;/h2&gt;&lt;p&gt;다음 저널에서는 실제 SDK 개발을 시작한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sui 렌딩 프로토콜 온체인 데이터 구조 분석&lt;/li&gt;
&lt;li&gt;Protocol Adapter 구현 (Scallop부터)&lt;/li&gt;
&lt;li&gt;PTB 기반 레버리지 트랜잭션 빌딩&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;DefiDash의 전체 코드는 &lt;a class="link" href="https://github.com/curg-13" target="_blank" rel="noopener"
&gt;curg-13&lt;/a&gt; 조직에서 확인할 수 있다.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Lending Protocol Study Day 2: Compound V2 Deep Dive와 Aave V3 아키텍처</title><link>https://jeongseup.github.io/p/lending-protocol-study-day2/</link><pubDate>Wed, 25 Feb 2026 00:00:00 +0000</pubDate><guid>https://jeongseup.github.io/p/lending-protocol-study-day2/</guid><description>&lt;blockquote&gt;
&lt;p&gt;7일간의 DeFi Lending Protocol 스터디 시리즈. Day 2에서는 Compound V2의 내부 구조를 코드 레벨로 파고들고, 렌딩 프로토콜의 3가지 유형을 분류한 뒤, Aave V3의 아키텍처 진화를 분석한다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a class="link" href="https://github.com/jeongseup/lending-protocol-study" target="_blank" rel="noopener"
&gt;jeongseup/lending-protocol-study&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="day-2-목표"&gt;Day 2 목표
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Compound V2의 CToken 상속 구조와 &lt;strong&gt;&amp;ldquo;Fresh&amp;rdquo; 패턴&lt;/strong&gt;을 코드 레벨로 이해한다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mantissa&lt;/strong&gt; 기반 고정소수점 연산과 &lt;strong&gt;Lazy Interest Accrual&lt;/strong&gt; 메커니즘을 파악한다&lt;/li&gt;
&lt;li&gt;렌딩 프로토콜을 &lt;strong&gt;3가지 유형&lt;/strong&gt;(Pool-based, CDP-based, Fixed-rate)으로 분류한다&lt;/li&gt;
&lt;li&gt;Aave V3의 &lt;strong&gt;비트맵 스토리지 최적화&lt;/strong&gt;와 아키텍처 진화를 분석한다&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="compound-v2-deep-dive-ctoken-상속-구조"&gt;Compound V2 Deep Dive: CToken 상속 구조
&lt;/h2&gt;&lt;p&gt;Day 1에서 Compound V2의 핵심 파일 3개를 언급했다. Day 2에서는 CToken의 &lt;strong&gt;상속 구조&lt;/strong&gt;부터 파고든다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CTokenInterface (인터페이스)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ CToken (핵심 로직)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ CErc20 (ERC20 자산용 - USDC, DAI 등)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ CEther (ETH 전용)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;CErc20&lt;/code&gt;과 &lt;code&gt;CEther&lt;/code&gt;의 차이는 단순하다. ETH는 ERC20이 아니라 &lt;code&gt;msg.value&lt;/code&gt;로 받아야 하므로, 자금 수수 로직만 다르고 &lt;strong&gt;핵심 렌딩 로직은 CToken에 모두 있다.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;중요한 건 CToken이 &lt;strong&gt;풀 역할까지 겸한다&lt;/strong&gt;는 점이다. &lt;code&gt;mint()&lt;/code&gt;, &lt;code&gt;borrow()&lt;/code&gt;, &lt;code&gt;repay()&lt;/code&gt;, &lt;code&gt;liquidate()&lt;/code&gt; 모두 CToken 컨트랙트에 있다. 하나의 컨트랙트가 ERC20 토큰이면서 동시에 렌딩 풀인 &lt;strong&gt;Monolithic 구조&lt;/strong&gt;다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="fresh-패턴-이자부터-정산하고-본론으로"&gt;Fresh 패턴: &amp;ldquo;이자부터 정산하고 본론으로&amp;rdquo;
&lt;/h2&gt;&lt;p&gt;Compound V2의 모든 핵심 함수 이름에 &lt;code&gt;Fresh&lt;/code&gt;가 붙어 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mintFresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;minter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;mintAmount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;borrowFresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="k"&gt;payable&lt;/span&gt; &lt;span class="n"&gt;borrower&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;borrowAmount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;repayBorrowFresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;payer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;borrower&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;repayAmount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;liquidateBorrowFresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;liquidator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;borrower&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;왜 &lt;code&gt;Fresh&lt;/code&gt;일까? **&amp;ldquo;이자를 최신 상태로 정산한 뒤에 핵심 로직을 실행한다&amp;rdquo;**는 패턴이다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;mintAmount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;accrueInterest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// 1. 이자 먼저 정산
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mintFresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mintAmount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2. 그 다음 본론
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;모든 external 함수가 이 패턴을 따른다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;사용자 호출 → accrueInterest() → xxxFresh() → 실제 로직
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;이렇게 하는 이유는 간단하다. 이자 계산은 &lt;strong&gt;마지막 업데이트 이후의 블록 수&lt;/strong&gt;에 기반한다. 이자를 정산하지 않고 &lt;code&gt;mint()&lt;/code&gt;을 실행하면, 기존 예치자들의 교환비율이 부정확한 상태에서 새로운 지분이 발행되어 &lt;strong&gt;기존 예치자가 손해를 본다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="mantissa-solidity의-소수점-해법"&gt;Mantissa: Solidity의 소수점 해법
&lt;/h2&gt;&lt;p&gt;Solidity에는 부동소수점이 없다. Compound V2는 이를 &lt;strong&gt;Mantissa&lt;/strong&gt; 방식으로 해결한다.&lt;/p&gt;
$$\text{Mantissa} = \text{실제값} \times 10^{18}$$&lt;p&gt;예를 들어:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;이자율 5% → &lt;code&gt;0.05 × 10^18 = 50000000000000000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;교환비율 0.02 → &lt;code&gt;0.02 × 10^18 = 20000000000000000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;곱셈과 나눗셈 시 스케일링을 맞춰야 한다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 두 Mantissa 값의 곱셈: 결과를 10^18으로 나눠서 스케일 복원
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mulScalar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exp&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;scalar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;pure&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exp&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Exp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;mantissa&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mantissa&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;scalar&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mulExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exp&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Exp&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;pure&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exp&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Exp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;mantissa&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mantissa&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mantissa&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;e18&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;이 패턴은 Compound만의 것이 아니다. Aave의 &lt;code&gt;RAY(10^27)&lt;/code&gt;, Uniswap V3의 &lt;code&gt;Q96(2^96)&lt;/code&gt;, MakerDAO의 &lt;code&gt;WAD(10^18)&lt;/code&gt; 모두 같은 원리다. &lt;strong&gt;정수로 소수점을 표현하기 위한 고정소수점 연산.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="lazy-interest-accrual-이자는-필요할-때만-계산한다"&gt;Lazy Interest Accrual: 이자는 &amp;ldquo;필요할 때만&amp;rdquo; 계산한다
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;accrueInterest()&lt;/code&gt;는 매 블록마다 자동으로 실행되는 게 아니다. &lt;strong&gt;누군가 트랜잭션을 보낼 때만&lt;/strong&gt; 실행된다. 이것이 &lt;strong&gt;Lazy Evaluation&lt;/strong&gt;이다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;블록 100: Alice가 mint() → accrueInterest() 실행 (블록 0~100 이자 계산)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;블록 200: 아무 일 없음 → 이자 계산 안 함
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;블록 300: Bob이 borrow() → accrueInterest() 실행 (블록 100~300 이자 계산)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;200 블록 동안 아무도 상호작용하지 않으면, 200 블록치의 이자가 한번에 계산된다. 가스비는 &lt;strong&gt;트랜잭션 수가 아니라 상호작용 빈도에 비례&lt;/strong&gt;한다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;accrueInterest()&lt;/code&gt;가 업데이트하는 상태 변수는 딱 &lt;strong&gt;4개&lt;/strong&gt;다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;totalBorrows&lt;/span&gt; &lt;span class="c1"&gt;// 총 대출량 (이자 포함)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="n"&gt;totalReserves&lt;/span&gt; &lt;span class="c1"&gt;// 프로토콜 수익 누적
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="n"&gt;borrowIndex&lt;/span&gt; &lt;span class="c1"&gt;// 대출자 이자 추적용 전역 인덱스
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="n"&gt;accrualBlockNumber&lt;/span&gt; &lt;span class="c1"&gt;// 마지막 이자 정산 블록 번호
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;4개의 &lt;code&gt;SSTORE&lt;/code&gt; = 20,000 gas. 사용자 수가 아무리 많아도 이 비용은 고정이다. 이것이 Day 1에서 설명한 &lt;strong&gt;Scaled Balance 패턴&lt;/strong&gt;의 실제 구현이다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="이자-시나리오-시뮬레이션"&gt;이자 시나리오 시뮬레이션
&lt;/h2&gt;&lt;p&gt;구체적인 숫자로 따라가보자.&lt;/p&gt;
&lt;h3 id="초기-상태"&gt;초기 상태
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;블록 0: Pool에 10,000 USDC
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- totalCash = 10,000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- totalBorrows = 0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- totalReserves = 0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- borrowIndex = 1.0 (1e18)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- exchangeRate = 10,000 / 500,000 = 0.02 (cToken 500,000개 발행 가정)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="alice가-1000-usdc-대출"&gt;Alice가 1,000 USDC 대출
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;블록 100: Alice borrow(1,000)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- accrueInterest() 실행 (totalBorrows = 0이므로 이자 없음)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- totalCash = 9,000 (1,000 빠짐)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- totalBorrows = 1,000
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Alice의 borrowSnapshot = {principal: 1,000, interestIndex: 1.0}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="100블록-후-이자-정산"&gt;100블록 후 이자 정산
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;블록 200: Bob이 mint() 호출
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 이자율: borrowRate = 0.0001/블록 (연 약 5.3%)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 경과 블록: 100
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- simpleInterestFactor = 0.0001 × 100 = 0.01
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 새 totalBorrows = 1,000 × 1.01 = 1,010
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- Reserve Factor 10%: 새 totalReserves = 10 × 0.1 = 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- 새 borrowIndex = 1.0 × 1.01 = 1.01
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Alice의 실제 대출 잔액은?&lt;/p&gt;
$$\text{Alice 대출잔액} = \frac{\text{principal} \times \text{현재 borrowIndex}}{\text{Alice의 interestIndex}} = \frac{1{,}000 \times 1.01}{1.0} = 1{,}010 \text{ USDC}$$&lt;p&gt;Alice의 Storage를 건드리지 않고도 &lt;strong&gt;전역 borrowIndex 하나만으로&lt;/strong&gt; 정확한 잔액을 계산했다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="렌딩-프로토콜의-3가지-유형"&gt;렌딩 프로토콜의 3가지 유형
&lt;/h2&gt;&lt;p&gt;Day 1에서는 Pool-based 모델만 다뤘다. 실제로 렌딩 프로토콜은 &lt;strong&gt;자금 조달 방식&lt;/strong&gt;에 따라 3가지로 분류된다.&lt;/p&gt;
&lt;h3 id="1-pool-based-compound-aave"&gt;1. Pool-based (Compound, Aave)
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;예치자 → [Pool] → 차입자
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;기존 예치금&lt;/strong&gt;에서 대출&lt;/li&gt;
&lt;li&gt;예치자가 없으면 빌릴 수 없다&lt;/li&gt;
&lt;li&gt;이자율은 Utilization Rate에 연동&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-cdp-based-makerdao"&gt;2. CDP-based (MakerDAO)
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;사용자 → [Vault] → 새 DAI 발행
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;프로토콜이 &lt;strong&gt;새 토큰을 발행&lt;/strong&gt; (mint)&lt;/li&gt;
&lt;li&gt;예치자 없이도 대출 가능&lt;/li&gt;
&lt;li&gt;Stability Fee(이자)는 거버넌스가 결정&lt;/li&gt;
&lt;li&gt;CDP = Collateralized Debt Position&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-fixed-rate-yield-protocol"&gt;3. Fixed-rate (Yield Protocol)
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;사용자 → fyToken (만기 시 1:1 교환 가능)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;할인된 미래 가치 토큰&lt;/strong&gt; 매매&lt;/li&gt;
&lt;li&gt;0.95 fyUSDC를 사면, 만기에 1 USDC → 약 5% 고정 금리&lt;/li&gt;
&lt;li&gt;이자율이 트레이딩으로 결정&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="비교-정리"&gt;비교 정리
&lt;/h3&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;특성&lt;/th&gt;
&lt;th&gt;Pool-based&lt;/th&gt;
&lt;th&gt;CDP-based&lt;/th&gt;
&lt;th&gt;Fixed-rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;자금 출처&lt;/td&gt;
&lt;td&gt;예치자&lt;/td&gt;
&lt;td&gt;프로토콜 발행&lt;/td&gt;
&lt;td&gt;시장 매매&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;이자율 결정&lt;/td&gt;
&lt;td&gt;알고리즘 (사용률)&lt;/td&gt;
&lt;td&gt;거버넌스 투표&lt;/td&gt;
&lt;td&gt;시장 수급&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;변동/고정&lt;/td&gt;
&lt;td&gt;변동&lt;/td&gt;
&lt;td&gt;반고정&lt;/td&gt;
&lt;td&gt;고정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;대표&lt;/td&gt;
&lt;td&gt;Compound, Aave&lt;/td&gt;
&lt;td&gt;MakerDAO&lt;/td&gt;
&lt;td&gt;Yield, Notional&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;필요 조건&lt;/td&gt;
&lt;td&gt;유동성 공급자&lt;/td&gt;
&lt;td&gt;없음 (mint)&lt;/td&gt;
&lt;td&gt;만기 매칭&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;대부분의 메이저 프로토콜이 Pool-based인 이유: &lt;strong&gt;구현이 단순하고, 유동성이 자연스럽게 형성&lt;/strong&gt;되기 때문이다. CDP는 토큰 경제 설계가 복잡하고, Fixed-rate는 만기 매칭이 어렵다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="aave-v3-아키텍처-compound에서-무엇이-진화했나"&gt;Aave V3 아키텍처: Compound에서 무엇이 진화했나
&lt;/h2&gt;&lt;p&gt;Compound V2는 CToken이 모든 걸 한다. Aave V3는 이를 &lt;strong&gt;분리&lt;/strong&gt;했다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Compound V2:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 사용자 → CToken.mint() (CToken = 풀 + 토큰)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Aave V3:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 사용자 → Pool.supply() (Pool = 라우터)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → SupplyLogic.executeSupply() (Library = 실제 로직)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → aToken.mint() (aToken = 순수 영수증)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="delegatecall--library-패턴"&gt;delegatecall + Library 패턴
&lt;/h3&gt;&lt;p&gt;Aave V3의 &lt;code&gt;Pool.sol&lt;/code&gt;은 얇은 프록시에 가깝다. 실제 로직은 &lt;strong&gt;Library&lt;/strong&gt; 컨트랙트에 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Pool.sol
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;supply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SupplyLogic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;executeSupply&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt; &lt;span class="c1"&gt;// delegatecall로 Library 호출
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;borrow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;asset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;BorrowLogic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;executeBorrow&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Library를 쓰면:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;코드 크기 제한(24KB)&lt;/strong&gt; 회피 - Pool의 로직이 아무리 커도 Library에 분산&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;관심사 분리&lt;/strong&gt; - Supply, Borrow, Liquidation 로직이 독립적으로 관리&lt;/li&gt;
&lt;li&gt;단, Library는 &lt;strong&gt;독립 배포 후 업그레이드 불가&lt;/strong&gt; - Proxy 패턴과 조합하여 해결&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="debt-tokenization"&gt;Debt Tokenization
&lt;/h3&gt;&lt;p&gt;Compound V2에서 대출은 단순 매핑이다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Compound V2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;BorrowSnapshot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;accountBorrows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Aave V3는 대출도 &lt;strong&gt;토큰화&lt;/strong&gt;했다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Aave V3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="n"&gt;variableDebtToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;borrower&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 대출하면 부채 토큰 발행
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="n"&gt;variableDebtToken&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;burn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;borrower&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 상환하면 부채 토큰 소각
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;부채를 토큰화하면 무엇이 좋은가?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;balanceOf()&lt;/code&gt;로 대출 잔액 조회 가능 (표준 인터페이스)&lt;/li&gt;
&lt;li&gt;Transfer 제한으로 부채 이전 방지&lt;/li&gt;
&lt;li&gt;이벤트 표준화 (Transfer 이벤트로 대출/상환 추적 가능)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Aave V3.2부터 Stable Rate이 제거되었다. 변동금리만 남았으므로 &lt;code&gt;stableDebtToken&lt;/code&gt;은 더 이상 사용되지 않는다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="비트맵-스토리지-최적화"&gt;비트맵 스토리지 최적화
&lt;/h2&gt;&lt;p&gt;Day 2의 가장 중요한 기술적 발견이다. Compound V2와 Aave V3의 &lt;strong&gt;사용자 상태 관리 방식&lt;/strong&gt;이 근본적으로 다르다.&lt;/p&gt;
&lt;h3 id="compound-v2-배열-순회"&gt;Compound V2: 배열 순회
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Comptroller.sol
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;CToken&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;accountAssets&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 사용자별 참여 마켓 배열
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Health Factor 계산 시
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;assets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 모든 마켓을 순회하며 담보 가치 합산
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;문제: 사용자가 참여한 마켓이 많을수록 &lt;strong&gt;가스비가 선형으로 증가&lt;/strong&gt;한다.&lt;/p&gt;
&lt;h3 id="aave-v3-비트맵"&gt;Aave V3: 비트맵
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 하나의 uint256에 128개 자산의 상태를 담는다
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 각 자산이 2비트를 차지: [담보 사용 여부][대출 여부]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;UserConfigurationMap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="n"&gt;_usersConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;UserConfigurationMap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="nb"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 256비트 = 128개 자산 × 2비트
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;비트맵의 구조:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;비트 위치: ... | 5 | 4 | 3 | 2 | 1 | 0 |
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;자산 ID: | 2 | 1 | 0 |
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;의미: ... | C | B | C | B | C | B |
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; B = Borrowing (대출 중)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; C = Collateral (담보로 사용 중)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Health Factor 계산 시:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 비트맵에서 해당 비트가 0이면 스킵
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userConfig&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;data&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reserveIndex&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 이 자산은 대출도 담보도 아님 → O(1)로 스킵
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="성능-비교"&gt;성능 비교
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Compound V2 (배열):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 10개 마켓 참여 → 10번 SLOAD + 루프 = ~50,000 gas
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Aave V3 (비트맵):
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 128개 마켓 확인 → 1번 SLOAD + 비트 연산 = ~2,100 gas
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;비트 연산(&lt;code&gt;AND&lt;/code&gt;, &lt;code&gt;SHIFT&lt;/code&gt;)은 3 gas다. 128개 자산을 확인해도 &lt;code&gt;2,100 + 128 × 3 = 2,484 gas&lt;/code&gt;. 배열 방식 대비 &lt;strong&gt;약 20배 절약&lt;/strong&gt;이다.&lt;/p&gt;
&lt;p&gt;이 차이가 결정적인 이유: Health Factor 계산은 &lt;strong&gt;모든 트랜잭션에서 발생&lt;/strong&gt;한다. supply, borrow, repay, liquidate 전부. 가장 빈번하게 호출되는 로직의 가스를 20배 줄이면 프로토콜 전체의 가스 효율이 극적으로 개선된다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="lendingpool-리팩토링-배운-것을-적용하기"&gt;LendingPool 리팩토링: 배운 것을 적용하기
&lt;/h2&gt;&lt;p&gt;스터디 프로젝트의 &lt;code&gt;LendingPool.sol&lt;/code&gt;에 Aave V3의 PoolStorage 패턴을 적용했다.&lt;/p&gt;
&lt;h3 id="before-단순-매핑"&gt;Before: 단순 매핑
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;deposits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;borrows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="after-구조화된-스토리지"&gt;After: 구조화된 스토리지
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;ReserveData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint128&lt;/span&gt; &lt;span class="n"&gt;liquidityIndex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint128&lt;/span&gt; &lt;span class="n"&gt;variableBorrowIndex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint128&lt;/span&gt; &lt;span class="n"&gt;currentLiquidityRate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint128&lt;/span&gt; &lt;span class="n"&gt;currentVariableBorrowRate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint40&lt;/span&gt; &lt;span class="n"&gt;lastUpdateTimestamp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint16&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;aTokenAddress&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;variableDebtTokenAddress&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint128&lt;/span&gt; &lt;span class="n"&gt;totalDeposits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint128&lt;/span&gt; &lt;span class="n"&gt;totalBorrows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ReserveData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="n"&gt;_reserves&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="n"&gt;_reservesList&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;uint16&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="n"&gt;_reservesCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;UserConfigurationMap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="n"&gt;_usersConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;핵심 변경점:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_reserves&lt;/code&gt;: 자산 주소 → ReserveData 매핑 (모든 자산 상태를 하나의 구조체로)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_reservesList&lt;/code&gt;: reserveId → 자산 주소 매핑 (비트맵 인덱싱용)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_usersConfig&lt;/code&gt;: 사용자별 비트맵 (담보/대출 상태)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;비트맵 헬퍼도 구현했다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isUsingAsCollateral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserConfigurationMap&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;reserveIndex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;pure&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;data&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reserveIndex&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isBorrowing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserConfigurationMap&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;reserveIndex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;pure&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;data&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reserveIndex&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;리팩토링 후 모든 62개 테스트(기존 61 + 비트맵 테스트 1)가 통과했다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="jumpratemodel-테스트-fuzz-testing까지"&gt;JumpRateModel 테스트: Fuzz Testing까지
&lt;/h2&gt;&lt;p&gt;Day 1에서 이론으로 다룬 JumpRateModel을 실제로 구현하고 테스트했다.&lt;/p&gt;
&lt;h3 id="unit-test-18개-케이스"&gt;Unit Test: 18개 케이스
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[PASS] testGetBorrowRate_ZeroUtilization()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[PASS] testGetBorrowRate_AtKink()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[PASS] testGetBorrowRate_AboveKink()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[PASS] testGetBorrowRate_FullUtilization()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[PASS] testGetSupplyRate_WithReserveFactor()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;... (18개 전부 통과)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="fuzz-test-6개-케이스"&gt;Fuzz Test: 6개 케이스
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;testFuzz_BorrowRateMonotonicity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;util1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;util2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;util1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;util1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;e18&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;util2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bound&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;util2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;util1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;e18&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;rate1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getBorrowRate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cash1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;borrows1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reserves1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;rate2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getBorrowRate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cash2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;borrows2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reserves2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;assertGe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rate2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rate1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 사용률이 높으면 이자율도 높아야 한다
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Fuzz Testing으로 검증한 불변 조건:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;단조 증가&lt;/strong&gt;: 사용률이 올라가면 이자율도 올라간다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Supply ≤ Borrow&lt;/strong&gt;: Supply Rate은 항상 Borrow Rate 이하&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kink에서의 연속성&lt;/strong&gt;: kink 전후로 이자율이 비연속적으로 뛰지 않는다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;전체 24개 테스트 (18 unit + 6 fuzz) 모두 통과.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="day-2-핵심-인사이트-정리"&gt;Day 2 핵심 인사이트 정리
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fresh 패턴은 렌딩의 정합성을 보장한다&lt;/strong&gt; - 이자를 먼저 정산하지 않으면 교환비율이 부정확해져서 기존 사용자가 손해본다. &amp;ldquo;이자부터, 그 다음 본론&amp;quot;이 원칙.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lazy Interest Accrual은 가스 효율의 핵심&lt;/strong&gt; - 매 블록이 아니라 트랜잭션이 발생할 때만 이자를 계산한다. 4개의 SSTORE로 전체 사용자의 이자를 한번에 정산.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;렌딩은 3가지 유형&lt;/strong&gt; - Pool-based(예치금에서 빌림), CDP-based(새 토큰 발행), Fixed-rate(할인 토큰). 대부분이 Pool-based인 이유는 구현 단순성과 유동성 형성의 용이함.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;비트맵이 아키텍처를 결정한다&lt;/strong&gt; - Compound의 배열 vs Aave의 비트맵. 한 번의 SLOAD로 128개 자산 상태를 확인하는 것은 단순한 최적화가 아니라, Health Factor 계산이 모든 트랜잭션에서 발생하기 때문에 &lt;strong&gt;프로토콜 전체 가스 효율&lt;/strong&gt;을 좌우한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Storage 레이아웃이 아키텍처를 결정한다&lt;/strong&gt; - Compound는 배열 중심이라 Monolithic이 자연스럽고, Aave는 비트맵 + 구조체 중심이라 Modular가 자연스럽다. 데이터 구조가 코드 구조를 결정한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="next-day-3"&gt;Next: Day 3
&lt;/h2&gt;&lt;p&gt;내일은 &lt;strong&gt;청산(Liquidation) 메커니즘&lt;/strong&gt;을 파고든다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;청산 트리거 조건과 &lt;code&gt;liquidateBorrowFresh()&lt;/code&gt; 코드 리딩&lt;/li&gt;
&lt;li&gt;청산 보너스(Liquidation Incentive) 경제학&lt;/li&gt;
&lt;li&gt;Foundry Fork Testing으로 Aave V3 메인넷 청산 시뮬레이션&lt;/li&gt;
&lt;li&gt;고급 Foundry 테스팅 패턴 (invariant, fork)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;이 시리즈의 전체 코드와 학습 자료는 &lt;a class="link" href="https://github.com/jeongseup/lending-protocol-study" target="_blank" rel="noopener"
&gt;lending-protocol-study&lt;/a&gt; 레포에서 확인할 수 있다.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Lending Protocol Study Day 1: DeFi 렌딩의 핵심 개념과 아키텍처</title><link>https://jeongseup.github.io/p/lending-protocol-study-day1/</link><pubDate>Mon, 23 Feb 2026 00:00:00 +0000</pubDate><guid>https://jeongseup.github.io/p/lending-protocol-study-day1/</guid><description>&lt;blockquote&gt;
&lt;p&gt;7일간의 DeFi Lending Protocol 스터디 시리즈. 백엔드/인프라 엔지니어 관점에서 렌딩 프로토콜을 코드 레벨까지 파헤친다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a class="link" href="https://github.com/jeongseup/lending-protocol-study" target="_blank" rel="noopener"
&gt;jeongseup/lending-protocol-study&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="why-lending-protocol"&gt;Why Lending Protocol?
&lt;/h2&gt;&lt;p&gt;블록체인 인프라 엔지니어로 일하면서 노드 운영, 밸리데이터 모니터링, 스테이킹 보상 분석 등을 해왔다. 그런데 DeFi의 가장 큰 축인 &lt;strong&gt;렌딩 프로토콜&lt;/strong&gt;은 &amp;ldquo;대충 알겠는데 코드 레벨에서는 모른다&amp;quot;는 상태였다.&lt;/p&gt;
&lt;p&gt;이번 스터디의 목표는 명확하다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compound V2 / Aave V3의 핵심 로직을 &lt;strong&gt;코드로 읽고 구현&lt;/strong&gt;한다&lt;/li&gt;
&lt;li&gt;렌딩의 수학적 모델(이자율, 청산, Health Factor)을 &lt;strong&gt;공식 수준&lt;/strong&gt;으로 이해한다&lt;/li&gt;
&lt;li&gt;Solidity + Go 모니터링 도구까지 만들어 &lt;strong&gt;실무에 적용 가능한 수준&lt;/strong&gt;으로 올린다&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="렌딩-프로토콜의-본질-풀-기반-중개"&gt;렌딩 프로토콜의 본질: 풀 기반 중개
&lt;/h2&gt;&lt;p&gt;전통 금융의 대출은 대출자와 차입자를 1:1로 매칭한다. DeFi 렌딩은 다르다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;전통 금융: Alice → [은행] → Bob (1:1 매칭)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;DeFi 렌딩: Alice → [Pool] ← Bob (풀 기반 간접 매칭)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;예치자들이 자산을 풀에 넣으면, 차입자들이 담보를 걸고 풀에서 빌려간다. &lt;strong&gt;아무도 누가 누구에게 빌려줬는지 모른다.&lt;/strong&gt; 이자율은 풀의 사용률(Utilization Rate)에 따라 알고리즘이 자동으로 결정한다.&lt;/p&gt;
&lt;p&gt;이 구조의 핵심 이유는 간단하다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;블록체인 = 익명 → 신용평가 불가 → 담보로만 판단 → 과담보 필수
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;신용이 없으니 담보로 대체한다. 그래서 DeFi 렌딩은 태생적으로 &lt;strong&gt;과담보(Over-collateralized)&lt;/strong&gt; 구조다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="렌딩의-5대-핵심-파라미터"&gt;렌딩의 5대 핵심 파라미터
&lt;/h2&gt;&lt;p&gt;렌딩 프로토콜을 이해하려면 이 5가지 숫자만 확실히 알면 된다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;파라미터&lt;/th&gt;
&lt;th&gt;의미&lt;/th&gt;
&lt;th&gt;일반적 범위&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LTV&lt;/strong&gt; (Loan-to-Value)&lt;/td&gt;
&lt;td&gt;담보 대비 얼마까지 빌릴 수 있나&lt;/td&gt;
&lt;td&gt;75-80%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Health Factor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;내 포지션이 안전한가 (&amp;lt; 1이면 청산)&lt;/td&gt;
&lt;td&gt;1.0 이상 유지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Utilization Rate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;풀의 자금 중 얼마가 빌려졌나&lt;/td&gt;
&lt;td&gt;이자율 결정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reserve Factor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;프로토콜이 이자에서 떼가는 비율&lt;/td&gt;
&lt;td&gt;10-35%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Collateral Factor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;자산의 담보 가치 인정 비율&lt;/td&gt;
&lt;td&gt;자산마다 다름&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="외워야-할-공식-3개"&gt;외워야 할 공식 3개
&lt;/h3&gt;$$HF = \frac{LT}{LTV}$$$$\text{최대 허용 하락률} = 1 - \frac{LTV}{LT}$$$$\text{Supply APY} = \text{Borrow APR} \times \text{Utilization} \times (1 - \text{Reserve Factor})$$&lt;p&gt;세 번째 공식이 특히 중요하다. Supply APY가 Borrow APR보다 &lt;strong&gt;수학적으로 항상 작은&lt;/strong&gt; 이유가 여기 있다. 풀의 돈이 100% 빌려진 게 아니고(Utilization &amp;lt; 1), 프로토콜이 Reserve Factor만큼 떼가기 때문이다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;단, 토큰 인센티브(COMP, AAVE)나 포인트/에어드랍까지 포함하면 역전될 수 있다. 2020년 DeFi Summer에 &amp;ldquo;빌리면 돈 버는&amp;rdquo; 상황이 실제로 발생했다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="이자율-모델-jump-rate-model"&gt;이자율 모델: Jump Rate Model
&lt;/h2&gt;&lt;p&gt;&amp;ldquo;사용률이 올라가면 이자율도 올라간다&amp;quot;는 단순한 원칙이지만, 구현 방식은 프로토콜마다 다르다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;프로토콜&lt;/th&gt;
&lt;th&gt;모델&lt;/th&gt;
&lt;th&gt;특징&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Compound V2&lt;/td&gt;
&lt;td&gt;Jump Rate Model&lt;/td&gt;
&lt;td&gt;원조. kink 지점에서 이자율 급등&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aave V3&lt;/td&gt;
&lt;td&gt;Variable Rate Strategy&lt;/td&gt;
&lt;td&gt;비슷하지만 파라미터 구조 다름&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MakerDAO&lt;/td&gt;
&lt;td&gt;거버넌스 직접 설정&lt;/td&gt;
&lt;td&gt;알고리즘 아님&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Euler V2&lt;/td&gt;
&lt;td&gt;모듈형&lt;/td&gt;
&lt;td&gt;풀 생성자가 모델 직접 선택&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;DEX에서 &lt;code&gt;x * y = k&lt;/code&gt; (CPMM)가 원조 모델이듯, 렌딩에서는 Jump Rate Model이 원조다. &amp;ldquo;유일한 표준&amp;quot;은 아니지만, 대부분의 모델이 이걸 변형한 것이다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="ctoken-vs-atoken-이자를-반영하는-두-가지-방법"&gt;cToken vs aToken: 이자를 반영하는 두 가지 방법
&lt;/h2&gt;&lt;p&gt;렌딩에 자산을 예치하면 &amp;ldquo;영수증 토큰&amp;quot;을 받는다. 이 영수증이 이자를 반영하는 방식이 Compound와 Aave에서 근본적으로 다르다.&lt;/p&gt;
&lt;h3 id="compound의-ctoken-교환비율-상승"&gt;Compound의 cToken: 교환비율 상승
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;예치: 1,000 USDC → 50,000 cUSDC (교환비율 0.02)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1년후: 50,000 cUSDC 그대로, 교환비율 0.025로 상승
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;인출: 50,000 × 0.025 = 1,250 USDC
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;토큰 수량은 변하지 않고, &lt;strong&gt;교환비율이 올라간다.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="aave의-atoken-잔고-자동-증가-rebase"&gt;Aave의 aToken: 잔고 자동 증가 (Rebase)
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;예치: 1,000 USDC → 1,000 aUSDC (1:1)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1년후: 지갑에 1,050 aUSDC로 자동 증가
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;인출: 1,050 aUSDC → 1,050 USDC
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;교환비율은 1:1 고정이고, &lt;strong&gt;토큰 수량이 늘어난다.&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;비교&lt;/th&gt;
&lt;th&gt;cToken&lt;/th&gt;
&lt;th&gt;aToken&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UX&lt;/td&gt;
&lt;td&gt;비직관적 (교환비율 계산 필요)&lt;/td&gt;
&lt;td&gt;직관적 (잔고 = 실제 가치)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DeFi 호환성&lt;/td&gt;
&lt;td&gt;유리 (표준 ERC20)&lt;/td&gt;
&lt;td&gt;불리 (rebase 토큰)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;수학&lt;/td&gt;
&lt;td&gt;&lt;code&gt;amount = shares × exchangeRate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;balance = scaledBalance × index&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;수학적으로는 동일하다. &lt;strong&gt;&amp;ldquo;언제 곱하느냐&amp;quot;의 차이일 뿐이다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="share-based-accounting-defi의-범용-패턴"&gt;Share-Based Accounting: DeFi의 범용 패턴
&lt;/h2&gt;&lt;p&gt;cToken의 교환비율 패턴은 사실 DeFi 전반에서 반복되는 범용 패턴이다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;지분으로 변환 → 전역 비율만 업데이트 → 인출 시 역변환
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;이 패턴을 쓰는 곳들:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;프로토콜&lt;/th&gt;
&lt;th&gt;용도&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Compound cToken&lt;/td&gt;
&lt;td&gt;렌딩 예치 영수증&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ERC-4626&lt;/td&gt;
&lt;td&gt;토큰화된 Vault 표준&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lido wstETH&lt;/td&gt;
&lt;td&gt;Liquid Staking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rocket Pool rETH&lt;/td&gt;
&lt;td&gt;Liquid Staking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Walrus StakingPool&lt;/td&gt;
&lt;td&gt;스토리지 네트워크 스테이킹&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Walrus의 &lt;code&gt;StakingPool&lt;/code&gt;과 비교하면:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Compound cToken:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; exchange_rate = (totalCash + totalBorrows - totalReserves) / totalSupply
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; deposit: shares = amount / exchange_rate
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; withdraw: amount = shares × exchange_rate
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Walrus StakingPool:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; exchange_rate = total_wal / total_shares
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; stake: shares = principal × total_shares / total_wal
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; withdraw: amount = shares × total_wal / total_shares
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;같은 공식이다. 변수명만 다르다.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="가스-최적화의-핵심-scaled-balance"&gt;가스 최적화의 핵심: Scaled Balance
&lt;/h2&gt;&lt;p&gt;aToken이 &amp;ldquo;잔고가 자동으로 늘어난다&amp;quot;면, 매번 모든 사용자의 잔고를 업데이트하는 걸까? 당연히 아니다. 그러면 가스비가 폭발한다.&lt;/p&gt;
&lt;p&gt;핵심 아이디어: &lt;strong&gt;쓰기를 읽기로 바꾼다.&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Scaled Balance = 예치금 / 예치 시점의 liquidityIndex
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;이 값은 한번 저장되면 &lt;strong&gt;절대 변하지 않는다.&lt;/strong&gt; 변하는 건 전역 &lt;code&gt;liquidityIndex&lt;/code&gt; 하나뿐이다.&lt;/p&gt;
&lt;p&gt;잔고를 조회할 때 &lt;code&gt;scaledBalance × 현재 index&lt;/code&gt;로 계산한다. &lt;code&gt;balanceOf()&lt;/code&gt;는 view 함수이므로 가스비가 0이다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;순진한 방식: 이자 발생 시 모든 사용자 잔고 SSTORE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 1,000명 × 5,000 gas = 5,000,000 gas
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Scaled Balance: 전역 index 1개만 SSTORE
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 5,000 gas
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; → 99.9% 절약
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;EVM에서 &lt;code&gt;SSTORE&lt;/code&gt;(쓰기)는 5,000 gas, &lt;code&gt;MUL&lt;/code&gt;(곱셈)은 5 gas다. &lt;strong&gt;쓰기는 계산보다 1,000배 비싸다.&lt;/strong&gt; Merkle Patricia Trie를 재계산하고 모든 노드에 영구 저장해야 하기 때문이다. Scaled Balance는 이 비용 구조를 정확히 활용한 최적화다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="compound-v2-vs-aave-v3-아키텍처-차이"&gt;Compound V2 vs Aave V3: 아키텍처 차이
&lt;/h2&gt;&lt;p&gt;두 프로토콜의 가장 큰 차이는 코드 구조에 있다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Compound: CToken이 풀 역할까지 겸함 (Monolithic)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 사용자 → CToken.mint()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Aave/우리 프로젝트: Pool과 토큰 분리 (Modular)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 사용자 → Pool.deposit() → aToken.mint()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Compound의 CToken은 ERC20 토큰이면서 동시에 렌딩 풀이다. &lt;code&gt;mint()&lt;/code&gt;, &lt;code&gt;borrow()&lt;/code&gt;, &lt;code&gt;repay()&lt;/code&gt;, &lt;code&gt;liquidate()&lt;/code&gt; 모두 CToken 컨트랙트에 있다. 반면 Aave는 Pool이 중심이고 aToken은 순수한 영수증 토큰이다.&lt;/p&gt;
&lt;h3 id="compound-v2-코드-리딩-가이드"&gt;Compound V2 코드 리딩 가이드
&lt;/h3&gt;&lt;p&gt;Compound V2 코드를 읽고 싶다면, 핵심 &lt;strong&gt;3개 파일, 5개 함수&lt;/strong&gt;만 보면 된다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CToken.sol&lt;/strong&gt; - 핵심 함수 5개:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;accrueInterest()&lt;/code&gt; - 이자 누적 (borrowIndex = scaled balance 패턴)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mintFresh()&lt;/code&gt; - 예치&lt;/li&gt;
&lt;li&gt;&lt;code&gt;borrowFresh()&lt;/code&gt; - 대출&lt;/li&gt;
&lt;li&gt;&lt;code&gt;repayBorrowFresh()&lt;/code&gt; - 상환&lt;/li&gt;
&lt;li&gt;&lt;code&gt;liquidateBorrowFresh()&lt;/code&gt; - 청산&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Comptroller.sol&lt;/strong&gt; - 핵심 함수 1개:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;getHypotheticalAccountLiquidityInternal()&lt;/code&gt; - Health Factor 계산&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;BaseJumpRateModelV2.sol&lt;/strong&gt; - 이자율 모델&lt;/p&gt;
&lt;p&gt;나머지(Governance, Lens, Timelock 등)는 렌딩 로직과 무관하므로 무시해도 된다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="이자율의-3개-레이어"&gt;이자율의 3개 레이어
&lt;/h2&gt;&lt;p&gt;DeFi에서 실제 수익률은 단순한 이자율이 아니라 3개 레이어의 합이다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Layer 1: 기본 이자 → Jump Rate Model이 결정
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Layer 2: 토큰 인센티브 → COMP, AAVE 등 거버넌스 토큰 보상
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Layer 3: 포인트/에어드랍 → Blast, EigenLayer 등
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Layer 2, 3까지 포함하면 &amp;ldquo;빌리면 돈 버는&amp;rdquo; 상황도 발생한다. 2020 DeFi Summer에 COMP 보상이 대출 이자보다 커서 Compound에서 빌리는 것 자체가 수익이었던 것이 대표적인 사례다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="day-1-핵심-인사이트-정리"&gt;Day 1 핵심 인사이트 정리
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;렌딩의 본질은 풀 기반 중개&lt;/strong&gt; - 예치자와 대출자를 직접 매칭하지 않고, 풀을 통해 간접 매칭한다. 스테이킹 풀과 동일한 패턴.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Share-Based Accounting은 DeFi의 범용 패턴&lt;/strong&gt; - cToken, ERC-4626, wstETH, rETH, Walrus 전부 같은 원리. &amp;ldquo;지분으로 변환 → 전역 비율만 업데이트 → 인출 시 역변환.&amp;rdquo;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;가스 최적화의 핵심은 &amp;ldquo;쓰기를 읽기로 바꾸기&amp;rdquo;&lt;/strong&gt; - SSTORE는 계산보다 1,000배 비싸다. Scaled Balance 패턴으로 전역 index 하나만 업데이트하고 나머지는 읽기 시점에 계산.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Compound는 Monolithic, Aave는 Modular&lt;/strong&gt; - CToken이 풀 겸 토큰 vs Pool과 토큰 분리.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;실제 수익률 = 기본 이자 + 토큰 인센티브 + 포인트&lt;/strong&gt; - 3개 레이어를 모두 봐야 DeFi의 실제 경제를 이해할 수 있다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="next-day-2"&gt;Next: Day 2
&lt;/h2&gt;&lt;p&gt;내일은 &lt;strong&gt;Aave V3 아키텍처를 코드 레벨로&lt;/strong&gt; 들어간다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Pool.sol&lt;/code&gt;, &lt;code&gt;SupplyLogic.sol&lt;/code&gt;, &lt;code&gt;BorrowLogic.sol&lt;/code&gt;, &lt;code&gt;LiquidationLogic.sol&lt;/code&gt; 리딩&lt;/li&gt;
&lt;li&gt;Fork Testing으로 Aave V3 메인넷 상태에서 직접 테스트&lt;/li&gt;
&lt;li&gt;Fuzz Testing으로 이자율 엣지 케이스 탐색&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;이 시리즈의 전체 코드와 학습 자료는 &lt;a class="link" href="https://github.com/jeongseup/lending-protocol-study" target="_blank" rel="noopener"
&gt;lending-protocol-study&lt;/a&gt; 레포에서 확인할 수 있다.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>DefiDash 시작 계기: Defi Saver for Sui</title><link>https://jeongseup.github.io/project/defidash/defidash-journal-origin/</link><pubDate>Thu, 11 Dec 2025 00:00:00 +0000</pubDate><guid>https://jeongseup.github.io/project/defidash/defidash-journal-origin/</guid><description>&lt;blockquote&gt;
&lt;p&gt;CURG 13기 활동 중 DefiDash 프로젝트가 시작된 배경과, 레퍼런스인 Defi Saver를 분석한 기록.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Team:&lt;/strong&gt; &lt;a class="link" href="https://github.com/curg-13" target="_blank" rel="noopener"
&gt;curg-13&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="1-프로젝트-히스토리"&gt;1. 프로젝트 히스토리
&lt;/h2&gt;&lt;p&gt;이 프로젝트는 &lt;a class="link" href="https://www.curg.co/" target="_blank" rel="noopener"
&gt;CURG(Crypto United Research Group)&lt;/a&gt;라는 한국 블록체인 스터디에서 출발했다. 퇴사 후 13기로 합류했고, 이번 기수의 활동기간은 2025.10.11부터 2026.3.28이었다. DefiDash는 2025.12부터 본격적으로 개발을 시작한 프로젝트다.&lt;/p&gt;
&lt;h3 id="초기-방향-탐색"&gt;초기 방향 탐색
&lt;/h3&gt;&lt;p&gt;처음에는 Sui Stack(Walrus, Seal, Nautilus, DeepBook 등)을 활용해서 재미있는 것들을 만들어보려 했다. 하지만 팀원들과 나 모두 Sui Stack 자체에 크게 흥미를 잃었다.&lt;/p&gt;
&lt;p&gt;간단히 써본 결과, 해당 스택은 커머셜한 Web2 비즈니스를 Web3화하는 방향에 초점이 맞춰진다고 느꼈기 때문이다.&lt;/p&gt;
&lt;p&gt;EVM 생태계에서는 필요한 인프라를 유저(커뮤니티)가 직접 개발하고 비즈니스화하면서 상호작용하는 반면, Sui에서는 필요한 인프라를 재단 레벨에서 미리 구상하고 생태계 툴로 자리잡아둔 구조다. 블록체인을 구축하고 개발자를 유치하는 전략적 차이라고 생각한다.&lt;/p&gt;
&lt;h3 id="방향성-좁히기"&gt;방향성 좁히기
&lt;/h3&gt;&lt;p&gt;이후 팀원들과의 회의를 통해 초기 방향을 아래 3가지로 좁혔다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Pendle to Sui + Lucky Gaming&lt;/strong&gt; — 기존에 Walrus Haultout 해커톤에서 Sui random module을 활용해 나간 경험을 확장&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Defi Saver to Sui&lt;/strong&gt; — Sui에 렌딩 프로토콜이 여럿 있으니 이를 aggregation 하는 것으로 출발&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Academic Research in Sui&lt;/strong&gt; — 오픈소스 Move DeFi 컨트랙트를 분석하면서 EVM과 MoveVM 차이를 비교&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;약 2주간의 논의를 거쳐, 2025.12.11 시점에 &lt;strong&gt;Defi Saver for Sui&lt;/strong&gt;로 방향을 결정지었다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="2-defi-saver-분석"&gt;2. Defi Saver 분석
&lt;/h2&gt;&lt;h3 id="defi-saver란"&gt;Defi Saver란?
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://defisaver.com/" target="_blank" rel="noopener"
&gt;Defi Saver&lt;/a&gt;를 간단히 말하면, &lt;strong&gt;crypto portfolio dashboard + leverage yield farming(looping)&lt;/strong&gt; 플랫폼이다. 추후 포지션 규모가 크면 자동으로 포지션을 조절해주는 기능도 제공한다.&lt;/p&gt;
&lt;p&gt;가령 담보로 맡긴 BTC가 급락하는 경우, liquidation을 방지하기 위해 leverage multiplier를 자동으로 줄여준다는 뜻이다.&lt;/p&gt;
&lt;p&gt;Defi Saver 말고도 비슷한 crypto asset dashboard 서비스는 다양하다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://help.defisaver.com/general/what-is-defi-saver" target="_blank" rel="noopener"
&gt;Defi Saver 공식 소개&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://defillama.com/protocol/defi-saver" target="_blank" rel="noopener"
&gt;DefiLlama - Defi Saver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.alchemy.com/dapps/best/crypto-portfolio-dashboards" target="_blank" rel="noopener"
&gt;Alchemy - Best Crypto Portfolio Dashboards&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="특장점"&gt;특장점
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Safe(Gnosis) Smart Wallet 사용&lt;/strong&gt;: 처음 접속 시 유저에게 Smart Wallet을 생성하도록 한다.
&lt;ul&gt;
&lt;li&gt;Automation 기능 지원을 위해서이며, &lt;code&gt;execTransaction&lt;/code&gt; 같은 여러 트랜잭션을 하나로 묶어서 실행하기 위함이다.&lt;/li&gt;
&lt;li&gt;이걸 보고 &lt;strong&gt;Sui에서는 PTB가 네이티브하게 지원되니까 오히려 만들기 편하겠다&lt;/strong&gt;는 생각을 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Looping 레버리지&lt;/strong&gt;: 유저가 BTC를 맡기면 LTV에 따라 최대 레버리지까지 USDC를 빌려서 → 그 금액으로 BTC를 다시 사서 → 재예치하는 looping 방식을 지원한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;직관적인 UX&lt;/strong&gt;: Liquidation price, 여러 리스크 팩터 등이 한눈에 보인다. 처음에는 별것 아닌 것 같았지만, 막상 만들어보니 이런 디테일한 정보를 잘 관리하고 UX로 풀어내는 게 쉽지 않다는 걸 뒤늦게 알게 되었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="defi-saver-직접-사용해보기"&gt;Defi Saver 직접 사용해보기
&lt;/h3&gt;&lt;p&gt;아래는 직접 써본 예시다.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jeongseup.github.io/img/defidash/defisaver-leverage-example.png"
loading="lazy"
alt="Defi Saver leverage 포지션 오픈 화면"
&gt;&lt;/p&gt;
&lt;p&gt;가격이 변동함에 따라, 담보 자산(여기선 cbBTC) 상승 시 레버리지 효과를 가질 수 있게 된다.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jeongseup.github.io/img/defidash/defisaver-leverage-result.png"
loading="lazy"
alt="가격 변동에 따른 레버리지 효과"
&gt;&lt;/p&gt;
&lt;p&gt;기본적으로 내 EOA(MetaMask 지갑 주소)에서 호출한 컨트랙트 메소드는 다음과 같다. 해당 rollup tx 안에는 여러 로직이 포함되어 있는 구조다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-solidity" data-lang="solidity"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;execTransaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="nb"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bytes&lt;/span&gt; &lt;span class="nb"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint8&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;safeTxGas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;baseGas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;gasPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;gasToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;refundReceiver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bytes&lt;/span&gt; &lt;span class="n"&gt;signatures&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Net Transfer로 보면 로직이 보다 명확해진다.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jeongseup.github.io/img/defidash/defisaver-net-transfer.png"
loading="lazy"
alt="Net Transfer 상세"
&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;실제 트랜잭션: &lt;a class="link" href="https://basescan.org/tx/0x0869a6913cda22441ec9ed568f72336602969d214db690dac6e22e23102073ef" target="_blank" rel="noopener"
&gt;basescan.org/tx/0x0869a6&amp;hellip;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;참고로 Defi Saver에서는 Flash Loan으로 빌린 금액의 &lt;strong&gt;0.25%를 서비스 수수료&lt;/strong&gt;로 받는 비즈니스 모델을 가진다.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jeongseup.github.io/img/defidash/defisaver-service-fee.png"
loading="lazy"
alt="서비스 수수료 구조"
&gt;&lt;/p&gt;
&lt;p&gt;포지션을 다음과 같이 preview 형태로도 제공해준다.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jeongseup.github.io/img/defidash/defisaver-position-preview.png"
loading="lazy"
alt="포지션 프리뷰"
&gt;&lt;/p&gt;
&lt;p&gt;포지션을 종료하면 기존 로직을 역행하는 과정을 거친다. 기본적으로 looping 과정에서 Morpho Flash Loan을 사용한다.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jeongseup.github.io/img/defidash/defisaver-close-position.png"
loading="lazy"
alt="포지션 종료(close position)"
&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Close position tx: &lt;a class="link" href="https://basescan.org/tx/0xe04ccbbd780f79de493dca0a000a0bfcf63c26bedbb1f078abb4d12413e09e5d" target="_blank" rel="noopener"
&gt;basescan.org/tx/0xe04ccb&amp;hellip;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="3-구조-분석"&gt;3. 구조 분석
&lt;/h2&gt;&lt;h3 id="leverage-max-multiplier"&gt;Leverage Max Multiplier
&lt;/h3&gt;&lt;p&gt;최대 레버리지 배수는 다음과 같이 결정된다.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://jeongseup.github.io/img/defidash/defisaver-max-multiplier.png"
loading="lazy"
alt="Max multiplier 산출 공식"
&gt;&lt;/p&gt;
$$\text{Max Multiplier} = \frac{1}{1 - \text{LTV}}$$&lt;h3 id="leverage-내부-트랜잭션-구조"&gt;Leverage 내부 트랜잭션 구조
&lt;/h3&gt;&lt;p&gt;롤업된 트랜잭션을 의미별로 구조화하면 3가지 컴포넌트로 나뉜다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Flash Loan&lt;/strong&gt; — 레버리지에 필요한 초기 자금 확보&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Swap&lt;/strong&gt; — 빌린 스테이블코인을 담보 자산으로 교환&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deposit &amp;amp; Lending&lt;/strong&gt; — 렌딩 프로토콜에 담보 예치 및 대출&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="4-defidash-프로젝트-구상"&gt;4. DefiDash 프로젝트 구상
&lt;/h2&gt;&lt;p&gt;위 분석을 바탕으로, 이번 13기 과정에서는 &lt;strong&gt;leverage, deleverage(포지션 on/off) 정도만 지원하는 MVP&lt;/strong&gt;를 만들기로 했다.&lt;/p&gt;
&lt;p&gt;각 컴포넌트별로 Sui 생태계에서 사용할 프로토콜을 매핑하면 다음과 같다.&lt;/p&gt;
&lt;h3 id="flash-loan"&gt;Flash Loan
&lt;/h3&gt;&lt;p&gt;레버리지 루핑에 필요한 스테이블코인을 어디서 빌려올 것인가?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scallop&lt;/li&gt;
&lt;li&gt;NAVI&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="swap-aggregator--dex"&gt;Swap (Aggregator / DEX)
&lt;/h3&gt;&lt;p&gt;Flash Loan으로 빌려온 스테이블코인을 최적 비율로 담보 자산으로 교환할 곳은?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Aftermath&lt;/li&gt;
&lt;li&gt;Cetus&lt;/li&gt;
&lt;li&gt;7k Protocol&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="deposit--lending"&gt;Deposit &amp;amp; Lending
&lt;/h3&gt;&lt;p&gt;레버리지 포지션의 유지 비용(Supply APR - Borrow APR)이 가장 저렴한 곳은?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Suilend&lt;/li&gt;
&lt;li&gt;NAVI&lt;/li&gt;
&lt;li&gt;Scallop&lt;/li&gt;
&lt;li&gt;Bluefin&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Flash Loan 출처가 Scallop이라고 해서 렌딩 프로토콜도 반드시 Scallop일 필요는 없다. 각 컴포넌트는 독립적으로 최적의 조합을 선택할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="5-프로젝트-목표-정의"&gt;5. 프로젝트 목표 정의
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;목표:&lt;/strong&gt; 3개 렌딩 프로토콜(Suilend, NAVI, Scallop)을 통합하는 leverage lending protocol aggregator 만들기.&lt;/p&gt;
&lt;h3 id="최종-워크플로우"&gt;최종 워크플로우
&lt;/h3&gt;&lt;p&gt;PTB 하나에 다음 5단계를 원자적으로 실행한다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1. Flash Loan ← Scallop
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;2. Swap ← 7k Aggregator
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;3. Deposit ← Lending Protocol (Suilend / NAVI / Scallop)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;4. Borrow ← 같은 Lending Protocol
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;5. Repay ← Scallop (Flash Loan 상환)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;각 컴포넌트를 TypeScript SDK 레벨로 먼저 만들어보고, 필요하다면 컨트랙트도 파헤쳐보는 것으로 방향을 잡았다.&lt;/p&gt;
&lt;p&gt;프로젝트 완성 후에는 실제 레버리지 포지션을 통해 서비스 이용의 수익성을 검증할 계획이다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="next"&gt;Next
&lt;/h2&gt;&lt;p&gt;다음 글에서는 실제 SDK 개발에 착수한다. Sui 렌딩 프로토콜의 온체인 데이터 구조를 분석하고, Protocol Adapter 패턴을 설계한 과정을 다룬다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://jeongseup.github.io/p/defidash-technical-journal-day1/" &gt;DefiDash Journal Day 1: 프로젝트 킥오프와 Sui 렌딩 생태계 분석&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;DefiDash의 전체 코드는 &lt;a class="link" href="https://github.com/curg-13" target="_blank" rel="noopener"
&gt;curg-13&lt;/a&gt; 조직에서 확인할 수 있다.&lt;/em&gt;&lt;/p&gt;</description></item></channel></rss>