Merge with master
This commit is contained in:
@ -9,13 +9,24 @@ import '../SafeMath.sol';
|
||||
* Basic token
|
||||
* Basic version of StandardToken, with no allowances
|
||||
*/
|
||||
contract BasicToken is ERC20Basic, SafeMath {
|
||||
contract BasicToken is ERC20Basic {
|
||||
using SafeMath for uint;
|
||||
|
||||
mapping(address => uint) balances;
|
||||
|
||||
function transfer(address _to, uint _value) {
|
||||
balances[msg.sender] = safeSub(balances[msg.sender], _value);
|
||||
balances[_to] = safeAdd(balances[_to], _value);
|
||||
/*
|
||||
* Fix for the ERC20 short address attack
|
||||
*/
|
||||
modifier onlyPayloadSize(uint size) {
|
||||
if(msg.data.length < size + 4) {
|
||||
throw;
|
||||
}
|
||||
_;
|
||||
}
|
||||
|
||||
function transfer(address _to, uint _value) onlyPayloadSize(2 * 32) {
|
||||
balances[msg.sender] = balances[msg.sender].sub(_value);
|
||||
balances[_to] = balances[_to].add(_value);
|
||||
Transfer(msg.sender, _to, _value);
|
||||
}
|
||||
|
||||
|
||||
@ -8,15 +8,20 @@ import "./StandardToken.sol";
|
||||
* CrowdsaleToken
|
||||
*
|
||||
* Simple ERC20 Token example, with crowdsale token creation
|
||||
* IMPORTANT NOTE: do not use or deploy this contract as-is.
|
||||
* It needs some changes to be production ready.
|
||||
*/
|
||||
contract CrowdsaleToken is StandardToken {
|
||||
|
||||
string public name = "CrowdsaleToken";
|
||||
string public symbol = "CRW";
|
||||
uint public decimals = 18;
|
||||
string public constant name = "CrowdsaleToken";
|
||||
string public constant symbol = "CRW";
|
||||
uint public constant decimals = 18;
|
||||
// replace with your fund collection multisig address
|
||||
address public constant multisig = 0x0;
|
||||
|
||||
|
||||
// 1 ether = 500 example tokens
|
||||
uint PRICE = 500;
|
||||
uint public constant PRICE = 500;
|
||||
|
||||
function () payable {
|
||||
createTokens(msg.sender);
|
||||
@ -27,10 +32,14 @@ contract CrowdsaleToken is StandardToken {
|
||||
throw;
|
||||
}
|
||||
|
||||
uint tokens = safeMul(msg.value, getPrice());
|
||||
uint tokens = msg.value.mul(getPrice());
|
||||
totalSupply = totalSupply.add(tokens);
|
||||
|
||||
totalSupply = safeAdd(totalSupply, tokens);
|
||||
balances[recipient] = safeAdd(balances[recipient], tokens);
|
||||
balances[recipient] = balances[recipient].add(tokens);
|
||||
|
||||
if (!multisig.send(msg.value)) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
// replace this with any other price function
|
||||
|
||||
@ -1,18 +1,16 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
|
||||
import './ERC20Basic.sol';
|
||||
|
||||
|
||||
/*
|
||||
* ERC20 interface
|
||||
* see https://github.com/ethereum/EIPs/issues/20
|
||||
*/
|
||||
contract ERC20 {
|
||||
uint public totalSupply;
|
||||
function balanceOf(address who) constant returns (uint);
|
||||
contract ERC20 is ERC20Basic {
|
||||
function allowance(address owner, address spender) constant returns (uint);
|
||||
|
||||
function transfer(address to, uint value) returns (bool ok);
|
||||
function transferFrom(address from, address to, uint value) returns (bool ok);
|
||||
function approve(address spender, uint value) returns (bool ok);
|
||||
event Transfer(address indexed from, address indexed to, uint value);
|
||||
function transferFrom(address from, address to, uint value);
|
||||
function approve(address spender, uint value);
|
||||
event Approval(address indexed owner, address indexed spender, uint value);
|
||||
}
|
||||
|
||||
@ -4,15 +4,15 @@ import "./ERC20.sol";
|
||||
|
||||
/*
|
||||
|
||||
TransferableToken defines the generic interface and the implementation
|
||||
LimitedTransferToken defines the generic interface and the implementation
|
||||
to limit token transferability for different events.
|
||||
|
||||
It is intended to be used as a base class for other token contracts.
|
||||
|
||||
Over-writting transferableTokens(address holder, uint64 time) is the way to provide
|
||||
the specific logic for limitting token transferability for a holder over time.
|
||||
Overwriting transferableTokens(address holder, uint64 time) is the way to provide
|
||||
the specific logic for limiting token transferability for a holder over time.
|
||||
|
||||
TransferableToken has been designed to allow for different limitting factors,
|
||||
LimitedTransferToken has been designed to allow for different limiting factors,
|
||||
this can be achieved by recursively calling super.transferableTokens() until the
|
||||
base class is hit. For example:
|
||||
|
||||
@ -25,7 +25,7 @@ https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/Ve
|
||||
|
||||
*/
|
||||
|
||||
contract TransferableToken is ERC20 {
|
||||
contract LimitedTransferToken is ERC20 {
|
||||
// Checks whether it can transfer or otherwise throws.
|
||||
modifier canTransfer(address _sender, uint _value) {
|
||||
if (_value > transferableTokens(_sender, uint64(now))) throw;
|
||||
@ -33,12 +33,12 @@ contract TransferableToken is ERC20 {
|
||||
}
|
||||
|
||||
// Checks modifier and allows transfer if tokens are not locked.
|
||||
function transfer(address _to, uint _value) canTransfer(msg.sender, _value) returns (bool success) {
|
||||
function transfer(address _to, uint _value) canTransfer(msg.sender, _value) {
|
||||
return super.transfer(_to, _value);
|
||||
}
|
||||
|
||||
// Checks modifier and allows transfer if tokens are not locked.
|
||||
function transferFrom(address _from, address _to, uint _value) canTransfer(_from, _value) returns (bool success) {
|
||||
function transferFrom(address _from, address _to, uint _value) canTransfer(_from, _value) {
|
||||
return super.transferFrom(_from, _to, _value);
|
||||
}
|
||||
|
||||
43
contracts/token/MintableToken.sol
Normal file
43
contracts/token/MintableToken.sol
Normal file
@ -0,0 +1,43 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
|
||||
import './StandardToken.sol';
|
||||
import '../ownership/Ownable.sol';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Mintable token
|
||||
*
|
||||
* Simple ERC20 Token example, with mintable token creation
|
||||
* Issue:
|
||||
* https://github.com/OpenZeppelin/zeppelin-solidity/issues/120
|
||||
* Based on code by TokenMarketNet:
|
||||
* https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol
|
||||
*/
|
||||
|
||||
contract MintableToken is StandardToken, Ownable {
|
||||
event Mint(address indexed to, uint value);
|
||||
event MintFinished();
|
||||
|
||||
bool public mintingFinished = false;
|
||||
uint public totalSupply = 0;
|
||||
|
||||
modifier canMint() {
|
||||
if(mintingFinished) throw;
|
||||
_;
|
||||
}
|
||||
|
||||
function mint(address _to, uint _amount) onlyOwner canMint returns (bool) {
|
||||
totalSupply = totalSupply.add(_amount);
|
||||
balances[_to] = balances[_to].add(_amount);
|
||||
Mint(_to, _amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
function finishMinting() onlyOwner returns (bool) {
|
||||
mintingFinished = true;
|
||||
MintFinished();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
25
contracts/token/PausableToken.sol
Normal file
25
contracts/token/PausableToken.sol
Normal file
@ -0,0 +1,25 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
import './StandardToken.sol';
|
||||
import '../lifecycle/Pausable.sol';
|
||||
|
||||
/**
|
||||
* Pausable token
|
||||
*
|
||||
* Simple ERC20 Token example, with pausable token creation
|
||||
* Issue:
|
||||
* https://github.com/OpenZeppelin/zeppelin-solidity/issues/194
|
||||
* Based on code by BCAPtoken:
|
||||
* https://github.com/BCAPtoken/BCAPToken/blob/5cb5e76338cc47343ba9268663a915337c8b268e/sol/BCAPToken.sol#L27
|
||||
**/
|
||||
|
||||
contract PausableToken is Pausable, StandardToken {
|
||||
|
||||
function transfer(address _to, uint _value) whenNotPaused {
|
||||
return super.transfer(_to, _value);
|
||||
}
|
||||
|
||||
function transferFrom(address _from, address _to, uint _value) whenNotPaused {
|
||||
return super.transferFrom(_from, _to, _value);
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
|
||||
import './BasicToken.sol';
|
||||
import './ERC20.sol';
|
||||
import '../SafeMath.sol';
|
||||
|
||||
|
||||
/**
|
||||
@ -12,39 +12,32 @@ import '../SafeMath.sol';
|
||||
* Based on code by FirstBlood:
|
||||
* https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
|
||||
*/
|
||||
contract StandardToken is ERC20, SafeMath {
|
||||
contract StandardToken is BasicToken, ERC20 {
|
||||
|
||||
mapping(address => uint) balances;
|
||||
mapping (address => mapping (address => uint)) allowed;
|
||||
|
||||
function transfer(address _to, uint _value) returns (bool success) {
|
||||
balances[msg.sender] = safeSub(balances[msg.sender], _value);
|
||||
balances[_to] = safeAdd(balances[_to], _value);
|
||||
Transfer(msg.sender, _to, _value);
|
||||
return true;
|
||||
}
|
||||
|
||||
function transferFrom(address _from, address _to, uint _value) returns (bool success) {
|
||||
function transferFrom(address _from, address _to, uint _value) onlyPayloadSize(3 * 32) {
|
||||
var _allowance = allowed[_from][msg.sender];
|
||||
|
||||
// Check is not needed because safeSub(_allowance, _value) will already throw if this condition is not met
|
||||
// Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
|
||||
// if (_value > _allowance) throw;
|
||||
|
||||
balances[_to] = safeAdd(balances[_to], _value);
|
||||
balances[_from] = safeSub(balances[_from], _value);
|
||||
allowed[_from][msg.sender] = safeSub(_allowance, _value);
|
||||
balances[_to] = balances[_to].add(_value);
|
||||
balances[_from] = balances[_from].sub(_value);
|
||||
allowed[_from][msg.sender] = _allowance.sub(_value);
|
||||
Transfer(_from, _to, _value);
|
||||
return true;
|
||||
}
|
||||
|
||||
function balanceOf(address _owner) constant returns (uint balance) {
|
||||
return balances[_owner];
|
||||
}
|
||||
function approve(address _spender, uint _value) {
|
||||
|
||||
// To change the approve amount you first have to reduce the addresses`
|
||||
// allowance to zero by calling `approve(_spender, 0)` if it is not
|
||||
// already 0 to mitigate the race condition described here:
|
||||
// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
|
||||
if ((_value != 0) && (allowed[msg.sender][_spender] != 0)) throw;
|
||||
|
||||
function approve(address _spender, uint _value) returns (bool success) {
|
||||
allowed[msg.sender][_spender] = _value;
|
||||
Approval(msg.sender, _spender, _value);
|
||||
return true;
|
||||
}
|
||||
|
||||
function allowance(address _owner, address _spender) constant returns (uint remaining) {
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
import "./StandardToken.sol";
|
||||
import "./TransferableToken.sol";
|
||||
import "./LimitedTransferToken.sol";
|
||||
|
||||
contract VestedToken is StandardToken, LimitedTransferToken {
|
||||
|
||||
contract VestedToken is StandardToken, TransferableToken {
|
||||
struct TokenGrant {
|
||||
address granter; // 20 bytes
|
||||
uint256 value; // 32 bytes
|
||||
@ -70,11 +71,12 @@ contract VestedToken is StandardToken, TransferableToken {
|
||||
grants[_holder][_grantId] = grants[_holder][grants[_holder].length - 1];
|
||||
grants[_holder].length -= 1;
|
||||
|
||||
balances[receiver] = safeAdd(balances[receiver], nonVested);
|
||||
balances[_holder] = safeSub(balances[_holder], nonVested);
|
||||
balances[receiver] = SafeMath.add(balances[receiver], nonVested);
|
||||
balances[_holder] = SafeMath.sub(balances[_holder], nonVested);
|
||||
Transfer(_holder, receiver, nonVested);
|
||||
}
|
||||
|
||||
|
||||
function transferableTokens(address holder, uint64 time) constant public returns (uint256) {
|
||||
uint256 grantIndex = tokenGrantsCount(holder);
|
||||
|
||||
@ -83,15 +85,15 @@ contract VestedToken is StandardToken, TransferableToken {
|
||||
// Iterate through all the grants the holder has, and add all non-vested tokens
|
||||
uint256 nonVested = 0;
|
||||
for (uint256 i = 0; i < grantIndex; i++) {
|
||||
nonVested = safeAdd(nonVested, nonVestedTokens(grants[holder][i], time));
|
||||
nonVested = SafeMath.add(nonVested, nonVestedTokens(grants[holder][i], time));
|
||||
}
|
||||
|
||||
// Balance - totalNonVested is the amount of tokens a holder can transfer at any given time
|
||||
uint256 vestedTransferable = safeSub(balanceOf(holder), nonVested);
|
||||
uint256 vestedTransferable = SafeMath.sub(balanceOf(holder), nonVested);
|
||||
|
||||
// Return the minimum of how many vested can transfer and other value
|
||||
// in case there are other limiting transferability factors (default is balanceOf)
|
||||
return min256(vestedTransferable, super.transferableTokens(holder, time));
|
||||
return SafeMath.min256(vestedTransferable, super.transferableTokens(holder, time));
|
||||
}
|
||||
|
||||
function tokenGrantsCount(address _holder) constant returns (uint index) {
|
||||
@ -129,12 +131,12 @@ contract VestedToken is StandardToken, TransferableToken {
|
||||
// in the vesting rect (as shown in above's figure)
|
||||
|
||||
// vestedTokens = tokens * (time - start) / (vesting - start)
|
||||
uint256 vestedTokens = safeDiv(
|
||||
safeMul(
|
||||
uint256 vestedTokens = SafeMath.div(
|
||||
SafeMath.mul(
|
||||
tokens,
|
||||
safeSub(time, start)
|
||||
SafeMath.sub(time, start)
|
||||
),
|
||||
safeSub(vesting, start)
|
||||
SafeMath.sub(vesting, start)
|
||||
);
|
||||
|
||||
return vestedTokens;
|
||||
@ -165,14 +167,14 @@ contract VestedToken is StandardToken, TransferableToken {
|
||||
}
|
||||
|
||||
function nonVestedTokens(TokenGrant grant, uint64 time) private constant returns (uint256) {
|
||||
return safeSub(grant.value, vestedTokens(grant, time));
|
||||
return grant.value.sub(vestedTokens(grant, time));
|
||||
}
|
||||
|
||||
function lastTokenIsTransferableDate(address holder) constant public returns (uint64 date) {
|
||||
date = uint64(now);
|
||||
uint256 grantIndex = grants[holder].length;
|
||||
for (uint256 i = 0; i < grantIndex; i++) {
|
||||
date = max64(grants[holder][i].vesting, date);
|
||||
date = SafeMath.max64(grants[holder][i].vesting, date);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user