Commit f8124337 by Jorge Izquierdo

Small refactor and documentation

parent 713b4722
pragma solidity ^0.4.8; pragma solidity ^0.4.8;
import "./StandardToken.sol"; import "./StandardToken.sol";
import "./TransferableToken.sol"; import "./TransferableToken.sol";
contract VestedToken is StandardToken, TransferableToken { contract VestedToken is StandardToken, TransferableToken {
struct TokenGrant { struct TokenGrant {
address granter; address granter; // 20 bytes
uint256 value; uint256 value; // 32 bytes
uint64 cliff; uint64 cliff;
uint64 vesting; uint64 vesting;
uint64 start; uint64 start; // 3 * 8 = 24 bytes
bool revokable; bool revokable;
bool burnsOnRevoke; bool burnsOnRevoke; // 2 * 1 = 2 bits? or 2 bytes?
} } // total 78 bytes = 3 sstore per operation (32 per sstore)
mapping (address => TokenGrant[]) public grants; mapping (address => TokenGrant[]) public grants;
event NewTokenGrant(address indexed from, address indexed to, uint256 value, uint256 grantId);
function grantVestedTokens( function grantVestedTokens(
address _to, address _to,
uint256 _value, uint256 _value,
...@@ -24,21 +25,17 @@ contract VestedToken is StandardToken, TransferableToken { ...@@ -24,21 +25,17 @@ contract VestedToken is StandardToken, TransferableToken {
uint64 _cliff, uint64 _cliff,
uint64 _vesting, uint64 _vesting,
bool _revokable, bool _revokable,
bool _burnsOnRevoke) { bool _burnsOnRevoke
) public {
if (_cliff < _start) { // Check for date inconsistencies that may cause unexpected behavior
throw; if (_cliff < _start || _vesting < _cliff) {
}
if (_vesting < _start) {
throw;
}
if (_vesting < _cliff) {
throw; throw;
} }
grants[_to].push( uint id = grants[_to].push(
TokenGrant( TokenGrant(
msg.sender, _revokable ? msg.sender : 0, // avoid storing an extra 20 bytes when it is non-revokable
_value, _value,
_cliff, _cliff,
_vesting, _vesting,
...@@ -49,9 +46,11 @@ contract VestedToken is StandardToken, TransferableToken { ...@@ -49,9 +46,11 @@ contract VestedToken is StandardToken, TransferableToken {
); );
transfer(_to, _value); transfer(_to, _value);
NewTokenGrant(msg.sender, _to, _value, id);
} }
function revokeTokenGrant(address _holder, uint _grantId) { function revokeTokenGrant(address _holder, uint _grantId) public {
TokenGrant grant = grants[_holder][_grantId]; TokenGrant grant = grants[_holder][_grantId];
if (!grant.revokable) { // Check if grant was revokable if (!grant.revokable) { // Check if grant was revokable
...@@ -76,6 +75,15 @@ contract VestedToken is StandardToken, TransferableToken { ...@@ -76,6 +75,15 @@ contract VestedToken is StandardToken, TransferableToken {
Transfer(_holder, receiver, nonVested); Transfer(_holder, receiver, nonVested);
} }
function transferableTokens(address holder, uint64 time) constant public returns (uint256 nonVested) {
uint256 grantIndex = tokenGrantsCount(holder);
for (uint256 i = 0; i < grantIndex; i++) {
nonVested = safeAdd(nonVested, nonVestedTokens(grants[holder][i], time));
}
return min256(safeSub(balances[holder], nonVested), super.transferableTokens(holder, time));
}
function tokenGrantsCount(address _holder) constant returns (uint index) { function tokenGrantsCount(address _holder) constant returns (uint index) {
return grants[_holder].length; return grants[_holder].length;
} }
...@@ -138,13 +146,4 @@ contract VestedToken is StandardToken, TransferableToken { ...@@ -138,13 +146,4 @@ contract VestedToken is StandardToken, TransferableToken {
date = max64(grants[holder][i].vesting, date); date = max64(grants[holder][i].vesting, date);
} }
} }
function transferableTokens(address holder, uint64 time) constant public returns (uint256 nonVested) {
uint256 grantIndex = grants[holder].length;
for (uint256 i = 0; i < grantIndex; i++) {
nonVested = safeAdd(nonVested, nonVestedTokens(grants[holder][i], time));
}
return min256(safeSub(balances[holder], nonVested), super.transferableTokens(holder, time));
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment