eth-faucet/solidity/EthFaucet.sol

131 lines
3.5 KiB
Solidity
Raw Normal View History

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;
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);
event FaucetStateChange(uint256 indexed _sealState, address _registry, address _periodChecker);
2023-02-05 11:16:23 +01:00
event ImNotGassy();
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) {
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;
}
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);
revert('ERR_PERIOD_BACKEND_ERROR');
}
if (_result[31] == 0) {
2023-02-03 17:02:27 +01:00
emit FaucetFail(_recipient, address(0), amount);
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
}
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);
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);
return true;
}
2023-02-05 11:16:23 +01:00
function checkBalance() private {
if (amount > address(this).balance) {
emit ImNotGassy();
revert('ERR_ITSNOTAGAS');
}
}
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();
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 12:41:48 +01:00
function giveTo(address _recipient) public returns(uint256) {
require(check(_recipient));
payable(_recipient).transfer(amount);
return amount;
}
receive () payable external {
}
}