contract PhotochainVesting {
    // ERC20 token contract being held
    ERC20 public token;

    // beneficiary of tokens after they are released
    address public beneficiary;

    // timestamp when token release is enabled
    uint256 public releaseTime;

    constructor(ERC20 _token, address _beneficiary, uint256 _releaseTime) public {
        // solium-disable-next-line security/no-block-members
        require(_releaseTime > block.timestamp, "Release time must be in future");

        // solium-disable-next-line security/no-block-members
        require(_releaseTime < block.timestamp + 3 * 365 days, "Release time must not exceed 3 years");

        token = _token;
        beneficiary = _beneficiary;
        releaseTime = _releaseTime;
    }

    /**
     * @notice Transfers tokens held by timelock to beneficiary.
     */
    function release() public {
        // solium-disable-next-line security/no-block-members
        require(block.timestamp >= releaseTime, "Release time must pass");

        uint256 amount = token.balanceOf(address(this));
        require(amount > 0, "Contract must hold any tokens");

        require(token.transfer(beneficiary, amount), "Transfer must succeed");
    }
}
/**
 * @title Photochain token vesting period contract
 *
 * @dev PhotochainVesting is a token holder contract that will allow a
 * beneficiary to extract the tokens after a given release time
 * @dev Based on https://github.com/OpenZeppelin/zeppelin-solidity
 */
function release() public {
        // solium-disable-next-line security/no-block-members
        require(block.timestamp >= releaseTime, "Release time must pass");

        uint256 amount = token.balanceOf(address(this));
        require(amount > 0, "Contract must hold any tokens");

        require(token.transfer(beneficiary, amount), "Transfer must succeed");
    }
/**
 * @notice Transfers tokens held by timelock to beneficiary.
 */