VestedToken.sol 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. pragma solidity ^0.4.8;
  2. import "./StandardToken.sol";
  3. import "./LimitedTransferToken.sol";
  4. /**
  5. * @title Vested token
  6. * @dev This tokens can be granted to a specific address after a determined
  7. amount of time.
  8. */
  9. contract VestedToken is StandardToken, LimitedTransferToken {
  10. struct TokenGrant {
  11. address granter;
  12. uint256 value;
  13. uint64 cliff;
  14. uint64 vesting;
  15. uint64 start;
  16. }
  17. mapping (address => TokenGrant[]) public grants;
  18. /**
  19. * @dev Grant tokens to a specified address
  20. * @param _to address The address which the tokens will be granted to.
  21. * @param _value uint256 The amount of tokens to be granted.
  22. * @param _start uint 64 The time of the begining of the grant.
  23. * @param _cliff uint64 The time before the grant is enforceble.
  24. * @param _vesting uint64 The time in which the tokens will be vested.
  25. */
  26. function grantVestedTokens(
  27. address _to,
  28. uint256 _value,
  29. uint64 _start,
  30. uint64 _cliff,
  31. uint64 _vesting) {
  32. if (_cliff < _start) {
  33. throw;
  34. }
  35. if (_vesting < _start) {
  36. throw;
  37. }
  38. if (_vesting < _cliff) {
  39. throw;
  40. }
  41. TokenGrant memory grant = TokenGrant(msg.sender, _value, _cliff, _vesting, _start);
  42. grants[_to].push(grant);
  43. transfer(_to, _value);
  44. }
  45. /**
  46. * @dev Revoke the grant of tokens of a specifed address.
  47. * @param _holder address The address which will have its tokens revoked.
  48. * @param _grantId uint The id of the token grant.
  49. */
  50. function revokeTokenGrant(address _holder, uint _grantId) {
  51. TokenGrant grant = grants[_holder][_grantId];
  52. if (grant.granter != msg.sender) {
  53. throw;
  54. }
  55. uint256 nonVested = nonVestedTokens(grant, uint64(now));
  56. // remove grant from array
  57. delete grants[_holder][_grantId];
  58. grants[_holder][_grantId] = grants[_holder][grants[_holder].length - 1];
  59. grants[_holder].length -= 1;
  60. balances[msg.sender] = balances[msg.sender].add(nonVested);
  61. balances[_holder] = balances[_holder].sub(nonVested);
  62. Transfer(_holder, msg.sender, nonVested);
  63. }
  64. /**
  65. * @dev Check the amount of grants that an address has.
  66. * @param _holder address The holder of the grants.
  67. * @return A uint representing the index of the grant.
  68. */
  69. function tokenGrantsCount(address _holder) constant returns (uint index) {
  70. return grants[_holder].length;
  71. }
  72. /**
  73. * @dev
  74. * @param _holder address The address which will have its tokens revoked.
  75. * @param _grantId uint The id of the token grant.
  76. */
  77. function tokenGrant(address _holder, uint _grantId) constant returns (address granter, uint256 value, uint256 vested, uint64 start, uint64 cliff, uint64 vesting) {
  78. TokenGrant grant = grants[_holder][_grantId];
  79. granter = grant.granter;
  80. value = grant.value;
  81. start = grant.start;
  82. cliff = grant.cliff;
  83. vesting = grant.vesting;
  84. vested = vestedTokens(grant, uint64(now));
  85. }
  86. function vestedTokens(TokenGrant grant, uint64 time) private constant returns (uint256) {
  87. return calculateVestedTokens(
  88. grant.value,
  89. uint256(time),
  90. uint256(grant.start),
  91. uint256(grant.cliff),
  92. uint256(grant.vesting)
  93. );
  94. }
  95. function calculateVestedTokens(
  96. uint256 tokens,
  97. uint256 time,
  98. uint256 start,
  99. uint256 cliff,
  100. uint256 vesting) constant returns (uint256 vestedTokens)
  101. {
  102. if (time < cliff) {
  103. return 0;
  104. }
  105. if (time >= vesting) {
  106. return tokens;
  107. }
  108. uint256 cliffTokens = tokens.mul(cliff.sub(start)).div(vesting.sub(start));
  109. vestedTokens = cliffTokens;
  110. uint256 vestingTokens = tokens.sub(cliffTokens);
  111. vestedTokens = vestedTokens.add(vestingTokens.mul(time.sub(cliff)).div(vesting.sub(cliff)));
  112. }
  113. function nonVestedTokens(TokenGrant grant, uint64 time) private constant returns (uint256) {
  114. return grant.value.sub(vestedTokens(grant, time));
  115. }
  116. function lastTokenIsTransferableDate(address holder) constant public returns (uint64 date) {
  117. date = uint64(now);
  118. uint256 grantIndex = grants[holder].length;
  119. for (uint256 i = 0; i < grantIndex; i++) {
  120. date = SafeMath.max64(grants[holder][i].vesting, date);
  121. }
  122. }
  123. function transferableTokens(address holder, uint64 time) constant public returns (uint256 nonVested) {
  124. uint256 grantIndex = grants[holder].length;
  125. for (uint256 i = 0; i < grantIndex; i++) {
  126. uint256 current = nonVestedTokens(grants[holder][i], time);
  127. nonVested = nonVested.add(current);
  128. }
  129. return SafeMath.min256(balances[holder].sub(nonVested), super.transferableTokens(holder, time));
  130. }
  131. }