ERC20Faucet.sol (3654B)
1 pragma solidity >=0.8.0; 2 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 5 contract SingleShotFaucet { 6 address public token; 7 address store; 8 address accountsIndex; 9 uint256 constant cooldownDisabled = uint256(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); 10 11 // Implements ERC173 12 address public owner; 13 14 // Implements Writer 15 mapping( address => bool) public isWriter; 16 17 // Implements Faucet 18 uint256 public tokenAmount; 19 20 // Implements Faucet 21 event FaucetAmountChange(uint256 _value); 22 23 // Implements Writer 24 event WriterAdded(address _account); 25 26 // Implements Writer 27 event WriterDeleted(address _account); 28 29 // Implements EIP 173 30 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 31 32 constructor(address _token, address _store, address _accountsIndex) { 33 owner = msg.sender; 34 store = _store; 35 token = _token; 36 accountsIndex = _accountsIndex; 37 } 38 39 // Implements Writer 40 function addWriter(address _address) public returns(bool) { 41 require(msg.sender == owner, 'ERR_AXX'); 42 isWriter[_address] = true; 43 emit WriterAdded(_address); 44 return true; 45 } 46 47 // Implements Writer 48 function deleteWriter(address _address) public returns(bool) { 49 require(msg.sender == owner || msg.sender == _address, 'ERR_AXX'); 50 isWriter[_address] = false; 51 emit WriterDeleted(_address); 52 return true; 53 } 54 55 // Change faucet amount 56 function setAmount(uint256 _amount) public returns (bool) { 57 require(isWriter[msg.sender] || msg.sender == owner); 58 tokenAmount = _amount; 59 emit FaucetAmountChange(_amount); 60 return true; 61 } 62 63 // Implements Faucet 64 function giveTo(address _recipient) public returns (uint256) { 65 bool _ok; 66 bytes memory _result; 67 68 if (accountsIndex != address(0)) { 69 (_ok, _result) = accountsIndex.call(abi.encodeWithSignature("have(address)", _recipient)); 70 require(_result[31] != 0, 'ERR_ACCOUNT_NOT_IN_INDEX'); 71 } 72 73 (_ok, _result) = store.call(abi.encodeWithSignature("have(address)", _recipient)); 74 75 require(_result[31] == 0, 'ERR_ACCOUNT_USED'); 76 (_ok, _result) = store.call(abi.encodeWithSignature("add(address)", _recipient)); 77 require(_ok, 'ERR_MARK_FAIL'); 78 79 (_ok, _result) = token.call(abi.encodeWithSignature("transfer(address,uint256)", _recipient, tokenAmount)); 80 if (!_ok) { 81 revert('ERR_TRANSFER'); 82 } 83 84 return tokenAmount; 85 } 86 87 // Implements Faucet 88 function gimme() public returns (uint256) { 89 return giveTo(msg.sender); 90 } 91 92 // Implements Faucet 93 function check(address _recipient) public returns (bool) { 94 bool _ok; 95 bytes memory _result; 96 97 (_ok, _result) = store.call(abi.encodeWithSignature("have(address)", _recipient)); 98 99 require(_ok, 'ERR_STORE_FAIL'); 100 101 return _result[31] == 0x00; 102 } 103 104 // Implements Faucet 105 function nextTime(address _recipient) public returns (uint256) { 106 bool _ok; 107 bytes memory _result; 108 109 (_ok, _result) = store.call(abi.encodeWithSignature("have(address)", _recipient)); 110 111 require(_ok, 'ERR_STORE_FAIL'); 112 113 if (_result[31] == 0x01) { 114 return cooldownDisabled; 115 } 116 117 return 0; 118 } 119 120 // Implements Faucet 121 function nextBalance(address _recipient) public pure returns (uint256) { 122 _recipient; 123 return 0; 124 } 125 126 // Implements EIP 173 127 function transferOwnership(address _newOwner) external { 128 address _oldOwner; 129 130 require(msg.sender == owner); 131 _oldOwner = owner; 132 133 owner = _newOwner; 134 135 emit OwnershipTransferred(_oldOwner, owner); 136 } 137 138 function supportsInterface(bytes4 _sum) public pure returns (bool) { 139 if (_sum == 0x01ffc9a7) { // EIP165 140 return true; 141 } 142 if (_sum == 0x1a3ac634) { // Faucet 143 return true; 144 } 145 if (_sum == 0xabe1f1f5) { // Writer 146 return true; 147 } 148 return false; 149 } 150 }