Update RefundVault.sol

Update RefundVault.sol

pragma solidity ^0.4.11;

import '../math/SafeMath.sol';
import '../ownership/Ownable.sol';

/**
 * @title RefundVault
 * @dev This contract is used for storing funds while a crowdsale
 * is in progress. Supports refunding the money if crowdsale fails,
 * and forwarding it if crowdsale is successful.
 */
contract RefundVault is Ownable {
  using SafeMath for uint256;

  enum State { Active, Refunding, Closed }

  mapping (address => uint256) public deposited;
  address public wallet;
  State public state;

  event Closed();
  event RefundsEnabled();
  event Refunded(address indexed beneficiary, uint256 weiAmount);

  function RefundVault(address _wallet) {
    require(_wallet != address(0));
    wallet = _wallet;
    state = State.Active;
  }

  function deposit(address investor) onlyOwner public payable {
    require(state == State.Active);
    deposited[investor] = deposited[investor].add(msg.value);
  }

  function close() onlyOwner public {
    require(state == State.Active);
    state = State.Closed;
    Closed();
    wallet.transfer(this.balance);
  }

  function enableRefunds() onlyOwner public {
    require(state == State.Active);
    state = State.Refunding;
    RefundsEnabled();
  }

  function refund(address investor) public {
    require(state == State.Refunding);
    uint256 depositedValue = deposited[investor];
    deposited[investor] = 0;
    investor.transfer(depositedValue);
    Refunded(investor, depositedValue);
  }
}

pragma solidity ^0.4.11;

import '../math/SafeMath.sol';
import '../ownership/Ownable.sol';

/**
 * @title RefundVault
 * @dev This contract is used for storing funds while a crowdsale
 * is in progress. Supports refunding the money if crowdsale fails,
 * and forwarding it if crowdsale is successful.
 */
contract RefundVault is Ownable {
  using SafeMath for uint256;

  enum State { Active, Refunding, Closed }

  mapping (address => uint256) public deposited;
  address public wallet;
  State public state;

  event Closed();
  event RefundsEnabled();
  event Refunded(address indexed beneficiary, uint256 weiAmount);

  function RefundVault(address _wallet) {
    require(_wallet != 0x0);
    wallet = _wallet;
    state = State.Active;
  }

  function deposit(address investor) onlyOwner public payable {
    require(state == State.Active);
    deposited[investor] = deposited[investor].add(msg.value);
  }

  function close() onlyOwner public {
    require(state == State.Active);
    state = State.Closed;
    Closed();
    wallet.transfer(this.balance);
  }

  function enableRefunds() onlyOwner public {
    require(state == State.Active);
    state = State.Refunding;
    RefundsEnabled();
  }

  function refund(address investor) public {
    require(state == State.Refunding);
    uint256 depositedValue = deposited[investor];
    deposited[investor] = 0;
    investor.transfer(depositedValue);
    Refunded(investor, depositedValue);
  }
}


ICO: added possibility for final test

ICO: added possibility for final test

pragma solidity 0.4.15;

import './ownership/multiowned.sol';
import './crowdsale/FixedTimeBonuses.sol';
import './crowdsale/FundsRegistry.sol';
import './crowdsale/InvestmentAnalytics.sol';
import './security/ArgumentsChecker.sol';
import './STQToken.sol';
import 'zeppelin-solidity/contracts/ReentrancyGuard.sol';
import 'zeppelin-solidity/contracts/math/Math.sol';
import 'zeppelin-solidity/contracts/math/SafeMath.sol';

/// @title Storiqa ICO contract
contract STQCrowdsale is ArgumentsChecker, ReentrancyGuard, multiowned, InvestmentAnalytics {
    using Math for uint256;
    using SafeMath for uint256;
    using FixedTimeBonuses for FixedTimeBonuses.Data;

    enum IcoState { INIT, ICO, PAUSED, FAILED, SUCCEEDED }

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

    modifier requiresState(IcoState _state) {
        require(m_state == _state);
        _;
    }

    /// @dev triggers some state changes based on current time
    /// note: function body could be skipped!
    modifier timedStateChange() {
        if (IcoState.INIT == m_state && getCurrentTime() >= getStartTime())
            changeState(IcoState.ICO);

        if (IcoState.ICO == m_state && getCurrentTime() > getEndTime()) {
            finishICO();

            if (msg.value > 0)
                msg.sender.transfer(msg.value);
            // note that execution of further (but not preceding!) modifiers and functions ends here
        } else {
            _;
        }
    }

    /// @dev automatic check for unaccounted withdrawals
    modifier fundsChecker() {
        assert(m_state == IcoState.ICO);

        uint atTheBeginning = m_funds.balance;
        if (atTheBeginning < m_lastFundsAmount) {
            changeState(IcoState.PAUSED);
            if (msg.value > 0)
                msg.sender.transfer(msg.value); // we cant throw (have to save state), so refunding this way
            // note that execution of further (but not preceding!) modifiers and functions ends here
        } else {
            _;

            if (m_funds.balance < atTheBeginning) {
                changeState(IcoState.PAUSED);
            } else {
                m_lastFundsAmount = m_funds.balance;
            }
        }
    }

    // PUBLIC interface

    function STQCrowdsale(address[] _owners, address _token, address _funds)
        multiowned(_owners, 2)
        validAddress(_token)
        validAddress(_funds)
    {
        require(3 == _owners.length);

        m_token = STQToken(_token);
        m_funds = FundsRegistry(_funds);

        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (1 weeks), bonus: 30}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (2 weeks), bonus: 25}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (3 weeks), bonus: 20}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (4 weeks), bonus: 15}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (5 weeks), bonus: 10}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (8 weeks), bonus: 5}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: 1514246400, bonus: 0}));
        m_bonuses.validate(true);
    }

    // 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);
    }

    function iaOnInvested(address investor, uint payment, bool usingPaymentChannel)
        internal
        nonReentrant
        timedStateChange
        fundsChecker
    {
        require(m_state == IcoState.ICO || m_state == IcoState.INIT && isOwner(investor) /* for final test */);

        require(payment >= c_MinInvestment);

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

        // checking for max cap
        uint fundsAllowed = getMaximumFunds().sub(getTotalInvested());
        assert(0 != fundsAllowed);  // in this case state must not be IcoState.ICO
        payment = fundsAllowed.min256(payment);
        uint256 change = msg.value.sub(payment);

        // issue tokens
        uint stq = calcSTQAmount(payment, usingPaymentChannel ? c_paymentChannelBonusPercent : 0);
        m_token.mint(investor, stq);

        // record payment
        m_funds.invested.value(payment)(investor);
        FundTransfer(investor, payment, true);

        // check if ICO must be closed early
        if (change > 0)
        {
            assert(getMaximumFunds() == getTotalInvested());
            finishICO();

            // send change
            investor.transfer(change);
            assert(startingInvariant == this.balance.add(m_funds.balance).add(change));
        }
        else
            assert(startingInvariant == this.balance.add(m_funds.balance));
    }

    // PUBLIC interface: owners: maintenance

    /// @notice pauses ICO
    function pause()
        external
        timedStateChange
        requiresState(IcoState.ICO)
        onlyowner
    {
        changeState(IcoState.PAUSED);
    }

    /// @notice resume paused ICO
    function unpause()
        external
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        changeState(IcoState.ICO);
        checkTime();
    }

    /// @notice consider paused ICO as failed
    function fail()
        external
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        changeState(IcoState.FAILED);
    }

    /// @notice In case we need to attach to existent token
    function setToken(address _token)
        external
        validAddress(_token)
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        m_token = STQToken(_token);
    }

    /// @notice In case we need to attach to existent funds
    function setFundsRegistry(address _funds)
        external
        validAddress(_funds)
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        m_funds = FundsRegistry(_funds);
    }

    /// @notice explicit trigger for timed state changes
    function checkTime()
        public
        timedStateChange
        onlyowner
    {
    }

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

    // INTERNAL functions

    function finishICO() private {
        if (getTotalInvested() < getMinFunds())
            changeState(IcoState.FAILED);
        else
            changeState(IcoState.SUCCEEDED);
    }

    /// @dev performs only allowed state transitions
    function changeState(IcoState _newState) private {
        assert(m_state != _newState);

        if (IcoState.INIT == m_state) {        assert(IcoState.ICO == _newState); }
        else if (IcoState.ICO == m_state) {    assert(IcoState.PAUSED == _newState || IcoState.FAILED == _newState || IcoState.SUCCEEDED == _newState); }
        else if (IcoState.PAUSED == m_state) { assert(IcoState.ICO == _newState || IcoState.FAILED == _newState); }
        else assert(false);

        m_state = _newState;
        StateChanged(m_state);

        // this should be tightly linked
        if (IcoState.SUCCEEDED == m_state) {
            onSuccess();
        } else if (IcoState.FAILED == m_state) {
            onFailure();
        }
    }

    function onSuccess() private {
        // mint tokens for owners
        uint tokensPerOwner = m_token.totalSupply().mul(4).div(m_numOwners);
        for (uint i = 0; i < m_numOwners; i++)
            m_token.mint(getOwner(i), tokensPerOwner);

        m_funds.changeState(FundsRegistry.State.SUCCEEDED);
        m_funds.detachController();

        m_token.disableMinting();
        m_token.startCirculation();
        m_token.detachController();
    }

    function onFailure() private {
        m_funds.changeState(FundsRegistry.State.REFUNDING);
        m_funds.detachController();
    }

    function getLargePaymentBonus(uint payment) private constant returns (uint) {
        if (payment > 5000 ether) return 20;
        if (payment > 3000 ether) return 15;
        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 calculates amount of STQ to which payer of _wei is entitled
    function calcSTQAmount(uint _wei, uint extraBonus) private constant returns (uint) {
        uint stq = _wei.mul(c_STQperETH);

        uint bonus = extraBonus.add(m_bonuses.getBonus(getCurrentTime())).add(getLargePaymentBonus(_wei));

        // apply bonus
        stq = stq.mul(bonus.add(100)).div(100);

        return stq;
    }

    /// @dev start time of the ICO, inclusive
    function getStartTime() private constant returns (uint) {
        return c_startTime;
    }

    /// @dev end time of the ICO, inclusive
    function getEndTime() private constant returns (uint) {
        return m_bonuses.getLastTime();
    }

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

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

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

    /// @dev amount of investments during all crowdsales
    function getTotalInvested() internal constant returns (uint) {
        return m_funds.totalInvested().add(2468 ether /* FIXME update me */);
    }

    // FIELDS

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

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

    /// @notice minimum investments to consider ICO as a success
    uint public constant c_MinFunds = 30000 ether;

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

    /// @notice start time of the ICO
    uint public constant c_startTime = 1508889600;

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

    /// @notice timed bonuses
    FixedTimeBonuses.Data m_bonuses;

    /// @dev state of the ICO
    IcoState public m_state = IcoState.INIT;

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

    /// @dev contract responsible for investments accounting
    FundsRegistry public m_funds;

    /// @dev last recorded funds
    uint256 public m_lastFundsAmount;
}

