From bcc049abffe2269c3607316779e0eead2e058993 Mon Sep 17 00:00:00 2001 From: CounterFire2023 <136581895+CounterFire2023@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:47:06 +0800 Subject: [PATCH] add contract for cec distributor --- contracts/activity/CECDistributor.sol | 81 +++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 contracts/activity/CECDistributor.sol diff --git a/contracts/activity/CECDistributor.sol b/contracts/activity/CECDistributor.sol new file mode 100644 index 0000000..b0207e1 --- /dev/null +++ b/contracts/activity/CECDistributor.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; +import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; + +/** + * @title CECDistributor + * @dev CECDistributor is a contract for distributing CEC token with unlock time + * after all data is set, transfer owner to timelock contract + */ +contract CECDistributor is ReentrancyGuard, Pausable, Ownable { + using SafeERC20 for IERC20; + + mapping(address account => uint256 amount) public balanceMap; + // unlock time for this distributor + uint256 public unlockTime; + + IERC20 public immutable cecToken; + + event EventBalanceUpdated(address indexed account, uint256 amount); + event EventUnlockTimeUpdated(uint256 unlockTime); + event EventCECClaimed(address indexed user, address indexed to, uint256 amount); + + constructor(address _cecToken, uint256 _unlockTime) { + cecToken = IERC20(_cecToken); + unlockTime = _unlockTime; + } + /** + * @dev update pause state + */ + function pause() external onlyOwner { + _pause(); + } + + /** + * @dev update unpause state + */ + function unpause() external onlyOwner { + _unpause(); + } + + function updateBalance(address account, uint256 amount) external onlyOwner { + balanceMap[account] = amount; + emit EventBalanceUpdated(account, amount); + } + + function updateBalances(address[] calldata accounts, uint256[] calldata amounts) external onlyOwner { + require(accounts.length == amounts.length, "CECDistributor: invalid input"); + for (uint256 i = 0; i < accounts.length; i++) { + balanceMap[accounts[i]] = amounts[i]; + emit EventBalanceUpdated(accounts[i], amounts[i]); + } + } + + function updateUnlockTime(uint256 _unlockTime) external onlyOwner { + unlockTime = _unlockTime; + emit EventUnlockTimeUpdated(_unlockTime); + } + + function withdrawToken(address to, uint256 amount) external onlyOwner { + require(to != address(0), "CECDistributor: invalid address"); + cecToken.safeTransfer(to, amount); + } + + function claim( + address to + ) external nonReentrant whenNotPaused { + require(block.timestamp > unlockTime, "CECDistributor: not unlock time"); + require(to != address(0), "CECDistributor: invalid address"); + address _user = _msgSender(); + uint256 amount = balanceMap[_user]; + require(amount > 0, "CECDistributor: no balance"); + balanceMap[_user] = 0; + cecToken.safeTransfer(to, amount); + emit EventCECClaimed(_user, to, amount); + } +}