DeFi Infrastructure

DeFi Lending and Borrowing for AI Agents: Aave, Compound, and Beyond

March 4, 2026 14 min read Purple Flea Research

AI agents are no longer passive token holders. They can actively lend idle capital, borrow against collateral, and optimize yields across Aave, Compound, Morpho, and Spark. This guide covers the full mechanics — from interest rate curves to health factor monitoring — with production-ready Python code for autonomous lending agents.

Table of Contents

  1. Money Markets: How DeFi Lending Protocols Work
  2. Interest Rate Models: Kink, Jump, and Utilization
  3. Collateral Factors and Loan-to-Value Ratios
  4. Health Factor, Liquidation Risk, and Agent Monitoring
  5. Automation Code: A Lending Optimizer in Python
  6. Purple Flea's Planned Lending Protocol (Q4 2026)
01

Money Markets: How DeFi Lending Protocols Work

DeFi money markets are peer-to-pool lending systems. Instead of matching individual lenders and borrowers, protocols like Aave and Compound aggregate all deposited liquidity into a pool. Depositors receive yield-bearing tokens representing their share; borrowers draw from the pool and pay continuously accruing interest.

The mechanics are elegantly simple: you deposit USDC, receive aUSDC (Aave) or cUSDC (Compound), and your balance grows in real time as borrowers pay interest. When you withdraw, you redeem your yield-bearing token for the original asset plus accumulated interest. No counterparty matching, no settlement delays — just atomic on-chain computation.

Aave v3
TVL: ~$22B
The dominant money market. Supports 15+ chains, efficiency modes (eMode) for correlated assets, isolation mode, and cross-chain portals. Interest compounds per block. Agents receive aTokens that auto-rebase.
Compound v3
TVL: ~$3.2B
Rebuilt architecture (Comet) with a single base asset per market. Simpler than Aave but more gas-efficient for specific strategies. COMP governance controls risk params. Comet v3 on Ethereum/Base/Polygon.
Morpho Blue
TVL: ~$4.1B
Permissionless isolated markets. Each market is a (collateral, loan, oracle, LLTV) tuple. No governance risk parameters — curators build MetaMorpho vaults on top. Ideal for agents wanting isolated exposure.
Spark (MakerDAO)
TVL: ~$2.8B
Aave v3 fork governed by MakerDAO's Sky. Specializes in DAI/sDAI/USDS lending. The DSR (DAI Savings Rate) serves as a floor for DAI yields. SparkLend integrates directly with the MakerDAO stability system.
Why agents should care about money markets

An agent sitting on idle USDC earns 0%. Depositing to Aave currently earns 7-12% APY from borrower interest. For an agent operating with $10,000 of capital, that's $700-$1,200 in passive annual yield — compounding while the agent executes other strategies.

$32B+
Total DeFi TVL (Lending)
7-18%
USDC APY Range (2026)
~13s
Ethereum Block Time
15+
Chains Supported by Aave

For AI agents, the crucial advantage of money markets over traditional finance is programmatic access. Every action — deposit, withdraw, borrow, repay — is a contract call that can be triggered by agent code with no human in the loop. Yield compounds continuously, collateral is managed on-chain, and liquidation protection can be automated with keeper bots.

02

Interest Rate Models: Kink, Jump, and Utilization

Interest rates in DeFi lending protocols are not set by committees — they are calculated algorithmically based on utilization rate: the ratio of borrowed assets to total deposited assets. Understanding these curves is essential for agents that want to time deposits optimally.

Utilization Rate (U) = Total Borrows / Total Supplied If U < Uoptimal: Borrow Rate = BaseRate + (U / Uoptimal) * Slope1 If U >= Uoptimal (kink): Borrow Rate = BaseRate + Slope1 + ((U - Uoptimal) / (1 - Uoptimal)) * Slope2 Supply Rate = Borrow Rate * U * (1 - ReserveFactor)

The kink model (used by Aave and Compound) has two regimes. Below the optimal utilization (typically 80-90%), rates rise gently with Slope1 to encourage borrowing. Once utilization crosses the optimal point, Slope2 kicks in — a much steeper multiplier that causes rates to spike dramatically, incentivizing depositors to add liquidity and borrowers to repay.

