address[]) private lockersByWallet; mapping(address => address[]) private lockersByToken; event LockerCreated( address indexed lockerAddress, address indexed owner, address indexed token, uint256 amount, uint256 unlockTimestamp, TokenLocker.UnlockMode mode ); /** * @notice Create a new token locker with CLIFF or DRIP mode. * @param _token Token to be locked. * @param _amount Amount of tokens to lock. * @param _lockDuration Duration (for CLIFF) or total drip period (for DRIP). * @param _mode Unlock mode: CLIFF or DRIP. */ function createLocker( "> address[]) private lockersByWallet; mapping(address => address[]) private lockersByToken; event LockerCreated( address indexed lockerAddress, address indexed owner, address indexed token, uint256 amount, uint256 unlockTimestamp, TokenLocker.UnlockMode mode ); /** * @notice Create a new token locker with CLIFF or DRIP mode. * @param _token Token to be locked. * @param _amount Amount of tokens to lock. * @param _lockDuration Duration (for CLIFF) or total drip period (for DRIP). * @param _mode Unlock mode: CLIFF or DRIP. */ function createLocker( "> address[]) private lockersByWallet; mapping(address => address[]) private lockersByToken; event LockerCreated( address indexed lockerAddress, address indexed owner, address indexed token, uint256 amount, uint256 unlockTimestamp, TokenLocker.UnlockMode mode ); /** * @notice Create a new token locker with CLIFF or DRIP mode. * @param _token Token to be locked. * @param _amount Amount of tokens to lock. * @param _lockDuration Duration (for CLIFF) or total drip period (for DRIP). * @param _mode Unlock mode: CLIFF or DRIP. */ function createLocker( ">
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./TokenLocker.sol"; // Make sure to adjust import path as needed
/**
 * @title TokenLockerFactory
 * @notice Deploys new TokenLocker contracts and transfers tokens into them.
 */
contract TokenLockerFactory {
    address[] public allLockers;
    mapping(address => address[]) private lockersByWallet;
    mapping(address => address[]) private lockersByToken;
    event LockerCreated(
        address indexed lockerAddress,
        address indexed owner,
        address indexed token,
        uint256 amount,
        uint256 unlockTimestamp,
        TokenLocker.UnlockMode mode
    );
    /**
     * @notice Create a new token locker with CLIFF or DRIP mode.
     * @param _token        Token to be locked.
     * @param _amount       Amount of tokens to lock.
     * @param _lockDuration Duration (for CLIFF) or total drip period (for DRIP).
     * @param _mode         Unlock mode: CLIFF or DRIP.
     */
    function createLocker(
        address _token,
        uint256 _amount,
        uint256 _lockDuration,
        TokenLocker.UnlockMode _mode
    ) external returns (address) {
        require(_token != address(0), "Token address cannot be zero");
        require(_amount > 0, "Amount must be > 0");
        require(_lockDuration > 0, "Lock duration must be > 0");
        // Transfer tokens to factory
        bool success = IERC20(_token).transferFrom(msg.sender, address(this), _amount);
        require(success, "Token transfer to factory failed");
        uint256 unlockTime = block.timestamp + _lockDuration;
        // Deploy the TokenLocker
        TokenLocker locker = new TokenLocker(
            _token,
            msg.sender,
            _amount,
            unlockTime,
            _mode,
            _mode == TokenLocker.UnlockMode.DRIP ? _lockDuration : 0
        );
        // Send tokens from factory to locker
        success = IERC20(_token).transfer(address(locker), _amount);
        require(success, "Token transfer to locker failed");
        // Save locker
        allLockers.push(address(locker));
        lockersByWallet[msg.sender].push(address(locker));
        lockersByToken[_token].push(address(locker));
        emit LockerCreated(address(locker), msg.sender, _token, _amount, unlockTime, _mode);
        return address(locker);
    }
    function getAllLockersLength() external view returns (uint256) {
        return allLockers.length;
    }
    function getLockersByWalletAddress(address _wallet) external view returns (address[] memory) {
        return lockersByWallet[_wallet];
    }
    function getLockersByTokenAddress(address _token) external view returns (address[] memory) {
        return lockersByToken[_token];
    }
}