becrypto/contracts/activity/ClaimToken.sol
2024-01-12 15:07:18 +08:00

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);
}
}