Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pragma solidity 0.4.15;
- import './Owned.sol';
- import './CrowdsaleParameters.sol';
- import './TokenRecipient.sol';
- import './ShortAddressAtackFix.sol';
- contract SeedToken is Owned, CrowdsaleParameters, ShortAddressAtackFix {
- /* Public variables of the token */
- string public standard = "Token 0.1";
- string public name = "Seed";
- string public symbol = "SED";
- uint8 public decimals = 18;
- /* This creates an array with all balances */
- mapping (address => uint256) private balances;
- mapping (address => mapping (uint256 => uint256)) public vestingBalanceOf;
- uint[] private vestingTimes;
- mapping (address => mapping (address => uint256)) private allowed;
- mapping (address => mapping (address => bool)) private allowanceUsed;
- uint256 private _totalSupply = 0;
- /* This generates a public event on the blockchain that will notify clients */
- event Transfer(address indexed from, address indexed to, uint256 value);
- event Transfer(address indexed spender, address indexed from, address indexed to, uint256 value);
- event VestingTransfer(address indexed from, address indexed to, uint256 value, uint256 vestingTime);
- event Approval(address indexed _owner, address indexed _spender, uint256 _value);
- // triggered when the total supply is increased
- event Issuance(uint256 _amount);
- // triggered when the total supply is decreased
- event Destruction(uint256 _amount);
- address[] public addressByIndex;
- mapping (address => bool) private addressAddedToIndex;
- mapping (address => uint) private vestingTimesForPools;
- bool public transfersEnabled = true;
- event NewSeedToken(address _token);
- /**
- * Constructor
- *
- * Initializes contract with initial supply tokens to the creator of the contract
- *
- * Fail to create contract if decimals is greater than 18. This allows to
- * avoid using SafeMath for internal methods for token operations because
- * there will be no overflow:
- *
- * uint256 provides roughly 10^77 range. The nubmer to express the greatest
- * amount of tokens possible (if decimals == 18) is approx.
- * 10^18 * 10^9 = 10^27 => no overflow possible.
- */
- function SeedToken() public {
- require(decimals <= 18);
- owner = msg.sender;
- addVestingTimesForPool(CrowdsaleParameters.presalePoolAddress, CrowdsaleParameters.presalePoolVestingTime);
- addVestingTimesForPool(CrowdsaleParameters.foundersAddress, CrowdsaleParameters.foundersVestingTime);
- addVestingTimesForPool(CrowdsaleParameters.incentiveReserveAddress, CrowdsaleParameters.incentiveReserveVestingTime);
- addVestingTimesForPool(CrowdsaleParameters.generalSaleAddress, CrowdsaleParameters.generalSaleVestingTime);
- addVestingTimesForPool(CrowdsaleParameters.lotteryAddress, CrowdsaleParameters.lotteryVestingTime);
- addVestingTimesForPool(CrowdsaleParameters.marketingAddress, CrowdsaleParameters.marketingVestingTime);
- addVestingTime(CrowdsaleParameters.presalePoolVestingTime);
- addVestingTime(CrowdsaleParameters.foundersVestingTime);
- addVestingTime(CrowdsaleParameters.incentiveReserveVestingTime);
- addVestingTime(CrowdsaleParameters.generalSaleVestingTime);
- addVestingTime(CrowdsaleParameters.lotteryVestingTime);
- addVestingTime(CrowdsaleParameters.marketingVestingTime);
- uint uintDecimals = decimals;
- uint exponent = 10**uintDecimals;
- mintToken(CrowdsaleParameters.generalSaleAddress, 170000000 * exponent, 0);
- mintToken(CrowdsaleParameters.foundersAddress, 26000000 * exponent, 0);
- mintToken(CrowdsaleParameters.presalePoolAddress, 35000000 * exponent, 0);
- mintToken(CrowdsaleParameters.incentiveReserveAddress, 17362500 * exponent, 0);
- mintToken(CrowdsaleParameters.lotteryAddress, 200000 * exponent, 0);
- mintToken(CrowdsaleParameters.marketingAddress, 7687500 * exponent, 0);
- NewSeedToken(address(this));
- }
- /**
- * verifies that transfers are enabled
- */
- modifier transfersAllowed {
- require(transfersEnabled);
- _;
- }
- /**
- * 1. Associate crowdsale contract address with this Token
- * 2. Allocate presale and general sale amounts
- * 3. Allocate all other amounts (such as Founder's pool, incentive,
- * lottery and marketing)
- *
- * @param _crowdsaleAddress - crowdsale contract address
- */
- function approveForCrowdsale(address _crowdsaleAddress) public onlyOwner {
- uint uintDecimals = decimals;
- uint exponent = 10**uintDecimals;
- allowed[CrowdsaleParameters.generalSaleAddress][_crowdsaleAddress] = 170000000 * exponent;
- allowed[CrowdsaleParameters.presalePoolAddress][_crowdsaleAddress] = 35000000 * exponent;
- Approval(CrowdsaleParameters.generalSaleAddress, _crowdsaleAddress, 170000000 * exponent);
- Approval(CrowdsaleParameters.presalePoolAddress, _crowdsaleAddress, 35000000 * exponent);
- allowed[CrowdsaleParameters.foundersAddress][_crowdsaleAddress] = 26000000 * exponent;
- Approval(CrowdsaleParameters.foundersAddress, _crowdsaleAddress, 26000000 * exponent);
- allowed[CrowdsaleParameters.incentiveReserveAddress][_crowdsaleAddress] = 17362500 * exponent;
- Approval(CrowdsaleParameters.incentiveReserveAddress, _crowdsaleAddress, 17362500 * exponent);
- allowed[CrowdsaleParameters.lotteryAddress][_crowdsaleAddress] = 200000 * exponent;
- Approval(CrowdsaleParameters.lotteryAddress, _crowdsaleAddress, 200000 * exponent);
- allowed[CrowdsaleParameters.marketingAddress][_crowdsaleAddress] = 7687500 * exponent;
- Approval(CrowdsaleParameters.marketingAddress, _crowdsaleAddress, 7687500 * exponent);
- }
- /**
- * Get total supply of SED token
- *
- * @return total minted supply
- */
- function totalSupply() public constant returns (uint256 result) {
- result = _totalSupply;
- }
- /**
- * Get token balance of an address
- *
- * @param _address - address to query
- * @return Token balance of _address
- */
- function balanceOf(address _address) public constant returns (uint256 balance) {
- return balances[_address];
- }
- /**
- * Get token amount allocated for a transaction from _owner to _spender addresses
- *
- * @param _owner - owner address, i.e. address to transfer from
- * @param _spender - spender address, i.e. address to transfer to
- * @return Remaining amount allowed to be transferred
- */
- function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
- return allowed[_owner][_spender];
- }
- /**
- * Send coins from sender's address to address specified in parameters
- *
- * @param _to - address to send to
- * @param _value - amount to send in Wei
- */
- function transfer(address _to, uint256 _value) public transfersAllowed onlyPayloadSize(2*32) returns (bool success) {
- checkMyVesting(msg.sender);
- require(accountBalance(msg.sender) >= _value);
- // Subtract from the sender
- // _value is never greater than balance of input validation above
- balances[msg.sender] -= _value;
- if (vestingTimesForPools[msg.sender] > 0 && vestingTimesForPools[msg.sender] > now) {
- addToVesting(msg.sender, _to, vestingTimesForPools[msg.sender], _value);
- }
- // Overflow is never possible due to input validation above
- balances[_to] += _value;
- addIndex(_to);
- Transfer(msg.sender, _to, _value);
- return true;
- }
- /**
- * Create token and credit it to target address
- * Created tokens need to vest (in opposite to issue method)
- *
- * @param target - address to credit new tokens to
- * @param mintedAmount - number of tokens to create
- * @param vestingTime - vesting time of new tokens
- */
- function mintToken(address target, uint256 mintedAmount, uint256 vestingTime) internal {
- if (vestingTime > now) {
- addToVesting(owner, target, vestingTime, mintedAmount);
- }
- balances[target] += mintedAmount;
- _totalSupply += mintedAmount;
- Issuance(mintedAmount);
- addIndex(target);
- Transfer(this, target, mintedAmount);
- }
- function addIndex(address _address) internal {
- if (!addressAddedToIndex[_address]) {
- addressAddedToIndex[_address] = true;
- addressByIndex.push(_address);
- }
- }
- function addVestingTime(uint256 time) internal {
- vestingTimes.push(time);
- }
- function addToVesting(address from, address target, uint256 vestingTime, uint256 amount) internal {
- vestingBalanceOf[target][0] += amount;
- vestingBalanceOf[target][vestingTime] += amount;
- VestingTransfer(from, target, amount, vestingTime);
- }
- /**
- * Allow another contract to spend some tokens on your behalf
- *
- * @param _spender - address to allocate tokens for
- * @param _value - number of tokens to allocate
- * @return True in case of success, otherwise false
- */
- function approve(address _spender, uint256 _value) public onlyPayloadSize(2*32) returns (bool success) {
- require(_value == 0 || allowanceUsed[msg.sender][_spender] == false);
- allowed[msg.sender][_spender] = _value;
- allowanceUsed[msg.sender][_spender] = false;
- Approval(msg.sender, _spender, _value);
- return true;
- }
- /**
- * Approve and then communicate the approved contract in a single tx
- *
- * @param _spender - address to allocate tokens for
- * @param _value - number of tokens to allocate
- * @param _extraData - extra data to be included in data field in this transaction
- * @return True in case of success, otherwise false
- */
- function approveAndCall(address _spender, uint256 _value, bytes _extraData) public onlyPayloadSize(2*32) returns (bool success) {
- TokenRecipient spender = TokenRecipient(_spender);
- if (approve(_spender, _value)) {
- spender.receiveApproval(msg.sender, _value, this, _extraData);
- return true;
- }
- }
- /**
- * A contract attempts to transfer previously allocated tokens.
- *
- * @param _to - address to transfer tokens to
- * @param _from - address to transfer tokens from
- * @param _value - number of tokens to transfer
- * @return True in case of success, otherwise false
- */
- function transferFrom(address _from, address _to, uint256 _value) public transfersAllowed onlyPayloadSize(3*32) returns (bool success) {
- checkMyVesting(_from);
- // Check if the sender has enough
- require(accountBalance(_from) >= _value);
- // Check allowed
- require(_value <= allowed[_from][msg.sender]);
- // Subtract from the sender
- // _value is never greater than balance because of input validation above
- balances[_from] -= _value;
- // Add the same to the recipient
- // Overflow is not possible because of input validation above
- balances[_to] += _value;
- // Deduct allocation
- // _value is never greater than allowed amount because of input validation above
- allowed[_from][msg.sender] -= _value;
- if (vestingTimesForPools[_from] > 0 && vestingTimesForPools[_from] > now) {
- addToVesting(_from, _to, vestingTimesForPools[_from], _value);
- }
- addIndex(_to);
- Transfer(msg.sender, _from, _to, _value);
- allowanceUsed[_from][msg.sender] = true;
- return true;
- }
- /**
- * Default method
- *
- * This unnamed function is called whenever someone tries to send ether to
- * it. Just revert transaction because there is nothing that Token can do
- * with incoming ether.
- */
- function() public {
- revert();
- // Prevents accidental sending of ether
- }
- function checkMyVesting(address sender) internal {
- if (vestingBalanceOf[sender][0] == 0) return;
- for (uint256 k = 0; k < vestingTimes.length; k++) {
- if (vestingTimes[k] < now) {
- vestingBalanceOf[sender][0] -= vestingBalanceOf[sender][vestingTimes[k]];
- vestingBalanceOf[sender][vestingTimes[k]] = 0;
- }
- }
- }
- function addVestingTimesForPool(address poolAddress, uint256 vestingTime) internal {
- vestingTimesForPools[poolAddress] = vestingTime;
- }
- function countAddresses() public constant returns (uint256 length) {
- return addressByIndex.length;
- }
- /**
- * Get vested token balance of an address
- *
- * @param _address - address to query
- * @return balance that has vested
- */
- function accountBalance(address _address) public constant returns (uint256 balance) {
- return balances[_address] - vestingBalanceOf[_address][0];
- }
- /**
- * Enable or disable transfers
- *
- * @param _enable - True = enable, False = disable
- */
- function toggleTransfers(bool _enable) public onlyOwner {
- transfersEnabled = _enable;
- }
- /**
- * Destroy tokens
- *
- * @param _from - address to destroy tokens from
- * @param _amount - number of tokens to destroy
- */
- function destroy(address _from, uint256 _amount) public onlyPayloadSize(2*32) {
- checkMyVesting(msg.sender);
- // validate input
- require(msg.sender == _from || msg.sender == owner);
- require(accountBalance(_from) >= _amount);
- // _amount is never greater than balance because of validation above
- balances[_from] -= _amount;
- // _amount is never greater than total supply:
- // 1. Because of validation above, it is never greater than balances[_from]
- // 2. balances[_from] is never greater than total supply
- _totalSupply -= _amount;
- Transfer(_from, this, _amount);
- Destruction(_amount);
- }
- }
Add Comment
Please, Sign In to add comment