A flash loan protocol for ERC20 tokens with proportional fee sharing among liquidity providers. Built using OpenZeppelin's battle-tested contracts with comprehensive precision attack protections and reviewed by AI systems, but requires professional audit before production use.
- π Flash Loans: Instant, uncollateralized loans for MEV operations
- π― Multi-Token Flash Loans: Borrow multiple tokens simultaneously in a single transaction
- π° Fee Sharing: Proportional fee distribution among liquidity providers
- π Fee Harvesting: Withdraw earned fees while keeping principal staked for compound growth
- π³οΈ Democratic Governance: LPs vote on fee rates with share-weighted voting
- β° Delayed Execution: 10-block delay for governance decisions
- π‘οΈ Security First: Comprehensive protection against precision attacks and common DeFi exploits
- β‘ Ultra-Low Fees: Default 0.01% LP fee with 1% of it as management fee (as % of LP fee)
- οΏ½ Emergency Pause (Withdraw-Only): Owner can enable withdraw-only mode during incidents
- β Non-Upgradeable: Fixed implementation; migrations happen via pause β withdraw β redeploy
- π Share-Based: Fair fee distribution using share-based accounting with virtual shares protection
- π Advanced Executors: Gas-optimized executor contracts for complex multi-step operations
Potential APY ranges from 1-10% (conservative) to 50-200%+ (high utilization) depending on flash loan adoption and fee governance.
π View Detailed ROI Analysis
- β Virtual Shares: A minimal amount of virtual shares minted to owner on first deposit to prevent share manipulation
- β Minimum Deposit: 100M wei (1e8) minimum deposit requirement to make dust attacks uneconomical
- β Fixed Entry/Exit Fees: 100 wei fixed fees (not percentage-based) that accumulate as permanent dust
- β Minimum Withdrawal: Rejects withdrawals below minimum threshold after exit fees
- β Precision Loss Prevention: Direct fee calculation without nested division to prevent rounding manipulation
- β Reentrancy protection
- β Share dilution attack prevention
- β Arithmetic underflow/overflow protection
- β Interface compliance checking
- β Fee caps and validation
- β Share-weighted governance voting
- β Time-delayed execution system
- β Proposal validation and cleanup
npm installnpm run build# Run all tests
npm run test
# Run with gas reporting
npm run test:gas
# Run with coverage
npm run test:coverage# Local deployment
npm run deploy:localhost
# Testnet deployment
npm run deploy:sepolia
# Mainnet deployment
npm run deploy:mainnetdeposit(token, amount)- Deposit tokens to earn feeswithdraw(token)- Withdraw principal + accumulated feeswithdrawFees(token)- Withdraw only fees while keeping principal stakedflashLoan(token, amount, receiver, data)- Execute single-token flash loanflashLoanMultiple(tokens[], amounts[], receiver, data)- Execute multi-token flash loan
setManagementFee(percentage)- Set management fee as % of LP fee (1-5%)withdrawManagementFees(token)- Withdraw collected feesemergencyPause()- Toggle emergency pause (withdraw-only mode)
voteForLPFee(token, feeAmountBps)- Vote for LP fee amount (share-weighted)proposeLPFeeChange(token, newFeeBps)- Propose fee change based on governanceexecuteLPFeeChange(token, newFeeBps)- Execute approved fee change after delay
getWithdrawableAmount(token, user)- Preview withdrawal amountgetEffectiveLPFee(token)- Get current LP fee rate
| Fee Type | Default Rate | Range | Description |
|---|---|---|---|
| LP Fee | 0.01% (1 bps) | 0-1% (0-100 bps) | Goes to liquidity providers (set by LP governance) |
| Management Fee | 1% of LP fee | 1-5% of LP fee | Percentage of LP fee that goes to protocol owner |
| Entry/Exit Fee | 100 wei (fixed) | Fixed | Precision attack protection |
π View Usage Examples
- π§ Flash Loan Executors: Gas-optimized contracts for multi-operation flash loans
- π Multi-Token Flash Loans: Borrow multiple tokens simultaneously (see contract docs)
- π° Fee Harvesting: Withdraw earned fees while keeping principal staked (see contract docs)
π Flash Loan Executors Guide | ERC20FlashLender Contract
- Copy
.env.exampleto.env - Fill in your private keys and RPC URLs
- Install dependencies:
npm install
# Development
npm run build # Compile contracts
npm run clean # Clean artifacts
npm run typechain # Generate TypeScript bindings
# Testing
npm run test # Run tests
npm run test:coverage # Coverage report
npm run test:gas # Gas usage report
# Code Quality
npm run lint # Lint Solidity code
npm run format # Format all code
# Local Development Environment
npm run node # Start local Hardhat node
npm run deploy:dev # Deploy with test tokens & setup (localhost)
# Production Deployment
npm run deploy:localhost # Deploy to localhost
npm run deploy:sepolia # Deploy to Sepolia
npm run deploy:mainnet # Deploy to Mainnet
# Verification
npm run verify:sepolia # Verify on Sepolia
npm run verify:mainnet # Verify on MainnetThe project provides three development scripts for different workflows:
npm run devRuns the complete development stack - compiles contracts, starts Hardhat node, deploys contracts, and launches the React app.
npm run dev:appStarts only the React development server. Use this when developing frontend features with the GitHub Pages deployed contracts.
npm run dev:nodeStarts only the Hardhat node with deployed contracts. Use this to connect the GitHub Pages app to your local blockchain for testing.
The full development script (npm run dev) will:
- π¦ Deploy the ERC20FlashLender contract
- πͺ Deploy 4 test tokens (TUSDC, TDAI, TWETH, TWBTC) with different decimals
- π₯ Set up 4 test accounts with token balances
- π° Make initial deposits to get the pools started
- π Save deployment info to
deployment-dev.json - π§ Provide ready-to-use contract interaction snippets
Test Tokens Deployed:
- TUSDC (6 decimals): Test USDC - 1B supply
- TDAI (18 decimals): Test DAI - 1B supply
- TWETH (18 decimals): Test WETH - 100K supply
- TWBTC (8 decimals): Test WBTC - 21K supply
Test Accounts Setup:
- Deployer: Contract owner with all permissions
- User1, User2, User3: Each gets 10K of every test token
This setup provides a complete local testing environment with realistic token scenarios and pre-funded accounts for immediate testing of flash loans, deposits, withdrawals, and governance features.
The project includes a comprehensive React-based decentralized application (DApp) that provides a user-friendly interface for interacting with the ERC20 Flash Lender protocol.
- π¨ Modern UI/UX: Built with React 18 and modern design patterns
- π Web3 Integration: Seamless wallet connection via RainbowKit and Wagmi
- π Real-time Dashboard: Live pool statistics, user positions, and earnings tracking
- π° Pool Management: Deposit, withdraw, and harvest fees with intuitive controls
- π³οΈ Governance Interface: Vote on fee rates and propose changes through the UI
- π Activity Tracking: Comprehensive transaction history and analytics
- π Theme Support: Light/dark mode with user preferences
- β‘ Performance Optimized: Lazy loading, memoization, and code splitting
- π‘οΈ Error Boundaries: Graceful error handling with fallback UI
- π Web3 Security: Built-in provider validation and secure transaction handling
- π± Responsive Design: Works seamlessly on desktop and mobile devices
# Option 1: Full development environment (recommended)
npm run dev
# Option 2: Frontend development only (uses GitHub Pages contracts)
npm run dev:app
# Option 3: Build for production
cd app && npm run buildapp/
βββ src/
β βββ components/ # React components
β β βββ common/ # Reusable UI components
β β βββ pages/ # Page-level components
β βββ context/ # React context providers
β βββ hooks/ # Custom React hooks
β βββ services/ # Data services and API layers
β βββ utils/ # Utility functions and constants
β βββ types/ # TypeScript type definitions
βββ public/ # Static assets
βββ package.json # Dependencies and scripts
The DApp automatically detects your network and connects to the appropriate contracts.
For full local development:
npm run dev # All-in-one: compile, deploy, and start appFor frontend-only development:
npm run dev:app # Uses GitHub Pages deployed contractsFor testing GitHub Pages app with local blockchain:
npm run dev:node # Start local node, then use GitHub Pages appConnect MetaMask to localhost:8545 when using local development options.
For detailed frontend documentation, component guides, and development setup, see app/README.md.
This DApp is wallet-only by design:
- No hosted/public RPCs are used for reads or writes.
- A user wallet provider (e.g., MetaMask via window.ethereum) is required to load data and interact.
- Server-side rendering is disabled to avoid any backend RPC dependencies.
- If no wallet is connected, the UI will show a connect-wallet prompt and will not perform chain queries until connected.
ERC20FlashLender
βββ Liquidity Management
β βββ deposit() - Add tokens to pool (min 100M wei, 100 wei entry fee)
β βββ withdraw() - Remove tokens + fees (100 wei exit fee, min threshold check)
β βββ Share-based accounting with virtual shares (1000 virtual shares)
β βββ Precision attack protections
βββ Flash Loans
β βββ flashLoan() - Execute single-token loan
β βββ flashLoanMultiple() - Execute multi-token loan (up to 20 tokens)
β βββ Interface validation (IFlashLoanReceiver & IMultiFlashLoanReceiver)
β βββ Fee collection with precision fixes
β βββ Duplicate token detection
β βββ Minimum fee enforcement for large loans
βββ LP Governance
β βββ voteForLPFee() - Share-weighted voting (including virtual shares)
β βββ proposeLPFeeChange() - Democratic proposals
β βββ executeLPFeeChange() - Delayed execution
βββ Administration
β βββ Management fee control (1-5% of LP fee)
β βββ Emergency pause (withdraw-only mode)
β βββ Owner functions (limited scope)
βββ Security Layer
βββ Virtual shares dilution (VIRTUAL_SHARES = 1000)
βββ Minimum deposit enforcement (MINIMUM_DEPOSIT = 1e8)
βββ Fixed fee dust accumulation (ENTRY_EXIT_FEE = 100 wei)
βββ Multi-token validation and gas limits
βββ Withdrawal validation and thresholds
THIS CONTRACT HAS NOT BEEN PROFESSIONALLY AUDITED
- β No professional security audit performed
- β AI-assisted code review completed
- β Built on OpenZeppelin's audited contracts
- β Comprehensive test suite (75+ passing tests)
- β Security best practices implemented
- β Precision attack protections implemented
DO NOT USE WITH REAL FUNDS ON MAINNET WITHOUT A PROFESSIONAL AUDIT
- Unaudited code risk - Primary concern
- Smart contract risk
- Admin key risk (management fees and pause authority)
- Liquidity risk
- Governance manipulation risk (voting power concentration)
- Time delay risks (governance proposals can be front-run)
- Oracle dependencies (if added)
This protocol implements comprehensive protections against precision-based attacks:
-
Virtual Shares (1000): Automatically minted to owner on first deposit
- Dilutes small attackers' ability to manipulate share calculations
- Makes it impossible to achieve meaningful ownership with dust amounts
-
Minimum Deposit (100M wei): Enforced on all deposits
- Makes dust attacks economically unviable
- Ensures meaningful stake for all participants
-
Fixed Entry/Exit Fees (100 wei each):
- Not percentage-based, creates permanent dust accumulation
- Reduces profitability of repeated small operations
- Acts as economic deterrent for precision attacks
-
Minimum Withdrawal Validation:
- Rejects withdrawals below minimum threshold after exit fees
- Prevents dust withdrawals that could be used for manipulation
-
Precision-Safe Fee Calculations:
- Direct multiplication instead of nested division
- Prevents rounding manipulation in fee calculations
These protections work together to make precision attacks both technically difficult and economically unviable.
- Use multisig for owner/pauser accounts
- Implement time locks for configuration changes where feasible (pause remains immediate)
- Monitor for unusual activity
- Keep emergency procedures ready
The protocol is non-upgradeable and includes an emergency pause that switches the system to withdraw-only mode to protect users during incidents.
What the pause does:
- Disables:
deposit,flashLoan,flashLoanMultiple,withdrawFees, governance actions (voteForLPFee,proposeLPFeeChange,executeLPFeeChange). - Allows:
withdrawof principal + accumulated fees, read-only views, ownerwithdrawManagementFees(optional policy to pause this, but current implementation allows owner-only).
Who can pause:
- The contract owner (strongly recommended to be a multisig). Function:
emergencyPause()toggles the state.
How to verify pause state:
- Call
paused()on the lender contract;truemeans withdraw-only mode is active.
Suggested incident flow:
- Detect anomaly β call
emergencyPause()to enable withdraw-only mode. - Communicate status and guidance to LPs (withdraw if necessary).
- Diagnose and decide whether to unpause or migrate.
- For migrations: keep paused, deploy a new version, publish addresses, guide users to withdraw from old and deposit into new.
- Unpause only when risk is cleared or migration is complete.
- Efficient share-based accounting
- Minimal storage operations
- Optimized compiler settings
- Gas reporter integration
GPL-3.0-or-later License - see LICENSE file for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request