StandingOrderDapp-20 Set Owner from Constructor

pragma solidity ^0.4.4;

import 'zeppelin/ownership/Ownable.sol';

contract StandingOrder is Ownable {

    address public payee;        // The payee gets the money
    uint public startTime;       // Time the order was created
    uint public paymentInterval; // How often can payee claim paymentAmount
    uint public paymentAmount;   // How much can payee claim per period
    uint public claimedFunds;    // How much funds have been claimed already
    string public ownerLabel;    // Label managed by contract owner
    string public payeeLabel;    // Label managed by payee

    function StandingOrder(address _owner, address _payee, uint _paymentInterval, uint _paymentAmount, string _label) payable {
        // Sanity check parameters
        if (_paymentInterval < 1)
            throw;
        if (_paymentAmount < 1)
            throw;

        // override default behaviour of Ownable base contract
        // Explicitly set owner to _owner, as msg.sender is the StandingOrderFactory contract
        owner = _owner;

        payee = _payee;
        paymentInterval = _paymentInterval;
        paymentAmount = _paymentAmount;
        ownerLabel = _label;
        payeeLabel = _label;
        startTime = now;
    }

    modifier onlyPayee() {
        if (msg.sender != payee) {
            throw;
        }
        _;
    }

    /* Allow adding funds to existing order */
    function() payable {
        // TODO: Log entry
    }

    /* How much funds are owned by Payee but not yet withdrawn */
    function getUnclaimedFunds() constant returns (uint) {
        // sanity check
        if (now < startTime) {
            // bad miner trying to mess with block time?
            return 0;
        }

        // Calculate theoretical amount that payee should own right now
        uint age = now - startTime;
        if (age == 0) {
            // order has just been created
            return 0;
        }

        uint completeIntervals = age / paymentInterval;
        // implicitly rounding down
        uint totalAmount = completeIntervals * paymentAmount;

        // subtract already withdrawn funds
        uint entitledAmount = totalAmount - claimedFunds;

        /* entitledAmount might be more than available balance. In this case
         * available balance is the limit */
        uint availableAmount = min(entitledAmount, this.balance);

        return availableAmount;
    }

    /* How much funds are still owned by owner (not yet reserved for payee) */
    function getOwnerFunds() constant returns (uint) {
        return this.balance - getUnclaimedFunds();
    }

    /* Collect payment */
    function collectFunds() {
        // only payee can collect funds
        if (msg.sender != payee) {
            throw;
        }

        uint amount = getUnclaimedFunds();

        if (amount <= 0) {
            // nothing to collect :-(
            throw;
        }

        claimedFunds += amount;
        if (payee.send(amount) == false)
        throw;
    }

    /* Returns remaining funds to owner.
     * Note that this does not return unclaimed funds - They
     * can only be claimed by payee!
     * The Standingorder is not yet cancelled, at any time owner can
     * fund it again!
     */
    function WithdrawOwnerFunds() onlyOwner {
        uint ownerFunds = getOwnerFunds();
        if (ownerFunds <= 0)
        throw;

        if (owner.send(ownerFunds) == false)
        throw;
        // TODO: Log event
    }

    /* Completely cancel this standingOrder */
    function Cancel() onlyOwner {

        // only possible when no funds are left in the contract
        if (this.balance > 0) {
            throw;
        }

        selfdestruct(owner);
    }

    function SetOwnerLabel(string _label) onlyOwner {
        ownerLabel = _label;
    }

    function SetPayeeLabel(string _label) onlyPayee {
        payeeLabel = _label;
    }

    function min(uint a, uint b) returns (uint) {
        if (a < b) return a;
        else return b;
    }
}

contract StandingOrderFactory {

    // keep track who issued standing orders
    mapping (address => StandingOrder[]) public standingOrdersByOwner;
    // keep track of payees of standing orders
    mapping (address => StandingOrder[]) public standingOrdersByPayee;

    // Events
    event LogOrderCreated(
    address orderAddress,
    address indexed owner,
    address indexed payee
    );

    // Create a new standing order.
    function createStandingOrder(address payee, uint rate, uint interval, string label) returns (StandingOrder) {
        StandingOrder so = new StandingOrder(msg.sender, payee, interval, rate, label);
        standingOrdersByOwner[msg.sender].push(so);
        standingOrdersByPayee[payee].push(so);
        LogOrderCreated(so, msg.sender, payee);
        return so;
    }

    function getNumOrdersByOwner() constant returns (uint) {
        return standingOrdersByOwner[msg.sender].length;
    }

    function getOwnOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByOwner[msg.sender][index];
    }

    function getNumOrdersByPayee() constant returns (uint) {
        return standingOrdersByPayee[msg.sender].length;
    }

    function getPaidOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByPayee[msg.sender][index];
    }
}

pragma solidity ^0.4.4;

import 'zeppelin/ownership/Ownable.sol';

contract StandingOrder is Ownable {

    address public payee;        // The payee gets the money
    uint public startTime;       // Time the order was created
    uint public paymentInterval; // How often can payee claim paymentAmount
    uint public paymentAmount;   // How much can payee claim per period
    uint public claimedFunds;    // How much funds have been claimed already
    string public ownerLabel;    // Label managed by contract owner
    string public payeeLabel;    // Label managed by payee

    function StandingOrder(address _payee, uint _paymentInterval, uint _paymentAmount, string _label) payable {
        // Sanity check parameters
        if (_paymentInterval < 1)
            throw;
        if (_paymentAmount < 1)
            throw;

        payee = _payee;
        paymentInterval = _paymentInterval;
        paymentAmount = _paymentAmount;
        ownerLabel = _label;
        payeeLabel = _label;
        startTime = now;
    }

    modifier onlyPayee() {
        if (msg.sender != payee) {
            throw;
        }
        _;
    }

    /* Allow adding funds to existing order */
    function() payable {
        // TODO: Log entry
    }

    /* How much funds are owned by Payee but not yet withdrawn */
    function getUnclaimedFunds() constant returns (uint) {
        // sanity check
        if (now < startTime) {
            // bad miner trying to mess with block time?
            return 0;
        }

        // Calculate theoretical amount that payee should own right now
        uint age = now - startTime;
        if (age == 0) {
            // order has just been created
            return 0;
        }

        uint completeIntervals = age / paymentInterval;
        // implicitly rounding down
        uint totalAmount = completeIntervals * paymentAmount;

        // subtract already withdrawn funds
        uint entitledAmount = totalAmount - claimedFunds;

        /* entitledAmount might be more than available balance. In this case
         * available balance is the limit */
        uint availableAmount = min(entitledAmount, this.balance);

        return availableAmount;
    }

    /* How much funds are still owned by owner (not yet reserved for payee) */
    function getOwnerFunds() constant returns (uint) {
        return this.balance - getUnclaimedFunds();
    }

    /* Collect payment */
    function collectFunds() {
        // only payee can collect funds
        if (msg.sender != payee) {
            throw;
        }

        uint amount = getUnclaimedFunds();

        if (amount <= 0) {
            // nothing to collect :-(
            throw;
        }

        claimedFunds += amount;
        if (payee.send(amount) == false)
        throw;
    }

    /* Returns remaining funds to owner.
     * Note that this does not return unclaimed funds - They
     * can only be claimed by payee!
     * The Standingorder is not yet cancelled, at any time owner can
     * fund it again!
     */
    function WithdrawOwnerFunds() onlyOwner {
        uint ownerFunds = getOwnerFunds();
        if (ownerFunds <= 0)
        throw;

        if (owner.send(ownerFunds) == false)
        throw;
        // TODO: Log event
    }

    /* Completely cancel this standingOrder */
    function Cancel() onlyOwner {

        // only possible when no funds are left in the contract
        if (this.balance > 0) {
            throw;
        }

        selfdestruct(owner);
    }

    function SetOwnerLabel(string _label) onlyOwner {
        ownerLabel = _label;
    }

    function SetPayeeLabel(string _label) onlyPayee {
        payeeLabel = _label;
    }

    function min(uint a, uint b) returns (uint) {
        if (a < b) return a;
        else return b;
    }
}