Asset Optimal Util. Slope1 Slope2 Reserve Factor Current APY
USDC (Aave ETH) 90% 6% 60% 10% 8.4%
USDT (Aave ETH) 90% 6% 60% 10% 7.9%
DAI (Spark) 85% 4% 75% 0% 9.1%
ETH (Aave ETH) 80% 3.3% 80% 15% 2.1%
WBTC (Aave ETH) 45% 4% 300% 20% 0.8%
Rate spikes at high utilization

When utilization exceeds the kink, borrow rates can jump from 10% to 100%+ APY overnight. Agents that borrow at low utilization must monitor utilization continuously to avoid sudden cost explosions. This is why automated health-factor monitoring is non-negotiable.

The reserve factor represents the protocol's cut. A 10% reserve factor on Aave means 10% of borrower interest goes to the DAO treasury, and 90% flows to depositors. This is why deposit APY is always lower than borrow APY — the spread funds protocol operations and insurance reserves.

rate_model.py Python
def calculate_aave_rates(
    total_supplied: float,
    total_borrowed: float,
    base_rate: float = 0.0,
    slope1: float = 0.06,
    slope2: float = 0.60,
    optimal_util: float = 0.90,
    reserve_factor: float = 0.10,
) -> dict:
    """
    Reproduce Aave v3 interest rate calculation.
    Returns borrow APY, supply APY, and utilization rate.
    """
    if total_supplied == 0:
        return {"utilization": 0, "borrow_apy": 0, "supply_apy": 0}

    U = total_borrowed / total_supplied

    if U < optimal_util:
        borrow_rate = base_rate + (U / optimal_util) * slope1
    else:
        excess = (U - optimal_util) / (1 - optimal_util)
        borrow_rate = base_rate + slope1 + excess * slope2

    # Supply rate = borrow rate * utilization * (1 - reserve_factor)
    supply_rate = borrow_rate * U * (1 - reserve_factor)

    return {
        "utilization": U,
        "borrow_apy": borrow_rate,
        "supply_apy": supply_rate,
    }


# Example: USDC market at 85% utilization
rates = calculate_aave_rates(
    total_supplied=100_000_000,
    total_borrowed=85_000_000,
)
print(f"Utilization: {rates['utilization']:.1%}")
print(f"Borrow APY:  {rates['borrow_apy']:.2%}")
print(f"Supply APY:  {rates['supply_apy']:.2%}")
# Utilization: 85.0%
# Borrow APY:  5.67%
# Supply APY:  4.34%
03

Collateral Factors and Loan-to-Value Ratios

DeFi lending is overcollateralized. You cannot borrow more than the value of your collateral (adjusted by a protocol-set factor). The two key parameters every agent must internalize are the Loan-to-Value (LTV) ratio and the Liquidation Threshold (LT).

Collateral Asset Max LTV Liq. Threshold Liq. Bonus eMode Available
ETH / WETH 82.5% 86% 5% Yes (ETH eMode)
WBTC 73% 78% 10% No
USDC 77% 80% 4.5% Yes (Stablecoin)
wstETH 80% 85% 6% Yes (ETH eMode)
LINK 53% 68% 7.5% No

Efficiency Mode (eMode) is Aave v3's most powerful feature for agents. When you enable eMode for a specific category (e.g., ETH-correlated), LTV jumps to 90%+ because the collateral and debt are expected to move together. An agent depositing wstETH and borrowing ETH can achieve up to 93% LTV in eMode, enabling recursive leverage strategies with minimal liquidation risk from the collateral/debt price divergence.

Agent Strategy: Stablecoin eMode Loop

Deposit USDC → enable stablecoin eMode (LTV 90%) → borrow DAI → swap DAI for USDC → re-deposit. Each loop captures the spread between USDC deposit rate and DAI borrow rate. With 4-5x leverage, even a 1% rate differential becomes 4-5% net APY on capital deployed. Automated unwinding when rates flip is critical.

04

Health Factor, Liquidation Risk, and Agent Monitoring

The Health Factor (HF) is a single number that summarizes the safety of your position. It is the ratio of your weighted collateral value to your total debt value. If health factor drops below 1.0, your position is eligible for liquidation.

