fix msg.sender in refactored functions issue

pragma solidity ^0.4.11;
import "./StandardToken.sol";
import "./PLCRVoting.sol";

// to do:
// implement events
// deposit
// token flooring issue

contract Registry {

    /*
     * Storage
     */

    //Registry storage
    StandardToken public token;
    PLCRVoting public voting;
    mapping(bytes32 => Publisher) public whitelist; //domainHash => Publisher struct
    mapping(bytes32 => Application) public appPool; //holds applications for both domain and parameter appPool
    mapping(bytes32 => Params) public paramSnapshots;
    mapping(uint => VoteInfo) public pollInfo; // holds information on individual polls
    mapping(address => mapping(uint => bool)) public voterInfo; // holds information on voters' token claims
    string domain;
    //Parameter storage
    mapping(bytes32 => uint) public Parameters;
    mapping(uint => bytes32) public idToHash;
    string parameter;
    uint value;

    struct Publisher {
        address owner;
        uint expTime;
        uint deposit;
    }

    struct Application {
        address owner;
        bool challenged;
        uint challengeTime; //End of challenge period
        address challenger;

        string domain;
        string parameter;
        uint value;
    }

    struct Params {
        // parameters concerning the whitelist and application pool
        uint minDeposit;
        uint challengeLen;
        uint registryLen;

        // parameters to be passed into the voting contract
        uint commitVoteLen;
        uint revealVoteLen;
        uint majority;

        // parameter representing the scale of how token rewards are distributed
        uint dispensationPct;
    }

    struct VoteInfo {
        // if the vote has been processed
        bool processed;
        // amount of leftover tokens available for winning party to claim
        // (a byproduct of needing to floor the distributed tokens to voters)
        uint remainder;
    }

    // Constructor
    /// @param _minDeposit      application & challenger deposit amounts
    /// @param _challengeLen    duration of the challenge period
    /// @param _registryLen     duration of a registration’s validity
    /// @param _commitVoteLen   duration of the commit period in token votes
    /// @param _revealVoteLen   duration of reveal period in token votes
    /// @param _dispensationPct percentage of forfeited deposit distributed to winning party; uint between 0 and 100
    /// @param _majority        percentage of votes that constitutes the majority; uint between 0 and 100

    function Registry(address _token,
       uint _minDeposit,
       uint _challengeLen,
       uint _registryLen,
       uint _commitVoteLen,
       uint _revealVoteLen,
       uint _dispensationPct,
       uint _majority) {

       token = StandardToken(_token);
       // initialize values
       Parameters[sha3("minDeposit")]        = _minDeposit;
       Parameters[sha3("challengeLen")]      = _challengeLen;
       Parameters[sha3("registryLen")]       = _registryLen;
       Parameters[sha3("commitVoteLen")]     = _commitVoteLen;
       Parameters[sha3("revealVoteLen")]     = _revealVoteLen;
       Parameters[sha3("dispensationPct")]   = _dispensationPct;
       Parameters[sha3("majority")]          = _majority;
    }

    // called by an applicant to apply (moves them into the application pool on success)
    function apply(string _domain) {
        bytes32 domainHash = sha3(_domain);
        // initialize with the current values of all parameters
        initializeSnapshot(_domain);
        initApplication(domainHash, msg.sender);
        appPool[domainHash].domain = _domain;
    }

    //helper function to apply() and proposeUpdate()
    //initialize general application
    function initApplication(bytes32 _hash, address _applicant) {
        // applicant must pay the current value of minDeposit
        uint deposit = paramSnapshots[_hash].minDeposit;
        // check to prevent repeat applications
        require(appPool[_hash].owner == 0);
        // check that registry can take sufficient amount of tokens from the applicant
        require(token.allowance(_applicant, this) >= deposit);
        token.transferFrom(_applicant, this, deposit);
        appPool[_hash].challengeTime = now + paramSnapshots[_hash].challengeLen;
        appPool[_hash].owner = msg.sender;
    }

    function renew (string _domain) {
        bytes32 domainHash = sha3(_domain);
        require(msg.sender == whitelist[domainHash].owner );
        if (whitelist[domainHash].deposit >= get(minDeposit)){
            apply(_domain);
        }
        else {
            //emit event need to send in more money, then the person
            //has to take back deposit then re-apply
        }
    }

    function claimDeposit(string _domain){
        bytes32 domainHash = sha3(_domain);
        require(msg.sender == whitelist[domainHash].owner );
        require(now >= whitelist[domainHash].expTime);
        require(whitelist[domainHash].deposit > 0);
        token.transfer(msg.sender,whitelist[domainHash].deposit);
        whitelist[domainHash].deposit = 0;
    }

    // called by any adtoken holder to challenge an application to the whitelist
    // initialize vote to accept/reject a domain to the registry
    function challengeApplication(string _domain) {
        bytes32 domainHash = sha3(_domain);
        challenge(domainHash);
        // start a vote
        uint pollID = callVote(_domain
        ,paramSnapshots[domainHash].majority
        ,paramSnapshots[domainHash].commitVoteLen
        ,paramSnapshots[domainHash].revealVoteLen);
        idToHash[pollID] = domainHash;
    }

    //helper function to challengeApplication() and challengeProposal()
    function challenge(bytes32 _hash) {
        // check that registry can take sufficient amount of tokens from the challenger
        uint deposit = paramSnapshots[_hash].minDeposit;
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);

        // prevent someone from challenging an unintialized application, rechallenging,
        // or challenging after the challenge period has ended
        require(appPool[_hash].owner != 0);
        require(appPool[_hash].challenged == false);
        require(appPool[_hash].challengeTime > now);

        // update the application's status
        appPool[_hash].challenged = true;
        appPool[_hash].challenger = msg.sender;
    }

    // helper function to the challenge() function. Initializes a vote through the voting contract
    // returns a poll id
    function callVote(string _proposalString,
        uint _majority,
        uint _commitVoteLen,
        uint _revealVoteLen
        ) private returns (uint) {
        // event that vote has started
        uint pollID = voting.startPoll( _proposalString, _majority, _commitVoteLen,  _revealVoteLen);
        return pollID;
    }

    // a one-time function for each completed vote
    // if domain won: domain is moved to the whitelist and applicant is rewarded tokens
    // if domain lost: challenger is rewarded tokens
    function processResult(uint _pollID)
    {
        require(pollInfo[_pollID].processed == false);
        bytes32 domainHash = idToHash[_pollID];

        if (voting.isPassed(_pollID)) {
            //??what would happen if didProposalPass() called and vote's still ongoing??
            // add to registry
            add(domainHash, appPool[domainHash].owner);
            delete appPool[domainHash].owner;
            // give tokens to applicant based on dist and total tokens
        }
        else {
            delete appPool[domainHash].owner;
            uint minDeposit = paramSnapshots[domainHash].minDeposit;
            uint dispensationPct = paramSnapshots[domainHash].dispensationPct;
            uint winning = minDeposit * dispensationPct;  // change math to be int between 0-100
            token.transfer(appPool[domainHash].challenger, winning + minDeposit);
        }
        // ensures the result cannot be processed again
        pollInfo[_pollID].processed = true;
    }

    // called by each voter to claim their reward for each completed vote
    function claimReward(uint _pollID, uint _salt) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        uint reward = giveTokens(_pollID, _salt);
        // ensures a voter cannot claim tokens again
        token.transfer(msg.sender, reward);
        voterInfo[msg.sender][_pollID] = true;
    }

    // number of tokens person used to vote / total number of tokens for winning side
    // scale using distribution number, give the tokens
    function giveTokens(uint _pollID, uint _salt) private returns(uint) {
        bytes32 hash = idToHash[_pollID];
        uint minDeposit = paramSnapshots[hash].minDeposit;
        uint dispensationPct = paramSnapshots[hash].dispensationPct;
        uint totalTokens = voting.getTotalNumberOfTokensForWinningOption(_pollID);
        uint voterTokens = voting.getNumCorrectVote(_pollID, _salt);
        uint reward = voterTokens*minDeposit*(1-dispensationPct)/totalTokens;

        // check if there will be leftover from flooring, add into a pool claimable by winner
        // (to prevent token locking due to flooring of voter rewards)
        // uint modCheck = voterTokens % ;
        // uint purchaseAmount = msg.value - excessAmount;
        // uint tokenPurchase = purchaseAmount / price;

        return reward;
    }

    // called to move an applying domain to the whitelist
    // iff the domain's challenge period has passed without a challenge
    function moveToRegistry(string _domain) {
        bytes32 domainHash = sha3(_domain);
        require(appPool[domainHash].challengeTime < now);
        require(appPool[domainHash].challenged == false);
        // prevents moving a domain to the registry without ever applying
        require(appPool[domainHash].owner != 0);
        // prevent applicant from moving to registry multiple times
        add(domainHash, appPool[domainHash].owner);
        delete appPool[domainHash].owner;
    }

    // private function to add a domain name to the whitelist
    function add(bytes32 _domainHash, address _owner) private {
        uint expiration = paramSnapshots[_domainHash].registryLen;
        whitelist[_domainHash].expTime = now + expiration;
        whitelist[_domainHash].owner = _owner;
        whitelist[_domainHash].deposit = paramSnapshots[_domainHash].minDeposit;
    }

    // checks if a domain name is in the whitelist and unexpired
    function isVerified(string _domain) returns (bool) {
        bytes32 domainHash = sha3(_domain);
        if (whitelist[domainHash].expTime > now) {
            return true;
        }
        else {
            return false;
        }
    }

    // private function to initialize a snapshot of parameters for each application
    function initializeSnapshot(string _domain) private {
        bytes32 domainHash = sha3(_domain);
        initializeSnapshotParam(domainHash);  // maybe put the two together
        paramSnapshots[domainHash].registryLen = get("registryLen");
    }