pragma solidity 0.4.15;

import './ownership/multiowned.sol';
import './crowdsale/FixedTimeBonuses.sol';
import './crowdsale/FundsRegistry.sol';
import './crowdsale/InvestmentAnalytics.sol';
import './security/ArgumentsChecker.sol';
import './STQToken.sol';
import 'zeppelin-solidity/contracts/ReentrancyGuard.sol';
import 'zeppelin-solidity/contracts/math/Math.sol';
import 'zeppelin-solidity/contracts/math/SafeMath.sol';

/// @title Storiqa ICO contract
contract STQCrowdsale is ArgumentsChecker, ReentrancyGuard, multiowned, InvestmentAnalytics {
    using Math for uint256;
    using SafeMath for uint256;
    using FixedTimeBonuses for FixedTimeBonuses.Data;

    enum IcoState { INIT, ICO, PAUSED, FAILED, SUCCEEDED }

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

    modifier requiresState(IcoState _state) {
        require(m_state == _state);
        _;
    }

    /// @dev triggers some state changes based on current time
    /// note: function body could be skipped!
    modifier timedStateChange() {
        if (IcoState.INIT == m_state && getCurrentTime() >= getStartTime())
            changeState(IcoState.ICO);

        if (IcoState.ICO == m_state && getCurrentTime() > getEndTime()) {
            finishICO();

            if (msg.value > 0)
                msg.sender.transfer(msg.value);
            // note that execution of further (but not preceding!) modifiers and functions ends here
        } else {
            _;
        }
    }

    /// @dev automatic check for unaccounted withdrawals
    modifier fundsChecker() {
        assert(m_state == IcoState.ICO);

        uint atTheBeginning = m_funds.balance;
        if (atTheBeginning < m_lastFundsAmount) {
            changeState(IcoState.PAUSED);
            if (msg.value > 0)
                msg.sender.transfer(msg.value); // we cant throw (have to save state), so refunding this way
            // note that execution of further (but not preceding!) modifiers and functions ends here
        } else {
            _;

            if (m_funds.balance < atTheBeginning) {
                changeState(IcoState.PAUSED);
            } else {
                m_lastFundsAmount = m_funds.balance;
            }
        }
    }

    // PUBLIC interface

    function STQCrowdsale(address[] _owners, address _token, address _funds)
        multiowned(_owners, 2)
        validAddress(_token)
        validAddress(_funds)
    {
        require(3 == _owners.length);

        m_token = STQToken(_token);
        m_funds = FundsRegistry(_funds);

        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (1 weeks), bonus: 30}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (2 weeks), bonus: 25}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (3 weeks), bonus: 20}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (4 weeks), bonus: 15}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (5 weeks), bonus: 10}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: c_startTime + (8 weeks), bonus: 5}));
        m_bonuses.bonuses.push(FixedTimeBonuses.Bonus({endTime: 1514246400, bonus: 0}));
        m_bonuses.validate(true);
    }

    // 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);
    }

    function iaOnInvested(address investor, uint payment, bool usingPaymentChannel)
        internal
        nonReentrant
        timedStateChange
        requiresState(IcoState.ICO)
        fundsChecker
    {
        require(payment >= c_MinInvestment);

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

        // checking for max cap
        uint fundsAllowed = getMaximumFunds().sub(getTotalInvested());
        assert(0 != fundsAllowed);  // in this case state must not be IcoState.ICO
        payment = fundsAllowed.min256(payment);
        uint256 change = msg.value.sub(payment);

        // issue tokens
        uint stq = calcSTQAmount(payment, usingPaymentChannel ? c_paymentChannelBonusPercent : 0);
        m_token.mint(investor, stq);

        // record payment
        m_funds.invested.value(payment)(investor);
        FundTransfer(investor, payment, true);

        // check if ICO must be closed early
        if (change > 0)
        {
            assert(getMaximumFunds() == getTotalInvested());
            finishICO();

            // send change
            investor.transfer(change);
            assert(startingInvariant == this.balance.add(m_funds.balance).add(change));
        }
        else
            assert(startingInvariant == this.balance.add(m_funds.balance));
    }

    // PUBLIC interface: owners: maintenance

    /// @notice pauses ICO
    function pause()
        external
        timedStateChange
        requiresState(IcoState.ICO)
        onlyowner
    {
        changeState(IcoState.PAUSED);
    }

    /// @notice resume paused ICO
    function unpause()
        external
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        changeState(IcoState.ICO);
        checkTime();
    }

    /// @notice consider paused ICO as failed
    function fail()
        external
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        changeState(IcoState.FAILED);
    }

    /// @notice In case we need to attach to existent token
    function setToken(address _token)
        external
        validAddress(_token)
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        m_token = STQToken(_token);
    }

    /// @notice In case we need to attach to existent funds
    function setFundsRegistry(address _funds)
        external
        validAddress(_funds)
        timedStateChange
        requiresState(IcoState.PAUSED)
        onlymanyowners(sha3(msg.data))
    {
        m_funds = FundsRegistry(_funds);
    }

    /// @notice explicit trigger for timed state changes
    function checkTime()
        public
        timedStateChange
        onlyowner
    {
    }

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

    // INTERNAL functions

    function finishICO() private {
        if (getTotalInvested() < getMinFunds())
            changeState(IcoState.FAILED);
        else
            changeState(IcoState.SUCCEEDED);
    }

    /// @dev performs only allowed state transitions
    function changeState(IcoState _newState) private {
        assert(m_state != _newState);

        if (IcoState.INIT == m_state) {        assert(IcoState.ICO == _newState); }
        else if (IcoState.ICO == m_state) {    assert(IcoState.PAUSED == _newState || IcoState.FAILED == _newState || IcoState.SUCCEEDED == _newState); }
        else if (IcoState.PAUSED == m_state) { assert(IcoState.ICO == _newState || IcoState.FAILED == _newState); }
        else assert(false);

        m_state = _newState;
        StateChanged(m_state);

        // this should be tightly linked
        if (IcoState.SUCCEEDED == m_state) {
            onSuccess();
        } else if (IcoState.FAILED == m_state) {
            onFailure();
        }
    }

    function onSuccess() private {
        // mint tokens for owners
        uint tokensPerOwner = m_token.totalSupply().mul(4).div(m_numOwners);
        for (uint i = 0; i < m_numOwners; i++)
            m_token.mint(getOwner(i), tokensPerOwner);

        m_funds.changeState(FundsRegistry.State.SUCCEEDED);
        m_funds.detachController();

        m_token.disableMinting();
        m_token.startCirculation();
        m_token.detachController();
    }

    function onFailure() private {
        m_funds.changeState(FundsRegistry.State.REFUNDING);
        m_funds.detachController();
    }

    function getLargePaymentBonus(uint payment) private constant returns (uint) {
        if (payment > 5000 ether) return 20;
        if (payment > 3000 ether) return 15;
        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 calculates amount of STQ to which payer of _wei is entitled
    function calcSTQAmount(uint _wei, uint extraBonus) private constant returns (uint) {
        uint stq = _wei.mul(c_STQperETH);

        uint bonus = extraBonus.add(m_bonuses.getBonus(getCurrentTime())).add(getLargePaymentBonus(_wei));

        // apply bonus
        stq = stq.mul(bonus.add(100)).div(100);

        return stq;
    }

    /// @dev start time of the ICO, inclusive
    function getStartTime() private constant returns (uint) {
        return c_startTime;
    }

    /// @dev end time of the ICO, inclusive
    function getEndTime() private constant returns (uint) {
        return m_bonuses.getLastTime();
    }

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

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

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

    /// @dev amount of investments during all crowdsales
    function getTotalInvested() internal constant returns (uint) {
        return m_funds.totalInvested().add(2468 ether /* FIXME update me */);
    }

    // FIELDS

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

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

    /// @notice minimum investments to consider ICO as a success
    uint public constant c_MinFunds = 30000 ether;

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

    /// @notice start time of the ICO
    uint public constant c_startTime = 1508889600;

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

    /// @notice timed bonuses
    FixedTimeBonuses.Data m_bonuses;

    /// @dev state of the ICO
    IcoState public m_state = IcoState.INIT;

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

    /// @dev contract responsible for investments accounting
    FundsRegistry public m_funds;

    /// @dev last recorded funds
    uint256 public m_lastFundsAmount;
}


remove extraneous else and returns

remove extraneous else and returns

pragma solidity ^0.4.11;

import "./Concept.sol";
import "./ConceptRegistry.sol";

/*
@type: contract
@name: UserRegistry
@purpose: To store data about users for easy, secure access and manage token balances
*/
contract UserRegistry {
    address public conceptRegistry;
    mapping (address => uint) public balances;
    mapping (address => mapping (address => uint)) public allowed;
    event Notification(address user, address sender, uint topic);
    /*
      0 = You've started an assessment
      1 = Called As A Potential Assessor
      2 = Confirmed for assessing, stake has been taken
      3 = Assessment Cancelled and you have been refunded
      4 = Assessment Has Started
      5 = All have commited; Reveal score
      6 = All have revealed; Tokens paid out
      7 = Assessment Finished
    */

    modifier onlyConcept() {
        require(ConceptRegistry(conceptRegistry).conceptExists(msg.sender));
        _;
    }

    function UserRegistry(address _conceptRegistry, address _user, uint _initialBalance) {
        conceptRegistry = _conceptRegistry;
        balances[_user] = _initialBalance;
    }

    function notification(address user, uint topic) {
        Notification(user, msg.sender, topic);
    }

    //@purpose: To perform payouts in Asessments
    function addBalance(address _to, uint _amount) onlyConcept() returns(bool) {
        if (balances[_to] + _amount > balances[_to]){
            balances[_to] += _amount;
            return true;
        }
    }

    //@purpose: To perform payments and staking for assessments
    function subtractBalance(address _from, uint _amount) onlyConcept() returns(bool) {
        if (balances[_from] > _amount){
            balances[_from] -= _amount;
            return true;
        }
    }

    function transfer(address _to, uint _amount) returns(bool) {
        if (balances[msg.sender] > _amount &&
           balances[_to] + _amount > balances[_to]) {
            balances[msg.sender] -= _amount;
            balances[_to] += _amount;
            return true;
        }
    }

    //@purpose: approve an address to transfer tokens on a users behalf
    function approve(address _spender, uint _amount) {
        allowed[msg.sender][_spender] = _amount;
    }

    //@purpose: transfer tokens from an account
    function transferFrom(address _from, address _to, uint _amount) returns(bool) {
        if (allowed[_from][msg.sender] > _amount &&
           balances[_from] > _amount &&
           balances[_to] > balances[_to] + _amount) {
            balances[_from] -= _amount;
            balances[_to] += _amount;
            allowed[_from][msg.sender] -= _amount;
            return true;
        }
    }
}