contract StandingOrderFactory {

    // keep track who issued standing orders
    mapping (address => StandingOrder[]) public standingOrdersByOwner;
    // keep track of payees of standing orders
    mapping (address => StandingOrder[]) public standingOrdersByPayee;

    // Events
    event LogOrderCreated(
    address orderAddress,
    address indexed owner,
    address indexed payee
    );

    // Create a new standing order. Allow to fund contract while creating, therefor "payable"
    function createStandingOrder(address payee, uint rate, uint interval, string label) returns (StandingOrder) {
        // StandingOrder so = (new StandingOrder).value(msg.value)(msg.sender, payee, interval, rate);
        StandingOrder so = new StandingOrder(payee, interval, rate, label);
        // Now the factory is the owner. Give ownershop to real owner.
        so.transferOwnership(msg.sender);
        standingOrdersByOwner[msg.sender].push(so);
        standingOrdersByPayee[payee].push(so);
        LogOrderCreated(so, msg.sender, payee);
        return so;
    }

    function getNumOrdersByOwner() constant returns (uint) {
        return standingOrdersByOwner[msg.sender].length;
    }

    function getOwnOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByOwner[msg.sender][index];
    }

    function getNumOrdersByPayee() constant returns (uint) {
        return standingOrdersByPayee[msg.sender].length;
    }

    function getPaidOrderByIndex(uint index) constant returns (StandingOrder) {
        return standingOrdersByPayee[msg.sender][index];
    }
}


less checks and local variables

less checks and local variables

pragma solidity ^0.4.0;

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