/*****************************************************************************/

    //called by a user who wishes to change a parameter
    //initializes a proposal to change a parameter
    function proposeUpdate(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);
        // initialize application with a with the current values of all parameters
        initializeSnapshotParam(parameterHash);
        initApplication(parameterHash, msg.sender);
        appPool[parameterHash].parameter = _parameter;
        appPool[parameterHash].value = _value;
    }

    //called by user who wishes to reject a proposal
    //initializes a vote to accept/reject the param change proposal
    function challengeProposal(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);
        challenge(parameterHash);
        // start a vote
        uint pollID = callVote(_parameter
        ,paramSnapshots[parameterHash].majority
        ,paramSnapshots[parameterHash].commitVoteLen
        ,paramSnapshots[parameterHash].revealVoteLen);
        idToHash[pollID] = parameterHash;
    }

    // called to change parameter
    // iff the proposal's challenge period has passed without a challenge
    function setParams(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);
        require(appPool[parameterHash].challengeTime < now);
        require(appPool[parameterHash].challenged == false);
        // prevents moving a domain to the registry without ever applying
        require(appPool[parameterHash].owner != 0);
        // prevent applicant from moving to registry multiple times
        Parameters[sha3(_parameter)] = _value;
        delete appPool[parameterHash].owner;
    }

    // a one-time function for each completed vote
    // if proposal won: new parameter value is set, and applicant is rewarded tokens
    // if prospsal lost: challenger is rewarded tokens
    function processProposal(uint _pollID)
    {
        require(pollInfo[_pollID].processed == false);
        bytes32 parameterHash = idToHash[_pollID];
        parameter = appPool[parameterHash].parameter;
        value = appPool[parameterHash].value;
        if (voting.isPassed(_pollID)) {
            // setting the value of parameter
            Parameters[sha3(parameter)] = value;
            delete appPool[parameterHash].owner;
            // give tokens to applicant based on dist and total tokens IMPLEMENT
        }
        else {
            delete appPool[parameterHash].owner;
            // give tokens to challenger based on dist and total tokens
        }
        // ensures the result cannot be processed again
        pollInfo[_pollID].processed = true;
    }

    function claimParamReward(uint _pollID, uint _salt) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        uint reward = giveTokens(_pollID, _salt);
        // ensures a voter cannot claim tokens again
        token.transfer(msg.sender, reward);
        voterInfo[msg.sender][_pollID] = true;
    }

     // private function to initialize a snapshot of parameters for each proposal
     function initializeSnapshotParam(bytes32 _hash) private {
        paramSnapshots[_hash].minDeposit = get("minDeposit");
        paramSnapshots[_hash].challengeLen = get("challengeLen");
        paramSnapshots[_hash].commitVoteLen = get("commitVoteLen");
        paramSnapshots[_hash].revealVoteLen = get("revealVoteLen");
        paramSnapshots[_hash].majority = get("majority");
        paramSnapshots[_hash].dispensationPct = get("dispensationPct");
    }

    // interface for retrieving config parameter from hashmapping
    /// @param _keyword key for hashmap (only useful when keyword matches variable name)
    function get(string _keyword) returns (uint) {
       return Parameters[sha3(_keyword)];
    }

/*****************************************************************************/

    // FOR TESTING
    function toHash(string _domain) returns (bytes32){
        return sha3(_domain);
    }
    function getCurrentTime() returns (uint){
        return now;
    }

}

pragma solidity ^0.4.11;
import "./StandardToken.sol";
import "./PLCRVoting.sol";

// to do:
// implement events
// deposit
// token flooring issue