pragma solidity ^0.4.11;

import "./Concept.sol";
import "./ConceptRegistry.sol";

/*
@type: contract
@name: UserRegistry
@purpose: To store data about users for easy, secure access and manage token balances
*/
contract UserRegistry {
    address public conceptRegistry;
    mapping (address => uint) public balances;
    mapping (address => mapping (address => uint)) public allowed;
    event Notification(address user, address sender, uint topic);
    /*
      0 = You've started an assessment
      1 = Called As A Potential Assessor
      2 = Confirmed for assessing, stake has been taken
      3 = Assessment Cancelled and you have been refunded
      4 = Assessment Has Started
      5 = All have commited; Reveal score
      6 = All have revealed; Tokens paid out
      7 = Assessment Finished
    */

    modifier onlyConcept() {
        require(ConceptRegistry(conceptRegistry).conceptExists(msg.sender));
        _;
    }

    function UserRegistry(address _conceptRegistry, address _user, uint _initialBalance) {
        conceptRegistry = _conceptRegistry;
        balances[_user] = _initialBalance;
    }

    function notification(address user, uint topic) {
        Notification(user, msg.sender, topic);
    }

    //@purpose: To perform payouts in Asessments
    function addBalance(address _to, uint _amount) onlyConcept() returns(bool) {
        if (balances[_to] + _amount > balances[_to]){
            balances[_to] += _amount;
            return true;
        }
        else {
            return false;
        }
    }

    //@purpose: To perform payments and staking for assessments
    function subtractBalance(address _from, uint _amount) onlyConcept() returns(bool) {
        if (balances[_from] > _amount){
            balances[_from] -= _amount;
            return true;
        }
        return false;
    }

    function transfer(address _to, uint _amount) returns(bool) {
        if (balances[msg.sender] > _amount &&
           balances[_to] + _amount > balances[_to]) {
            balances[msg.sender] -= _amount;
            balances[_to] += _amount;
            return true;
        }
        else {
            return false;
        }
    }

    //@purpose: approve an address to transfer tokens on a users behalf
    function approve(address _spender, uint _amount) returns(bool) {
        allowed[msg.sender][_spender] = _amount;
        return true;
    }

    //@purpose: transfer tokens from an account
    function transferFrom(address _from, address _to, uint _amount) returns(bool) {
        if (allowed[_from][msg.sender] > _amount &&
           balances[_from] > _amount &&
           balances[_to] > balances[_to] + _amount) {
            balances[_from] -= _amount;
            balances[_to] += _amount;
            allowed[_from][msg.sender] -= _amount;
            return true;
        }
        else {
            return false;
        }
    }
}


fix contract

fix contract

contract GovContracts {

	struct Contract {
		uint128		id;
		bytes		termsHash;
		bool		projectDone
	};

	struct Milestone {
		uint128 	id;
		uint128 	contractId;
		uint128 	duration;
		uint128		targetBudget
	};

}


added comment

added comment

pragma solidity ^0.4.15;
import './SmartTokenController.sol';
import './Utils.sol';
import './Managed.sol';
import './Pausable.sol';
import './SmartToken.sol';
import './interfaces/ISmartToken.sol';

/*
    Crowdsale v0.1

    The crowdsale version of the smart token controller, allows contributing ether in exchange for Rootcoin tokens
    The price remains fixed for the entire duration of the crowdsale
    Note that 20% of the contributions are for the Bancor token's reserve
    Presale contributes are allocated (manually) with additional 20% tokens from the beneficiary tokens.
*/
contract CrowdsaleController is SmartTokenController, Managed, Pausable {
    string public version = "0.1";

    uint256 public constant PRESALE_DURATION = 14 days;                 // pressale duration
    uint256 public constant PRESALE_MIN_CONTRIBUTION = 200 ether;     // pressale min contribution
    uint256 public constant MIN_CONTRIBUTION = 0.01 ether;      // general sale min contribution
    uint256 public constant DURATION = 14 days;                 // crowdsale duration
    uint256 public constant TOKEN_PRICE_N = 1;                  // initial price in wei (numerator)
    uint256 public constant TOKEN_PRICE_D = 1000;                // initial price in wei (denominator) (1 wei equals 1000 token "wei")
    uint256 public constant MAX_GAS_PRICE = 50000000000 wei;    // maximum gas price for contribution transactions
    uint256 public constant MAX_CONTRIBUTION = 40 ether;    // maximum ether allowed to contribute by an unauthorized single account

    string public constant TOKEN_NAME = "Rootcoin"; //Token name
    string public constant TOKEN_SYM = "RCT";       //Token symbol
    uint8 public constant TOKEN_DEC = 18;           //Token decimals

    uint256 public startTime = 0;                   // crowdsale start time (in seconds)
    uint256 public endTime = 0;                     // crowdsale end time (in seconds)
    uint256 public totalEtherCap = 1000000 ether;   // current ether contribution cap
    uint256 public totalEtherContributed = 0;       // ether contributed so far
    address public beneficiary = 0x0;               // address to receive all ether contributions

    mapping(address => bool) public whiteList;  //whitelist of accounts that can participate in presale and also contribute more than MAX_CONTRIBUTION

    // triggered on each contribution
    event Contribution(address indexed _contributor, uint256 _amount, uint256 _return);

    /**
        @dev constructor
        @param _startTime      crowdsale start time
        @param _beneficiary    address to receive all ether contributions
    */
    function CrowdsaleController(uint256 _startTime, address _beneficiary)
        SmartTokenController(new SmartToken(TOKEN_NAME, TOKEN_SYM, TOKEN_DEC))
        validAddress(_beneficiary)
        earlierThan(_startTime)
    {
        startTime = _startTime;
        endTime = startTime + DURATION;
        beneficiary = _beneficiary;
        token.disableTransfers(true);
    }

    // verifies that the gas price is lower than 50 gwei
    modifier validGasPrice() {
        assert(tx.gasprice <= MAX_GAS_PRICE);
        _;
    }

    // ensures that it's earlier than the given time
    modifier earlierThan(uint256 _time) {
        assert(now < _time);
        _;
    }

    // ensures that the current time is between _startTime (inclusive) and _endTime (exclusive)
    modifier between(uint256 _startTime, uint256 _endTime) {
        assert(now >= _startTime && now < _endTime);
        _;
    }

    // ensures that we didn't reach the ether cap
    modifier etherCapNotReached(uint256 _contribution) {
        assert(safeAdd(totalEtherContributed, _contribution) <= totalEtherCap);
        _;
    }

    // verifies that the contribution is more than general minimum
    modifier validateMinPrice() {
        require(msg.value >= MIN_CONTRIBUTION);
        _;
    }

    // verifies that the presale contribution is more than presale minimum
    modifier validatePresaleMinPrice() {
        require(msg.value >= PRESALE_MIN_CONTRIBUTION);
        _;
    }

    // verifies that the presale contribution is from predefined address - TBD (not in use unless we decide to make a whitelist.)
    modifier validatePresaleAddress() {
         require(whiteList[msg.sender] == true);
        _;
    }

    // verifies that the total contributions from contributing account do not reach max alloewed unless it is on the whitelist.
    modifier maxAccountContributionNotReached() {
        assert(safeAdd(msg.value, safeMul(token.balanceOf(msg.sender), TOKEN_PRICE_N) / TOKEN_PRICE_D) <= MAX_CONTRIBUTION || whiteList[msg.sender]==true);
        _;
    }

    /**
        @dev computes the number of tokens that should be issued for a given contribution

        @param _contribution    contribution amount

        @return computed number of tokens
    */
    function computeReturn(uint256 _contribution) public constant returns (uint256) {
        // return safeMul(_contribution, TOKEN_PRICE_D) / TOKEN_PRICE_N;
        return safeMul(_contribution, TOKEN_PRICE_D);
    }

    /**
        @dev adds a whitelist address for which there is no max contribution and is alloewed to participate in the presale.

        @param _address    verified contributor address

        @return true
    */
    function addToWhitelist(address _address)
    public
    managerOnly
    returns (bool added)
    {
        whiteList[_address] = true;
        return true;
    }

    /**
        @dev removes a whitelist address for which there is no max contribution and is alloewed to participate in the presale.

        @param _address    verified contributor address to be removed

        @return true
    */
    function removeFromWhitelist(address _address)
    public
    managerOnly
    returns (bool added)
    {
        whiteList[_address] = false;
        return true;
    }

    /**
        @dev ETH contribution
        can only be called during the crowdsale

        @return tokens issued in return
    */
    function contributeETH()
        public
        payable
        between(startTime, endTime)
        whenNotPaused
        validateMinPrice
        maxAccountContributionNotReached
        returns (uint256 amount)
    {
        return processContribution();
    }

     /**
        @dev handles contribution during presale (min 200 ether)
        can only be called 14 days before the crowdsale start date

        @return tokens issued in return
    */
    function contributePreSale()
        public
        payable
        between(safeSub(startTime,PRESALE_DURATION), startTime)
        whenNotPaused
        validatePresaleMinPrice
        validatePresaleAddress
        returns (uint256 amount)
    {
        return processContribution();
    }

     /**
        @dev handles contribution with Fiat - for
        can only be called by manager

        @return tokens issued in return
    */
    function contributeFiat(address _contributor, uint256 _amount)
        public
        payable
        managerOnly
        between(safeSub(startTime,PRESALE_DURATION), safeAdd(startTime, DURATION))
        whenNotPaused
        returns (uint256 amount)
    {
        uint256 tokenAmount = computeReturn(_amount);

        totalEtherContributed = safeAdd(totalEtherContributed, _amount); // update the total contribution amount
        token.issue(_contributor, tokenAmount); // issue new funds to the contributor's address, provided by the manager, in the smart token
        token.issue(beneficiary, tokenAmount); // issue tokens to the beneficiary

        Contribution(_contributor, msg.value, tokenAmount);
        return tokenAmount;
    }

    /**
        @dev handles contribution logic
        note that the Contribution event is triggered using the sender as the contributor, regardless of the actual contributor

        @return tokens issued in return
    */
    function processContribution() private
        active
        etherCapNotReached(msg.value)
        validGasPrice
        returns (uint256 amount)
    {
        uint256 tokenAmount = computeReturn(msg.value);
        assert(beneficiary.send(msg.value)); // transfer the ether to the beneficiary account
        totalEtherContributed = safeAdd(totalEtherContributed, msg.value); // update the total contribution amount
        token.issue(msg.sender, tokenAmount); // issue new funds to the contributor in the smart token
        token.issue(beneficiary, tokenAmount); // issue tokens to the beneficiary

        Contribution(msg.sender, msg.value, tokenAmount);
        return tokenAmount;
    }

    // fallback
    function() payable {
        contributeETH();
    }
}

