ETH Price: $1,987.42 (+6.65%)
Gas: 0.03 Gwei

Transaction Decoder

Block:
4615937 at Nov-24-2017 11:14:36 PM +UTC
Transaction Fee:
0.00036943 ETH $0.73
Gas Used:
73,886 Gas / 5 Gwei

Emitted Events:

126 PreCAToken.Unpause( )
127 PreCAToken.Transfer( from=[Receiver] CATCrowdsale, to=0x0FC248e2dD7DDd27F4400566F2c25BA49EACb049, value=50000000000000000000 )
128 PreCAToken.Pause( )

Account State Difference:

  Address   Before After State Difference Code
(Nanopool)
7,924.384271272915506064 Eth7,924.384640702915506064 Eth0.00036943
0x68e14bb5...d962C1a39
0xec4f63C5...b5E5BFdAc
11.445485354 Eth
Nonce: 13388
11.445115924 Eth
Nonce: 13389
0.00036943

Execution Trace

CATCrowdsale.transferPresaleTokens( destination=0x0FC248e2dD7DDd27F4400566F2c25BA49EACb049, amount=50000000000000000000 )
  • PreCAToken.CALL( )
  • PreCAToken.transfer( _to=0x0FC248e2dD7DDd27F4400566F2c25BA49EACb049, _value=50000000000000000000 ) => ( True )
  • PreCAToken.CALL( )
    File 1 of 2: CATCrowdsale
    pragma solidity ^0.4.11;
    
    //
    // SafeMath
    //
    // Ownable
    // Destructible
    // Pausable
    //
    // ERC20Basic
    // ERC20 : ERC20Basic
    // BasicToken : ERC20Basic
    // StandardToken : ERC20, BasicToken
    // MintableToken : StandardToken, Ownable
    // PausableToken : StandardToken, Pausable
    //
    // CAToken : MintableToken, PausableToken
    //
    // Crowdsale
    // PausableCrowdsale
    // BonusCrowdsale
    // TokensCappedCrowdsale
    // FinalizableCrowdsale
    //
    // CATCrowdsale
    //
    
    /**
     * @title SafeMath
     * @dev Math operations with safety checks that throw on error
     */
    library SafeMath {
      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a * b;
        assert(a == 0 || c / a == b);
        return c;
      }
    
      function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // assert(b > 0); // Solidity automatically throws when dividing by 0
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        return c;
      }
    
      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        assert(b <= a);
        return a - b;
      }
    
      function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        assert(c >= a);
        return c;
      }
    }
    
    /**
     * @title Ownable
     * @dev The Ownable contract has an owner address, and provides basic authorization control
     * functions, this simplifies the implementation of "user permissions".
     */
    contract Ownable {
      address public owner;
    
    
      event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
    
      /**
       * @dev The Ownable constructor sets the original `owner` of the contract to the sender
       * account.
       */
      function Ownable() public {
        owner = msg.sender;
      }
    
    
      /**
       * @dev Throws if called by any account other than the owner.
       */
      modifier onlyOwner() {
        require(msg.sender == owner);
        _;
      }
    
    
      /**
       * @dev Allows the current owner to transfer control of the contract to a newOwner.
       * @param newOwner The address to transfer ownership to.
       */
      function transferOwnership(address newOwner) onlyOwner public {
        require(newOwner != address(0));
        OwnershipTransferred(owner, newOwner);
        owner = newOwner;
      }
    
    }
    
    /**
     * @title Destructible
     * @dev Base contract that can be destroyed by owner. All funds in contract will be sent to the owner.
     */
    contract Destructible is Ownable {
    
      function Destructible() public payable { }
    
      /**
       * @dev Transfers the current balance to the owner and terminates the contract.
       */
      function destroy() onlyOwner public {
        selfdestruct(owner);
      }
    
      function destroyAndSend(address _recipient) onlyOwner public {
        selfdestruct(_recipient);
      }
    }
    
    /**
     * @title Pausable
     * @dev Base contract which allows children to implement an emergency stop mechanism.
     */
    contract Pausable is Ownable {
      event Pause();
      event Unpause();
    
      bool public paused = false;
    
    
      /**
       * @dev Modifier to make a function callable only when the contract is not paused.
       */
      modifier whenNotPaused() {
        require(!paused);
        _;
      }
    
      /**
       * @dev Modifier to make a function callable only when the contract is paused.
       */
      modifier whenPaused() {
        require(paused);
        _;
      }
    
      /**
       * @dev called by the owner to pause, triggers stopped state
       */
      function pause() onlyOwner whenNotPaused public {
        paused = true;
        Pause();
      }
    
      /**
       * @dev called by the owner to unpause, returns to normal state
       */
      function unpause() onlyOwner whenPaused public {
        paused = false;
        Unpause();
      }
    }
    
    /**
     * @title ERC20Basic
     * @dev Simpler version of ERC20 interface
     * @dev see https://github.com/ethereum/EIPs/issues/179
     */
    contract ERC20Basic {
      uint256 public totalSupply;
      function balanceOf(address who) public constant returns (uint256);
      function transfer(address to, uint256 value) public returns (bool);
      event Transfer(address indexed from, address indexed to, uint256 value);
    }
    
    /**
     * @title ERC20 interface
     * @dev see https://github.com/ethereum/EIPs/issues/20
     */
    contract ERC20 is ERC20Basic {
      function allowance(address owner, address spender) public constant returns (uint256);
      function transferFrom(address from, address to, uint256 value) public returns (bool);
      function approve(address spender, uint256 value) public returns (bool);
      event Approval(address indexed owner, address indexed spender, uint256 value);
    }
    
    /**
     * @title Basic token
     * @dev Basic version of StandardToken, with no allowances.
     */
    contract BasicToken is ERC20Basic {
      using SafeMath for uint256;
    
      mapping(address => uint256) balances;
    
      /**
      * @dev transfer token for a specified address
      * @param _to The address to transfer to.
      * @param _value The amount to be transferred.
      */
      function transfer(address _to, uint256 _value) public returns (bool) {
        require(_to != address(0));
    
        // SafeMath.sub will throw if there is not enough balance.
        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(_value);
        Transfer(msg.sender, _to, _value);
        return true;
      }
    
      /**
      * @dev Gets the balance of the specified address.
      * @param _owner The address to query the the balance of.
      * @return An uint256 representing the amount owned by the passed address.
      */
      function balanceOf(address _owner) public constant returns (uint256 balance) {
        return balances[_owner];
      }
    
    }
    
    /**
     * @title Standard ERC20 token
     *
     * @dev Implementation of the basic standard token.
     * @dev https://github.com/ethereum/EIPs/issues/20
     * @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
     */
    contract StandardToken is ERC20, BasicToken {
    
      mapping (address => mapping (address => uint256)) allowed;
    
    
      /**
       * @dev Transfer tokens from one address to another
       * @param _from address The address which you want to send tokens from
       * @param _to address The address which you want to transfer to
       * @param _value uint256 the amount of tokens to be transferred
       */
      function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
        require(_to != address(0));
    
        uint256 _allowance = allowed[_from][msg.sender];
    
        // Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
        // require (_value <= _allowance);
    
        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(_value);
        allowed[_from][msg.sender] = _allowance.sub(_value);
        Transfer(_from, _to, _value);
        return true;
      }
    
      /**
       * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
       *
       * Beware that changing an allowance with this method brings the risk that someone may use both the old
       * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
       * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
       * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
       * @param _spender The address which will spend the funds.
       * @param _value The amount of tokens to be spent.
       */
      function approve(address _spender, uint256 _value) public returns (bool) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
      }
    
      /**
       * @dev Function to check the amount of tokens that an owner allowed to a spender.
       * @param _owner address The address which owns the funds.
       * @param _spender address The address which will spend the funds.
       * @return A uint256 specifying the amount of tokens still available for the spender.
       */
      function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
        return allowed[_owner][_spender];
      }
    
      /**
       * approve should be called when allowed[_spender] == 0. To increment
       * allowed value is better to use this function to avoid 2 calls (and wait until
       * the first transaction is mined)
       * From MonolithDAO Token.sol
       */
      function increaseApproval (address _spender, uint _addedValue) public
        returns (bool success) {
        allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
        Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
        return true;
      }
    
      function decreaseApproval (address _spender, uint _subtractedValue) public
        returns (bool success) {
        uint oldValue = allowed[msg.sender][_spender];
        if (_subtractedValue > oldValue) {
          allowed[msg.sender][_spender] = 0;
        } else {
          allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
        }
        Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
        return true;
      }
    
    }
    
    /**
     * @title Mintable token
     * @dev Simple ERC20 Token example, with mintable token creation
     * @dev 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, uint256 amount);
      event MintFinished();
    
      bool public mintingFinished = false;
    
    
      modifier canMint() {
        require(!mintingFinished);
        _;
      }
    
      /**
       * @dev Function to mint tokens
       * @param _to The address that will receive the minted tokens.
       * @param _amount The amount of tokens to mint.
       * @return A boolean that indicates if the operation was successful.
       */
      function mint(address _to, uint256 _amount) onlyOwner canMint public returns (bool) {
        totalSupply = totalSupply.add(_amount);
        balances[_to] = balances[_to].add(_amount);
        Mint(_to, _amount);
        Transfer(0x0, _to, _amount);
        return true;
      }
    
      /**
       * @dev Function to stop minting new tokens.
       * @return True if the operation was successful.
       */
      function finishMinting() onlyOwner public returns (bool) {
        mintingFinished = true;
        MintFinished();
        return true;
      }
    }
    
    /**
     * @title Pausable token
     *
     * @dev StandardToken modified with pausable transfers.
     **/
    
    contract PausableToken is StandardToken, Pausable {
    
      function transfer(address _to, uint256 _value) public whenNotPaused returns (bool) {
        return super.transfer(_to, _value);
      }
    
      function transferFrom(address _from, address _to, uint256 _value) public whenNotPaused returns (bool) {
        return super.transferFrom(_from, _to, _value);
      }
    
      function approve(address _spender, uint256 _value) public whenNotPaused returns (bool) {
        return super.approve(_spender, _value);
      }
    
      function increaseApproval(address _spender, uint _addedValue) public whenNotPaused returns (bool success) {
        return super.increaseApproval(_spender, _addedValue);
      }
    
      function decreaseApproval(address _spender, uint _subtractedValue) public whenNotPaused returns (bool success) {
        return super.decreaseApproval(_spender, _subtractedValue);
      }
    }
    
    /**
    * @dev Pre main Bitcalve CAT token ERC20 contract
    * Based on references from OpenZeppelin: https://github.com/OpenZeppelin/zeppelin-solidity
    */
    contract CAToken is MintableToken, PausableToken {
        
        // Metadata
        string public constant symbol = "CAT";
        string public constant name = "BitClave - Consumer Activity Token";
        uint8 public constant decimals = 18;
        string public constant version = "2.0";
    
        /**
        * @dev Override MintableTokenn.finishMinting() to add canMint modifier
        */
        function finishMinting() onlyOwner canMint public returns(bool) {
            return super.finishMinting();
        }
    
    }
    
    /**
    * @dev Main Bitcalve PreCAT token ERC20 contract
    * Based on references from OpenZeppelin: https://github.com/OpenZeppelin/zeppelin-solidity
    */
    contract PreCAToken is CAToken, Destructible {
    
        // Metadata
        string public constant symbol = "CAT";
        string public constant name = "BitClave - Consumer Activity Token";
        uint8 public constant decimals = 18;
        string public constant version = "1.1";
    
        // Overrided destructor
        function destroy() public onlyOwner {
            require(mintingFinished);
            super.destroy();
        }
    
        // Overrided destructor companion
        function destroyAndSend(address _recipient) public onlyOwner {
            require(mintingFinished);
            super.destroyAndSend(_recipient);
        }
    
    }
    
    /**
     * @title Crowdsale
     * @dev Crowdsale is a base contract for managing a token crowdsale.
     * Crowdsales have a start and end timestamps, where investors can make
     * token purchases and the crowdsale will assign them tokens based
     * on a token per ETH rate. Funds collected are forwarded to a wallet
     * as they arrive.
     */
    contract Crowdsale {
      using SafeMath for uint256;
    
      // The token being sold
      MintableToken public token;
    
      // start and end timestamps where investments are allowed (both inclusive)
      uint256 public startTime;
      uint256 public endTime;
    
      // address where funds are collected
      address public wallet;
    
      // how many token units a buyer gets per wei
      uint256 public rate;
    
      // amount of raised money in wei
      uint256 public weiRaised;
    
      /**
       * event for token purchase logging
       * @param purchaser who paid for the tokens
       * @param beneficiary who got the tokens
       * @param value weis paid for purchase
       * @param amount amount of tokens purchased
       */
      event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
    
    
      function Crowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, address _wallet) public {
        require(_startTime >= now);
        require(_endTime >= _startTime);
        require(_rate > 0);
        require(_wallet != 0x0);
    
        token = createTokenContract();
        startTime = _startTime;
        endTime = _endTime;
        rate = _rate;
        wallet = _wallet;
      }
    
      // creates the token to be sold.
      // override this method to have crowdsale of a specific mintable token.
      function createTokenContract() internal returns (MintableToken) {
        return new MintableToken();
      }
    
    
      // fallback function can be used to buy tokens
      function () public payable {
        buyTokens(msg.sender);
      }
    
      // low level token purchase function
      function buyTokens(address beneficiary) public payable {
        require(beneficiary != 0x0);
        require(validPurchase());
    
        uint256 weiAmount = msg.value;
    
        // calculate token amount to be created
        uint256 tokens = weiAmount.mul(rate);
    
        // update state
        weiRaised = weiRaised.add(weiAmount);
    
        token.mint(beneficiary, tokens);
        TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
    
        forwardFunds();
      }
    
      // send ether to the fund collection wallet
      // override to create custom fund forwarding mechanisms
      function forwardFunds() internal {
        wallet.transfer(msg.value);
      }
    
      // @return true if the transaction can buy tokens
      function validPurchase() internal constant returns (bool) {
        bool withinPeriod = now >= startTime && now <= endTime;
        bool nonZeroPurchase = msg.value != 0;
        return withinPeriod && nonZeroPurchase;
      }
    
      // @return true if crowdsale event has ended
      function hasEnded() public constant returns (bool) {
        return now > endTime;
      }
    
    
    }
    
    /**
    * @dev Parent crowdsale contract extended with support for pausable crowdsale, meaning crowdsale can be paused by owner at any time
    * Based on references from OpenZeppelin: https://github.com/OpenZeppelin/zeppelin-solidity
    * 
    * While the contract is in paused state, the contributions will be rejected
    * 
    */
    contract PausableCrowdsale is Crowdsale, Pausable {
    
        function PausableCrowdsale(bool _paused) public {
            if (_paused) {
                pause();
            }
        }
    
        // overriding Crowdsale#validPurchase to add extra paused logic
        // @return true if investors can buy at the moment
        function validPurchase() internal constant returns(bool) {
            return super.validPurchase() && !paused;
        }
    
    }
    
    /**
    * @dev Parent crowdsale contract with support for time-based and amount based bonuses 
    * Based on references from OpenZeppelin: https://github.com/OpenZeppelin/zeppelin-solidity
    * 
    */
    contract BonusCrowdsale is Crowdsale, Ownable {
    
        // Constants
        // The following will be populated by main crowdsale contract
        uint32[] public BONUS_TIMES;
        uint32[] public BONUS_TIMES_VALUES;
        uint32[] public BONUS_AMOUNTS;
        uint32[] public BONUS_AMOUNTS_VALUES;
        uint public constant BONUS_COEFF = 1000; // Values should be 10x percents, value 1000 = 100%
        
        // Members
        uint public tokenPriceInCents;
    
        /**
        * @dev Contructor
        * @param _tokenPriceInCents token price in USD cents. The price is fixed
        */
        function BonusCrowdsale(uint256 _tokenPriceInCents) public {
            tokenPriceInCents = _tokenPriceInCents;
        }
    
        /**
        * @dev Retrieve length of bonuses by time array
        * @return Bonuses by time array length
        */
        function bonusesForTimesCount() public constant returns(uint) {
            return BONUS_TIMES.length;
        }
    
        /**
        * @dev Sets bonuses for time
        */
        function setBonusesForTimes(uint32[] times, uint32[] values) public onlyOwner {
            require(times.length == values.length);
            for (uint i = 0; i + 1 < times.length; i++) {
                require(times[i] < times[i+1]);
            }
    
            BONUS_TIMES = times;
            BONUS_TIMES_VALUES = values;
        }
    
        /**
        * @dev Retrieve length of bonuses by amounts array
        * @return Bonuses by amounts array length
        */
        function bonusesForAmountsCount() public constant returns(uint) {
            return BONUS_AMOUNTS.length;
        }
    
        /**
        * @dev Sets bonuses for USD amounts
        */
        function setBonusesForAmounts(uint32[] amounts, uint32[] values) public onlyOwner {
            require(amounts.length == values.length);
            for (uint i = 0; i + 1 < amounts.length; i++) {
                require(amounts[i] > amounts[i+1]);
            }
    
            BONUS_AMOUNTS = amounts;
            BONUS_AMOUNTS_VALUES = values;
        }
    
        /**
        * @dev Overrided buyTokens method of parent Crowdsale contract  to provide bonus by changing and restoring rate variable
        * @param beneficiary walelt of investor to receive tokens
        */
        function buyTokens(address beneficiary) public payable {
            // Compute usd amount = wei * catsInEth * usdcentsInCat / usdcentsPerUsd / weisPerEth
            uint256 usdValue = msg.value.mul(rate).mul(tokenPriceInCents).div(100).div(1 ether); 
            
            // Compute time and amount bonus
            uint256 bonus = computeBonus(usdValue);
    
            // Apply bonus by adjusting and restoring rate member
            uint256 oldRate = rate;
            rate = rate.mul(BONUS_COEFF.add(bonus)).div(BONUS_COEFF);
            super.buyTokens(beneficiary);
            rate = oldRate;
        }
    
        /**
        * @dev Computes overall bonus based on time of contribution and amount of contribution. 
        * The total bonus is the sum of bonus by time and bonus by amount
        * @return bonus percentage scaled by 10
        */
        function computeBonus(uint256 usdValue) public constant returns(uint256) {
            return computeAmountBonus(usdValue).add(computeTimeBonus());
        }
    
        /**
        * @dev Computes bonus based on time of contribution relative to the beginning of crowdsale
        * @return bonus percentage scaled by 10
        */
        function computeTimeBonus() public constant returns(uint256) {
            require(now >= startTime);
    
            for (uint i = 0; i < BONUS_TIMES.length; i++) {
                if (now.sub(startTime) <= BONUS_TIMES[i]) {
                    return BONUS_TIMES_VALUES[i];
                }
            }
    
            return 0;
        }
    
        /**
        * @dev Computes bonus based on amount of contribution
        * @return bonus percentage scaled by 10
        */
        function computeAmountBonus(uint256 usdValue) public constant returns(uint256) {
            for (uint i = 0; i < BONUS_AMOUNTS.length; i++) {
                if (usdValue >= BONUS_AMOUNTS[i]) {
                    return BONUS_AMOUNTS_VALUES[i];
                }
            }
    
            return 0;
        }
    
    }
    
    
    
    /**
    * @dev Parent crowdsale contract is extended with support for cap in tokens
    * Based on references from OpenZeppelin: https://github.com/OpenZeppelin/zeppelin-solidity
    * 
    */
    contract TokensCappedCrowdsale is Crowdsale {
    
        uint256 public tokensCap;
    
        function TokensCappedCrowdsale(uint256 _tokensCap) public {
            tokensCap = _tokensCap;
        }
    
        // overriding Crowdsale#validPurchase to add extra tokens cap logic
        // @return true if investors can buy at the moment
        function validPurchase() internal constant returns(bool) {
            uint256 tokens = token.totalSupply().add(msg.value.mul(rate));
            bool withinCap = tokens <= tokensCap;
            return super.validPurchase() && withinCap;
        }
    
        // overriding Crowdsale#hasEnded to add tokens cap logic
        // @return true if crowdsale event has ended
        function hasEnded() public constant returns(bool) {
            bool capReached = token.totalSupply() >= tokensCap;
            return super.hasEnded() || capReached;
        }
    
    }
    
    /**
     * @title FinalizableCrowdsale
     * @dev Extension of Crowdsale where an owner can do extra work
     * after finishing.
     */
    contract FinalizableCrowdsale is Crowdsale, Ownable {
      using SafeMath for uint256;
    
      bool public isFinalized = false;
    
      event Finalized();
    
      /**
       * @dev Must be called after crowdsale ends, to do some extra finalization
       * work. Calls the contract's finalization function.
       */
      function finalize() onlyOwner public {
        require(!isFinalized);
        require(hasEnded());
    
        finalization();
        Finalized();
    
        isFinalized = true;
      }
    
      /**
       * @dev Can be overridden to add finalization logic. The overriding function
       * should call super.finalization() to ensure the chain of finalization is
       * executed entirely.
       */
      function finalization() internal {
        isFinalized = isFinalized;
      }
    }
    
    
       /**
       * @dev Main BitCalve Crowdsale contract. 
       * Based on references from OpenZeppelin: https://github.com/OpenZeppelin/zeppelin-solidity
       * 
       */
    contract CATCrowdsale is FinalizableCrowdsale, TokensCappedCrowdsale(CATCrowdsale.CAP), PausableCrowdsale(true), BonusCrowdsale(CATCrowdsale.TOKEN_USDCENT_PRICE) {
    
        // Constants
        uint256 public constant DECIMALS = 18;
        uint256 public constant CAP = 2 * (10**9) * (10**DECIMALS);              // 2B CAT
        uint256 public constant BITCLAVE_AMOUNT = 1 * (10**9) * (10**DECIMALS);  // 1B CAT
        uint256 public constant TOKEN_USDCENT_PRICE = 10;                        // $0.10
    
        // Variables
        address public remainingTokensWallet;
        address public presaleWallet;
    
        /**
        * @dev Sets CAT to Ether rate. Will be called multiple times durign the crowdsale to adjsut the rate
        * since CAT cost is fixed in USD, but USD/ETH rate is changing
        * @param _rate defines CAT/ETH rate: 1 ETH = _rate CATs
        */
        function setRate(uint256 _rate) external onlyOwner {
            require(_rate != 0x0);
            rate = _rate;
            RateChange(_rate);
        }
    
        /**
        * @dev Allows to adjust the crowdsale end time
        */
        function setEndTime(uint256 _endTime) external onlyOwner {
            require(!isFinalized);
            require(_endTime >= startTime);
            require(_endTime >= now);
            endTime = _endTime;
        }
    
        /**
        * @dev Sets the wallet to forward ETH collected funds
        */
        function setWallet(address _wallet) external onlyOwner {
            require(_wallet != 0x0);
            wallet = _wallet;
        }
    
        /**
        * @dev Sets the wallet to hold unsold tokens at the end of ICO
        */
        function setRemainingTokensWallet(address _remainingTokensWallet) external onlyOwner {
            require(_remainingTokensWallet != 0x0);
            remainingTokensWallet = _remainingTokensWallet;
        }
    
        // Events
        event RateChange(uint256 rate);
    
        /**
        * @dev Contructor
        * @param _startTime startTime of crowdsale
        * @param _endTime endTime of crowdsale
        * @param _rate CAT / ETH rate
        * @param _wallet wallet to forward the collected funds
        * @param _remainingTokensWallet wallet to hold the unsold tokens
        * @param _bitClaveWallet wallet to hold the initial 1B tokens of BitClave
        */
        function CATCrowdsale(
            uint256 _startTime,
            uint256 _endTime,
            uint256 _rate,
            address _wallet,
            address _remainingTokensWallet,
            address _bitClaveWallet
        ) public
            Crowdsale(_startTime, _endTime, _rate, _wallet)
        {
            remainingTokensWallet = _remainingTokensWallet;
            presaleWallet = this;
    
            // allocate tokens to BitClave
            mintTokens(_bitClaveWallet, BITCLAVE_AMOUNT);
        }
    
        // Overrided methods
    
        /**
        * @dev Creates token contract for ICO
        * @return ERC20 contract associated with the crowdsale
        */
        function createTokenContract() internal returns(MintableToken) {
            PreCAToken token = new PreCAToken();
            token.pause();
            return token;
        }
    
        /**
        * @dev Finalizes the crowdsale
        */
        function finalization() internal {
            super.finalization();
    
            // Mint tokens up to CAP
            if (token.totalSupply() < tokensCap) {
                uint tokens = tokensCap.sub(token.totalSupply());
                token.mint(remainingTokensWallet, tokens);
            }
    
            // disable minting of CATs
            token.finishMinting();
    
            // take onwership over CAToken contract
            token.transferOwnership(owner);
        }
    
        // Owner methods
    
        /**
        * @dev Helper to Pause CAToken
        */
        function pauseTokens() public onlyOwner {
            PreCAToken(token).pause();
        }
    
        /**
        * @dev Helper to UnPause CAToken
        */
        function unpauseTokens() public onlyOwner {
            PreCAToken(token).unpause();
        }
    
        /**
        * @dev Allocates tokens from preSale to a special wallet. Called once as part of crowdsale setup
        */
        function mintPresaleTokens(uint256 tokens) public onlyOwner {
            mintTokens(presaleWallet, tokens);
            presaleWallet = 0;
        }
    
        /**
        * @dev Transfer presaled tokens even on paused token contract
        */
        function transferPresaleTokens(address destination, uint256 amount) public onlyOwner {
            unpauseTokens();
            token.transfer(destination, amount);
            pauseTokens();
        }
    
        // 
        /**
        * @dev Allocates tokens for investors that contributed from website. These include
        * whitelisted investors and investors paying with BTC/QTUM/LTC
        */
        function mintTokens(address beneficiary, uint256 tokens) public onlyOwner {
            require(beneficiary != 0x0);
            require(tokens > 0);
            require(now <= endTime);                               // Crowdsale (without startTime check)
            require(!isFinalized);                                 // FinalizableCrowdsale
            require(token.totalSupply().add(tokens) <= tokensCap); // TokensCappedCrowdsale
            
            token.mint(beneficiary, tokens);
        }
    
    }

    File 2 of 2: PreCAToken
    pragma solidity ^0.4.11;
    
    //
    // SafeMath
    //
    // Ownable
    // Destructible
    // Pausable
    //
    // ERC20Basic
    // ERC20 : ERC20Basic
    // BasicToken : ERC20Basic
    // StandardToken : ERC20, BasicToken
    // MintableToken : StandardToken, Ownable
    // PausableToken : StandardToken, Pausable
    //
    // CAToken : MintableToken, PausableToken
    //
    // Crowdsale
    // PausableCrowdsale
    // BonusCrowdsale
    // TokensCappedCrowdsale
    // FinalizableCrowdsale
    //
    // CATCrowdsale
    //
    
    /**
     * @title SafeMath
     * @dev Math operations with safety checks that throw on error
     */
    library SafeMath {
      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a * b;
        assert(a == 0 || c / a == b);
        return c;
      }
    
      function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // assert(b > 0); // Solidity automatically throws when dividing by 0
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        return c;
      }
    
      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        assert(b <= a);
        return a - b;
      }
    
      function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        assert(c >= a);
        return c;
      }
    }
    
    /**
     * @title Ownable
     * @dev The Ownable contract has an owner address, and provides basic authorization control
     * functions, this simplifies the implementation of "user permissions".
     */
    contract Ownable {
      address public owner;
    
    
      event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    
    
      /**
       * @dev The Ownable constructor sets the original `owner` of the contract to the sender
       * account.
       */
      function Ownable() public {
        owner = msg.sender;
      }
    
    
      /**
       * @dev Throws if called by any account other than the owner.
       */
      modifier onlyOwner() {
        require(msg.sender == owner);
        _;
      }
    
    
      /**
       * @dev Allows the current owner to transfer control of the contract to a newOwner.
       * @param newOwner The address to transfer ownership to.
       */
      function transferOwnership(address newOwner) onlyOwner public {
        require(newOwner != address(0));
        OwnershipTransferred(owner, newOwner);
        owner = newOwner;
      }
    
    }
    
    /**
     * @title Destructible
     * @dev Base contract that can be destroyed by owner. All funds in contract will be sent to the owner.
     */
    contract Destructible is Ownable {
    
      function Destructible() public payable { }
    
      /**
       * @dev Transfers the current balance to the owner and terminates the contract.
       */
      function destroy() onlyOwner public {
        selfdestruct(owner);
      }
    
      function destroyAndSend(address _recipient) onlyOwner public {
        selfdestruct(_recipient);
      }
    }
    
    /**
     * @title Pausable
     * @dev Base contract which allows children to implement an emergency stop mechanism.
     */
    contract Pausable is Ownable {
      event Pause();
      event Unpause();
    
      bool public paused = false;
    
    
      /**
       * @dev Modifier to make a function callable only when the contract is not paused.
       */
      modifier whenNotPaused() {
        require(!paused);
        _;
      }
    
      /**
       * @dev Modifier to make a function callable only when the contract is paused.
       */
      modifier whenPaused() {
        require(paused);
        _;
      }
    
      /**
       * @dev called by the owner to pause, triggers stopped state
       */
      function pause() onlyOwner whenNotPaused public {
        paused = true;
        Pause();
      }
    
      /**
       * @dev called by the owner to unpause, returns to normal state
       */
      function unpause() onlyOwner whenPaused public {
        paused = false;
        Unpause();
      }
    }
    
    /**
     * @title ERC20Basic
     * @dev Simpler version of ERC20 interface
     * @dev see https://github.com/ethereum/EIPs/issues/179
     */
    contract ERC20Basic {
      uint256 public totalSupply;
      function balanceOf(address who) public constant returns (uint256);
      function transfer(address to, uint256 value) public returns (bool);
      event Transfer(address indexed from, address indexed to, uint256 value);
    }
    
    /**
     * @title ERC20 interface
     * @dev see https://github.com/ethereum/EIPs/issues/20
     */
    contract ERC20 is ERC20Basic {
      function allowance(address owner, address spender) public constant returns (uint256);
      function transferFrom(address from, address to, uint256 value) public returns (bool);
      function approve(address spender, uint256 value) public returns (bool);
      event Approval(address indexed owner, address indexed spender, uint256 value);
    }
    
    /**
     * @title Basic token
     * @dev Basic version of StandardToken, with no allowances.
     */
    contract BasicToken is ERC20Basic {
      using SafeMath for uint256;
    
      mapping(address => uint256) balances;
    
      /**
      * @dev transfer token for a specified address
      * @param _to The address to transfer to.
      * @param _value The amount to be transferred.
      */
      function transfer(address _to, uint256 _value) public returns (bool) {
        require(_to != address(0));
    
        // SafeMath.sub will throw if there is not enough balance.
        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(_value);
        Transfer(msg.sender, _to, _value);
        return true;
      }
    
      /**
      * @dev Gets the balance of the specified address.
      * @param _owner The address to query the the balance of.
      * @return An uint256 representing the amount owned by the passed address.
      */
      function balanceOf(address _owner) public constant returns (uint256 balance) {
        return balances[_owner];
      }
    
    }
    
    /**
     * @title Standard ERC20 token
     *
     * @dev Implementation of the basic standard token.
     * @dev https://github.com/ethereum/EIPs/issues/20
     * @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
     */
    contract StandardToken is ERC20, BasicToken {
    
      mapping (address => mapping (address => uint256)) allowed;
    
    
      /**
       * @dev Transfer tokens from one address to another
       * @param _from address The address which you want to send tokens from
       * @param _to address The address which you want to transfer to
       * @param _value uint256 the amount of tokens to be transferred
       */
      function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
        require(_to != address(0));
    
        uint256 _allowance = allowed[_from][msg.sender];
    
        // Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
        // require (_value <= _allowance);
    
        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(_value);
        allowed[_from][msg.sender] = _allowance.sub(_value);
        Transfer(_from, _to, _value);
        return true;
      }
    
      /**
       * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
       *
       * Beware that changing an allowance with this method brings the risk that someone may use both the old
       * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
       * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
       * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
       * @param _spender The address which will spend the funds.
       * @param _value The amount of tokens to be spent.
       */
      function approve(address _spender, uint256 _value) public returns (bool) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
      }
    
      /**
       * @dev Function to check the amount of tokens that an owner allowed to a spender.
       * @param _owner address The address which owns the funds.
       * @param _spender address The address which will spend the funds.
       * @return A uint256 specifying the amount of tokens still available for the spender.
       */
      function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
        return allowed[_owner][_spender];
      }
    
      /**
       * approve should be called when allowed[_spender] == 0. To increment
       * allowed value is better to use this function to avoid 2 calls (and wait until
       * the first transaction is mined)
       * From MonolithDAO Token.sol
       */
      function increaseApproval (address _spender, uint _addedValue) public
        returns (bool success) {
        allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
        Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
        return true;
      }
    
      function decreaseApproval (address _spender, uint _subtractedValue) public
        returns (bool success) {
        uint oldValue = allowed[msg.sender][_spender];
        if (_subtractedValue > oldValue) {
          allowed[msg.sender][_spender] = 0;
        } else {
          allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
        }
        Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
        return true;
      }
    
    }
    
    /**
     * @title Mintable token
     * @dev Simple ERC20 Token example, with mintable token creation
     * @dev 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, uint256 amount);
      event MintFinished();
    
      bool public mintingFinished = false;
    
    
      modifier canMint() {
        require(!mintingFinished);
        _;
      }
    
      /**
       * @dev Function to mint tokens
       * @param _to The address that will receive the minted tokens.
       * @param _amount The amount of tokens to mint.
       * @return A boolean that indicates if the operation was successful.
       */
      function mint(address _to, uint256 _amount) onlyOwner canMint public returns (bool) {
        totalSupply = totalSupply.add(_amount);
        balances[_to] = balances[_to].add(_amount);
        Mint(_to, _amount);
        Transfer(0x0, _to, _amount);
        return true;
      }
    
      /**
       * @dev Function to stop minting new tokens.
       * @return True if the operation was successful.
       */
      function finishMinting() onlyOwner public returns (bool) {
        mintingFinished = true;
        MintFinished();
        return true;
      }
    }
    
    /**
     * @title Pausable token
     *
     * @dev StandardToken modified with pausable transfers.
     **/
    
    contract PausableToken is StandardToken, Pausable {
    
      function transfer(address _to, uint256 _value) public whenNotPaused returns (bool) {
        return super.transfer(_to, _value);
      }
    
      function transferFrom(address _from, address _to, uint256 _value) public whenNotPaused returns (bool) {
        return super.transferFrom(_from, _to, _value);
      }
    
      function approve(address _spender, uint256 _value) public whenNotPaused returns (bool) {
        return super.approve(_spender, _value);
      }
    
      function increaseApproval(address _spender, uint _addedValue) public whenNotPaused returns (bool success) {
        return super.increaseApproval(_spender, _addedValue);
      }
    
      function decreaseApproval(address _spender, uint _subtractedValue) public whenNotPaused returns (bool success) {
        return super.decreaseApproval(_spender, _subtractedValue);
      }
    }
    
    /**
    * @dev Pre main Bitcalve CAT token ERC20 contract
    * Based on references from OpenZeppelin: https://github.com/OpenZeppelin/zeppelin-solidity
    */
    contract CAToken is MintableToken, PausableToken {
        
        // Metadata
        string public constant symbol = "CAT";
        string public constant name = "BitClave - Consumer Activity Token";
        uint8 public constant decimals = 18;
        string public constant version = "2.0";
    
        /**
        * @dev Override MintableTokenn.finishMinting() to add canMint modifier
        */
        function finishMinting() onlyOwner canMint public returns(bool) {
            return super.finishMinting();
        }
    
    }
    
    /**
    * @dev Main Bitcalve PreCAT token ERC20 contract
    * Based on references from OpenZeppelin: https://github.com/OpenZeppelin/zeppelin-solidity
    */
    contract PreCAToken is CAToken, Destructible {
    
        // Metadata
        string public constant symbol = "CAT";
        string public constant name = "BitClave - Consumer Activity Token";
        uint8 public constant decimals = 18;
        string public constant version = "1.1";
    
        // Overrided destructor
        function destroy() public onlyOwner {
            require(mintingFinished);
            super.destroy();
        }
    
        // Overrided destructor companion
        function destroyAndSend(address _recipient) public onlyOwner {
            require(mintingFinished);
            super.destroyAndSend(_recipient);
        }
    
    }