121 lines
3.1 KiB
Solidity
121 lines
3.1 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.10;
|
|
|
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
import "../core/HasSignature.sol";
|
|
import "../utils/TimeChecker.sol";
|
|
|
|
/**
|
|
* @title ClaimToken
|
|
* @dev for user to claim token
|
|
*/
|
|
contract ClaimToken is HasSignature, TimeChecker {
|
|
using SafeERC20 for IERC20;
|
|
uint256 private immutable _CACHED_CHAIN_ID;
|
|
address private immutable _CACHED_THIS;
|
|
address private verifier;
|
|
address private paymentAddress;
|
|
mapping(address => bool) public tokenSupported;
|
|
mapping(address => uint256) public claimHistory;
|
|
struct TestStuct {
|
|
address user;
|
|
address nft;
|
|
uint256 tokenId;
|
|
uint64 start;
|
|
uint64 stakeTime;
|
|
}
|
|
event TestEvent (
|
|
address indexed user,
|
|
TestStuct info
|
|
);
|
|
|
|
|
|
event TokenClaimed(
|
|
address indexed tokenAddress,
|
|
address indexed to,
|
|
uint256 indexed nonce,
|
|
uint256 amount
|
|
);
|
|
event TokenSupportUpdated(address indexed tokenAddress, bool support);
|
|
event VerifierUpdated(address indexed verifier);
|
|
event PaymentAddressUpdated(address indexed paymentAddress);
|
|
|
|
constructor() {
|
|
_CACHED_CHAIN_ID = block.chainid;
|
|
_CACHED_THIS = address(this);
|
|
}
|
|
|
|
function updateTokenSupport(address _token, bool _support) external onlyOwner {
|
|
tokenSupported[_token] = _support;
|
|
emit TokenSupportUpdated(_token, _support);
|
|
}
|
|
|
|
/**
|
|
* @dev update verifier address
|
|
*/
|
|
function updateVerifier(address _verifier) external onlyOwner {
|
|
require(_verifier != address(0), "ClaimToken: address can not be zero");
|
|
verifier = _verifier;
|
|
emit VerifierUpdated(_verifier);
|
|
}
|
|
|
|
/**
|
|
* @dev update payment address
|
|
*/
|
|
function updatePaymentAddress(address _paymentAddress) external onlyOwner {
|
|
require(
|
|
_paymentAddress != address(0),
|
|
"ClaimToken: payment address can not be zero"
|
|
);
|
|
paymentAddress = _paymentAddress;
|
|
emit PaymentAddressUpdated(_paymentAddress);
|
|
}
|
|
|
|
function claim(
|
|
address _token,
|
|
uint256 _amount,
|
|
uint256 _startTime,
|
|
uint256 _saltNonce,
|
|
bytes calldata _signature
|
|
) external signatureValid(_signature) timeValid(_startTime) {
|
|
require(tokenSupported[_token], "ClaimToken: unsupported token");
|
|
address to = _msgSender();
|
|
bytes32 criteriaMessageHash = getMessageHash(
|
|
to,
|
|
_token,
|
|
_CACHED_THIS,
|
|
_CACHED_CHAIN_ID,
|
|
_amount,
|
|
_startTime,
|
|
_saltNonce
|
|
);
|
|
checkSigner(verifier, criteriaMessageHash, _signature);
|
|
IERC20(_token).safeTransferFrom(paymentAddress, to, _amount);
|
|
claimHistory[to] = _amount;
|
|
_useSignature(_signature);
|
|
emit TokenClaimed(_token, to, _saltNonce, _amount);
|
|
}
|
|
|
|
function getMessageHash(
|
|
address _to,
|
|
address _address,
|
|
address _contract,
|
|
uint256 _chainId,
|
|
uint256 _amount,
|
|
uint256 _startTime,
|
|
uint256 _saltNonce
|
|
) public pure returns (bytes32) {
|
|
bytes memory encoded = abi.encodePacked(
|
|
_to,
|
|
_address,
|
|
_contract,
|
|
_chainId,
|
|
_amount,
|
|
_startTime,
|
|
_saltNonce
|
|
);
|
|
return keccak256(encoded);
|
|
}
|
|
}
|