contract TokenVesting is Ownable {
  using SafeMath for uint256;
  using SafeERC20 for ERC20Basic;

  event Released(uint256 amount);
  event Revoked();

  // beneficiary of tokens after they are released
  address public beneficiary;
  
  ERC20Basic public token;
  address public addressToken; 
  uint256 public cliff;
  uint256 public start;
  uint256 public duration;

  mapping (address => uint256) public released;
  mapping (address => bool) public revoked;

  /**
   * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
   * _beneficiary, gradually in a linear fashion until _start + _duration. By then all
   * of the balance will have vested.
   */
  function TokenVesting() public
  { 
    //address of the beneficiary to whom vested tokens are transferred
    beneficiary = 0xEdc62572208C819ee413a2e19a037BbC3eA1F9c8; //address of team
    //duration in seconds of the period in which the tokens will vest
    duration = 24 * 31 * 24 * 60 * 60; 
    //date of start
    start = 1523275200; //09 Apr 2018 12:00:00 
    cliff = start;
  }

  function setToken(address _addressToken) public onlyOwner{
    require(_addressToken != address(0));  
    addressToken = _addressToken;  
    token = ERC20Basic(_addressToken);  
  }
 
  function release() public {
    uint256 unreleased = releasableAmount();
    require(addressToken != address(0));
    require(unreleased > 0);

    released[token] = released[token].add(unreleased);

    token.safeTransfer(beneficiary, unreleased);

    emit Released(unreleased);
  }


  /**
   * Calculates the amount that has already vested but hasn't been released yet.
   */
  function releasableAmount() public view returns (uint256) {
    return vestedAmount().sub(released[token]);
  }

  /**
   * Calculates the amount that has already vested.
   */
  function vestedAmount() public view returns (uint256) {
    uint256 currentBalance = token.balanceOf(this);
    uint256 totalBalance = currentBalance.add(released[token]);

    if (block.timestamp < cliff) {
      return 0;
    } else if (block.timestamp >= start.add(duration) || revoked[token]) {
      return totalBalance;
    } else {
      return totalBalance.mul(block.timestamp.sub(start)).div(duration);
    }
  }
}
/**
 * @title TokenVesting
 * @dev A token holder contract that can release its token balance gradually like a
 * typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
 * owner.
 */
function releasableAmount() public view returns (uint256) {
  return vestedAmount().sub(released[token]);
}

/**
 * Calculates the amount that has already vested but hasn't been released yet.
 */