fixed variable name and docs

fixed variable name and docs

/*
    Copyright 2017 Phillip A. Elsasser

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

pragma solidity 0.4.18;

import "./Creatable.sol";
import "./oraclize/oraclizeAPI.sol";
import "./libraries/MathLib.sol";
import "./libraries/HashLib.sol";
import "zeppelin-solidity/contracts/token/ERC20.sol";
import "zeppelin-solidity/contracts/token/SafeERC20.sol";

// TODO:
//      add failsafe for pool distribution.
//      push as much into library as possible
//      think about circuit breaker in case of issues
//      discuss build out ability to use ETH vs only ERC20? - WETH?
//      add open interest to allow users to see outstanding open positions
//      add function to allow user to pay for an extra query that could trigger settlement
//      require creator to own arbitrary amount of MEM token
//      add in fee functionality needed for nodes and the reduced fees for holders of MEM.

/// @title MarketContract first example of a MarketProtocol contract using Oraclize services
/// @author Phil Elsasser <phil@marketprotcol.io>
contract MarketContract is Creatable, usingOraclize  {
    using MathLib for uint256;
    using MathLib for int;
    using HashLib for address;
    using SafeERC20 for ERC20;

    struct UserNetPosition {
        address userAddress;
        Position[] positions;   // all open positions (lifo upon exit - allows us to not reindex array!)
        int netPosition;        // net position across all prices / executions
    }

    struct Position {
        uint price;
        int qty;
    }

    struct Order {
        address maker;
        address taker;
        address feeRecipient;
        uint makerFee;
        uint takerFee;
        uint qty;
        uint price;
        uint expirationTimeStamp;
        bytes32 orderHash;
    }

    enum ErrorCodes {
        ORDER_EXPIRED,              // past designated timestamp
        ORDER_DEAD                  // order if fully filled or fully cancelled
    }

    // constants
    string public CONTRACT_NAME;
    address public BASE_TOKEN_ADDRESS;
    ERC20 public BASE_TOKEN;
    uint public PRICE_CAP;
    uint public PRICE_FLOOR;
    uint public PRICE_DECIMAL_PLACES;   // how to convert the pricing from decimal format (if valid) to integer
    uint public QTY_DECIMAL_PLACES;     // how many tradeable units make up a whole pricing increment
    uint public EXPIRATION;
    string public ORACLE_DATA_SOURCE;
    string public ORACLE_QUERY;
    uint public ORACLE_QUERY_REPEAT;
    uint8 constant public BUY_SIDE = 0;
    uint8 constant public SELL_SIDE = 1;
    uint constant public COST_PER_QUERY = 2 finney;    // leave static for now, price of first query from oraclize is 0
    uint constant public QUERY_CALLBACK_GAS = 300000;

    // state variables
    string public lastPriceQueryResult;
    uint public lastPrice;
    uint public settlementPrice;
    bool public isSettled;
    mapping(bytes32 => bool) validQueryIDs;

    // accounting
    mapping(address => UserNetPosition) addressToUserPosition;
    mapping(address => uint) userAddressToAccountBalance;   // stores account balances allowed to be allocated to orders
    mapping (bytes32 => int) public filledOrderQty;
    mapping (bytes32 => int) public cancelledOrderQty;
    uint collateralPoolBalance = 0;                         // current balance of all collateral committed

    // events
    event OracleQuerySuccess();
    event OracleQueryFailed();
    event UpdatedLastPrice(string price);
    event ContractSettled(uint settlePrice);
    event UpdatedUserBalance(address indexed user, uint balance);
    event UpdatedPoolBalance(uint balance);
    event Error(ErrorCodes indexed errorCode, bytes32 indexed orderHash);

    // order events
    event OrderFilled(
        address indexed maker,
        address indexed taker,
        address indexed feeRecipient,
        int filledQty,
        uint paidMakerFee,
        uint paidTakerFee,
        bytes32 indexed orderHash
    );
    event OrderCancelled(
        address indexed maker,
        address indexed feeRecipient,
        int cancelledQty,
        bytes32 indexed orderHash
    );

    /// @param contractName viewable name of this contract (BTC/ETH, LTC/ETH, etc)
    /// @param baseTokenAddress address of the ERC20 token that will be used for collateral and pricing
    /// @param oracleDataSource a data-source such as "URL", "WolframAlpha", "IPFS"
    /// see http://docs.oraclize.it/#ethereum-quick-start-simple-query
    /// @param oracleQuery see http://docs.oraclize.it/#ethereum-quick-start-simple-query for examples
    /// @param oracleQueryRepeatSeconds how often to repeat this callback to check for settlement, more frequent
    /// queries require more gas and may not be needed.
    /// @param floorPrice minimum tradeable price of this contract, contract enters settlement if breached
    /// @param capPrice maximum tradeable price of this contract, contract enters settlement if breached
    /// @param priceDecimalPlaces number of decimal places to convert our queried price from a floating point to
    /// an integer
    /// @param qtyDecimalPlaces decimal places to multiply traded qty by.
    /// @param secondsToExpiration - second from now that this contract expires and enters settlement
    function MarketContract(
        string contractName,
        address baseTokenAddress,
        string oracleDataSource,
        string oracleQuery,
        uint oracleQueryRepeatSeconds,
        uint floorPrice,
        uint capPrice,
        uint priceDecimalPlaces,
        uint qtyDecimalPlaces,
        uint secondsToExpiration
    ) public payable {

        require(capPrice > floorPrice);
        // TODO: check for minimum MEM token balance of caller.
        oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
        CONTRACT_NAME = contractName;
        BASE_TOKEN_ADDRESS = baseTokenAddress;
        BASE_TOKEN = ERC20(baseTokenAddress);
        PRICE_CAP = capPrice;
        PRICE_FLOOR = floorPrice;
        EXPIRATION = now + secondsToExpiration;
        ORACLE_DATA_SOURCE = oracleDataSource;
        ORACLE_QUERY = oracleQuery;
        ORACLE_QUERY_REPEAT = oracleQueryRepeatSeconds;
        PRICE_DECIMAL_PLACES = priceDecimalPlaces;
        QTY_DECIMAL_PLACES = qtyDecimalPlaces;
        require(checkSufficientStartingBalance(secondsToExpiration));
        queryOracle();  // schedules recursive calls to oracle
    }

    /*
    // EXTERNAL METHODS
    */

    // @param userAddress address to return position for
    // @return the users current open position.
    function getUserPosition(address userAddress) external view returns (int)  {
        return addressToUserPosition[userAddress].netPosition;
    }

    /// @notice deposits tokens to the smart contract to fund the user account and provide needed tokens for collateral
    /// pool upon trade matching.
    /// @param depositAmount qty of ERC20 tokens to deposit to the smart contract to cover open orders and collateral
    function depositTokensForTrading(uint256 depositAmount) external {
        // user must call approve!
        BASE_TOKEN.safeTransferFrom(msg.sender, this, depositAmount);
        uint256 balanceAfterDeposit = userAddressToAccountBalance[msg.sender].add(depositAmount);
        userAddressToAccountBalance[msg.sender] = balanceAfterDeposit;
        UpdatedUserBalance(msg.sender, balanceAfterDeposit);
    }

    // @notice called by a participant wanting to trade a specific order
    /// @param maker address of the maker of this order
    /// @param taker address of the designated taker or address(0) if publicly available to be traded
    /// @param feeRecipient address of a fee recipient, optional
    /// @param makerFee amount of MKT token for maker fee
    /// @param takerFee amount of MKT token for taker fee
    /// @param price of the order
    /// @param orderQty quantity of the order
    /// @param qtyToFill quantity taker is willing to fill of original order(max)
    /// @param expirationTimeStamp last valid timestamp of the order (seconds since epoch)
    /// @param v order signature
    /// @param r order signature
    /// @param s order signature
    function tradeOrder(
        address maker,
        address taker,
        address feeRecipient,
        uint makerFee,
        uint takerFee,
        uint price,
        int orderQty,
        int qtyToFill,
        uint expirationTimeStamp,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (int filledQty) {
        require(!isSettled);                                // no trading past settlement
        require(taker == address(0) || taker == msg.sender);// taker can be anyone, or specifically the caller!
        require(maker != address(0) && maker != taker);     // do not allow self trade
        require(orderQty != 0 && qtyToFill != 0);           // no zero trades
        require(orderQty.isSameSign(qtyToFill));            // signs should match

        bytes32 orderHash = address(this).createOrderHash(maker, feeRecipient,
                                makerFee, takerFee, orderQty, price, expirationTimeStamp);

        require(maker.isValidSignature(orderHash, v, r, s));

        if(now >= expirationTimeStamp) {
            Error(ErrorCodes.ORDER_EXPIRED, orderHash);
            return 0;
        }

        int remainingQty = orderQty.subtract(getQtyFilledOrCancelledFromOrder(orderHash));
        if(remainingQty == 0) { // there is no qty remaining  - cannot fill!
            Error(ErrorCodes.ORDER_DEAD, orderHash);
            return 0;
        }

        filledQty = MathLib.absMin(remainingQty, qtyToFill);
        updatePositions(maker, taker, filledQty, price);    // this will fail if any of the balances are insufficient

        uint paidMakerFee = 0;
        uint paidTakerFee = 0;

        if(feeRecipient != address(0)) { // we need to transfer fees to recipient

            if(makerFee > 0) {

            }

            if(takerFee > 0) {

            }
        }

        OrderFilled(maker, taker, feeRecipient, filledQty, paidMakerFee, paidTakerFee, orderHash);
        return filledQty;
    }

    // @notice called by the maker of an order to attempt to cancel the order before its expiration time stamp
    /// @param maker address of the maker of this order
    /// @param taker address of the designated taker or address(0) if publicly available to be traded
    /// @param feeRecipient address of a fee recipient, optional
    /// @param makerFee amount of MKT token for maker fee
    /// @param takerFee amount of MKT token for taker fee
    /// @param price of the order
    /// @param orderQty quantity of the order
    /// @param qtyToCancel quantity maker is attempting to cancel
    /// @param expirationTimeStamp last valid timestamp of the order (seconds since epoch)
    /// @return qty that was successfully cancelled of order.
    function cancelOrder(
        address maker,
        address taker,
        address feeRecipient,
        uint makerFee,
        uint takerFee,
        uint price,
        int orderQty,
        int qtyToCancel,
        uint expirationTimeStamp
    ) external returns (int qtyCancelled){
        require(maker == msg.sender);                                       // only maker can cancel standing order
        require(qtyToCancel != 0 && qtyToCancel.isSameSign(orderQty));      // cannot cancel 0 and signs must match
        require(!isSettled);

        bytes32 orderHash = address(this).createOrderHash(maker, feeRecipient,
            makerFee, takerFee, orderQty, price, expirationTimeStamp);

        if(now >= expirationTimeStamp) {
            Error(ErrorCodes.ORDER_EXPIRED, orderHash);
            return 0;
        }

        int remainingQty = orderQty.subtract(getQtyFilledOrCancelledFromOrder(orderHash));
        if(remainingQty == 0) { // there is no qty remaining to cancel order is dead
            Error(ErrorCodes.ORDER_DEAD, orderHash);
            return 0;
        }

        qtyCancelled = MathLib.absMin(qtyToCancel, remainingQty);   // we can only cancel what remains
        cancelledOrderQty[orderHash] = cancelledOrderQty[orderHash].add(qtyCancelled);
        OrderCancelled(maker, feeRecipient, qtyCancelled, orderHash);
        return qtyCancelled;
    }

    // @notice called by a user after settlement has occurred.  This function will finalize all accounting around any
    // outstanding positions and return all remaining collateral to the caller. This should only be called after
    // settlement has occurred.
    function settleAndClose() external {
        require(isSettled);
        UserNetPosition storage userNetPos = addressToUserPosition[msg.sender];
        if(userNetPos.netPosition != 0) {
            // this user has a position that we need to settle based upon the settlement price of the contract
            reduceUserNetPosition(msg.sender, userNetPos.netPosition * - 1, settlementPrice);
        }
        withdrawTokens(userAddressToAccountBalance[msg.sender]);   // transfer all balances back to user.
    }

    /*
    // PUBLIC METHODS
    */

    /// @param queryID of the returning query, this should match our own internal mapping
    /// @param result query to be processed
    /// @param proof result proof
    function __callback(bytes32 queryID, string result, bytes proof) public {
        require(validQueryIDs[queryID]);
        require(msg.sender == oraclize_cbAddress());
        lastPriceQueryResult = result;
        lastPrice = parseInt(result, PRICE_DECIMAL_PLACES);
        UpdatedLastPrice(result);
        delete validQueryIDs[queryID];
        checkSettlement();
        if (!isSettled) {
            queryOracle();  // set up our next query
        }
    }

    /// @notice returns the qty that is no longer available to trade for a given order
    /// @param orderHash hash of order to find filled and cancelled qty
    /// @return int quantity that is no longer able to filled from the supplied order hash
    function getQtyFilledOrCancelledFromOrder(bytes32 orderHash) public view returns (int) {
        return filledOrderQty[orderHash].add(cancelledOrderQty[orderHash]);
    }

    /// @notice removes token from users trading account
    /// @param withdrawAmount qty of token to attempt to withdraw
    function withdrawTokens(uint256 withdrawAmount) public {
        require(userAddressToAccountBalance[msg.sender] >= withdrawAmount);   // ensure sufficient balance
        uint256 balanceAfterWithdrawal = userAddressToAccountBalance[msg.sender].subtract(withdrawAmount);
        userAddressToAccountBalance[msg.sender] = balanceAfterWithdrawal;   // update balance before external call!
        BASE_TOKEN.safeTransfer(msg.sender, withdrawAmount);
        UpdatedUserBalance(msg.sender, balanceAfterWithdrawal);
    }

    /*
    // PRIVATE METHODS
    */

    /// @param maker address of the maker in the trade
    /// @param taker address of the taker in the trade
    /// @param qty quantity transacted between parties
    /// @param price agreed price of the matched trade.
    function updatePositions(address maker, address taker, int qty, uint price) private {
        updatePosition(maker, qty, price);
        // continue process for taker, but qty is opposite sign for taker
        updatePosition(taker, qty * -1, price);

    }

    /// @param userAddress storage struct containing position information for this user
    /// @param qty signed quantity this users position is changing by, + for buy and - for sell
    /// @param price transacted price of the new position / trade
    function updatePosition(address userAddress, int qty, uint price) private {
        UserNetPosition storage userNetPosition = addressToUserPosition[userAddress];
        if(userNetPosition.netPosition == 0 ||  userNetPosition.netPosition.isSameSign(qty)) {
            // new position or adding to open pos
            addUserNetPosition(userNetPosition, userAddress, qty, price);
        }
        else {
            // opposite side from open position, reduce, flattened, or flipped.
            if(userNetPosition.netPosition >= qty * -1) { // pos is reduced of flattened
                reduceUserNetPosition(userNetPosition, qty, price);
            } else {    // pos is flipped, reduce and then create new open pos!
                reduceUserNetPosition(userNetPosition, userNetPosition.netPosition * -1, price); // flatten completely
                int newNetPos = userNetPosition.netPosition + qty;            // the portion remaining after flattening
                addUserNetPosition(userNetPosition, userAddress, newNetPos, price);
            }
        }
        userNetPosition.netPosition.add(qty);   // keep track of total net pos across all prices for user.
    }

    /// @dev calculates the needed collateral for a new position and commits it to the pool removing it from the
    /// users account and creates the needed Position struct to record the new position.
    /// @param userNetPosition current positions held by user
    /// @param userAddress address of user entering into the position
    /// @param qty signed quantity of the trade
    /// @param price agreed price of trade
    function addUserNetPosition(
        UserNetPosition storage userNetPosition,
        address userAddress,
        int qty,
        uint price
    ) private {
        uint neededCollateral = MathLib.calculateNeededCollateral(this, qty, price);
        commitCollateralToPool(userAddress, neededCollateral);
        userNetPosition.positions.push(Position(price, qty));   // append array with new position
    }

    /// @param userAddress address of user who is reducing their pos
    /// @param userNetPos storage struct for this users position
    /// @param qty signed quantity of the qty to reduce this users position by
    /// @param price transacted price
    function reduceUserNetPosition(
        address userAddress,
        UserNetPosition storage userNetPos,
        int qty,
        uint price
    ) private {
        uint collateralToReturnToUserAccount = 0;
        int qtyToReduce = qty;                      // note: this sign is opposite of our users position
        assert(userNetPos.positions.length != 0);   // sanity check
        while(qtyToReduce != 0) {   //TODO: ensure we dont run out of gas here!
            Position storage position = userNetPos.positions[userNetPos.positions.length - 1];  // get the last pos (LIFO)
            if(position.qty.abs() <= qtyToReduce.abs()) {   // this position is completely consumed!
                collateralToReturnToUserAccount.add(MathLib.calculateNeededCollateral(this, position.qty, price));
                qtyToReduce = qtyToReduce.add(position.qty);
                userNetPos.positions.length--;  // remove this position from our array.
            }
            else {  // this position stays, just reduce the qty.
                position.qty = position.qty.add(qtyToReduce);
                // pos is opp sign of qty we are reducing here!
                collateralToReturnToUserAccount.add(MathLib.calculateNeededCollateral(this, qtyToReduce * -1, price));
                //qtyToReduce = 0; // completely reduced now!
                break;
            }
        }

        if(collateralToReturnToUserAccount != 0) {  // allocate funds back to user acct.
            withdrawCollateralFromPool(userAddress, collateralToReturnToUserAccount);
        }
    }

    /// @notice moves collateral from a user's account to the pool upon trade execution.
    /// @param fromAddress address of user entering trade
    /// @param collateralAmount amount of collateral to transfer from user account to collateral pool
    function commitCollateralToPool(address fromAddress, uint collateralAmount) private {
        require(userAddressToAccountBalance[fromAddress] >= collateralAmount);   // ensure sufficient balance
        uint newBalance = userAddressToAccountBalance[fromAddress].subtract(collateralAmount);
        userAddressToAccountBalance[fromAddress] = newBalance;
        collateralPoolBalance = collateralPoolBalance.add(collateralAmount);
        UpdatedUserBalance(fromAddress, newBalance);
        UpdatedPoolBalance(collateralPoolBalance);
    }

    /// @notice withdraws collateral from pool to a user account upon exit or trade settlement
    /// @param toAddress address of user
    /// @param collateralAmount amount to transfer from pool to user.
    function withdrawCollateralFromPool(address toAddress, uint collateralAmount) private {
        require(collateralPoolBalance >= collateralAmount); // ensure sufficient balance
        uint newBalance = userAddressToAccountBalance[toAddress].add(collateralAmount);
        userAddressToAccountBalance[toAddress] = newBalance;
        collateralPoolBalance = collateralPoolBalance.subtract(collateralAmount);
        UpdatedUserBalance(toAddress, newBalance);
        UpdatedPoolBalance(collateralPoolBalance);
    }

    /// @dev call to oraclize to set up our query and record its hash.
    function queryOracle() private {
        if (oraclize_getPrice(ORACLE_DATA_SOURCE) > this.balance) {
            OracleQueryFailed();
            lastPriceQueryResult = "FAILED"; //TODO: failsafe
        } else {
            OracleQuerySuccess();
            bytes32 queryId = oraclize_query(ORACLE_QUERY_REPEAT, ORACLE_DATA_SOURCE, ORACLE_QUERY, QUERY_CALLBACK_GAS);
            validQueryIDs[queryId] = true;
        }
    }

    /// @dev checks our last query price to see if our contract should enter settlement due to it being past our
    //  expiration date or outside of our tradeable ranges.
    function checkSettlement() private {
        if(isSettled)   // already settled.
            return;

        if(now > EXPIRATION) {  // note: miners can cheat this by small increments of time (minutes, not hours)
            isSettled = true;   // time based expiration has occurred.
        } else if(lastPrice >= PRICE_CAP || lastPrice <= PRICE_FLOOR) {
            isSettled = true;   // we have breached/touched our pricing bands
        }

        if(isSettled) {
            settleContract();
        }
    }

    /// @dev records our final settlement price and fires needed events.
    /// @param finalSettlementPrice final query price at time of settlement
    function settleContract(uint finalSettlementPrice) private {
        settlementPrice = finalSettlementPrice;
        ContractSettled(finalSettlementPrice);
        // TODO: return any remaining ether balance to creator of this contract (no longer needs gas for queries)
    }

    /// @dev over estimates needed gas to power queries until expiration and determines if provided contract
    /// contains enough.
    /// @param secondsToExpiration seconds from now that expiration is scheduled.
    /// @return true if sufficient gas is present to create queries at the designated
    /// frequency from now until expiration
    function checkSufficientStartingBalance(uint secondsToExpiration) private view returns (bool isSufficient) {
        //uint costPerQuery = oraclize_getPrice(ORACLE_DATA_SOURCE); this doesn't work prior to first query(its free)
        uint expectedNoOfQueries = secondsToExpiration / ORACLE_QUERY_REPEAT;
        uint approxGasRequired = COST_PER_QUERY * expectedNoOfQueries;
        return this.balance > (approxGasRequired * 2);
    }
}