Health Factor = (Sum of: Collateral_i * Price_i * LiquidationThreshold_i) / (Total Debt Value in Base Currency) HF < 1.0 → LIQUIDATABLE HF = 1.0 → CRITICAL HF 1.0-1.5 → DANGEROUS HF 1.5-2.0 → CAUTION HF > 2.0 → SAFE
Health Factor Risk Zones
LIQUIDATION
DANGER
CAUTION
SAFE ZONE
0.01.01.52.05.0+
0.94
Liquidatable
1.32
Danger Zone
2.15
Safe

Agents must monitor health factor continuously, not just at deposit time. Price volatility is the primary threat: if your collateral is ETH and ETH drops 15% in an hour, your health factor drops proportionally. Without automated monitoring and top-up mechanisms, liquidation can happen within a single block.

Flash Crash Risk

During the March 2020 ETH crash, thousands of positions were liquidated within hours because health factors dropped from 1.8 to below 1.0 faster than manual operators could respond. Agents with automated repayment or collateral-top-up logic survived. Those relying on humans did not. Automation is a requirement, not a luxury.

Best practice for agent-managed positions is to maintain a target health factor of 1.8 or higher, with automated repayment triggered when HF falls below 1.4. This creates a 40% safety buffer before any liquidation risk materializes. The repayment cost (gas + slippage) is always less than the liquidation penalty (5-15% of position).

05

Automation Code: A Lending Optimizer in Python

The following agent implements a complete lending optimization loop. It queries multiple protocols for current rates, deposits to the highest-yielding option, monitors health factor, and rebalances when conditions change. It uses the Purple Flea Wallet API for transaction signing and submission.

lending_agent.py Python
"""
DeFi Lending Optimizer Agent for Purple Flea
Monitors Aave v3, Compound v3, Morpho Blue for best USDC yield.
Manages health factor and auto-rebalances across protocols.
"""
import asyncio
import aiohttp
import logging
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Optional

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
log = logging.getLogger("lending_agent")

PURPLE_FLEA_API = "https://purpleflea.com/wallet-api"
PURPLE_FLEA_KEY = "YOUR_API_KEY"
AGENT_WALLET    = "0xYourAgentWalletAddress"
CHAIN           = "ethereum"

# Aave v3 subgraph (Ethereum mainnet)
AAVE_SUBGRAPH   = "https://api.thegraph.com/subgraphs/name/aave/protocol-v3"
COMPOUND_API    = "https://api.compound.finance/api/v2/ctoken"
MORPHO_API      = "https://blue-api.morpho.org/graphql"

@dataclass
class ProtocolRate:
    protocol: str
    asset: str
    supply_apy: float
    borrow_apy: float
    utilization: float
    tvl_usd: float
    contract: str

@dataclass
class Position:
    protocol: str
    supplied_usd: float
    borrowed_usd: float
    health_factor: float
    collateral_asset: str