pragma solidity ^0.4.15;
import './SmartTokenController.sol';
import './Utils.sol';
import './Managed.sol';
import './Pausable.sol';
import './SmartToken.sol';
import './interfaces/ISmartToken.sol';

/*
    Crowdsale v0.1

    The crowdsale version of the smart token controller, allows contributing ether in exchange for Rootcoin tokens
    The price remains fixed for the entire duration of the crowdsale
    Note that 20% of the contributions are for the Bancor token's reserve
    Presale contributes are allocated (manually) with additional 20% tokens from the beneficiary tokens.
*/
contract CrowdsaleController is SmartTokenController, Managed, Pausable {
    string public version = "0.1";

    uint256 public constant PRESALE_DURATION = 14 days;                 // pressale duration
    uint256 public constant PRESALE_MIN_CONTRIBUTION = 200 ether;     // pressale min contribution
    uint256 public constant MIN_CONTRIBUTION = 0.01 ether;      // general sale min contribution
    uint256 public constant DURATION = 14 days;                 // crowdsale duration
    uint256 public constant TOKEN_PRICE_N = 1;                  // initial price in wei (numerator)
    uint256 public constant TOKEN_PRICE_D = 1000;                // initial price in wei (denominator)
    uint256 public constant MAX_GAS_PRICE = 50000000000 wei;    // maximum gas price for contribution transactions
    uint256 public constant MAX_CONTRIBUTION = 40 ether;    // maximum ether allowed to contribute by an unauthorized single account

    string public constant TOKEN_NAME = "Rootcoin"; //Token name
    string public constant TOKEN_SYM = "RCT";       //Token symbol
    uint8 public constant TOKEN_DEC = 18;           //Token decimals

    uint256 public startTime = 0;                   // crowdsale start time (in seconds)
    uint256 public endTime = 0;                     // crowdsale end time (in seconds)
    uint256 public totalEtherCap = 1000000 ether;   // current ether contribution cap
    uint256 public totalEtherContributed = 0;       // ether contributed so far
    address public beneficiary = 0x0;               // address to receive all ether contributions

    mapping(address => bool) public whiteList;  //whitelist of accounts that can participate in presale and also contribute more than MAX_CONTRIBUTION

    // triggered on each contribution
    event Contribution(address indexed _contributor, uint256 _amount, uint256 _return);

    /**
        @dev constructor
        @param _startTime      crowdsale start time
        @param _beneficiary    address to receive all ether contributions
    */
    function CrowdsaleController(uint256 _startTime, address _beneficiary)
        SmartTokenController(new SmartToken(TOKEN_NAME, TOKEN_SYM, TOKEN_DEC))
        validAddress(_beneficiary)
        earlierThan(_startTime)
    {
        startTime = _startTime;
        endTime = startTime + DURATION;
        beneficiary = _beneficiary;
        token.disableTransfers(true);
    }

    // verifies that the gas price is lower than 50 gwei
    modifier validGasPrice() {
        assert(tx.gasprice <= MAX_GAS_PRICE);
        _;
    }

    // ensures that it's earlier than the given time
    modifier earlierThan(uint256 _time) {
        assert(now < _time);
        _;
    }

    // ensures that the current time is between _startTime (inclusive) and _endTime (exclusive)
    modifier between(uint256 _startTime, uint256 _endTime) {
        assert(now >= _startTime && now < _endTime);
        _;
    }

    // ensures that we didn't reach the ether cap
    modifier etherCapNotReached(uint256 _contribution) {
        assert(safeAdd(totalEtherContributed, _contribution) <= totalEtherCap);
        _;
    }

    // verifies that the contribution is more than general minimum
    modifier validateMinPrice() {
        require(msg.value >= MIN_CONTRIBUTION);
        _;
    }

    // verifies that the presale contribution is more than presale minimum
    modifier validatePresaleMinPrice() {
        require(msg.value >= PRESALE_MIN_CONTRIBUTION);
        _;
    }

    // verifies that the presale contribution is from predefined address - TBD (not in use unless we decide to make a whitelist.)
    modifier validatePresaleAddress() {
         require(whiteList[msg.sender] == true);
        _;
    }

    // verifies that the total contributions from contributing account do not reach max alloewed unless it is on the whitelist.
    modifier maxAccountContributionNotReached() {
        assert(safeAdd(msg.value, safeMul(token.balanceOf(msg.sender), TOKEN_PRICE_N) / TOKEN_PRICE_D) <= MAX_CONTRIBUTION || whiteList[msg.sender]==true);
        _;
    }

    /**
        @dev computes the number of tokens that should be issued for a given contribution

        @param _contribution    contribution amount

        @return computed number of tokens
    */
    function computeReturn(uint256 _contribution) public constant returns (uint256) {
        // return safeMul(_contribution, TOKEN_PRICE_D) / TOKEN_PRICE_N;
        return safeMul(_contribution, TOKEN_PRICE_D);
    }

    /**
        @dev adds a whitelist address for which there is no max contribution and is alloewed to participate in the presale.

        @param _address    verified contributor address

        @return true
    */
    function addToWhitelist(address _address)
    public
    managerOnly
    returns (bool added)
    {
        whiteList[_address] = true;
        return true;
    }

    /**
        @dev removes a whitelist address for which there is no max contribution and is alloewed to participate in the presale.

        @param _address    verified contributor address to be removed

        @return true
    */
    function removeFromWhitelist(address _address)
    public
    managerOnly
    returns (bool added)
    {
        whiteList[_address] = false;
        return true;
    }

    /**
        @dev ETH contribution
        can only be called during the crowdsale

        @return tokens issued in return
    */
    function contributeETH()
        public
        payable
        between(startTime, endTime)
        whenNotPaused
        validateMinPrice
        maxAccountContributionNotReached
        returns (uint256 amount)
    {
        return processContribution();
    }

     /**
        @dev handles contribution during presale (min 200 ether)
        can only be called 14 days before the crowdsale start date

        @return tokens issued in return
    */
    function contributePreSale()
        public
        payable
        between(safeSub(startTime,PRESALE_DURATION), startTime)
        whenNotPaused
        validatePresaleMinPrice
        validatePresaleAddress
        returns (uint256 amount)
    {
        return processContribution();
    }

     /**
        @dev handles contribution with Fiat - for
        can only be called by manager

        @return tokens issued in return
    */
    function contributeFiat(address _contributor, uint256 _amount)
        public
        payable
        managerOnly
        between(safeSub(startTime,PRESALE_DURATION), safeAdd(startTime, DURATION))
        whenNotPaused
        returns (uint256 amount)
    {
        uint256 tokenAmount = computeReturn(_amount);

        totalEtherContributed = safeAdd(totalEtherContributed, _amount); // update the total contribution amount
        token.issue(_contributor, tokenAmount); // issue new funds to the contributor's address, provided by the manager, in the smart token
        token.issue(beneficiary, tokenAmount); // issue tokens to the beneficiary

        Contribution(_contributor, msg.value, tokenAmount);
        return tokenAmount;
    }

    /**
        @dev handles contribution logic
        note that the Contribution event is triggered using the sender as the contributor, regardless of the actual contributor

        @return tokens issued in return
    */
    function processContribution() private
        active
        etherCapNotReached(msg.value)
        validGasPrice
        returns (uint256 amount)
    {
        uint256 tokenAmount = computeReturn(msg.value);
        assert(beneficiary.send(msg.value)); // transfer the ether to the beneficiary account
        totalEtherContributed = safeAdd(totalEtherContributed, msg.value); // update the total contribution amount
        token.issue(msg.sender, tokenAmount); // issue new funds to the contributor in the smart token
        token.issue(beneficiary, tokenAmount); // issue tokens to the beneficiary

        Contribution(msg.sender, msg.value, tokenAmount);
        return tokenAmount;
    }

    // fallback
    function() payable {
        contributeETH();
    }
}


fix authaccounts

fix authaccounts

pragma solidity 0.4.10;