contract Registry {

    /*
     * Storage
     */

    //Registry storage
    StandardToken public token;
    PLCRVoting public voting;
    mapping(bytes32 => Publisher) public whitelist; //domainHash => Publisher struct
    mapping(bytes32 => Application) public appPool; //holds applications for both domain and parameter appPool
    mapping(bytes32 => Params) public paramSnapshots;
    mapping(uint => VoteInfo) public pollInfo; // holds information on individual polls
    mapping(address => mapping(uint => bool)) public voterInfo; // holds information on voters' token claims
    string domain;
    //Parameter storage
    mapping(bytes32 => uint) public Parameters;
    mapping(uint => bytes32) public idToHash;
    string parameter;
    uint value;

    struct Publisher {
        address owner;
        uint expTime;
        uint deposit;
    }

    struct Application {
        address owner;
        bool challenged;
        uint challengeTime; //End of challenge period
        address challenger;

        string domain;
        string parameter;
        uint value;
    }

    struct Params {
        // parameters concerning the whitelist and application pool
        uint minDeposit;
        uint challengeLen;
        uint registryLen;

        // parameters to be passed into the voting contract
        uint commitVoteLen;
        uint revealVoteLen;
        uint majority;

        // parameter representing the scale of how token rewards are distributed
        uint dispensationPct;
    }

    struct VoteInfo {
        // if the vote has been processed
        bool processed;
        // amount of leftover tokens available for winning party to claim
        // (a byproduct of needing to floor the distributed tokens to voters)
        uint remainder;
    }

    // Constructor
    /// @param _minDeposit      application & challenger deposit amounts
    /// @param _challengeLen    duration of the challenge period
    /// @param _registryLen     duration of a registration’s validity
    /// @param _commitVoteLen   duration of the commit period in token votes
    /// @param _revealVoteLen   duration of reveal period in token votes
    /// @param _dispensationPct percentage of forfeited deposit distributed to winning party; uint between 0 and 100
    /// @param _majority        percentage of votes that constitutes the majority; uint between 0 and 100

    function Registry(address _token,
       uint _minDeposit,
       uint _challengeLen,
       uint _registryLen,
       uint _commitVoteLen,
       uint _revealVoteLen,
       uint _dispensationPct,
       uint _majority) {

       token = StandardToken(_token);
       // initialize values
       Parameters[sha3("minDeposit")]        = _minDeposit;
       Parameters[sha3("challengeLen")]      = _challengeLen;
       Parameters[sha3("registryLen")]       = _registryLen;
       Parameters[sha3("commitVoteLen")]     = _commitVoteLen;
       Parameters[sha3("revealVoteLen")]     = _revealVoteLen;
       Parameters[sha3("dispensationPct")]   = _dispensationPct;
       Parameters[sha3("majority")]          = _majority;
    }

    // called by an applicant to apply (moves them into the application pool on success)
    function apply(string _domain) {
        bytes32 domainHash = sha3(_domain);
        // initialize with the current values of all parameters
        initializeSnapshot(_domain);
        initApplication(domainHash);
        appPool[domainHash].domain = _domain;
    }

    //helper function to apply() and proposeUpdate()
    //initialize general application
    function initApplication(bytes32 _hash) {
        // applicant must pay the current value of minDeposit
        uint deposit = paramSnapshots[_hash].minDeposit;
        // check to prevent repeat applications
        require(appPool[_hash].owner == 0);
        // check that registry can take sufficient amount of tokens from the applicant
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);
        appPool[_hash].challengeTime = now + paramSnapshots[_hash].challengeLen;
        appPool[_hash].owner = msg.sender;
    }

    // called by any adtoken holder to challenge an application to the whitelist
    // initialize vote to accept/reject a domain to the registry
    function challengeApplication(string _domain) {
        bytes32 domainHash = sha3(_domain);
        challenge(domainHash);
        // start a vote
        uint pollID = callVote(_domain
        ,paramSnapshots[domainHash].majority
        ,paramSnapshots[domainHash].commitVoteLen
        ,paramSnapshots[domainHash].revealVoteLen);
        idToHash[pollID] = domainHash;
    }

    //helper function to challengeApplication() and challengeProposal()
    function challenge(bytes32 _hash) {
        // check that registry can take sufficient amount of tokens from the challenger
        uint deposit = paramSnapshots[_hash].minDeposit;
        require(token.allowance(msg.sender, this) >= deposit);
        token.transferFrom(msg.sender, this, deposit);

        // prevent someone from challenging an unintialized application, rechallenging,
        // or challenging after the challenge period has ended
        require(appPool[_hash].owner != 0);
        require(appPool[_hash].challenged == false);
        require(appPool[_hash].challengeTime > now);

        // update the application's status
        appPool[_hash].challenged = true;
        appPool[_hash].challenger = msg.sender;
    }

    // helper function to the challenge() function. Initializes a vote through the voting contract
    // returns a poll id
    function callVote(string _proposalString,
        uint _majority,
        uint _commitVoteLen,
        uint _revealVoteLen
        ) private returns (uint) {
        // event that vote has started
        uint pollID = voting.startPoll( _proposalString, _majority, _commitVoteLen,  _revealVoteLen);
        return pollID;
    }

    // a one-time function for each completed vote
    // if domain won: domain is moved to the whitelist and applicant is rewarded tokens
    // if domain lost: challenger is rewarded tokens
    function processResult(uint _pollID)
    {
        require(pollInfo[_pollID].processed == false);
        bytes32 domainHash = idToHash[_pollID];

        if (voting.isPassed(_pollID)) {
            //??what would happen if didProposalPass() called and vote's still ongoing??
            // add to registry
            add(domainHash, appPool[domainHash].owner);
            delete appPool[domainHash].owner;
            // give tokens to applicant based on dist and total tokens
        }
        else {
            delete appPool[domainHash].owner;
            uint minDeposit = paramSnapshots[domainHash].minDeposit;
            uint dispensationPct = paramSnapshots[domainHash].dispensationPct;
            uint winning = minDeposit * dispensationPct;  // change math to be int between 0-100
            token.transfer(appPool[domainHash].challenger, winning + minDeposit);
        }
        // ensures the result cannot be processed again
        pollInfo[_pollID].processed = true;
    }

    // called by each voter to claim their reward for each completed vote
    function claimReward(uint _pollID, uint _salt) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        uint reward = giveTokens(_pollID, _salt);
        // ensures a voter cannot claim tokens again
        token.transfer(msg.sender, reward);
        voterInfo[msg.sender][_pollID] = true;
    }

    // number of tokens person used to vote / total number of tokens for winning side
    // scale using distribution number, give the tokens
    function giveTokens(uint _pollID, uint _salt) private returns(uint) {
        bytes32 hash = idToHash[_pollID];
        uint minDeposit = paramSnapshots[hash].minDeposit;
        uint dispensationPct = paramSnapshots[hash].dispensationPct;
        uint totalTokens = voting.getTotalNumberOfTokensForWinningOption(_pollID);
        uint voterTokens = voting.getNumCorrectVote(_pollID, _salt);
        uint reward = voterTokens*minDeposit*(1-dispensationPct)/totalTokens;

        // check if there will be leftover from flooring, add into a pool claimable by winner
        // (to prevent token locking due to flooring of voter rewards)
        // uint modCheck = voterTokens % ;
        // uint purchaseAmount = msg.value - excessAmount;
        // uint tokenPurchase = purchaseAmount / price;

        return reward;
    }

    // called to move an applying domain to the whitelist
    // iff the domain's challenge period has passed without a challenge
    function moveToRegistry(string _domain) {
        bytes32 domainHash = sha3(_domain);
        require(appPool[domainHash].challengeTime < now);
        require(appPool[domainHash].challenged == false);
        // prevents moving a domain to the registry without ever applying
        require(appPool[domainHash].owner != 0);
        // prevent applicant from moving to registry multiple times
        add(domainHash, appPool[domainHash].owner);
        delete appPool[domainHash].owner;
    }

    // private function to add a domain name to the whitelist
    function add(bytes32 _domainHash, address _owner) private {
        uint expiration = paramSnapshots[_domainHash].registryLen;
        whitelist[_domainHash].expTime = now + expiration;
        whitelist[_domainHash].owner = _owner;
        whitelist[_domainHash].deposit = paramSnapshots[_domainHash].minDeposit;
    }

    // checks if a domain name is in the whitelist and unexpired
    function isVerified(string _domain) returns (bool) {
        bytes32 domainHash = sha3(_domain);
        if (whitelist[domainHash].expTime > now) {
            return true;
        }
        else {
            return false;
        }
    }

    // private function to initialize a snapshot of parameters for each application
    function initializeSnapshot(string _domain) private {
        bytes32 domainHash = sha3(_domain);
        initializeSnapshotParam(domainHash);  // maybe put the two together
        paramSnapshots[domainHash].registryLen = get("registryLen");
    }

/*****************************************************************************/

    //called by a user who wishes to change a parameter
    //initializes a proposal to change a parameter
    function proposeUpdate(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);
        // initialize application with a with the current values of all parameters
        initializeSnapshotParam(parameterHash);
        initApplication(parameterHash);
        appPool[parameterHash].parameter = _parameter;
        appPool[parameterHash].value = _value;
    }

    //called by user who wishes to reject a proposal
    //initializes a vote to accept/reject the param change proposal
    function challengeProposal(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);
        challenge(parameterHash);
        // start a vote
        uint pollID = callVote(_parameter
        ,paramSnapshots[parameterHash].majority
        ,paramSnapshots[parameterHash].commitVoteLen
        ,paramSnapshots[parameterHash].revealVoteLen);
        idToHash[pollID] = parameterHash;
    }

    // called to change parameter
    // iff the proposal's challenge period has passed without a challenge
    function setParams(string _parameter, uint _value) {
        bytes32 parameterHash = sha3(_parameter, _value);
        require(appPool[parameterHash].challengeTime < now);
        require(appPool[parameterHash].challenged == false);
        // prevents moving a domain to the registry without ever applying
        require(appPool[parameterHash].owner != 0);
        // prevent applicant from moving to registry multiple times
        Parameters[sha3(_parameter)] = _value;
        delete appPool[parameterHash].owner;
    }

    // a one-time function for each completed vote
    // if proposal won: new parameter value is set, and applicant is rewarded tokens
    // if prospsal lost: challenger is rewarded tokens
    function processProposal(uint _pollID)
    {
        require(pollInfo[_pollID].processed == false);
        bytes32 parameterHash = idToHash[_pollID];
        parameter = appPool[parameterHash].parameter;
        value = appPool[parameterHash].value;
        if (voting.isPassed(_pollID)) {
            // setting the value of parameter
            Parameters[sha3(parameter)] = value;
            delete appPool[parameterHash].owner;
            // give tokens to applicant based on dist and total tokens IMPLEMENT
        }
        else {
            delete appPool[parameterHash].owner;
            // give tokens to challenger based on dist and total tokens
        }
        // ensures the result cannot be processed again
        pollInfo[_pollID].processed = true;
    }

    function claimParamReward(uint _pollID, uint _salt) {
        // checks if a voter has claimed tokens
        require(voterInfo[msg.sender][_pollID] == false);
        uint reward = giveTokens(_pollID, _salt);
        // ensures a voter cannot claim tokens again
        token.transfer(msg.sender, reward);
        voterInfo[msg.sender][_pollID] = true;
    }

     // private function to initialize a snapshot of parameters for each proposal
     function initializeSnapshotParam(bytes32 _hash) private {
        paramSnapshots[_hash].minDeposit = get("minDeposit");
        paramSnapshots[_hash].challengeLen = get("challengeLen");
        paramSnapshots[_hash].commitVoteLen = get("commitVoteLen");
        paramSnapshots[_hash].revealVoteLen = get("revealVoteLen");
        paramSnapshots[_hash].majority = get("majority");
        paramSnapshots[_hash].dispensationPct = get("dispensationPct");
    }

    // interface for retrieving config parameter from hashmapping
    /// @param _keyword key for hashmap (only useful when keyword matches variable name)
    function get(string _keyword) returns (uint) {
       return Parameters[sha3(_keyword)];
    }

/*****************************************************************************/

    // FOR TESTING
    function toHash(string _domain) returns (bytes32){
        return sha3(_domain);
    }
    function getCurrentTime() returns (uint){
        return now;
    }

}


killable formatting

killable formatting

pragma solidity ^0.4.4;

import "./Ownable.sol";

/*
 * Killable
 * Base contract that can be killed by owner. All funds in contract will be sent to the owner.
 */
contract Killable is Ownable {
  function kill() onlyOwner {
    selfdestruct(owner);
  }
}


Fixing solidity warnings

Fixing solidity warnings

pragma solidity ^0.4.24;

import "./ConvertLib.sol";

// This is just a simple example of a coin-like contract.
// It is not standards compatible and cannot be expected to talk to other
// coin/token contracts. If you want to create a standards-compliant
// token, see: https://github.com/ConsenSys/Tokens. Cheers!

contract MetaCoin {
	mapping (address => uint) balances;

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

	constructor() public {
		balances[tx.origin] = 10000;
	}

	function sendCoin(address receiver, uint amount) public returns(bool sufficient) {
		if (balances[msg.sender] < amount) return false;
		balances[msg.sender] -= amount;
		balances[receiver] += amount;
		emit Transfer(msg.sender, receiver, amount);
		return true;
	}

	function getBalanceInEth(address addr) public view returns(uint){
		return ConvertLib.convert(getBalance(addr),2);
	}

	function getBalance(address addr) public view returns(uint) {
		return balances[addr];
	}
}

pragma solidity ^0.4.16;

import "./ConvertLib.sol";

// This is just a simple example of a coin-like contract.
// It is not standards compatible and cannot be expected to talk to other
// coin/token contracts. If you want to create a standards-compliant
// token, see: https://github.com/ConsenSys/Tokens. Cheers!

contract MetaCoin {
	mapping (address => uint) balances;

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

	function MetaCoin() public {
		balances[tx.origin] = 10000;
	}

	function sendCoin(address receiver, uint amount) public returns(bool sufficient) {
		if (balances[msg.sender] < amount) return false;
		balances[msg.sender] -= amount;
		balances[receiver] += amount;
		Transfer(msg.sender, receiver, amount);
		return true;
	}

	function getBalanceInEth(address addr) public view returns(uint){
		return ConvertLib.convert(getBalance(addr),2);
	}

	function getBalance(address addr) public view returns(uint) {
		return balances[addr];
	}
}


require(pot.loser == 0); // need this?

require(pot.loser == 0); // need this?

pragma solidity ^0.4.11;
contract PotOfGold {

    struct Pot {
        string name;
        uint buyIn;

        address[] players;

        uint lastPlayerBlockNumber; // uint8(uint256(sha3(block.blockhash(lastPlayerBlockNumber+1)))) % 3 == loser index

        address loser;
    }

    address public owner;

    Pot[] allPots;
    mapping(string => Pot) nameToPot;

    event newPot(string name, uint buyIn, address creator);
    event potJoin(string name, address newPlayer);
    event potExpired(string name);
    event potClosed(string name, address loser);

    function PotOfGold() {
        owner = msg.sender;
    }

    function ownerWithdraw(){
        require(msg.sender == owner);

        int toWithdraw = int(this.balance - 100 finney); // leave 0.1 ether for gas (?)
        require(toWithdraw > 0);

        owner.transfer(uint(toWithdraw));
    }

    function createPot(string name) payable {
        require(msg.value > 0); // must bet something
        require(bytes(name).length > 0); // name mustn't be empty
        require(nameToPot[name].buyIn == 0); // there isn't already a pot with this name

        Pot pot = nameToPot[name];
        pot.name = name;
        pot.buyIn = msg.value;
        pot.players.push(msg.sender);

        allPots.push(pot);

        newPot(name, msg.value, msg.sender);
    }

    function joinPot(string name) payable {
        Pot pot = nameToPot[name];
        require(pot.buyIn > 0); // pot exists
        require(pot.loser == 0); // pot isn't over
        require(pot.players.length < 3); // pot isn't full
        require(msg.value == pot.buyIn); // must pay buyIn amount

        pot.players.push(msg.sender);
        if(pot.players.length == 3){
           pot.lastPlayerBlockNumber = block.number;
        }

        potJoin(name, msg.sender);
    }

    /*function leavePot(string name) {
        Pot pot = nameToPot[name];
        if(pot.buyIn == 0) throw; // no pot
        if(pot.loser != 0) throw; // pot is over
        if(pot.players.length == 3) throw; // pot is full but waiting for a loser

        if(pot.players[0] != msg.sender && pot.players[1] != msg.sender) throw; // no such player in pot

        address[] newPlayers;
        for(uint i = 0; i < pot.players.length; i++){
            if(pot.players[i] != msg.sender){
                newPlayers.push(pot.players[i]);
            }
        }

        pot.players = newPlayers;

        msg.sender.transfer((pot.buyIn * 99) / 100); // leaving fee 1%
    }*/

    function solvePot(string name){
        Pot pot = nameToPot[name];
        require(pot.loser == 0); // pot isn't over
        require(pot.players.length == 3); // pot full
        require(block.number > pot.lastPlayerBlockNumber);

        bytes32 blockHash = block.blockhash(pot.lastPlayerBlockNumber + 1);
        if(blockHash == 0) { // pot expired due to hash storage limits - players didn't solve pot
            require(pot.loser == 0); // need this?
            pot.loser = msg.sender; // doesn't matter, everybody loses a fee

            for(uint i = 0; i < pot.players.length; i++){
                pot.players[i].transfer((pot.buyIn * 99) / 100); // return money minus 1% fee
            }

            potExpired(name);
            return;
        }

        bytes32 potShaResult = sha3(msg.sender, blockHash);
        uint8 loserIndex = uint8(uint256(potShaResult) % 3);

        require(pot.loser == 0); // need this?
        pot.loser = pot.players[loserIndex];

        address winner1 = pot.players[(loserIndex + 1) % 3];
        address winner2 = pot.players[(loserIndex + 2) % 3];

        uint winAmount = ((pot.buyIn / 2) * 99) / 100;
        uint returnAmount = pot.buyIn + winAmount;

        winner1.transfer(returnAmount);
        winner2.transfer(returnAmount);

        potClosed(name, pot.loser);
    }
}

pragma solidity ^0.4.11;
contract PotOfGold {

    struct Pot {
        string name;
        uint buyIn;

        address[] players;

        uint lastPlayerBlockNumber; // uint8(uint256(sha3(block.blockhash(lastPlayerBlockNumber+1)))) % 3 == loser index

        address loser;
    }

    address public owner;

    Pot[] allPots;
    mapping(string => Pot) nameToPot;

    event newPot(string name, uint buyIn, address creator);
    event potJoin(string name, address newPlayer);
    event potExpired(string name);
    event potClosed(string name, address loser);

    function PotOfGold() {
        owner = msg.sender;
    }

    function ownerWithdraw(){
        require(msg.sender == owner);

        int toWithdraw = int(this.balance - 100 finney); // leave 0.1 ether for gas (?)
        require(toWithdraw > 0);

        owner.transfer(uint(toWithdraw));
    }

    function createPot(string name) payable {
        require(msg.value > 0); // must bet something
        require(bytes(name).length > 0); // name mustn't be empty
        require(nameToPot[name].buyIn == 0); // there isn't already a pot with this name

        Pot pot = nameToPot[name];
        pot.name = name;
        pot.buyIn = msg.value;
        pot.players.push(msg.sender);

        allPots.push(pot);

        newPot(name, msg.value, msg.sender);
    }

    function joinPot(string name) payable {
        Pot pot = nameToPot[name];
        require(pot.buyIn > 0); // pot exists
        require(pot.loser == 0); // pot isn't over
        require(pot.players.length < 3); // pot isn't full
        require(msg.value == pot.buyIn); // must pay buyIn amount

        pot.players.push(msg.sender);
        if(pot.players.length == 3){
           pot.lastPlayerBlockNumber = block.number;
        }

        potJoin(name, msg.sender);
    }

    /*function leavePot(string name) {
        Pot pot = nameToPot[name];
        if(pot.buyIn == 0) throw; // no pot
        if(pot.loser != 0) throw; // pot is over
        if(pot.players.length == 3) throw; // pot is full but waiting for a loser

        if(pot.players[0] != msg.sender && pot.players[1] != msg.sender) throw; // no such player in pot

        address[] newPlayers;
        for(uint i = 0; i < pot.players.length; i++){
            if(pot.players[i] != msg.sender){
                newPlayers.push(pot.players[i]);
            }
        }

        pot.players = newPlayers;

        msg.sender.transfer((pot.buyIn * 99) / 100); // leaving fee 1%
    }*/

    function solvePot(string name){
        Pot pot = nameToPot[name];
        require(pot.loser == 0); // pot isn't over
        require(pot.players.length == 3); // pot full
        require(block.number > pot.lastPlayerBlockNumber);

        bytes32 blockHash = block.blockhash(pot.lastPlayerBlockNumber + 1);
        if(blockHash == 0) { // pot expired due to hash storage limits - players didn't solve pot
            pot.loser = msg.sender; // doesn't matter, everybody loses a fee

            for(uint i = 0; i < pot.players.length; i++){
                pot.players[i].transfer((pot.buyIn * 99) / 100); // return money minus 1% fee
            }

            potExpired(name);
            return;
        }

        bytes32 potShaResult = sha3(msg.sender, blockHash);
        uint8 loserIndex = uint8(uint256(potShaResult) % 3);

        pot.loser = pot.players[loserIndex];

        address winner1 = pot.players[(loserIndex + 1) % 3];
        address winner2 = pot.players[(loserIndex + 2) % 3];

        uint winAmount = ((pot.buyIn / 2) * 99) / 100;
        uint returnAmount = pot.buyIn + winAmount;

        winner1.transfer(returnAmount);
        winner2.transfer(returnAmount);

        potClosed(name, pot.loser);
    }
}


updated comments

updated comments

pragma solidity ^0.4.10;
import './ERC20Token.sol';

/*
    Ether tokenization contract
*/
contract EtherToken is ERC20Token {
    function EtherToken()
        ERC20Token('Ether Token', 'ETH') {
    }

    // deposit ether in the account
    function deposit() public payable returns (bool success) {
        assert(balanceOf[msg.sender] + msg.value >= balanceOf[msg.sender]); // overflow protection
        balanceOf[msg.sender] += msg.value;
        return true;
    }

    // withdraw ether from the account
    function withdraw(uint256 _amount) public returns (bool success) {
        require(_amount <= balanceOf[msg.sender]); // balance check

        // deduct the amount from the account balance
        balanceOf[msg.sender] -= _amount;
        // send the amount
        assert(msg.sender.send(_amount));
        return true;
    }

    // deposit ether in the account - identical to deposit function
    function() public payable {
        assert(balanceOf[msg.sender] + msg.value >= balanceOf[msg.sender]); // overflow protection
        balanceOf[msg.sender] += msg.value;
    }
}

pragma solidity ^0.4.10;
import './ERC20Token.sol';

/*
    Open issues:
    - throw vs. return value?
*/

contract EtherToken is ERC20Token {
    function EtherToken()
        ERC20Token('Ether Token', 'ETH') {
    }

    // deposit ether in the account
    function deposit() public payable returns (bool success) {
        assert(balanceOf[msg.sender] + msg.value >= balanceOf[msg.sender]); // overflow protection
        balanceOf[msg.sender] += msg.value;
        return true;
    }

    // withdraw ether from the account
    function withdraw(uint256 _amount) public returns (bool success) {
        require(_amount <= balanceOf[msg.sender]); // balance check

        // deduct the amount from the account balance
        balanceOf[msg.sender] -= _amount;
        // send the amount
        assert(msg.sender.send(_amount));
        return true;
    }

    // deposit ether in the account - identical to deposit function
    function() public payable {
        assert(balanceOf[msg.sender] + msg.value >= balanceOf[msg.sender]); // overflow protection
        balanceOf[msg.sender] += msg.value;
    }
}


Fix some minor contract bugs

Fix some minor contract bugs

pragma solidity ^0.4.11;

contract Token {
    uint256 public totalSupply;
    function balanceOf(address _owner) constant returns (uint256 balance);
    function transfer(address _to, uint256 _value) returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
    function approve(address _spender, uint256 _value) returns (bool success);
    function allowance(address _owner, address _spender) constant returns (uint256 remaining);
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

contract StandardToken is Token {
    function transfer(address _to, uint256 _value) returns (bool success) {
        if (balances[msg.sender] >= _value && _value > 0) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        } else {
            return false;
        }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) {
            balances[_to] += _value;
            balances[_from] -= _value;
            allowed[_from][msg.sender] -= _value;
            Transfer(_from, _to, _value);
            return true;
        } else {
            return false;
        }
    }

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

    function approve(address _spender, uint256 _value) returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }

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

    mapping (address => uint256) balances;

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

contract Eclipse is StandardToken {
    uint8 public decimals = 18;
    string public name = 'Eclipse';
    address owner;
    string public symbol = 'ECL';

    uint startTime = 1503330410; // Aug 21, 2017 at 15:46:50 UTC
    uint endTime = 1503349461; // Aug 21, 2017 at 21:04:21 UTC

    uint METERS_IN_ASTRONOMICAL_UNIT = 149597870700;
    uint MILES_IN_ASTRONOMICAL_UNIT = 92955807;

    uint TOTAL_SUPPLY_CAP = METERS_IN_ASTRONOMICAL_UNIT * 1 ether;
    uint TOKENS_PER_ETH = MILES_IN_ASTRONOMICAL_UNIT;

    function () payable {
        // revert if solar eclipse has not started
        if (now < startTime) revert();

        // revert if TOTAL_SUPPLY_CAP has been exhausted
        if (totalSupply >= TOTAL_SUPPLY_CAP) revert();

        uint tokensIssued;

        if (now > endTime) {
            // transfer remaining supply to owner
            tokensIssued = TOTAL_SUPPLY_CAP - totalSupply;
            totalSupply = TOTAL_SUPPLY_CAP;
            balances[owner] += tokensIssued;
            Transfer(address(this), owner, tokensIssued);

            // refund sender
            msg.sender.transfer(msg.value);
        } else {
            // Send ETH to owner
            owner.transfer(msg.value);

            // Send tokens to contributor
            tokensIssued = msg.value * TOKENS_PER_ETH;

            if (totalSupply + tokensIssued > TOTAL_SUPPLY_CAP) {
                tokensIssued = TOTAL_SUPPLY_CAP - totalSupply;
            }

            totalSupply += tokensIssued;
            balances[msg.sender] += tokensIssued;
            Transfer(address(this), msg.sender, tokensIssued);
        }
    }

    function Eclipse() {
        owner = msg.sender;
        totalSupply = 0;
    }
}

pragma solidity ^0.4.15;

contract Token {
    uint256 public totalSupply;
    function balanceOf(address _owner) constant returns (uint256 balance);
    function transfer(address _to, uint256 _value) returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) returns (bool success);
    function approve(address _spender, uint256 _value) returns (bool success);
    function allowance(address _owner, address _spender) constant returns (uint256 remaining);
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

contract StandardToken is Token {
    function transfer(address _to, uint256 _value) returns (bool success) {
        if (balances[msg.sender] >= _value && _value > 0) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        } else {
            return false;
        }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) {
            balances[_to] += _value;
            balances[_from] -= _value;
            allowed[_from][msg.sender] -= _value;
            Transfer(_from, _to, _value);
            return true;
        } else {
            return false;
        }
    }

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

    function approve(address _spender, uint256 _value) returns (bool success) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }

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

    mapping (address => uint256) balances;

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

contract Eclipse is StandardToken {
    uint8 public decimals = 18;
    string public name = 'Eclipse';
    address owner;
    string public symbol = 'ECL';

    uint startTime = 1503330410; // Aug 21, 2017 at 15:46:50 UTC
    uint endTime = 1503349461; // Aug 21, 2017 at 21:04:21 UTC

    uint METERS_IN_ASTRONOMICAL_UNIT = 149597870700;
    uint MILES_IN_ASTRONOMICAL_UNIT = 92955807;

    uint TOTAL_SUPPLY_CAP = METERS_IN_ASTRONOMICAL_UNIT;
    uint TOKENS_PER_ETH = MILES_IN_ASTRONOMICAL_UNIT;

    function () payable {
        // revert if solar eclipse has not started
        if (now < startTime) revert();

        // revert if TOTAL_SUPPLY_CAP has been exhausted
        if (totalSupply >= TOTAL_SUPPLY_CAP) revert();

        uint tokensIssued;

        if (now > endTime) {
            // transfer remaining supply to owner
            tokensIssued = TOTAL_SUPPLY_CAP - totalSupply;
            balances[owner] += tokensIssued;
            totalSupply = TOTAL_SUPPLY_CAP;
        } else {
            // Send ETH to owner
            owner.transfer(msg.value);

            // Send tokens to contributor
            tokensIssued = msg.value * TOKENS_PER_ETH;

            if (totalSupply + tokensIssued > TOTAL_SUPPLY_CAP) {
                tokensIssued = TOTAL_SUPPLY_CAP - totalSupply;
            }

            totalSupply += tokensIssued;
            balances[msg.sender] += tokensIssued;
            Transfer(address(this), msg.sender, tokensIssued);
        }
    }

    function Eclipse() {
        owner = msg.sender;
        totalSupply = 0;
    }
}


Refactor constructor to use msg.sender like admin if administrator address is empty

pragma solidity ^0.4.4;

contract Shop {

	struct Product {
		uint price;
		string name;
		uint stockBalance;
	}

    uint ownerWithdrawals;

	mapping (uint => Product) stock;

	uint[] products;

	address administrator;

	address owner;

	event AddProductEvent(uint id, uint price, string name);

	event DeleteProductEvent(uint id);

	event BuyProductEvent(uint id);

    event LogWithdrawEvent(address main, uint quantity);

	function Shop(address administratorAddress)
		public
	{
		if(administratorAddress == address(0)){
			administrator = msg.sender;
		}
		else {
			administrator = administratorAddress;
		}
		owner = msg.sender;
	}

    modifier isOwner
    {
        require(msg.sender == owner);
        _;
    }

    modifier isAdministrator
    {
        require(msg.sender == administrator);
        _;
    }

	function getProductCount()
		constant
		returns (uint length)
	{
		return products.length;
	}

	function getProductIdAt(uint index)
		constant
		returns (uint id)
	{
		return products[index];
	}

	function getProduct(uint id)
		constant
		returns (string name, uint price, uint stockBalance)
	{
		Product product = stock[id];
		return (product.name,
			product.price,
			product.stockBalance);
	}

    function addProduct(uint id, uint price, string name)
   		public
   		isAdministrator
   	{
   		products.push(id);
        stock[id].price = price;
        stock[id].stockBalance += 1;
        stock[id].name = name;
        AddProductEvent(id, price, name);

    }

    function deleteProduct(uint id)
    	public
    	isAdministrator
    {

        uint index = indexOf(id);

        for (uint i = index; i<products.length-1; i++){
            products[i] = products[i+1];
        }
        delete products[products.length-1];
        products.length--;
        delete stock[id];
        DeleteProductEvent(id);
    }

    function indexOf(uint id)
    	private
    	returns(uint)
	{

        for (uint i = 0; i<products.length-1; i++){
             if(products[i] == id) return i;
        }
       	throw;
  	}

    function buyProduct(uint id)
    	payable
    	public
    {
        require(stock[id].price > 0);
        require(stock[id].price <= msg.value);
        require(stock[id].stockBalance > 0);
        stock[id].stockBalance--;
        ownerWithdrawals += stock[id].price;
        BuyProductEvent(id);
    }

    function withdraw()
    	public
    	isOwner
    {

        if (ownerWithdrawals<=0) revert();

        ownerWithdrawals = 0;
        msg.sender.transfer(ownerWithdrawals);
        LogWithdrawEvent(msg.sender, ownerWithdrawals);

    }
}

pragma solidity ^0.4.4;

contract Shop {

	struct Product {
		uint price;
		string name;
		uint stockBalance;
	}

    uint ownerWithdrawals;

	mapping (uint => Product) stock;

	uint[] products;

	address administrator;

	address owner;

	event AddProductEvent(uint id, uint price, string name);

	event DeleteProductEvent(uint id);

	event BuyProductEvent(uint id);

    event LogWithdrawEvent(address main, uint quantity);

	function Shop(address administratorAddress)
		public
	{
		administrator = administratorAddress;
		owner = msg.sender;
	}

    modifier isOwner
    {
        require(msg.sender == owner);
        _;
    }

    modifier isAdministrator
    {
        require(msg.sender == administrator);
        _;
    }

	function getProductCount()
		constant
		returns (uint length)
	{
		return products.length;
	}

	function getProductIdAt(uint index)
		constant
		returns (uint id)
	{
		return products[index];
	}

	function getProduct(uint id)
		constant
		returns (string name, uint price, uint stockBalance)
	{
		Product product = stock[id];
		return (product.name,
			product.price,
			product.stockBalance);
	}

    function addProduct(uint id, uint price, string name)
   		public
   		isAdministrator
   	{
   		products.push(id);
        stock[id].price = price;
        stock[id].stockBalance += 1;
        stock[id].name = name;
        AddProductEvent(id, price, name);

    }

    function deleteProduct(uint id)
    	public
    	isAdministrator
    {

        uint index = indexOf(id);

        for (uint i = index; i<products.length-1; i++){
            products[i] = products[i+1];
        }
        delete products[products.length-1];
        products.length--;
        delete stock[id];
        DeleteProductEvent(id);
    }

    function indexOf(uint id)
    	private
    	returns(uint)
	{

        for (uint i = 0; i<products.length-1; i++){
             if(products[i] == id) return i;
        }
       	throw;
  	}

    function buyProduct(uint id)
    	payable
    	public
    {
        require(stock[id].price > 0);
        require(stock[id].price <= msg.value);
        require(stock[id].stockBalance > 0);
        stock[id].stockBalance--;
        ownerWithdrawals += stock[id].price;
        BuyProductEvent(id);
    }

    function withdraw()
    	public
    	isOwner
    {

        if (ownerWithdrawals<=0) revert();

        ownerWithdrawals = 0;
        msg.sender.transfer(ownerWithdrawals);
        LogWithdrawEvent(msg.sender, ownerWithdrawals);

    }
}


Add payback money in buy function. Pending refactor to add new contracts like Owned, Utils....

pragma solidity ^0.4.4;

contract Shop {

	struct Product {
		uint price;
		string name;
		uint stockBalance;
	}

    uint ownerWithdrawals;

	mapping (address => uint) public payBack;

	mapping (uint => Product) stock;

	uint[] products;

	address administrator;

	address owner;

	event AddProductEvent(uint id, uint price, string name);

	event DeleteProductEvent(uint id);

	event BuyProductEvent(uint id);

    event LogWithdrawEvent(address main, uint quantity);

    event LogPayMeBackEvent(address main, uint quantity);

	function Shop(address administratorAddress)
		public
	{
		if(administratorAddress == address(0)){
			administrator = msg.sender;
		}
		else {
			administrator = administratorAddress;
		}
		owner = msg.sender;
	}

    modifier isOwner
    {
        require(msg.sender == owner);
        _;
    }

    modifier isAdministrator
    {
        require(msg.sender == administrator);
        _;
    }

	function getProductCount()
		constant
		returns (uint length)
	{
		return products.length;
	}

	function getProductIdAt(uint index)
		constant
		returns (uint id)
	{
		return products[index];
	}

	function getProduct(uint id)
		constant
		returns (string name, uint price, uint stockBalance)
	{
		Product product = stock[id];
		return (product.name,
			product.price,
			product.stockBalance);
	}

    function addProduct(uint id, uint price, string name)
   		public
   		isAdministrator
   	{
   		products.push(id);
        stock[id].price = price;
        stock[id].stockBalance += 1;
        stock[id].name = name;
        AddProductEvent(id, price, name);

    }

    function deleteProduct(uint id)
    	public
    	isAdministrator
    {

        uint index = indexOf(id);

        for (uint i = index; i<products.length-1; i++){
            products[i] = products[i+1];
        }
        delete products[products.length-1];
        products.length--;
        delete stock[id];
        DeleteProductEvent(id);
    }

    function indexOf(uint id)
    	private
    	returns(uint)
	{

        for (uint i = 0; i<products.length-1; i++){
             if(products[i] == id) return i;
        }
       	throw;
  	}

    function buyProduct(uint id)
    	payable
    	public
    {
        require(stock[id].price > 0);
        require(stock[id].price <= msg.value);
        require(stock[id].stockBalance > 0);
        stock[id].stockBalance--;
        ownerWithdrawals += stock[id].price;
        int payBack=msg.value-stock[id].price;

        if(payBack>0) payBack[msg.sender]=payBack;

        BuyProductEvent(id);
    }

    function withdraw()
    	public
    	isOwner
    {

        if (ownerWithdrawals<=0) revert();

        ownerWithdrawals = 0;
        msg.sender.transfer(ownerWithdrawals);
        LogWithdrawEvent(msg.sender, ownerWithdrawals);

    }

    function payMeBack()
    	public
    {

        if (payBack[msg.sender]<=0) revert();

        payBack[msg.sender] = 0;
        msg.sender.transfer(payBack[msg.sender]);
        LogPayMeBackEvent(msg.sender, payBack[msg.sender]);

    }
}

pragma solidity ^0.4.4;

contract Shop {

	struct Product {
		uint price;
		string name;
		uint stockBalance;
	}

    uint ownerWithdrawals;

	mapping (uint => Product) stock;

	uint[] products;

	address administrator;

	address owner;

	event AddProductEvent(uint id, uint price, string name);

	event DeleteProductEvent(uint id);

	event BuyProductEvent(uint id);

    event LogWithdrawEvent(address main, uint quantity);

	function Shop(address administratorAddress)
		public
	{
		if(administratorAddress == address(0)){
			administrator = msg.sender;
		}
		else {
			administrator = administratorAddress;
		}
		owner = msg.sender;
	}

    modifier isOwner
    {
        require(msg.sender == owner);
        _;
    }

    modifier isAdministrator
    {
        require(msg.sender == administrator);
        _;
    }

	function getProductCount()
		constant
		returns (uint length)
	{
		return products.length;
	}

	function getProductIdAt(uint index)
		constant
		returns (uint id)
	{
		return products[index];
	}

	function getProduct(uint id)
		constant
		returns (string name, uint price, uint stockBalance)
	{
		Product product = stock[id];
		return (product.name,
			product.price,
			product.stockBalance);
	}

    function addProduct(uint id, uint price, string name)
   		public
   		isAdministrator
   	{
   		products.push(id);
        stock[id].price = price;
        stock[id].stockBalance += 1;
        stock[id].name = name;
        AddProductEvent(id, price, name);

    }

    function deleteProduct(uint id)
    	public
    	isAdministrator
    {

        uint index = indexOf(id);

        for (uint i = index; i<products.length-1; i++){
            products[i] = products[i+1];
        }
        delete products[products.length-1];
        products.length--;
        delete stock[id];
        DeleteProductEvent(id);
    }

    function indexOf(uint id)
    	private
    	returns(uint)
	{

        for (uint i = 0; i<products.length-1; i++){
             if(products[i] == id) return i;
        }
       	throw;
  	}

    function buyProduct(uint id)
    	payable
    	public
    {
        require(stock[id].price > 0);
        require(stock[id].price <= msg.value);
        require(stock[id].stockBalance > 0);
        stock[id].stockBalance--;
        ownerWithdrawals += stock[id].price;
        BuyProductEvent(id);
    }

    function withdraw()
    	public
    	isOwner
    {

        if (ownerWithdrawals<=0) revert();

        ownerWithdrawals = 0;
        msg.sender.transfer(ownerWithdrawals);
        LogWithdrawEvent(msg.sender, ownerWithdrawals);

    }
}


add an address typecast to this per issue #1457 (#1471)

/* solium-disable security/no-block-members */

pragma solidity ^0.4.24;

import "../token/ERC20/SafeERC20.sol";
import "../ownership/Ownable.sol";
import "../math/SafeMath.sol";

/**
 * @title TokenVesting
 * @dev A token holder contract that can release its token balance gradually like a
 * typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
 * owner.
 */
