Mangled/streamlined makeConcept

Mangled/streamlined makeConcept

import "lib/random.sol";
import "userMaster.sol";
import "concept.sol";
import "assessment.sol";
import "user.sol";

/*
@type: contract
@name: ConceptMaster
@purpose: To create concepts and store some concept data
*/
contract ConceptMaster
{
  mapping (address => bool) public conceptExists; //Maps concept addresses to a bool to confirm their existance
  mapping (address => string) public names; //Maps the concept address to its name
  mapping (string => address) addresses; //Maps the concept name to its address
  address userMasterAddress; //The address of the userMaster contract
  bool locked = false; //Keeps track of whether or not the function to set the userMasterAddress variable is locked yet or not
  address randomAddress; //The address of the random contract
  address public mewAddress;

  /*
  @type: modifier
  @name: onlyThis
  @purpose: to only allow the this contract to call a function to which this modifier is applied
  */
  modifier onlyThis()
  {
    if(msg.sender != address(this)) //Checks if msg.sender is this contract
    {
      throw; //Throws out the function call if it isn't
    }
    _;
  }

  /*
  @type: event
  @name: ConceptCreation
  @occasion: When a concept is created
  @purpose: To help build a data store of concepts
  @stores: string _conceptName
  @stores: address _conceptAddress
  @stores: address[] _parents
  */
  event ConceptCreation (address _conceptAddress); //the address of the concept that was created

  /*
  @type: constructor function
  @purpose: To initialize the conceptMaster contract and have it make the random contract
  @returns: nothing
  */
  function ConceptMaster()
  {
  }

  function getAddress(string name) constant returns(address)
  {
    return addresses[name];
  }

  /*
  @type: function
  @purpose: To set the userMasterAddress
  @param: address userMaster = the address of the userMaster contract
  @returns: nothing
  */
  function init(address userMaster, address random, address mew)
  {
    if(locked == false) //Checks if the function has already been called
    {
      userMasterAddress = userMaster; //Sets the userMasterAddress to the value of userMaster
      randomAddress = random;
      mewAddress = mew;
      Concept(mewAddress).setMew(mewAddress);
      locked = true; //Makes it so this function cannot be called again
    }
  }

  /*
  @type: function
  @purpose: To make a concept
  @param: string name = the name of the concept to be made
  @param: address[] parentList = an array of addresses containing the addresses of the concepts parents
  @returns: nothing
  */
  function makeConcept(string name, address[] parentList) returns (bool)
  {
    if(addresses[name] == 0) //Checks if the name is not taken
    {
      Concept newConcept = new Concept(name, parentList, userMasterAddress, address(this), randomAddress); //Makes a new concept with the provided data
      newConcept.setMew(mewAddress);
      address newConceptAddress = address(newConcept); //initializes an address variable and sets it equal to the address of the newly created concept
      conceptExists[newConceptAddress] = true; //Maps the concept address to true to show that it exists
      names[newConceptAddress] = name;
      addresses[name] = newConceptAddress;
      if(parentList.length == 0)
      {
        Concept(mewAddress).addChild(newConceptAddress);
      }
      for(uint j=0; j < parentList.length; j++) //Iterates of the parents array in memory
      {
        Concept(parentList[j]).addChild(newConceptAddress); //Adds the newly created concept to each of the parents as a child
      }
      ConceptCreation(newConceptAddress); //Makes ConceptCreation event with provided data
      return true;
    }
    else
    {
      return false;
    }
  }
}

import "lib/random.sol";
import "userMaster.sol";
import "concept.sol";
import "assessment.sol";
import "user.sol";

/*
@type: contract
@name: ConceptMaster
@purpose: To create concepts and store some concept data
*/
contract ConceptMaster
{
  mapping (address => bool) public conceptExists; //Maps concept addresses to a bool to confirm their existance
  mapping (address => string) public names; //Maps the concept address to its name
  mapping (string => address) addresses; //Maps the concept name to its address
  address userMasterAddress; //The address of the userMaster contract
  bool locked = false; //Keeps track of whether or not the function to set the userMasterAddress variable is locked yet or not
  address randomAddress; //The address of the random contract
  address public mewAddress;

  /*
  @type: modifier
  @name: onlyThis
  @purpose: to only allow the this contract to call a function to which this modifier is applied
  */
  modifier onlyThis()
  {
    if(msg.sender != address(this)) //Checks if msg.sender is this contract
    {
      throw; //Throws out the function call if it isn't
    }
    _;
  }

  /*
  @type: event
  @name: ConceptCreation
  @occasion: When a concept is created
  @purpose: To help build a data store of concepts
  @stores: string _conceptName
  @stores: address _conceptAddress
  @stores: address[] _parents
  */
  event ConceptCreation
  ( uint _response, //the error code of the procedure
    string _conceptName, //the name of the concept that was created
    address _conceptAddress, //the address of the concept that was created
    address[] _parents); //the addresses of the parents of the concept that as created

  /*
  @type: constructor function
  @purpose: To initialize the conceptMaster contract and have it make the random contract
  @returns: nothing
  */
  function ConceptMaster()
  {
  }

  function getAddress(string name) constant returns(address)
  {
    return addresses[name];
  }

  /*
  @type: function
  @purpose: To set the userMasterAddress
  @param: address userMaster = the address of the userMaster contract
  @returns: nothing
  */
  function init(address userMaster, address random, address mew)
  {
    if(locked == false) //Checks if the function has already been called
    {
      userMasterAddress = userMaster; //Sets the userMasterAddress to the value of userMaster
      randomAddress = random;
      mewAddress = mew;
      Concept(mewAddress).setMew(mewAddress);
      locked = true; //Makes it so this function cannot be called again
    }
  }

  /*
  @type: function
  @purpose: To make a concept
  @param: string name = the name of the concept to be made
  @param: address[] parentList = an array of addresses containing the addresses of the concepts parents
  @returns: nothing
  */
  function makeConcept(string name, address[] parentList)
  {
    uint response = 0; //initializes the error code
    address[] memory parents = new address[] (parentList.length);
    for(uint i=0; i < parentList.length; i++) //iterates over the parentList
    {
      if(checkConcept(parentList[i])==false) //checks if the parents exist
      {
        response += (10**i); //modifies the error code to reflect any nonexistant parents
      }
      else
      {
        parents[i] = parentList[i]; //adds the parents that exist to the array in memory of parents
      }
    }
    if(response==0) //Checks if there were no errors so far
    {
      Concept newConcept = new Concept(name, parents, userMasterAddress, address(this), randomAddress); //Makes a new concept with the provided data
      newConcept.setMew(mewAddress);
      address newConceptAddress = address(newConcept); //initializes an address variable and sets it equal to the address of the newly created concept
      conceptExists[newConceptAddress] = true; //Maps the concept address to true to show that it exists
      names[newConceptAddress] = name;
      addresses[name] = newConceptAddress;
      if(parents.length == 0)
      {
        Concept(mewAddress).addChild(newConceptAddress);
      }
      for(uint j=0; j < parents.length; j++) //Iterates of the parents array in memory
      {
        Concept(parents[j]).addChild(newConceptAddress); //Adds the newly created concept to each of the parents as a child
      }
    }
    ConceptCreation(response, name, newConceptAddress, parents); //Makes ConceptCreation event with provided data
  }
}


