TokenVesting.sol 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. pragma solidity ^0.4.11;
  2. import './ERC20Basic.sol';
  3. import '../ownership/Ownable.sol';
  4. import '../math/Math.sol';
  5. import '../math/SafeMath.sol';
  6. /**
  7. * @title TokenVesting
  8. * @dev A token holder contract that can release its token balance gradually like a
  9. * typical vesting scheme, with a cliff and vesting period. Revokable by the owner.
  10. */
  11. contract TokenVesting is Ownable {
  12. using SafeMath for uint256;
  13. // beneficiary of tokens after they are released
  14. address beneficiary;
  15. uint256 cliff;
  16. uint256 start;
  17. uint256 end;
  18. mapping (address => uint256) released;
  19. /**
  20. * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
  21. * _beneficiary, gradually in a linear fashion until _end. By then all of the balance
  22. * will have vested.
  23. * @param _beneficiary address of the beneficiary to whom vested tokens are transferred
  24. * @param _cliff timestamp of the moment when tokens will begin to vest
  25. * @param _end timestamp of the moment when all balance will have been vested
  26. */
  27. function TokenVesting(address _beneficiary, uint256 _cliff, uint256 _end) {
  28. require(_beneficiary != 0x0);
  29. require(_cliff > now);
  30. require(_end > _cliff);
  31. beneficiary = _beneficiary;
  32. cliff = _cliff;
  33. end = _end;
  34. start = now;
  35. }
  36. /**
  37. * @notice Transfers vested tokens to beneficiary.
  38. * @param token ERC20 token which is being vested
  39. */
  40. function release(ERC20Basic token) {
  41. uint256 vested = vestedAmount(token);
  42. require(vested > 0);
  43. token.transfer(beneficiary, vested);
  44. released[token] = released[token].add(vested);
  45. }
  46. /**
  47. * @notice Allows the owner to revoke the vesting. Tokens already vested remain in the contract.
  48. * @param token ERC20 token which is being vested
  49. */
  50. function revoke(ERC20Basic token) onlyOwner {
  51. uint256 balance = token.balanceOf(this);
  52. uint256 vested = vestedAmount(token);
  53. token.transfer(owner, balance - vested);
  54. }
  55. /**
  56. * @dev Calculates the amount that has already vested.
  57. * @param token ERC20 token which is being vested
  58. */
  59. function vestedAmount(ERC20Basic token) constant returns (uint256) {
  60. if (now < cliff) {
  61. return 0;
  62. } else if (now >= end) {
  63. return token.balanceOf(this);
  64. } else {
  65. uint256 currentBalance = token.balanceOf(this);
  66. uint256 totalBalance = currentBalance.add(released[token]);
  67. uint256 vested = totalBalance.mul(now - start).div(end - start);
  68. return Math.min256(currentBalance, vested);
  69. }
  70. }
  71. }