title: what is Vesting and Cliff for ERC20 Token
body: <p>Hello I am writing a crowdsale using <a href="https://github.com/OpenZeppelin/zeppelin-solidity" rel="nofollow noreferrer">Zeppelin-Solidity</a> where I need to integrate the token lock function so the <a href="https://theethereum.wiki/w/index.php/ERC20_Token_Standard" rel="nofollow noreferrer">ERC20 tokens</a> can be locked for a specific period of time.</p>
  
  <p>The zeppelin-solidity seems to provide <a href="https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/TokenVesting.sol" rel="nofollow noreferrer">Tokenvesting.sol</a> for this purpose.</p>
  
  <pre><code>pragma solidity ^0.4.11;
  
  import './ERC20Basic.sol';
  import './SafeERC20.sol';
  import '../ownership/Ownable.sol';
  import '../math/Math.sol';
  import '../math/SafeMath.sol';
  
  /**
   * @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.
   */
  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;
  
    uint256 public cliff;
    uint256 public start;
    uint256 public duration;
  
    bool public revocable;
  
    mapping (address =&gt; uint256) public released;
    mapping (address =&gt; 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.
     * @param _beneficiary address of the beneficiary to whom vested tokens are transferred
     * @param _cliff duration in seconds of the cliff in which tokens will begin to vest
     * @param _duration duration in seconds of the period in which the tokens will vest
     * @param _revocable whether the vesting is revocable or not
     */
    function TokenVesting(address _beneficiary, uint256 _start, uint256 _cliff, uint256 _duration, bool _revocable) {
      require(_beneficiary != address(0));
      require(_cliff &lt;= _duration);
  
      beneficiary = _beneficiary;
      revocable = _revocable;
      duration = _duration;
      cliff = _start.add(_cliff);
      start = _start;
    }
  
    /**
     * @notice Transfers vested tokens to beneficiary.
     * @param token ERC20 token which is being vested
     */
    function release(ERC20Basic token) public {
      uint256 unreleased = releasableAmount(token);
  
      require(unreleased &gt; 0);
  
      released[token] = released[token].add(unreleased);
  
      token.safeTransfer(beneficiary, unreleased);
  
      Released(unreleased);
    }
  
    /**
     * @notice Allows the owner to revoke the vesting. Tokens already vested
     * remain in the contract, the rest are returned to the owner.
     * @param token ERC20 token which is being vested
     */
    function revoke(ERC20Basic token) public onlyOwner {
      require(revocable);
      require(!revoked[token]);
  
      uint256 balance = token.balanceOf(this);
  
      uint256 unreleased = releasableAmount(token);
      uint256 refund = balance.sub(unreleased);
  
      revoked[token] = true;
  
      token.safeTransfer(owner, refund);
  
      Revoked();
    }
  
    /**
     * @dev Calculates the amount that has already vested but hasn't been released yet.
     * @param token ERC20 token which is being vested
     */
    function releasableAmount(ERC20Basic token) public constant returns (uint256) {
      return vestedAmount(token).sub(released[token]);
    }
  
    /**
     * @dev Calculates the amount that has already vested.
     * @param token ERC20 token which is being vested
     */
    function vestedAmount(ERC20Basic token) public constant returns (uint256) {
      uint256 currentBalance = token.balanceOf(this);
      uint256 totalBalance = currentBalance.add(released[token]);
  
      if (now &lt; cliff) {
        return 0;
      } else if (now &gt;= start.add(duration) || revoked[token]) {
        return totalBalance;
      } else {
        return totalBalance.mul(now.sub(start)).div(duration);
      }
    }
  }
  © 2017 GitHub, Inc.
  </code></pre>
  
  <p>But there are different paramters in it (start , vesting period and cliff). I am not sure how this will work</p>
  
  <p>-Whether tokens are transferred to the beneficiary first and then gets lock
  or tokens are stored in locked contract and released later. 
  And how vesting and cliff works. 
  I have researched vesting and cliff on <a href="http://www.investopedia.com/terms/c/cliffvesting.asp" rel="nofollow noreferrer">Investopedia</a> but doesn't clarify the concept on how this will be described with respect to crowdsale(cliff, Vesting And Revoked)</p>