/*
    Copyright 2017 Phillip A. Elsasser

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

pragma solidity 0.4.18;

import "./Creatable.sol";
import "./oraclize/oraclizeAPI.sol";
import "./libraries/MathLib.sol";
import "./libraries/HashLib.sol";
import "zeppelin-solidity/contracts/token/ERC20.sol";
import "zeppelin-solidity/contracts/token/SafeERC20.sol";

// TODO:
//      add failsafe for pool distribution.
//      push as much into library as possible
//      think about circuit breaker in case of issues
//      discuss build out ability to use ETH vs only ERC20? - WETH?
//      add open interest to allow users to see outstanding open positions
//      add function to allow user to pay for an extra query that could trigger settlement
//      require creator to own arbitrary amount of MEM token
//      add in fee functionality needed for nodes and the reduced fees for holders of MEM.

/// @title MarketContract first example of a MarketProtocol contract using Oraclize services
/// @author Phil Elsasser <phil@marketprotcol.io>
contract MarketContract is Creatable, usingOraclize  {
    using MathLib for uint256;
    using MathLib for int;
    using HashLib for address;
    using SafeERC20 for ERC20;

    struct UserNetPosition {
        address userAddress;
        Position[] positions;   // all open positions (lifo upon exit - allows us to not reindex array!)
        int netPosition;        // net position across all prices / executions
    }

    struct Position {
        uint price;
        int qty;
    }

    struct Order {
        address maker;
        address taker;
        address feeRecipient;
        uint makerFee;
        uint takerFee;
        uint qty;
        uint price;
        uint expirationTimeStamp;
        bytes32 orderHash;
    }

    enum ErrorCodes {
        ORDER_EXPIRED,              // past designated timestamp
        ORDER_DEAD                  // order if fully filled or fully cancelled
    }

    // constants
    string public CONTRACT_NAME;
    address public BASE_TOKEN_ADDRESS;
    ERC20 public BASE_TOKEN;
    uint public PRICE_CAP;
    uint public PRICE_FLOOR;
    uint public PRICE_DECIMAL_PLACES;   // how to convert the pricing from decimal format (if valid) to integer
    uint public QTY_DECIMAL_PLACES;     // how many tradeable units make up a whole pricing increment
    uint public EXPIRATION;
    string public ORACLE_DATA_SOURCE;
    string public ORACLE_QUERY;
    uint public ORACLE_QUERY_REPEAT;
    uint8 constant public BUY_SIDE = 0;
    uint8 constant public SELL_SIDE = 1;
    uint constant public COST_PER_QUERY = 2 finney;    // leave static for now, price of first query from oraclize is 0
    uint constant public QUERY_CALLBACK_GAS = 300000;

    // state variables
    string public lastPriceQueryResult;
    uint public lastPrice;
    uint public settlementPrice;
    bool public isSettled;
    mapping(bytes32 => bool) validQueryIDs;

    // accounting
    mapping(address => UserNetPosition) addressToUserPosition;
    mapping(address => uint) userAddressToAccountBalance;   // stores account balances allowed to be allocated to orders
    mapping (bytes32 => int) public filledOrderQty;
    mapping (bytes32 => int) public cancelledOrderQty;
    uint collateralPoolBalance = 0;                         // current balance of all collateral committed

    // events
    event OracleQuerySuccess();
    event OracleQueryFailed();
    event UpdatedLastPrice(string price);
    event ContractSettled(uint settlePrice);
    event UpdatedUserBalance(address indexed user, uint balance);
    event UpdatedPoolBalance(uint balance);
    event Error(ErrorCodes indexed errorCode, bytes32 indexed orderHash);

    // order events
    event OrderFilled(
        address indexed maker,
        address indexed taker,
        address indexed feeRecipient,
        int filledQty,
        uint paidMakerFee,
        uint paidTakerFee,
        bytes32 indexed orderHash
    );
    event OrderCancelled(
        address indexed maker,
        address indexed feeRecipient,
        int cancelledQty,
        bytes32 indexed orderHash
    );

    /// @param contractName viewable name of this contract (BTC/ETH, LTC/ETH, etc)
    /// @param baseTokenAddress address of the ERC20 token that will be used for collateral and pricing
    /// @param oracleDataSource a data-source such as "URL", "WolframAlpha", "IPFS"
    /// see http://docs.oraclize.it/#ethereum-quick-start-simple-query
    /// @param oracleQuery see http://docs.oraclize.it/#ethereum-quick-start-simple-query for examples
    /// @param oracleQueryRepeatSeconds how often to repeat this callback to check for settlement, more frequent
    /// queries require more gas and may not be needed.
    /// @param floorPrice minimum tradeable price of this contract, contract enters settlement if breached
    /// @param capPrice maximum tradeable price of this contract, contract enters settlement if breached
    /// @param priceDecimalPlaces number of decimal places to convert our queried price from a floating point to
    /// an integer
    /// @param qtyDecimalPlaces decimal places to multiply traded qty by.
    /// @param secondsToExpiration - second from now that this contract expires and enters settlement
    function MarketContract(
        string contractName,
        address baseTokenAddress,
        string oracleDataSource,
        string oracleQuery,
        uint oracleQueryRepeatSeconds,
        uint floorPrice,
        uint capPrice,
        uint priceDecimalPlaces,
        uint qtyDecimalPlaces,
        uint secondsToExpiration
    ) public payable {

        require(capPrice > floorPrice);
        // TODO: check for minimum MEM token balance of caller.
        oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
        CONTRACT_NAME = contractName;
        BASE_TOKEN_ADDRESS = baseTokenAddress;
        BASE_TOKEN = ERC20(baseTokenAddress);
        PRICE_CAP = capPrice;
        PRICE_FLOOR = floorPrice;
        EXPIRATION = now + secondsToExpiration;
        ORACLE_DATA_SOURCE = oracleDataSource;
        ORACLE_QUERY = oracleQuery;
        ORACLE_QUERY_REPEAT = oracleQueryRepeatSeconds;
        PRICE_DECIMAL_PLACES = priceDecimalPlaces;
        QTY_DECIMAL_PLACES = qtyDecimalPlaces;
        require(checkSufficientStartingBalance(secondsToExpiration));
        queryOracle();  // schedules recursive calls to oracle
    }

    /*
    // EXTERNAL METHODS
    */

    // @param userAddress address to return position for
    // @return the users current open position.
    function getUserPosition(address userAddress) external view returns (int)  {
        return addressToUserPosition[userAddress].netPosition;
    }

    /// @notice deposits tokens to the smart contract to fund the user account and provide needed tokens for collateral
    /// pool upon trade matching.
    /// @param depositAmount qty of ERC20 tokens to deposit to the smart contract to cover open orders and collateral
    function depositTokensForTrading(uint256 depositAmount) external {
        // user must call approve!
        BASE_TOKEN.safeTransferFrom(msg.sender, this, depositAmount);
        uint256 balanceAfterDeposit = userAddressToAccountBalance[msg.sender].add(depositAmount);
        userAddressToAccountBalance[msg.sender] = balanceAfterDeposit;
        UpdatedUserBalance(msg.sender, balanceAfterDeposit);
    }

    // @notice called by a participant wanting to trade a specific order
    /// @param maker address of the maker of this order
    /// @param taker address of the designated taker or address(0) if publicly available to be traded
    /// @param feeRecipient address of a fee recipient, optional
    /// @param makerFee amount of MKT token for maker fee
    /// @param takerFee amount of MKT token for taker fee
    /// @param price of the order
    /// @param orderQty quantity of the order
    /// @param qtyToFill quantity taker is willing to fill of original order(max)
    /// @param expirationTimeStamp last valid timestamp of the order (seconds since epoch)
    /// @param v order signature
    /// @param r order signature
    /// @param s order signature
    function tradeOrder(
        address maker,
        address taker,
        address feeRecipient,
        uint makerFee,
        uint takerFee,
        uint price,
        int orderQty,
        int qtyToFill,
        uint expirationTimeStamp,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (int filledQty) {
        require(!isSettled);                                // no trading past settlement
        require(taker == address(0) || taker == msg.sender);// taker can be anyone, or specifically the caller!
        require(maker != address(0) && maker != taker);     // do not allow self trade
        require(orderQty != 0 && qtyToFill != 0);           // no zero trades
        require(orderQty.isSameSign(qtyToFill));            // signs should match

        bytes32 orderHash = address(this).createOrderHash(maker, feeRecipient,
                                makerFee, takerFee, orderQty, price, expirationTimeStamp);

        require(maker.isValidSignature(orderHash, v, r, s));

        if(now >= expirationTimeStamp) {
            Error(ErrorCodes.ORDER_EXPIRED, orderHash);
            return 0;
        }

        int remainingQty = orderQty.subtract(getQtyFilledOrCancelledFromOrder(orderHash));
        if(remainingQty == 0) { // there is no qty remaining  - cannot fill!
            Error(ErrorCodes.ORDER_DEAD, orderHash);
            return 0;
        }

        filledQty = MathLib.absMin(remainingQty, qtyToFill);
        updatePositions(maker, taker, filledQty, price);    // this will fail if any of the balances are insufficient

        uint paidMakerFee = 0;
        uint paidTakerFee = 0;

        if(feeRecipient != address(0)) { // we need to transfer fees to recipient

            if(makerFee > 0) {

            }

            if(takerFee > 0) {

            }
        }

        OrderFilled(maker, taker, feeRecipient, filledQty, paidMakerFee, paidTakerFee, orderHash);
        return filledQty;
    }

    // @notice called by the maker of an order to attempt to cancel the order before its expiration time stamp
    /// @param maker address of the maker of this order
    /// @param taker address of the designated taker or address(0) if publicly available to be traded
    /// @param feeRecipient address of a fee recipient, optional
    /// @param makerFee amount of MKT token for maker fee
    /// @param takerFee amount of MKT token for taker fee
    /// @param price of the order
    /// @param orderQty quantity of the order
    /// @param qtyToCancel quantity maker is attempting to cancel
    /// @param expirationTimeStamp last valid timestamp of the order (seconds since epoch)
    /// @return qty that was successfully cancelled of order.
    function cancelOrder(
        address maker,
        address taker,
        address feeRecipient,
        uint makerFee,
        uint takerFee,
        uint price,
        int orderQty,
        int qtyToCancel,
        uint expirationTimeStamp
    ) external returns (int qtyCancelled){
        require(maker == msg.sender);                                       // only maker can cancel standing order
        require(qtyToCancel != 0 && qtyToCancel.isSameSign(orderQty));      // cannot cancel 0 and signs must match
        require(!isSettled);

        bytes32 orderHash = address(this).createOrderHash(maker, feeRecipient,
            makerFee, takerFee, orderQty, price, expirationTimeStamp);

        if(now >= expirationTimeStamp) {
            Error(ErrorCodes.ORDER_EXPIRED, orderHash);
            return 0;
        }

        int remainingQty = orderQty.subtract(getQtyFilledOrCancelledFromOrder(orderHash));
        if(remainingQty == 0) { // there is no qty remaining to cancel order is dead
            Error(ErrorCodes.ORDER_DEAD, orderHash);
            return 0;
        }

        qtyCancelled = MathLib.absMin(qtyToCancel, remainingQty);   // we can only cancel what remains
        cancelledOrderQty[orderHash] = cancelledOrderQty[orderHash].add(qtyCancelled);
        OrderCancelled(maker, feeRecipient, cancelledQty, orderHash);
        return qtyCancelled;
    }

    // @notice called by a user after settlement has occurred.  This function will finalize all accounting around any
    // outstanding positions and return all remaining collateral to the caller. This should only be called after
    // settlement has occurred.
    function settleAndClose() external {
        require(isSettled);
        UserNetPosition storage userNetPos = addressToUserPosition[msg.sender];
        if(userNetPos.netPosition != 0) {
            // this user has a position that we need to settle based upon the settlement price of the contract
            reduceUserNetPosition(msg.sender, userNetPos.netPosition * - 1, settlementPrice);
        }
        withdrawTokens(userAddressToAccountBalance[msg.sender]);   // transfer all balances back to user.
    }

    /*
    // PUBLIC METHODS
    */

    /// @param queryID of the returning query, this should match our own internal mapping
    /// @param result query to be processed
    /// @param proof result proof
    function __callback(bytes32 queryID, string result, bytes proof) public {
        require(validQueryIDs[queryID]);
        require(msg.sender == oraclize_cbAddress());
        lastPriceQueryResult = result;
        lastPrice = parseInt(result, PRICE_DECIMAL_PLACES);
        UpdatedLastPrice(result);
        delete validQueryIDs[queryID];
        checkSettlement();
        if (!isSettled) {
            queryOracle();  // set up our next query
        }
    }

    /// @notice returns the qty that is no longer available to trade for a given order
    /// @param orderHash hash of order to find filled and cancelled qty
    /// @return int quantity that is no longer able to filled from the supplied order hash
    function getQtyFilledOrCancelledFromOrder(bytes32 orderHash) public view returns (int) {
        return filledOrderQty[orderHash].add(cancelledOrderQty[orderHash]);
    }

    /// @notice removes token from users trading account
    /// @param withdrawAmount qty of token to attempt to withdraw
    function withdrawTokens(uint256 withdrawAmount) public {
        require(userAddressToAccountBalance[msg.sender] >= withdrawAmount);   // ensure sufficient balance
        uint256 balanceAfterWithdrawal = userAddressToAccountBalance[msg.sender].subtract(withdrawAmount);
        userAddressToAccountBalance[msg.sender] = balanceAfterWithdrawal;   // update balance before external call!
        BASE_TOKEN.safeTransfer(msg.sender, withdrawAmount);
        UpdatedUserBalance(msg.sender, balanceAfterWithdrawal);
    }

    /*
    // PRIVATE METHODS
    */

    /// @param maker address of the maker in the trade
    /// @param taker address of the taker in the trade
    /// @param qty quantity transacted between parties
    /// @param price agreed price of the matched trade.
    function updatePositions(address maker, address taker, int qty, uint price) private {
        updatePosition(maker, qty, price);
        // continue process for taker, but qty is opposite sign for taker
        updatePosition(taker, qty * -1, price);

    }

    /// @param userAddress storage struct containing position information for this user
    /// @param qty signed quantity this users position is changing by, + for buy and - for sell
    /// @param price transacted price of the new position / trade
    function updatePosition(address userAddress, int qty, uint price) private {
        UserNetPosition storage userNetPosition = addressToUserPosition[userAddress];
        if(userNetPosition.netPosition == 0 ||  userNetPosition.netPosition.isSameSign(qty)) {
            // new position or adding to open pos
            addUserNetPosition(userNetPosition, userAddress, qty, price);
        }
        else {
            // opposite side from open position, reduce, flattened, or flipped.
            if(userNetPosition.netPosition >= qty * -1) { // pos is reduced of flattened
                reduceUserNetPosition(userNetPosition, qty, price);
            } else {    // pos is flipped, reduce and then create new open pos!
                reduceUserNetPosition(userNetPosition, userNetPosition.netPosition * -1, price); // flatten completely
                int newNetPos = userNetPosition.netPosition + qty;            // the portion remaining after flattening
                addUserNetPosition(userNetPosition, userAddress, newNetPos, price);
            }
        }
        userNetPosition.netPosition.add(qty);   // keep track of total net pos across all prices for user.
    }

    /// @dev calculates the needed collateral for a new position and commits it to the pool removing it from the
    /// users account and creates the needed Position struct to record the new position.
    /// @param userNetPosition current positions held by user
    /// @param userAddress address of user entering into the position
    /// @param qty signed quantity of the trade
    /// @param price agreed price of trade
    function addUserNetPosition(
        UserNetPosition storage userNetPosition,
        address userAddress,
        int qty,
        uint price
    ) private {
        uint neededCollateral = MathLib.calculateNeededCollateral(this, qty, price);
        commitCollateralToPool(userAddress, neededCollateral);
        userNetPosition.positions.push(Position(price, qty));   // append array with new position
    }

    /// @param userAddress address of user who is reducing their pos
    /// @param userNetPos storage struct for this users position
    /// @param qty signed quantity of the qty to reduce this users position by
    /// @param price transacted price
    function reduceUserNetPosition(
        address userAddress,
        UserNetPosition storage userNetPos,
        int qty,
        uint price
    ) private {
        uint collateralToReturnToUserAccount = 0;
        int qtyToReduce = qty;                      // note: this sign is opposite of our users position
        assert(userNetPos.positions.length != 0);   // sanity check
        while(qtyToReduce != 0) {   //TODO: ensure we dont run out of gas here!
            Position storage position = userNetPos.positions[userNetPos.positions.length - 1];  // get the last pos (LIFO)
            if(position.qty.abs() <= qtyToReduce.abs()) {   // this position is completely consumed!
                collateralToReturnToUserAccount.add(MathLib.calculateNeededCollateral(this, position.qty, price));
                qtyToReduce = qtyToReduce.add(position.qty);
                userNetPos.positions.length--;  // remove this position from our array.
            }
            else {  // this position stays, just reduce the qty.
                position.qty = position.qty.add(qtyToReduce);
                // pos is opp sign of qty we are reducing here!
                collateralToReturnToUserAccount.add(MathLib.calculateNeededCollateral(this, qtyToReduce * -1, price));
                //qtyToReduce = 0; // completely reduced now!
                break;
            }
        }

        if(collateralToReturnToUserAccount != 0) {  // allocate funds back to user acct.
            withdrawCollateralFromPool(userAddress, collateralToReturnToUserAccount);
        }
    }

    /// @notice moves collateral from a user's account to the pool upon trade execution.
    /// @param fromAddress address of user entering trade
    /// @param collateralAmount amount of collateral to transfer from user account to collateral pool
    function commitCollateralToPool(address fromAddress, uint collateralAmount) private {
        require(userAddressToAccountBalance[fromAddress] >= collateralAmount);   // ensure sufficient balance
        uint newBalance = userAddressToAccountBalance[fromAddress].subtract(collateralAmount);
        userAddressToAccountBalance[fromAddress] = newBalance;
        collateralPoolBalance = collateralPoolBalance.add(collateralAmount);
        UpdatedUserBalance(fromAddress, newBalance);
        UpdatedPoolBalance(collateralPoolBalance);
    }

    /// @notice withdraws collateral from pool to a user account upon exit or trade settlement
    /// @param toAddress address of user
    /// @param collateralAmount amount to transfer from pool to user.
    function withdrawCollateralFromPool(address toAddress, uint collateralAmount) private {
        require(collateralPoolBalance >= collateralAmount); // ensure sufficient balance
        uint newBalance = userAddressToAccountBalance[toAddress].add(collateralAmount);
        userAddressToAccountBalance[toAddress] = newBalance;
        collateralPoolBalance = collateralPoolBalance.subtract(collateralAmount);
        UpdatedUserBalance(toAddress, newBalance);
        UpdatedPoolBalance(collateralPoolBalance);
    }

    /// @dev call to oraclize to set up our query and record its hash.
    function queryOracle() private {
        if (oraclize_getPrice(ORACLE_DATA_SOURCE) > this.balance) {
            OracleQueryFailed();
            lastPriceQueryResult = "FAILED"; //TODO: failsafe
        } else {
            OracleQuerySuccess();
            bytes32 queryId = oraclize_query(ORACLE_QUERY_REPEAT, ORACLE_DATA_SOURCE, ORACLE_QUERY, QUERY_CALLBACK_GAS);
            validQueryIDs[queryId] = true;
        }
    }

    /// @dev checks our last query price to see if our contract should enter settlement due to it being past our
    //  expiration date or outside of our tradeable ranges.
    function checkSettlement() private {
        if(isSettled)   // already settled.
            return;

        if(now > EXPIRATION) {  // note: miners can cheat this by small increments of time (minutes, not hours)
            isSettled = true;   // time based expiration has occurred.
        } else if(lastPrice >= PRICE_CAP || lastPrice <= PRICE_FLOOR) {
            isSettled = true;   // we have breached/touched our pricing bands
        }

        if(isSettled) {
            settleContract();
        }
    }

    /// @dev records our final settlement price and fires needed events.
    /// @param finalSettlementPrice final query price at time of settlement
    function settleContract(uint finalSettlementPrice) private {
        settlementPrice = finalSettlementPrice;
        ContractSettled(finalSettlementPrice);
        // TODO: return any remaining ether balance to creator of this contract (no longer needs gas for queries)
    }

    /// @dev over estimates needed gas to power queries until expiration and determines if provided contract
    /// contains enough.
    /// @param secondsToExpiration seconds from now that expiration is scheduled.
    /// @returns true if sufficient gas is present to create queries at the designated
    /// frequency from now until expiration
    function checkSufficientStartingBalance(uint secondsToExpiration) private view returns (bool isSufficient) {
        //uint costPerQuery = oraclize_getPrice(ORACLE_DATA_SOURCE); this doesn't work prior to first query(its free)
        uint expectedNoOfQueries = secondsToExpiration / ORACLE_QUERY_REPEAT;
        uint approxGasRequired = COST_PER_QUERY * expectedNoOfQueries;
        return this.balance > (approxGasRequired * 2);
    }
}