adding folders

adding folders

pragma solidity ^0.4.0;

contract SFEscrow{

    address public owner;
    uint256 public totalBalance;

    // Helper to restrict invocation to owner
    modifier only_owner() {
        if (msg.sender == owner) {
            _;
        }
    }

    // Constructor
    function SFEscrow() {
        owner = msg.sender;
        totalBalance = 0;
    }

    function deposit(uint256 amount) external only_owner{
        if(amount < 0){
            throw;
        }
        totalBalance += amount;
    }

    function payout(address payee, uint256 amount) external only_owner{
        if(amount <= 0){
            throw;
        }
        payee.transfer(amount);
    }

}

error: pathspec 'SFEscrow.sol' did not match any file(s) known to git


creating proxy contract to execute call via ABI

creating proxy contract to execute call via ABI

//
// Exploring purpose original taken source from
//
// proxy.sol - execute actions atomically through the proxy's identity

// Copyright (C) 2017  DappHub, LLC

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

pragma solidity ^0.4.13;

import "ds-auth/auth.sol";
import "ds-note/note.sol";

// DSProxy
// Allows code execution using a persistant identity This can be very
// useful to execute a sequence of atomic actions. Since the owner of
// the proxy can be changed, this allows for dynamic ownership models
// i.e. a multisig
contract DSProxy is DSAuth, DSNote {
    DSProxyCache public cache;  // global cache for contracts

    function DSProxy(address _cacheAddr) public {
        require(setCache(_cacheAddr));
    }

    function() public payable {
    }

    // use the proxy to execute calldata _data on contract _code
    function execute(bytes _code, bytes _data)
        public
        payable
        returns (address target, bytes32 response)
    {
        target = cache.read(_code);
        if (target == 0x0) {
            // deploy contract & store its address in cache
            target = cache.write(_code);
        }

        response = execute(target, _data);
    }

    function execute(address _target, bytes _data)
        public
        auth
        note
        payable
        returns (bytes32 response)
    {
        require(_target != 0x0);

        // call contract in current context
        assembly {
            let succeeded := delegatecall(sub(gas, 5000), _target, add(_data, 0x20), mload(_data), 0, 32)
            response := mload(0)      // load delegatecall output
            switch iszero(succeeded)
            case 1 {
                // throw if delegatecall failed
                revert(0, 0)
            }
        }
    }

    //set new cache
    function setCache(address _cacheAddr)
        public
        auth
        note
        returns (bool)
    {
        require(_cacheAddr != 0x0);        // invalid cache address
        cache = DSProxyCache(_cacheAddr);  // overwrite cache
        return true;
    }
}

// DSProxyFactory
// This factory deploys new proxy instances through build()
// Deployed proxy addresses are logged
contract DSProxyFactory {
    event Created(address indexed sender, address proxy, address cache);
    mapping(address=>bool) public isProxy;
    DSProxyCache public cache = new DSProxyCache();

    // deploys a new proxy instance
    // sets owner of proxy to caller
    function build() public returns (DSProxy proxy) {
        proxy = build(msg.sender);
    }

    // deploys a new proxy instance
    // sets custom owner of proxy
    function build(address owner) public returns (DSProxy proxy) {
        proxy = new DSProxy(cache);
        Created(owner, address(proxy), address(cache));
        proxy.setOwner(owner);
        isProxy[proxy] = true;
    }
}

// DSProxyCache
// This global cache stores addresses of contracts previously deployed
// by a proxy. This saves gas from repeat deployment of the same
// contracts and eliminates blockchain bloat.

// By default, all proxies deployed from the same factory store
// contracts in the same cache. The cache a proxy instance uses can be
// changed.  The cache uses the sha3 hash of a contract's bytecode to
// lookup the address
contract DSProxyCache {
    mapping(bytes32 => address) cache;

    function read(bytes _code) public view returns (address) {
        bytes32 hash = keccak256(_code);
        return cache[hash];
    }

    function write(bytes _code) public returns (address target) {
        assembly {
            target := create(0, add(_code, 0x20), mload(_code))
            switch iszero(extcodesize(target))
            case 1 {
                // throw if contract failed to deploy
                revert(0, 0)
            }
        }
        bytes32 hash = keccak256(_code);
        cache[hash] = target;
    }
}

error: pathspec 'DSProxy.sol' did not match any file(s) known to git


Index shortId in event.

Index shortId in event.

pragma solidity ^0.5.9;

/**
 * @title ItemStoreShortId
 * @author Jonathan Brown <jbrown@mix-blockchain.org>
 * @dev Maintain bidirectional mapping between 32 byte itemIds and 4 byte shortIds.
 */
contract ItemStoreShortId {

    /**
     * @dev Mapping of itemId to shortId.
     */
    mapping (bytes32 => bytes4) itemIdShortId;

    /**
     * @dev Mapping of shortId to itemId.
     */
    mapping (bytes4 => bytes32) shortIdItemId;

    /**
     * @dev A new shortId has been created.
     * @param itemId itemId of the item.
     * @param shortId shortId of the item
     */
    event CreateShortId(bytes32 indexed itemId, bytes32 indexed shortId);

    /**
     * @dev Revert if the itemId already has a shortId.
     * @param itemId itemId of the item.
     */
    modifier noShortId(bytes32 itemId) {
        require (itemIdShortId[itemId] == 0, "itemId does not have a shortId.");
        _;
    }

    /**
     * @dev Create a 4 byte shortId for a 32 byte itemId.
     * @param itemId itemId of the item.
     * @return shortId New 4 byte shortId.
     */
    function createShortId(bytes32 itemId) external noShortId(itemId) returns (bytes4 shortId) {
        // Find a shortId that hasn't been used before.
        bytes32 hash = keccak256(abi.encodePacked(itemId));
        shortId = bytes4(hash);
        while (shortIdItemId[shortId] != 0) {
            hash = keccak256(abi.encodePacked(hash));
            shortId = bytes4(hash);
        }
        // Store the mappings.
        itemIdShortId[itemId] = shortId;
        shortIdItemId[shortId] = itemId;
        // Log the event.
        emit CreateShortId(itemId, shortId);
    }

    /**
     * @dev Get itemId for shortId.
     * @param shortId to get the itemId for.
     * @return The itemId.
     */
    function getItemId(bytes4 shortId) external view returns (bytes32) {
        return shortIdItemId[shortId];
    }

    /**
     * @dev Get shortId for itemId.
     * @param itemId to get the shortId for.
     * @return The shortId.
     */
    function getShortId(bytes32 itemId) external view returns (bytes4) {
        return itemIdShortId[itemId];
    }

}

pragma solidity ^0.5.9;

/**
 * @title ItemStoreShortId
 * @author Jonathan Brown <jbrown@mix-blockchain.org>
 * @dev Maintain bidirectional mapping between 32 byte itemIds and 4 byte shortIds.
 */
contract ItemStoreShortId {

    /**
     * @dev Mapping of itemId to shortId.
     */
    mapping (bytes32 => bytes4) itemIdShortId;

    /**
     * @dev Mapping of shortId to itemId.
     */
    mapping (bytes4 => bytes32) shortIdItemId;

    /**
     * @dev A new shortId has been created.
     * @param itemId itemId of the item.
     * @param shortId shortId of the item
     */
    event CreateShortId(bytes32 indexed itemId, bytes32 shortId);

    /**
     * @dev Revert if the itemId already has a shortId.
     * @param itemId itemId of the item.
     */
    modifier noShortId(bytes32 itemId) {
        require (itemIdShortId[itemId] == 0, "itemId does not have a shortId.");
        _;
    }

    /**
     * @dev Create a 4 byte shortId for a 32 byte itemId.
     * @param itemId itemId of the item.
     * @return shortId New 4 byte shortId.
     */
    function createShortId(bytes32 itemId) external noShortId(itemId) returns (bytes4 shortId) {
        // Find a shortId that hasn't been used before.
        bytes32 hash = keccak256(abi.encodePacked(itemId));
        shortId = bytes4(hash);
        while (shortIdItemId[shortId] != 0) {
            hash = keccak256(abi.encodePacked(hash));
            shortId = bytes4(hash);
        }
        // Store the mappings.
        itemIdShortId[itemId] = shortId;
        shortIdItemId[shortId] = itemId;
        // Log the event.
        emit CreateShortId(itemId, shortId);
    }

    /**
     * @dev Get itemId for shortId.
     * @param shortId to get the itemId for.
     * @return The itemId.
     */
    function getItemId(bytes4 shortId) external view returns (bytes32) {
        return shortIdItemId[shortId];
    }

    /**
     * @dev Get shortId for itemId.
     * @param itemId to get the shortId for.
     * @return The shortId.
     */
    function getShortId(bytes32 itemId) external view returns (bytes4) {
        return itemIdShortId[itemId];
    }

}


Restore payable modifier in deposit() Solidity method.

pragma solidity ^0.4.24;

import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/ECRecovery.sol";

/// @title Unidirectional Ether payment channels contract.
contract Unidirectional {
    using SafeMath for uint256;

    struct PaymentChannel {
        address sender;
        address receiver;
        uint256 value; // Total amount of money deposited to the channel.

        uint256 settlingPeriod; // How many blocks to wait for the receiver to claim her funds, after sender starts settling.
        uint256 settlingUntil; // Starting with this block number, anyone can settle the channel.
    }

    mapping (bytes32 => PaymentChannel) public channels;

    event DidOpen(bytes32 indexed channelId, address indexed sender, address indexed receiver, uint256 value);
    event DidDeposit(bytes32 indexed channelId, uint256 deposit);
    event DidClaim(bytes32 indexed channelId);
    event DidStartSettling(bytes32 indexed channelId);
    event DidSettle(bytes32 indexed channelId);

    /*** ACTIONS AND CONSTRAINTS ***/

    /// @notice Open a new channel between `msg.sender` and `receiver`, and do an initial deposit to the channel.
    /// @param channelId Unique identifier of the channel to be created.
    /// @param receiver Receiver of the funds, counter-party of `msg.sender`.
    /// @param settlingPeriod Number of blocks to wait for receiver to `claim` her funds after the sender starts settling period (see `startSettling`).
    /// After that period is over anyone could call `settle`, and move all the channel funds to the sender.
    function open(bytes32 channelId, address receiver, uint256 settlingPeriod) public payable {
        require(isAbsent(channelId));

        channels[channelId] = PaymentChannel({
            sender: msg.sender,
            receiver: receiver,
            value: msg.value,
            settlingPeriod: settlingPeriod,
            settlingUntil: 0
            });

        emit DidOpen(channelId, msg.sender, receiver, msg.value);
    }

    /// @notice Ensure `origin` address can deposit money into the channel identified by `channelId`.
    /// @dev Constraint `deposit` call.
    /// @param channelId Identifier of the channel.
    /// @param origin Caller of `deposit` function.
    function canDeposit(bytes32 channelId, address origin) public view returns(bool) {
        PaymentChannel memory channel = channels[channelId];
        bool isSender = channel.sender == origin;
        return isOpen(channelId) && isSender;
    }

    /// @notice Add more money to the contract.
    /// @param channelId Identifier of the channel.
    function deposit(bytes32 channelId) public payable {
        require(canDeposit(channelId, msg.sender));

        channels[channelId].value += msg.value;

        emit DidDeposit(channelId, msg.value);
    }

    /// @notice Ensure `origin` address can start settling the channel identified by `channelId`.
    /// @dev Constraint `startSettling` call.
    /// @param channelId Identifier of the channel.
    /// @param origin Caller of `startSettling` function.
    function canStartSettling(bytes32 channelId, address origin) public view returns(bool) {
        PaymentChannel memory channel = channels[channelId];
        bool isSender = channel.sender == origin;
        return isOpen(channelId) && isSender;
    }

    /// @notice Sender initiates settling of the contract.
    /// @dev Actually set `settlingUntil` field of the PaymentChannel structure.
    /// @param channelId Identifier of the channel.
    function startSettling(bytes32 channelId) public {
        require(canStartSettling(channelId, msg.sender));

        PaymentChannel storage channel = channels[channelId];
        channel.settlingUntil = block.number + channel.settlingPeriod;

        emit DidStartSettling(channelId);
    }

    /// @notice Ensure one can settle the channel identified by `channelId`.
    /// @dev Check if settling period is over by comparing `settlingUntil` to a current block number.
    /// @param channelId Identifier of the channel.
    function canSettle(bytes32 channelId) public view returns(bool) {
        PaymentChannel memory channel = channels[channelId];
        bool isWaitingOver = isSettling(channelId) && block.number >= channel.settlingUntil;
        return isSettling(channelId) && isWaitingOver;
    }

    /// @notice Move the money to sender, and close the channel.
    /// After the settling period is over, and receiver has not claimed the funds, anyone could call that.
    /// @param channelId Identifier of the channel.
    function settle(bytes32 channelId) public {
        require(canSettle(channelId));
        PaymentChannel storage channel = channels[channelId];
        channel.sender.transfer(channel.value);

        delete channels[channelId];
        emit DidSettle(channelId);
    }

    /// @notice Ensure `origin` address can claim `payment` amount on channel identified by `channelId`.
    /// @dev Check if `signature` is made by sender part of the channel, and is for payment promise (see `paymentDigest`).
    /// @param channelId Identifier of the channel.
    /// @param payment Amount claimed.
    /// @param origin Caller of `claim` function.
    /// @param signature Signature for the payment promise.
    function canClaim(bytes32 channelId, uint256 payment, address origin, bytes signature) public view returns(bool) {
        PaymentChannel memory channel = channels[channelId];
        bool isReceiver = origin == channel.receiver;
        bytes32 hash = recoveryPaymentDigest(channelId, payment);
        bool isSigned = channel.sender == ECRecovery.recover(hash, signature);

        return isReceiver && isSigned;
    }

    /// @notice Claim the funds, and close the channel.
    /// @dev Can be claimed by channel receiver only. Guarded by `canClaim`.
    /// @param channelId Identifier of the channel.
    /// @param payment Amount claimed.
    /// @param signature Signature for the payment promise.
    function claim(bytes32 channelId, uint256 payment, bytes signature) public {
        require(canClaim(channelId, payment, msg.sender, signature));

        PaymentChannel memory channel = channels[channelId];

        if (payment >= channel.value) {
            channel.receiver.transfer(channel.value);
        } else {
            channel.receiver.transfer(payment);
            channel.sender.transfer(channel.value.sub(payment));
        }

        delete channels[channelId];

        emit DidClaim(channelId);
    }

    /*** CHANNEL STATE ***/

    /// @notice Check if the channel is present: in open or settling state.
    /// @param channelId Identifier of the channel.
    function isPresent(bytes32 channelId) public view returns(bool) {
        return !isAbsent(channelId);
    }

    /// @notice Check if the channel is not present.
    /// @param channelId Identifier of the channel.
    function isAbsent(bytes32 channelId) public view returns(bool) {
        PaymentChannel memory channel = channels[channelId];
        return channel.sender == 0;
    }

    /// @notice Check if the channel is in settling state: waits till the settling period is over.
    /// @dev It is settling, if `settlingUntil` is set to non-zero.
    /// @param channelId Identifier of the channel.
    function isSettling(bytes32 channelId) public view returns(bool) {
        PaymentChannel memory channel = channels[channelId];
        return channel.settlingUntil != 0;
    }

    /// @notice Check if the channel is open: present and not settling.
    /// @param channelId Identifier of the channel.
    function isOpen(bytes32 channelId) public view returns(bool) {
        return isPresent(channelId) && !isSettling(channelId);
    }

    /*** PAYMENT DIGEST ***/

    /// @return Hash of the payment promise to sign.
    /// @param channelId Identifier of the channel.
    /// @param payment Amount to send, and to claim later.
    function paymentDigest(bytes32 channelId, uint256 payment) public view returns(bytes32) {
        return keccak256(abi.encodePacked(address(this), channelId, payment));
    }

    /// @return Actually signed hash of the payment promise, considering "Ethereum Signed Message" prefix.
    /// @param channelId Identifier of the channel.
    /// @param payment Amount to send, and to claim later.
    function recoveryPaymentDigest(bytes32 channelId, uint256 payment) internal view returns(bytes32) {
        bytes memory prefix = "\x19Ethereum Signed Message:\n32";
        return keccak256(abi.encodePacked(prefix, paymentDigest(channelId, payment)));
    }
}

