// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "https://github.com/openzeppelin/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
contract DequestJackpot {
address private owner;
uint8 private tokenIndex;
mapping(uint8 => address) public idToToken;
mapping(uint8 => address) public idToSigner;
mapping(address => uint8) public tokenToId;
mapping(address => uint256) public request;
event Claim(uint8 _tokenIndex, address indexed _receiver, uint256 indexed _index, uint256 _amount);
constructor() {
owner = msg.sender;
}
function changeOwner(address _owner) external returns (bool) {
require(msg.sender == owner, "DequestJackpot: Invalid owner");
owner = _owner;
return true;
}
function changeSigner(uint8 _index, address _signer) external returns (bool) {
require(msg.sender == owner, "DequestJackpot: Invalid owner");
idToSigner[_index] = _signer;
return true;
}
function addToken(address _tokenAddress, address _signer) external returns (bool) {
require(msg.sender == owner, "DequestJackpot: Invalid owner");
idToSigner[tokenIndex] = _signer;
idToToken[tokenIndex] = _tokenAddress;
tokenToId[_tokenAddress] = tokenIndex;
++tokenIndex;
return true;
}
function claim(uint8 tIndex, uint256 amount, uint8 v, bytes32 r, bytes32 s) external returns (bool) {
require(idToSigner[tIndex] != address(0x0), "DequestJackpot: Invalid index");
require(idToToken[tIndex] != address(0x0), "DequestJackpot: Invalid token");
address sender = msg.sender;
bytes32 message = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", keccak256(abi.encode(tIndex, sender, request[sender], amount))));
require(ecrecover(message, v, r, s) == idToSigner[tIndex], "DequestJackpot: Invalid signer");
IERC20 token = IERC20(idToToken[tIndex]);
token.transfer(sender, amount);
emit Claim(tIndex, sender, request[sender], amount);
++request[sender];
return true;
}
}
{
"compilationTarget": {
"contracts/DequestJackpot.sol": "DequestJackpot"
},
"evmVersion": "berlin",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"_tokenIndex","type":"uint8"},{"indexed":true,"internalType":"address","name":"_receiver","type":"address"},{"indexed":true,"internalType":"uint256","name":"_index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Claim","type":"event"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"address","name":"_signer","type":"address"}],"name":"addToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"changeOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_index","type":"uint8"},{"internalType":"address","name":"_signer","type":"address"}],"name":"changeSigner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"tIndex","type":"uint8"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"claim","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"idToSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"idToToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"request","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenToId","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}]