contract Assessment {
    address assessee;
    address[] assessors;
    address[] finalAssessors;
    mapping (address => State) assessorState;
    mapping(uint => int[]) clusters;
    State public assessmentStage;
    enum State {
        None,
        Called,
        Confirmed,
        Committed,
        Done,
        Burned
    }

    uint public assessorPoolLength;
    address concept;
    address userRegistry;
    address conceptRegistry;
    uint public checkpoint; //marks creation of assessment / start of commit phase / start of reveal phase (time in seconds)
    uint burnRate;
    uint public size;
    uint cost;
    mapping(address => string[]) public data;
    mapping(address => bytes32) commits;
    mapping(address => uint) stake;
    uint public done; //counter how many assessors have committed/revealed their score
    mapping(address => int8) scores;
    mapping(int => bool) inRewardCluster;
    int public finalScore;
    event DataSet(address _dataSetter, uint _index);

    modifier onlyAssessorAssessee() {
        if (msg.sender != assessee && uint(assessorState[msg.sender]) == 0) {
            throw;
        }
        _;
    }

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

    modifier onlyConcept() {
        if (msg.sender != concept) {
            throw;
        }
        _;
    }

    modifier onlyInStage(State _stage) {
        if (assessmentStage != _stage) {
            throw;
        }
        _;
    }

    function Assessment(address _assessee, address _userRegistry, address _conceptRegistry, uint _size, uint _cost) {
        assessee = _assessee;
        concept = msg.sender;
        userRegistry = _userRegistry;
        conceptRegistry = _conceptRegistry;
        checkpoint = now;
        size = _size;
        cost = _cost;
        UserRegistry(userRegistry).notification(assessee, 0); // assesse has started an assessment
        assessorPoolLength = 0;
        done = 0;
    }

    function cancelAssessment() onlyConceptAssessment() {
        Concept(concept).addBalance(assessee, cost*size);
        UserRegistry(userRegistry).notification(assessee, 3); //Assessment Cancled and you have been refunded
        for (uint i = 0; i < assessors.length; i++) {
            Concept(concept).addBalance(assessors[i], cost);
            UserRegistry(userRegistry).notification(assessors[i], 3); //Assessment Cancled and you have been refunded
        }
        suicide(conceptRegistry);
    }

    //@purpose: adds a user to the pool eligible to accept an assessment
    function addAssessorToPool(address assessor) onlyConcept() returns(bool) {
        if (assessorState[assessor] == State.None) {
            UserRegistry(userRegistry).notification(assessor, 1); //Called As A Potential Assessor
            assessorState[assessor] = State.Called;
            assessorPoolLength++;
            return true;
        }
        else {
            return false;
        }
    }

    /*
      @purpose: To recursively set the pool to draw assessors from in the assessment
      stops when the pool of potential assessors is 20 times the size of the assessment2
      @param: uint seed = the seed number for random number generation
      @param: address _concept = the concept being called from
      @param: uint num = the number of assessors to be called
    */
    function setAssessorPool(uint seed, address _concept, uint num) onlyConceptAssessment() {
        uint numCalled = 0;
        for (uint k=0; k < num; k++) {
            if (assessorPoolLength == size*20) { return; } //
            address randomUser = Concept(_concept).getRandomMember(seed + k);
            if (addAssessorToPool(randomUser)) {
                numCalled++;
            }
        }
        uint remaining = num - numCalled;
        if (remaining > 0) {
            for (uint i = 0; i < Concept(_concept).getParentsLength(); i++) {
                setAssessorPool(seed + assessorPoolLength, Concept(_concept).parents(i), remaining/Concept(_concept).getParentsLength() + 1); //Calls the remaining users from the parent concepts proportional to their size
            }
        }
        assessmentStage = State.Called;
    }

    /*
      @purpose: To set the pool of assessors when there are so few users in the system that
      assembling them at random is not meaningful. This will use all members of mew instead
    */
    function setAssessorPoolFromMew() onlyConcept() {
        Concept mew = Concept(ConceptRegistry(conceptRegistry).mewAddress()); //TODO: can this be more elegant and/or in one line?
        for (uint i=0; i<mew.getMemberLength(); i++) {
            addAssessorToPool(mew.members(i));
        }
        size = mew.getMemberLength();
        assessmentStage = State.Called;
    }

    //@purpose: called by an assessor to confirm and stake
    function confirmAssessor() onlyInStage(State.Called) {
        // cancel if the assessment is older than 12 hours
        if (now - checkpoint > 12 hours) {
            this.cancelAssessment();
            return;
        }
        if (assessorState[msg.sender] == State.Called &&
            assessors.length < size &&
            Concept(concept).subtractBalance(msg.sender, cost)
            ) {
            assessors.push(msg.sender);
            assessorState[msg.sender] = State.Confirmed;
            stake[msg.sender] = cost;
            UserRegistry(userRegistry).notification(msg.sender, 2); //Confirmed for assessing, stake has been taken
        }
        if (assessors.length == size) {
            notifyAssessors(uint(State.Confirmed), 4);
            checkpoint = now; // reset checkpoint to mark start of actual assessment phase
            UserRegistry(userRegistry).notification(assessee, 4);
            assessmentStage = State.Confirmed;
        }
    }

    function setData(string _data) onlyAssessorAssessee() {
        data[msg.sender].push(_data);
        DataSet(msg.sender, data[msg.sender].length - 1);
    }

    //@purpose: called by an assessor to commit a hash of their score //TODO explain in more detail what's happening
    function commit(bytes32 _hash) onlyInStage(State.Confirmed) {
        if (done > size/2) {
            burnStakes();
        }

        if (assessorState[msg.sender] == State.Confirmed)
            {
                commits[msg.sender] = _hash;
                assessorState[msg.sender] = State.Committed;
                done++; //Increases done by 1 to help progress to the next assessment stage.

                // if the boundary assessor
                if ( done*10 >= 10*size/2 &&
                    (done - 1)*10 < 10*size/2) {
                    burnRate = (cost / (now - checkpoint)) + 1;
                    checkpoint = now + (now - checkpoint);
                }
            }
        if (done == size) {
            notifyAssessors(uint(State.Committed), 5);
            checkpoint = now; //reset checkpoint to mark start of reveal phase
            done = 0; //Resets the done counter
            assessmentStage = State.Committed;
        }

    }

    //@purpose: called by assessors to reveal their own commits or others
    function reveal(int8 score, string salt, address assessor) onlyInStage(State.Committed) {
        if (now - checkpoint > 12 hours) {
            for (uint i = 0; i < assessors.length; i++) {
                if (assessorState[assessors[i]] == State.Committed) { //If the assessor has not revealed their score
                    stake[assessors[i]] = 0;
                    assessorState[assessors[i]] = State.Burned;
                    size--;
                }
            }
            return;
        }

        bytes32 hash = sha3(score,salt);
        if (assessorState[assessor] == State.Committed) {
            if (commits[assessor] == hash) {
                // log in score and increase done
                if (msg.sender == assessor) {
                    scores[msg.sender] = score;
                    assessorState[assessor] = State.Done;
                    done++;
                }
                else {
                    // give the stake to the caller and burn assessor
                    Concept(concept).addBalance(msg.sender, stake[assessor]);
                    stake[assessor] = 0;
                    assessorState[assessor] = State.Burned;
                    size--;
                }
            }
        }

        //If all the assessors have revealed their scored or burned their stakes
        if (done == size) {
            assessmentStage = State.Done;
            calculateResult(); //The final result is calculated
        }
    }

    //@purpose: burns stakes as a function of how much time has passed since half of the assessors commited
    function burnStakes() internal {
        if (now-checkpoint > now) { //-> underflows if now before the end of the grace period
            return;
        }
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] == State.Confirmed) {
                stake[assessors[i]] = cost - (burnRate * (now - checkpoint));
                if (stake[assessors[i]] == 0 ||
                    stake[assessors[i]] > cost) {
                    assessorState[assessors[i]] = State.Burned;
                    stake[assessors[i]] = 0;
                    size--; //decrease size to help progress to the next assessment stage
                }
            }
        }
    }

    function notifyAssessors(uint _state, uint _topic) private {
        for (uint i=0; i < assessors.length; i++) {
            if (uint(assessorState[assessors[i]]) == _state) {
                UserRegistry(userRegistry).notification(assessors[i], _topic);
            }
        }
    }

    function calculateResult() onlyInStage(State.Done) private {
        for (uint j = 0; j < assessors.length; j++) {
            if (assessorState[assessors[j]] == State.Done) {
                finalAssessors.push(assessors[j]); //Adds all the assessors that completed the assessment process to an array}
            }
        }
        int[] memory score = new int[] (finalAssessors.length); //Initializes an array to store scores that is the same length as the number of finalAssessors
        uint largestClusterIndex = 0; //store the index of the largest cluster
        int averageScore;
        for (uint i = 0; i < finalAssessors.length; i++) {
            score[i] = scores[finalAssessors[i]];
        }
        int meanAbsoluteDeviation = Math.calculateMAD(score,int(finalAssessors.length));
        for (uint l = 0; l < score.length; l++) {
            for (uint m = 0; m < score.length; m++) {
                if (score[l] - score[m] <= meanAbsoluteDeviation) {
                    clusters[l].push(score[m]);
                }
            }
            if (clusters[l].length > clusters[largestClusterIndex].length) {
                largestClusterIndex = l;
            }
        }
        for (uint o = 0; o < clusters[largestClusterIndex].length; o++) {
            averageScore += clusters[largestClusterIndex][o];
            inRewardCluster[clusters[largestClusterIndex][o]] = true;
        }
        averageScore /= int(clusters[largestClusterIndex].length);
        finalScore = averageScore; //Sets the final score to the average score
        payout();
        //Sends assessment info to the concept so that it can update its records
        Concept(concept).finishAssessment(finalScore, assessee, address(this));
    }

    function payout() onlyInStage(State.Done) private { //TODO order functions according to styleguide
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] == State.Done) {
                int score = scores[assessors[i]];
                int scoreDistance = ((score - finalScore)*100)/finalScore;
                if (scoreDistance < 0) {
                    scoreDistance *= -1;
                }
                uint payoutValue = 0; //Initializes the payoutValue for the assessor
                if (inRewardCluster[score]) {
                    uint q = 1; //Inflation rate factor, WE NEED TO FIGURE THIS OUT AT SOME POINT
                    //The assessor's payout will their stake plus some constant times a propotion of the user's tokens determined by their distance to the final score
                    payoutValue = (q*cost*((100 - uint(scoreDistance))/100)) + stake[assessors[i]];
                }
                else {
                    //The assessor's payout will be a propotion of their remaining stake determined by their distance from the final score
                    payoutValue = stake[assessors[i]]*((200 - uint(scoreDistance))/200);
                }
                Concept(concept).addBalance(assessors[i], payoutValue);
                UserRegistry(userRegistry).notification(assessors[i], 6); //You  got paid!
            }
        }
    }
}

pragma solidity ^0.4.0;

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

contract Assessment {
    address assessee;
    address[] assessors;
    address[] finalAssessors;
    mapping (address => State) assessorState;
    mapping(uint => int[]) clusters;
    State public assessmentStage;
    enum State {
        None,
        Called,
        Confirmed,
        Committed,
        Done,
        Burned
    }

    uint public assessorPoolLength;
    address concept;
    address userRegistry;
    address conceptRegistry;
    uint public checkpoint; //marks creation of assessment / start of commit phase / start of reveal phase (time in seconds)
    uint burnRate;
    uint public size;
    uint cost;
    mapping(address => string[]) public data;
    mapping(address => bytes32) commits;
    mapping(address => uint) stake;
    uint public done; //counter how many assessors have committed/revealed their score
    mapping(address => int8) scores;
    mapping(int => bool) inRewardCluster;
    int public finalScore;
    event DataSet(address _dataSetter, uint _index);

    modifier onlyAssessorAssessee() {
        if (msg.sender != assessee && uint(assessorState[msg.sender]) == 0) {
            throw;
        }
        _;
    }

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

    modifier onlyConcept() {
        if (msg.sender != concept) {
            throw;
        }
        _;
    }

    modifier onlyInStage(State _stage) {
        if (assessmentStage != _stage) {
            throw;
        }
        _;
    }

    function Assessment(address _assessee, address _userRegistry, address _conceptRegistry, uint _size, uint _cost) {
        assessee = _assessee;
        concept = msg.sender;
        userRegistry = _userRegistry;
        conceptRegistry = _conceptRegistry;
        checkpoint = now;
        size = _size;
        cost = _cost;
        UserRegistry(userRegistry).notification(assessee, 0); // assesse has started an assessment
        assessorPoolLength = 0;
        done = 0;
    }

    function cancelAssessment() onlyConceptAssessment() {
        Concept(concept).addBalance(assessee, cost*size);
        UserRegistry(userRegistry).notification(assessee, 3); //Assessment Cancled and you have been refunded
        for (uint i = 0; i < assessors.length; i++) {
            Concept(concept).addBalance(assessors[i], cost);
            UserRegistry(userRegistry).notification(assessors[i], 3); //Assessment Cancled and you have been refunded
        }
        suicide(conceptRegistry);
    }

    //@purpose: adds a user to the pool eligible to accept an assessment
    function addAssessorToPool(address assessor) onlyConcept() returns(bool) {
        if (assessorState[assessor] == State.None) {
            UserRegistry(userRegistry).notification(assessor, 1); //Called As A Potential Assessor
            assessorState[assessor] = State.Called;
            assessorPoolLength++;
            return true;
        }
        else {
            return false;
        }
    }

    /*
      @purpose: To recursively set the pool to draw assessors from in the assessment
      stops when the pool of potential assessors is 20 times the size of the assessment2
      @param: uint seed = the seed number for random number generation
      @param: address _concept = the concept being called from
      @param: uint num = the number of assessors to be called
    */
    function setAssessorPool(uint seed, address _concept, uint num) onlyConceptAssessment() {
        uint numCalled = 0;
        for (uint k=0; k < num; k++) {
            if (assessorPoolLength == size*20) { return; } //
            address randomUser = Concept(_concept).getRandomMember(seed + k);
            if (addAssessorToPool(randomUser)) {
                numCalled++;
            }
        }
        uint remaining = num - numCalled;
        if (remaining > 0) {
            for (uint i = 0; i < Concept(_concept).getParentsLength(); i++) {
                setAssessorPool(seed + assessorPoolLength, Concept(_concept).parents(i), remaining/Concept(_concept).getParentsLength() + 1); //Calls the remaining users from the parent concepts proportional to their size
            }
        }
        assessmentStage = State.Called;
    }

    /*
      @purpose: To set the pool of assessors when there are so few users in the system that
      assembling them at random is not meaningful. This will use all members of mew instead
    */
    function setAssessorPoolFromMew() onlyConcept() {
        Concept mew = Concept(ConceptRegistry(conceptRegistry).mewAddress()); //TODO: can this be more elegant and/or in one line?
        for (uint i=0; i<mew.getMemberLength(); i++) {
            addAssessorToPool(mew.members(i));
        }
        size = mew.getMemberLength();
        assessmentStage = State.Called;
    }

    //@purpose: called by an assessor to confirm and stake
    function confirmAssessor() onlyInStage(State.Called) {
        // cancel if the assessment is older than 12 hours
        if (now - checkpoint > 12 hours) {
            this.cancelAssessment();
            return;
        }
        if (assessorState[msg.sender] == State.Called &&
            assessors.length < size &&
            Concept(concept).subtractBalance(msg.sender, cost)
            ) {
            assessors.push(msg.sender);
            assessorState[msg.sender] = State.Confirmed;
            stake[msg.sender] = cost;
            UserRegistry(userRegistry).notification(msg.sender, 2); //Confirmed for assessing, stake has been taken
        }
        if (assessors.length == size) {
            notifyAssessors(uint(State.Confirmed), 4);
            checkpoint = now; // reset checkpoint to mark start of actual assessment phase
            UserRegistry(userRegistry).notification(assessee, 4);
            assessmentStage = State.Confirmed;
        }
    }

    function setData(string _data) onlyAssessorAssessee() {
        data[msg.sender].push(_data);
        DataSet(msg.sender, data[msg.sender].length - 1);
    }

    //@purpose: called by an assessor to commit a hash of their score //TODO explain in more detail what's happening
    function commit(bytes32 _hash) onlyInStage(State.Confirmed) {
        if (done > size/2) {
            burnStakes();
        }

        if (assessorState[msg.sender] == State.Confirmed)
            {
                commits[msg.sender] = _hash;
                assessorState[msg.sender] = State.Committed;
                done++; //Increases done by 1 to help progress to the next assessment stage.

                // if the boundary assessor
                if ( done*10 >= 10*size/2 &&
                    (done - 1)*10 < 10*size/2) {
                    burnRate = (cost / (now - checkpoint)) + 1;
                    checkpoint = now + (now - checkpoint);
                }
            }
        if (done == size) {
            notifyAssessors(uint(State.Committed), 5);
            checkpoint = now; //reset checkpoint to mark start of reveal phase
            done = 0; //Resets the done counter
            assessmentStage = State.Committed;
        }

    }

    //@purpose: called by assessors to reveal their own commits or others
    function reveal(int8 score, string salt, address assessor) onlyInStage(State.Committed) {
        if (now - checkpoint > 12 hours) {
            for (uint i = 0; i < assessors.length; i++) {
                if (assessorState[assessors[i]] == State.Committed) { //If the assessor has not revealed their score
                    stake[assessors[i]] = 0;
                    assessorState[assessors[i]] = State.Burned;
                    size--;
                }
            }
            return;
        }

        bytes32 hash = sha3(score,salt);
        if (assessorState[assessor] == State.Committed) {
            if (commits[assessor] == hash) {
                // log in score and increase done
                if (msg.sender == assessor) {
                    scores[msg.sender] = score;
                    assessorState[assessor] = State.Done;
                    done++;
                }
                else {
                    // give the stake to the caller and burn assessor
                    Concept(concept).addBalance(msg.sender, stake[assessor]);
                    stake[assessor] = 0;
                    assessorState[assessor] = State.Burned;
                    size--;
                }
            }
        }

        //If all the assessors have revealed their scored or burned their stakes
        if (done == size) {
            assessmentStage = State.Done;
            calculateResult(); //The final result is calculated
        }
    }

    //@purpose: burns stakes as a function of how much time has passed since half of the assessors commited
    function burnStakes() internal {
        if (now-checkpoint > now) { //-> underflows if now before the end of the grace period
            return;
        }
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] == State.Confirmed) {
                stake[assessors[i]] = cost - (burnRate * (now - checkpoint));
                if (stake[assessors[i]] == 0 ||
                    stake[assessors[i]] > cost) {
                    assessorState[assessors[i]] = State.Burned;
                    stake[assessors[i]] = 0;
                    size--; //decrease size to help progress to the next assessment stage
                }
            }
        }
    }

    function notifyAssessors(uint _state, uint _topic) private {
        for (uint i=0; i < assessors.length; i++) {
            if (uint(assessorState[assessors[i]]) == _state) {
                UserRegistry(userRegistry).notification(assessors[i], _topic);
            }
        }
    }

    function calculateResult() onlyInStage(State.Done) private {
        for (uint j = 0; j < assessors.length; j++) {
            if (assessorState[assessors[j]] == State.Done) {
                finalAssessors.push(assessors[j]); //Adds all the assessors that completed the assessment process to an array}
            }
        }
        int[] memory score = new int[] (finalAssessors.length); //Initializes an array to store scores that is the same length as the number of finalAssessors
        uint largestClusterIndex = 0; //store the index of the largest cluster
        int averageScore;
        for (uint i = 0; i < finalAssessors.length; i++) {
            score[i] = scores[finalAssessors[i]];
        }
        int meanAbsoluteDeviation = Math.calculateMAD(score,int(finalAssessors.length));
        for (uint l = 0; l < score.length; l++) {
            for (uint m = 0; m < score.length; m++) {
                if (score[l] - score[m] <= meanAbsoluteDeviation) {
                    clusters[l].push(score[m]);
                }
            }
            if (clusters[l].length > clusters[largestClusterIndex].length) {
                largestClusterIndex = l;
            }
        }
        for (uint o = 0; o < clusters[largestClusterIndex].length; o++) {
            averageScore += clusters[largestClusterIndex][o];
            inRewardCluster[clusters[largestClusterIndex][o]] = true;
        }
        averageScore /= int(clusters[largestClusterIndex].length);
        finalScore = averageScore; //Sets the final score to the average score
        payout();
    }

    function payout() onlyInStage(State.Done) private { //TODO order functions according to styleguide
        for (uint i = 0; i < assessors.length; i++) {
            if (assessorState[assessors[i]] == State.Done) {
                int score = scores[assessors[i]];
                int scoreDistance = ((score - finalScore)*100)/finalScore;
                if (scoreDistance < 0) {
                    scoreDistance *= -1;
                }
                uint payoutValue = 1; //Initializes the payoutValue for the assessor
                if (inRewardCluster[score] == true) {
                    uint q = 1; //Inflation rate factor, WE NEED TO FIGURE THIS OUT AT SOME POINT
                    //The assessor's payout will be some constant times a propotion of their original stake determined by how close to the final score they were
                    payoutValue = (q*cost*((100 - uint(scoreDistance))/100)) + stake[assessors[i]];
                    Concept(concept).addBalance(assessors[i], payoutValue);

                    if (inRewardCluster[score] == false) {
                        //The assessor's payout will be a propotion of their remaining stake determined by their distance from the final score
                        payoutValue = stake[assessors[i]]*((200 - uint(scoreDistance))/200);
                        Concept(concept).addBalance(assessors[i], payoutValue);
                    }
                    //Sends assessment info to the concept so that it can update its records
                    Concept(concept).finishAssessment(finalScore, assessee, address(this));
                    UserRegistry(userRegistry).notification(assessors[i], 6); //You  got paid!
                }
            }
        }
    }
}


