// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /// @notice Optional immutable cliff; allocation and duration need launch approval. contract FoldGenesisLock { using SafeERC20 for IERC20; IERC20 public immutable token; address public immutable beneficiary; uint256 public immutable unlockAt; error InvalidConfiguration(); error Locked(); event Released(uint256 amount); constructor(address token_, address beneficiary_, uint256 unlockAt_) { if (token_.code.length == 0 || beneficiary_ == address(0) || unlockAt_ <= block.timestamp) revert InvalidConfiguration(); token = IERC20(token_); beneficiary = beneficiary_; unlockAt = unlockAt_; } function release() external { if (block.timestamp < unlockAt) revert Locked(); uint256 amount = token.balanceOf(address(this)); if (amount != 0) { token.safeTransfer(beneficiary, amount); emit Released(amount); } } }