Make UINT_MAX public

Make UINT_MAX public

contract Adjudicator {

	uint public constant UINT_MAX = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

	bool public frozen = false;
	uint nonce = 0;
	uint lastTimestamp = 0;
	address owner;
	uint timeout;
	bytes32 public stateHash;

	modifier onlyOwner {
		if (msg.sender == owner) {
			_
		} else {
			throw;
		}
	}

	modifier notFrozen {
		if (frozen) {
			throw;
		} else {
			_
		}
	}

	function Adjudicator(address _owner, uint _timeout) {
		owner = _owner;
		timeout = _timeout;
	}

	function submit(uint _newNonce, bytes32 _stateHash)
		external
		onlyOwner
		notFrozen
		returns (bool)
	{
		if (_newNonce > nonce) {
			nonce = _newNonce;
			stateHash = _stateHash;
			return true;
		} else {
			return false;
		}
	}

	function unfreeze() external onlyOwner returns (bool) {
		if (frozen && nonce != UINT_MAX) {
			lastTimestamp = 0;
			frozen = false;
			return true;
		} else {
			return false;
		}
	}

	function finalize() external notFrozen returns (bool) {
		if (nonce == UINT_MAX || (lastTimestamp != 0 && now > lastTimestamp + timeout)) {
			frozen = true;
			return true;
		} else {
			return false;
		}
	}

	function kill(address _recipient) external onlyOwner {
		selfdestruct(_recipient);
	}
}

