// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; /** * @title AereFaucet * @notice Distributes small amounts of AERE to new users for gas. * Cooldown per address; configurable drip and cooldown by owner. * Funded by the foundation (or anyone) by sending AERE directly. */ contract AereFaucet is Ownable, ReentrancyGuard { uint256 public dripAmount = 0.05 ether; // 0.05 AERE uint64 public cooldown = 1 days; mapping(address => uint64) public lastClaim; event Dripped(address indexed to, uint256 amount); event Funded(address indexed from, uint256 amount); event ConfigUpdated(uint256 dripAmount, uint64 cooldown); receive() external payable { emit Funded(msg.sender, msg.value); } function claim() external nonReentrant { require(block.timestamp - lastClaim[msg.sender] >= cooldown, "cooldown"); require(address(this).balance >= dripAmount, "dry"); lastClaim[msg.sender] = uint64(block.timestamp); (bool ok, ) = msg.sender.call{value: dripAmount}(""); require(ok, "transfer"); emit Dripped(msg.sender, dripAmount); } function setConfig(uint256 _drip, uint64 _cooldown) external onlyOwner { require(_drip > 0 && _cooldown >= 1 hours, "params"); dripAmount = _drip; cooldown = _cooldown; emit ConfigUpdated(_drip, _cooldown); } function nextClaimAt(address user) external view returns (uint64) { uint64 last = lastClaim[user]; if (last == 0) return uint64(block.timestamp); return last + cooldown; } }