erc20-faucet

ERC20 token faucet
Log | Files | Refs

commit 9d0afe9ea398408a861b3256b25efd281b45accf
Author: nolash <dev@holbrook.no>
Date:   Mon,  7 Dec 2020 16:16:56 +0100

Initial commit

Diffstat:
Apython/erc20_single_shot_faucet/data/ERC20SingleShotFaucet.abi.json | 1+
Apython/erc20_single_shot_faucet/data/ERC20SingleShotFaucet.bin | 2++
Apython/erc20_single_shot_faucet/data/ERC20SingleShotFaucetStorage.abi.json | 1+
Apython/erc20_single_shot_faucet/data/ERC20SingleShotFaucetStorage.bin | 2++
Apython/erc20_single_shot_faucet/data/Erc20SingleShotFaucet.abi.json | 0
Apython/erc20_single_shot_faucet/data/Erc20SingleShotFaucet.bin | 0
Apython/erc20_single_shot_faucet/data/Erc20SingleShotFaucetStorage.abi.json | 0
Apython/erc20_single_shot_faucet/data/Erc20SingleShotFaucetStorage.bin | 0
Apython/erc20_single_shot_faucet/data/GiftableToken.abi.json | 1+
Apython/erc20_single_shot_faucet/data/GiftableToken.bin | 2++
Apython/erc20_single_shot_faucet/data/IERC20SingleShotFaucet.abi.json | 0
Apython/erc20_single_shot_faucet/data/IERC20SingleShotFaucetStorage.abi.json | 1+
Apython/erc20_single_shot_faucet/data/SingleShotFaucet.abi.json | 5+++++
Apython/erc20_single_shot_faucet/data/SingleShotFaucet.bin | 6++++++
Apython/erc20_single_shot_faucet/data/SingleShotFaucetStorage.abi.json | 1+
Apython/erc20_single_shot_faucet/data/SingleShotFaucetStorage.bin | 2++
Apython/setup.cfg | 40++++++++++++++++++++++++++++++++++++++++
Apython/setup.py | 4++++
Apython/tests/test_app.py | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asolidity/ERC20SingleShotFaucet.abi.json | 1+
Asolidity/ERC20SingleShotFaucet.bin | 2++
Asolidity/ERC20SingleShotFaucet.sol | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asolidity/ERC20SingleShotFaucetStorage.abi.json | 1+
Asolidity/ERC20SingleShotFaucetStorage.bin | 2++
Asolidity/ERC20SingleShotFaucetStorage.sol | 35+++++++++++++++++++++++++++++++++++
Asolidity/IERC20SingleShotFaucet.abi.json | 0
Asolidity/IERC20SingleShotFaucetStorage.abi.json | 1+
Asolidity/IERC20SingleShotFaucetStorage.sol | 10++++++++++
Asolidity/Makefile | 12++++++++++++
29 files changed, 317 insertions(+), 0 deletions(-)