contract Adjudicator {

	uint constant UINT_MAX = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

	bool public frozen = false;
	uint nonce = 0;
	uint lastTimestamp = 0;
	address owner;
	uint timeout;
	bytes32 public stateHash;

	modifier onlyOwner {
		if (msg.sender == owner) {
			_
		} else {
			throw;
		}
	}

	modifier notFrozen {
		if (frozen) {
			throw;
		} else {
			_
		}
	}

	function Adjudicator(address _owner, uint _timeout) {
		owner = _owner;
		timeout = _timeout;
	}

	function submit(uint _newNonce, bytes32 _stateHash)
		external
		onlyOwner
		notFrozen
		returns (bool)
	{
		if (_newNonce > nonce) {
			nonce = _newNonce;
			stateHash = _stateHash;
			return true;
		} else {
			return false;
		}
	}

	function unfreeze() external onlyOwner returns (bool) {
		if (frozen && nonce != UINT_MAX) {
			lastTimestamp = 0;
			frozen = false;
			return true;
		} else {
			return false;
		}
	}

	function finalize() external notFrozen returns (bool) {
		if (nonce == UINT_MAX || (lastTimestamp != 0 && now > lastTimestamp + timeout)) {
			frozen = true;
			return true;
		} else {
			return false;
		}
	}

	function kill(address _recipient) external onlyOwner {
		selfdestruct(_recipient);
	}
}


