// SPDX-License-Identifier: MIT pragma solidity 0.8.16; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; error UnmatchedLengths(); contract RollaFaucet is AccessControl { using SafeERC20 for IERC20; mapping(address => uint256) public asset_maxValue; address public whitelist; bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); event FaucetTransfer(address token, uint256 amount, address to, uint256 timestamp); constructor() { _setupRole(ADMIN_ROLE, msg.sender); } function multiTransfer(address to, address[] calldata token, uint256[] calldata amount) public { uint256 length = token.length; if (length != amount.length) { revert UnmatchedLengths(); } for (uint256 i = 0; i < length;) { transfer(to, token[i], amount[i]); unchecked { i++; } } } function transfer(address to, address token, uint256 amount) public { require(msg.sender == whitelist || whitelist == address(0), "Faucet: caller not whitelisted"); require(IERC20(token).balanceOf(to) + amount <= asset_maxValue[token], "Faucet: excessive funds transfer"); // Check existing balance of the user IERC20(token).safeTransfer(to, amount); emit FaucetTransfer(token, amount, to, block.timestamp); } function getFaucetBalance(address token) public view returns (uint256 balance) { return IERC20(token).balanceOf(address(this)); } function getTokenBalanceOf(address token, address user) public view returns (uint256 balance) { return IERC20(token).balanceOf(user); } function setMaxValue(address token, uint256 maxTransferValue) public { require(hasRole(ADMIN_ROLE, msg.sender), "Faucet: caller not an admin"); asset_maxValue[token] = maxTransferValue; } function withdrawNativeToken() public { require(hasRole(ADMIN_ROLE, msg.sender), "Faucet: caller not an admin"); (bool success,) = msg.sender.call{value: address(this).balance}(""); require(success, "Faucet: withdrawal successful"); } function setWhitelistAddress(address whitelistAddress) public { require(hasRole(ADMIN_ROLE, msg.sender), "Faucet: caller not an admin"); whitelist = whitelistAddress; } receive() external payable {} }