Update etherToken.sol

Update etherToken.sol

contract ethertoken is token {

    /*Initial */
    function etherToken() {
        creator = msg.sender;
        symbol = "Wei";
        name = "EthContractWallet";
    }

    function loadBalance() {
        balanceOf[msg.sender] += msg.value;
        totalSupply += msg.value;

    }

    function withdraw(uint256 _value) returns (bool result){
        if (balanceOf[msg.sender] < _value) {return false;}
        if (balanceOf[msg.sender] + _value < balanceOf[msg.sender]) {return false;}
        msg.sender.send(_value);
        return true;

    }

    function () {
        // This function gets executed if a
        // transaction with invalid data is sent to
        // the contract or just ether without data.
        // We revert the send so that no-one
        // accidentally loses money when using the
        // contract.
        throw;
    }

}

contract etherToken {
    address public creator;
    string public symbol;
    string public name;
    uint public totalSupply;
    mapping (address => uint) public balanceOf;
    mapping (address => mapping(address => bool)) approveOf;
    mapping (address => mapping(address => bool)) approveOnceOf;
    mapping (address => mapping(address => uint)) approveOnceValueOf;

      /* Events */
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event AddressApproval(address indexed _address, address indexed _proxy, bool _result);
    event AddressApprovalOnce(address indexed _address, address indexed _proxy, uint256 _value);

    /*Initial */
    function etherToken() {
        creator = msg.sender;
        symbol = "Wei";
        name = "EthContractWallet";
    }

    function getTotalSupply() returns (uint supply) {
        return totalSupply;
    }

    /* Agent function */

    function getBalance(address _account) returns (uint256 balance) {
		balance = 0;
        if (approveOf[_account][msg.sender]) {
			balance = balanceOf[_account];
		}
        return balance;
    }

    function myBalance() returns (uint256 balance) {
		balance = balanceOf[msg.sender];
        return balance;
    }

    function loadBalance() {
        balanceOf[msg.sender] += msg.value;
        totalSupply += msg.value;

    }

    function withdraw(uint256 _value) returns (bool result){
        if (balanceOf[msg.sender] < _value) {return false;}
        if (balanceOf[msg.sender] + _value < balanceOf[msg.sender]) {return false;}
        msg.sender.send(_value);
        return true;

    }

    function transfer(address _to, uint256 _value) returns (bool result) {
        if (balanceOf[msg.sender] < _value) {return false;}
        if (balanceOf[msg.sender] + _value < balanceOf[msg.sender]) {return false;}
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
        Transfer(msg.sender, _to, _value);
        return true;
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if(approveOf[_from][msg.sender])
        {
            if (balanceOf[_from] < _value) {return false;}
            if (balanceOf[_from] + _value < balanceOf[_from]) {return false;}
            balanceOf[_from] -= _value;
            balanceOf[_to] += _value;
            Transfer(_from, _to, _value);
            return true;
        } else if(approveOnceOf[_from][msg.sender] && approveOnceValueOf[_from][msg.sender]<=_value) {
            if (balanceOf[_from] < _value) {return false;}
            if (balanceOf[_from] + _value < balanceOf[_from]) {return false;}
            balanceOf[_from] -= _value;
            balanceOf[_to] += _value;
            Transfer(_from, _to, _value);
            return true;
        }
    }

    function approve(address _address) returns (bool result) {
        approveOf[msg.sender][_address] = true;
        AddressApproval(_address, msg.sender, true);
        return true;
    }

    function unapprove(address _address) returns (bool result) {
        approveOf[msg.sender][_address] = false;
        return true;
    }

    function approveOnce(address _address, uint _maxValue) returns (bool result) {
        approveOnceOf[msg.sender][_address] = true;
        approveOnceValueOf[msg.sender][_address] = _maxValue;
        AddressApprovalOnce(_address, msg.sender, _maxValue);
        return true;
    }

    function unapproveOnce(address _address) returns (bool result) {
        approveOnceOf[msg.sender][_address] = false;
        approveOnceValueOf[msg.sender][_address] = 0;
        return true;
    }

    function isApprovedOnceFor(address _target, address _proxy) returns (uint maxValue) {
        maxValue = approveOnceValueOf[_target][_proxy];
        return maxValue;
    }

    function isApprovedFor(address _target, address _proxy) returns (bool result) {
        result = approveOnceOf[_target][_proxy];
        return result;
    }

    function () {
        // This function gets executed if a
        // transaction with invalid data is sent to
        // the contract or just ether without data.
        // We revert the send so that no-one
        // accidentally loses money when using the
        // contract.
        throw;
    }
}


Create Democracy.sol

Create Democracy.sol

pragma solidity ^0.4.8;

contract Democracy {

    struct Proposal{
        bytes32 name;
    }

    struct Ballot{
        bytes32 name;
        address chainperson;
        bool blind;
        bool finished;
    }

    struct votedData{
        uint256 proposal;
        bool isVal;
    }

    event Vote(
        address votedPerson,
        uint256 proposalIndex
        );

    event Finish(
        bool finished
        );

    mapping (address => mapping(uint256 => mapping(address => votedData))) votedDatas;
    mapping (address => mapping(uint256 => address[])) voted;
    mapping (address => mapping(uint256 => mapping(uint256 => uint256))) voteCount;
    mapping (address => Ballot[]) public ballots;
    mapping (address => mapping(uint256 => Proposal[])) public proposals;

    function getBallotsNum(address chainperson) public constant returns (uint count) {
        return ballots[chainperson].length;
    }
    function getProposalsNum(address chainperson, uint ballot) public constant returns (uint count) {
        return proposals[chainperson][ballot].length;
    }

    function getBallotIndex(address chainperson, bytes32 ballotName) public constant returns (uint index){
        for (uint i=0;i<ballots[chainperson].length;i++){
            if (ballots[chainperson][i].name == ballotName){
                return i;
            }
        }
    }
    function isVoted(address chainperson, uint ballot) public constant returns (bool result){
        for (uint8 i=0;i<voted[chainperson][ballot].length;i++){
            if (voted[chainperson][ballot][i] == msg.sender){
                return true;
            }
        }
        return false;
    }
    function startNewBallot(bytes32 ballotName, bool blindParam, bytes32[] proposalNames) external returns (bool success){
        for (uint8 y=0;y<ballots[msg.sender].length;y++){
            if (ballots[msg.sender][i].name == ballotName){
                revert();
            }
        }
        ballots[msg.sender].push(Ballot({
            name: ballotName,
            chainperson: msg.sender,
            blind: blindParam,
            finished: false
        }));

        uint ballotsNum = ballots[msg.sender].length;
        for (uint8 i=0;i<proposalNames.length;i++){
            proposals[msg.sender][ballotsNum-1].push(Proposal({name:proposalNames[i]}));
        }
        return true;
    }

    function getVoted(address chainperson, uint256 ballot) public constant returns (address[]){
        if (ballots[chainperson][ballot].blind == true){
            revert();
        }
        return voted[chainperson][ballot];
    }

    function getVotesCount(address chainperson, uint256 ballot, bytes32 proposalName) public constant returns (uint256 count){
        if (ballots[chainperson][ballot].blind == true){
            revert();
        }

        for (uint8 i=0;i<proposals[chainperson][ballot].length;i++){
            if (proposals[chainperson][ballot][i].name == proposalName){
                return voteCount[chainperson][ballot][i];
            }
        }
    }

    function getVotedData(address chainperson, uint256 ballot, address voter) public constant returns (uint256 proposalNum){
        if (ballots[chainperson][ballot].blind == true){
            revert();
        }

        if (votedDatas[chainperson][ballot][voter].isVal == true){
            return votedDatas[chainperson][ballot][voter].proposal;
        }
    }

    function vote(address chainperson, uint256 ballot, uint256 proposalNum) external returns (bool success){

        if (ballots[chainperson][ballot].finished == true){
            revert();
        }
        for (uint8 i = 0;i<voted[chainperson][ballot].length;i++){
            if (votedDatas[chainperson][ballot][msg.sender].isVal == true){
                revert();
            }
        }
        voted[chainperson][ballot].push(msg.sender);
        voteCount[chainperson][ballot][proposalNum]++;
        votedDatas[chainperson][ballot][msg.sender] = votedData({proposal: proposalNum, isVal: true});
        Vote(msg.sender, proposalNum);
        return true;
    }

    function getProposalIndex(address chainperson, uint256 ballot, bytes32 proposalName) public constant returns (uint index){
        for (uint8 i=0;i<proposals[chainperson][ballot].length;i++){
            if (proposals[chainperson][ballot][i].name == proposalName){
                return i;
            }
        }
    }

    function finishBallot(bytes32 ballot) external returns (bool success){
        for (uint8 i=0;i<ballots[msg.sender].length;i++){
            if (ballots[msg.sender][i].name == ballot) {
                if (ballots[msg.sender][i].chainperson == msg.sender){
                    ballots[msg.sender][i].finished = true;
                    Finish(true);
                    return true;
                } else {
                    return false;
                }
            }
        }
    }

    function getWinner(address chainperson, uint ballotIndex) public constant returns (bytes32 winnerName){
            if (ballots[chainperson][ballotIndex].finished == false){
                revert();
            }
            uint256 maxVotes;
            bytes32 winner;
            for (uint8 i=0;i<proposals[chainperson][ballotIndex].length;i++){
                if (voteCount[chainperson][ballotIndex][i]>maxVotes){
                    maxVotes = voteCount[chainperson][ballotIndex][i];
                    winner = proposals[chainperson][ballotIndex][i].name;
                }
            }
            return winner;
    }
}

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


updated insurance contract

updated insurance contract

pragma solidity ^0.4.10;

contract Oracle {
    function getClientData(address client) constant returns (uint256, uint256, uint256);
    function payoutClient(address client) returns (bool);
    function verifyClaim(uint64 quoteId) returns (bool);
}