pragma solidity ^0.4.24;

import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/ECRecovery.sol";

/// @title Unidirectional Ether payment channels contract.
contract Unidirectional {
    using SafeMath for uint256;

    struct PaymentChannel {
        address sender;
        address receiver;
        uint256 value; // Total amount of money deposited to the channel.

        uint256 settlingPeriod; // How many blocks to wait for the receiver to claim her funds, after sender starts settling.
        uint256 settlingUntil; // Starting with this block number, anyone can settle the channel.
    }

    mapping (bytes32 => PaymentChannel) public channels;

    event DidOpen(bytes32 indexed channelId, address indexed sender, address indexed receiver, uint256 value);
    event DidDeposit(bytes32 indexed channelId, uint256 deposit);
    event DidClaim(bytes32 indexed channelId);
    event DidStartSettling(bytes32 indexed channelId);
    event DidSettle(bytes32 indexed channelId);

    /*** ACTIONS AND CONSTRAINTS ***/

    /// @notice Open a new channel between `msg.sender` and `receiver`, and do an initial deposit to the channel.
    /// @param channelId Unique identifier of the channel to be created.
    /// @param receiver Receiver of the funds, counter-party of `msg.sender`.
    /// @param settlingPeriod Number of blocks to wait for receiver to `claim` her funds after the sender starts settling period (see `startSettling`).
    /// After that period is over anyone could call `settle`, and move all the channel funds to the sender.
    function open(bytes32 channelId, address receiver, uint256 settlingPeriod) public payable {
        require(isAbsent(channelId));

        channels[channelId] = PaymentChannel({
            sender: msg.sender,
            receiver: receiver,
            value: msg.value,
            settlingPeriod: settlingPeriod,
            settlingUntil: 0
            });

        emit DidOpen(channelId, msg.sender, receiver, msg.value);
    }

    /// @notice Ensure `origin` address can deposit money into the channel identified by `channelId`.
    /// @dev Constraint `deposit` call.
    /// @param channelId Identifier of the channel.
    /// @param origin Caller of `deposit` function.
    function canDeposit(bytes32 channelId, address origin) public view returns(bool) {
        PaymentChannel memory channel = channels[channelId];
        bool isSender = channel.sender == origin;
        return isOpen(channelId) && isSender;
    }

    /// @notice Add more money to the contract.
    /// @param channelId Identifier of the channel.
    function deposit(bytes32 channelId) public {
        require(canDeposit(channelId, msg.sender));

        channels[channelId].value += msg.value;

        emit DidDeposit(channelId, msg.value);
    }

    /// @notice Ensure `origin` address can start settling the channel identified by `channelId`.
    /// @dev Constraint `startSettling` call.
    /// @param channelId Identifier of the channel.
    /// @param origin Caller of `startSettling` function.
    function canStartSettling(bytes32 channelId, address origin) public view returns(bool) {
        PaymentChannel memory channel = channels[channelId];
        bool isSender = channel.sender == origin;
        return isOpen(channelId) && isSender;
    }

    /// @notice Sender initiates settling of the contract.
    /// @dev Actually set `settlingUntil` field of the PaymentChannel structure.
    /// @param channelId Identifier of the channel.
    function startSettling(bytes32 channelId) public {
        require(canStartSettling(channelId, msg.sender));

        PaymentChannel storage channel = channels[channelId];
        channel.settlingUntil = block.number + channel.settlingPeriod;

        emit DidStartSettling(channelId);
    }

    /// @notice Ensure one can settle the channel identified by `channelId`.
    /// @dev Check if settling period is over by comparing `settlingUntil` to a current block number.
    /// @param channelId Identifier of the channel.
    function canSettle(bytes32 channelId) public view returns(bool) {
        PaymentChannel memory channel = channels[channelId];
        bool isWaitingOver = isSettling(channelId) && block.number >= channel.settlingUntil;
        return isSettling(channelId) && isWaitingOver;
    }

    /// @notice Move the money to sender, and close the channel.
    /// After the settling period is over, and receiver has not claimed the funds, anyone could call that.
    /// @param channelId Identifier of the channel.
    function settle(bytes32 channelId) public {
        require(canSettle(channelId));
        PaymentChannel storage channel = channels[channelId];
        channel.sender.transfer(channel.value);

        delete channels[channelId];
        emit DidSettle(channelId);
    }

    /// @notice Ensure `origin` address can claim `payment` amount on channel identified by `channelId`.
    /// @dev Check if `signature` is made by sender part of the channel, and is for payment promise (see `paymentDigest`).
    /// @param channelId Identifier of the channel.
    /// @param payment Amount claimed.
    /// @param origin Caller of `claim` function.
    /// @param signature Signature for the payment promise.
    function canClaim(bytes32 channelId, uint256 payment, address origin, bytes signature) public view returns(bool) {
        PaymentChannel memory channel = channels[channelId];
        bool isReceiver = origin == channel.receiver;
        bytes32 hash = recoveryPaymentDigest(channelId, payment);
        bool isSigned = channel.sender == ECRecovery.recover(hash, signature);

        return isReceiver && isSigned;
    }

    /// @notice Claim the funds, and close the channel.
    /// @dev Can be claimed by channel receiver only. Guarded by `canClaim`.
    /// @param channelId Identifier of the channel.
    /// @param payment Amount claimed.
    /// @param signature Signature for the payment promise.
    function claim(bytes32 channelId, uint256 payment, bytes signature) public {
        require(canClaim(channelId, payment, msg.sender, signature));

        PaymentChannel memory channel = channels[channelId];

        if (payment >= channel.value) {
            channel.receiver.transfer(channel.value);
        } else {
            channel.receiver.transfer(payment);
            channel.sender.transfer(channel.value.sub(payment));
        }

        delete channels[channelId];

        emit DidClaim(channelId);
    }

    /*** CHANNEL STATE ***/

    /// @notice Check if the channel is present: in open or settling state.
    /// @param channelId Identifier of the channel.
    function isPresent(bytes32 channelId) public view returns(bool) {
        return !isAbsent(channelId);
    }

    /// @notice Check if the channel is not present.
    /// @param channelId Identifier of the channel.
    function isAbsent(bytes32 channelId) public view returns(bool) {
        PaymentChannel memory channel = channels[channelId];
        return channel.sender == 0;
    }

    /// @notice Check if the channel is in settling state: waits till the settling period is over.
    /// @dev It is settling, if `settlingUntil` is set to non-zero.
    /// @param channelId Identifier of the channel.
    function isSettling(bytes32 channelId) public view returns(bool) {
        PaymentChannel memory channel = channels[channelId];
        return channel.settlingUntil != 0;
    }

    /// @notice Check if the channel is open: present and not settling.
    /// @param channelId Identifier of the channel.
    function isOpen(bytes32 channelId) public view returns(bool) {
        return isPresent(channelId) && !isSettling(channelId);
    }

    /*** PAYMENT DIGEST ***/

    /// @return Hash of the payment promise to sign.
    /// @param channelId Identifier of the channel.
    /// @param payment Amount to send, and to claim later.
    function paymentDigest(bytes32 channelId, uint256 payment) public view returns(bytes32) {
        return keccak256(abi.encodePacked(address(this), channelId, payment));
    }

    /// @return Actually signed hash of the payment promise, considering "Ethereum Signed Message" prefix.
    /// @param channelId Identifier of the channel.
    /// @param payment Amount to send, and to claim later.
    function recoveryPaymentDigest(bytes32 channelId, uint256 payment) internal view returns(bytes32) {
        bytes memory prefix = "\x19Ethereum Signed Message:\n32";
        return keccak256(abi.encodePacked(prefix, paymentDigest(channelId, payment)));
    }
}


