// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {MoonRushTokenLocker} from "./MoonRushTokenLocker.sol"; /// @title MoonRushLockerFactory — Create token/LP locks; $10 fee funds RUSH buy & burn. contract MoonRushLockerFactory is Ownable { using SafeERC20 for IERC20; address public feeCollector; uint256 public lockFee; event LockCreated( address indexed creator, address indexed locker, address indexed token, address beneficiary, uint256 amount, uint256 unlockTime, MoonRushTokenLocker.LockKind lockKind ); event LockFeeUpdated(uint256 fee); event FeeCollectorUpdated(address indexed collector); constructor(address feeCollector_, uint256 lockFee_) Ownable(msg.sender) { require(feeCollector_ != address(0), "collector=0"); feeCollector = feeCollector_; lockFee = lockFee_; } function setLockFee(uint256 fee) external onlyOwner { lockFee = fee; emit LockFeeUpdated(fee); } function setFeeCollector(address collector) external onlyOwner { require(collector != address(0), "collector=0"); feeCollector = collector; emit FeeCollectorUpdated(collector); } function createTokenLock( address token, address beneficiary, uint256 unlockTime, uint256 amount ) external payable returns (address locker) { locker = _createLock(token, beneficiary, unlockTime, amount, MoonRushTokenLocker.LockKind.Token); } function createLiquidityLock( address lpToken, address beneficiary, uint256 unlockTime, uint256 amount ) external payable returns (address locker) { locker = _createLock(lpToken, beneficiary, unlockTime, amount, MoonRushTokenLocker.LockKind.Liquidity); } function _createLock( address token, address beneficiary, uint256 unlockTime, uint256 amount, MoonRushTokenLocker.LockKind lockKind ) private returns (address locker) { require(token != address(0), "token=0"); require(beneficiary != address(0), "beneficiary=0"); require(unlockTime > block.timestamp, "unlock in past"); require(amount > 0, "amount=0"); _collectFee(); locker = address( new MoonRushTokenLocker(msg.sender, beneficiary, token, unlockTime, amount, lockKind) ); IERC20(token).safeTransferFrom(msg.sender, locker, amount); emit LockCreated(msg.sender, locker, token, beneficiary, amount, unlockTime, lockKind); } function _collectFee() private { require(msg.value >= lockFee, "fee too low"); (bool ok,) = feeCollector.call{value: msg.value}(""); require(ok, "fee transfer failed"); } }