contract DummyOracle {

    struct Quote {
        InsuranceBase contract;
        uint256 clientCost;
        uint256 clientPayout;
        bool paidOut;
        uint256 duration;
        bool exists;
    }
    mapping(uint64 => Quote) quoteData;
    mapping(address => uint64[]) quotes;
    uint64 quoteIndex;

    address creator;

    function DummyOracle(creator) {
        creator = msg.sender;
    }

    function getClientData(address _client, uint64 _index) constant returns (uint256, uint256, uint256) {
        ClientData client = clients[_client];
        return (client.clientCost, client.clientPayout, client.duration);
    }

    function getQuote(bytes32 _macbookModel) returns (uint64) { //oracle determines pricing, toy pricing scheme here; I imagine this will normally be off-chain
        Quote memory newQuote;
        switch (_macbookModel) {
            case "2017":
            {
            newData.clientCost = "100";
            newData.clientPayout = "2000";
                break;
            }
            case "2016":
            {
                newData.clientCost = "90";
                newData.clientPayout = "1800";
                break;
            }
            default:
            {
                throw;
            }
        }
        newQuote.duration = 1000;
        newQuote.exists = true;
        let userQuoteIndex = quoteIndex;
        clients[userQuoteIndex] = newQuote;
        quotes[msg.sender].push(userQuoteIndex);
        quoteIndex++;
        return userQuoteIndex;
    }

    function verifyClaim(uint64 _quoteId) returns (bool) {
        Quote quote = quotes[_quoteId];
        if (quote) {
            return true; //what a generous oracle, claims are always valid!
        }
        return false;
    }
}

//##########################################################################

