contract CBTToken is StandardToken {

    // metadata
    string public constant name = "Crebit Token";
    string public constant symbol = "CBT";
    uint256 public constant decimals = 18;
    string public version = "1.0";

    // contracts
    address public ethFundDeposit;      // deposit address of ETH for Crebit Ltd.
    address public cbtFundDeposit;      // deposit address of CBT for Crebit Ltd.

    // crowdsale parameters
    bool public isFinalized;              // switched to true in operational state
    uint256 public fundingStartBlock;
    uint256 public fundingEndBlock;
    uint256 public crowdsaleSupply = 0;         // crowdsale supply
    uint256 public tokenExchangeRate = 6500;    // 6500 CBT tokens per 1 ETH
    uint256 public constant tokenCreationCap =  1 * (10**9) * 10**decimals;
    uint256 public tokenCrowdsaleCap =  1 * (10**8) * 10**decimals;

    // events
    event CreateCBT(address indexed _to, uint256 _value);

    // constructor
    function CBTToken(
        address _ethFundDeposit,
        address _cbtFundDeposit,
        uint256 _tokenExchangeRate,
        uint256 _fundingStartBlock,
        uint256 _fundingEndBlock) public
    {
        isFinalized = false;                   //controls pre through crowdsale state
        ethFundDeposit = _ethFundDeposit;
        cbtFundDeposit = _cbtFundDeposit;
        tokenExchangeRate = _tokenExchangeRate;
        fundingStartBlock = _fundingStartBlock;
        fundingEndBlock = _fundingEndBlock;
        totalSupply = tokenCreationCap;
        balances[cbtFundDeposit] = tokenCreationCap;    // deposit all CBT to Crebit Ltd.
        CreateCBT(cbtFundDeposit, tokenCreationCap);    // logs deposit of Crebit Ltd. fund
    }

    function () public payable {
        assert(!isFinalized);
        require(block.number >= fundingStartBlock);
        require(block.number < fundingEndBlock);
        require(msg.value > 0);

        uint256 tokens = safeMult(msg.value, tokenExchangeRate);    // check that we're not over totals
        crowdsaleSupply = safeAdd(crowdsaleSupply, tokens);

        // return money if something goes wrong
        require(tokenCrowdsaleCap >= crowdsaleSupply);

        balances[msg.sender] += tokens;     // add amount of CBT to sender
        balances[cbtFundDeposit] = safeSub(balances[cbtFundDeposit], tokens); // subtracts amount from Crebit's balance
        CreateCBT(msg.sender, tokens);      // logs token creation

    }
    /// @dev Accepts ether and creates new CBT tokens.
    function createTokens() payable external {
        assert(!isFinalized);
        require(block.number >= fundingStartBlock);
        require(block.number < fundingEndBlock);
        require(msg.value > 0);

        uint256 tokens = safeMult(msg.value, tokenExchangeRate);    // check that we're not over totals
        crowdsaleSupply = safeAdd(crowdsaleSupply, tokens);

        // return money if something goes wrong
        require(tokenCrowdsaleCap >= crowdsaleSupply);

        balances[msg.sender] += tokens;     // add amount of CBT to sender
        balances[cbtFundDeposit] = safeSub(balances[cbtFundDeposit], tokens); // subtracts amount from Crebit's balance
        CreateCBT(msg.sender, tokens);      // logs token creation
    }

    /* Approve and then communicate the approved contract in a single tx */
    function approveAndCall(address _spender, uint256 _value, bytes _extraData) public
        returns (bool success) {    
        tokenRecipient spender = tokenRecipient(_spender);
        if (approve(_spender, _value)) {
            spender.receiveApproval(msg.sender, _value, this, _extraData);
            return true;
        }
    }
    /// @dev Update crowdsale parameter
    function updateParams(
        uint256 _tokenExchangeRate,
        uint256 _tokenCrowdsaleCap,
        uint256 _fundingStartBlock,
        uint256 _fundingEndBlock) onlyOwner external 
    {
        assert(block.number < fundingStartBlock);
        assert(!isFinalized);
      
        // update system parameters
        tokenExchangeRate = _tokenExchangeRate;
        tokenCrowdsaleCap = _tokenCrowdsaleCap;
        fundingStartBlock = _fundingStartBlock;
        fundingEndBlock = _fundingEndBlock;
    }
    /// @dev Ends the funding period and sends the ETH home
    function finalize() onlyOwner external {
        assert(!isFinalized);
      
        // move to operational
        isFinalized = true;
        assert(ethFundDeposit.send(this.balance));              // send the eth to Crebit ltd.
    }
}
function finalize() onlyOwner external {
    assert(!isFinalized);
      
    // move to operational
    isFinalized = true;
    assert(ethFundDeposit.send(this.balance));              // send the eth to Crebit ltd.
}

/// @dev Ends the funding period and sends the ETH home