Decentralized Finance (DeFi) has revolutionized traditional financial systems by enabling permissionless, transparent, and trustless financial services. Among the leading DeFi protocols, Compound stands out as a robust lending and borrowing platform built on blockchain technology. This comprehensive guide walks you through deploying a simplified version of the Compound protocol on the BSC Testnet using Remix IDE and MetaMask, offering hands-on experience with core DeFi mechanisms.
Whether you're a developer exploring smart contract architecture or a blockchain enthusiast diving into DeFi, this tutorial delivers practical insights into building a decentralized lending bank from scratch.
π Discover how to interact with decentralized financial protocols securely and efficiently.
Core Keywords
- Compound deployment
- DeFi lending platform
- cToken creation
- Interest rate model
- Price oracle setup
- Collateral factor
- Liquidity mining
- Smart contract deployment
Understanding the Compound Architecture
Before deployment, itβs essential to understand Compoundβs modular design. The protocol consists of several interconnected smart contracts that manage lending, borrowing, interest accrual, price feeds, and governance incentives.
Despite its complexity β with over 30 source files β breaking down the system into functional modules makes it approachable. Below is a structured walkthrough of each critical component.
Pro Tip: While Compound's codebase may seem daunting at first, studying it reveals elegant design patterns and security-conscious engineering. With patience, even beginners can grasp its inner workings.
Module 1: COMP Token β Incentive Mechanism
The COMP token serves as the governance and reward token within the Compound ecosystem. Although optional for test environments, deploying a mock COMP token helps simulate real-world incentive mechanics.
Deployment Steps:
- Use
Comp.solfrom the official repository. Customize parameters:
- Name:
MyCOMP - Symbol:
MCOMP - Total Supply:
10,000,000 MCOMP
- Name:
- Deploy via Remix IDE using Account 1.
After deployment, note the contract address:
0x1fe7FF222D59B6648D640090046661313A1CF0a2Update this address in the ComptrollerG7.sol contract using the getCompAddress() function to ensure compatibility.
π Learn how top-tier platforms handle token economics and user incentives.
Module 2: Comptroller β Core Logic Controller
The Comptroller acts as the central risk management and market coordination engine. It uses a proxy pattern (Unitroller) for upgradability.
2.1 Deploy Unitroller (Proxy Contract)
- Deploy
Unitroller.solusing Account 1. - Address:
0x268e3eF4380DA46e55B77a6263810910722a875E
2.2 Deploy ComptrollerG7 (Logic Contract)
- Deploy
ComptrollerG7.solas the implementation. - Address:
0x67006E2110119Abfd40b2A743A85b4d3bF8967b9
Proxy Binding Process
To activate the proxy:
- Call
_setPendingImplementation(newImplementation)onUnitroller, passing theComptrollerG7address. - Call
_become(unitroller)onComptrollerG7.
This two-step process prevents accidental upgrades to invalid logic contracts.
Note: Always expose the Unitroller address externally β it proxies all calls to the live logic contract.Module 3: Price Oracle β Market Valuation System
Accurate asset pricing is vital for maintaining loan health and preventing under-collateralization.
Deploy SimplePriceOracle
- Deploy
SimplePriceOracle.solusing Account 1. - Address:
0x5991199a9aB1801A229a2E49a042471eDE997a21
Later, set prices for underlying assets like USDT and ETH to reflect their USD values.
Module 4: Configuration & Risk Parameters
Now configure global risk controls through the Comptroller interface.
4.2 Set Close Factor
Defines the maximum portion of a loan that can be repaid during liquidation.
- Value:
50%β500000000000000000(in mantissa) - Function:
_setCloseFactor(uint)
4.3 Set Liquidation Incentive
Rewards liquidators for maintaining system solvency.
- Value:
8% bonusβ1.08 * 1e18 = 1080000000000000000 - Function:
_setLiquidationIncentive(uint)
4.4 Assign Price Oracle
Link the oracle to Comptroller:
- Call
_setPriceOracle(newOracle) - Pass:
SimplePriceOracleaddress
Module 5: Interest Rate Models
Interest rates dynamically adjust based on asset utilization.
Deploy JumpRateModelV2
Used for both ERC-20 and native ETH markets.
Parameters:
- Base Rate:
0 - Multiplier Per Year:
7%β70000000000000000 - Jump Multiplier:
3xβ3000000000000000000 - Kink (Utilization threshold):
75%β750000000000000000 - Owner:
msg.sender
Deploy two instances:
- For ERC20-based cTokens β Address:
0x8A517DA790929D2aC3527210f9472E2822424180 - For ETH-based cETH β Address:
0x0cca4ccD1ED542B5D7F3Ebbcf49D92DCB0a8D04e
These models allow flexible rate adjustments post-deployment.
Module 6: cToken for ERC-20 Assets
cTokens represent tokenized deposits and accrue interest over time.
6.1 Deploy Mock ERC-20 (e.g., USDT)
Create a test stablecoin:
- Name:
TestUSDT - Symbol:
tUSDT - Decimals:
18 - Address:
0xBEA207ec294BCe7a866C3a598195A61Bb7E8D599
6.2 Deploy CErc20Delegate
Shared logic contract for all ERC-20-backed cTokens.
- Address:
0xc176eD65274b2a2d422126d597Be715fc97d2e98
6.3 Deploy CErc20Delegator (cUSD)
The actual cToken representing USDT deposits.
Constructor Arguments:
| Parameter | Value |
|---|---|
| Underlying | tUSDT address |
| Comptroller | Unitroller address |
| Interest Rate Model | First JumpRateModelV2 |
| Initial Exchange Rate | 1e18 (1:1) |
| Name | "COMPOUND USD" |
| Symbol | "cUSD" |
| Decimals | 18 |
| Admin | msg.sender |
| Implementation | CErc20Delegate address |
| Data | 0x |
Deployed at: 0x209C9b6a0Ec37b91d0758514070A8439B14B9B3c
Module 7: cToken for Native ETH (cETH)
For native cryptocurrency support.
Deploy CEther.sol
Parameters:
- Comptroller: Unitroller address
- Interest Model: Second JumpRateModelV2
- Exchange Rate:
1e18 - Name: "COMPOUND ETHER"
- Symbol: "cETH"
- Decimals: 18
- Admin: msg.sender
Deployed at: 0xf3feeab27E8B8b71ED92040be19E5aA80baf9B01
Module 8: Set Market Prices
Update asset valuations in the oracle.
8.1 cUSD Price
- cToken:
cUSD address - Price:
$1β1e18
8.2 cETH Price
- cToken:
cETH address - Price:
$2,000β2e21
These values enable accurate collateral calculations.
Module 9: Final cToken Configuration
9.1 Set Reserve Factor
Portion of interest reserved for protocol reserves.
- For cUSD:
10%β1e17 - For cETH:
20%β2e17
Call _setReserveFactor(newReserveFactorMantissa) on each cToken.
9.2 Add Markets
Enable markets in Comptroller:
- Call
_supportMarket(cToken)for both cUSD and cETH.
9.3 Set Collateral Factor
Determines how much users can borrow against deposited assets.
- Example: Set cUSD collateral factor to
60%β6e17 - Function:
_setCollateralFactor(cToken, factor)
Only supported markets with sufficient price data can be used as collateral.
Module 10: COMP Rewards & Distribution
Users earn COMP tokens when supplying or borrowing in enabled markets.
Enable COMP Speed
Use _setCompSpeed(cToken, compSpeed) where:
compSpeed: Amount of COMP distributed per block (in wei).- Example: Distribute 1 COMP/day across ~5,760 blocks β
173,611,111,111,111,111 wei/block.
Note: COMP is not distributed by default. Admins must explicitly enable rewards per market.
Calculate daily emissions:
const compSpeedPerBlock = await comptroller.methods.compSpeeds(cTokenAddr).call();
const compPerDay = (compSpeedPerBlock / 1e18) * 4 * 60 * 24;Module 11: Claiming COMP Rewards
Users claim accumulated rewards via:
function claimComp(address holder);
function claimComp(address holder, CToken[] memory cTokens);
function claimComp(address[] memory holders, CToken[] memory cTokens, bool borrowers, bool suppliers);Example Web3 call:
await comptroller.methods.claimComp("your-wallet-address").send({ from: sender });Rewards accumulate per block while active in markets.
Testing Core User Functions
Validate functionality with five key operations:
1. Deposit (Mint)
User supplies USDT β receives cUSD at current exchange rate.
await usdt.approve(cUSD.address, amount);
await cUSD.mint(amount);Check balances and liquidity:
const liquidity = await comptroller.getAccountLiquidity(user);2. Borrow
User borrows against collateral after entering markets.
await comptroller.enterMarkets([cUSD.address, cETH.address]);
await cUSD.borrow(loanAmount);System checks liquidity pre-borrow.
3. Repay Loan
Repay debt directly or on behalf of others.
await usdt.approve(cUSD.address, repayment);
await cUSD.repayBorrow(repayment);Interest accrues up to repayment block.
4. Withdraw (Redeem)
Convert cTokens back to underlying assets.
await cUSD.redeem(cTokenAmount);
// OR redeem specific amount of underlying
await cUSD.redeemUnderlying(usdtAmount);Subject to liquidity and solvency checks.
5. Liquidation
Occurs when collateral value drops below threshold.
- Liquidator repays part of borrowerβs debt.
- Receives discounted collateral in return.
- Triggered via
liquidateBorrow()on cToken.
Critical for protocol stability.
Frequently Asked Questions (FAQ)
Q: Can I deploy Compound on mainnet?
A: Yes, but ensure thorough testing on testnets first. Mainnet deployment requires robust security audits and risk parameter tuning.
Q: What is the role of Unitroller?
A: Unitroller is a proxy contract that delegates calls to the Comptroller logic contract, enabling future upgrades without disrupting user positions.
Q: Why use two JumpRateModelV2 instances?
A: Each cToken requires its own interest rate model instance due to independent configuration needs for different asset types (ERC-20 vs ETH).
Q: How are COMP rewards calculated?
A: Rewards are distributed per block based on supply/borrow activity in enabled markets. The _setCompSpeed() function controls emission rates.
Q: Is manual price feeding secure?
A: For production, use decentralized oracles like Chainlink. SimplePriceOracle is suitable only for testing and development.
Q: Can I customize collateral factors?
A: Yes, admins can set collateral factors between 0% and ~90%, depending on asset volatility and risk tolerance.
π Explore secure wallet integrations and advanced DeFi interactions today.
By following this guide, youβve successfully deployed a functional decentralized lending platform inspired by Compound. This foundation enables further experimentation with governance, flash loans, cross-chain integration, and automated yield strategies β all core components of modern DeFi ecosystems.