diff --git a/python/erc20_single_shot_faucet/data/ERC20SingleShotFaucet.abi.json b/python/erc20_single_shot_faucet/data/ERC20SingleShotFaucet.abi.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address[]","name":"_overriders","type":"address[]"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_store","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_recipient","type":"address"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"FaucetFail","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_recipient","type":"address"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"FaucetUsed","type":"event"},{"inputs":[],"name":"amount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"}],"name":"giveTo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setAmount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}] diff --git a/python/erc20_single_shot_faucet/data/ERC20SingleShotFaucet.bin b/python/erc20_single_shot_faucet/data/ERC20SingleShotFaucet.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50604051610c9c380380610c9c8339818101604052606081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b8382019150602082018581111561006957600080fd5b825186602082028301116401000000008211171561008657600080fd5b8083526020830192505050908051906020019060200280838360005b838110156100bd5780820151818401526020810190506100a2565b505050509050016040526020018051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060005b83518110156101fb57600180600086848151811061019557fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808060010191505061017b565b5080600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050610a0c806102906000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063271f88b41461005157806363e4bff414610095578063aa8c217c146100ef578063fc0c546a1461010d575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610141565b60405180821515815260200191505060405180910390f35b6100d7600480360360208110156100ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101a9565b60405180821515815260200191505060405180910390f35b6100f76109aa565b6040518082815260200191505060405180910390f35b6101156109b0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661019957600080fd5b8160028190555060019050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561026b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f4552525f4143434553530000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006060600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1684604051602401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506040516020818303038152906040527f4a4fbeec000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061037f578051825260208201915060208101905060208303925061035c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146103e1576040519150601f19603f3d011682016040523d82523d6000602084013e6103e6565b606091505b5091509150600060f81b81601f815181106103fd57fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461049d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4552525f4143434f554e545f555345440000000000000000000000000000000081525060200191505060405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1684604051602401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506040516020818303038152906040527ff435f5a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106105ad578051825260208201915060208101905060208303925061058a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461060f576040519150601f19603f3d011682016040523d82523d6000602084013e610614565b606091505b50809250819350505081610690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4552525f4d41524b5f4641494c0000000000000000000000000000000000000081525060200191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1684600254604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106107aa5780518252602082019150602081019050602083039250610787565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461080c576040519150601f19603f3d011682016040523d82523d6000602084013e610811565b606091505b5080925081935050508161091657600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2a56a00a5c532c49314f19361f71cdca8a5d10fdcb42c3fa52800d13419d60706002546040518082815260200191505060405180910390a36040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4552525f5452414e53464552000000000000000000000000000000000000000081525060200191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f45c201a59ac545000ead84f30b2db67da23353aa1d58ac522c48505412143ffa6002546040518082815260200191505060405180910390a3600192505050919050565b60025481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156fea26469706673582212208683f8a5f5acfd905a88c46e8baf3484c087359c84ac56f5d15385ac8291ec0d64736f6c63430007050033 +\ No newline at end of file diff --git a/python/erc20_single_shot_faucet/data/ERC20SingleShotFaucetStorage.abi.json b/python/erc20_single_shot_faucet/data/ERC20SingleShotFaucetStorage.abi.json @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"completeOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"lock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new_owner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"used_accounts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] diff --git a/python/erc20_single_shot_faucet/data/ERC20SingleShotFaucetStorage.bin b/python/erc20_single_shot_faucet/data/ERC20SingleShotFaucetStorage.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061043b806100606000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80634a4fbeec1461005c57806354974421146100b65780637ff2f063146100d6578063f2fde38b14610130578063f435f5a71461018a575b600080fd5b61009e6004803603602081101561007257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101e4565b60405180821515815260200191505060405180910390f35b6100be61023a565b60405180821515815260200191505060405180910390f35b610118600480360360208110156100ec57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506102dd565b60405180821515815260200191505060405180910390f35b6101726004803603602081101561014657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506102fd565b60405180821515815260200191505060405180910390f35b6101cc600480360360208110156101a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103a2565b60405180821515815260200191505060405180910390f35b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029657600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001905090565b60026020528060005260406000206000915054906101000a900460ff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461035857600080fd5b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b60006001600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001905091905056fea264697066735822122039af97232321d8b159a8daeffced27a7fe467d067ba607f5db9c0fbc027333d764736f6c63430007050033 +\ No newline at end of file diff --git a/python/erc20_single_shot_faucet/data/Erc20SingleShotFaucet.abi.json b/python/erc20_single_shot_faucet/data/Erc20SingleShotFaucet.abi.json diff --git a/python/erc20_single_shot_faucet/data/Erc20SingleShotFaucet.bin b/python/erc20_single_shot_faucet/data/Erc20SingleShotFaucet.bin diff --git a/python/erc20_single_shot_faucet/data/Erc20SingleShotFaucetStorage.abi.json b/python/erc20_single_shot_faucet/data/Erc20SingleShotFaucetStorage.abi.json diff --git a/python/erc20_single_shot_faucet/data/Erc20SingleShotFaucetStorage.bin b/python/erc20_single_shot_faucet/data/Erc20SingleShotFaucetStorage.bin diff --git a/python/erc20_single_shot_faucet/data/GiftableToken.abi.json b/python/erc20_single_shot_faucet/data/GiftableToken.abi.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"TransferFrom","type":"event"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"addMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"removeMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/python/erc20_single_shot_faucet/data/GiftableToken.bin b/python/erc20_single_shot_faucet/data/GiftableToken.bin @@ -0,0 +1 @@ +60806040523480156200001157600080fd5b506040516200120338038062001203833981810160405260608110156200003757600080fd5b81019080805160405193929190846401000000008211156200005857600080fd5b838201915060208201858111156200006f57600080fd5b82518660018202830111640100000000821117156200008d57600080fd5b8083526020830192505050908051906020019080838360005b83811015620000c3578082015181840152602081019050620000a6565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011557600080fd5b838201915060208201858111156200012c57600080fd5b82518660018202830111640100000000821117156200014a57600080fd5b8083526020830192505050908051906020019080838360005b838110156200018057808201518184015260208101905062000163565b50505050905090810190601f168015620001ae5780820380516001836020036101000a031916815260200191505b5060405260200180519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600290805190602001906200021a929190620002af565b50816003908051906020019062000233929190620002af565b5080600460006101000a81548160ff021916908360ff16021790555060018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050505062000365565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620002e7576000855562000333565b82601f106200030257805160ff191683800117855562000333565b8280016001018555821562000333579182015b828111156200033257825182559160200191906001019062000315565b5b50905062000342919062000346565b5090565b5b808211156200036157600081600090555060010162000347565b5090565b610e8e80620003756000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c806355b6ed5c1161007157806355b6ed5c146102bd57806370a082311461033557806395d89b411461038d578063983b2d5614610410578063a0712d681461046a578063a9059cbb146104ae576100b4565b806306fdde03146100b9578063095ea7b31461013c57806318160ddd146101a057806323b872dd146101be5780633092afd514610242578063313ce5671461029c575b600080fd5b6100c1610512565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101015780820151818401526020810190506100e6565b50505050905090810190601f16801561012e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101886004803603604081101561015257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506105b0565b60405180821515815260200191505060405180910390f35b6101a86106ab565b6040518082815260200191505060405180910390f35b61022a600480360360608110156101d457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506106b1565b60405180821515815260200191505060405180910390f35b6102846004803603602081101561025857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506109a8565b60405180821515815260200191505060405180910390f35b6102a4610a9a565b604051808260ff16815260200191505060405180910390f35b61031f600480360360408110156102d357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610aad565b6040518082815260200191505060405180910390f35b6103776004803603602081101561034b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ad2565b6040518082815260200191505060405180910390f35b610395610aea565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103d55780820151818401526020810190506103ba565b50505050905090810190601f1680156104025780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104526004803603602081101561042657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b88565b60405180821515815260200191505060405180910390f35b6104966004803603602081101561048057600080fd5b8101908080359060200190929190505050610c43565b60405180821515815260200191505060405180910390f35b6104fa600480360360408110156104c457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610d01565b60405180821515815260200191505060405180910390f35b60028054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105a85780601f1061057d576101008083540402835291602001916105a8565b820191906000526020600020905b81548152906001019060200180831161058b57829003601f168201915b505050505081565b600081600760003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60055481565b600081600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561073c57600080fd5b81600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101561078857600080fd5b81600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205403600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f5f7542858008eeb041631f30e6109ae94b83a58e9a58261dd2c42c508850f939856040518082815260200191505060405180910390a4600190509392505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610a3057508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610a3957600080fd5b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b600460009054906101000a900460ff1681565b6007602052816000526040600020602052806000526040600020600091509150505481565b60066020528060005260406000206000915090505481565b60038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610b805780601f10610b5557610100808354040283529160200191610b80565b820191906000526020600020905b815481529060010190602001808311610b6357829003601f168201915b505050505081565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610be357600080fd5b60018060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610c9b57600080fd5b81600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508160056000828254019250508190555060019050919050565b600081600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015610d4f57600080fd5b81600660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509291505056fea2646970667358221220decedd646f4686c330f11369f5c7b4908d8940d20f00c85711890c5f75172d8764736f6c63430007050033 +\ No newline at end of file diff --git a/python/erc20_single_shot_faucet/data/IERC20SingleShotFaucet.abi.json b/python/erc20_single_shot_faucet/data/IERC20SingleShotFaucet.abi.json diff --git a/python/erc20_single_shot_faucet/data/IERC20SingleShotFaucetStorage.abi.json b/python/erc20_single_shot_faucet/data/IERC20SingleShotFaucetStorage.abi.json @@ -0,0 +1 @@ +[{"inputs":[],"name":"completeOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/python/erc20_single_shot_faucet/data/SingleShotFaucet.abi.json b/python/erc20_single_shot_faucet/data/SingleShotFaucet.abi.json @@ -0,0 +1,5 @@ +[{"inputs":[],"name":"completeOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] + +======= SingleShotFaucet.sol:SingleShotFaucet ======= +Contract JSON ABI +[{"inputs":[{"internalType":"address[]","name":"_overriders","type":"address[]"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_store","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_recipient","type":"address"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"NewBeneficiary","type":"event"},{"inputs":[],"name":"amount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"}],"name":"giveTo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setAmount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}] diff --git a/python/erc20_single_shot_faucet/data/SingleShotFaucet.bin b/python/erc20_single_shot_faucet/data/SingleShotFaucet.bin @@ -0,0 +1,5 @@ + + +======= SingleShotFaucet.sol:SingleShotFaucet ======= +Binary: +608060405234801561001057600080fd5b506040516109c53803806109c58339818101604052606081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b8382019150602082018581111561006957600080fd5b825186602082028301116401000000008211171561008657600080fd5b8083526020830192505050908051906020019060200280838360005b838110156100bd5780820151818401526020810190506100a2565b505050509050016040526020018051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060005b83518110156101fb57600180600086848151811061019557fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808060010191505061017b565b5080600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050610735806102906000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063271f88b41461005157806363e4bff414610095578063aa8c217c146100ef578063fc0c546a1461010d575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610141565b60405180821515815260200191505060405180910390f35b6100d7600480360360208110156100ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101a9565b60405180821515815260200191505060405180910390f35b6100f76106d3565b6040518082815260200191505060405180910390f35b6101156106d9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661019957600080fd5b8160028190555060019050919050565b6000806060600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1684604051602401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506040516020818303038152906040527f7ff2f063000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106102be578051825260208201915060208101905060208303925061029b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610320576040519150601f19603f3d011682016040523d82523d6000602084013e610325565b606091505b5091509150811561033557600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1684604051602401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506040516020818303038152906040527fdb7d3fc7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106104455780518252602082019150602081019050602083039250610422565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146104a7576040519150601f19603f3d011682016040523d82523d6000602084013e6104ac565b606091505b508092508193505050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1684600254604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106105cf57805182526020820191506020810190506020830392506105ac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610631576040519150601f19603f3d011682016040523d82523d6000602084013e610636565b606091505b508092508193505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f1812274c41aaf75e4c38824d94e185a8d4609cdc7ba6044a896b05c31c8430f86002546040518082815260200191505060405180910390a3600192505050919050565b60025481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156fea26469706673582212207af20c4ea9c6f7ff0b892d18d26b44fb89fc0f1c4ad665fb584e67f21db12bf764736f6c63430007050033 +\ No newline at end of file diff --git a/python/erc20_single_shot_faucet/data/SingleShotFaucetStorage.abi.json b/python/erc20_single_shot_faucet/data/SingleShotFaucetStorage.abi.json @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"completeOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"lock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new_owner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"used_accounts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] diff --git a/python/erc20_single_shot_faucet/data/SingleShotFaucetStorage.bin b/python/erc20_single_shot_faucet/data/SingleShotFaucetStorage.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061043b806100606000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80634a4fbeec1461005c57806354974421146100b65780637ff2f063146100d6578063f2fde38b14610130578063f435f5a71461018a575b600080fd5b61009e6004803603602081101561007257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101e4565b60405180821515815260200191505060405180910390f35b6100be61023a565b60405180821515815260200191505060405180910390f35b610118600480360360208110156100ec57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506102dd565b60405180821515815260200191505060405180910390f35b6101726004803603602081101561014657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506102fd565b60405180821515815260200191505060405180910390f35b6101cc600480360360208110156101a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103a2565b60405180821515815260200191505060405180910390f35b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029657600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001905090565b60026020528060005260406000206000915054906101000a900460ff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461035857600080fd5b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b60006001600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001905091905056fea2646970667358221220f617e462c253102c10bcb82dbf9861737254ed63fb6ee686007c9a103bbec2c964736f6c63430007050033 +\ No newline at end of file diff --git a/python/setup.cfg b/python/setup.cfg @@ -0,0 +1,40 @@ +[metadata] +name = erc20-single-shot-faucet +version = 0.0.1 +description = ERC20 token faucet that can be used once per account +author = Louis Holbrook +author_email = dev@holbrook.no +url = https://gitlab.com/nolash/simple-multisig +keywords = + ethereum +classifiers = + Programming Language :: Python :: 3 + Operating System :: OS Independent + Development Status :: 3 - Alpha + Environment :: No Input/Output (Daemon) + Intended Audience :: Developers + License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+) + Topic :: Internet + #Topic :: Blockchain :: EVM +license = GPL3 +licence_files = + LICENSE + +[options] +python_requires = >= 3.6 +packages = + erc20_approval_escrow.runnable +install_requires = + web3==5.12.2 +tests_require = + eth-tester==0.5.0b2 + py-evm==0.3.0a20 + +[options.extras_require] +testing = + eth-tester==0.5.0b2 + py-evm==0.3.0a20 + +[options.entry_points] +console_scripts = + erc20-single-shot-faucet = erc20_approval_escrow.runnable.deploy:main diff --git a/python/setup.py b/python/setup.py @@ -0,0 +1,4 @@ +from setuptools import setup + +setup( + ) diff --git a/python/tests/test_app.py b/python/tests/test_app.py @@ -0,0 +1,135 @@ +import os +import unittest +import json +import logging + +import web3 +import eth_tester +import eth_abi + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + +logging.getLogger('web3').setLevel(logging.WARNING) +logging.getLogger('eth.vm').setLevel(logging.WARNING) + +testdir = os.path.dirname(__file__) + + +class Test(unittest.TestCase): + + contract = None + + def setUp(self): + eth_params = eth_tester.backends.pyevm.main.get_default_genesis_params({ + 'gas_limit': 9000000, + }) + + # create store of used accounts + f = open(os.path.join(testdir, '../erc20_single_shot_faucet/data/ERC20SingleShotFaucetStorage.bin'), 'r') + bytecode = f.read() + f.close() + + f = open(os.path.join(testdir, '../erc20_single_shot_faucet/data/ERC20SingleShotFaucetStorage.abi.json'), 'r') + self.abi_storage = json.load(f) + f.close() + + + backend = eth_tester.PyEVMBackend(eth_params) + self.eth_tester = eth_tester.EthereumTester(backend) + provider = web3.Web3.EthereumTesterProvider(self.eth_tester) + self.w3 = web3.Web3(provider) + c = self.w3.eth.contract(abi=self.abi_storage, bytecode=bytecode) + tx_hash = c.constructor().transact({'from': self.w3.eth.accounts[0]}) + + r = self.w3.eth.getTransactionReceipt(tx_hash) + + self.address_storage = r.contractAddress + + + # create token + f = open(os.path.join(testdir, '../erc20_single_shot_faucet/data/GiftableToken.bin'), 'r') + bytecode = f.read() + f.close() + + f = open(os.path.join(testdir, '../erc20_single_shot_faucet/data/GiftableToken.abi.json'), 'r') + self.abi_token = json.load(f) + f.close() + + t = self.w3.eth.contract(abi=self.abi_token, bytecode=bytecode) + tx_hash = t.constructor('Foo Token', 'FOO', 18).transact({'from': self.w3.eth.accounts[0]}) + + r = self.w3.eth.getTransactionReceipt(tx_hash) + + self.address_token = r.contractAddress + t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token) + + tx_hash = t.functions.mint(1000).transact({'from': self.w3.eth.accounts[0]}) + + + # create faucet + f = open(os.path.join(testdir, '../erc20_single_shot_faucet/data/ERC20SingleShotFaucet.bin'), 'r') + bytecode = f.read() + f.close() + + f = open(os.path.join(testdir, '../erc20_single_shot_faucet/data/ERC20SingleShotFaucet.abi.json'), 'r') + self.abi_faucet = json.load(f) + f.close() + +# f = open(os.path.join(testdir, '../erc20_single_shot_faucet/data/ERC20SingleShotFaucet.abi.json'), 'r') +# abi_storage_interface = json.load(f) +# f.close() + + c = self.w3.eth.contract(abi=self.abi_faucet, bytecode=bytecode) + tx_hash = c.constructor([ + self.w3.eth.accounts[1], + self.w3.eth.accounts[2], + ], + self.address_token, + self.address_storage, + ).transact({'from': self.w3.eth.accounts[0]}) + + r = self.w3.eth.getTransactionReceipt(tx_hash) + + self.address_faucet = r.contractAddress + c = self.w3.eth.contract(abi=self.abi_faucet, address=self.address_faucet) + + tx_hash = t.functions.transfer(self.address_faucet, 100).transact({'from': self.w3.eth.accounts[0]}) + + + def tearDown(self): + pass + + + def test_basic(self): + c = self.w3.eth.contract(abi=self.abi_faucet, address=self.address_faucet) + self.assertTrue(c.functions.setAmount(10).transact({'from': self.w3.eth.accounts[0]})) + self.assertTrue(c.functions.setAmount(20).transact({'from': self.w3.eth.accounts[1]})) + with self.assertRaises(Exception): + c.functions.setAmount(30).transact({'from': self.w3.eth.accounts[3]}) + + + def test_giveto(self): + c = self.w3.eth.contract(abi=self.abi_faucet, address=self.address_faucet) + c.functions.setAmount(10).transact({'from': self.w3.eth.accounts[2]}) + c.functions.giveTo(self.w3.eth.accounts[3]).transact({'from': self.w3.eth.accounts[1]}) + + t = self.w3.eth.contract(abi=self.abi_token, address=self.address_token) + self.assertEqual(t.functions.balanceOf(self.w3.eth.accounts[3]).call(), 10); + self.assertEqual(t.functions.balanceOf(self.address_faucet).call(), 90); + + with self.assertRaises(Exception): + c.functions.giveTo(self.w3.eth.accounts[3]).transact({'from': self.w3.eth.accounts[1]}) + + c.functions.setAmount(50).transact({'from': self.w3.eth.accounts[1]}) + c.functions.giveTo(self.w3.eth.accounts[4]).transact({'from': self.w3.eth.accounts[1]}) + self.assertEqual(t.functions.balanceOf(self.w3.eth.accounts[4]).call(), 50); + self.assertEqual(t.functions.balanceOf(self.address_faucet).call(), 40); + + with self.assertRaises(Exception): + c.functions.giveTo(self.w3.eth.accounts[5]).transact({'from': self.w3.eth.accounts[1]}) + self.assertEqual(t.functions.balanceOf(self.w3.eth.accounts[5]).call(), 0); + self.assertEqual(t.functions.balanceOf(self.address_faucet).call(), 40); + +if __name__ == '__main__': + unittest.main() diff --git a/solidity/ERC20SingleShotFaucet.abi.json b/solidity/ERC20SingleShotFaucet.abi.json @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address[]","name":"_overriders","type":"address[]"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_store","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_recipient","type":"address"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"FaucetFail","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_recipient","type":"address"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"FaucetUsed","type":"event"},{"inputs":[],"name":"amount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"}],"name":"giveTo","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"setAmount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}] diff --git a/solidity/ERC20SingleShotFaucet.bin b/solidity/ERC20SingleShotFaucet.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50604051610c9c380380610c9c8339818101604052606081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b8382019150602082018581111561006957600080fd5b825186602082028301116401000000008211171561008657600080fd5b8083526020830192505050908051906020019060200280838360005b838110156100bd5780820151818401526020810190506100a2565b505050509050016040526020018051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060005b83518110156101fb57600180600086848151811061019557fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550808060010191505061017b565b5080600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050610a0c806102906000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063271f88b41461005157806363e4bff414610095578063aa8c217c146100ef578063fc0c546a1461010d575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610141565b60405180821515815260200191505060405180910390f35b6100d7600480360360208110156100ab57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101a9565b60405180821515815260200191505060405180910390f35b6100f76109aa565b6040518082815260200191505060405180910390f35b6101156109b0565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661019957600080fd5b8160028190555060019050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561026b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600a8152602001807f4552525f4143434553530000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006060600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1684604051602401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506040516020818303038152906040527f4a4fbeec000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061037f578051825260208201915060208101905060208303925061035c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146103e1576040519150601f19603f3d011682016040523d82523d6000602084013e6103e6565b606091505b5091509150600060f81b81601f815181106103fd57fe5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461049d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f4552525f4143434f554e545f555345440000000000000000000000000000000081525060200191505060405180910390fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1684604051602401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506040516020818303038152906040527ff435f5a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106105ad578051825260208201915060208101905060208303925061058a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461060f576040519150601f19603f3d011682016040523d82523d6000602084013e610614565b606091505b50809250819350505081610690576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f4552525f4d41524b5f4641494c0000000000000000000000000000000000000081525060200191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1684600254604051602401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106107aa5780518252602082019150602081019050602083039250610787565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461080c576040519150601f19603f3d011682016040523d82523d6000602084013e610811565b606091505b5080925081935050508161091657600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f2a56a00a5c532c49314f19361f71cdca8a5d10fdcb42c3fa52800d13419d60706002546040518082815260200191505060405180910390a36040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4552525f5452414e53464552000000000000000000000000000000000000000081525060200191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f45c201a59ac545000ead84f30b2db67da23353aa1d58ac522c48505412143ffa6002546040518082815260200191505060405180910390a3600192505050919050565b60025481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168156fea26469706673582212208683f8a5f5acfd905a88c46e8baf3484c087359c84ac56f5d15385ac8291ec0d64736f6c63430007050033 +\ No newline at end of file diff --git a/solidity/ERC20SingleShotFaucet.sol b/solidity/ERC20SingleShotFaucet.sol @@ -0,0 +1,50 @@ +pragma solidity >=0.6.21; + +// SPDX-License-Identifier: GPL-3.0-or-later + +contract SingleShotFaucet { + + address owner; + mapping( address => bool) overriders; + uint256 public amount; + address public token; + address store; + + event FaucetUsed(address indexed _recipient, address indexed _token, uint256 _value); + event FaucetFail(address indexed _recipient, address indexed _token, uint256 _value); + + constructor(address[] memory _overriders, address _token, address _store) public { + owner = msg.sender; + overriders[msg.sender] = true; + for (uint i = 0; i < _overriders.length; i++) { + overriders[_overriders[i]] = true; + } + store = _store; + token = _token; + } + + function setAmount(uint256 _amount) public returns (bool) { + require(overriders[msg.sender]); + amount = _amount; + return true; + } + + function giveTo(address _recipient) public returns (bool) { + require(!overriders[_recipient], 'ERR_ACCESS'); + (bool _ok, bytes memory _result) = store.call(abi.encodeWithSignature("isLocked(address)", _recipient)); + + require(_result[31] == 0, 'ERR_ACCOUNT_USED'); // less conversion than: // require(abi.decode(_result, (bool)) == false, 'ERR_ACCOUNT_USED'); + + (_ok, _result) = store.call(abi.encodeWithSignature("lock(address)", _recipient)); + require(_ok, 'ERR_MARK_FAIL'); + + (_ok, _result) = token.call(abi.encodeWithSignature("transfer(address,uint256)", _recipient, amount)); + if (!_ok) { + emit FaucetFail(_recipient, token, amount); + revert('ERR_TRANSFER'); + } + + emit FaucetUsed(_recipient, token, amount); + return true; + } +} diff --git a/solidity/ERC20SingleShotFaucetStorage.abi.json b/solidity/ERC20SingleShotFaucetStorage.abi.json @@ -0,0 +1 @@ +[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"completeOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"lock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new_owner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"used_accounts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}] diff --git a/solidity/ERC20SingleShotFaucetStorage.bin b/solidity/ERC20SingleShotFaucetStorage.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061043b806100606000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80634a4fbeec1461005c57806354974421146100b65780637ff2f063146100d6578063f2fde38b14610130578063f435f5a71461018a575b600080fd5b61009e6004803603602081101561007257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506101e4565b60405180821515815260200191505060405180910390f35b6100be61023a565b60405180821515815260200191505060405180910390f35b610118600480360360208110156100ec57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506102dd565b60405180821515815260200191505060405180910390f35b6101726004803603602081101561014657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506102fd565b60405180821515815260200191505060405180910390f35b6101cc600480360360208110156101a057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103a2565b60405180821515815260200191505060405180910390f35b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461029657600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001905090565b60026020528060005260406000206000915054906101000a900460ff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461035857600080fd5b81600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b60006001600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506001905091905056fea264697066735822122039af97232321d8b159a8daeffced27a7fe467d067ba607f5db9c0fbc027333d764736f6c63430007050033 +\ No newline at end of file diff --git a/solidity/ERC20SingleShotFaucetStorage.sol b/solidity/ERC20SingleShotFaucetStorage.sol @@ -0,0 +1,35 @@ +pragma solidity >=0.6.21; + +// SPDX-License-Identifier: GPL-3.0-or-later + +contract SingleShotFaucetStorage { + address owner; + address new_owner; + + mapping (address => bool) public used_accounts; + + constructor() public { + owner = msg.sender; + } + + function transferOwnership(address _new_owner) external returns (bool) { + require(msg.sender == owner); + new_owner = _new_owner; + return true; + } + + function completeOwnership() external returns (bool) { + require(msg.sender == new_owner); + owner = msg.sender; + return true; + } + + function lock(address _account) external returns (bool) { + used_accounts[_account] = true; + return true; + } + + function isLocked(address _account) external view returns (bool) { + return used_accounts[_account]; + } +} diff --git a/solidity/IERC20SingleShotFaucet.abi.json b/solidity/IERC20SingleShotFaucet.abi.json diff --git a/solidity/IERC20SingleShotFaucetStorage.abi.json b/solidity/IERC20SingleShotFaucetStorage.abi.json @@ -0,0 +1 @@ +[{"inputs":[],"name":"completeOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/solidity/IERC20SingleShotFaucetStorage.sol b/solidity/IERC20SingleShotFaucetStorage.sol @@ -0,0 +1,10 @@ +pragma solidity >=0.6.21; + +// SPDX-License-Identifier: GPL-3.0-or-later + +interface ISingleShotFaucetStorage { + function transferOwnership(address) external returns(bool); + function completeOwnership() external returns(bool); + function lock(address) external returns(bool); + function isLocked(address) external returns(bool); +} diff --git a/solidity/Makefile b/solidity/Makefile @@ -0,0 +1,12 @@ +all: + solc --bin ERC20SingleShotFaucetStorage.sol | awk 'NR>3' > ERC20SingleShotFaucetStorage.bin + truncate -s -1 ERC20SingleShotFaucetStorage.bin + solc --abi ERC20SingleShotFaucetStorage.sol | awk 'NR>3' > ERC20SingleShotFaucetStorage.abi.json + solc --bin ERC20SingleShotFaucet.sol | awk 'NR>3' > ERC20SingleShotFaucet.bin + truncate -s -1 ERC20SingleShotFaucet.bin + solc --abi ERC20SingleShotFaucet.sol | awk 'NR==4' > ERC20SingleShotFaucet.abi.json + solc --abi IERC20SingleShotFaucetStorage.sol | awk 'NR>3' > IERC20SingleShotFaucetStorage.abi.json + +install: all + cp -v *{json,bin} ../python/erc20_single_shot_faucet/data/ +