Assalamualaikum guys! 🙌 This is Mohammad Ayaan Siddiqui (♦moayaan.eth♦). I’m a Full Stack Blockchain Developer , Crypto Investor and MBA in Blockchain Management with 2 years of experience rocking the Web3 world! 🚀 I’ve worn many hats:
- Research Intern at a Hong Kong-based firm 🇭🇰
- Founding Engineer at a Netherlands-based firm 🇳🇱
- Full Stack Intern at a Singapore-based crypto hardware wallet firm 🇸🇬
- Blockchain Developer at a US-based Bitcoin DeFi project 🇺🇸
- PG Diploma in Blockchain Management from Cambridge International Qualifications (CIQ) 🇬🇧
- MBA in Blockchain Management from University of Studies Guglielmo Marconi, Italy 🇮🇹
Let’s connect and build something epic! Find me at moayaan.com 🌐
If you liked this project, please donate to Gaza 🇵🇸 UNRWA Donation Link
Happy coding, fam! 😎✨
A fully decentralized, algorithmic stablecoin system pegged to USD, backed by WETH and WBTC collateral.
- Overview
- How It Works
- Architecture
- Key Concepts
- Smart Contracts
- Getting Started
- Testing
- Deployment
- Security
- Acknowledgements
This project implements a decentralized stablecoin with the following properties:
| Property | Description |
|---|---|
| Collateral Type | Exogenous (WETH & WBTC) |
| Minting Mechanism | Algorithmic (no central authority) |
| Peg | 1 DSC = $1 USD |
| Collateral Ratio | 200% (overcollateralized) |
Unlike centralized stablecoins (USDT, USDC) that rely on trust, DSC is:
✅ Trustless - No central party controls your funds
✅ Transparent - All operations on-chain
✅ Censorship-resistant - No one can freeze your DSC
✅ Overcollateralized - Always backed by >100% collateral
┌─────────────────────────────────────────────────────────────┐
│ USER JOURNEY │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. DEPOSIT COLLATERAL │
│ ┌──────────┐ deposit ┌──────────────┐ │
│ │ User │ ───────────► │ DSCEngine │ │
│ │ (WETH) │ 1 WETH │ │ │
│ └──────────┘ └──────────────┘ │
│ │
│ 2. MINT DSC (Borrow against collateral) │
│ ┌──────────┐ mint ┌──────────────┐ │
│ │ User │ ◄─────────── │ DSCEngine │ │
│ │ (DSC) │ $1000 DSC │ │ │
│ └──────────┘ └──────────────┘ │
│ │
│ 3. REPAY & WITHDRAW │
│ ┌──────────┐ burn + redeem ┌──────────────┐ │
│ │ User │ ───────────► │ DSCEngine │ │
│ │ │ DSC + fee │ returns ETH │ │
│ └──────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
📊 SCENARIO: Alice wants to mint DSC
Step 1: Alice deposits 1 ETH (worth $2000)
Step 2: With 200% collateral ratio, she can mint up to $1000 DSC
Step 3: Alice mints $800 DSC (staying safe)
Her Position:
┌────────────────────────────────────┐
│ Collateral: 1 ETH = $2000 │
│ Debt: 800 DSC = $800 │
│ Health Factor: ($2000 × 50%) / $800│
│ = $1000 / $800 │
│ = 1.25 ✅ (Safe!) │
└────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ PROTOCOL ARCHITECTURE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ DSCEngine.sol │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Deposit │ │ Mint │ │ Liquidate │ │ │
│ │ │ Collateral │ │ DSC │ │ Users │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Redeem │ │ Burn │ │ Health │ │ │
│ │ │ Collateral │ │ DSC │ │ Factor │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ DecentralizedStableCoin.sol │ │
│ │ (ERC20 Token) │ │
│ │ Only DSCEngine can mint/burn tokens │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────┼───────────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ Chainlink │ │ WETH │ │ WBTC │ │
│ │ Price Feeds │ │ Collateral │ │ Collateral │ │
│ └───────────────┘ └───────────────┘ └───────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
The health factor determines if a position is safe or can be liquidated.
Collateral Value × Liquidation Threshold
Health Factor = ─────────────────────────────────────────────
Total DSC Minted
Where: Liquidation Threshold = 50%
| Health Factor | Status | Action |
|---|---|---|
| > 1.0 | ✅ Safe | Nothing happens |
| = 1.0 | Should add collateral | |
| < 1.0 | ❌ Unsafe | Can be liquidated! |
Example:
Collateral: $2000 ETH
DSC Minted: $800
Health Factor = ($2000 × 50%) / $800
= $1000 / $800
= 1.25 ✅ Safe!
When a user's health factor drops below 1.0, anyone can liquidate their position and earn a 10% bonus.
┌─────────────────────────────────────────────────────────────┐
│ LIQUIDATION EXAMPLE │
├─────────────────────────────────────────────────────────────┤
│ │
│ Bob's Position (UNHEALTHY): │
│ • Collateral: 1 ETH @ $1500 = $1500 │
│ • Debt: $1000 DSC │
│ • Health Factor: ($1500 × 50%) / $1000 = 0.75 ❌ │
│ │
│ Alice Liquidates Bob: │
│ • Alice pays: $500 DSC (covering half Bob's debt) │
│ • Alice receives: $500 + 10% bonus = $550 worth of ETH │
│ • Alice profit: $50 🎉 │
│ │
│ Bob's New Position: │
│ • Collateral: $950 worth of ETH │
│ • Debt: $500 DSC │
│ • Health Factor: ($950 × 50%) / $500 = 0.95 (improved!) │
│ │
└─────────────────────────────────────────────────────────────┘
The protocol uses Chainlink price feeds with staleness checks to prevent attacks using outdated prices.
// If price data is older than 3 hours, the protocol FREEZES
uint256 private constant TIMEOUT = 3 hours;Why? Stale prices can lead to exploits:
Real ETH price: $1000 (crashed!)
Stale oracle: $2000 (old data)
Attacker deposits 1 ETH → Protocol thinks $2000
Attacker mints $1000 DSC → Protocol now UNDERCOLLATERALIZED! 💀
| Contract | Description | Lines |
|---|---|---|
DSCEngine.sol |
Core logic for collateral, minting, liquidation | ~700 |
DecentralizedStableCoin.sol |
ERC20 token with restricted mint/burn | ~60 |
OracleLib.sol |
Chainlink price feed wrapper with staleness check | ~50 |
User ──► DSCEngine ──► DecentralizedStableCoin
│
├──► Chainlink (ETH/USD)
│
└──► Chainlink (BTC/USD)
# Clone the repository
git clone https://github.com/moayaan1911/stablecoin
cd stablecoin
# Install dependencies
forge install
# Build
forge build# Run all tests
forge test
# Run with verbosity
forge test -vvv
# Run specific test
forge test --mt testDepositCollateral
# Run invariant tests
forge test --mt invariantThis project includes comprehensive testing:
test/
├── unit/
│ ├── DSCEngine.t.sol # Unit tests for DSCEngine (36 tests)
│ └── OracleLibTest.t.sol # Unit + Fuzz tests for OracleLib (9 tests)
├── fuzz/
│ ├── Handler.t.sol # Fuzz test handler
│ ├── Invariants.t.sol # Invariant tests (2 tests)
│ ├── OracleStalePriceFuzz.t.sol # Oracle integration fuzz tests (5 tests)
│ └── OpenInvariantsTest.t.sol # Open invariant tests
└── mocks/
├── ERC20Mock.sol # Mock ERC20 token
└── MockV3Aggregator.sol # Mock Chainlink price feed
| Category | Tests | Status |
|---|---|---|
| Unit Tests | 45 | ✅ Passing |
| Fuzz Tests | 5 | ✅ Passing |
| Invariant Tests | 2 | ✅ Passing |
| Total | 52 | ✅ All Passing |
The protocol maintains these invariants:
- Protocol Solvency: Total collateral value (USD) >= Total DSC minted
- Getter Stability: All getter functions should never revert
# Run invariant tests
forge test --mt invariant -vvv# Fuzz testing configuration (foundry.toml)
[invariant]
runs = 1000
depth = 128
fail_on_revert = true| Contract | Address | Etherscan |
|---|---|---|
| DecentralizedStableCoin (DSC) | 0x47AE250261B6142a9Eede69F17FA11DF3d11D5e6 |
View ↗ |
| DSCEngine | 0x93d8535A43bC44b28441A42945e14f1CD5871831 |
View ↗ |
| OracleLib | 0x165a43AF20746074D4dbe554AB02a77e0B3892ac |
View ↗ |
# Start local node
anvil
# Deploy
forge script script/DeployDSCEngine.s.sol --rpc-url http://localhost:8545 --broadcast# Set environment variables in .env
PRIVATE_KEY=0xyour_private_key
ALCHEMY=https://eth-sepolia.g.alchemy.com/v2/your_key
ETHERSCAN=your_etherscan_api_key
# Deploy & Verify
source .env && forge script script/DeployDSCEngine.s.sol --rpc-url $ALCHEMY --broadcast --verify --etherscan-api-key $ETHERSCAN| Issue | Description | Mitigation |
|---|---|---|
| Oracle Dependency | Relies on Chainlink | Staleness checks implemented |
| Flash Loan Attacks | Potential price manipulation | Overcollateralization helps |
| Smart Contract Risk | Code bugs | Extensive testing |
- ✅ Reentrancy protection (
nonReentrantmodifier) - ✅ Overcollateralization (200% minimum)
- ✅ Oracle staleness checks (3-hour timeout)
- ✅ Health factor validation on all operations
- ✅ Access control (only DSCEngine can mint/burn)
| Token | Mainnet Address | Price Feed |
|---|---|---|
| WETH | 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 |
ETH/USD |
| WBTC | 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599 |
BTC/USD |
| Parameter | Value | Description |
|---|---|---|
LIQUIDATION_THRESHOLD |
50% | Max borrowing power |
LIQUIDATION_BONUS |
10% | Liquidator reward |
MIN_HEALTH_FACTOR |
1e18 | Minimum safe health |
ORACLE_TIMEOUT |
3 hours | Staleness threshold |
stablecoin/
├── src/
│ ├── DSCEngine.sol # Core protocol logic
│ ├── DecentralizedStableCoin.sol # ERC20 stablecoin
│ └── libraries/
│ └── OracleLib.sol # Chainlink helper
├── script/
│ ├── DeployDSCEngine.s.sol # Deployment script
│ └── HelperConfig.s.sol # Network config
├── test/
│ ├── unit/ # Unit tests
│ ├── fuzz/ # Fuzz & invariant tests
│ └── mocks/ # Mock contracts
├── foundry.toml # Foundry config
└── README.md # This file!
This project was built following the Cyfrin Updraft course by Patrick Collins.
- Cyfrin Updraft - Advanced Foundry
- Foundry Documentation
- Chainlink Price Feeds
- OpenZeppelin Contracts
This project is licensed under the MIT License - see the LICENSE file for details.
Built with ❤️ by moayaan.eth
⭐ Star this repo if you found it helpful!
