TokenVesting.sol 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. Optionally revocable by the
  10. * owner.
  11. */
  12. contract TokenVesting is Ownable {
  13. using SafeMath for uint256;
  14. // beneficiary of tokens after they are released
  15. address beneficiary;
  16. uint256 cliff;
  17. uint256 start;
  18. uint256 end;
  19. bool revocable;
  20. mapping (address => uint256) released;
  21. /**
  22. * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
  23. * _beneficiary, gradually in a linear fashion until _end. By then all of the balance
  24. * will have vested.
  25. * @param _beneficiary address of the beneficiary to whom vested tokens are transferred
  26. * @param _cliff timestamp of the moment when tokens will begin to vest
  27. * @param _end timestamp of the moment when all balance will have been vested
  28. * @param _revocable whether the vesting is revocable or not
  29. */
  30. function TokenVesting(address _beneficiary, uint256 _cliff, uint256 _end, bool _revocable) {
  31. require(_beneficiary != 0x0);
  32. require(_cliff > now);
  33. require(_end > _cliff);
  34. beneficiary = _beneficiary;
  35. cliff = _cliff;
  36. end = _end;
  37. revocable = _revocable;
  38. start = now;
  39. }
  40. /**
  41. * @notice Transfers vested tokens to beneficiary.
  42. * @param token ERC20 token which is being vested
  43. */
  44. function release(ERC20Basic token) {
  45. uint256 vested = vestedAmount(token);
  46. require(vested > 0);
  47. token.transfer(beneficiary, vested);
  48. released[token] = released[token].add(vested);
  49. }
  50. /**
  51. * @notice Allows the owner to revoke the vesting. Tokens already vested remain in the contract.
  52. * @param token ERC20 token which is being vested
  53. */
  54. function revoke(ERC20Basic token) onlyOwner {
  55. require(revocable);
  56. uint256 balance = token.balanceOf(this);
  57. uint256 vested = vestedAmount(token);
  58. token.transfer(owner, balance - vested);
  59. }
  60. /**
  61. * @dev Calculates the amount that has already vested.
  62. * @param token ERC20 token which is being vested
  63. */
  64. function vestedAmount(ERC20Basic token) constant returns (uint256) {
  65. if (now < cliff) {
  66. return 0;
  67. } else if (now >= end) {
  68. return token.balanceOf(this);
  69. } else {
  70. uint256 currentBalance = token.balanceOf(this);
  71. uint256 totalBalance = currentBalance.add(released[token]);
  72. uint256 vested = totalBalance.mul(now - start).div(end - start);
  73. return Math.min256(currentBalance, vested);
  74. }
  75. }
  76. }