contract TokenTimelock {
    using SafeERC20 for IERC20;
    using SafeMath for uint256;

    // ERC20 basic token contract being held
    IERC20 private _token;
    // beneficiary of tokens after they are released
    address private _beneficiary;
    // timestamp when token release is enabled
    uint256 private _nextReleaseTime;
    uint256 private RELEASE_INTERVAL = 90 days;
    uint256 private RELEASE_PORTION = 175 ether;

    constructor (IERC20 token, address beneficiary) public {
        // solhint-disable-next-line not-rely-on-time
        _token = token;
        _beneficiary = beneficiary;
        _nextReleaseTime = block.timestamp.add(RELEASE_INTERVAL);
    }

    /**
     * @return the token being held.
     */
    function token() public view returns (IERC20) {
        return _token;
    }

    /**
     * @return the beneficiary of the tokens.
     */
    function beneficiary() public view returns (address) {
        return _beneficiary;
    }

    /**
     * @return the time when the tokens are released.
     */
    function nextReleaseTime() public view returns (uint256) {
        return _nextReleaseTime;
    }

    /**
     * @notice Transfers tokens held by timelock to beneficiary.
     */
    function release() public {
        // solhint-disable-next-line not-rely-on-time
        require(block.timestamp >= _nextReleaseTime, "TokenTimelock: current time is before release time");
        uint256 amount = _token.balanceOf(address(this));
        require(amount > 0, "TokenTimelock: no tokens to release");
        if (amount > RELEASE_PORTION) {
            amount = RELEASE_PORTION;
        }
        _token.safeTransfer(_beneficiary, amount);
        _nextReleaseTime = _nextReleaseTime.add(RELEASE_INTERVAL);
    }
}
function release() public {
    // solhint-disable-next-line not-rely-on-time
    require(block.timestamp >= _nextReleaseTime, "TokenTimelock: current time is before release time");
    uint256 amount = _token.balanceOf(address(this));
    require(amount > 0, "TokenTimelock: no tokens to release");
    if (amount > RELEASE_PORTION) {
        amount = RELEASE_PORTION;
    }
    _token.safeTransfer(_beneficiary, amount);
    _nextReleaseTime = _nextReleaseTime.add(RELEASE_INTERVAL);
}

/**
 * @notice Transfers tokens held by timelock to beneficiary.
 */