Skip to content

DeFi Protocols: Aave, Compound and MakerDAO Deep Dive

DodaTech Updated 2026-06-22 8 min read

In this tutorial, you'll learn major DeFi protocols including Aave for lending, Compound for money markets, and MakerDAO for stablecoins with practical interaction examples. Why it matters: Aave, Compound, and MakerDAO are the three foundational DeFi protocols, managing over $30 billion in combined total value locked and enabling the entire DeFi ecosystem through lending, borrowing, and stablecoin creation. By the end, you'll interact with each protocol programmatically.

DeFi protocols provide decentralized financial services through smart contracts, with Aave and Compound dominating lending markets while MakerDAO provides the DAI stablecoin that underpins DeFi liquidity.

Aave Lending Protocol

Aave is a non-custodial liquidity protocol where users deposit assets to earn interest and borrow assets by providing collateral.

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

// Simplified Aave pool interaction contract
contract AaveInteraction {
    ILendingPool public lendingPool;
    
    constructor(address _pool) {
        lendingPool = ILendingPool(_pool);
    }
    
    function deposit(address _asset, uint256 _amount) external {
        IERC20(_asset).approve(address(lendingPool), _amount);
        lendingPool.deposit(_asset, _amount, msg.sender, 0);
    }
    
    function borrow(address _asset, uint256 _amount) external {
        lendingPool.borrow(_asset, _amount, 2, 0, msg.sender);
        // Interest rate mode: 1=stable, 2=variable
    }
    
    function repay(address _asset, uint256 _amount) external {
        IERC20(_asset).approve(address(lendingPool), _amount);
        lendingPool.repay(_asset, _amount, 2, msg.sender);
    }
    
    function withdraw(address _asset, uint256 _amount) external {
        lendingPool.withdraw(_asset, _amount, msg.sender);
    }
}
const { ethers } = require("ethers");

async function interactWithAave() {
  const provider = new ethers.JsonRpcProvider("https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY");
  const signer = new ethers.Wallet("YOUR_KEY", provider);
  
  // Aave V3 Pool (Ethereum Mainnet)
  const poolAddress = "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2";
  
  const poolABI = [
    "function deposit(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external",
    "function borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf) external",
    "function withdraw(address asset, uint256 amount, address to) external returns (uint256)",
    "function repay(address asset, uint256 amount, uint256 rateMode, address onBehalfOf) external returns (uint256)",
    "function getUserAccountData(address user) external view returns (uint256 totalCollateralETH, uint256 totalDebtETH, uint256 availableBorrowsETH, uint256 currentLiquidationThreshold, uint256 ltv, uint256 healthFactor)",
    "function getReserveData(address asset) external view returns (tuple(uint256, ...) )]
  ];
  
  const pool = new ethers.Contract(poolAddress, poolABI, signer);
  
  // Check account health
  const accountData = await pool.getUserAccountData(signer.address);
  console.log("Account health:");
  console.log("  Total collateral:", ethers.formatEther(accountData.totalCollateralETH), "ETH");
  console.log("  Total debt:", ethers.formatEther(accountData.totalDebtETH), "ETH");
  console.log("  Available to borrow:", ethers.formatEther(accountData.availableBorrowsETH), "ETH");
  console.log("  LTV:", accountData.ltv.toString());
  console.log("  Health factor:", ethers.formatEther(accountData.healthFactor));
  
  // Deposit USDC
  const usdcAddress = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
  const usdcDecimals = 6;
  const depositAmount = ethers.parseUnits("1000", usdcDecimals); // 1000 USDC
  
  // Expected output:
  // Account health:
  //   Total collateral: 0.0 ETH
  //   Total debt: 0.0 ETH
  //   Available to borrow: 0.0 ETH
  //   LTV: 0
  //   Health factor: ∞
}

interactWithAave();
flowchart LR
  A[Depositor] -->|Deposit aUSDC| B[Aave Pool]
  B -->|Mint aToken| A
  C[Borrower] -->|Deposit Collateral| B
  B -->|Borrow variable/stable| C
  C -->|Pay interest| B
  B -->|Distribute yield| A
  D[Liquidator] -->|Repay debt| B
  B -->|Seize collateral| D
  E[Flash Borrower] -->|Flash loan
No collateral| B B -->|Return + fee| E

Compound Protocol

Compound is an algorithmic money market protocol similar to Aave but with cToken architecture and COMP governance.

const { ethers } = require("ethers");

