代币水龙头

ERC20 代币水龙头 #

1 需求描述 #

  1. 实现一个合约,用来发放 ERC20 代币;
  2. 用户可以调用合约中的 requestForCoin 函数来领取 perAmount 代币,每个 address 只能领取一次;
  3. requestForCoin 函数被调用时,触发 SendToken 事件,以记录领取代币的用户 address 及领取的额度 amount
  4. 合约发放的代币总数为 totalAmount
  5. 代币合约、perAmounttotalAmount 均在合约部署时初始化。

2 代码实现 #

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract Faucet {
    // 代币合约
    IERC20 myCoin;
    // 可领取代币总数额
    uint256 totalAmount;
    // 每次可领取代币数额
    uint256 perAmount;
    // 领取记录表,领取过的地址记录为true
    mapping(address => bool) requestedMap;

    /*
    * 构造函数,初始化代币合约地址、可领取总数额、每次领取数额
    */
    constructor(address _contractAddress, uint256 _totalAmount, uint256 _perAmount) {
        myCoin = IERC20(_contractAddress);
        totalAmount = _totalAmount;
        perAmount = _perAmount;
    }

    /*
    * 领取代币时触发事件
    */
    event SendToken(address indexed receiver, uint256 indexed amount);

    /*
    * 领取代币
    */
    function requestForCoin() external returns(bool) {
        require(!requestedMap[msg.sender], "You can only request once!");
        require(totalAmount >= perAmount, "Faucet Empty!");
        myCoin.transfer(msg.sender, perAmount);
        totalAmount -= perAmount;
        emit SendToken(msg.sender, perAmount);
        return true;
    }
}