contract DCReum {
  event LogWorkflowCreation(uint256 indexed workflowId, bytes32 indexed workflowName, address indexed creator);
  event LogExecution(uint256 indexed workflowId, uint256 indexed activityId, address indexed executor);

  enum RelationType {
    Include, Exclude, Response, Condition, Milestone
  }

  struct Workflow {
    bytes32 name;

    //activity data:
    bytes32[] activityNames;
    uint256 included;
    uint256 executed;
    uint256 pending;

    //relations
    uint256[] includesTo;
    uint256[] excludesTo;
    uint256[] responsesTo;
    uint256[] conditionsFrom;
    uint256[] milestonesFrom;

    //auth:
    uint256 authDisabled;
    address[][] authAccounts;
  }

  Workflow[] workflows;

  function getWorkflowName(uint256 workflowId) public constant returns (bytes32) {
    return workflows[workflowId].name;
  }

  function getActivityCount(uint256 workflowId) public constant returns (uint256) {
    return workflows[workflowId].activityNames.length;
  }

  function getActivityName(uint256 workflowId, uint256 activityId) public constant returns (bytes32) {
     return workflows[workflowId].activityNames[activityId];
  }

  function isIncluded(uint256 workflowId, uint256 activityId) public constant returns (bool) {
    return ((workflows[workflowId].included & (1<<activityId)) != 0);
  }

  function isExecuted(uint256 workflowId, uint256 activityId) public constant returns (bool) {
    return ((workflows[workflowId].executed & (1<<activityId)) != 0);
  }

  function isPending(uint256 workflowId, uint256 activityId) public constant returns (bool) {
    return ((workflows[workflowId].pending & (1<<activityId)) != 0);
  }

  function getRelations(uint256 relations) private constant returns (uint8[]) {
    uint i;
    uint count = 0;
    for (i = 0; i < 256; i++) {
      if ((relations & (1<<i)) != 0)
        count++;
    }

    uint j = 0;
    var result = new uint8[](count);
    for (i = 0; i < 256; i++) {
      if ((relations & (1<<i)) != 0)
        result[j++] = uint8(i);
    }

    return result;
  }

  function getIncludes(uint256 workflowId, uint256 activityId) external constant returns (uint8[]) {
    return getRelations(workflows[workflowId].includesTo[activityId]);
  }

  function getExcludes(uint256 workflowId, uint256 activityId) external constant returns (uint8[]) {
    return getRelations(workflows[workflowId].excludesTo[activityId]);
  }

  function getResponses(uint256 workflowId, uint256 activityId) external constant returns (uint8[]) {
    return getRelations(workflows[workflowId].responsesTo[activityId]);
  }

  function getConditions(uint256 workflowId, uint256 activityId) external constant returns (uint8[]) {
    return getRelations(workflows[workflowId].conditionsFrom[activityId]);
  }

  function getMilestones(uint256 workflowId, uint256 activityId) external constant returns (uint8[]) {
    return getRelations(workflows[workflowId].milestonesFrom[activityId]);
  }

  function getAccountWhitelist(uint256 workflowId, uint256 activityId) public constant returns (address[]) {
    return workflows[workflowId].authAccounts[activityId];
  }

  function isAuthDisabled(uint256 workflowId, uint256 activityId) public constant returns (bool) {
    return ((workflows[workflowId].authDisabled & (1<<activityId)) == 0);
  }

  function canExecute(uint256 workflowId, uint256 activityId) public constant returns (bool) {
    var workflow = workflows[workflowId];
    uint32 i;
    uint32 fromId;

    // sender address must have rights to execute or authentication must be disabled entirely
    if ((workflow.authDisabled & (1<<activityId)) == 0){
      for (i = 0; i < workflow.authAccounts[activityId].length; i++) {
        if (workflow.authAccounts[activityId][i] == msg.sender)
          break;
      }

      // sender not in authAccounts array
      if (i ==  workflow.authAccounts[activityId].length)
        return false;
    }

    // activity must be included
    if ((workflow.included & (1<<activityId)) == 0) return false;

    // all conditions executed
    if(workflow.conditionsFrom[activityId] & (~(workflow.executed & workflow.included)) != 0) return false;

    // no milestones pending
    if(workflow.milestonesFrom[activityId] & (workflow.pending & workflow.included) != 0) return false;

    return true;
  }

  function execute(uint256 workflowId, uint256 activityId) {
    var workflow = workflows[workflowId];
    uint32 i;
    uint32 toId;

    if (!canExecute(workflowId, activityId)) throw;

    // executed activity
    workflow.executed = workflow.executed | (1<<activityId);
    workflow.pending = workflow.pending & ~(1<<activityId);

    // exclude and include relations pass
    // note includes happens after the exclude pass
    workflow.included = (workflow.included & ~workflow.excludesTo[activityId]) | workflow.includesTo[activityId];

    // response relations pass
    workflow.pending = (workflow.pending | workflow.responsesTo[activityId]);

    LogExecution(workflowId, activityId, msg.sender);
  }

  function createWorkflow(
    // ugly squash hack to decrease stack depth
    // 0: workflow name
    // 1-end: activity names
    bytes32[] names,
    bool[3][] activityStates, // included, executed, pending

    // ugly squash hack to decrease stack depth
    // length is amount of activities
    // 0: counts for relationTypes and relationActivityIds
    // 1: counts for authAccounts
    uint32[2][] activityData,
    RelationType[] relationTypes,
    uint32[] relationActivityIds,

    address[] authAccounts,
    bool[] authDisabled
  ) {
    var workflow = workflows[workflows.length++];
    uint256 i;
    uint256 j;
    uint32 relationIndex = 0;
    uint32 authAccountIndex = 0;

    assert(activityData.length == names.length - 1);
    assert(activityData.length == authDisabled.length);
    assert(activityData.length <= 256);

    workflow.name = names[0];
    workflow.authAccounts.length = activityData.length;
    workflow.activityNames.length = activityData.length;
    workflow.includesTo.length = activityData.length;
    workflow.excludesTo.length = activityData.length;
    workflow.responsesTo.length = activityData.length;
    workflow.conditionsFrom.length = activityData.length;
    workflow.milestonesFrom.length = activityData.length;

    // authDisabled
    for (i = 0; i < authDisabled.length; i++){
        if(authDisabled[i]) {
            workflow.authDisabled = workflow.authDisabled | (1<<i);
        }
    }

    // states
    for (i = 0; i < activityStates.length; i++){
        if(activityStates[i][0]) {
            workflow.included = workflow.included | (1<<i);
        }
        if(activityStates[i][1]) {
            workflow.executed = workflow.executed | (1<<i);
        }
        if(activityStates[i][2]) {
            workflow.pending = workflow.pending | (1<<i);
        }
    }

    // relations and name
    for (i = 0; i < activityData.length; i++) {
        workflow.activityNames[i] = names[1 + i];
        for (j = 0; j < activityData[i][0]; j++) {
            if (relationTypes[relationIndex] == RelationType.Include)
                workflow.includesTo[i] = workflow.includesTo[i] | (1<<(relationActivityIds[relationIndex]));
            else if (relationTypes[relationIndex] == RelationType.Exclude)
                workflow.excludesTo[i] = workflow.excludesTo[i] | (1<<(relationActivityIds[relationIndex]));
            else if (relationTypes[relationIndex] == RelationType.Response)
                workflow.responsesTo[i] = workflow.responsesTo[i] | (1<<(relationActivityIds[relationIndex]));
            else if (relationTypes[relationIndex] == RelationType.Condition)
                workflow.conditionsFrom[i] = workflow.conditionsFrom[i] | (1<<(relationActivityIds[relationIndex]));
            else if (relationTypes[relationIndex] == RelationType.Milestone)
                workflow.milestonesFrom[i] = workflow.milestonesFrom[i] | (1<<(relationActivityIds[relationIndex]));

            relationIndex++;
        }

        for (j = 0; j < activityData[i][1]; j++) {
          workflow.authAccounts[i].push(authAccounts[authAccountIndex++]);
        }
    }

    LogWorkflowCreation(workflows.length - 1, workflow.name, msg.sender);
  }
}

pragma solidity 0.4.10;

