106 lines
2.7 KiB
Solidity
106 lines
2.7 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.10;
|
|
|
|
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
|
|
import "../core/HasSignature.sol";
|
|
|
|
/**
|
|
* Contract for activity NFT claim.
|
|
*/
|
|
interface IClaimAbleNFT {
|
|
function safeMint(
|
|
address to
|
|
) external returns (uint256);
|
|
}
|
|
|
|
contract NFTClaimer is HasSignature, ReentrancyGuard{
|
|
uint256 private immutable _CACHED_CHAIN_ID;
|
|
address private immutable _CACHED_THIS;
|
|
address public immutable nftAddress;
|
|
address public signer;
|
|
uint256 public startTime;
|
|
uint256 public endTime;
|
|
|
|
mapping(address => uint256) public claimHistory;
|
|
|
|
event NFTClaimed(
|
|
address indexed nftAddress,
|
|
address indexed to,
|
|
uint256 tokenId,
|
|
uint256 nonce
|
|
);
|
|
|
|
event SignerUpdated(address indexed signer);
|
|
event StartTimeUpdated(uint256 indexed startTime);
|
|
event EndTimeUpdated(uint256 indexed endTime);
|
|
|
|
constructor(address _nftAddress) {
|
|
_CACHED_CHAIN_ID = block.chainid;
|
|
_CACHED_THIS = address(this);
|
|
nftAddress = _nftAddress;
|
|
}
|
|
|
|
|
|
function updateStartTime(uint256 _startTime) external onlyOwner {
|
|
startTime = _startTime;
|
|
emit StartTimeUpdated(_startTime);
|
|
}
|
|
|
|
function updateEndTime(uint256 _endTime) external onlyOwner {
|
|
endTime = _endTime;
|
|
emit EndTimeUpdated(_endTime);
|
|
}
|
|
|
|
|
|
/**
|
|
* @dev update signer
|
|
* @param _account new signer address
|
|
*/
|
|
function updateSigner(address _account) external onlyOwner {
|
|
require(_account != address(0), "NFTClaimer: address can not be zero");
|
|
signer = _account;
|
|
emit SignerUpdated(_account);
|
|
}
|
|
|
|
/**
|
|
* @dev claim NFT
|
|
* Get whitelist signature from a third-party service, then call this method to claim NFT
|
|
* @param saltNonce nonce
|
|
* @param signature signature
|
|
*/
|
|
function claim(
|
|
uint256 saltNonce,
|
|
bytes calldata signature
|
|
) external nonReentrant {
|
|
require(block.timestamp >= startTime, "NFTClaimer: not started");
|
|
require(block.timestamp <= endTime, "NFTClaimer: already ended");
|
|
address to = _msgSender();
|
|
require(claimHistory[to] == 0, "NFTClaimer: already claimed");
|
|
bytes32 criteriaMessageHash = getMessageHash(
|
|
to,
|
|
nftAddress,
|
|
saltNonce
|
|
);
|
|
checkSigner(signer, criteriaMessageHash, signature);
|
|
uint256 tokenId = IClaimAbleNFT(nftAddress).safeMint(to);
|
|
claimHistory[to] = tokenId;
|
|
_useSignature(signature);
|
|
emit NFTClaimed(nftAddress, to, tokenId, saltNonce);
|
|
}
|
|
|
|
function getMessageHash(
|
|
address _to,
|
|
address _address,
|
|
uint256 _saltNonce
|
|
) public view returns (bytes32) {
|
|
bytes memory encoded = abi.encodePacked(
|
|
_to,
|
|
_address,
|
|
_CACHED_CHAIN_ID,
|
|
_CACHED_THIS,
|
|
_saltNonce
|
|
);
|
|
return keccak256(encoded);
|
|
}
|
|
}
|