update contract for token claim
This commit is contained in:
parent
1018027f2c
commit
7d9d6ce482
File diff suppressed because one or more lines are too long
@ -23,13 +23,7 @@ contract TokenClaim is HasSignature, ReentrancyGuard, Pausable, TimeChecker {
|
||||
event EventERC20Wallet(address erc20, address wallet);
|
||||
|
||||
event EventVerifierUpdated(address indexed verifier);
|
||||
event EventTokenClaimed(
|
||||
address indexed user,
|
||||
address indexed token,
|
||||
address passport,
|
||||
uint256 amount,
|
||||
uint256 nonce
|
||||
);
|
||||
event EventTokenClaimed(address indexed user, address indexed token, address passport, uint256 amount, uint256 nonce);
|
||||
|
||||
constructor(address _wallet, address _token, address _verifier, uint256 _duration) TimeChecker(_duration) {
|
||||
_CACHED_CHAIN_ID = block.chainid;
|
||||
@ -42,7 +36,7 @@ contract TokenClaim is HasSignature, ReentrancyGuard, Pausable, TimeChecker {
|
||||
* @dev update verifier address
|
||||
*/
|
||||
function updateVerifier(address _verifier) external onlyOwner {
|
||||
require(_verifier != address(0), "TokenClaimer: address can not be zero");
|
||||
require(_verifier != address(0), "TokenClaim: address can not be zero");
|
||||
verifier = _verifier;
|
||||
emit EventVerifierUpdated(_verifier);
|
||||
}
|
||||
@ -65,30 +59,35 @@ contract TokenClaim is HasSignature, ReentrancyGuard, Pausable, TimeChecker {
|
||||
* @dev update ERC20 wallet
|
||||
*/
|
||||
function updateERC20Wallet(address erc20, address wallet) external onlyOwner {
|
||||
require(erc20Wallets[erc20] != wallet, "TokenClaimer: ERC20 wallet not changed");
|
||||
require(erc20Wallets[erc20] != wallet, "TokenClaim: ERC20 wallet not changed");
|
||||
erc20Wallets[erc20] = wallet;
|
||||
emit EventERC20Wallet(erc20, wallet);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev claim CEC with signature
|
||||
* @param account address which eligible to claim, only for event log
|
||||
* @param token address of token
|
||||
* @param amount amount of token
|
||||
* @param signTime time of signature
|
||||
* @param saltNonce nonce of signature
|
||||
* @param signature signature of claim
|
||||
*/
|
||||
|
||||
function claim(
|
||||
address passport,
|
||||
address account,
|
||||
address token,
|
||||
uint256 amount,
|
||||
uint256 signTime,
|
||||
uint256 saltNonce,
|
||||
bytes calldata signature
|
||||
) external signatureValid(signature) timeValid(signTime) nonReentrant whenNotPaused {
|
||||
require(passport != address(0), "TokenClaimer: passport address can not be zero");
|
||||
require(erc20Wallets[token] != address(0), "TokenClaimer: token is not supported");
|
||||
require(amount > 0, "TokenClaimer: amount is zero");
|
||||
) external signatureValid(signature) timeValid(signTime) nonReentrant whenNotPaused {
|
||||
require(erc20Wallets[token] != address(0), "TokenClaim: token is not supported");
|
||||
require(amount > 0, "TokenClaim: amount is zero");
|
||||
address user = _msgSender();
|
||||
bytes32 criteriaMessageHash = getMessageHash(
|
||||
user,
|
||||
passport,
|
||||
account,
|
||||
token,
|
||||
amount,
|
||||
_CACHED_THIS,
|
||||
@ -98,14 +97,14 @@ contract TokenClaim is HasSignature, ReentrancyGuard, Pausable, TimeChecker {
|
||||
);
|
||||
checkSigner(verifier, criteriaMessageHash, signature);
|
||||
_useSignature(signature);
|
||||
claimedAmount[user][token] += amount;
|
||||
claimedAmount[account][token] += amount;
|
||||
IERC20(token).safeTransferFrom(erc20Wallets[token], user, amount);
|
||||
emit EventTokenClaimed(user, token, passport, amount, saltNonce);
|
||||
emit EventTokenClaimed(user, token, account, amount, saltNonce);
|
||||
}
|
||||
|
||||
function getMessageHash(
|
||||
address _user,
|
||||
address _passport,
|
||||
address _account,
|
||||
address _token,
|
||||
uint256 _amount,
|
||||
address _contract,
|
||||
@ -115,7 +114,7 @@ contract TokenClaim is HasSignature, ReentrancyGuard, Pausable, TimeChecker {
|
||||
) public pure returns (bytes32) {
|
||||
bytes memory encoded = abi.encodePacked(
|
||||
_user,
|
||||
_passport,
|
||||
_account,
|
||||
_token,
|
||||
_amount,
|
||||
_contract,
|
||||
|
File diff suppressed because one or more lines are too long
@ -38,7 +38,7 @@
|
||||
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n"
|
||||
},
|
||||
"contracts/activity/TokenClaim.sol": {
|
||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Pausable} from \"@openzeppelin/contracts/security/Pausable.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {HasSignature} from \"../core/HasSignature.sol\";\nimport {TimeChecker} from \"../utils/TimeChecker.sol\";\n\ncontract TokenClaim is HasSignature, ReentrancyGuard, Pausable, TimeChecker {\n using SafeERC20 for IERC20;\n\n uint256 public immutable _CACHED_CHAIN_ID;\n address public immutable _CACHED_THIS;\n address public verifier;\n\n mapping(address token => address wallet) public erc20Wallets;\n \n // store user's claimed amount\n mapping(address user => mapping(address token => uint256 amount)) public claimedAmount;\n\n event EventERC20Wallet(address erc20, address wallet);\n \n event EventVerifierUpdated(address indexed verifier);\n event EventTokenClaimed(\n address indexed user, \n address indexed token, \n address passport, \n uint256 amount, \n uint256 nonce\n );\n\n constructor(address _wallet, address _token, address _verifier, uint256 _duration) TimeChecker(_duration) {\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_THIS = address(this);\n erc20Wallets[_token] = _wallet;\n verifier = _verifier;\n }\n\n /**\n * @dev update verifier address\n */\n function updateVerifier(address _verifier) external onlyOwner {\n require(_verifier != address(0), \"TokenClaimer: address can not be zero\");\n verifier = _verifier;\n emit EventVerifierUpdated(_verifier);\n }\n\n /**\n * @dev update pause state\n */\n function pause() external onlyOwner {\n _pause();\n }\n\n /**\n * @dev update unpause state\n */\n function unpause() external onlyOwner {\n _unpause();\n }\n\n /**\n * @dev update ERC20 wallet\n */\n function updateERC20Wallet(address erc20, address wallet) external onlyOwner {\n require(erc20Wallets[erc20] != wallet, \"TokenClaimer: ERC20 wallet not changed\");\n erc20Wallets[erc20] = wallet;\n emit EventERC20Wallet(erc20, wallet);\n }\n\n /**\n * @dev claim CEC with signature\n */\n\n function claim(\n address passport,\n address token,\n uint256 amount,\n uint256 signTime,\n uint256 saltNonce,\n bytes calldata signature\n ) external signatureValid(signature) timeValid(signTime) nonReentrant whenNotPaused {\n require(passport != address(0), \"TokenClaimer: passport address can not be zero\");\n require(erc20Wallets[token] != address(0), \"TokenClaimer: token is not supported\");\n require(amount > 0, \"TokenClaimer: amount is zero\");\n address user = _msgSender();\n bytes32 criteriaMessageHash = getMessageHash(\n user,\n passport,\n token,\n amount,\n _CACHED_THIS,\n _CACHED_CHAIN_ID,\n signTime,\n saltNonce\n );\n checkSigner(verifier, criteriaMessageHash, signature);\n _useSignature(signature);\n claimedAmount[user][token] += amount;\n IERC20(token).safeTransferFrom(erc20Wallets[token], user, amount);\n emit EventTokenClaimed(user, token, passport, amount, saltNonce);\n }\n\n function getMessageHash(\n address _user,\n address _passport,\n address _token,\n uint256 _amount,\n address _contract,\n uint256 _chainId,\n uint256 _signTime,\n uint256 _saltNonce\n ) public pure returns (bytes32) {\n bytes memory encoded = abi.encodePacked(\n _user,\n _passport,\n _token,\n _amount,\n _contract,\n _chainId,\n _signTime,\n _saltNonce\n );\n return keccak256(encoded);\n }\n}"
|
||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\n\nimport {ReentrancyGuard} from \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport {Pausable} from \"@openzeppelin/contracts/security/Pausable.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {HasSignature} from \"../core/HasSignature.sol\";\nimport {TimeChecker} from \"../utils/TimeChecker.sol\";\n\ncontract TokenClaim is HasSignature, ReentrancyGuard, Pausable, TimeChecker {\n using SafeERC20 for IERC20;\n\n uint256 public immutable _CACHED_CHAIN_ID;\n address public immutable _CACHED_THIS;\n address public verifier;\n\n mapping(address token => address wallet) public erc20Wallets;\n\n // store user's claimed amount\n mapping(address user => mapping(address token => uint256 amount)) public claimedAmount;\n\n event EventERC20Wallet(address erc20, address wallet);\n\n event EventVerifierUpdated(address indexed verifier);\n event EventTokenClaimed(address indexed user, address indexed token, address passport, uint256 amount, uint256 nonce);\n\n constructor(address _wallet, address _token, address _verifier, uint256 _duration) TimeChecker(_duration) {\n _CACHED_CHAIN_ID = block.chainid;\n _CACHED_THIS = address(this);\n erc20Wallets[_token] = _wallet;\n verifier = _verifier;\n }\n\n /**\n * @dev update verifier address\n */\n function updateVerifier(address _verifier) external onlyOwner {\n require(_verifier != address(0), \"TokenClaim: address can not be zero\");\n verifier = _verifier;\n emit EventVerifierUpdated(_verifier);\n }\n\n /**\n * @dev update pause state\n */\n function pause() external onlyOwner {\n _pause();\n }\n\n /**\n * @dev update unpause state\n */\n function unpause() external onlyOwner {\n _unpause();\n }\n\n /**\n * @dev update ERC20 wallet\n */\n function updateERC20Wallet(address erc20, address wallet) external onlyOwner {\n require(erc20Wallets[erc20] != wallet, \"TokenClaim: ERC20 wallet not changed\");\n erc20Wallets[erc20] = wallet;\n emit EventERC20Wallet(erc20, wallet);\n }\n\n /**\n * @dev claim CEC with signature\n * @param account address which eligible to claim, only for event log\n * @param token address of token\n * @param amount amount of token\n * @param signTime time of signature\n * @param saltNonce nonce of signature\n * @param signature signature of claim\n */\n\n function claim(\n address account,\n address token,\n uint256 amount,\n uint256 signTime,\n uint256 saltNonce,\n bytes calldata signature\n ) external signatureValid(signature) timeValid(signTime) nonReentrant whenNotPaused {\n require(erc20Wallets[token] != address(0), \"TokenClaim: token is not supported\");\n require(amount > 0, \"TokenClaim: amount is zero\");\n address user = _msgSender();\n bytes32 criteriaMessageHash = getMessageHash(\n user,\n account,\n token,\n amount,\n _CACHED_THIS,\n _CACHED_CHAIN_ID,\n signTime,\n saltNonce\n );\n checkSigner(verifier, criteriaMessageHash, signature);\n _useSignature(signature);\n claimedAmount[account][token] += amount;\n IERC20(token).safeTransferFrom(erc20Wallets[token], user, amount);\n emit EventTokenClaimed(user, token, account, amount, saltNonce);\n }\n\n function getMessageHash(\n address _user,\n address _account,\n address _token,\n uint256 _amount,\n address _contract,\n uint256 _chainId,\n uint256 _signTime,\n uint256 _saltNonce\n ) public pure returns (bytes32) {\n bytes memory encoded = abi.encodePacked(\n _user,\n _account,\n _token,\n _amount,\n _contract,\n _chainId,\n _signTime,\n _saltNonce\n );\n return keccak256(encoded);\n }\n}\n"
|
||||
},
|
||||
"contracts/core/HasSignature.sol": {
|
||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.19;\nimport {ECDSA} from \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport {Ownable} from \"@openzeppelin/contracts/access/Ownable.sol\";\n\ncontract HasSignature is Ownable {\n mapping(bytes signature => bool status) private _usedSignatures;\n\n function checkSigner(\n address signer,\n bytes32 hash,\n bytes memory signature\n ) public pure {\n bytes32 ethSignedMessageHash = ECDSA.toEthSignedMessageHash(hash);\n\n address recovered = ECDSA.recover(ethSignedMessageHash, signature);\n require(recovered == signer, \"invalid signature\");\n }\n\n modifier signatureValid(bytes calldata signature) {\n require(\n !_usedSignatures[signature],\n \"signature used. please send another transaction with new signature\"\n );\n _;\n }\n\n function _useSignature(bytes calldata signature) internal {\n if (!_usedSignatures[signature]) {\n _usedSignatures[signature] = true;\n }\n }\n}\n"
|
@ -21,6 +21,6 @@
|
||||
"name": "TokenClaim",
|
||||
"type": "logic",
|
||||
"json": "assets/contracts/TokenClaim.json",
|
||||
"address": "0xc058411B15E544291765F15B13c88582b7bceaD0"
|
||||
"address": "0x2C7221588D4FBac2585D71618CD540e74c7413B8"
|
||||
}
|
||||
]
|
@ -20,6 +20,7 @@
|
||||
"deploy:gameitemmall": "hardhat deploy --tags GameItemMall --network imtbl_test --reset",
|
||||
"solhint": "solhint --config ./.solhint.json",
|
||||
"show_verify_list": "npx hardhat verify --list-networks",
|
||||
"convert-abi": "npx hardhat run scripts/convert-abi.js",
|
||||
"verify_sample": "npx hardhat verify --network bsc_test --constructor-args ./verify/tokenclaim.js 0xee0044BF2ACEf7C3D7f6781d8f5DC4d2Dd1CE64c"
|
||||
},
|
||||
"author": "",
|
||||
|
16
scripts/convert-abi.js
Normal file
16
scripts/convert-abi.js
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* npx hardhat run scripts/convert-abi.js
|
||||
*/
|
||||
async function main() {
|
||||
|
||||
const jsonAbi = require("../artifacts/contracts/activity/TokenClaim.sol/TokenClaim.json").abi;
|
||||
|
||||
const iface = new ethers.Interface(jsonAbi);
|
||||
console.log(iface.format(true));
|
||||
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exitCode = 1;
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user