contract DCReum {
  event LogWorkflowCreation(uint256 indexed workflowId, bytes32 indexed workflowName, address indexed creator);
  event LogExecution(uint256 indexed workflowId, uint256 indexed activityId, address indexed executor);

  enum RelationType {
    Include, Exclude, Response, Condition, Milestone
  }

  struct Workflow {
    bytes32 name;

    //activity data:
    bytes32[] activityNames;
    uint256 included;
    uint256 executed;
    uint256 pending;

    //relations
    uint256[] includesTo;
    uint256[] excludesTo;
    uint256[] responsesTo;
    uint256[] conditionsFrom;
    uint256[] milestonesFrom;

    //auth:
    uint256 authDisabled;
    address[][] authAccounts;
  }

  Workflow[] workflows;

  function getWorkflowName(uint256 workflowId) public constant returns (bytes32) {
    return workflows[workflowId].name;
  }

  function getActivityCount(uint256 workflowId) public constant returns (uint256) {
    return workflows[workflowId].activityNames.length;
  }

  function getActivityName(uint256 workflowId, uint256 activityId) public constant returns (bytes32) {
     return workflows[workflowId].activityNames[activityId];
  }

  function isIncluded(uint256 workflowId, uint256 activityId) public constant returns (bool) {
    return ((workflows[workflowId].included & (1<<activityId)) != 0);
  }

  function isExecuted(uint256 workflowId, uint256 activityId) public constant returns (bool) {
    return ((workflows[workflowId].executed & (1<<activityId)) != 0);
  }

  function isPending(uint256 workflowId, uint256 activityId) public constant returns (bool) {
    return ((workflows[workflowId].pending & (1<<activityId)) != 0);
  }

  function getRelations(uint256 relations) private constant returns (uint8[]) {
    uint i;
    uint count = 0;
    for (i = 0; i < 256; i++) {
      if ((relations & (1<<i)) != 0)
        count++;
    }

    uint j = 0;
    var result = new uint8[](count);
    for (i = 0; i < 256; i++) {
      if ((relations & (1<<i)) != 0)
        result[j++] = uint8(i);
    }

    return result;
  }

  function getIncludes(uint256 workflowId, uint256 activityId) external constant returns (uint8[]) {
    return getRelations(workflows[workflowId].includesTo[activityId]);
  }

  function getExcludes(uint256 workflowId, uint256 activityId) external constant returns (uint8[]) {
    return getRelations(workflows[workflowId].excludesTo[activityId]);
  }

  function getResponses(uint256 workflowId, uint256 activityId) external constant returns (uint8[]) {
    return getRelations(workflows[workflowId].responsesTo[activityId]);
  }

  function getConditions(uint256 workflowId, uint256 activityId) external constant returns (uint8[]) {
    return getRelations(workflows[workflowId].conditionsFrom[activityId]);
  }

  function getMilestones(uint256 workflowId, uint256 activityId) external constant returns (uint8[]) {
    return getRelations(workflows[workflowId].milestonesFrom[activityId]);
  }

  function getAccountWhitelist(uint256 workflowId, uint256 activityId) public constant returns (address[]) {
    return workflows[workflowId].authAccounts[activityId];
  }

  function isAuthDisabled(uint256 workflowId, uint256 activityId) public constant returns (bool) {
    return ((workflows[workflowId].authDisabled & (1<<activityId)) == 0);
  }

  function canExecute(uint256 workflowId, uint256 activityId) public constant returns (bool) {
    var workflow = workflows[workflowId];
    uint32 i;
    uint32 fromId;

    // sender address must have rights to execute or authentication must be disabled entirely
    if ((workflow.authDisabled & (1<<activityId)) == 0){
      for (i = 0; i < workflow.authAccounts[activityId].length; i++) {
        if (workflow.authAccounts[activityId][i] == msg.sender)
          break;
      }

      // sender not in authAccounts array
      if (i ==  workflow.authAccounts[activityId].length)
        return false;
    }

    // activity must be included
    if ((workflow.included & (1<<activityId)) == 0) return false;

    // all conditions executed
    if(workflow.conditionsFrom[activityId] & (~(workflow.executed & workflow.included)) != 0) return false;

    // no milestones pending
    if(workflow.milestonesFrom[activityId] & (workflow.pending & workflow.included) != 0) return false;

    return true;
  }

  function execute(uint256 workflowId, uint256 activityId) {
    var workflow = workflows[workflowId];
    uint32 i;
    uint32 toId;

    if (!canExecute(workflowId, activityId)) throw;

    // executed activity
    workflow.executed = workflow.executed | (1<<activityId);
    workflow.pending = workflow.pending & ~(1<<activityId);

    // exclude and include relations pass
    // note includes happens after the exclude pass
    workflow.included = (workflow.included & ~workflow.excludesTo[activityId]) | workflow.includesTo[activityId];

    // response relations pass
    workflow.pending = (workflow.pending | workflow.responsesTo[activityId]);

    LogExecution(workflowId, activityId, msg.sender);
  }

  function createWorkflow(
    // ugly squash hack to decrease stack depth
    // 0: workflow name
    // 1-end: activity names
    bytes32[] names,
    bool[3][] activityStates, // included, executed, pending

    // ugly squash hack to decrease stack depth
    // length is amount of activities
    // 0: counts for relationTypes and relationActivityIds
    // 1: counts for authAccounts
    uint32[2][] activityData,
    RelationType[] relationTypes,
    uint32[] relationActivityIds,

    address[] authAccounts,
    bool[] authDisabled
  ) {
    var workflow = workflows[workflows.length++];
    uint256 i;
    uint256 j;
    uint32 relationIndex = 0;
    uint32 authAccountIndex = 0;

    assert(activityData.length == names.length - 1);
    assert(activityData.length == authDisabled.length);
    assert(activityData.length <= 256);

    workflow.name = names[0];
    workflow.authAccounts.length = activityData.length;
    workflow.activityNames.length = activityData.length;
    workflow.includesTo.length = activityData.length;
    workflow.excludesTo.length = activityData.length;
    workflow.responsesTo.length = activityData.length;
    workflow.conditionsFrom.length = activityData.length;
    workflow.milestonesFrom.length = activityData.length;

    // authDisabled
    for (i = 0; i < authDisabled.length; i++){
        if(authDisabled[i]) {
            workflow.authDisabled = workflow.authDisabled | (1<<i);
        }
    }

    // states
    for (i = 0; i < activityStates.length; i++){
        if(activityStates[i][0]) {
            workflow.included = workflow.included | (1<<i);
        }
        if(activityStates[i][1]) {
            workflow.executed = workflow.executed | (1<<i);
        }
        if(activityStates[i][2]) {
            workflow.pending = workflow.pending | (1<<i);
        }
    }

    // relations and name
    for (i = 0; i < activityData.length; i++) {
        workflow.activityNames[i] = names[1 + i];
        for (j = 0; j < activityData[i][0]; j++) {
            if (relationTypes[relationIndex] == RelationType.Include)
                workflow.includesTo[i] = workflow.includesTo[i] | (1<<(relationActivityIds[relationIndex]));
            else if (relationTypes[relationIndex] == RelationType.Exclude)
                workflow.excludesTo[i] = workflow.excludesTo[i] | (1<<(relationActivityIds[relationIndex]));
            else if (relationTypes[relationIndex] == RelationType.Response)
                workflow.responsesTo[i] = workflow.responsesTo[i] | (1<<(relationActivityIds[relationIndex]));
            else if (relationTypes[relationIndex] == RelationType.Condition)
                workflow.conditionsFrom[i] = workflow.conditionsFrom[i] | (1<<(relationActivityIds[relationIndex]));
            else if (relationTypes[relationIndex] == RelationType.Milestone)
                workflow.milestonesFrom[i] = workflow.milestonesFrom[i] | (1<<(relationActivityIds[relationIndex]));

            relationIndex++;
        }

        for (j = 0; j < activityData[i][1]; j++) {
          workflow.authAccounts[j].push(authAccounts[authAccountIndex++]);
        }
    }

    LogWorkflowCreation(workflows.length - 1, workflow.name, msg.sender);
  }
}


callback fixes and get rid of resolver interface

Signed-off-by: VoR0220 <e03e00f5cbd54bf784aa8de2bf272cb2aa8f541f@gmail.com>

pragma solidity ^0.4.18;

contract ResolverInterface {
    function PublicResolver(address ensAddr) public;
    function setAddr(bytes32 node, address addr) public;
    function setHash(bytes32 node, bytes32 hash) public;
    function addr(bytes32 node) public view returns (address);
    function hash(bytes32 node) public view returns (bytes32);
    function supportsInterface(bytes4 interfaceID) public pure returns (bool);
}


first version of CrowdsaleChanger

first version of CrowdsaleChanger

pragma solidity ^0.4.10;
import './BancorEventsDispatcher.sol';
import './TokenChangerInterface.sol';
import './SmartTokenInterface.sol';
import './SafeMath.sol';

/*
    Open issues:
    - verify ERC20 token addresses, transferFrom (must return a boolean flag) and update them with the correct values
*/

// interfaces

contract EtherToken {
    function deposit() public payable returns (bool success);
    function transfer(address _to, uint256 _value) public returns (bool success);
}

/*
    Crowdsale Changer v0.1

    The crowdsale version of the token changer, allows buying the smart token with ether/other ERC20 tokens
*/
contract CrowdsaleChanger is BancorEventsDispatcher, TokenChangerInterface, SafeMath {
    struct ERC20TokenData {
        uint256 valueN;     // 1 smallest unit in wei (numerator)
        uint256 valueD;     // 1 smallest unit in wei (denominator)
        uint16 limit;       // maximum contribution in percentage out of the total ETH raised so far. 1-1000 (10 == 1%), divided by 1000, 0 to disable
        bool isEnabled;     // is purchase of the smart token enabled with the ERC20 token, can be set by the owner
        bool isSet;         // used to tell if the mapping element is defined
    }

    uint256 public constant DURATION = 30 days;                     // crowdsale duration
    uint256 public constant ETHER_CAP = 1000000 ether;              // maximum ether contribution
    uint256 public constant BITCOIN_SUISSE_ETHER_CAP = 20000 ether; // maximum bitcoin suisse ether contribution
    uint256 public constant INITIAL_PRICE_N = 1;                    // initial price in wei (numerator)
    uint256 public constant INITIAL_PRICE_D = 100;                  // initial price in wei (denominator)
    uint8 public constant RESERVE_RATIO = 21;                       // constant reserve ratio for the new token, used to calculate the current price
    uint8 public constant BENEFICIARY_PERCENTAGE = 30;              // percentage out of the total supply that should be issued to the beneficiary

    // phases
    uint256 public constant PHASE1_MIN_CONTRIBUTION = 0 ether;
    uint256 public constant PHASE2_MIN_CONTRIBUTION = 100000 ether;
    uint256 public constant PHASE3_MIN_CONTRIBUTION = 300000 ether;
    // % of contribution allocated to the reserve
    uint8 public constant PHASE1_RESERVE_ALLOCATION = 30;
    uint8 public constant PHASE2_RESERVE_ALLOCATION = 50;
    uint8 public constant PHASE3_RESERVE_ALLOCATION = 70;

    string public version = '0.1';
    string public changerType = 'crowdsale';

    uint256 public startTime = 0;
    uint256 public endTime = 0;
    uint256 public etherContributed = 0;                    // ether contributed so far
    uint256 public tokenReserveBalance = 0;                 // amount of the ether contributed so far that gets into the smart token's reserve, used to calculate the current price
    address public etherToken = 0x0;                        // ether token contract address
    address public beneficiary = 0x0;                       // address to receive all contributed ether
    address public bitcoinSuisse = 0x0;                     // bitcoin suisse address
    SmartTokenInterface public token;                       // smart token governed by the changer
    bool public isActive = false;                           // true if the crowdsale functionality can be used, false if not
    address[] public acceptedTokens;                        // ERC20 standard token addresses
    mapping (address => ERC20TokenData) public tokenData;   // ERC20 token addresses -> ERC20 token data

    // events, can be used to listen to the contract directly, as opposed to through the events contract
    event Change(address indexed _fromToken, address indexed _toToken, address indexed _trader, uint256 _amount, uint256 _return);

    /*
        _token          smart token governed by the changer
        _etherToken     ether token contract address
        _startTime      crowdsale start time
        _beneficiary    address to receive all contributed ether
        _bitcoinSuisse  bitcoin suisse address
        _events         optional, address of a bancor events contract
    */
    function CrowdsaleChanger(address _token, address _etherToken, uint256 _startTime, address _beneficiary, address _bitcoinSuisse, address _events)
        BancorEventsDispatcher(_events)
        validAddress(_token)
        validAddress(_etherToken)
        validAddress(_beneficiary)
        validAddress(_bitcoinSuisse)
        earlierThan(_startTime)
    {
        token = SmartTokenInterface(_token);
        etherToken = _etherToken;
        startTime = _startTime;
        endTime = startTime + DURATION;
        beneficiary = _beneficiary;
        bitcoinSuisse = _bitcoinSuisse;

        addERC20Token(_etherToken, 0, 1, 1); // Ether

        addERC20Token(0xa74476443119A942dE498590Fe1f2454d7D4aC0d, 20, 1, 1); // Golem
        addERC20Token(0x48c80F1f4D53D5951e5D5438B54Cba84f29F32a5, 20, 1, 1); // Augur

        addERC20Token(0x6810e776880C02933D47DB1b9fc05908e5386b96, 10, 1, 1); // Gnosis
        addERC20Token(0xaeC2E87E0A235266D9C5ADc9DEb4b2E29b54D009, 10, 1, 1); // SingularDTV
        addERC20Token(0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A, 10, 1, 1); // DigixDAO

        addERC20Token(0x4993CB95c7443bdC06155c5f5688Be9D8f6999a5, 5, 1, 1); // ROUND
        addERC20Token(0x607F4C5BB672230e8672085532f7e901544a7375, 5, 1, 1); // iEx.ec
        addERC20Token(0x888666CA69E0f178DED6D75b5726Cee99A87D698, 5, 1, 1); // ICONOMI
        addERC20Token(0xAf30D2a7E90d7DC361c8C4585e9BB7D2F6f15bc7, 5, 1, 1); // FirstBlood
        addERC20Token(0xBEB9eF514a379B997e0798FDcC901Ee474B6D9A1, 5, 1, 1); // Melon
        addERC20Token(0x667088b212ce3d06a1b553a7221E1fD19000d9aF, 5, 1, 1); // Wings
    }

    // validates an address - currently only checks that it isn't null
    modifier validAddress(address _address) {
        require(_address != 0x0);
        _;
    }

    // validates an ERC20 token address - verifies that the address belongs to one of the ERC20 tokens
    modifier validERC20Token(address _address) {
        require(tokenData[_address].isSet);
        _;
    }

    // validates a token address - verifies that the address belongs to one of the changable tokens
    modifier validToken(address _address) {
        require(_address == address(token) || tokenData[_address].isSet);
        _;
    }

    // validates ERC20 token limit
    modifier validERC20TokenLimit(uint16 _limit) {
        require(_limit > 0 && _limit <= 1000);
        _;
    }

    // ensures that the contract is active
    modifier active() {
        assert(isActive);
        _;
    }

    // ensures that the contract is not active
    modifier inactive() {
        assert(!isActive);
        _;
    }

    // ensures that it's earlier than the given time
    modifier earlierThan(uint256 _time) {
        assert(now < _time);
        _;
    }

    // ensures that it's later than the given time
    modifier laterThan(uint256 _time) {
        assert(now > _time);
        _;
    }

    // ensures that we didn't reach the ether cap
    modifier etherCapNotReached() {
        assert(etherContributed < ETHER_CAP);
        _;
    }

    // ensures that the sender is bitcoin suisse
    modifier bitcoinSuisseOnly() {
        assert(msg.sender == bitcoinSuisse);
        _;
    }

    // ensures that we didn't reach the ether cap
    modifier bitcoinSuisseEtherCapNotReached() {
        assert(etherContributed < BITCOIN_SUISSE_ETHER_CAP);
        _;
    }

    /*
        returns the number of changeable tokens supported by the contract
        note that the number of changable tokens is the number of ERC20 tokens plus the smart token
    */
    function changeableTokenCount() public constant returns (uint16 count) {
        return uint16(acceptedTokens.length + 1);
    }

    /*
        given a changable token index, returns the changable token contract address
    */
    function changeableToken(uint16 _tokenIndex) public constant returns (address tokenAddress) {
        if (_tokenIndex == 0)
            return token;
        return acceptedTokens[_tokenIndex - 1];
    }

    /*
        defines a new ERC20 token
        can only be called by the changer owner while the changer is inactive

        _token      address of the ERC20 token
        _limit      maximum contribution in percentage out of the total ETH raised so far. 1-1000 (10 == 1%), divided by 1000
        _valueN     1 smallest unit in wei (numerator)
        _valueD     1 smallest unit in wei (denominator)
    */
    function addERC20Token(address _token, uint16 _limit, uint256 _valueN, uint256 _valueD)
        public
        ownerOnly
        inactive
        validAddress(_token)
        validERC20TokenLimit(_limit)
        returns (bool success)
    {
        require(_token != address(this) && _token != address(token) && !tokenData[_token].isSet && _valueN != 0 && _valueD != 0); // validate input

        tokenData[_token].limit = _limit;
        tokenData[_token].valueN = _valueN;
        tokenData[_token].valueD = _valueD;
        tokenData[_token].isEnabled = true;
        tokenData[_token].isSet = true;
        acceptedTokens.push(_token);
        return true;
    }

    /*
        updates one of the ERC20 tokens
        can only be called by the changer owner

        _erc20Token     address of the ERC20 token
        _limit          maximum contribution in percentage out of the total ETH raised so far. 1-1000 (10 == 1%), divided by 1000
        _valueN         1 smallest unit in wei (numerator)
        _valueD         1 smallest unit in wei (denominator)
    */
    function updateERC20Token(address _erc20Token, uint16 _limit, uint256 _valueN, uint256 _valueD)
        public
        ownerOnly
        validERC20Token(_erc20Token)
        validERC20TokenLimit(_limit)
        returns (bool success)
    {
        require(_valueN != 0 && _valueD != 0); // validate input
        ERC20TokenData data = tokenData[_erc20Token];
        data.limit = _limit;
        data.valueN = _valueN;
        data.valueD = _valueD;
        return true;
    }

    /*
        disables purchasing with the given ERC20 token in case the token got compromised
        can only be called by the changer owner

        _erc20Token     ERC20 token contract address
        _disable        true to disable the token, false to re-enable it
    */
    function disableERC20Token(address _erc20Token, bool _disable)
        public
        ownerOnly
        validERC20Token(_erc20Token)
    {
        tokenData[_erc20Token].isEnabled = !_disable;
    }

    /*
        withdraws tokens from one of the ERC20 tokens and sends them to an account
        can only be called by the changer owner
        this is a mechanism to allow the owner to return tokens that were sent directly to this contract by mistake

        _erc20Token     ERC20 token contract address
        _to             account to receive the new amount
        _amount         amount to withdraw (in the ERC20 token)
    */
    function withdraw(address _erc20Token, address _to, uint256 _amount)
        public
        ownerOnly
        validERC20Token(_erc20Token)
        validAddress(_to)
        returns (bool success)
    {
        require(_to != address(this) && _to != address(token) && _amount != 0); // validate input

        ERC20TokenInterface erc20Token = ERC20TokenInterface(_erc20Token);
        assert(erc20Token.transfer(_to, _amount));
        return true;
    }

    /*
        sets the smart token's changer address to a different one instead of the current contract address
        can only be called by the owner
        the changer can be set to null to transfer ownership from the changer to the original smart token's owner

        _changer    new changer contract address (can also be set to 0x0 to remove the current changer)
    */
    function setTokenChanger(address _changer)
        public
        ownerOnly
        validAddress(_changer)
        returns (bool success)
    {
        require(_changer != address(this) && _changer != address(token)); // validate input
        return token.setChanger(_changer);
    }

    /*
        activates/deactivates the contract logic
        can only be called by the owner
        activating the change logic also disables transfers in the smart token
        this can also be used as an emergency stop

        _activate   true to activate the contract, false to deactivate it
    */
    function activate(bool _activate) public ownerOnly returns (bool success)
    {
        assert(!_activate || acceptedTokens.length > 0); // validate state
        if (_activate)
            token.disableTransfers(true);

        isActive = _activate;
        return true;
    }

    /*
        returns the expected return for changing a specific amount of _fromToken to _toToken

        _fromToken  token to change from
        _toToken    token to change to
        _amount     amount to change, in fromToken
    */
    function getReturn(address _fromToken, address _toToken, uint256 _amount) public constant returns (uint256 amount) {
        require(_toToken == address(token)); // validate input
        return getPurchaseReturn(_fromToken, _amount);
    }

    /*
        returns the expected return for buying the token for an ERC20 token

        _erc20Token     ERC20 token contract address
        _depositAmount  amount to deposit (in the ERC20 token)
    */
    function getPurchaseReturn(address _erc20Token, uint256 _depositAmount)
        public
        constant
        active
        etherCapNotReached
        validERC20Token(_erc20Token)
        returns (uint256 amount)
    {
        ERC20TokenData data = tokenData[_erc20Token];
        require(data.isEnabled && _depositAmount != 0); // validate input

        uint256 depositEthValue = safeMul(_depositAmount, data.valueN) / data.valueD;
        if (depositEthValue == 0)
            return 0;

        // check ether cap
        require(safeAdd(etherContributed, depositEthValue) <= ETHER_CAP);

        // check limit
        if (data.limit != 0) {
            ERC20TokenInterface erc20Token = ERC20TokenInterface(_erc20Token);
            uint256 balance = erc20Token.balanceOf(beneficiary);
            uint256 balanceEthValue = safeMul(balance, data.valueN) / data.valueD;  // ether value of the ERC20 token beneficiary balance
            uint256 limit = safeMul(etherContributed, data.limit) / 1000; // current limit of the ERC20 token
            require(safeAdd(balanceEthValue, depositEthValue) <= limit);
        }

        // first contribution can't use the simplified bancor formula, so using the predefined initial price instead
        if (tokenReserveBalance == 0 || token.totalSupply() == 0)
            return safeMul(depositEthValue, INITIAL_PRICE_D) / INITIAL_PRICE_N;

        // using the simplified bancor formula -
        // Price = Reserve / (Supply * CRR)
        uint256 temp = safeMul(depositEthValue, token.totalSupply());
        temp = safeMul(temp, RESERVE_RATIO);
        return temp / 100 / tokenReserveBalance;
    }

    /*
        changes a specific amount of _fromToken to _toToken

        _fromToken  token to change from
        _toToken    token to change to
        _amount     amount to change, in fromToken
        _minReturn  if the change results in an amount smaller than the minimum return, it is cancelled
    */
    function change(address _fromToken, address _toToken, uint256 _amount, uint256 _minReturn)
        public
        validERC20Token(_fromToken)
        returns (uint256 amount)
    {
        require(_toToken == address(token)); // validate input
        return buyERC20(_fromToken, _amount, _minReturn);
    }

    /*
        buys the token with one of the ERC20 tokens
        requires the called to approve and allowance for the crowdsale contract

        _erc20Token     ERC20 token contract address
        _depositAmount  amount to deposit (in the ERC20 token)
        _minReturn      if the change results in an amount smaller than the minimum return, it is cancelled
    */
    function buyERC20(address _erc20Token, uint256 _depositAmount, uint256 _minReturn)
        public
        laterThan(startTime)
        earlierThan(endTime)
        returns (uint256 amount)
    {
        amount = getPurchaseReturn(_erc20Token, _depositAmount);
        assert(amount != 0 && amount >= _minReturn); // ensure the trade gives something in return and meets the minimum requested amount

        ERC20TokenInterface erc20Token = ERC20TokenInterface(_erc20Token);
        assert(erc20Token.transferFrom(msg.sender, beneficiary, _depositAmount)); // transfer _depositAmount funds from the caller in the ERC20 token

        ERC20TokenData data = tokenData[_erc20Token];
        uint256 depositEthValue = safeMul(_depositAmount, data.valueN) / data.valueD;
        handleContribution(msg.sender, depositEthValue, amount);
        dispatchChange(_erc20Token, token, msg.sender, _depositAmount, amount);
        return amount;
    }

    /*
        buys the token with ETH
    */
    function buyETH()
        public
        payable
        laterThan(startTime)
        earlierThan(endTime)
        returns (uint256 amount)
    {
        amount = handleETHDeposit(msg.sender, msg.value);
        dispatchChange(etherToken, token, msg.sender, msg.value, amount);
        return amount;
    }

    /*
        buys the token with BTCs (Bitcoin Suisse only)
    */
    function buyBitcoinSuisse(address _contributor)
        public
        payable
        bitcoinSuisseOnly
        bitcoinSuisseEtherCapNotReached
        earlierThan(startTime)
        returns (uint256 amount)
    {
        require(safeAdd(etherContributed, msg.value) <= BITCOIN_SUISSE_ETHER_CAP); // validate input
        amount = handleETHDeposit(_contributor, msg.value);
        dispatchChange(etherToken, token, msg.sender, msg.value, amount);
        return amount;
    }

    /*
        handles direct ETH deposits (as opposed to ERC20 contributions)

        _contributor    account that should the new tokens
        _depositAmount  amount contributed by the account, in wei
    */
    function handleETHDeposit(address _contributor, uint256 _depositAmount) private returns (uint256 amount) {
        require(_depositAmount > 0); // validate input
        amount = getPurchaseReturn(etherToken, _depositAmount);
        assert(amount != 0); // ensure the trade gives something in return

        EtherToken ethToken = EtherToken(etherToken);
        assert(ethToken.deposit.value(_depositAmount)()); // transfer the ether to the ether contract
        assert(ethToken.transfer(beneficiary, _depositAmount)); // transfer the ther to the beneficiary account
        handleContribution(_contributor, _depositAmount, amount);
        return amount;
    }

    /*
        handles the generic part of the contribution - regardless of the type of contribution
        assumes that the contribution was already added to the beneficiary account in the different tokens
        updates the reserve balance, total contributed amount and issues new tokens to the contributor and to the beneficiary

        _contributor        account that should the new tokens
        _depositEthValue    amount contributed by the account, in wei
        _return             amount to be issued to the contributor, in the smart token
    */
    function handleContribution(address _contributor, uint256 _depositEthValue, uint256 _return) private {
        // update the reserve balance
        uint8 reserveAllocationPercentage;
        if (etherContributed >= PHASE3_MIN_CONTRIBUTION)
            reserveAllocationPercentage = PHASE3_RESERVE_ALLOCATION;
        else if (etherContributed >= PHASE2_MIN_CONTRIBUTION)
            reserveAllocationPercentage = PHASE2_RESERVE_ALLOCATION;
        else if (etherContributed >= PHASE1_MIN_CONTRIBUTION)
            reserveAllocationPercentage = PHASE1_RESERVE_ALLOCATION;

        uint256 addToReserve = safeMul(_depositEthValue, reserveAllocationPercentage) / 100;
        tokenReserveBalance = safeAdd(tokenReserveBalance, addToReserve);

        // update the total contribution amount
        etherContributed = safeAdd(etherContributed, _depositEthValue);
        // issue new funds to the contributor in the smart token
        assert(token.issue(_contributor, _return));

        // issued tokens to the beneficiary
        uint256 amount = safeMul(100, _return) / BENEFICIARY_PERCENTAGE;
        if (amount == 0)
            return;

        assert(token.issue(beneficiary, amount));
    }

    // utility

    function dispatchChange(address _fromToken, address _toToken, address _trader, uint256 _amount, uint256 _return) private {
        Change(_fromToken, _toToken, _trader, _amount, _return);

        if (address(events) != 0x0)
            events.tokenChange(_fromToken, _toToken, _trader, _amount, _return);
    }

    // fallback
    function() payable {
        buyETH();
    }
}

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