[#5] Add cancelTransaction()

[#5] Add cancelTransaction()

/// Partnership
/// Requires all pre-defined partners agreement on transactions and operations.
contract Partnership
{
	event Funded();
	event Deposit(address _from, uint _value);
	event TransactionProposed(bytes32 _id, address _initiator, string _description);
	event TransactionCanceled(bytes32 _id, address _actor);
	event TransactionPassed(bytes32 _id, address _finalSigner, string _description);
	event TransactionSent(bytes32 _transaction, address _executor, string _description);
	event Withdrawal(address _partner, uint _amount);

	/// Price in wei of each equal share of the partnership
	uint public sharePrice;

	/// Flag indicating whether or not all partners have paid for their share
	bool public funded;

	/// Array of partner addresses
	address [] public partners;

	/// Collection of partner records
	mapping(address => Partner) public partnerRecords;

	/// Count of partners
	uint public partnerCount;

	/// Count of partners who have paid for their share
	uint public paidPartnerCount;

	/// Collection of pending transactions (ie send X ETH to Y with Z data)
	mapping(bytes32 => Transaction) public transactions;

	struct Partner {
		/// Flag indicating that this record has been initialized
		bool isPartner;
		/// Flag indicating that the partner has paid for their share
		bool paid;
		/// Total amount loaned to the partnership by the partner
		uint loanBalance;
		/// Amount released for withdrawal by the partner
		uint withdrawableAmount;
	}

	struct Transaction {
		/// Flag indicating that this record has been initialized
		bool valid;
		/// Proposed recipient for the transaction (0 indicates a new contract will be created)
		address to;
		/// Proposed amount to send (0 indicates no wei)
		uint value;
		/// Optional array of data to send with the transaction
		bytes data;
		/// Optional description of proposed transaction
		string description;
		/// Account that created the transaction
		address creator;
		/// Total number of partners that have confirmed/voted
		uint voteCount;
		/// Collection of partners that have confirmed/voted
		mapping(address => uint) votes;
		/// Flag indicating that all partners have confirmed
		bool passed;
		/// Flag indicatint that the transaction has been sent
		bool sent;
	}

	modifier onlyFunded {
		if (!funded)
	       		throw;
		_
	}

	modifier onlyPartner {
		if (!isPartner(msg.sender))
			throw;
		_
	}

	modifier onlyDao {
		if (msg.sender != address(this))
			throw;
		_
	}

	function Partnership(address[] _partners, uint _sharePrice) {
		funded = false;
		partners = _partners;
		sharePrice = _sharePrice;
		for (uint i = 0; i < _partners.length; i++) {
			partnerRecords[_partners[i]].isPartner = true;
		}
		partnerCount = _partners.length;
		paidPartnerCount = 0;
	}

	/// This executes when funds are sent to the contract
	function() {
		if (msg.value > 0) {
			if (funded) {
				if (isPartner(msg.sender)) {
					partnerRecords[msg.sender].loanBalance += msg.value;
				}
			}
			else {
				if (isPartner(msg.sender)) {
					if (partnerRecords[msg.sender].paid) {
						throw;
					}
					else {
						if (msg.value == sharePrice) {
							partnerRecords[msg.sender].paid = true;
							paidPartnerCount = paidPartnerCount + 1;
							if (paidPartnerCount == partnerCount) {
								funded = true;
								Funded();
							}
						}
						else {
							throw;
						}
					}
				}
				else {
					throw;
				}
			}
			Deposit(msg.sender, msg.value);
		}
	}

	/// Adds a proposed transaction to be confirmed by other partners
	function proposeTransaction(address _to, uint _value, bytes _data, string _description) onlyFunded onlyPartner external returns (bytes32) {

		// generate hash for easy specification in confirm and execute
		bytes32 id = sha3(msg.data, block.number);

		// grab the presumably blank transaction
		var transaction = transactions[id];

		transaction.valid = true;
		transaction.to = _to;
		transaction.value = _value;
		transaction.data = _data;
		transaction.description = _description;
		transaction.creator = msg.sender;
		transaction.voteCount = 1;
		transaction.votes[msg.sender] = 1;
		transaction.passed = false;
		transaction.sent = false;

		TransactionProposed(id, msg.sender, _description);

		return id;
	}

	/// Cancels a transaction that has not yet passed
	function cancelTransaction(bytes32 _id) onlyFunded onlyPartner external {

		var transaction = transactions[_id];

		// ensure this is a transaction we've set up
		if (!transaction.valid)
			throw;

		// ensure this transaction hasn't passed
		if (transaction.passed)
			throw;

		// only the creator can cancel
		if (transaction.creator != msg.sender)
			throw;

		delete transactions[_id];

		TransactionCanceled(_id, msg.sender);
	}

	/// Confirms an existing proposed transaction
	function confirmTransaction(bytes32 _id) onlyFunded onlyPartner external {

		var transaction = transactions[_id];

		// ensure this is a transaction we've set up
		if (!transaction.valid)
			throw;

		// ignore second confirmation
		if (transaction.votes[msg.sender] == 1)
			throw;

		// register the vote
		transaction.voteCount += 1;
		transaction.votes[msg.sender] = 1;

		if (transaction.voteCount == partnerCount) {
			transaction.passed = true;
			TransactionPassed(_id, msg.sender, transaction.description);
		}
	}

	/// Executes a passed transaction
	function executeTransaction(bytes32 _id) onlyFunded onlyPartner external {

		var transaction = transactions[_id];

		// ignore transactions that have not passed yet
		if (!transaction.passed)
			throw;

		// ignore transactions that have already been sent
		if (transaction.sent)
			throw;

		// register the sent transaction
		transaction.sent = true;

		// send the transaction
		if (transactions[_id].to.call.value(transactions[_id].value)(transactions[_id].data)) {

			TransactionSent(_id, msg.sender, transaction.description);

			// clear the transaction structure to free memory
			delete transactions[_id];
		}
		else {
			// roll back if the call failed
			transaction.sent = false;
		}
	}

	/// Distribute ETH to a partner
	function distribute(address _partner, uint _amount) onlyDao external {

		// ignore invalid partners
		if (!isPartner(_partner))
			throw;

		partnerRecords[_partner].withdrawableAmount += _amount;
	}

	/// Distribute ETH evenly amongst all partners
	function distributeEvenly(uint _amount) onlyDao external {

		var payout = _amount / partnerCount;

		for (uint i = 0; i < partnerCount; i++) {
			partnerRecords[partners[i]].withdrawableAmount += payout;
		}
	}

	/// Mark down partner's loan and make it available for withdrawal
	function repayLoan(address _partner, uint _amount) onlyDao external {

		// ignore invalid partners
		if (!partnerRecords[_partner].isPartner)
			throw;

		// ignore invalid amounts
		if (_amount > partnerRecords[_partner].loanBalance)
			throw;

		partnerRecords[_partner].loanBalance -= _amount;
		partnerRecords[_partner].withdrawableAmount += _amount;
	}

	/// Allow partner to withdraw funds marked as withdrawable
	function withdraw(uint _amount) onlyFunded onlyPartner external {

		// ignore requests for more than the amount allowed
		if (_amount > partnerRecords[msg.sender].withdrawableAmount)
			throw;

		// ignore requests for more than the available balance
		if (_amount > this.balance)
			throw;

		// mark the withdrawal as successful
		partnerRecords[msg.sender].withdrawableAmount -= _amount;

		// send the wei
		if (msg.sender.send(_amount)) {
			Withdrawal(msg.sender, _amount);
		}
		else {
			// roll back if the send failed
			partnerRecords[msg.sender].withdrawableAmount += _amount;
		}
	}

	/// Dissolve DAO and send the remaining ETH to a beneficiary
	function dissolve(address _beneficiary) onlyDao external {

		// ignore unset beneficiary
		if (_beneficiary == 0)
			throw;

		// prevent lost balance
		if (_beneficiary == address(this))
		    throw;

		suicide(_beneficiary);
	}

	function isPartner(address _address) internal returns (bool) {
		return partnerRecords[_address].isPartner;
	}

}

/// Partnership
/// Requires all pre-defined partners agreement on transactions and operations.
contract Partnership
{
	event Funded();
	event Deposit(address _from, uint _value);
	event TransactionProposed(bytes32 _id, address _initiator, string _description);
	event TransactionPassed(bytes32 _id, address _finalSigner, string _description);
	event TransactionSent(bytes32 _transaction, address _executor, string _description);
	event Withdrawal(address _partner, uint _amount);

	/// Price in wei of each equal share of the partnership
	uint public sharePrice;

	/// Flag indicating whether or not all partners have paid for their share
	bool public funded;

	/// Array of partner addresses
	address [] public partners;

	/// Collection of partner records
	mapping(address => Partner) public partnerRecords;

	/// Count of partners
	uint public partnerCount;

	/// Count of partners who have paid for their share
	uint public paidPartnerCount;

	/// Collection of pending transactions (ie send X ETH to Y with Z data)
	mapping(bytes32 => Transaction) public transactions;

	struct Partner {
		/// Flag indicating that this record has been initialized
		bool isPartner;
		/// Flag indicating that the partner has paid for their share
		bool paid;
		/// Total amount loaned to the partnership by the partner
		uint loanBalance;
		/// Amount released for withdrawal by the partner
		uint withdrawableAmount;
	}

	struct Transaction {
		/// Flag indicating that this record has been initialized
		bool valid;
		/// Proposed recipient for the transaction (0 indicates a new contract will be created)
		address to;
		/// Proposed amount to send (0 indicates no wei)
		uint value;
		/// Optional array of data to send with the transaction
		bytes data;
		/// Optional description of proposed transaction
		string description;
		/// Account that created the transaction
		address creator;
		/// Total number of partners that have confirmed/voted
		uint voteCount;
		/// Collection of partners that have confirmed/voted
		mapping(address => uint) votes;
		/// Flag indicating that all partners have confirmed
		bool passed;
		/// Flag indicatint that the transaction has been sent
		bool sent;
	}

	modifier onlyFunded {
		if (!funded)
	       		throw;
		_
	}

	modifier onlyPartner {
		if (!isPartner(msg.sender))
			throw;
		_
	}

	modifier onlyDao {
		if (msg.sender != address(this))
			throw;
		_
	}

	function Partnership(address[] _partners, uint _sharePrice) {
		funded = false;
		partners = _partners;
		sharePrice = _sharePrice;
		for (uint i = 0; i < _partners.length; i++) {
			partnerRecords[_partners[i]].isPartner = true;
		}
		partnerCount = _partners.length;
		paidPartnerCount = 0;
	}

	/// This executes when funds are sent to the contract
	function() {
		if (msg.value > 0) {
			if (funded) {
				if (isPartner(msg.sender)) {
					partnerRecords[msg.sender].loanBalance += msg.value;
				}
			}
			else {
				if (isPartner(msg.sender)) {
					if (partnerRecords[msg.sender].paid) {
						throw;
					}
					else {
						if (msg.value == sharePrice) {
							partnerRecords[msg.sender].paid = true;
							paidPartnerCount = paidPartnerCount + 1;
							if (paidPartnerCount == partnerCount) {
								funded = true;
								Funded();
							}
						}
						else {
							throw;
						}
					}
				}
				else {
					throw;
				}
			}
			Deposit(msg.sender, msg.value);
		}
	}

	/// Adds a proposed transaction to be confirmed by other partners
	function proposeTransaction(address _to, uint _value, bytes _data, string _description) onlyFunded onlyPartner external returns (bytes32) {

		// generate hash for easy specification in confirm and execute
		bytes32 id = sha3(msg.data, block.number);

		// grab the presumably blank transaction
		var transaction = transactions[id];

		transaction.valid = true;
		transaction.to = _to;
		transaction.value = _value;
		transaction.data = _data;
		transaction.description = _description;
		transaction.creator = msg.sender;
		transaction.voteCount = 1;
		transaction.votes[msg.sender] = 1;
		transaction.passed = false;
		transaction.sent = false;

		TransactionProposed(id, msg.sender, _description);

		return id;
	}

	/// Confirms an existing proposed transaction
	function confirmTransaction(bytes32 _id) onlyFunded onlyPartner external {

		var transaction = transactions[_id];

		// ensure this is a transaction we've set up
		if (!transaction.valid)
			throw;

		// ignore second confirmation
		if (transaction.votes[msg.sender] == 1)
			throw;

		// register the vote
		transaction.voteCount += 1;
		transaction.votes[msg.sender] = 1;

		if (transaction.voteCount == partnerCount) {
			transaction.passed = true;
			TransactionPassed(_id, msg.sender, transaction.description);
		}
	}

	/// Executes a passed transaction
	function executeTransaction(bytes32 _id) onlyFunded onlyPartner external {

		var transaction = transactions[_id];

		// ignore transactions that have not passed yet
		if (!transaction.passed)
			throw;

		// ignore transactions that have already been sent
		if (transaction.sent)
			throw;

		// register the sent transaction
		transaction.sent = true;

		// send the transaction
		if (transactions[_id].to.call.value(transactions[_id].value)(transactions[_id].data)) {

			TransactionSent(_id, msg.sender, transaction.description);

			// clear the transaction structure to free memory
			delete transactions[_id];
		}
		else {
			// roll back if the call failed
			transaction.sent = false;
		}
	}

	/// Distribute ETH to a partner
	function distribute(address _partner, uint _amount) onlyDao external {

		// ignore invalid partners
		if (!isPartner(_partner))
			throw;

		partnerRecords[_partner].withdrawableAmount += _amount;
	}

	/// Distribute ETH evenly amongst all partners
	function distributeEvenly(uint _amount) onlyDao external {

		var payout = _amount / partnerCount;

		for (uint i = 0; i < partnerCount; i++) {
			partnerRecords[partners[i]].withdrawableAmount += payout;
		}
	}

	/// Mark down partner's loan and make it available for withdrawal
	function repayLoan(address _partner, uint _amount) onlyDao external {

		// ignore invalid partners
		if (!partnerRecords[_partner].isPartner)
			throw;

		// ignore invalid amounts
		if (_amount > partnerRecords[_partner].loanBalance)
			throw;

		partnerRecords[_partner].loanBalance -= _amount;
		partnerRecords[_partner].withdrawableAmount += _amount;
	}

	/// Allow partner to withdraw funds marked as withdrawable
	function withdraw(uint _amount) onlyFunded onlyPartner external {

		// ignore requests for more than the amount allowed
		if (_amount > partnerRecords[msg.sender].withdrawableAmount)
			throw;

		// ignore requests for more than the available balance
		if (_amount > this.balance)
			throw;

		// mark the withdrawal as successful
		partnerRecords[msg.sender].withdrawableAmount -= _amount;

		// send the wei
		if (msg.sender.send(_amount)) {
			Withdrawal(msg.sender, _amount);
		}
		else {
			// roll back if the send failed
			partnerRecords[msg.sender].withdrawableAmount += _amount;
		}
	}

	/// Dissolve DAO and send the remaining ETH to a beneficiary
	function dissolve(address _beneficiary) onlyDao external {

		// ignore unset beneficiary
		if (_beneficiary == 0)
			throw;

		// prevent lost balance
		if (_beneficiary == address(this))
		    throw;

		suicide(_beneficiary);
	}

	function isPartner(address _address) internal returns (bool) {
		return partnerRecords[_address].isPartner;
	}

}


pre-ICO hard cap 3500

pre-ICO hard cap 3500

pragma solidity 0.4.15;

import './STQToken.sol';
import './crowdsale/InvestmentAnalytics.sol';
import 'zeppelin-solidity/contracts/ReentrancyGuard.sol';
import 'zeppelin-solidity/contracts/math/SafeMath.sol';
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';

/// @title Storiqa pre-ICO contract
contract STQPreICO is Ownable, ReentrancyGuard, InvestmentAnalytics {
    using SafeMath for uint256;

    event FundTransfer(address backer, uint amount, bool isContribution);

    function STQPreICO(address token, address funds) {
        require(address(0) != address(token) && address(0) != address(funds));

        m_token = STQToken(token);
        m_funds = funds;
    }

    // PUBLIC interface: payments

    // fallback function as a shortcut
    function() payable {
        require(0 == msg.data.length);
        buy();  // only internal call here!
    }

    /// @notice ICO participation
    function buy() public payable {     // dont mark as external!
        iaOnInvested(msg.sender, msg.value, false);
    }

    // PUBLIC interface: maintenance

    function createMorePaymentChannels(uint limit) external onlyOwner returns (uint) {
        return createMorePaymentChannelsInternal(limit);
    }

    /// @notice Tests ownership of the current caller.
    /// @return true if it's an owner
    // It's advisable to call it by new owner to make sure that the same erroneous address is not copy-pasted to
    // addOwner/changeOwner and to isOwner.
    function amIOwner() external constant onlyOwner returns (bool) {
        return true;
    }

    // INTERNAL

    /// @dev payment callback
    function iaOnInvested(address investor, uint payment, bool usingPaymentChannel)
        internal
        nonReentrant
    {
        require(payment >= c_MinInvestment);
        require(getCurrentTime() >= c_startTime && getCurrentTime() < c_endTime || msg.sender == owner);

        uint startingInvariant = this.balance.add(m_funds.balance);

        // return or update payment if needed
        uint paymentAllowed = getMaximumFunds().sub(m_totalInvested);
        if (0 == paymentAllowed) {
            investor.transfer(payment);
            return;
        }
        uint change;
        if (paymentAllowed < payment) {
            change = payment.sub(paymentAllowed);
            payment = paymentAllowed;
        }

        // calculate rate
        uint bonusPercent = c_preICOBonusPercent;
        bonusPercent += getLargePaymentBonus(payment);
        if (usingPaymentChannel)
            bonusPercent += c_paymentChannelBonusPercent;

        uint rate = c_STQperETH.mul(100 + bonusPercent).div(100);

        // issue tokens
        uint stq = payment.mul(rate);
        m_token.mint(investor, stq);

        // record payment
        m_funds.transfer(payment);
        m_totalInvested = m_totalInvested.add(payment);
        assert(m_totalInvested <= getMaximumFunds());
        FundTransfer(investor, payment, true);

        if (change > 0)
            investor.transfer(change);

        assert(startingInvariant == this.balance.add(m_funds.balance).add(change));
    }

    function getLargePaymentBonus(uint payment) private constant returns (uint) {
        if (payment > 1000 ether) return 10;
        if (payment > 800 ether) return 8;
        if (payment > 500 ether) return 5;
        if (payment > 200 ether) return 2;
        return 0;
    }

    /// @dev to be overridden in tests
    function getCurrentTime() internal constant returns (uint) {
        return now;
    }

    /// @dev to be overridden in tests
    function getMaximumFunds() internal constant returns (uint) {
        return c_MaximumFunds;
    }

    // FIELDS

    /// @notice start time of the pre-ICO
    uint public constant c_startTime = 1507766400;

    /// @notice end time of the pre-ICO
    uint public constant c_endTime = c_startTime + (1 days);

    /// @notice minimum investment
    uint public constant c_MinInvestment = 10 finney;

    /// @notice maximum investments to be accepted during pre-ICO
    uint public constant c_MaximumFunds = 3500 ether;

    /// @notice starting exchange rate of STQ
    uint public constant c_STQperETH = 100000;

    /// @notice pre-ICO bonus
    uint public constant c_preICOBonusPercent = 40;

    /// @notice authorised payment bonus
    uint public constant c_paymentChannelBonusPercent = 2;

    /// @dev total investments amount
    uint public m_totalInvested;

    /// @dev contract responsible for token accounting
    STQToken public m_token;

    /// @dev address responsible for investments accounting
    address public m_funds;
}

pragma solidity 0.4.15;

import './STQToken.sol';
import './crowdsale/InvestmentAnalytics.sol';
import 'zeppelin-solidity/contracts/ReentrancyGuard.sol';
import 'zeppelin-solidity/contracts/math/SafeMath.sol';
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';

/// @title Storiqa pre-ICO contract
contract STQPreICO is Ownable, ReentrancyGuard, InvestmentAnalytics {
    using SafeMath for uint256;

    event FundTransfer(address backer, uint amount, bool isContribution);

    function STQPreICO(address token, address funds) {
        require(address(0) != address(token) && address(0) != address(funds));

        m_token = STQToken(token);
        m_funds = funds;
    }

    // PUBLIC interface: payments

    // fallback function as a shortcut
    function() payable {
        require(0 == msg.data.length);
        buy();  // only internal call here!
    }

    /// @notice ICO participation
    function buy() public payable {     // dont mark as external!
        iaOnInvested(msg.sender, msg.value, false);
    }

    // PUBLIC interface: maintenance

    function createMorePaymentChannels(uint limit) external onlyOwner returns (uint) {
        return createMorePaymentChannelsInternal(limit);
    }

    /// @notice Tests ownership of the current caller.
    /// @return true if it's an owner
    // It's advisable to call it by new owner to make sure that the same erroneous address is not copy-pasted to
    // addOwner/changeOwner and to isOwner.
    function amIOwner() external constant onlyOwner returns (bool) {
        return true;
    }

    // INTERNAL

    /// @dev payment callback
    function iaOnInvested(address investor, uint payment, bool usingPaymentChannel)
        internal
        nonReentrant
    {
        require(payment >= c_MinInvestment);
        require(getCurrentTime() >= c_startTime && getCurrentTime() < c_endTime || msg.sender == owner);

        uint startingInvariant = this.balance.add(m_funds.balance);

        // return or update payment if needed
        uint paymentAllowed = getMaximumFunds().sub(m_totalInvested);
        if (0 == paymentAllowed) {
            investor.transfer(payment);
            return;
        }
        uint change;
        if (paymentAllowed < payment) {
            change = payment.sub(paymentAllowed);
            payment = paymentAllowed;
        }

        // calculate rate
        uint bonusPercent = c_preICOBonusPercent;
        bonusPercent += getLargePaymentBonus(payment);
        if (usingPaymentChannel)
            bonusPercent += c_paymentChannelBonusPercent;

        uint rate = c_STQperETH.mul(100 + bonusPercent).div(100);

        // issue tokens
        uint stq = payment.mul(rate);
        m_token.mint(investor, stq);

        // record payment
        m_funds.transfer(payment);
        m_totalInvested = m_totalInvested.add(payment);
        assert(m_totalInvested <= getMaximumFunds());
        FundTransfer(investor, payment, true);

        if (change > 0)
            investor.transfer(change);

        assert(startingInvariant == this.balance.add(m_funds.balance).add(change));
    }

    function getLargePaymentBonus(uint payment) private constant returns (uint) {
        if (payment > 1000 ether) return 10;
        if (payment > 800 ether) return 8;
        if (payment > 500 ether) return 5;
        if (payment > 200 ether) return 2;
        return 0;
    }

    /// @dev to be overridden in tests
    function getCurrentTime() internal constant returns (uint) {
        return now;
    }

    /// @dev to be overridden in tests
    function getMaximumFunds() internal constant returns (uint) {
        return c_MaximumFunds;
    }

    // FIELDS

    /// @notice start time of the pre-ICO
    uint public constant c_startTime = 1507766400;

    /// @notice end time of the pre-ICO
    uint public constant c_endTime = c_startTime + (1 days);

    /// @notice minimum investment
    uint public constant c_MinInvestment = 10 finney;

    /// @notice maximum investments to be accepted during pre-ICO
    uint public constant c_MaximumFunds = 8000 ether;

    /// @notice starting exchange rate of STQ
    uint public constant c_STQperETH = 100000;

    /// @notice pre-ICO bonus
    uint public constant c_preICOBonusPercent = 40;

    /// @notice authorised payment bonus
    uint public constant c_paymentChannelBonusPercent = 2;

    /// @dev total investments amount
    uint public m_totalInvested;

    /// @dev contract responsible for token accounting
    STQToken public m_token;

    /// @dev address responsible for investments accounting
    address public m_funds;
}


stoppable polish

stoppable polish

/*
 * Stoppable
 * Abstract contract that allows children to implement an
 * emergency stop mechanism.
 */
contract Stoppable {
  address public curator;
  bool public stopped;

  modifier stopInEmergency { if (!stopped) _ }
  modifier onlyInEmergency { if (stopped) _ }

  function Stoppable(address _curator) {
    if (_curator == 0) {
      throw;
    }
    curator = _curator;
  }

  function emergencyStop() external {
    if (msg.sender != curator) {
      throw;
    }
    stopped = true;
  }

}

/*
 * Stoppable
 */
contract Stoppable {
  address public curator;
  bool public stopped;

  modifier stopInEmergency { if (!stopped) _ }
  modifier onlyInEmergency { if (stopped) _ }

  function Stoppable(address _curator) {
		if (_curator == 0) {
      throw;
    }
    curator = _curator;
  }

  function emergencyStop() external {
    if (msg.sender != curator) {
      throw;
    }
    stopped = true;
  }

}