ETH Price: $2,319.73 (+6.17%)

Transaction Decoder

Block:
3969304 at Jul-03-2017 07:33:34 PM +UTC
Transaction Fee:
0.00363710194185855 ETH $8.44
Gas Used:
143,579 Gas / 25.33171245 Gwei

Emitted Events:

33 RelaunchedCrowdsale.Invested( investor=0xCD12c7eE459a43E0087E944A3DdeA06A092Df739, weiAmount=1800000000000000000, tokenAmount=7875000295312, customerId=0 )
34 RelaunchedCrowdsale.RestoredInvestment( addr=0xCD12c7eE459a43E0087E944A3DdeA06A092Df739, originalTxHash=517991900781091200318351539459134338030758649075329266115743635460946127632 )
35 CrowdsaleToken.Transfer( from=0x0000000000000000000000000000000000000000, to=0xCD12c7eE459a43E0087E944A3DdeA06A092Df739, value=7875000295312 )

Account State Difference:

  Address   Before After State Difference Code
0x4aF893EE...5a1619C3a
6.452678181780082302 Eth
Nonce: 442
6.449041079838223752 Eth
Nonce: 443
0.00363710194185855
0xa5Ca78D8...cC6c92A7e
0xB2E59493...914B0fCC2
(Ethermine)
658.403569067943127855 Eth658.407206169884986405 Eth0.00363710194185855

Execution Trace

