Skip to content
Contract · Utilities

Faucet

Simple token faucet with cooldown. Ideal for classrooms and BSC Testnet drips.

All templates
Testnet
~700k gas
BNB Smart Chain
Post-deploy checklist
  1. Prefer BSC Testnet for public faucets
  2. Set drip amount and cooldown thoughtfully
  3. Fund the contract after deploy
  4. Monitor balance so the faucet does not run dry mid-event
Configure & deploy

BNB20 to drip, or zero address to drip native BNB.

Amount per claim in wei (1e17 = 0.1).

Minimum seconds between claims per address.

Use cases
  • Classroom labs
  • Testnet community drips
  • Hackathon starter kits
TokenFaucet.solsolidity
// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0 (Wizard / Contracts MCP patterns)
// Compiled with Solidity ^0.8.24 — BNB Toolset browser solc
pragma solidity ^0.8.24;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract TokenFaucet is Ownable {
    using SafeERC20 for IERC20;

    IERC20 public immutable token; // address(0) = native BNB
    uint256 public dripAmount;
    uint256 public cooldown;
    mapping(address => uint256) public lastClaim;

    constructor(address initialOwner, IERC20 _token, uint256 _drip, uint256 _cooldown)
        Ownable(initialOwner)
    {
        token = _token;
        dripAmount = _drip;
        cooldown = _cooldown;
    }

    receive() external payable {}

    function claim() external {
        require(block.timestamp >= lastClaim[msg.sender] + cooldown, "cooldown");
        lastClaim[msg.sender] = block.timestamp;
        if (address(token) == address(0)) {
            require(address(this).balance >= dripAmount, "empty");
            (bool ok,) = msg.sender.call{value: dripAmount}("");
            require(ok, "bnb transfer failed");
        } else {
            token.safeTransfer(msg.sender, dripAmount);
        }
    }

    function setDrip(uint256 _drip) external onlyOwner { dripAmount = _drip; }
    function setCooldown(uint256 _cd) external onlyOwner { cooldown = _cd; }
}