Fix revert message.

Fix revert message.

pragma solidity ^0.5.10;

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

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

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

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

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

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

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

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

}

pragma solidity ^0.5.10;

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

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

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

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

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

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

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

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

}


events

events

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, uint buyIn) {
        require(buyIn > 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 = buyIn;
        pot.players.push(msg.sender);
        pot.buyIn = buyIn;

        allPots.push(pot);

        newPot(name, buyIn, msg.sender)
    }

    function joinPot(string name) {
        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 bet 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);

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

        event potClosed(name, pot.players[loserIndex]);
    }
}

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(address => Pot[]) playerToPots;
    mapping(string => Pot) nameToPot;

    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 getMyPots() constant returns (Pot[]){
        return playerToPots(msg.sender);
    }

    function getAllPots() constant returns (Pot[]){
        return allPots;
    }

    function getPot(string name) constant returns (Pot){
        return nameToPot[name];
    }

    function createPot(string name, uint buyIn) {
        require(buyIn > 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 = buyIn;
        pot.players.push(msg.sender);
        pot.buyIn = buyIn;

        allPots.push(pot);
        playerToPots[msg.sender].push(pot);
    }

    function joinPot(string name) {
        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 bet buyIn amount

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

    /*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
            }

            return;
        }

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

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


Review wording of SafeMath need in Solidity 0.8 (#2898)

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}


Add the solidity version declaration in the Vote.sol smart contract.

pragma solidity ^0.4.2;

contract Vote {

    event Ballot (
        address indexed voter,
        uint8 proposal
    );

    event VoterRegistered (
        address indexed voter
    );

    event VoteError (
        address indexed user,
        string message
    );

    struct Voter {
        bool registered;
        bool voted;
        uint8 vote;
    }

    mapping(address => Voter) voters;
    address chairperson;
    uint[] results;

    /* This unnamed function is called whenever someone tries to send ether to it */
    function () {
        throw; // Prevents accidental sending of ether
    }

    // Create a new vote with $(_numProposals) different results.
    function Vote(uint8 _numProposals) {
        chairperson = msg.sender;
        results.length = _numProposals;
    }

    modifier onlyChairPerson() {
        if (msg.sender != chairperson)
            throw;
        _;
    }

    modifier onlyRegisteredVoter() {
        Voter voter = voters[msg.sender];

        if (voter.voted || !voter.registered)
            throw;
        _;
    }

    function registerVoter(address voterAddress) onlyChairPerson {
        Voter voter = voters[voterAddress];

        if (voter.voted || voter.registered)
            throw;

        voter.registered = true;

        VoterRegistered(voterAddress);
    }

    // Give a single vote to proposal $(proposal).
    function vote(uint8 proposal) onlyRegisteredVoter {
        Voter voter = voters[msg.sender];

        if (proposal >= results.length)
            return; // FIXME: emit a BallotError event

        voter.voted = true;
        voter.vote = proposal;
        results[proposal] += 1;

        Ballot(msg.sender, proposal);
    }

    function cancelVote() onlyRegisteredVoter {
        Voter voter = voters[msg.sender];

        results[voter.vote] -= 1;

        voter.voted = false;
    }

    function getVoteResults() constant returns (uint[]) {
        return results;
    }
}


change to or-equals

change to or-equals

pragma solidity ^0.4.11;

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.4.11;

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

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

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

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

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

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

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

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

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

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


linting

linting

pragma solidity ^0.4.11;
contract PotOfEther {

    struct Pot {
        string name;
        uint buyIn;

        address[] players;

        uint lastPlayerBlockNumber;

        bool isOpen;
    }

    address public owner;

    mapping(string => Pot) nameToPot;
    mapping(address => uint) public refunds;
    uint public totalPendingRefunds;

    event LogPotCreated(string name, uint buyIn);
    event LogPotJoined(string name, address indexed newPlayer, uint buyIn);
    event LogPotFull(string name);
    event LogPotClosed(string name);
    event LogPotWinner(string name, address indexed winner, uint refundAmount);
    event LogPotLoser(string name, address indexed loser);
    event LogAccountRefund(address indexed account, uint refundAmount);

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

    function availableOwnerWithdraw() constant returns (uint) {
        return this.balance - totalPendingRefunds;
    }

    function ownerWithdraw() {
        owner.transfer(availableOwnerWithdraw());
    }

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

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

        totalPendingRefunds += pot.buyIn; // owner can't withdraw this funds while pot is open

        LogPotCreated(name, msg.value);
        LogPotJoined(name, msg.sender, msg.value);
    }

    function joinPot(string name) payable {
        Pot storage pot = nameToPot[name];
        require(pot.isOpen); // pot exists and isn't over
        require(pot.players.length < 3); // pot isn't full
        require(msg.value == pot.buyIn); // must pay buyIn amount
        for (uint i = 0; i < pot.players.length; i++) {
            require(pot.players[i] != msg.sender); //must be new to this pot
        }

        pot.players.push(msg.sender);
        LogPotJoined(name, msg.sender, msg.value);

        totalPendingRefunds += pot.buyIn; // owner can't withdraw this funds while pot is open

        if (pot.players.length == 3) {
            pot.lastPlayerBlockNumber = block.number;
            LogPotFull(name);
        }
    }

    function canClosePot(string name) constant returns (bool) {
        Pot storage pot = nameToPot[name];
        return pot.isOpen && pot.players.length == 3 && block.number > pot.lastPlayerBlockNumber + 1;
    }

    function closePot(string name) {
        Pot storage pot = nameToPot[name];
        require(pot.isOpen); // pot isn't closed
        require(pot.players.length == 3); // pot full
        require(block.number > pot.lastPlayerBlockNumber + 1);

        pot.isOpen = false;
        LogPotClosed(name);
        totalPendingRefunds -= (pot.buyIn * 3);

        bytes32 blockHash = block.blockhash(block.number);

        bytes32 potShaResult = sha3(name, blockHash);
        uint8 loserIndex = uint8(uint256(potShaResult) % 3);

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

        uint fee = pot.buyIn / 100;
        uint playerWinAmount = (pot.buyIn - fee) / 2; // take 1% fee and split winnins
        uint winnerRefundAmount = pot.buyIn + playerWinAmount;

        refunds[winner1] += winnerRefundAmount;
        totalPendingRefunds += winnerRefundAmount;

        refunds[winner2] += winnerRefundAmount;
        totalPendingRefunds += winnerRefundAmount;

        LogPotWinner(name, winner1, winnerRefundAmount);
        LogPotWinner(name, winner2, winnerRefundAmount);
        LogPotLoser(name, loser);
    }

    function withdrawRefund() {
        uint refund = refunds[msg.sender];
        refunds[msg.sender] = 0;
        totalPendingRefunds -= refund;

        msg.sender.transfer(refund);
        LogAccountRefund(msg.sender, refund);
    }
}

pragma solidity ^0.4.11;
contract PotOfEther {

    struct Pot {
        string name;
        uint buyIn;

        address[] players;

        uint lastPlayerBlockNumber;

        bool isOpen;
    }

    address public owner;

    mapping(string => Pot) nameToPot;
    mapping(address => uint) public refunds;
    uint public totalPendingRefunds;

    event LogPotCreated(string name, uint buyIn);
    event LogPotJoined(string name, address indexed newPlayer, uint buyIn);
    event LogPotFull(string name);
    event LogPotClosed(string name);
    event LogPotWinner(string name, address indexed winner, uint refundAmount);
    event LogPotLoser(string name, address indexed loser);
    event LogAccountRefund(address indexed account, uint refundAmount);

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

    function availableOwnerWithdraw() constant returns (uint){
        return this.balance - totalPendingRefunds;
    }

    function ownerWithdraw(){
        owner.transfer(availableOwnerWithdraw());
    }

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

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

        totalPendingRefunds += pot.buyIn; // owner can't withdraw this funds while pot is open

        LogPotCreated(name, msg.value);
        LogPotJoined(name, msg.sender, msg.value);
    }

    function joinPot(string name) payable {
        Pot storage pot = nameToPot[name];
        require(pot.isOpen); // pot exists and isn't over
        require(pot.players.length < 3); // pot isn't full
        require(msg.value == pot.buyIn); // must pay buyIn amount
        for(uint i = 0; i < pot.players.length; i++){
            require(pot.players[i] != msg.sender); //must be new to this pot
        }

        pot.players.push(msg.sender);
        LogPotJoined(name, msg.sender, msg.value);

        totalPendingRefunds += pot.buyIn; // owner can't withdraw this funds while pot is open

        if(pot.players.length == 3){
            pot.lastPlayerBlockNumber = block.number;
            LogPotFull(name);
        }
    }

    function canClosePot(string name) constant returns (bool){
        Pot storage pot = nameToPot[name];
        return pot.isOpen &&
                pot.players.length == 3 &&
                block.number > pot.lastPlayerBlockNumber + 1;
    }

    function closePot(string name){
        Pot storage pot = nameToPot[name];
        require(pot.isOpen); // pot isn't closed
        require(pot.players.length == 3); // pot full
        require(block.number > pot.lastPlayerBlockNumber + 1);

        pot.isOpen = false;
        LogPotClosed(name);
        totalPendingRefunds -= (pot.buyIn * 3);

        bytes32 blockHash = block.blockhash(block.number);

        bytes32 potShaResult = sha3(name, blockHash);
        uint8 loserIndex = uint8(uint256(potShaResult) % 3);

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

        uint fee = pot.buyIn / 100;
        uint playerWinAmount = (pot.buyIn - fee) / 2; // take 1% fee and split winnins
        uint winnerRefundAmount = pot.buyIn + playerWinAmount;

        refunds[winner1] += winnerRefundAmount;
        totalPendingRefunds += winnerRefundAmount;

        refunds[winner2] += winnerRefundAmount;
        totalPendingRefunds += winnerRefundAmount;

        LogPotWinner(name, winner1, winnerRefundAmount);
        LogPotWinner(name, winner2, winnerRefundAmount);
        LogPotLoser(name, loser);
    }

    function withdrawRefund(){
        uint refund = refunds[msg.sender];
        refunds[msg.sender] = 0;
        totalPendingRefunds -= refund;

        msg.sender.transfer(refund);
        LogAccountRefund(msg.sender, refund);
    }
}


Update conference

Update conference

- Prevent the same account from booking more than one ticket
- Refund ether when no ticket is purchased

pragma solidity ^0.4.6;

contract Conference {

	address Organizer;
	mapping (address => uint) RegistrantsPaid;
	uint public Registrants;
	uint Quota;

	event Deposit(address from, uint amount);
	event Refund(address to, uint amount);

	function Conference()
    {
		Organizer = msg.sender;
		Quota = 5;
		Registrants = 0;
	}

	function GetQuota() constant returns(uint)
	{
		return Quota;
	}

	function BuyTicket() payable
    {
		if (msg.value > 0)
		{
			if (Registrants < Quota && RegistrantsPaid[msg.sender] == 0)
			{
				RegistrantsPaid[msg.sender] = msg.value;
				Registrants++;
				Deposit(msg.sender, msg.value);
			}
			else
			{
				if (!msg.sender.send(msg.value))
				{
					throw;
				}
			}
		}
	}

	function ChangeQuota(uint newquota) public
    {
		if (msg.sender != Organizer)
        {
            throw;
        }

		Quota = newquota;
	}

	function RefundTicket(address recipient, uint amount) public
    {
		if (msg.sender != Organizer)
        {
            throw;
        }

		if (RegistrantsPaid[recipient] == amount)
        {
			address myAddress = this;

            if (myAddress.balance >= amount) {
				if (recipient.send(amount))
				{
				    Refund(recipient, amount);
				    RegistrantsPaid[recipient] = 0;
				    Registrants--;
				}
			}
		}
	}

	function Destroy()
    {
		if (msg.sender == Organizer)
        {
            // without this funds could be locked in the contract forever!
			suicide(Organizer);
		}
	}
}

pragma solidity ^0.4.6;

contract Conference {

	address Organizer;
	mapping (address => uint) RegistrantsPaid;
	uint public Registrants;
	uint Quota;

	event Deposit(address from, uint amount);
	event Refund(address to, uint amount);

	function Conference()
    {
		Organizer = msg.sender;
		Quota = 5;
		Registrants = 0;
	}

	function GetQuota() constant returns(uint)
	{
		return Quota;
	}

	function BuyTicket() payable
    {
		if (Registrants < Quota)
        {
            RegistrantsPaid[msg.sender] = msg.value;
            Registrants++;
            Deposit(msg.sender, msg.value);
        }
	}

	function ChangeQuota(uint newquota) public
    {
		if (msg.sender != Organizer)
        {
            throw;
        }

		Quota = newquota;
	}

	function RefundTicket(address recipient, uint amount) public
    {
		if (msg.sender != Organizer)
        {
            throw;
        }

		if (RegistrantsPaid[recipient] == amount)
        {
			address myAddress = this;

            if (myAddress.balance >= amount) {
				if (recipient.send(amount))
				{
				    Refund(recipient, amount);
				    RegistrantsPaid[recipient] = 0;
				    Registrants--;
				}
			}
		}
	}

	function Destroy()
    {
		if (msg.sender == Organizer)
        {
            // without this funds could be locked in the contract forever!
			suicide(Organizer);
		}
	}
}


tests: restore suicide

tests: restore suicide

pragma solidity 0.5.0;

contract Suicide {

  function kill(address payable addr) public {
    selfdestruct(addr);
  }

}