Browse Source

Merge pull request #155 from AragonOne/vested-transfer-from

[VestedToken] Check if tokens can be transferred on transferFrom
Manuel Aráoz 8 years ago
parent
commit
52d0df7961
2 changed files with 30 additions and 8 deletions
  1. 13 8
      contracts/token/VestedToken.sol
  2. 17 0
      test/VestedToken.js

+ 13 - 8
contracts/token/VestedToken.sol

@@ -15,6 +15,19 @@ contract VestedToken is StandardToken {
 
   mapping (address => TokenGrant[]) public grants;
 
+  modifier canTransfer(address _sender, uint _value) {
+    if (_value > transferableTokens(_sender, uint64(now))) throw;
+    _;
+  }
+
+  function transfer(address _to, uint _value) canTransfer(msg.sender, _value) returns (bool success) {
+    return super.transfer(_to, _value);
+  }
+
+  function transferFrom(address _from, address _to, uint _value) canTransfer(_from, _value) returns (bool success) {
+    return super.transferFrom(_from, _to, _value);
+  }
+
   function grantVestedTokens(
     address _to,
     uint256 _value,
@@ -126,12 +139,4 @@ contract VestedToken is StandardToken {
 
     return safeSub(balances[holder], nonVested);
   }
-
-  function transfer(address _to, uint _value) returns (bool success) {
-    if (_value > transferableTokens(msg.sender, uint64(now))) {
-      throw;
-    }
-
-    return super.transfer(_to, _value);
-  }
 }

+ 17 - 0
test/VestedToken.js

@@ -52,6 +52,16 @@ contract('VestedToken', function(accounts) {
       assert.fail('should have thrown before');
     })
 
+    it('throws when trying to transfer from non vested tokens', async () => {
+      try {
+        await token.approve(accounts[7], 1, { from: receiver })
+        await token.transferFrom(receiver, accounts[7], tokenAmount, { from: accounts[7] })
+      } catch(error) {
+        return assertJump(error);
+      }
+      assert.fail('should have thrown before');
+    })
+
     it('can be revoked by granter', async () => {
       await token.revokeTokenGrant(receiver, 0, { from: granter });
       assert.equal(await token.balanceOf(receiver), 0);
@@ -78,5 +88,12 @@ contract('VestedToken', function(accounts) {
       await token.transfer(accounts[7], tokenAmount, { from: receiver })
       assert.equal(await token.balanceOf(accounts[7]), tokenAmount);
     })
+
+    it('can approve and transferFrom all tokens after vesting ends', async () => {
+      await timer(vesting + 1);
+      await token.approve(accounts[7], tokenAmount, { from: receiver })
+      await token.transferFrom(receiver, accounts[7], tokenAmount, { from: accounts[7] })
+      assert.equal(await token.balanceOf(accounts[7]), tokenAmount);
+    })
   })
 });