async function interactWithCompound() {
  const provider = new ethers.JsonRpcProvider("https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY");
  const signer = new ethers.Wallet("YOUR_KEY", provider);
  
  // cUSDC (Compound USDC) contract
  const cUSDCAddress = "0x39AA39c021dfbaE8faC545936693aC917d5E7563";
  
  const cTokenABI = [
    "function mint(uint256 mintAmount) external returns (uint256)",
    "function redeem(uint256 redeemTokens) external returns (uint256)",
    "function borrow(uint256 borrowAmount) external returns (uint256)",
    "function repayBorrow(uint256 repayAmount) external returns (uint256)",
    "function balanceOf(address owner) view returns (uint256)",
    "function exchangeRateCurrent() view returns (uint256)",
    "function supplyRatePerBlock() view returns (uint256)",
    "function borrowRatePerBlock() view returns (uint256)",
    "function getCash() view returns (uint256)",
    "function totalBorrows() view returns (uint256)",
    "function totalSupply() view returns (uint256)]
  ];
  
  const cUSDC = new ethers.Contract(cUSDCAddress, cTokenABI, signer);
  
  // Get supply rate
  const supplyRate = await cUSDC.supplyRatePerBlock();
  const borrowRate = await cUSDC.borrowRatePerBlock();
  
  // Convert to APY: (1 + rate_per_block)^blocks_per_year - 1
  const blocksPerYear = 2102400; // ~4 second blocks
  const supplyAPY = (Math.pow(1 + Number(ethers.formatUnits(supplyRate, 18)), blocksPerYear) - 1) * 100;
  const borrowAPY = (Math.pow(1 + Number(ethers.formatUnits(borrowRate, 18)), blocksPerYear) - 1) * 100;
  
  console.log("Compound USDC Market:");
  console.log(`  Supply APY: ${supplyAPY.toFixed(2)}%`);
  console.log(`  Borrow APY: ${borrowAPY.toFixed(2)}%`);
  
  // Get exchange rate (1 cUSDC = how much USDC?)
  const exchangeRate = await cUSDC.exchangeRateCurrent();
  console.log(`  Exchange rate: ${ethers.formatUnits(exchangeRate, 28)} USDC/cUSDC`);
  
  // Get market liquidity
  const cash = await cUSDC.getCash();
  console.log(`  Available liquidity: ${ethers.formatUnits(cash, 6)} USDC`);
  
  const totalBorrows = await cUSDC.totalBorrows();
  console.log(`  Total borrows: ${ethers.formatUnits(totalBorrows, 6)} USDC`);
  
  // Calculate utilization rate
  const utilization = Number(totalBorrows) / (Number(totalBorrows) + Number(cash));
  console.log(`  Utilization: ${(utilization * 100).toFixed(2)}%`);
}

interactWithCompound();
// Expected output:
// Compound USDC Market:
//   Supply APY: 3.45%
//   Borrow APY: 5.12%
//   Exchange rate: 0.020000 USDC/cUSDC
//   Available liquidity: 50000000.00 USDC
//   Total borrows: 75000000.00 USDC
//   Utilization: 60.00%

MakerDAO and DAI Stablecoin

MakerDAO is a decentralized stablecoin protocol that maintains DAI's peg to $1 through overcollateralized vaults (formerly CDPs).

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

// Simplified MakerDAO vault interaction
contract MakerVault {
    IDSProxy public proxy;
    IManager public manager;
    
    function openVault(address _collateralType) external returns (uint256 vaultId) {
        vaultId = manager.open(_collateralType, address(this));
    }
    
    function depositCollateral(uint256 _vaultId, uint256 _amount) external {
        IERC20(collateral).approve(address(manager), _amount);
        manager.deposit(_vaultId, _amount);
    }
    
    function generateDAI(uint256 _vaultId, uint256 _amount) external {
        manager.draw(_vaultId, _amount);
    }
    
    function repayDAI(uint256 _vaultId, uint256 _amount) external {
        IERC20(dai).approve(address(manager), _amount);
        manager.wipe(_vaultId, _amount);
    }
    
    function withdrawCollateral(uint256 _vaultId, uint256 _amount) external {
        manager.free(_vaultId, _amount);
    }
}
const { ethers } = require("ethers");

async function makerDAOExample() {
  const provider = new ethers.JsonRpcProvider("https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY");
  
  // DAI token
  const daiAddress = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
  const dai = new ethers.Contract(daiAddress, [
    "function balanceOf(address) view returns (uint256)",
    "function totalSupply() view returns (uint256)]
  ], provider);
  
  // Get DAI stats
  const totalSupply = await dai.totalSupply();
  console.log("DAI total supply:", ethers.formatEther(totalSupply));
  
  // Check DAI/USD peg via Chainlink oracle
  const oracleAddress = "0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9";
  const oracle = new ethers.Contract(oracleAddress, [
    "function latestRoundData() view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)]
  ], provider);
  
  const roundData = await oracle.latestRoundData();
  const daiPrice = Number(roundData.answer) / 1e8;
  console.log("DAI/USD price:", daiPrice.toFixed(4));
  
  // Check if DAI is pegged
  const deviation = Math.abs(daiPrice - 1) * 100;
  console.log(`Peg deviation: ${deviation.toFixed(4)}%`);
  
  if (deviation > 1) {
    console.log("DAI is de-pegged!");
  } else {
    console.log("DAI is within peg range.");
  }
  
  // Get Maker protocol stats
  const mcdVat = new ethers.Contract("0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B", [
    "function debt() view returns (uint256)]
  ], provider);
  
  const systemDebt = await mcdVat.debt();
  console.log("System debt (total DAI):", ethers.formatEther(systemDebt));
}

makerDAOExample();
// Expected output:
// DAI total supply: 5000000000.00
// DAI/USD price: 1.0002
// Peg deviation: 0.0200%
// DAI is within peg range.
// System debt (total DAI): 5000000000.00

Comparing Protocols

Feature Aave Compound MakerDAO
Lending aTokens cTokens Vault-based
Interest Rate Variable + Stable Algorithmic Stability fee
Governance AAVE token COMP token MKR token
Unique Feature Flash loans, credit delegation COMP rewards, cToken composability DAI stablecoin, Peg Stability Module
Collateral Type Multiple (40+ assets) Multiple (20+ assets) Mostly ETH, stETH, USDC
Risk Smart contract, oracle Smart contract, oracle Collateral volatility, governance

Common Errors and Misunderstandings

1. Not Understanding Liquidation

Each protocol has different liquidation thresholds. Aave liquidates at health factor < 1, Compound at collateral factor ~75-85%. Know these before borrowing.

2. Confusing Variable and Stable Rates

Aave offers both. Variable rates fluctuate with market conditions. Stable rates are fixed for a period but can be adjusted by the protocol. Variable rates are usually lower initially.

3. Forgetting cToken Exchange Rate

In Compound, cTokens appreciate against the underlying (not increase in quantity). 1 cUSDC = more USDC over time. Users redeem cTokens for the underlying plus interest.

4. DAI Depeg Risk

DAI has historically depegged during extreme market conditions (March 2020, $0.88; March 2023, $0.90). Understanding the Peg Stability Module and liquidation mechanisms is essential.

5. Underestimating Governance Risk

All three protocols are governed by token holders. Governance attacks (proposing malicious upgrades) pose systemic risks. Monitor active proposals.

Practice Questions

  1. How does Aave's aToken model differ from Compound's cToken model? Aave aTokens increase in quantity over time (rebasing). Compound cTokens appreciate in value against the underlying (non-rebasing, exchange rate increases).

  2. What is a flash loan on Aave? A flash loan allows borrowing any amount of assets without collateral, as long as the loan is repaid within the same transaction. If not repaid, the transaction reverts.

  3. How does MakerDAO maintain DAI's peg? Through overcollateralized vaults (minimum 150-170%), the Peg Stability Module (direct USDC/DAI swaps), DAI Savings Rate (adjusting demand), and arbitrage incentives.

  4. What is the health factor in Aave? Health Factor = (Total Collateral * Liquidation Threshold) / Total Borrowed. When below 1, the position is liquidatable. Most users maintain > 1.5 for safety.

  5. How does Compound's interest rate model work? Interest rates are a function of utilization rate (borrows / total liquidity). Higher utilization = higher rates. The "kink" point (~80%) creates steep rate increases above optimal utilization.

Challenge

Build a DeFi portfolio manager in TypeScript using ethers.js that tracks a user's positions across Aave, Compound, and MakerDAO. Calculate net APY across all positions, detect positions approaching liquidation (health factor < 1.2), estimate gas costs for moving positions between protocols for yield optimization, and provide alerts for governance proposals that affect the user.

Real-World Task

Create a yield optimization strategy using Solidity that deposits ETH into Aave, borrows stablecoins against it, deposits the stablecoins into Compound for yield, claims COMP rewards, and compounds the rewards back into the position. Implement safety checks: maintain health factor above 1.8, handle liquidation warnings via React notifications, and allow emergency withdrawal.

Frequently Asked Questions

Which protocol is safer: Aave or Compound?

Both are similarly secure with extensive audits and long track records. Aave has more features (flash loans, credit delegation) which increases attack surface slightly. Compound's simpler design may have fewer bugs. Both have survived major market events without loss of funds.

Can DAI really maintain its peg?

DAI has maintained its $1 peg within 1% for 90%+ of its history. During extreme volatility (COVID crash, USDC depeg), DAI deviated temporarily but recovered. The Peg Stability Module and multiple collateral types have improved peg stability over time.

Do I need COMP/MKR tokens to use these protocols?

No. You can deposit, borrow, and repay without holding governance tokens. COMP tokens are earned as rewards on Compound (Comet). MKR is only needed to pay stability fees on MakerDAO. AAVE is not required for Aave usage.

Next Steps

After mastering these protocols, explore DeFi composability by combining them in strategies, then study Web3 Security for protecting user funds in DeFi applications.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro