The Rate-Limited Token Faucet is a small but high-quality Solidity project designed to distribute ERC20 tokens to users while enforcing a cooldown period between claims. This prevents abuse and ensures fairness while keeping the system simple, auditable, and dependency-free.
The faucet is engineered with a strong focus on:
- clarity of logic
- security best practices
- ease of deployment
- practical usefulness for test environments
- educational value for new developers
This project is intentionally minimalistic but contains all the fundamentals of:
- access control
- rate limiting
- token transfers
- event logging
- administrative configuration
If you're learning Solidity or demonstrating smart contract mechanics, this is one of the best compact examples.
Faucets are essential in blockchain environments because:
To simulate transactions, staking, swapping, or other mechanics.
To run continuous testing of user journeys.
Rate limiting prevents draining by bots or malicious actors.
Perfect for giving students controlled access to tokens.
- access control
- storage mappings
- ERC20 interactions
- safe transfer patterns
This faucet is not a toy. It’s a realistic micro-application illustrating how production contracts should be structured.
Each user has their own individual timer:
lastClaimAt[user] → timestamp of last claim
cooldown → seconds required between claims
If cooldown is 86400 (24 hours), then:
now >= lastClaimAt[user] + 86400
must be true.
This prevents:
- faucet draining
- wallet spamming
- automated abuse
- repeated claims from bots
It’s a simple but powerful protection mechanism.
The faucet uses a minimal ERC20 interface, not OpenZeppelin.
Why?
- Works with ANY ERC20
- Zero import errors
- 100% transparent
- Easy to audit
- Perfect for education
This is intentional: the contract shows the essentials of interacting with tokens, purely, clearly, without wrappers.
The owner can:
- update dripAmount
- update cooldown
- withdraw tokens
- transfer ownership
This matches real-world patterns in production contracts:
- admin role
- controlled configuration
- safe withdrawal flows
This reflects how DeFi protocols manage adjustable parameters.
Every change emits events:
ClaimedDripAmountUpdatedCooldownUpdatedOwnershipTransferredTokensWithdrawn
This enables:
- dApp UI tracking
- indexer integration
- historical audits
- backend automation
Events are crucial in blockchain architecture, and this faucet demonstrates their correct use.
The entire contract fits into a single file and follows these best practices:
- single-responsibility functions
- well-labeled sections
- no inline assembly
- no hidden burn/mint logic
- no modifiers except
onlyOwner - clear require statements
- explicit error messages
This is how professional contracts are structured for clarity.
Below is a conceptual breakdown of every component.
IERC20 public immutable token;
A direct pointer to the ERC20 being distributed.
Immutable → cannot be changed after deployment → safer.
address public owner;
Only owner can modify faucet settings.
dripAmount| how many tokens per claimcooldown| how many seconds between claims
mapping(address => uint256) public lastClaimAt;
Tracks timestamps for every user.
- token
- drip amount
- cooldown
- owner
It also validates critical values:
- token cannot be zero
- drip amount must be > 0
This prevents “broken faucet” deployments.
The most important flow:
1. Check cooldown
2. Check faucet has tokens
3. Update user timestamp
4. Transfer tokens
5. Emit event
Each step is independent, safe, and ordered correctly.
Admin functions include:
- parameter updates
- withdraw tokens
- transfer ownership
They are gated by:
modifier onlyOwner()
A classic access-control pattern.
lastClaimAt[msg.sender] = now; (before transfer)
This prevents reentrancy issues.
Reduces attack surface.
Avoids failed-state scenarios.
Vital for debugging.
rate-limited-token-faucet/
│
├── contracts/
│ └── RateLimitedFaucet.sol # main faucet contract
│
├── README.md # documentation (this file)
├── .gitignore # standard ignores
└── (optional future additions)
├── scripts/ # deployment scripts
├── test/ # Hardhat/Foundry tests
└── frontend/ # simple UI
This structure is compatible with ALL major dev tools.
-
Drag your folder into Remix
-
Open
RateLimitedFaucet.sol -
Compile with
0.8.20 -
Deploy with parameters:
- token address
- drip amount
- cooldown seconds
-
Fund the faucet with tokens
-
Call
claim()
npx hardhat compile
npx hardhat run scripts/deploy.js --network sepolia
I can generate this script for you if you want.
forge build
forge create ... RateLimitedFaucet --constructor-args <token> <drip> <cooldown>
Foundry support can be added with one command:
forge init
Give users tokens to try your contract:
- staking
- swapping
- governance voting
Students always need test tokens for exercises.
QA pipelines can call faucet in:
- local Anvil chains
- CI testing
- integration workflows
Perfect for hackathons or prototype demos.
If you build DeFi protocols locally, you can use this faucet instead of manually minting tokens.
Drip 5 tokens every 24 hours:
dripAmount = 5e18
cooldown = 86400
Allow unlimited claims:
setCooldown(0)
Useful in local testing environments.
Drip 1 token every 7 days:
dripAmount = 1e18
cooldown = 604800
Prevents draining and spreads token usage across weeks.
Owner can gracefully remove tokens:
withdrawTokens(owner, faucetBalance)
Then set:
setDripAmount(0)
(optional, to disable claiming)
This faucet is safe for test environments but comes with known constraints:
Users can create multiple wallets to bypass cooldown.
Mitigation (optional upgrade):
- address whitelist
- social login faucet
- IP-based rate limiting (off-chain)
- maintain on testnets only
Owner can:
- withdraw tokens
- change drip amount
- change cooldown
This is desired for faucet management, but not suited for mainnet or financial use.
Some ERC20 tokens are non-standard (fees, rebasing).
This faucet assumes:
transfer()returnstrue- no fees based on transfer
If you need support for fee-on-transfer tokens, I can modify the contract.
Faucet does not mint tokens → must be funded.
If you want a V2 or V3 version:
I can build any version you want.
This project is released under the MIT License, allowing unrestricted use, modification, distribution, and commercial utilization.
Contributions, improvements, and feature requests are welcome.
If you're learning Solidity → fork this repo. If you're teaching → use this as a classroom example. If you're building → integrate this faucet into your test flows.