Create a crypto faucet using a Solidity smart contract

In this tutorial we will create two crypto currency faucet smart contracts. The first faucet contract allows users to request free ETH to be sent to a wallet. The second faucet contract creates an ERC20 token and allow users to request free ERC20 tokens. Both faucets have a time lock feature that prevents users from making the same request multiple time per day. We will write these contracts in Solidity and deploy them to the Ethereum blockchain.

What is a faucet?

A crypto currency faucet is a system that dispenses tokens to users upon request. Just like small drops of water dripping from a faucet a crypto faucet drips small amounts of tokens to requestors. Tokens from a faucet are free or are awarded for performing tasks on the internet. Consequently, faucets are a great way to distribute tokens to users all around the world or in the metaverse.

How do crypto currency faucets work?

A crypto faucet is a system where a user makes a request on a website for free tokens. The user might perform a task such as clicking on an advertisement, watching a video or taking a survey and as a reward the user earns free crypto currency. It should be noted that to use a faucet every participant has to supply their wallet address to receive token rewards. Users will follow the directions on the faucet website in order for the system to transfer tokens to their wallet.

Websites and mobile applications running crypto faucets generally configure a threshold of a specified number of tokens to be awarded each day for each user. For example a faucet might allow 100 tokens to be claimed per day and each wallet can only claim 1 token. So this system would distribute 1 token to 100 unique wallets per day. In addition, a minimum payment threshold could be set before the collected rewards can be claimed by the user. For example the user must claim 5 tokens before a payment is processed.

Some crypto currency faucets have the following process flow:

crypto currency faucet process flow. Request free tokens ETH or ERC20. Metaverse

Crypto faucets have all different types of uses and implementations. They can be implemented in a simple website or you can be creative and implement a crypto dispensary in the metaverse.

Create a crypto faucet to dispense ETH

First, lets create a simple faucet contract that dispenses ETH when a user makes a request. The ETH faucet contract below contains the following features:

  • Contract has an owner that can be changed
  • Has a configurable amount of ETH to dispense to each requested wallet
  • Supports donations to the faucet
  • Keeps track of addresses requesting ETH
  • Requestors can request ETH only one time per day

To illustrate the features above read the comments in the code to understand how this ETH faucet contract works.

pragma solidity ^0.8.3;

contract faucet {
	

    //state variable to keep track of owner and amount of ETHER to dispense
    address public owner;
    uint public amountAllowed = 1000000000000000000;


    //mapping to keep track of requested rokens
    //Address and blocktime + 1 day is saved in TimeLock
    mapping(address => uint) public lockTime;


    //constructor to set the owner
	constructor() payable {
		owner = msg.sender;
	}

    //function modifier
    modifier onlyOwner {
        require(msg.sender == owner, "Only owner can call this function.");
        _; 
    }


    //function to change the owner.  Only the owner of the contract can call this function
    function setOwner(address newOwner) public onlyOwner {
        owner = newOwner;
    }


    //function to set the amount allowable to be claimed. Only the owner can call this function
    function setAmountallowed(uint newAmountAllowed) public onlyOwner {
        amountAllowed = newAmountAllowed;
    }


    //function to donate funds to the faucet contract
	function donateTofaucet() public payable {
	}


    //function to send tokens from faucet to an address
    function requestTokens(address payable _requestor) public payable {

        //perform a few checks to make sure function can execute
        require(block.timestamp > lockTime[msg.sender], "lock time has not expired. Please try again later");
        require(address(this).balance > amountAllowed, "Not enough funds in the faucet. Please donate");

        //if the balance of this contract is greater then the requested amount send funds
        _requestor.transfer(amountAllowed);        
 
        //updates locktime 1 day from now
        lockTime[msg.sender] = block.timestamp + 1 days;
    }
}

Try it in Remix

Make a crypto faucet to dispense an ERC20 token

Second, lets create a faucet contract for an ERC20 token. ERC20 token faucets are similar in concept to the contract above but their contract structure could be different. The ERC20 faucet contract below contains the following features:

  • Unlike the contract above the contract below creates an ERC20 token
  • You can name and create a symbol for the token
  • It inherits all of the functions of the Open Zepplin ERC20 contract
  • The owner mints tokens in the constructor
  • It keeps track of addresses requesting the ERC20 token
  • Requestors can request the ERC20 token only one time per day

To illustrate the features above read the comments in the code to understand how the process of an ERC20 faucet contract works. Read the request token function to see how it differs from the contract above.

pragma solidity ^0.8.3;

//import Open Zepplins ERC-20 contract
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol";

//create a sample token that inherits Open Zepplins ERC-20 contract
contract sampleToken is ERC20 {

    uint public amountAllowed = 1000000000000000000;

    //when deploying the token give it a name and symbol
    //specify the amount of tokens minted for the owner
    constructor(string memory name, string memory symbol) ERC20(name, symbol) {
        _mint(msg.sender, 50000000 * (10 ** 18));
    }

    //when you requestTokens address and blocktime+1 day is saved in Time Lock
    mapping(address => uint) public lockTime;

    //allow users to call the requestTokens function to mint tokens
    function requestTokens (address requestor , uint amount) external {
        
        //perform a few check to make sure function can execute
        require(block.timestamp > lockTime[msg.sender], "lock time has not expired. Please try again later");
        
        //mint tokens
        _mint(requestor, amount);

        //updates locktime 1 day from now
        lockTime[msg.sender] = block.timestamp + 1 days;
    }
}

Try it in Remix

In Summary, the above contracts are two examples of how to create a crypto faucet to dispense ETH or an ERC20 token. These are very simple Solidity smart contracts to help you understand the concepts of crypto currency faucets. Modify the contracts above to meet your use case. Whether you have a simple website or you want to create a crypto dispensary in the metaverse the use cases are endless.

Finally, remember that this code is for learning and entertainment purposes only. The code has not been audited and use at your own risk. Remember smart contracts are experimental and could contain bugs.

Resources

Blockchain Networks

Below is a list of EVM compatible Mainnet and Testnet blockchain networks. Each link contains network configuration, links to multiple faucets for test ETH and tokens, bridge details, and technical resources for each blockchain. Basically everything you need to test and deploy smart contracts or decentralized applications on each chain. For a list of popular Ethereum forums and chat applications click here.

Ethereum test network configuration and test ETH faucet information
Optimistic Ethereum Mainnet and Testnet configuration, bridge details, etc.
Polygon network Mainnet and Testnet configuration, faucets for test MATIC tokens, bridge details, etc.
Binance Smart Chain Mainnet and Testnet configuration, faucets for test BNB tokens, bridge details, etc.
Fanton networt Mainnet and Testnet configuration, faucets for test FTM tokens, bridge details, etc.
Kucoin Chain Mainnet and Testnet configuration, faucets for test KCS tokens, bridge details, etc.

Web3 Software Libraries

You can use the following libraries to interact with an EVM compatible blockchain.

Nodes

Learn how to run a Geth node. Read getting started with Geth to run an Ethereum node.

Fix a transaction

How to fix a pending transaction stuck on Ethereum or EVM compatible chain

Next Review – Implement Upkeep using Chainlink Keepers