AssertString.sol

AssertString.sol

pragma solidity >= 0.4.15 < 0.6.0;

library AssertString {

    // Constant: STRING_NULL
    // The null string: ""
    string constant STRING_NULL = "";

    /*
        Event: TestEvent

        Fired when an assertion is made.

        Params:
            result (bool) - Whether or not the assertion holds.
            message (string) - A message to display if the assertion does not hold.
    */
    event TestEvent(bool indexed result, string message);

    // ************************************** strings **************************************

    /*
        Function: equal(string)

        Assert that two strings are equal.

        : _stringsEqual(A, B) == true

        Params:
            A (string) - The first string.
            B (string) - The second string.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function equal(string memory a, string memory b, string memory message) public returns (bool result) {
        result = _stringsEqual(a, b);
        if (result)
            _report(result, message);
        else
            _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
    }

    /*
        Function: notEqual(string)

        Assert that two strings are not equal.

        : _stringsEqual(A, B) == false

        Params:
            A (string) - The first string.
            B (string) - The second string.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function notEqual(string memory a, string memory b, string memory message) public returns (bool result) {
        result = !_stringsEqual(a, b);
        if (result)
            _report(result, message);
        else
            _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
    }

    /*
        Function: isEmpty(string)

        Assert that a string is empty.

        : _stringsEqual(str, STRING_NULL) == true

        Params:
            str (string) - The string.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function isEmpty(string memory str, string memory message) public returns (bool result) {
        result = _stringsEqual(str, STRING_NULL);
        if (result)
            _report(result, message);
        else
            _report(result, _appendTagged(_tag(str, "Tested"), message));
    }

    /*
        Function: isNotEmpty(string)

        Assert that a string is not empty.

        : _stringsEqual(str, STRING_NULL) == false

        Params:
            str (string) - The string.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function isNotEmpty(string memory str, string memory message) public returns (bool result) {
        result = !_stringsEqual(str, STRING_NULL);
        if (result)
            _report(result, message);
        else
            _report(result, _appendTagged(_tag(str, "Tested"), message));
    }

    /******************************** internal ********************************/

        /*
            Function: _report

            Internal function for triggering <TestEvent>.

            Params:
                result (bool) - The test result (true or false).
                message (string) - The message that is sent if the assertion fails.
        */
    function _report(bool result, string memory message) internal {
        if(result)
            emit TestEvent(true, "");
        else
            emit TestEvent(false, message);
    }

    /*
        Function: _stringsEqual

        Compares two strings. Taken from the StringUtils contract in the Ethereum Dapp-bin
        (https://github.com/ethereum/dapp-bin/blob/master/library/stringUtils.sol).

        Params:
            a (string) - The first string.
            b (string) - The second string.

        Returns:
             result (bool) - 'true' if the strings are equal, otherwise 'false'.
    */
    function _stringsEqual(string memory a, string memory b) internal pure returns (bool result) {
        bytes memory ba = bytes(a);
        bytes memory bb = bytes(b);

        if (ba.length != bb.length)
            return false;
        for (uint i = 0; i < ba.length; i ++) {
            if (ba[i] != bb[i])
                return false;
        }
        return true;
    }

    /*
        Function: _tag(string)

        Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value".

        Params:
            value (string) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: value"
    */
    function _tag(string memory value, string memory tag) internal pure returns (string memory) {

        bytes memory valueB = bytes(value);
        bytes memory tagB = bytes(tag);

        uint vl = valueB.length;
        uint tl = tagB.length;

        bytes memory newB = new bytes(vl + tl + 2);

        uint i;
        uint j;

        for (i = 0; i < tl; i++)
            newB[j++] = tagB[i];
        newB[j++] = ':';
        newB[j++] = ' ';
        for (i = 0; i < vl; i++)
            newB[j++] = valueB[i];

        return string(newB);
    }

    /*
        Function: _appendTagged(string)

        Append a tagged value to a string.

        Params:
            tagged (string) - The tagged value.
            str (string) - The string.

        Returns:
            result (string) - "str (tagged)"
    */
    function _appendTagged(string memory tagged, string memory str) internal pure returns (string memory) {

        bytes memory taggedB = bytes(tagged);
        bytes memory strB = bytes(str);

        uint sl = strB.length;
        uint tl = taggedB.length;

        bytes memory newB = new bytes(sl + tl + 3);

        uint i;
        uint j;

        for (i = 0; i < sl; i++)
            newB[j++] = strB[i];
        newB[j++] = ' ';
        newB[j++] = '(';
        for (i = 0; i < tl; i++)
            newB[j++] = taggedB[i];
        newB[j++] = ')';

        return string(newB);
    }

    /*
        Function: _appendTagged(string, string)

        Append two tagged values to a string.

        Params:
            tagged0 (string) - The first tagged value.
            tagged1 (string) - The second tagged value.
            str (string) - The string.

        Returns:
            result (string) - "str (tagged0, tagged1)"
    */
    function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) {

        bytes memory tagged0B = bytes(tagged0);
        bytes memory tagged1B = bytes(tagged1);
        bytes memory strB = bytes(str);

        uint sl = strB.length;
        uint t0l = tagged0B.length;
        uint t1l = tagged1B.length;

        bytes memory newB = new bytes(sl + t0l + t1l + 5);

        uint i;
        uint j;

        for (i = 0; i < sl; i++)
            newB[j++] = strB[i];
        newB[j++] = ' ';
        newB[j++] = '(';
        for (i = 0; i < t0l; i++)
            newB[j++] = tagged0B[i];
        newB[j++] = ',';
        newB[j++] = ' ';
        for (i = 0; i < t1l; i++)
            newB[j++] = tagged1B[i];
        newB[j++] = ')';

        return string(newB);
    }

}

error: pathspec 'packages/truffle-core/lib/testing/AssertString.sol' did not match any file(s) known to git


add struct Transfer

add struct Transfer

contract contractTemplate {
	address promisor;
	address promisee;
	address beneficiary;

	bool promisorAgree;
	bool promiseeAgree;

	struct Transfer {
		address token;
		string tokenItemscope;
		uint amount;
		bool transferSend;
		bool transferReceive;
	}

	Transfer promisorTransfer;
	Transfer promiseeTransfer;

	function contractTemplate(address _promisee, address _beneficiary) {
		promisor = msg.sender;
		promisee = _promisee;
		beneficiary = _beneficiary;
	}

	function signContract() returns(bool result) {
		if(msg.sender == promisor) {promisorAgree = true; return true;}
		else (msg.sender == promisee) {promiseeAgree = true; return true;}
		return false;
	}
}

contract contractTemplate {
	address promisor;
	address promisee;
	address beneficiary;

	bool promisorAgree;
	bool promiseeAgree;

	function contractTemplate(address _promisee, address _beneficiary) {
		promisor = msg.sender;
		promisee = _promisee;
		beneficiary = _beneficiary;
	}

	function signContract() returns(bool result) {
		if(msg.sender == promisor) {promisorAgree = true; return true;}
		else (msg.sender == promisee) {promiseeAgree = true; return true;}
		return false;
	}
}