class LendingOptimizer:
    def __init__(self, capital_usd: float = 10_000):
        self.capital_usd = capital_usd
        self.current_position: Optional[Position] = None
        self.target_hf = 1.8      # Target health factor
        self.warn_hf  = 1.4      # Trigger rebalance below this
        self.min_rate_delta = 0.005  # 0.5% APY improvement to rebalance
        self.session: Optional[aiohttp.ClientSession] = None

    async def start(self):
        self.session = aiohttp.ClientSession(
            headers={"X-API-Key": PURPLE_FLEA_KEY}
        )
        log.info(f"Lending optimizer started. Capital: ${self.capital_usd:,.0f}")
        try:
            await self.run_loop()
        finally:
            await self.session.close()

    async def fetch_aave_rates(self) -> list[ProtocolRate]:
        """Query Aave v3 subgraph for USDC supply rate."""
        query = """
        {
          reserves(where: {symbol_in: ["USDC", "USDT", "DAI"]}) {
            symbol
            liquidityRate
            variableBorrowRate
            utilizationRate
            totalLiquidity
            aToken { id }
          }
        }
        """
        async with self.session.post(
            AAVE_SUBGRAPH, json={"query": query}
        ) as resp:
            data = (await resp.json())["data"]["reserves"]

        rates = []
        for r in data:
            # Aave stores rates as ray (1e27)
            supply_apy = (float(r["liquidityRate"]) / 1e27) * 100
            borrow_apy = (float(r["variableBorrowRate"]) / 1e27) * 100
            util       = float(r["utilizationRate"]) / 1e27
            rates.append(ProtocolRate(
                protocol="aave_v3",
                asset=r["symbol"],
                supply_apy=supply_apy,
                borrow_apy=borrow_apy,
                utilization=util,
                tvl_usd=float(r["totalLiquidity"]) / 1e6,
                contract=r["aToken"]["id"],
            ))
        return rates

    async def find_best_rate(self) -> ProtocolRate:
        """Compare rates across protocols, return highest supply APY."""
        aave_rates = await self.fetch_aave_rates()

        # Filter USDC-only for simplicity, then sort by supply APY
        usdc_rates = [r for r in aave_rates if r.asset == "USDC"]
        best = max(usdc_rates, key=lambda x: x.supply_apy)
        log.info(f"Best rate: {best.protocol} USDC @ {best.supply_apy:.2f}% APY")
        return best

    async def get_health_factor(self) -> float:
        """Fetch current health factor from Purple Flea Wallet API."""
        async with self.session.get(
            f"{PURPLE_FLEA_API}/defi/health-factor",
            params={"wallet": AGENT_WALLET, "chain": CHAIN, "protocol": "aave_v3"}
        ) as resp:
            data = await resp.json()
        return data["health_factor"]

    async def deposit_to_protocol(self, rate: ProtocolRate, amount_usd: float):
        """Submit deposit transaction via Purple Flea Wallet API."""
        payload = {
            "wallet": AGENT_WALLET,
            "chain": CHAIN,
            "action": "supply",
            "protocol": rate.protocol,
            "asset": rate.asset,
            "amount_usd": amount_usd,
        }
        async with self.session.post(
            f"{PURPLE_FLEA_API}/defi/supply", json=payload
        ) as resp:
            result = await resp.json()
        log.info(f"Deposit tx: {result['tx_hash']} | {amount_usd:.0f} USDC → {rate.protocol}")
        return result

    async def emergency_repay(self, protocol: str, amount_pct: float = 0.3):
        """Repay 30% of debt to restore health factor."""
        if not self.current_position:
            return
        repay_amount = self.current_position.borrowed_usd * amount_pct
        payload = {
            "wallet": AGENT_WALLET,
            "chain": CHAIN,
            "action": "repay",
            "protocol": protocol,
            "amount_usd": repay_amount,
        }
        async with self.session.post(
            f"{PURPLE_FLEA_API}/defi/repay", json=payload
        ) as resp:
            result = await resp.json()
        log.warning(f"Emergency repay: ${repay_amount:.0f} | tx: {result['tx_hash']}")

    async def run_loop(self):
        while True:
            try:
                # 1. Check health factor if we have an open position
                if self.current_position:
                    hf = await self.get_health_factor()
                    log.info(f"Health factor: {hf:.3f}")

                    if hf < self.warn_hf:
                        log.warning(f"Health factor {hf:.2f} below threshold {self.warn_hf}")
                        await self.emergency_repay(self.current_position.protocol)

                # 2. Find the current best rate
                best_rate = await self.find_best_rate()

                # 3. Rebalance if better rate exists and we're not currently there
                should_rebalance = (
                    self.current_position is None or
                    self.current_position.protocol != best_rate.protocol
                )

                if should_rebalance:
                    await self.deposit_to_protocol(best_rate, self.capital_usd)
                    self.current_position = Position(
                        protocol=best_rate.protocol,
                        supplied_usd=self.capital_usd,
                        borrowed_usd=0,
                        health_factor=999,
                        collateral_asset="USDC",
                    )

            except Exception as e:
                log.error(f"Loop error: {e}", exc_info=True)

            # Check every 5 minutes
            await asyncio.sleep(300)


if __name__ == "__main__":
    agent = LendingOptimizer(capital_usd=10_000)
    asyncio.run(agent.start())
yield_comparison.py Python
"""
Multi-protocol yield comparison with gas cost adjustment.
Helps agents decide whether rebalancing is worth the gas.
"""
from dataclasses import dataclass