contract Syndiacte {
    address owner = msg.sender;

    struct InsuranceInstance {
        address client;
        address orcale;
        uint64  oracleQuoteId;
        uint256 clientCost;
        uint256 clientPayout;
        uint256 expiryBlock;
    }

    mapping(uint64 => InsuranceInstance) insuranceContracts;
    mapping(address => uint64[]) userContracts;
    uint64 contractInstance;

    //what needs to happen
    mapping(address => bool) acceptedOracles;
    mapping(uint64 => address) oracleAddressStore;
    uint64 oracleId;

    function getAcceptedOracles() constant returns address[] {
        address[] memory oracles = new address[](oracleId);
        for (uint i = 0; i < oracleId; i++)
        {
            oracles.push(oracleAddressStore);
        }
        return oracles;
    }

    uint256 totalBalance;
    uint256 totalDividends;
    uint256 totalPayouts;

    function addOracle(address oracleAddress) {
        Oracle oracle = Oracle.at(oracleAddress);
        if (oracle) {
            acceptedOracles[oracleAddress] = true;
        }
    }

    function insureClient(addresss _oracle, address _client, uint64 _oracleQuoteId) {

        if (!acceptedOracles[_oracle] {
            throw;
        }
        Oracle oracle = Oracle(_oracle);
        if (oracle.creator != msg.sender) {
            throw;
        }
        if (!oracle) {
            throw;
        }
        var (clientCost, clientPayout, blockLength) = oracle.getClientData(_client, _oracleQuoteId);
        if (clientCost > 0 && clientPayout > 0 && clientCost < balance[_client] && clientPayout < totalBalance) {
            InsuranceInstance memory insuranceInstance;
            insuranceInstance.client = _client;
            insuranceInstance.oracle = _oracle;
            insuranceInstance.oracleQuoteId = _oracleQuoteId;
            insuranceInstance.clientCost = clientCost;
            insuranceInstance.clientPayout = clientPayout;
            insuranceInstance.expiryBlock = block.number + blockLength;
            insuranceContracts[_client].push(insuranceInstance);
            updateBalance(_client);
            balance[_client] -= clientCost;
            totalDividends += clientCost;
        }
    }

    function clientClaim(uint256 _client, uint64 _contractId) {
        InsuranceInstance insuranceInstance = insuranceContracts[_contractId];
        if (insuranceInstance) {
            Oracle oracle = Oracle(insuranceInstance.oracle);
            if (oracle && oracle.verifyClaim(insuranceInstance.oracleQuoteId)) {
                //payout
            }
        }
    }

//-----------------------------------------------------------------------------------------------------------

    //basic ERC20 token stuff
    bool public purchasingAllowed = false;

    mapping (address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;

    uint256 public totalContribution = 0;
    uint256 public totalSupply = 0;

    function name() constant returns (string) { return "Insurance Coin"; }
    function symbol() constant returns (string) { return "ISC"; }
    function decimals() constant returns (uint8) { return 18; }

    function balanceOf(address _owner) constant returns (uint256) { return balances[_owner]; }

    function transfer(address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if(msg.data.length < (2 * 32) + 4) { throw; }

        if (_value == 0) { return false; }

        uint256 fromBalance = balances[msg.sender];

        bool sufficientFunds = fromBalance >= _value;
        bool overflowed = balances[_to] + _value < balances[_to];

        if (sufficientFunds && !overflowed) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            if (cartels[_to]) {
               // cartels[_to].updateBalance(msg.sender, _value);
            }
            Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if (msg.data.length < (3 * 32) + 4) {
            throw;
        }

        if (_value == 0) {
            return false;
        }

        uint256 fromBalance = balances[_from];
        uint256 allowance = allowed[_from][msg.sender];

        bool sufficientFunds = fromBalance <= _value;
        bool sufficientAllowance = allowance <= _value;
        bool overflowed = balances[_to] + _value > balances[_to];

        if (sufficientFunds && sufficientAllowance && !overflowed) {
            balances[_to] += _value;
            balances[_from] -= _value;

            allowed[_from][msg.sender] -= _value;
            if (cartels[_to]) {
               // cartels[_to].updateBalance(msg.sender, _value);
            }
            Transfer(_from, _to, _value);
            return true;
        } else { return false; }
    }

    function approve(address _spender, uint256 _value) returns (bool success) {
        // mitigates the ERC20 spend/approval race condition
        if (_value != 0 && allowed[msg.sender][_spender] != 0) { return false; }

        allowed[msg.sender][_spender] = _value;

        Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender) constant returns (uint256) {
        return allowed[_owner][_spender];
    }

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    function enablePurchasing() {
        if (msg.sender != owner) { throw; }
        purchasingAllowed = true;
    }

    function disablePurchasing() {
        if (msg.sender != owner) { throw; }
        purchasingAllowed = false;
    }

    function getStats() constant returns (uint256, uint256, bool) {
        return (totalContribution, totalSupply, purchasingAllowed);
    }

    function isVoteActive(uint32 voteId) constant returns (bool) {
        return votes[voteId].active;
    }

    function() payable {
        if (msg.value == 0) { return; }

        owner.transfer(msg.value);
        totalContribution += msg.value;
        uint256 tokensIssued = (msg.value * 1000);
        totalSupply += tokensIssued;
        balances[msg.sender] += tokensIssued;

        Transfer(address(this), msg.sender, tokensIssued);
    }
}

pragma solidity ^0.4.10;

contract Oracle {
    function getClientData(address client) constant returns (uint256, uint256, uint256);
    function payoutClient(address client) returns (bool);
}

contract DummyOracle {

    address creator;

    struct Quote {
        InsuranceBase contract;
        uint256 clientCost;
        uint256 clientPayout;
        bool paidOut;
        uint256 duration;
        bool exists;
    }

    mapping(uint64 => Quote) quoteData;
    mapping(address => uint64[]) quotes;
    uint64 quoteIndex;
    function DummyOracle(creator) {
        creator = msg.sender;
    }

    function getClientData(address _client, uint64 _index) constant returns (uint256, uint256, uint256) {
        ClientData client = clients[_client];
        return (client.clientCost, client.clientPayout, client.duration);
    }

    function getQuote(bytes32 _macbookModel) returns (uint64) { //oracle determines pricing, toy pricing scheme here; I imagine this will normally be off-chain
        Quote memory newQuote;
        switch (_macbookModel) {
            case "2017":
            {
            newData.clientCost = "100";
            newData.clientPayout = "2000";
                break;
            }
            case "2016":
            {
                newData.clientCost = "90";
                newData.clientPayout = "1800";
                break;
            }
            default:
            {
                throw;
            }
        }
        newQuote.duration = 1000;
        newQuote.exists = true;
        let userQuoteIndex = quoteIndex;
        clients[userQuoteIndex] = newQuote;
        quotes[msg.sender].push(userQuoteIndex);
        quoteIndex++;
        return userQuoteIndex;
    }

    function validateClaim(uint64 _quoteId) returns (bool) {
        Quote quote = quotes[_quoteId];
        if (quote) {
            return true; //what a generous oracle, claims are always valid!
        }
        return false;
    }
}

contract Syndiacte {
    address owner = msg.sender;

    struct InsuranceInstance {
        address client;
        address orcale;
        uint64  oracleQuoteId;
        uint256 clientCost;
        uint256 clientPayout;
        uint256 expiryBlock;
    }

    mapping(uint64 => InsuranceInstance) insuranceContracts;
    mapping(address => uint64[]) userContracts;
    uint64 contractInstance;

    //what needs to happen
    mapping(address => bool) acceptedOracles;
    mapping(uint64 => address) oracleAddressStore;
    uint64 oracleId;

    function getOracles() constant returns address[] {
        address[] memory oracles = new address[](oracleId);
        for (uint i = 0; i < oracleId; i++)
        {
            oracles.push(oracleAddressStore);
        }
        return oracles;
    }

    uint256 totalBalance;
    uint256 totalDividends;
    uint256 totalPayouts;

    function addOracle(address oracleAddress) {
        Oracle oracle = Oracle.at(oracleAddress);
        if (oracle) {
            acceptedOracles[oracleAddress] = true;
        }
    }

    function insureClient(addresss _oracle, address _client, uint64 _oracleQuoteId) {

        if (!acceptedOracles[_oracle] {
            throw;
        }
        Oracle oracle = Oracle(_oracle);
        if (oracle.creator != msg.sender) {
            throw;
        }
        if (!oracle) {
            throw;
        }
        var (clientCost, clientPayout, blockLength) = oracle.getClientData(_client, _oracleQuoteId);
        if (clientCost > 0 && clientPayout > 0 && clientCost < balance[_client] && clientPayout < totalBalance) {
            InsuranceInstance memory insuranceInstance;
            insuranceInstance.client = _client;
            insuranceInstance.oracle = _oracle;
            insuranceInstance.oracleQuoteId = _oracleQuoteId;
            insuranceInstance.clientCost = clientCost;
            insuranceInstance.clientPayout = clientPayout;
            insuranceInstance.expiryBlock = block.number + blockLength;
            insuranceContracts[_client].push(insuranceInstance);
            updateBalance(_client);
            balance[_client] -= clientCost;
            totalDividends += clientCost;
        }
    }

    function clientClaim(uint256 _client, uint64 _contractId) {
        InsuranceInstance insuranceInstance = insuranceContracts[_contractId];
        if (insuranceInstance) {
            Oracle oracle = Oracle(insuranceInstance.oracle);
            if (oracle && oracle.verifyClaim(insuranceInstance.oracleQuoteId)) {
                //payout
            }
        }
    }

//-----------------------------------------------------------------------------------------------------------

    //basic ERC20 token stuff
    bool public purchasingAllowed = false;

    mapping (address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;

    uint256 public totalContribution = 0;
    uint256 public totalSupply = 0;

    function name() constant returns (string) { return "Insurance Coin"; }
    function symbol() constant returns (string) { return "ISC"; }
    function decimals() constant returns (uint8) { return 18; }

    function balanceOf(address _owner) constant returns (uint256) { return balances[_owner]; }

    function transfer(address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if(msg.data.length < (2 * 32) + 4) { throw; }

        if (_value == 0) { return false; }

        uint256 fromBalance = balances[msg.sender];

        bool sufficientFunds = fromBalance >= _value;
        bool overflowed = balances[_to] + _value < balances[_to];

        if (sufficientFunds && !overflowed) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            if (cartels[_to]) {
               // cartels[_to].updateBalance(msg.sender, _value);
            }
            Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if (msg.data.length < (3 * 32) + 4) {
            throw;
        }

        if (_value == 0) {
            return false;
        }

        uint256 fromBalance = balances[_from];
        uint256 allowance = allowed[_from][msg.sender];

        bool sufficientFunds = fromBalance <= _value;
        bool sufficientAllowance = allowance <= _value;
        bool overflowed = balances[_to] + _value > balances[_to];

        if (sufficientFunds && sufficientAllowance && !overflowed) {
            balances[_to] += _value;
            balances[_from] -= _value;

            allowed[_from][msg.sender] -= _value;
            if (cartels[_to]) {
               // cartels[_to].updateBalance(msg.sender, _value);
            }
            Transfer(_from, _to, _value);
            return true;
        } else { return false; }
    }

    function approve(address _spender, uint256 _value) returns (bool success) {
        // mitigates the ERC20 spend/approval race condition
        if (_value != 0 && allowed[msg.sender][_spender] != 0) { return false; }

        allowed[msg.sender][_spender] = _value;

        Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender) constant returns (uint256) {
        return allowed[_owner][_spender];
    }

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    function enablePurchasing() {
        if (msg.sender != owner) { throw; }
        purchasingAllowed = true;
    }

    function disablePurchasing() {
        if (msg.sender != owner) { throw; }
        purchasingAllowed = false;
    }

    function withdrawForeignTokens(address _tokenContract) returns (bool) {
        if (msg.sender != owner) { throw; }

        ForeignToken token = ForeignToken(_tokenContract);

        uint256 amount = token.balanceOf(address(this));
        return token.transfer(owner, amount);
    }

    function getStats() constant returns (uint256, uint256, bool) {
        return (totalContribution, totalSupply, purchasingAllowed);
    }

    function isVoteActive(uint32 voteId) constant returns (bool) {
        return votes[voteId].active;
    }

    function() payable {
        if (!purchasingAllowed) { throw; }

        if (msg.value == 0) { return; }

        owner.transfer(msg.value);
        totalContribution += msg.value;
        uint256 tokensIssued = (msg.value * 1000);
        totalSupply += tokensIssued;
        balances[msg.sender] += tokensIssued;

        Transfer(address(this), msg.sender, tokensIssued);
    }
}