RelaunchedCrowdsale.setInvestorDataAndIssueNewToken( _addr=0xCD12c7eE459a43E0087E944A3DdeA06A092Df739, _weiAmount=1800000000000000000, _tokenAmount=7875000295312, _originalTxHash=517991900781091200318351539459134338030758649075329266115743635460946127632 )
  • CrowdsaleToken.mint( receiver=0xCD12c7eE459a43E0087E944A3DdeA06A092Df739, amount=7875000295312 )
    • 0x2e12bb83316cf7dbbdb04c09704687211c73e3ac.66098d4f( )
    • 0x2e12bb83316cf7dbbdb04c09704687211c73e3ac.66098d4f( )
      File 1 of 2: RelaunchedCrowdsale
      /**
       * Safe unsigned safe math.
       *
       * https://blog.aragon.one/library-driven-development-in-solidity-2bebcaf88736#.750gwtwli
       *
       * Originally from https://raw.githubusercontent.com/AragonOne/zeppelin-solidity/master/contracts/SafeMathLib.sol
       *
       * Maintained here until merged to mainline zeppelin-solidity.
       *
       */
      library SafeMathLib {
      
        function times(uint a, uint b) returns (uint) {
          uint c = a * b;
          assert(a == 0 || c / a == b);
          return c;
        }
      
        function minus(uint a, uint b) returns (uint) {
          assert(b <= a);
          return a - b;
        }
      
        function plus(uint a, uint b) returns (uint) {
          uint c = a + b;
          assert(c>=a);
          return c;
        }
      
        function assert(bool assertion) private {
          if (!assertion) throw;
        }
      }
      
      
      
      
      /*
       * Ownable
       *
       * Base contract with an owner.
       * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.
       */
      contract Ownable {
        address public owner;
      
        function Ownable() {
          owner = msg.sender;
        }
      
        modifier onlyOwner() {
          if (msg.sender != owner) {
            throw;
          }
          _;
        }
      
        function transferOwnership(address newOwner) onlyOwner {
          if (newOwner != address(0)) {
            owner = newOwner;
          }
        }
      
      }
      
      
      /*
       * Haltable
       *
       * Abstract contract that allows children to implement an
       * emergency stop mechanism. Differs from Pausable by causing a throw when in halt mode.
       *
       *
       * Originally envisioned in FirstBlood ICO contract.
       */
      contract Haltable is Ownable {
        bool public halted;
      
        modifier stopInEmergency {
          if (halted) throw;
          _;
        }
      
        modifier onlyInEmergency {
          if (!halted) throw;
          _;
        }
      
        // called by the owner on emergency, triggers stopped state
        function halt() external onlyOwner {
          halted = true;
        }
      
        // called by the owner on end of emergency, returns to normal state
        function unhalt() external onlyOwner onlyInEmergency {
          halted = false;
        }
      
      }
      
      
      /**
       * Interface for defining crowdsale pricing.
       */
      contract PricingStrategy {
      
        /** Interface declaration. */
        function isPricingStrategy() public constant returns (bool) {
          return true;
        }
      
        /** Self check if all references are correctly set.
         *
         * Checks that pricing strategy matches crowdsale parameters.
         */
        function isSane(address crowdsale) public constant returns (bool) {
          return true;
        }
      
        /**
         * When somebody tries to buy tokens for X eth, calculate how many tokens they get.
         *
         *
         * @param value - What is the value of the transaction send in as wei
         * @param tokensSold - how much tokens have been sold this far
         * @param weiRaised - how much money has been raised this far
         * @param msgSender - who is the investor of this transaction
         * @param decimals - how many decimal units the token has
         * @return Amount of tokens the investor receives
         */
        function calculatePrice(uint value, uint weiRaised, uint tokensSold, address msgSender, uint decimals) public constant returns (uint tokenAmount);
      }
      
      
      /**
       * Finalize agent defines what happens at the end of succeseful crowdsale.
       *
       * - Allocate tokens for founders, bounties and community
       * - Make tokens transferable
       * - etc.
       */
      contract FinalizeAgent {
      
        function isFinalizeAgent() public constant returns(bool) {
          return true;
        }
      
        /** Return true if we can run finalizeCrowdsale() properly.
         *
         * This is a safety check function that doesn't allow crowdsale to begin
         * unless the finalizer has been set up properly.
         */
        function isSane() public constant returns (bool);
      
        /** Called once by crowdsale finalize() if the sale was success. */
        function finalizeCrowdsale();
      
      }
      
      
      
      
      /*
       * ERC20 interface
       * see https://github.com/ethereum/EIPs/issues/20
       */
      contract ERC20 {
        uint public totalSupply;
        function balanceOf(address who) constant returns (uint);
        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);
        event Approval(address indexed owner, address indexed spender, uint value);
      }
      
      
      /**
       * A token that defines fractional units as decimals.
       */
      contract FractionalERC20 is ERC20 {
      
        uint public decimals;
      
      }
      
      
      
      /**
       * Abstract base contract for token sales.
       *
       * Handle
       * - start and end dates
       * - accepting investments
       * - minimum funding goal and refund
       * - various statistics during the crowdfund
       * - different pricing strategies
       * - different investment policies (require server side customer id, allow only whitelisted addresses)
       *
       */
      contract Crowdsale is Haltable {
      
        /* Max investment count when we are still allowed to change the multisig address */
        uint public MAX_INVESTMENTS_BEFORE_MULTISIG_CHANGE = 5;
      
        using SafeMathLib for uint;
      
        /* The token we are selling */
        FractionalERC20 public token;
      
        /* How we are going to price our offering */
        PricingStrategy public pricingStrategy;
      
        /* Post-success callback */
        FinalizeAgent public finalizeAgent;
      
        /* tokens will be transfered from this address */
        address public multisigWallet;
      
        /* if the funding goal is not reached, investors may withdraw their funds */
        uint public minimumFundingGoal;
      
        /* the UNIX timestamp start date of the crowdsale */
        uint public startsAt;
      
        /* the UNIX timestamp end date of the crowdsale */
        uint public endsAt;
      
        /* the number of tokens already sold through this contract*/
        uint public tokensSold = 0;
      
        /* How many wei of funding we have raised */
        uint public weiRaised = 0;
      
        /* How many distinct addresses have invested */
        uint public investorCount = 0;
      
        /* How much wei we have returned back to the contract after a failed crowdfund. */
        uint public loadedRefund = 0;
      
        /* How much wei we have given back to investors.*/
        uint public weiRefunded = 0;
      
        /* Has this crowdsale been finalized */
        bool public finalized;
      
        /* Do we need to have unique contributor id for each customer */
        bool public requireCustomerId;
      
        /**
          * Do we verify that contributor has been cleared on the server side (accredited investors only).
          * This method was first used in FirstBlood crowdsale to ensure all contributors have accepted terms on sale (on the web).
          */
        bool public requiredSignedAddress;
      
        /* Server side address that signed allowed contributors (Ethereum addresses) that can participate the crowdsale */
        address public signerAddress;
      
        /** How much ETH each address has invested to this crowdsale */
        mapping (address => uint256) public investedAmountOf;
      
        /** How much tokens this crowdsale has credited for each investor address */
        mapping (address => uint256) public tokenAmountOf;
      
        /** Addresses that are allowed to invest even before ICO offical opens. For testing, for ICO partners, etc. */
        mapping (address => bool) public earlyParticipantWhitelist;
      
        /** This is for manul testing for the interaction from owner wallet. You can set it to any value and inspect this in blockchain explorer to see that crowdsale interaction works. */
        uint public ownerTestValue;
      
        /** State machine
         *
         * - Preparing: All contract initialization calls and variables have not been set yet
         * - Prefunding: We have not passed start time yet
         * - Funding: Active crowdsale
         * - Success: Minimum funding goal reached
         * - Failure: Minimum funding goal not reached before ending time
         * - Finalized: The finalized has been called and succesfully executed
         * - Refunding: Refunds are loaded on the contract for reclaim.
         */
        enum State{Unknown, Preparing, PreFunding, Funding, Success, Failure, Finalized, Refunding}
      
        // A new investment was made
        event Invested(address investor, uint weiAmount, uint tokenAmount, uint128 customerId);
      
        // Refund was processed for a contributor
        event Refund(address investor, uint weiAmount);
      
        // The rules were changed what kind of investments we accept
        event InvestmentPolicyChanged(bool requireCustomerId, bool requiredSignedAddress, address signerAddress);
      
        // Address early participation whitelist status changed
        event Whitelisted(address addr, bool status);
      
        // Crowdsale end time has been changed
        event EndsAtChanged(uint endsAt);
      
        function Crowdsale(address _token, PricingStrategy _pricingStrategy, address _multisigWallet, uint _start, uint _end, uint _minimumFundingGoal) {
      
          owner = msg.sender;
      
          token = FractionalERC20(_token);
      
          setPricingStrategy(_pricingStrategy);
      
          multisigWallet = _multisigWallet;
          if(multisigWallet == 0) {
              throw;
          }
      
          if(_start == 0) {
              throw;
          }
      
          startsAt = _start;
      
          if(_end == 0) {
              throw;
          }
      
          endsAt = _end;
      
          // Don't mess the dates
          if(startsAt >= endsAt) {
              throw;
          }
      
          // Minimum funding goal can be zero
          minimumFundingGoal = _minimumFundingGoal;
        }
      
        /**
         * Don't expect to just send in money and get tokens.
         */
        function() payable {
          throw;
        }
      
        /**
         * Make an investment.
         *
         * Crowdsale must be running for one to invest.
         * We must have not pressed the emergency brake.
         *
         * @param receiver The Ethereum address who receives the tokens
         * @param customerId (optional) UUID v4 to track the successful payments on the server side
         *
         */
        function investInternal(address receiver, uint128 customerId) stopInEmergency private {
      
          // Determine if it's a good time to accept investment from this participant
          if(getState() == State.PreFunding) {
            // Are we whitelisted for early deposit
            if(!earlyParticipantWhitelist[receiver]) {
              throw;
            }
          } else if(getState() == State.Funding) {
            // Retail participants can only come in when the crowdsale is running
            // pass
          } else {
            // Unwanted state
            throw;
          }
      
          uint weiAmount = msg.value;
          uint tokenAmount = pricingStrategy.calculatePrice(weiAmount, weiRaised, tokensSold, msg.sender, token.decimals());
      
          if(tokenAmount == 0) {
            // Dust transaction
            throw;
          }
      
          if(investedAmountOf[receiver] == 0) {
             // A new investor
             investorCount++;
          }
      
          // Update investor
          investedAmountOf[receiver] = investedAmountOf[receiver].plus(weiAmount);
          tokenAmountOf[receiver] = tokenAmountOf[receiver].plus(tokenAmount);
      
          // Update totals
          weiRaised = weiRaised.plus(weiAmount);
          tokensSold = tokensSold.plus(tokenAmount);
      
          // Check that we did not bust the cap
          if(isBreakingCap(weiAmount, tokenAmount, weiRaised, tokensSold)) {
            throw;
          }
      
          assignTokens(receiver, tokenAmount);
      
          // Pocket the money
          if(!multisigWallet.send(weiAmount)) throw;
      
          // Tell us invest was success
          Invested(receiver, weiAmount, tokenAmount, customerId);
        }
      
        /**
         * Preallocate tokens for the early investors.
         *
         * Preallocated tokens have been sold before the actual crowdsale opens.
         * This function mints the tokens and moves the crowdsale needle.
         *
         * Investor count is not handled; it is assumed this goes for multiple investors
         * and the token distribution happens outside the smart contract flow.
         *
         * No money is exchanged, as the crowdsale team already have received the payment.
         *
         * @param fullTokens tokens as full tokens - decimal places added internally
         * @param weiPrice Price of a single full token in wei
         *
         */
        function preallocate(address receiver, uint fullTokens, uint weiPrice) public onlyOwner {
      
          uint tokenAmount = fullTokens * 10**token.decimals();
          uint weiAmount = weiPrice * fullTokens; // This can be also 0, we give out tokens for free
      
          weiRaised = weiRaised.plus(weiAmount);
          tokensSold = tokensSold.plus(tokenAmount);
      
          investedAmountOf[receiver] = investedAmountOf[receiver].plus(weiAmount);
          tokenAmountOf[receiver] = tokenAmountOf[receiver].plus(tokenAmount);
      
          assignTokens(receiver, tokenAmount);
      
          // Tell us invest was success
          Invested(receiver, weiAmount, tokenAmount, 0);
        }
      
        /**
         * Allow anonymous contributions to this crowdsale.
         */
        function investWithSignedAddress(address addr, uint128 customerId, uint8 v, bytes32 r, bytes32 s) public payable {
           bytes32 hash = sha256(addr);
           if (ecrecover(hash, v, r, s) != signerAddress) throw;
           if(customerId == 0) throw;  // UUIDv4 sanity check
           investInternal(addr, customerId);
        }
      
        /**
         * Track who is the customer making the payment so we can send thank you email.
         */
        function investWithCustomerId(address addr, uint128 customerId) public payable {
          if(requiredSignedAddress) throw; // Crowdsale allows only server-side signed participants
          if(customerId == 0) throw;  // UUIDv4 sanity check
          investInternal(addr, customerId);
        }
      
        /**
         * Allow anonymous contributions to this crowdsale.
         */
        function invest(address addr) public payable {
          if(requireCustomerId) throw; // Crowdsale needs to track partipants for thank you email
          if(requiredSignedAddress) throw; // Crowdsale allows only server-side signed participants
          investInternal(addr, 0);
        }
      
        /**
         * Invest to tokens, recognize the payer and clear his address.
         *
         */
        function buyWithSignedAddress(uint128 customerId, uint8 v, bytes32 r, bytes32 s) public payable {
          investWithSignedAddress(msg.sender, customerId, v, r, s);
        }
      
        /**
         * Invest to tokens, recognize the payer.
         *
         */
        function buyWithCustomerId(uint128 customerId) public payable {
          investWithCustomerId(msg.sender, customerId);
        }
      
        /**
         * The basic entry point to participate the crowdsale process.
         *
         * Pay for funding, get invested tokens back in the sender address.
         */
        function buy() public payable {
          invest(msg.sender);
        }
      
        /**
         * Finalize a succcesful crowdsale.
         *
         * The owner can triggre a call the contract that provides post-crowdsale actions, like releasing the tokens.
         */
        function finalize() public inState(State.Success) onlyOwner stopInEmergency {
      
          // Already finalized
          if(finalized) {
            throw;
          }
      
          // Finalizing is optional. We only call it if we are given a finalizing agent.
          if(address(finalizeAgent) != 0) {
            finalizeAgent.finalizeCrowdsale();
          }
      
          finalized = true;
        }
      
        /**
         * Allow to (re)set finalize agent.
         *
         * Design choice: no state restrictions on setting this, so that we can fix fat finger mistakes.
         */
        function setFinalizeAgent(FinalizeAgent addr) onlyOwner {
          finalizeAgent = addr;
      
          // Don't allow setting bad agent
          if(!finalizeAgent.isFinalizeAgent()) {
            throw;
          }
        }
      
        /**
         * Set policy do we need to have server-side customer ids for the investments.
         *
         */
        function setRequireCustomerId(bool value) onlyOwner {
          requireCustomerId = value;
          InvestmentPolicyChanged(requireCustomerId, requiredSignedAddress, signerAddress);
        }
      
        /**
         * Set policy if all investors must be cleared on the server side first.
         *
         * This is e.g. for the accredited investor clearing.
         *
         */
        function setRequireSignedAddress(bool value, address _signerAddress) onlyOwner {
          requiredSignedAddress = value;
          signerAddress = _signerAddress;
          InvestmentPolicyChanged(requireCustomerId, requiredSignedAddress, signerAddress);
        }
      
        /**
         * Allow addresses to do early participation.
         *
         * TODO: Fix spelling error in the name
         */
        function setEarlyParicipantWhitelist(address addr, bool status) onlyOwner {
          earlyParticipantWhitelist[addr] = status;
          Whitelisted(addr, status);
        }
      
        /**
         * Allow crowdsale owner to close early or extend the crowdsale.
         *
         * This is useful e.g. for a manual soft cap implementation:
         * - after X amount is reached determine manual closing
         *
         * This may put the crowdsale to an invalid state,
         * but we trust owners know what they are doing.
         *
         */
        function setEndsAt(uint time) onlyOwner {
      
          if(now > time) {
            throw; // Don't change past
          }
      
          endsAt = time;
          EndsAtChanged(endsAt);
        }
      
        /**
         * Allow to (re)set pricing strategy.
         *
         * Design choice: no state restrictions on the set, so that we can fix fat finger mistakes.
         */
        function setPricingStrategy(PricingStrategy _pricingStrategy) onlyOwner {
          pricingStrategy = _pricingStrategy;
      
          // Don't allow setting bad agent
          if(!pricingStrategy.isPricingStrategy()) {
            throw;
          }
        }
      
        /**
         * Allow to change the team multisig address in the case of emergency.
         *
         * This allows to save a deployed crowdsale wallet in the case the crowdsale has not yet begun
         * (we have done only few test transactions). After the crowdsale is going
         * then multisig address stays locked for the safety reasons.
         */
        function setMultisig(address addr) public onlyOwner {
      
          // Change
          if(investorCount > MAX_INVESTMENTS_BEFORE_MULTISIG_CHANGE) {
            throw;
          }
      
          multisigWallet = addr;
        }
      
        /**
         * Allow load refunds back on the contract for the refunding.
         *
         * The team can transfer the funds back on the smart contract in the case the minimum goal was not reached..
         */
        function loadRefund() public payable inState(State.Failure) {
          if(msg.value == 0) throw;
          loadedRefund = loadedRefund.plus(msg.value);
        }
      
        /**
         * Investors can claim refund.
         *
         * Note that any refunds from proxy buyers should be handled separately,
         * and not through this contract.
         */
        function refund() public inState(State.Refunding) {
          uint256 weiValue = investedAmountOf[msg.sender];
          if (weiValue == 0) throw;
          investedAmountOf[msg.sender] = 0;
          weiRefunded = weiRefunded.plus(weiValue);
          Refund(msg.sender, weiValue);
          if (!msg.sender.send(weiValue)) throw;
        }
      
        /**
         * @return true if the crowdsale has raised enough money to be a successful.
         */
        function isMinimumGoalReached() public constant returns (bool reached) {
          return weiRaised >= minimumFundingGoal;
        }
      
        /**
         * Check if the contract relationship looks good.
         */
        function isFinalizerSane() public constant returns (bool sane) {
          return finalizeAgent.isSane();
        }
      
        /**
         * Check if the contract relationship looks good.
         */
        function isPricingSane() public constant returns (bool sane) {
          return pricingStrategy.isSane(address(this));
        }
      
        /**
         * Crowdfund state machine management.
         *
         * We make it a function and do not assign the result to a variable, so there is no chance of the variable being stale.
         */
        function getState() public constant returns (State) {
          if(finalized) return State.Finalized;
          else if (address(finalizeAgent) == 0) return State.Preparing;
          else if (!finalizeAgent.isSane()) return State.Preparing;
          else if (!pricingStrategy.isSane(address(this))) return State.Preparing;
          else if (block.timestamp < startsAt) return State.PreFunding;
          else if (block.timestamp <= endsAt && !isCrowdsaleFull()) return State.Funding;
          else if (isMinimumGoalReached()) return State.Success;
          else if (!isMinimumGoalReached() && weiRaised > 0 && loadedRefund >= weiRaised) return State.Refunding;
          else return State.Failure;
        }
      
        /** This is for manual testing of multisig wallet interaction */
        function setOwnerTestValue(uint val) onlyOwner {
          ownerTestValue = val;
        }
      
        /** Interface marker. */
        function isCrowdsale() public constant returns (bool) {
          return true;
        }
      
        //
        // Modifiers
        //
      
        /** Modified allowing execution only if the crowdsale is currently running.  */
        modifier inState(State state) {
          if(getState() != state) throw;
          _;
        }
      
      
        //
        // Abstract functions
        //
      
        /**
         * Check if the current invested breaks our cap rules.
         *
         *
         * The child contract must define their own cap setting rules.
         * We allow a lot of flexibility through different capping strategies (ETH, token count)
         * Called from invest().
         *
         * @param weiAmount The amount of wei the investor tries to invest in the current transaction
         * @param tokenAmount The amount of tokens we try to give to the investor in the current transaction
         * @param weiRaisedTotal What would be our total raised balance after this transaction
         * @param tokensSoldTotal What would be our total sold tokens count after this transaction
         *
         * @return true if taking this investment would break our cap rules
         */
        function isBreakingCap(uint weiAmount, uint tokenAmount, uint weiRaisedTotal, uint tokensSoldTotal) constant returns (bool limitBroken);
      
        /**
         * Check if the current crowdsale is full and we can no longer sell any tokens.
         */
        function isCrowdsaleFull() public constant returns (bool);
      
        /**
         * Create new tokens or transfer issued tokens to the investor depending on the cap model.
         */
        function assignTokens(address receiver, uint tokenAmount) private;
      }
      
      
      
      
      
      
      
      
      /**
       * Math operations with safety checks
       */
      contract SafeMath {
        function safeMul(uint a, uint b) internal returns (uint) {
          uint c = a * b;
          assert(a == 0 || c / a == b);
          return c;
        }
      
        function safeDiv(uint a, uint b) internal returns (uint) {
          assert(b > 0);
          uint c = a / b;
          assert(a == b * c + a % b);
          return c;
        }
      
        function safeSub(uint a, uint b) internal returns (uint) {
          assert(b <= a);
          return a - b;
        }
      
        function safeAdd(uint a, uint b) internal returns (uint) {
          uint c = a + b;
          assert(c>=a && c>=b);
          return c;
        }
      
        function max64(uint64 a, uint64 b) internal constant returns (uint64) {
          return a >= b ? a : b;
        }
      
        function min64(uint64 a, uint64 b) internal constant returns (uint64) {
          return a < b ? a : b;
        }
      
        function max256(uint256 a, uint256 b) internal constant returns (uint256) {
          return a >= b ? a : b;
        }
      
        function min256(uint256 a, uint256 b) internal constant returns (uint256) {
          return a < b ? a : b;
        }
      
        function assert(bool assertion) internal {
          if (!assertion) {
            throw;
          }
        }
      }
      
      
      
      /**
       * Standard ERC20 token with Short Hand Attack and approve() race condition mitigation.
       *
       * Based on code by FirstBlood:
       * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
       */
      contract StandardToken is ERC20, SafeMath {
      
        /* Token supply got increased and a new owner received these tokens */
        event Minted(address receiver, uint amount);
      
        /* Actual balances of token holders */
        mapping(address => uint) balances;
      
        /* approve() allowances */
        mapping (address => mapping (address => uint)) allowed;
      
        /* Interface declaration */
        function isToken() public constant returns (bool weAre) {
          return true;
        }
      
        /**
         *
         * Fix for the ERC20 short address attack
         *
         * http://vessenes.com/the-erc20-short-address-attack-explained/
         */
        modifier onlyPayloadSize(uint size) {
           if(msg.data.length < size + 4) {
             throw;
           }
           _;
        }
      
        function transfer(address _to, uint _value) onlyPayloadSize(2 * 32) 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) {
          uint _allowance = allowed[_from][msg.sender];
      
          balances[_to] = safeAdd(balances[_to], _value);
          balances[_from] = safeSub(balances[_from], _value);
          allowed[_from][msg.sender] = safeSub(_allowance, _value);
          Transfer(_from, _to, _value);
          return true;
        }
      
        function balanceOf(address _owner) constant returns (uint balance) {
          return balances[_owner];
        }
      
        function approve(address _spender, uint _value) returns (bool success) {
      
          // 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;
      
          allowed[msg.sender][_spender] = _value;
          Approval(msg.sender, _spender, _value);
          return true;
        }
      
        function allowance(address _owner, address _spender) constant returns (uint remaining) {
          return allowed[_owner][_spender];
        }
      
      }
      
      
      
      
      /**
       * A token that can increase its supply by another contract.
       *
       * This allows uncapped crowdsale by dynamically increasing the supply when money pours in.
       * Only mint agents, contracts whitelisted by owner, can mint new tokens.
       *
       */
      contract MintableToken is StandardToken, Ownable {
      
        using SafeMathLib for uint;
      
        bool public mintingFinished = false;
      
        /** List of agents that are allowed to create new tokens */
        mapping (address => bool) public mintAgents;
      
        event MintingAgentChanged(address addr, bool state  );
      
        /**
         * Create new tokens and allocate them to an address..
         *
         * Only callably by a crowdsale contract (mint agent).
         */
        function mint(address receiver, uint amount) onlyMintAgent canMint public {
          totalSupply = totalSupply.plus(amount);
          balances[receiver] = balances[receiver].plus(amount);
      
          // This will make the mint transaction apper in EtherScan.io
          // We can remove this after there is a standardized minting event
          Transfer(0, receiver, amount);
        }
      
        /**
         * Owner can allow a crowdsale contract to mint new tokens.
         */
        function setMintAgent(address addr, bool state) onlyOwner canMint public {
          mintAgents[addr] = state;
          MintingAgentChanged(addr, state);
        }
      
        modifier onlyMintAgent() {
          // Only crowdsale contracts are allowed to mint new tokens
          if(!mintAgents[msg.sender]) {
              throw;
          }
          _;
        }
      
        /** Make sure we are not done yet. */
        modifier canMint() {
          if(mintingFinished) throw;
          _;
        }
      }
      
      
      /**
       * ICO crowdsale contract that is capped by amout of tokens.
       *
       * - Tokens are dynamically created during the crowdsale
       *
       *
       */
      contract MintedTokenCappedCrowdsale is Crowdsale {
      
        /* Maximum amount of tokens this crowdsale can sell. */
        uint public maximumSellableTokens;
      
        function MintedTokenCappedCrowdsale(address _token, PricingStrategy _pricingStrategy, address _multisigWallet, uint _start, uint _end, uint _minimumFundingGoal, uint _maximumSellableTokens) Crowdsale(_token, _pricingStrategy, _multisigWallet, _start, _end, _minimumFundingGoal) {
          maximumSellableTokens = _maximumSellableTokens;
        }
      
        /**
         * Called from invest() to confirm if the curret investment does not break our cap rule.
         */
        function isBreakingCap(uint weiAmount, uint tokenAmount, uint weiRaisedTotal, uint tokensSoldTotal) constant returns (bool limitBroken) {
          return tokensSoldTotal > maximumSellableTokens;
        }
      
        function isCrowdsaleFull() public constant returns (bool) {
          return tokensSold >= maximumSellableTokens;
        }
      
        /**
         * Dynamically create tokens and assign them to the investor.
         */
        function assignTokens(address receiver, uint tokenAmount) private {
          MintableToken mintableToken = MintableToken(token);
          mintableToken.mint(receiver, tokenAmount);
        }
      }
      
      
      
      /**
       * A crowdsale that retains the previous token, but changes some parameters.
       *
       * Investor data can be manually fed in.
       *
       * Mostly useful as a hot fix.
       *
       */
      contract RelaunchedCrowdsale is MintedTokenCappedCrowdsale {
      
        // This transaction was restored from a previous crowdsale
        event RestoredInvestment(address addr, uint originalTxHash);
      
        mapping(uint => bool) public reissuedTransactions;
      
        function RelaunchedCrowdsale(address _token, PricingStrategy _pricingStrategy, address _multisigWallet, uint _start, uint _end, uint _minimumFundingGoal, uint _maximumSellableTokens) MintedTokenCappedCrowdsale(_token, _pricingStrategy, _multisigWallet, _start, _end, _minimumFundingGoal, _maximumSellableTokens) {
        }
      
        /**
         * Check if a particular transaction has already been written.
         */
        function getRestoredTransactionStatus(uint _originalTxHash) public constant returns(bool) {
          return reissuedTransactions[_originalTxHash];
        }
      
        /**
         * Rebuild the previous invest data back to the crowdsale.
         */
        function setInvestorData(address _addr, uint _weiAmount, uint _tokenAmount, uint _originalTxHash) onlyOwner public {
      
          if(investedAmountOf[_addr] == 0) {
            investorCount++;
          }
      
          investedAmountOf[_addr] += _weiAmount;
          tokenAmountOf[_addr] += _tokenAmount;
      
          weiRaised += _weiAmount;
          tokensSold += _tokenAmount;
      
          Invested(_addr, _weiAmount, _tokenAmount, 0);
          RestoredInvestment(_addr, _originalTxHash);
        }
      
        /**
         * Rebuild the previous invest data and do a token reissuance.
         */
        function setInvestorDataAndIssueNewToken(address _addr, uint _weiAmount, uint _tokenAmount, uint _originalTxHash) onlyOwner public {
      
          // This transaction has already been rebuild
          if(reissuedTransactions[_originalTxHash]) {
            throw;
          }
      
          setInvestorData(_addr, _weiAmount, _tokenAmount, _originalTxHash);
      
          // Check that we did not bust the cap in the restoration process
          if(isBreakingCap(_weiAmount, _tokenAmount, weiRaised, tokensSold)) {
            throw;
          }
      
          // Mark transaction processed
          reissuedTransactions[_originalTxHash] = true;
      
          // Mint new token to give it to the original investor
          MintableToken mintableToken = MintableToken(token);
          mintableToken.mint(_addr, _tokenAmount);
        }
      
      }

      File 2 of 2: CrowdsaleToken
      /*
       * ERC20 interface
       * see https://github.com/ethereum/EIPs/issues/20
       */
      contract ERC20 {
        uint public totalSupply;
        function balanceOf(address who) constant returns (uint);
        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);
        event Approval(address indexed owner, address indexed spender, uint value);
      }
      
      
      
      /**
       * Math operations with safety checks
       */
      contract SafeMath {
        function safeMul(uint a, uint b) internal returns (uint) {
          uint c = a * b;
          assert(a == 0 || c / a == b);
          return c;
        }
      
        function safeDiv(uint a, uint b) internal returns (uint) {
          assert(b > 0);
          uint c = a / b;
          assert(a == b * c + a % b);
          return c;
        }
      
        function safeSub(uint a, uint b) internal returns (uint) {
          assert(b <= a);
          return a - b;
        }
      
        function safeAdd(uint a, uint b) internal returns (uint) {
          uint c = a + b;
          assert(c>=a && c>=b);
          return c;
        }
      
        function max64(uint64 a, uint64 b) internal constant returns (uint64) {
          return a >= b ? a : b;
        }
      
        function min64(uint64 a, uint64 b) internal constant returns (uint64) {
          return a < b ? a : b;
        }
      
        function max256(uint256 a, uint256 b) internal constant returns (uint256) {
          return a >= b ? a : b;
        }
      
        function min256(uint256 a, uint256 b) internal constant returns (uint256) {
          return a < b ? a : b;
        }
      
        function assert(bool assertion) internal {
          if (!assertion) {
            throw;
          }
        }
      }
      
      
      
      /**
       * Standard ERC20 token with Short Hand Attack and approve() race condition mitigation.
       *
       * Based on code by FirstBlood:
       * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
       */
      contract StandardToken is ERC20, SafeMath {
      
        /* Token supply got increased and a new owner received these tokens */
        event Minted(address receiver, uint amount);
      
        /* Actual balances of token holders */
        mapping(address => uint) balances;
      
        /* approve() allowances */
        mapping (address => mapping (address => uint)) allowed;
      
        /* Interface declaration */
        function isToken() public constant returns (bool weAre) {
          return true;
        }
      
        /**
         *
         * Fix for the ERC20 short address attack
         *
         * http://vessenes.com/the-erc20-short-address-attack-explained/
         */
        modifier onlyPayloadSize(uint size) {
           if(msg.data.length < size + 4) {
             throw;
           }
           _;
        }
      
        function transfer(address _to, uint _value) onlyPayloadSize(2 * 32) 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) {
          uint _allowance = allowed[_from][msg.sender];
      
          balances[_to] = safeAdd(balances[_to], _value);
          balances[_from] = safeSub(balances[_from], _value);
          allowed[_from][msg.sender] = safeSub(_allowance, _value);
          Transfer(_from, _to, _value);
          return true;
        }
      
        function balanceOf(address _owner) constant returns (uint balance) {
          return balances[_owner];
        }
      
        function approve(address _spender, uint _value) returns (bool success) {
      
          // 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;
      
          allowed[msg.sender][_spender] = _value;
          Approval(msg.sender, _spender, _value);
          return true;
        }
      
        function allowance(address _owner, address _spender) constant returns (uint remaining) {
          return allowed[_owner][_spender];
        }
      
      }
      
      
      
      
      
      /**
       * Upgrade agent interface inspired by Lunyr.
       *
       * Upgrade agent transfers tokens to a new contract.
       * Upgrade agent itself can be the token contract, or just a middle man contract doing the heavy lifting.
       */
      contract UpgradeAgent {
      
        uint public originalSupply;
      
        /** Interface marker */
        function isUpgradeAgent() public constant returns (bool) {
          return true;
        }
      
        function upgradeFrom(address _from, uint256 _value) public;
      
      }
      
      
      /**
       * A token upgrade mechanism where users can opt-in amount of tokens to the next smart contract revision.
       *
       * First envisioned by Golem and Lunyr projects.
       */
      contract UpgradeableToken is StandardToken {
      
        /** Contract / person who can set the upgrade path. This can be the same as team multisig wallet, as what it is with its default value. */
        address public upgradeMaster;
      
        /** The next contract where the tokens will be migrated. */
        UpgradeAgent public upgradeAgent;
      
        /** How many tokens we have upgraded by now. */
        uint256 public totalUpgraded;
      
        /**
         * Upgrade states.
         *
         * - NotAllowed: The child contract has not reached a condition where the upgrade can bgun
         * - WaitingForAgent: Token allows upgrade, but we don't have a new agent yet
         * - ReadyToUpgrade: The agent is set, but not a single token has been upgraded yet
         * - Upgrading: Upgrade agent is set and the balance holders can upgrade their tokens
         *
         */
        enum UpgradeState {Unknown, NotAllowed, WaitingForAgent, ReadyToUpgrade, Upgrading}
      
        /**
         * Somebody has upgraded some of his tokens.
         */
        event Upgrade(address indexed _from, address indexed _to, uint256 _value);
      
        /**
         * New upgrade agent available.
         */
        event UpgradeAgentSet(address agent);
      
        /**
         * Do not allow construction without upgrade master set.
         */
        function UpgradeableToken(address _upgradeMaster) {
          upgradeMaster = _upgradeMaster;
        }
      
        /**
         * Allow the token holder to upgrade some of their tokens to a new contract.
         */
        function upgrade(uint256 value) public {
      
            UpgradeState state = getUpgradeState();
            if(!(state == UpgradeState.ReadyToUpgrade || state == UpgradeState.Upgrading)) {
              // Called in a bad state
              throw;
            }
      
            // Validate input value.
            if (value == 0) throw;
      
            balances[msg.sender] = safeSub(balances[msg.sender], value);
      
            // Take tokens out from circulation
            totalSupply = safeSub(totalSupply, value);
            totalUpgraded = safeAdd(totalUpgraded, value);
      
            // Upgrade agent reissues the tokens
            upgradeAgent.upgradeFrom(msg.sender, value);
            Upgrade(msg.sender, upgradeAgent, value);
        }
      
        /**
         * Set an upgrade agent that handles
         */
        function setUpgradeAgent(address agent) external {
      
            if(!canUpgrade()) {
              // The token is not yet in a state that we could think upgrading
              throw;
            }
      
            if (agent == 0x0) throw;
            // Only a master can designate the next agent
            if (msg.sender != upgradeMaster) throw;
            // Upgrade has already begun for an agent
            if (getUpgradeState() == UpgradeState.Upgrading) throw;
      
            upgradeAgent = UpgradeAgent(agent);
      
            // Bad interface
            if(!upgradeAgent.isUpgradeAgent()) throw;
            // Make sure that token supplies match in source and target
            if (upgradeAgent.originalSupply() != totalSupply) throw;
      
            UpgradeAgentSet(upgradeAgent);
        }
      
        /**
         * Get the state of the token upgrade.
         */
        function getUpgradeState() public constant returns(UpgradeState) {
          if(!canUpgrade()) return UpgradeState.NotAllowed;
          else if(address(upgradeAgent) == 0x00) return UpgradeState.WaitingForAgent;
          else if(totalUpgraded == 0) return UpgradeState.ReadyToUpgrade;
          else return UpgradeState.Upgrading;
        }
      
        /**
         * Change the upgrade master.
         *
         * This allows us to set a new owner for the upgrade mechanism.
         */
        function setUpgradeMaster(address master) public {
            if (master == 0x0) throw;
            if (msg.sender != upgradeMaster) throw;
            upgradeMaster = master;
        }
      
        /**
         * Child contract can enable to provide the condition when the upgrade can begun.
         */
        function canUpgrade() public constant returns(bool) {
           return true;
        }
      
      }
      
      
      
      
      /*
       * Ownable
       *
       * Base contract with an owner.
       * Provides onlyOwner modifier, which prevents function from running if it is called by anyone other than the owner.
       */
      contract Ownable {
        address public owner;
      
        function Ownable() {
          owner = msg.sender;
        }
      
        modifier onlyOwner() {
          if (msg.sender != owner) {
            throw;
          }
          _;
        }
      
        function transferOwnership(address newOwner) onlyOwner {
          if (newOwner != address(0)) {
            owner = newOwner;
          }
        }
      
      }
      
      
      
      
      /**
       * Define interface for releasing the token transfer after a successful crowdsale.
       */
      contract ReleasableToken is ERC20, Ownable {
      
        /* The finalizer contract that allows unlift the transfer limits on this token */
        address public releaseAgent;
      
        /** A crowdsale contract can release us to the wild if ICO success. If false we are are in transfer lock up period.*/
        bool public released = false;
      
        /** Map of agents that are allowed to transfer tokens regardless of the lock down period. These are crowdsale contracts and possible the team multisig itself. */
        mapping (address => bool) public transferAgents;
      
        /**
         * Limit token transfer until the crowdsale is over.
         *
         */
        modifier canTransfer(address _sender) {
      
          if(!released) {
              if(!transferAgents[_sender]) {
                  throw;
              }
          }
      
          _;
        }
      
        /**
         * Set the contract that can call release and make the token transferable.
         *
         * Design choice. Allow reset the release agent to fix fat finger mistakes.
         */
        function setReleaseAgent(address addr) onlyOwner inReleaseState(false) public {
      
          // We don't do interface check here as we might want to a normal wallet address to act as a release agent
          releaseAgent = addr;
        }
      
        /**
         * Owner can allow a particular address (a crowdsale contract) to transfer tokens despite the lock up period.
         */
        function setTransferAgent(address addr, bool state) onlyOwner inReleaseState(false) public {
          transferAgents[addr] = state;
        }
      
        /**
         * One way function to release the tokens to the wild.
         *
         * Can be called only from the release agent that is the final ICO contract. It is only called if the crowdsale has been success (first milestone reached).
         */
        function releaseTokenTransfer() public onlyReleaseAgent {
          released = true;
        }
      
        /** The function can be called only before or after the tokens have been releasesd */
        modifier inReleaseState(bool releaseState) {
          if(releaseState != released) {
              throw;
          }
          _;
        }
      
        /** The function can be called only by a whitelisted release agent. */
        modifier onlyReleaseAgent() {
          if(msg.sender != releaseAgent) {
              throw;
          }
          _;
        }
      
        function transfer(address _to, uint _value) canTransfer(msg.sender) returns (bool success) {
          // Call StandardToken.transfer()
         return super.transfer(_to, _value);
        }
      
        function transferFrom(address _from, address _to, uint _value) canTransfer(_from) returns (bool success) {
          // Call StandardToken.transferForm()
          return super.transferFrom(_from, _to, _value);
        }
      
      }
      
      
      
      
      
      /**
       * Safe unsigned safe math.
       *
       * https://blog.aragon.one/library-driven-development-in-solidity-2bebcaf88736#.750gwtwli
       *
       * Originally from https://raw.githubusercontent.com/AragonOne/zeppelin-solidity/master/contracts/SafeMathLib.sol
       *
       * Maintained here until merged to mainline zeppelin-solidity.
       *
       */
      library SafeMathLib {
      
        function times(uint a, uint b) returns (uint) {
          uint c = a * b;
          assert(a == 0 || c / a == b);
          return c;
        }
      
        function minus(uint a, uint b) returns (uint) {
          assert(b <= a);
          return a - b;
        }
      
        function plus(uint a, uint b) returns (uint) {
          uint c = a + b;
          assert(c>=a);
          return c;
        }
      
        function assert(bool assertion) private {
          if (!assertion) throw;
        }
      }
      
      
      
      /**
       * A token that can increase its supply by another contract.
       *
       * This allows uncapped crowdsale by dynamically increasing the supply when money pours in.
       * Only mint agents, contracts whitelisted by owner, can mint new tokens.
       *
       */
      contract MintableToken is StandardToken, Ownable {
      
        using SafeMathLib for uint;
      
        bool public mintingFinished = false;
      
        /** List of agents that are allowed to create new tokens */
        mapping (address => bool) public mintAgents;
      
        event MintingAgentChanged(address addr, bool state  );
      
        /**
         * Create new tokens and allocate them to an address..
         *
         * Only callably by a crowdsale contract (mint agent).
         */
        function mint(address receiver, uint amount) onlyMintAgent canMint public {
          totalSupply = totalSupply.plus(amount);
          balances[receiver] = balances[receiver].plus(amount);
      
          // This will make the mint transaction apper in EtherScan.io
          // We can remove this after there is a standardized minting event
          Transfer(0, receiver, amount);
        }
      
        /**
         * Owner can allow a crowdsale contract to mint new tokens.
         */
        function setMintAgent(address addr, bool state) onlyOwner canMint public {
          mintAgents[addr] = state;
          MintingAgentChanged(addr, state);
        }
      
        modifier onlyMintAgent() {
          // Only crowdsale contracts are allowed to mint new tokens
          if(!mintAgents[msg.sender]) {
              throw;
          }
          _;
        }
      
        /** Make sure we are not done yet. */
        modifier canMint() {
          if(mintingFinished) throw;
          _;
        }
      }
      
      
      
      /**
       * A crowdsaled token.
       *
       * An ERC-20 token designed specifically for crowdsales with investor protection and further development path.
       *
       * - The token transfer() is disabled until the crowdsale is over
       * - The token contract gives an opt-in upgrade path to a new contract
       * - The same token can be part of several crowdsales through approve() mechanism
       * - The token can be capped (supply set in the constructor) or uncapped (crowdsale contract can mint new tokens)
       *
       */
      contract CrowdsaleToken is ReleasableToken, MintableToken, UpgradeableToken {
      
        /** Name and symbol were updated. */
        event UpdatedTokenInformation(string newName, string newSymbol);
      
        string public name;
      
        string public symbol;
      
        uint public decimals;
      
        /**
         * Construct the token.
         *
         * This token must be created through a team multisig wallet, so that it is owned by that wallet.
         *
         * @param _name Token name
         * @param _symbol Token symbol - should be all caps
         * @param _initialSupply How many tokens we start with
         * @param _decimals Number of decimal places
         * @param _mintable Are new tokens created over the crowdsale or do we distribute only the initial supply? Note that when the token becomes transferable the minting always ends.
         */
        function CrowdsaleToken(string _name, string _symbol, uint _initialSupply, uint _decimals, bool _mintable)
          UpgradeableToken(msg.sender) {
      
          // Create any address, can be transferred
          // to team multisig via changeOwner(),
          // also remember to call setUpgradeMaster()
          owner = msg.sender;
      
          name = _name;
          symbol = _symbol;
      
          totalSupply = _initialSupply;
      
          decimals = _decimals;
      
          // Create initially all balance on the team multisig
          balances[owner] = totalSupply;
      
          if(totalSupply > 0) {
            Minted(owner, totalSupply);
          }
      
          // No more new supply allowed after the token creation
          if(!_mintable) {
            mintingFinished = true;
            if(totalSupply == 0) {
              throw; // Cannot create a token without supply and no minting
            }
          }
        }
      
        /**
         * When token is released to be transferable, enforce no new tokens can be created.
         */
        function releaseTokenTransfer() public onlyReleaseAgent {
          mintingFinished = true;
          super.releaseTokenTransfer();
        }
      
        /**
         * Allow upgrade agent functionality kick in only if the crowdsale was success.
         */
        function canUpgrade() public constant returns(bool) {
          return released && super.canUpgrade();
        }
      
        /**
         * Owner can update token information here.
         *
         * It is often useful to conceal the actual token association, until
         * the token operations, like central issuance or reissuance have been completed.
         *
         * This function allows the token owner to rename the token after the operations
         * have been completed and then point the audience to use the token contract.
         */
        function setTokenInformation(string _name, string _symbol) onlyOwner {
          name = _name;
          symbol = _symbol;
      
          UpdatedTokenInformation(name, symbol);
        }
      
      }