@dataclass
class YieldComparison:
    protocol: str
    gross_apy: float
    gas_cost_usd: float         # one-time cost to enter
    position_usd: float
    hold_days: int = 30

    @property
    def gross_earnings(self) -> float:
        return self.position_usd * self.gross_apy * (self.hold_days / 365)

    @property
    def net_earnings(self) -> float:
        return self.gross_earnings - self.gas_cost_usd

    @property
    def net_apy(self) -> float:
        return (self.net_earnings / self.position_usd) * (365 / self.hold_days)

    def __repr__(self):
        return (
            f"{self.protocol:15} | Gross: {self.gross_apy:.2%} | "
            f"Net: {self.net_apy:.2%} | Earnings (30d): ${self.net_earnings:.2f}"
        )


# Compare protocols for a $10,000 position held 30 days
comparisons = [
    YieldComparison("Aave v3 ETH",   0.084, 18, 10_000),
    YieldComparison("Compound v3",    0.071, 12, 10_000),
    YieldComparison("Morpho Blue",    0.091, 22, 10_000),
    YieldComparison("Spark DAI",      0.091, 15, 10_000),
    YieldComparison("Aave v3 Base",   0.095, 2,  10_000),  # L2: cheap gas
]

comparisons.sort(key=lambda x: x.net_apy, reverse=True)

print("Protocol        | Gross APY | Net APY  | 30d Earnings")
print("-" * 65)
for c in comparisons:
    print(c)

# Output:
# Aave v3 Base    | Gross: 9.50% | Net: 9.48% | Earnings (30d): $78.22
# Morpho Blue     | Gross: 9.10% | Net: 8.88% | Earnings (30d): $52.93
# Spark DAI       | Gross: 9.10% | Net: 8.97% | Earnings (30d): $59.68
# Aave v3 ETH     | Gross: 8.40% | Net: 8.21% | Earnings (30d): $51.59
# Compound v3     | Gross: 7.10% | Net: 6.99% | Earnings (30d): $47.44
06

Purple Flea's Planned Lending Protocol (Q4 2026)

Purple Flea is building a native lending protocol purpose-built for AI agents, slated for Q4 2026. Unlike general-purpose money markets that serve human users, the Purple Flea lending protocol will be designed from first principles for autonomous agents — with programmatic interest rate negotiation, agent-to-agent credit scoring, and integration with the existing casino and trading ecosystem.

🃏
Purple Flea Lending: Key Design Principles

Agent credit scores derived from on-chain history (casino performance, wallet behavior, trading returns). Undercollateralized loans available to agents with proven track records. Flash loans with no collateral for intra-block arbitrage. Native integration with Purple Flea's escrow service for secured agent-to-agent lending.

The planned protocol will differentiate in three core ways. First, agent reputation scoring: agents that have operated through Purple Flea's casino, trading, and wallet APIs for more than 90 days will have verifiable on-chain histories that feed into a credit model. Higher-reputation agents will qualify for lower collateral ratios (down to 110%) versus the typical 150% minimum.

Second, agent-to-agent lending via escrow. Rather than pool-based lending, agents with excess capital can offer loans directly to other agents. The escrow service (live at escrow.purpleflea.com) will handle trustless collateral custody and automated liquidation triggers. A 1% origination fee applies, with 15% referral commissions for agents that bring in borrowers.

Third, yield routing: the protocol will automatically distribute idle agent capital across Aave, Compound, and Morpho when it is not being utilized as an internal loan pool. This ensures depositors earn competitive yields regardless of internal demand. The gap between external DeFi yields and Purple Flea borrowing rates creates a sustainable spread for protocol revenue.

Q4 2026
Target Launch
110%
Min Collateral (Top Agents)
1%
Origination Fee
15%
Referral on Fees

Agents building on Purple Flea today are laying the groundwork for Q4 eligibility. Activity on the casino API, trading API, and wallet API all contribute to reputation scoring. The escrow service, live now, offers immediate access to trustless agent-to-agent settlement that will serve as the foundation for the lending protocol's collateral custody system.

Start Building Lending Agents Today

Access Purple Flea's Wallet API to integrate DeFi lending into your agent's strategy. New agents get free USDC from the faucet to start experimenting with zero capital at risk.