2023-02-03 08:21:38 +01:00
|
|
|
pragma solidity >0.8.0;
|
|
|
|
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
|
|
|
contract EthFacuet {
|
|
|
|
|
|
|
|
address public owner;
|
|
|
|
address public registry;
|
|
|
|
address public periodChecker;
|
|
|
|
uint256 public sealState;
|
2023-02-03 12:41:48 +01:00
|
|
|
uint256 public amount;
|
2023-02-03 08:21:38 +01:00
|
|
|
|
|
|
|
uint8 constant REGISTRY_STATE = 1;
|
|
|
|
uint8 constant PERIODCHECKER_STATE = 2;
|
|
|
|
uint8 constant VALUE_STATE = 4;
|
|
|
|
uint256 constant public maxSealState = 7;
|
|
|
|
|
2023-02-03 12:41:48 +01:00
|
|
|
event FaucetUsed(address indexed _recipient, address indexed _token, uint256 _amount);
|
|
|
|
event FaucetFail(address indexed _recipient, address indexed _token, uint256 _amount);
|
|
|
|
event FaucetAmountChange(uint256 _amount);
|
2023-02-03 08:21:38 +01:00
|
|
|
event FaucetStateChange(uint256 indexed _sealState, address _registry, address _periodChecker);
|
2023-02-05 11:16:23 +01:00
|
|
|
event ImNotGassy();
|
2023-02-03 08:21:38 +01:00
|
|
|
|
|
|
|
constructor() {
|
|
|
|
owner = msg.sender;
|
|
|
|
}
|
|
|
|
|
|
|
|
function seal(uint256 _state) public returns(uint256) {
|
|
|
|
require(_state < 8, 'ERR_INVALID_STATE');
|
|
|
|
require(_state & sealState == 0, 'ERR_ALREADY_LOCKED');
|
|
|
|
sealState |= _state;
|
|
|
|
emit FaucetStateChange(sealState, registry, periodChecker);
|
|
|
|
return uint256(sealState);
|
|
|
|
}
|
|
|
|
|
2023-02-03 12:41:48 +01:00
|
|
|
function setAmount(uint256 _v) public returns(uint256) {
|
2023-02-03 08:21:38 +01:00
|
|
|
require(msg.sender == owner, 'ERR_NOT_OWNER');
|
|
|
|
require(sealState & VALUE_STATE == 0, 'ERR_SEALED');
|
2023-02-03 12:41:48 +01:00
|
|
|
amount = _v;
|
|
|
|
emit FaucetAmountChange(amount);
|
|
|
|
return amount;
|
2023-02-03 08:21:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function setPeriodChecker(address _checker) public {
|
|
|
|
require(msg.sender == owner, 'ERR_NOT_OWNER');
|
|
|
|
require(sealState & PERIODCHECKER_STATE == 0, 'ERR_SEALED');
|
|
|
|
periodChecker = _checker;
|
|
|
|
emit FaucetStateChange(sealState, registry, periodChecker);
|
|
|
|
}
|
|
|
|
|
|
|
|
function setRegistry(address _registry) public {
|
|
|
|
require(msg.sender == owner, 'ERR_NOT_OWNER');
|
|
|
|
require(sealState & REGISTRY_STATE == 0, 'ERR_SEALED');
|
|
|
|
registry = _registry;
|
|
|
|
emit FaucetStateChange(sealState, registry, periodChecker);
|
|
|
|
}
|
|
|
|
|
|
|
|
function checkPeriod(address _recipient) private returns(bool) {
|
|
|
|
bool _ok;
|
|
|
|
bytes memory _result;
|
|
|
|
|
|
|
|
(_ok, _result) = periodChecker.call(abi.encodeWithSignature("check(address)", _recipient));
|
|
|
|
if (!_ok) {
|
2023-02-03 17:02:27 +01:00
|
|
|
emit FaucetFail(_recipient, address(0), amount);
|
2023-02-03 08:21:38 +01:00
|
|
|
revert('ERR_PERIOD_BACKEND_ERROR');
|
|
|
|
}
|
|
|
|
if (_result[31] == 0) {
|
2023-02-03 17:02:27 +01:00
|
|
|
emit FaucetFail(_recipient, address(0), amount);
|
2023-02-03 08:21:38 +01:00
|
|
|
revert('ERR_PERIOD_CHECK');
|
|
|
|
}
|
2023-02-03 16:04:44 +01:00
|
|
|
|
|
|
|
(_ok, _result) = periodChecker.call(abi.encodeWithSignature("poke(address)", _recipient));
|
|
|
|
if (!_ok) {
|
|
|
|
emit FaucetFail(_recipient, address(0), amount);
|
2023-02-03 17:02:27 +01:00
|
|
|
revert('ERR_REGISTRY_BACKEND_ERROR');
|
2023-02-03 16:04:44 +01:00
|
|
|
}
|
2023-02-03 08:21:38 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function checkRegistry(address _recipient) private returns(bool) {
|
|
|
|
bool _ok;
|
|
|
|
bytes memory _result;
|
|
|
|
|
|
|
|
(_ok, _result) = registry.call(abi.encodeWithSignature("have(address)", _recipient));
|
|
|
|
if (!_ok) {
|
2023-02-03 12:41:48 +01:00
|
|
|
emit FaucetFail(_recipient, address(0), amount);
|
2023-02-03 08:21:38 +01:00
|
|
|
revert('ERR_TRANSFER');
|
|
|
|
}
|
2023-02-03 17:02:27 +01:00
|
|
|
if (_result[31] == 0) {
|
|
|
|
emit FaucetFail(_recipient, address(0), amount);
|
|
|
|
revert('ERR_REGISTRY_CHECK');
|
|
|
|
}
|
|
|
|
|
2023-02-03 12:41:48 +01:00
|
|
|
emit FaucetUsed(_recipient, address(0), amount);
|
2023-02-03 08:21:38 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-02-05 11:16:23 +01:00
|
|
|
function checkBalance() private {
|
|
|
|
if (amount > address(this).balance) {
|
|
|
|
emit ImNotGassy();
|
|
|
|
revert('ERR_ITSNOTAGAS');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-03 08:21:38 +01:00
|
|
|
function check(address _recipient) private returns(bool) {
|
|
|
|
if (periodChecker != address(0)) {
|
|
|
|
checkPeriod(_recipient);
|
|
|
|
}
|
|
|
|
if (registry != address(0)) {
|
|
|
|
checkRegistry(_recipient);
|
|
|
|
}
|
2023-02-05 11:16:23 +01:00
|
|
|
checkBalance();
|
2023-02-03 08:21:38 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-02-03 12:41:48 +01:00
|
|
|
function gimme() public returns(uint256) {
|
|
|
|
require(check(msg.sender));
|
|
|
|
payable(msg.sender).transfer(amount);
|
|
|
|
return amount;
|
2023-02-03 08:21:38 +01:00
|
|
|
}
|
|
|
|
|
2023-02-03 12:41:48 +01:00
|
|
|
function giveTo(address _recipient) public returns(uint256) {
|
|
|
|
require(check(_recipient));
|
|
|
|
payable(_recipient).transfer(amount);
|
|
|
|
return amount;
|
2023-02-03 08:21:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
receive () payable external {
|
|
|
|
}
|
|
|
|
}
|