Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 15169b245b | |||
| cc222c02a9 | |||
| 29ab824e5c | |||
| 8d828bc789 | |||
| f038cdc9c9 | |||
| 72d31c2471 | |||
| b31c92c27c | |||
| eb2cb5dd06 | |||
| 52d0df7961 | |||
| 12aadbed51 | |||
| 23703280ee | |||
| 5e50090da0 | |||
| b9257a1092 |
@ -27,6 +27,9 @@ contract StandardToken is ERC20, SafeMath {
|
|||||||
function transferFrom(address _from, address _to, uint _value) returns (bool success) {
|
function transferFrom(address _from, address _to, uint _value) returns (bool success) {
|
||||||
var _allowance = allowed[_from][msg.sender];
|
var _allowance = allowed[_from][msg.sender];
|
||||||
|
|
||||||
|
// Check is not needed because safeSub(_allowance, _value) will already throw if this condition is not met
|
||||||
|
// if (_value > _allowance) throw;
|
||||||
|
|
||||||
balances[_to] = safeAdd(balances[_to], _value);
|
balances[_to] = safeAdd(balances[_to], _value);
|
||||||
balances[_from] = safeSub(balances[_from], _value);
|
balances[_from] = safeSub(balances[_from], _value);
|
||||||
allowed[_from][msg.sender] = safeSub(_allowance, _value);
|
allowed[_from][msg.sender] = safeSub(_allowance, _value);
|
||||||
|
|||||||
@ -15,6 +15,19 @@ contract VestedToken is StandardToken {
|
|||||||
|
|
||||||
mapping (address => TokenGrant[]) public grants;
|
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(
|
function grantVestedTokens(
|
||||||
address _to,
|
address _to,
|
||||||
uint256 _value,
|
uint256 _value,
|
||||||
@ -32,7 +45,8 @@ contract VestedToken is StandardToken {
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenGrant memory grant = TokenGrant({start: _start, value: _value, cliff: _cliff, vesting: _vesting, granter: msg.sender});
|
|
||||||
|
TokenGrant memory grant = TokenGrant(msg.sender, _value, _cliff, _vesting, _start);
|
||||||
grants[_to].push(grant);
|
grants[_to].push(grant);
|
||||||
|
|
||||||
transfer(_to, _value);
|
transfer(_to, _value);
|
||||||
@ -126,12 +140,4 @@ contract VestedToken is StandardToken {
|
|||||||
|
|
||||||
return safeSub(balances[holder], nonVested);
|
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
ethpm.json
Normal file
17
ethpm.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"package_name": "zeppelin",
|
||||||
|
"version": "1.0.4",
|
||||||
|
"description": "Secure Smart Contract library for Solidity",
|
||||||
|
"authors": [
|
||||||
|
"Manuel Araoz <manuelaraoz@gmail.com>"
|
||||||
|
],
|
||||||
|
"keywords": [
|
||||||
|
"solidity",
|
||||||
|
"ethereum",
|
||||||
|
"smart",
|
||||||
|
"contracts",
|
||||||
|
"security",
|
||||||
|
"zeppelin"
|
||||||
|
],
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
23
package.json
23
package.json
@ -1,16 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "zeppelin-solidity",
|
"name": "zeppelin-solidity",
|
||||||
"version": "1.0.2",
|
"version": "1.0.4",
|
||||||
"description": "Secure Smart Contract library for Solidity",
|
"description": "Secure Smart Contract library for Solidity",
|
||||||
"main": "truffle.js",
|
"main": "truffle.js",
|
||||||
"devDependencies": {
|
|
||||||
"babel-preset-es2015": "^6.18.0",
|
|
||||||
"babel-preset-stage-2": "^6.18.0",
|
|
||||||
"babel-preset-stage-3": "^6.17.0",
|
|
||||||
"babel-register": "^6.23.0",
|
|
||||||
"ethereumjs-testrpc": "^3.0.2",
|
|
||||||
"truffle": "https://github.com/ConsenSys/truffle.git#3.1.9"
|
|
||||||
},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "scripts/test.sh",
|
"test": "scripts/test.sh",
|
||||||
"console": "truffle console",
|
"console": "truffle console",
|
||||||
@ -33,5 +25,16 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/OpenZeppelin/zeppelin-solidity/issues"
|
"url": "https://github.com/OpenZeppelin/zeppelin-solidity/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/OpenZeppelin/zeppelin-solidity"
|
"homepage": "https://github.com/OpenZeppelin/zeppelin-solidity",
|
||||||
|
"dependencies": {
|
||||||
|
"truffle-hdwallet-provider": "0.0.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-preset-es2015": "^6.18.0",
|
||||||
|
"babel-preset-stage-2": "^6.18.0",
|
||||||
|
"babel-preset-stage-3": "^6.17.0",
|
||||||
|
"babel-register": "^6.23.0",
|
||||||
|
"ethereumjs-testrpc": "^3.0.2",
|
||||||
|
"truffle": "https://github.com/ConsenSys/truffle.git#3.1.9"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,6 +52,16 @@ contract('VestedToken', function(accounts) {
|
|||||||
assert.fail('should have thrown before');
|
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 () => {
|
it('can be revoked by granter', async () => {
|
||||||
await token.revokeTokenGrant(receiver, 0, { from: granter });
|
await token.revokeTokenGrant(receiver, 0, { from: granter });
|
||||||
assert.equal(await token.balanceOf(receiver), 0);
|
assert.equal(await token.balanceOf(receiver), 0);
|
||||||
@ -78,5 +88,12 @@ contract('VestedToken', function(accounts) {
|
|||||||
await token.transfer(accounts[7], tokenAmount, { from: receiver })
|
await token.transfer(accounts[7], tokenAmount, { from: receiver })
|
||||||
assert.equal(await token.balanceOf(accounts[7]), tokenAmount);
|
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);
|
||||||
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
14
truffle.js
14
truffle.js
@ -1,12 +1,22 @@
|
|||||||
require('babel-register');
|
require('babel-register');
|
||||||
require('babel-polyfill');
|
require('babel-polyfill');
|
||||||
|
|
||||||
|
var HDWalletProvider = require('truffle-hdwallet-provider');
|
||||||
|
|
||||||
|
var mnemonic = '[REDACTED]';
|
||||||
|
var provider = new HDWalletProvider(mnemonic, 'https://ropsten.infura.io/');
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
networks: {
|
networks: {
|
||||||
development: {
|
development: {
|
||||||
host: "localhost",
|
host: 'localhost',
|
||||||
port: 8545,
|
port: 8545,
|
||||||
network_id: "*"
|
network_id: '*'
|
||||||
|
},
|
||||||
|
ropsten: {
|
||||||
|
provider: provider,
|
||||||
|
network_id: 3 // official id of the ropsten network
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user