Overview
TheFundMe contract is a production-grade crowdfunding smart contract that accepts ETH donations with a minimum USD value requirement. It uses Chainlink Oracle to get real-time ETH/USD price data from the Sepolia testnet.
Key Features:
- Accept ETH donations with minimum $5 USD value
- Track all funders and amounts contributed
- Owner-only withdrawal functionality
- Real-time USD conversion using Chainlink Price Feeds
- Gas-optimized with
constantandimmutablevariables - Custom errors for efficient error handling
- Automatic funding via
receive()andfallback()functions
This contract is deployed on the Sepolia testnet and uses the Chainlink ETH/USD price feed at
0x694AA1769357215DE4FAC081bf1f309aDC325306.Contract Architecture
The FundMe system consists of two components:- FundMe.sol - Main contract with funding and withdrawal logic
- PriceConverter.sol - Library for ETH to USD conversion using Chainlink
FundMe Contract
State Variables
MINIMUM_USD- Minimum donation of $5 (in wei, 18 decimals)funders- Array of all unique funder addressesaddressToAmountFunded- Tracks total amount funded by each addressi_owner- Contract deployer address (immutable for gas savings)
Gas Optimization:
constantvariables are replaced at compile-time (cheapest)immutablevariables are set once at deployment (cheaper than storage)- Naming convention:
i_prefix for immutable,ALL_CAPSfor constants
Custom Error
require statements with string messages.
Constructor
Core Functions
fund()
- Converts sent ETH to USD using Chainlink price feed
- Requires at least $5 USD equivalent
- Adds sender to funders array
- Updates the amount funded by the sender
public payable - Can receive ETH
withdraw()
- Resets all funder balances to 0
- Clears the funders array
- Transfers entire contract balance to owner using
.call()
onlyOwner - Only contract owner can withdraw
ETH Transfer Methods:
The contract shows three methods (commented code included):
transfer()- 2300 gas limit, reverts on failuresend()- 2300 gas limit, returns boolcall()- No gas limit, returns bool (recommended)
.call() as it’s the most flexible and secure method.Modifier: onlyOwner
receive() and fallback()
fund() when ETH is sent directly to the contract.
receive()- Called when ETH is sent with empty calldatafallback()- Called when function signature doesn’t match or with data
PriceConverter Library
A library that provides USD conversion functionality using Chainlink.Key Functions
getPrice()
getPrice()
Fetches the current ETH/USD price from Chainlink.Returns: ETH price in USD with 18 decimals (e.g., 2000e18 = $2000)The Chainlink feed returns 8 decimals, so we multiply by 1e10 to get 18 decimals for consistency.
getConversionRate(uint256 ethAmount)
getConversionRate(uint256 ethAmount)
Converts an ETH amount to its USD value.Parameters:
ethAmount- Amount of ETH in wei
(ethPrice * ethAmount) / 1e18getVersion()
getVersion()
Returns the version of the Chainlink price feed contract.Useful for debugging and verifying the correct feed is being used.
Using Libraries
uint256 variables:
Full Contract Code
Usage Examples
- Fund the Contract
- Check Funding
- Withdraw (Owner Only)
- Price Conversion
Concepts Demonstrated
Chainlink Oracles
Get real-world data (ETH/USD price) from decentralized oracle networks.
Libraries
Reusable code with
using ... for syntax to extend types.Gas Optimization
Use
constant and immutable to reduce storage costs.Access Control
Custom modifiers and errors for permission management.
Payable Functions
Accept and manage ETH transfers with
payable keyword.Special Functions
receive() and fallback() for direct ETH transfers.Key Takeaways
FundMe demonstrates production-ready patterns:
- Integration with Chainlink oracles for real-world data
- Using libraries with
using ... forsyntax - Gas optimization with
constantandimmutable - Custom errors vs
requirewith strings (50% gas savings) - Owner-only functions with modifiers
- Safe ETH transfers using
.call() - Automatic funding with
receive()andfallback() - Proper access control patterns
Security Considerations
This contract is designed for educational purposes on the Sepolia testnet. For mainnet deployment, consider additional security measures like audits, testing, and upgradability patterns.
Chainlink Integration
The contract uses Chainlink’s decentralized oracle network: Sepolia ETH/USD Price Feed:- Address:
0x694AA1769357215DE4FAC081bf1f309aDC325306 - Network: Ethereum Sepolia Testnet
- Decimals: 8 (converted to 18 in the library)
Chainlink Price Feeds provide tamper-proof, high-quality price data aggregated from multiple sources. They’re the industry standard for DeFi applications.Learn more at docs.chain.link