contract TokenVesting is Ownable {
  using SafeMath for uint256;
  using SafeERC20 for IERC20;

  event TokensReleased(address token, uint256 amount);
  event TokenVestingRevoked(address token);

  // beneficiary of tokens after they are released
  address private _beneficiary;

  uint256 private _cliff;
  uint256 private _start;
  uint256 private _duration;

  bool private _revocable;

  mapping (address => uint256) private _released;
  mapping (address => bool) private _revoked;

  /**
   * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
   * beneficiary, gradually in a linear fashion until start + duration. By then all
   * of the balance will have vested.
   * @param beneficiary address of the beneficiary to whom vested tokens are transferred
   * @param cliffDuration duration in seconds of the cliff in which tokens will begin to vest
   * @param start the time (as Unix time) at which point vesting starts
   * @param duration duration in seconds of the period in which the tokens will vest
   * @param revocable whether the vesting is revocable or not
   */
  constructor(
    address beneficiary,
    uint256 start,
    uint256 cliffDuration,
    uint256 duration,
    bool revocable
  )
    public
  {
    require(beneficiary != address(0));
    require(cliffDuration <= duration);
    require(duration > 0);
    require(start.add(duration) > block.timestamp);

    _beneficiary = beneficiary;
    _revocable = revocable;
    _duration = duration;
    _cliff = start.add(cliffDuration);
    _start = start;
  }

  /**
   * @return the beneficiary of the tokens.
   */
  function beneficiary() public view returns(address) {
    return _beneficiary;
  }

  /**
   * @return the cliff time of the token vesting.
   */
  function cliff() public view returns(uint256) {
    return _cliff;
  }

  /**
   * @return the start time of the token vesting.
   */
  function start() public view returns(uint256) {
    return _start;
  }

  /**
   * @return the duration of the token vesting.
   */
  function duration() public view returns(uint256) {
    return _duration;
  }

  /**
   * @return true if the vesting is revocable.
   */
  function revocable() public view returns(bool) {
    return _revocable;
  }

  /**
   * @return the amount of the token released.
   */
  function released(address token) public view returns(uint256) {
    return _released[token];
  }

  /**
   * @return true if the token is revoked.
   */
  function revoked(address token) public view returns(bool) {
    return _revoked[token];
  }

  /**
   * @notice Transfers vested tokens to beneficiary.
   * @param token ERC20 token which is being vested
   */
  function release(IERC20 token) public {
    uint256 unreleased = _releasableAmount(token);

    require(unreleased > 0);

    _released[token] = _released[token].add(unreleased);

    token.safeTransfer(_beneficiary, unreleased);

    emit TokensReleased(token, unreleased);
  }

  /**
   * @notice Allows the owner to revoke the vesting. Tokens already vested
   * remain in the contract, the rest are returned to the owner.
   * @param token ERC20 token which is being vested
   */
  function revoke(IERC20 token) public onlyOwner {
    require(_revocable);
    require(!_revoked[token]);

    uint256 balance = token.balanceOf(address(this));

    uint256 unreleased = _releasableAmount(token);
    uint256 refund = balance.sub(unreleased);

    _revoked[token] = true;

    token.safeTransfer(owner(), refund);

    emit TokenVestingRevoked(token);
  }

  /**
   * @dev Calculates the amount that has already vested but hasn't been released yet.
   * @param token ERC20 token which is being vested
   */
  function _releasableAmount(IERC20 token) private view returns (uint256) {
    return _vestedAmount(token).sub(_released[token]);
  }

  /**
   * @dev Calculates the amount that has already vested.
   * @param token ERC20 token which is being vested
   */
  function _vestedAmount(IERC20 token) private view returns (uint256) {
    uint256 currentBalance = token.balanceOf(address(this));
    uint256 totalBalance = currentBalance.add(_released[token]);

    if (block.timestamp < _cliff) {
      return 0;
    } else if (block.timestamp >= _start.add(_duration) || _revoked[token]) {
      return totalBalance;
    } else {
      return totalBalance.mul(block.timestamp.sub(_start)).div(_duration);
    }
  }
}

/* solium-disable security/no-block-members */

pragma solidity ^0.4.24;

import "../token/ERC20/SafeERC20.sol";
import "../ownership/Ownable.sol";
import "../math/SafeMath.sol";

/**
 * @title TokenVesting
 * @dev A token holder contract that can release its token balance gradually like a
 * typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
 * owner.
 */
contract TokenVesting is Ownable {
  using SafeMath for uint256;
  using SafeERC20 for IERC20;

  event TokensReleased(address token, uint256 amount);
  event TokenVestingRevoked(address token);

  // beneficiary of tokens after they are released
  address private _beneficiary;

  uint256 private _cliff;
  uint256 private _start;
  uint256 private _duration;

  bool private _revocable;

  mapping (address => uint256) private _released;
  mapping (address => bool) private _revoked;

  /**
   * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
   * beneficiary, gradually in a linear fashion until start + duration. By then all
   * of the balance will have vested.
   * @param beneficiary address of the beneficiary to whom vested tokens are transferred
   * @param cliffDuration duration in seconds of the cliff in which tokens will begin to vest
   * @param start the time (as Unix time) at which point vesting starts
   * @param duration duration in seconds of the period in which the tokens will vest
   * @param revocable whether the vesting is revocable or not
   */
  constructor(
    address beneficiary,
    uint256 start,
    uint256 cliffDuration,
    uint256 duration,
    bool revocable
  )
    public
  {
    require(beneficiary != address(0));
    require(cliffDuration <= duration);
    require(duration > 0);
    require(start.add(duration) > block.timestamp);

    _beneficiary = beneficiary;
    _revocable = revocable;
    _duration = duration;
    _cliff = start.add(cliffDuration);
    _start = start;
  }

  /**
   * @return the beneficiary of the tokens.
   */
  function beneficiary() public view returns(address) {
    return _beneficiary;
  }

  /**
   * @return the cliff time of the token vesting.
   */
  function cliff() public view returns(uint256) {
    return _cliff;
  }

  /**
   * @return the start time of the token vesting.
   */
  function start() public view returns(uint256) {
    return _start;
  }

  /**
   * @return the duration of the token vesting.
   */
  function duration() public view returns(uint256) {
    return _duration;
  }

  /**
   * @return true if the vesting is revocable.
   */
  function revocable() public view returns(bool) {
    return _revocable;
  }

  /**
   * @return the amount of the token released.
   */
  function released(address token) public view returns(uint256) {
    return _released[token];
  }

  /**
   * @return true if the token is revoked.
   */
  function revoked(address token) public view returns(bool) {
    return _revoked[token];
  }

  /**
   * @notice Transfers vested tokens to beneficiary.
   * @param token ERC20 token which is being vested
   */
  function release(IERC20 token) public {
    uint256 unreleased = _releasableAmount(token);

    require(unreleased > 0);

    _released[token] = _released[token].add(unreleased);

    token.safeTransfer(_beneficiary, unreleased);

    emit TokensReleased(token, unreleased);
  }

  /**
   * @notice Allows the owner to revoke the vesting. Tokens already vested
   * remain in the contract, the rest are returned to the owner.
   * @param token ERC20 token which is being vested
   */
  function revoke(IERC20 token) public onlyOwner {
    require(_revocable);
    require(!_revoked[token]);

    uint256 balance = token.balanceOf(address(this));

    uint256 unreleased = _releasableAmount(token);
    uint256 refund = balance.sub(unreleased);

    _revoked[token] = true;

    token.safeTransfer(owner(), refund);

    emit TokenVestingRevoked(token);
  }

  /**
   * @dev Calculates the amount that has already vested but hasn't been released yet.
   * @param token ERC20 token which is being vested
   */
  function _releasableAmount(IERC20 token) private view returns (uint256) {
    return _vestedAmount(token).sub(_released[token]);
  }

  /**
   * @dev Calculates the amount that has already vested.
   * @param token ERC20 token which is being vested
   */
  function _vestedAmount(IERC20 token) private view returns (uint256) {
    uint256 currentBalance = token.balanceOf(this);
    uint256 totalBalance = currentBalance.add(_released[token]);

    if (block.timestamp < _cliff) {
      return 0;
    } else if (block.timestamp >= _start.add(_duration) || _revoked[token]) {
      return totalBalance;
    } else {
      return totalBalance.mul(block.timestamp.sub(_start)).div(_duration);
    }
  }
}