Create SingleIndexModule.sol

Create SingleIndexModule.sol

/*
    Copyright 2020 Set Labs Inc.
    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.
    SPDX-License-Identifier: Apache License, Version 2.0
*/

pragma solidity 0.6.10;
pragma experimental "ABIEncoderV2";

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { Math } from "@openzeppelin/contracts/math/Math.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import { SafeCast } from "@openzeppelin/contracts/utils/SafeCast.sol";
import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";

import { AddressArrayUtils } from "../../lib/AddressArrayUtils.sol";
import { IController } from "../../interfaces/IController.sol";
import { Invoke } from "../lib/Invoke.sol";
import { ISetToken } from "../../interfaces/ISetToken.sol";
import { IWETH } from "../../interfaces/external/IWETH.sol";
import { ModuleBase } from "../lib/ModuleBase.sol";
import { Position } from "../lib/Position.sol";
import { PreciseUnitMath } from "../../lib/PreciseUnitMath.sol";
import { Uint256ArrayUtils } from "../../lib/Uint256ArrayUtils.sol";

/**
 * @title SingleIndexModule
 * @author Set Protocol
 *
 * Smart contract that facilitates rebalances for indices. Manager can set target unit amounts, max trade sizes, the
 * exchange to trade on, and the cool down period between trades (on a per asset basis). As currently constructed
 * the module only works for one Set at a time.
 *
 * SECURITY ASSUMPTION:
 *  - Works with following modules: StreamingFeeModule, BasicIssuanceModule (any other module additions to Sets using
      this module need to be examined separately)
 */
contract SingleIndexModule is ModuleBase, ReentrancyGuard {
    using SafeCast for int256;
    using SafeCast for uint256;
    using SafeMath for uint256;
    using Position for uint256;
    using Math for uint256;
    using Position for ISetToken;
    using Invoke for ISetToken;
    using AddressArrayUtils for address[];
    using Uint256ArrayUtils for uint256[];

    /* ============ Structs ============ */

    struct AssetTradeInfo {
        uint256 targetUnit;              // Target unit for the asset during current rebalance period
        uint256 maxSize;                 // Max trade size in precise units
        uint256 coolOffPeriod;           // Required time between trades for the asset
        uint256 lastTradeTimestamp;      // Timestamp of last trade
        uint256 exchange;                // Integer representing ID of exchange to use
    }

    /* ============ Enums ============ */

    // Enum of exchange Ids
    enum ExchangeId {
        None,
        Uniswap,
        Sushiswap,
        Balancer,
        Last
    }

    /* ============ Events ============ */

    event TargetUnitsUpdated(address indexed _component, uint256 _newUnit, uint256 _positionMultiplier);
    event TradeMaximumUpdated(address indexed _component, uint256 _newMaximum);
    event AssetExchangeUpdated(address indexed _component, uint256 _newExchange);
    event CoolOffPeriodUpdated(address indexed _component, uint256 _newCoolOffPeriod);
    event TraderStatusUpdated(address indexed _trader, bool _status);
    event AnyoneTradeUpdated(bool indexed _status);
    event TradeExecuted(
        address indexed _executor,
        address indexed _sellComponent,
        address indexed _buyComponent,
        uint256 _amountSold,
        uint256 _amountBought
    );

    /* ============ Constants ============ */

    uint256 private constant TARGET_RAISE_DIVISOR = 1.0025e18;       // Raise targets 25 bps
    uint256 private constant BALANCER_POOL_LIMIT = 3;                // Amount of pools examined when fetching quote

    string private constant UNISWAP_OUT = "swapTokensForExactTokens(uint256,uint256,address[],address,uint256)";
    string private constant UNISWAP_IN = "swapExactTokensForTokens(uint256,uint256,address[],address,uint256)";
    string private constant BALANCER_OUT = "smartSwapExactOut(address,address,uint256,uint256,uint256)";
    string private constant BALANCER_IN = "smartSwapExactIn(address,address,uint256,uint256,uint256)";

    /* ============ State Variables ============ */

    mapping(address => AssetTradeInfo) public assetInfo;    // Mapping of component to component restrictions
    address[] public rebalanceComponents;                   // Components having units updated during current rebalance
    uint256 public positionMultiplier;                      // Position multiplier when current rebalance units were devised
    mapping(address => bool) public tradeAllowList;         // Mapping of addresses allowed to call trade()
    bool public anyoneTrade;                                // Toggles on or off skipping the tradeAllowList
    ISetToken public index;                                 // Index being managed with contract
    IWETH public weth;                                      // Weth contract address
    address public uniswapRouter;                           // Uniswap router address
    address public sushiswapRouter;                         // Sushiswap router address
    address public balancerProxy;                           // Balancer exchange proxy address

    /* ============ Modifiers ============ */

    modifier onlyAllowedTrader(address _caller) {
        require(_isAllowedTrader(_caller), "Address not permitted to trade");
        _;
    }

    modifier onlyEOA() {
        require(msg.sender == tx.origin, "Caller must be EOA Address");
        _;
    }

    /* ============ Constructor ============ */

    constructor(
        IController _controller,
        IWETH _weth,
        address _uniswapRouter,
        address _sushiswapRouter,
        address _balancerProxy
    )
    public
    ModuleBase(_controller)
    {
        weth = _weth;
        uniswapRouter = _uniswapRouter;
        sushiswapRouter = _sushiswapRouter;
        balancerProxy = _balancerProxy;
    }

    /**
     * MANAGER ONLY: Set new target units, zeroing out any units for components being removed from index. Log position multiplier to
     * adjust target units in case fees are accrued. Validate that weth is not a part of the new allocation and that all components
     * in current allocation are in _components array.
     *
     * @param _newComponents                    Array of new components to add to allocation
     * @param _newComponentsTargetUnits         Array of target units at end of rebalance for new components, maps to same index of component
     * @param _oldComponentsTargetUnits         Array of target units at end of rebalance for old component, maps to same index of component,
     *                                               if component being removed set to 0.
     * @param _positionMultiplier               Position multiplier when target units were calculated, needed in order to adjust target units
     *                                               if fees accrued
     */
    function startRebalance(
        address[] calldata _newComponents,
        uint256[] calldata _newComponentsTargetUnits,
        uint256[] calldata _oldComponentsTargetUnits,
        uint256 _positionMultiplier
    )
    external
    onlyManagerAndValidSet(index)
    {
        // Don't use validate arrays because empty arrays are valid
        require(_newComponents.length == _newComponentsTargetUnits.length, "Array length mismatch");

        address[] memory currentComponents = index.getComponents();
        require(currentComponents.length == _oldComponentsTargetUnits.length, "New allocation must have target for all old components");

        address[] memory aggregateComponents = currentComponents.extend(_newComponents);
        uint256[] memory aggregateTargetUnits = _oldComponentsTargetUnits.extend(_newComponentsTargetUnits);

        require(!aggregateComponents.hasDuplicate(), "Cannot duplicate components");

        for (uint256 i = 0; i < aggregateComponents.length; i++) {
            address component = aggregateComponents[i];
            uint256 targetUnit = aggregateTargetUnits[i];

            require(address(component) != address(weth), "WETH cannot be an index component");
            assetInfo[component].targetUnit = targetUnit;

            emit TargetUnitsUpdated(component, targetUnit, _positionMultiplier);
        }

        rebalanceComponents = aggregateComponents;
        positionMultiplier = _positionMultiplier;
    }

    /**
     * ACCESS LIMITED: Only approved addresses can call if anyoneTrade is false. Determines trade size
     * and direction and swaps into or out of WETH on exchange specified by manager.
     *
     * @param _component            Component to trade
     */
    function trade(address _component) external nonReentrant onlyAllowedTrader(msg.sender) onlyEOA() virtual {

        _validateTradeParameters(_component);

        (
        bool isBuy,
        uint256 tradeAmount
        ) = _calculateTradeSizeAndDirection(_component);

        if (isBuy) {
            _buyUnderweight(_component, tradeAmount);
        } else {
            _sellOverweight(_component, tradeAmount);
        }

        assetInfo[_component].lastTradeTimestamp = block.timestamp;
    }

    /**
     * ACCESS LIMITED: Only approved addresses can call if anyoneTrade is false. Only callable when 1) there are no
     * more components to be sold and, 2) entire remaining WETH amount can be traded such that resulting inflows won't
     * exceed components maxTradeSize nor overshoot the target unit. To be used near the end of rebalances when a
     * component's calculated trade size is greater in value than remaining WETH.
     *
     * @param _component            Component to trade
     */
    function tradeRemainingWETH(address _component) external nonReentrant onlyAllowedTrader(msg.sender) onlyEOA() virtual {
        require(_noTokensToSell(), "Must sell all sellable tokens before can be called");

        _validateTradeParameters(_component);

        (, uint256 tradeLimit) = _calculateTradeSizeAndDirection(_component);

        uint256 preTradeComponentAmount = IERC20(_component).balanceOf(address(index));
        uint256 preTradeWethAmount = weth.balanceOf(address(index));

        _executeTrade(address(weth), _component, true, preTradeWethAmount, assetInfo[_component].exchange);

        (,
        uint256 componentTradeSize
        ) = _updatePositionState(address(weth), _component, preTradeWethAmount, preTradeComponentAmount);

        require(componentTradeSize < tradeLimit, "Trade size exceeds trade size limit");

        assetInfo[_component].lastTradeTimestamp = block.timestamp;
    }

    /**
     * ACCESS LIMITED: For situation where all target units met and remaining WETH, uniformly raise targets by same
     * percentage in order to allow further trading. Can be called multiple times if necessary, increase should be
     * small in order to reduce tracking error.
     */
    function raiseAssetTargets() external nonReentrant onlyAllowedTrader(msg.sender) virtual {
        require(
            _allTargetsMet() && index.getDefaultPositionRealUnit(address(weth)) > 0,
            "Targets must be met and ETH remaining in order to raise target"
        );

        positionMultiplier = positionMultiplier.preciseDiv(TARGET_RAISE_DIVISOR);
    }

    /**
     * MANAGER ONLY: Set trade maximums for passed components
     *
     * @param _components            Array of components
     * @param _tradeMaximums         Array of trade maximums mapping to correct component
     */
    function setTradeMaximums(
        address[] calldata _components,
        uint256[] calldata _tradeMaximums
    )
    external
    onlyManagerAndValidSet(index)
    {
        _validateArrays(_components, _tradeMaximums);

        for (uint256 i = 0; i < _components.length; i++) {
            assetInfo[_components[i]].maxSize = _tradeMaximums[i];
            emit TradeMaximumUpdated(_components[i], _tradeMaximums[i]);
        }
    }

    /**
     * MANAGER ONLY: Set exchange for passed components
     *
     * @param _components        Array of components
     * @param _exchanges         Array of exchanges mapping to correct component, uint256 used to signify exchange
     */
    function setExchanges(
        address[] calldata _components,
        uint256[] calldata _exchanges
    )
    external
    onlyManagerAndValidSet(index)
    {
        _validateArrays(_components, _exchanges);

        for (uint256 i = 0; i < _components.length; i++) {
            uint256 exchange = _exchanges[i];
            require(exchange < uint256(ExchangeId.Last), "Unrecognized exchange identifier");
            assetInfo[_components[i]].exchange = _exchanges[i];

            emit AssetExchangeUpdated(_components[i], exchange);
        }
    }

    /**
     * MANAGER ONLY: Set exchange for passed components
     *
     * @param _components           Array of components
     * @param _coolOffPeriods       Array of cool off periods to correct component
     */
    function setCoolOffPeriods(
        address[] calldata _components,
        uint256[] calldata _coolOffPeriods
    )
    external
    onlyManagerAndValidSet(index)
    {
        _validateArrays(_components, _coolOffPeriods);

        for (uint256 i = 0; i < _components.length; i++) {
            assetInfo[_components[i]].coolOffPeriod = _coolOffPeriods[i];
            emit CoolOffPeriodUpdated(_components[i], _coolOffPeriods[i]);
        }
    }

    /**
     * MANAGER ONLY: Toggle ability for passed addresses to trade from current state
     *
     * @param _traders           Array trader addresses to toggle status
     * @param _statuses          Booleans indicating if matching trader can trade
     */
    function updateTraderStatus(address[] calldata _traders, bool[] calldata _statuses) external onlyManagerAndValidSet(index) {
        require(_traders.length == _statuses.length, "Array length mismatch");
        require(_traders.length > 0, "Array length must be > 0");
        require(!_traders.hasDuplicate(), "Cannot duplicate traders");

        for (uint256 i = 0; i < _traders.length; i++) {
            address trader = _traders[i];
            bool status = _statuses[i];
            tradeAllowList[trader] = status;
            emit TraderStatusUpdated(trader, status);
        }
    }

    /**
     * MANAGER ONLY: Toggle whether anyone can trade, bypassing the traderAllowList
     *
     * @param _status           Boolean indicating if anyone can trade
     */
    function updateAnyoneTrade(bool _status) external onlyManagerAndValidSet(index) {
        anyoneTrade = _status;
        emit AnyoneTradeUpdated(_status);
    }

    /**
     * MANAGER ONLY: Set target units to current units and last trade to zero. Initialize module.
     *
     * @param _index            Address of index being used for this Set
     */
    function initialize(ISetToken _index)
    external
    onlySetManager(_index, msg.sender)
    onlyValidAndPendingSet(_index)
    {
        require(address(index) == address(0), "Module already in use");

        ISetToken.Position[] memory positions = _index.getPositions();

        for (uint256 i = 0; i < positions.length; i++) {
            ISetToken.Position memory position = positions[i];
            assetInfo[position.component].targetUnit = position.unit.toUint256();
            assetInfo[position.component].lastTradeTimestamp = 0;
        }

        index = _index;
        _index.initializeModule();
    }

    function removeModule() external override {}

    /* ============ Getter Functions ============ */

    /**
     * Get target units for passed components, normalized to current positionMultiplier.
     *
     * @param _components           Array of components to get target units for
     * @return                      Array of targetUnits mapping to passed components
     */
    function getTargetUnits(address[] calldata _components) external view returns(uint256[] memory) {
        uint256 currentPositionMultiplier = index.positionMultiplier().toUint256();

        uint256[] memory targetUnits = new uint256[](_components.length);
        for (uint256 i = 0; i < _components.length; i++) {
            targetUnits[i] = _normalizeTargetUnit(_components[i], currentPositionMultiplier);
        }

        return targetUnits;
    }

    function getRebalanceComponents() external view returns(address[] memory) {
        return rebalanceComponents;
    }

    /* ============ Internal Functions ============ */

    /**
     * Validate that enough time has elapsed since component's last trade and component isn't WETH.
     */
    function _validateTradeParameters(address _component) internal view virtual {
        require(rebalanceComponents.contains(_component), "Passed component not included in rebalance");

        AssetTradeInfo memory componentInfo = assetInfo[_component];
        require(componentInfo.exchange != uint256(ExchangeId.None), "Exchange must be specified");
        require(
            componentInfo.lastTradeTimestamp.add(componentInfo.coolOffPeriod) <= block.timestamp,
            "Cool off period has not elapsed."
        );
    }

    /**
     * Calculate trade size and whether trade is buy. Trade size is the minimum of the max size and components left to trade.
     * Reverts if target quantity is already met. Target unit is adjusted based on ratio of position multiplier when target was defined
     * and the current positionMultiplier.
     */
    function _calculateTradeSizeAndDirection(address _component) internal view returns (bool isBuy, uint256) {
        uint256 totalSupply = index.totalSupply();

        uint256 componentMaxSize = assetInfo[_component].maxSize;
        uint256 currentPositionMultiplier = index.positionMultiplier().toUint256();

        uint256 currentUnit = index.getDefaultPositionRealUnit(_component).toUint256();
        uint256 targetUnit = _normalizeTargetUnit(_component, currentPositionMultiplier);

        require(currentUnit != targetUnit, "Target already met");

        uint256 currentNotional = totalSupply.getDefaultTotalNotional(currentUnit);
        uint256 targetNotional = totalSupply.preciseMulCeil(targetUnit);

        return targetNotional > currentNotional ? (true, componentMaxSize.min(targetNotional.sub(currentNotional))) :
        (false, componentMaxSize.min(currentNotional.sub(targetNotional)));
    }

    /**
     * Buy an underweight asset by selling an unfixed amount of WETH for a fixed amount of the component.
     */
    function _buyUnderweight(address _component, uint256 _amount) internal {
        uint256 preTradeBuyComponentAmount = IERC20(_component).balanceOf(address(index));
        uint256 preTradeSellComponentAmount = weth.balanceOf(address(index));

        _executeTrade(address(weth), _component, false, _amount, assetInfo[_component].exchange);

        _updatePositionState(address(weth), _component, preTradeSellComponentAmount, preTradeBuyComponentAmount);
    }

    /**
     * Sell an overweight asset by selling a fixed amount of component for an unfixed amount of WETH.
     */
    function _sellOverweight(address _component, uint256 _amount) internal {
        uint256 preTradeBuyComponentAmount = weth.balanceOf(address(index));
        uint256 preTradeSellComponentAmount = IERC20(_component).balanceOf(address(index));

        _executeTrade(_component, address(weth), true, _amount, assetInfo[_component].exchange);

        _updatePositionState(_component, address(weth), preTradeSellComponentAmount, preTradeBuyComponentAmount);
    }

    /**
     * Determine parameters for trade and invoke trade on index using correct exchange.
     */
    function _executeTrade(
        address _sellComponent,
        address _buyComponent,
        bool _fixIn,
        uint256 _amount,
        uint256 _exchange
    )
    internal
    virtual
    {
        uint256 wethBalance = weth.balanceOf(address(index));

        (
        address exchangeAddress,
        bytes memory tradeCallData
        ) = _exchange == uint256(ExchangeId.Balancer) ? _getBalancerTradeData(_sellComponent, _buyComponent, _fixIn, _amount, wethBalance) :
        _getUniswapLikeTradeData(_sellComponent, _buyComponent, _fixIn, _amount, _exchange);

        uint256 approveAmount = _sellComponent == address(weth) ? wethBalance : _amount;
        index.invokeApprove(_sellComponent, exchangeAddress, approveAmount);
        index.invoke(exchangeAddress, 0, tradeCallData);
    }

    /**
     * Update position units on index. Emit event.
     */
    function _updatePositionState(
        address _sellComponent,
        address _buyComponent,
        uint256 _preTradeSellComponentAmount,
        uint256 _preTradeBuyComponentAmount
    )
    internal
    returns (uint256 sellAmount, uint256 buyAmount)
    {
        uint256 totalSupply = index.totalSupply();

        (uint256 postTradeSellComponentAmount,,) = index.calculateAndEditDefaultPosition(
            _sellComponent,
            totalSupply,
            _preTradeSellComponentAmount
        );
        (uint256 postTradeBuyComponentAmount,,) = index.calculateAndEditDefaultPosition(
            _buyComponent,
            totalSupply,
            _preTradeBuyComponentAmount
        );

        sellAmount = _preTradeSellComponentAmount.sub(postTradeSellComponentAmount);
        buyAmount = postTradeBuyComponentAmount.sub(_preTradeBuyComponentAmount);

        emit TradeExecuted(
            msg.sender,
            _sellComponent,
            _buyComponent,
            sellAmount,
            buyAmount
        );
    }

    /**
     * Create Balancer trade call data
     */
    function _getBalancerTradeData(
        address _sellComponent,
        address _buyComponent,
        bool _fixIn,
        uint256 _amount,
        uint256 _maxOut
    )
    internal
    view
    returns(address, bytes memory)
    {
        address exchangeAddress = balancerProxy;
        (
        string memory functionSignature,
        uint256 limit
        ) = _fixIn ? (BALANCER_IN, 1) : (BALANCER_OUT, _maxOut);

        bytes memory tradeCallData = abi.encodeWithSignature(
            functionSignature,
            _sellComponent,
            _buyComponent,
            _amount,
            limit,
            BALANCER_POOL_LIMIT
        );

        return (exchangeAddress, tradeCallData);
    }

    /**
     * Determine whether exchange to call is Uniswap or Sushiswap and generate necessary call data.
     */
    function _getUniswapLikeTradeData(
        address _sellComponent,
        address _buyComponent,
        bool _fixIn,
        uint256 _amount,
        uint256 _exchange
    )
    internal
    view
    returns(address, bytes memory)
    {
        address exchangeAddress = _exchange == uint256(ExchangeId.Uniswap) ? uniswapRouter : sushiswapRouter;

        string memory functionSignature;
        address[] memory path = new address[](2);
        uint256 limit;
        if (_fixIn) {
            functionSignature = UNISWAP_IN;
            limit = 1;
        } else {
            functionSignature = UNISWAP_OUT;
            limit = PreciseUnitMath.maxUint256();
        }
        path[0] = _sellComponent;
        path[1] = _buyComponent;

        bytes memory tradeCallData = abi.encodeWithSignature(
            functionSignature,
            _amount,
            limit,
            path,
            address(index),
            now.add(180)
        );

        return (exchangeAddress, tradeCallData);
    }

    /**
     * Check if there are any more tokens to sell.
     */
    function _noTokensToSell() internal view returns (bool) {
        uint256 currentPositionMultiplier = index.positionMultiplier().toUint256();
        for (uint256 i = 0; i < rebalanceComponents.length; i++) {
            address component = rebalanceComponents[i];
            bool canSell = _normalizeTargetUnit(component, currentPositionMultiplier) < index.getDefaultPositionRealUnit(
                component
            ).toUint256();
            if (canSell) { return false; }
        }
        return true;
    }

    /**
     * Check if all targets are met
     */
    function _allTargetsMet() internal view returns (bool) {
        uint256 currentPositionMultiplier = index.positionMultiplier().toUint256();
        for (uint256 i = 0; i < rebalanceComponents.length; i++) {
            address component = rebalanceComponents[i];
            bool targetUnmet = _normalizeTargetUnit(component, currentPositionMultiplier) != index.getDefaultPositionRealUnit(
                component
            ).toUint256();
            if (targetUnmet) { return false; }
        }
        return true;
    }

    /**
     * Normalize target unit to current position multiplier in case fees have been accrued.
     */
    function _normalizeTargetUnit(address _component, uint256 _currentPositionMultiplier) internal view returns(uint256) {
        return assetInfo[_component].targetUnit.mul(_currentPositionMultiplier).div(positionMultiplier);
    }

    /**
     * Determine if passed address is allowed to call trade. If anyoneTrade set to true anyone can call otherwise needs to be approved.
     */
    function _isAllowedTrader(address _caller) internal view virtual returns (bool) {
        return anyoneTrade || tradeAllowList[_caller];
    }

    /**
     * Validate arrays are of equal length and not empty.
     */
    function _validateArrays(address[] calldata _components, uint256[] calldata _data) internal pure {
        require(_components.length == _data.length, "Array length mismatch");
        require(_components.length > 0, "Array length must be > 0");
        require(!_components.hasDuplicate(), "Cannot duplicate components");
    }
}

error: pathspec 'party/contracts/protocol/modules/SingleIndexModule.sol' did not match any file(s) known to git


Add counter contract

Add counter contract

pragma solidity ^0.4.10;

contract Counter {
    uint public counter;

    function setCounter(uint value) {
        counter = value;
    }
}

error: pathspec 'src/contracts/counter.sol' did not match any file(s) known to git


add abstract function to access mew

add abstract function to access mew

pragma solidity ^0.4.0;
/*
@type: contract
@name: AbstractConceptRegistry
@purpose: To create concepts and store some concept data
*/
contract AbstractConceptRegistry
{
  function init(address _userRegistry, address mew)
  {
  }

  function makeConcept(address[] parentList)
  {
  }
  function mew() returns(address)
  {
  }
}

pragma solidity ^0.4.0;
/*
@type: contract
@name: AbstractConceptRegistry
@purpose: To create concepts and store some concept data
*/
contract AbstractConceptRegistry
{

  function init(address _userRegistry, address mew)
  {
  }

  function makeConcept(address[] parentList)
  {
  }
}


Create Crowdsale on ChainX Network .

Create Crowdsale on ChainX Network .

pragma solidity ^0.4.8;

import "./Exchange.sol";
import "./tokens/ChainXToken.sol";
import "./base/Token.sol";
import "./base/Ownable.sol";
import "./base/SafeMath.sol";

contract SimpleCrowdsale is Ownable, SafeMath {

    address public PROXY_ADDRESS;
    address public EXCHANGE_ADDRESS;
    address public PROTOCOL_TOKEN_ADDRESS;
    address public CHX_TOKEN_ADDRESS;

    Exchange exchange;
    Token protocolToken;
    ChainXToken chxToken;

    bool public isInitialized;
    bool public isFinished;
    Order order;

    struct Order {
        address maker;
        address taker;
        address tokenM;
        address tokenT;
        address feeRecipient;
        uint valueM;
        uint valueT;
        uint feeM;
        uint feeT;
        uint expiration;
        uint salt;
        uint8 v;
        bytes32 r;
        bytes32 s;
        bytes32 orderHash;
    }

    modifier saleInitialized() {
        assert(isInitialized);
        _;
    }

    modifier saleNotInitialized() {
        assert(!isInitialized);
        _;
    }

    modifier saleNotFinished() {
        assert(!isFinished);
        _;
    }

    function SimpleCrowdsale(
        address _exchange,
        address _proxy,
        address _protocolToken,
        address _chxToken)
    {
        PROXY_ADDRESS = _proxy;
        EXCHANGE_ADDRESS = _exchange;
        PROTOCOL_TOKEN_ADDRESS = _protocolToken;
        ChainX_TOKEN_ADDRESS = _chxToken;

        exchange = Exchange(_exchange);
        protocolToken = Token(_protocolToken);
        ethToken = EtherToken(_ethToken);
    }

    /// @dev Allows users to fill stored order by sending ETH to contract.
    function()
        payable
        saleInitialized
        saleNotFinished
    {
        uint remainingEth = safeSub(order.valueT, exchange.getUnavailableValueT(order.orderHash));
        uint ethToFill = min(msg.value, remainingEth);
        ethToken.deposit.value(ethToFill)();
        assert(exchange.fillOrKill(
            [order.maker, order.taker, order.tokenM, order.tokenT, order.feeRecipient],
            [order.valueM, order.valueT, order.feeM, order.feeT, order.expiration, order.salt],
            ethToFill,
            order.v,
            order.r,
            order.s
        ));
        uint filledProtocolToken = safeDiv(safeMul(order.valueM, ethToFill), order.valueT);
        assert(protocolToken.transfer(msg.sender, filledProtocolToken));
        if (ethToFill < msg.value) {
            assert(msg.sender.send(safeSub(msg.value, ethToFill)));
            isFinished = true;
        }
    }

    /// @dev Stores order and initializes sale.
    /// @param orderAddresses Array of order's maker, taker, tokenM, tokenT, and feeRecipient.
    /// @param orderValues Array of order's valueM, valueT, feeM, feeT, expiration, and salt.
    /// @param v ECDSA signature parameter v.
    /// @param r CDSA signature parameters r.
    /// @param s CDSA signature parameters s.
    function init(
        address[5] orderAddresses,
        uint[6] orderValues,
        uint8 v,
        bytes32 r,
        bytes32 s)
        saleNotInitialized
        onlyOwner
    {
        order = Order({
            maker: orderAddresses[0],
            taker: orderAddresses[1],
            tokenM: orderAddresses[2],
            tokenT: orderAddresses[3],
            feeRecipient: orderAddresses[4],
            valueM: orderValues[0],
            valueT: orderValues[1],
            feeM: orderValues[2],
            feeT: orderValues[3],
            expiration: orderValues[4],
            salt: orderValues[5],
            v: v,
            r: r,
            s: s,
            orderHash: getOrderHash(orderAddresses, orderValues)
        });

        assert(order.tokenM == PROTOCOL_TOKEN_ADDRESS);
        assert(order.tokenT == ETH_TOKEN_ADDRESS);

        assert(isValidSignature(
            order.maker,
            order.orderHash,
            v,
            r,
            s
        ));

        assert(setTokenAllowance(order.tokenT, order.valueT));
        isInitialized = true;
    }

    function setTokenAllowance(address _token, uint _allowance)
        onlyOwner
        returns (bool success)
    {
        assert(Token(_token).approve(PROXY_ADDRESS, _allowance));
        return true;
    }

    /// @dev Calculates Keccak-256 hash of order with specified parameters.
    /// @param orderAddresses Array of order's maker, taker, tokenM, tokenT, and feeRecipient.
    /// @param orderValues Array of order's valueM, valueT, feeM, feeT, expiration, and salt.
    /// @return Keccak-256 hash of order.
    function getOrderHash(address[5] orderAddresses, uint[6] orderValues)
        constant
        returns (bytes32 orderHash)
    {
        return sha3(
            EXCHANGE_ADDRESS,
            orderAddresses[0],
            orderAddresses[1],
            orderAddresses[2],
            orderAddresses[3],
            orderAddresses[4],
            orderValues[0],
            orderValues[1],
            orderValues[2],
            orderValues[3],
            orderValues[4],
            orderValues[5]
        );
    }

    /// @dev Verifies that an order signature is valid.
    /// @param pubKey Public address of signer.
    /// @param hash Signed Keccak-256 hash.
    /// @param v ECDSA signature parameter v.
    /// @param r ECDSA signature parameters r.
    /// @param s ECDSA signature parameters s.
    /// @return Validity of order signature.
    function isValidSignature(
        address pubKey,
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s)
        constant
        returns (bool isValid)
    {
        return pubKey == ecrecover(
            sha3("\x19Ethereum Signed Message:\n32", hash),
            v,
            r,
            s
        );
    }

    /// @dev Calculates minimum of two values.
    /// @param a First value.
    /// @param b Second value.
    /// @return Minimum of values.
    function min(uint a, uint b)
        constant
        returns (uint min)
    {
        if (a < b) return a;
        return b;
    }
}

error: pathspec 'Contracts/Base/SimpleCrowdsale.sol' did not match any file(s) known to git


Throw if wrong user tries to add revision.

/**
 * @title BlobStore
 * @author Jonathan Brown <jbrown@bluedroplet.com>
 */
contract BlobStore {

    struct BlobInfo {
        uint96 blockNumber;
        address owner;
    }

    mapping (bytes32 => BlobInfo) blobInfo;
    mapping (bytes32 => uint256[]) revisionBlockNumbers;

    event logBlob(bytes32 indexed hash, uint256 indexed revisionId, bytes blob) anonymous;
    event logRetraction(bytes32 indexed hash) anonymous;

    modifier isOwner(bytes32 hash) {
        if (blobInfo[hash].owner != msg.sender) {
            throw;
        }
        _
    }

    /**
     * @dev Stores a blob in the transaction log. It is guaranteed that each user will get a different hash when storing the same blob.
     * @param blob Blob that should be stored.
     * @return hash Hash of sender and blob.
     */
    function storeBlob(bytes blob, bool revisionable) external returns (bytes32 hash) {
        // Calculate the hash.
        hash = sha3(msg.sender, blob);
        // Store block number and owner in state.
        blobInfo[hash] = BlobInfo({
            blockNumber: uint96(block.number),
            owner: revisionable ? msg.sender : 0,
        });
        // Store the blob in a log in the current block.
        logBlob(hash, 0, blob);
    }

    function updateBlob(bytes32 hash, bytes blob) isOwner(hash) external {
        revisionBlockNumbers[hash].push(block.number);
        // Store the new blob in a log in the current block.
        logBlob(hash, revisionBlockNumbers[hash].length, blob);
    }

    function retractBlob(bytes32 hash) isOwner(hash) external {
        // Get a refund for the storage slots.
        delete blobInfo[hash];
        delete revisionBlockNumbers[hash];
        // Log the retraction.
        logRetraction(hash);
    }

    function getBlobInfo(bytes32 hash) constant external returns (address owner, uint256 revisions, uint256 blockNumber) {
        owner = blobInfo[hash].owner;
        revisions = revisionBlockNumbers[hash].length;
        if (revisions == 0) {
            blockNumber = blobInfo[hash].blockNumber;
        }
        else {
            blockNumber = revisionBlockNumbers[hash][revisions - 1];
        }
    }

    function getRevisionBlockNumber(bytes32 hash, uint256 revisionId) constant external returns (uint256 blockNumber) {
        if (revisionId == 0) {
            blockNumber = blobInfo[hash].blockNumber;
        }
        else {
            blockNumber = revisionBlockNumbers[hash][revisionId - 1];
        }
    }

    function() {
        throw;      // Do not maintain an ether balance.
    }

}

/**
 * @title BlobStore
 * @author Jonathan Brown <jbrown@bluedroplet.com>
 */
contract BlobStore {

    struct BlobInfo {
        uint96 blockNumber;
        address owner;
    }

    mapping (bytes32 => BlobInfo) blobInfo;
    mapping (bytes32 => uint256[]) revisionBlockNumbers;

    event logBlob(bytes32 indexed hash, uint256 indexed revisionId, bytes blob) anonymous;
    event logRetraction(bytes32 indexed hash) anonymous;

    modifier isOwner(bytes32 hash) {
        if (blobInfo[hash].owner == msg.sender) {
            _
        }
    }

    /**
     * @dev Stores a blob in the transaction log. It is guaranteed that each user will get a different hash when storing the same blob.
     * @param blob Blob that should be stored.
     * @return hash Hash of sender and blob.
     */
    function storeBlob(bytes blob, bool revisionable) external returns (bytes32 hash) {
        // Calculate the hash.
        hash = sha3(msg.sender, blob);
        // Store block number and owner in state.
        blobInfo[hash] = BlobInfo({
            blockNumber: uint96(block.number),
            owner: revisionable ? msg.sender : 0,
        });
        // Store the blob in a log in the current block.
        logBlob(hash, 0, blob);
    }

    function updateBlob(bytes32 hash, bytes blob) isOwner(hash) external {
        revisionBlockNumbers[hash].push(block.number);
        // Store the new blob in a log in the current block.
        logBlob(hash, revisionBlockNumbers[hash].length, blob);
    }

    function retractBlob(bytes32 hash) isOwner(hash) external {
        // Get a refund for the storage slots.
        delete blobInfo[hash];
        delete revisionBlockNumbers[hash];
        // Log the retraction.
        logRetraction(hash);
    }

    function getBlobInfo(bytes32 hash) constant external returns (address owner, uint256 revisions, uint256 blockNumber) {
        owner = blobInfo[hash].owner;
        revisions = revisionBlockNumbers[hash].length;
        if (revisions == 0) {
            blockNumber = blobInfo[hash].blockNumber;
        }
        else {
            blockNumber = revisionBlockNumbers[hash][revisions - 1];
        }
    }

    function getRevisionBlockNumber(bytes32 hash, uint256 revisionId) constant external returns (uint256 blockNumber) {
        if (revisionId == 0) {
            blockNumber = blobInfo[hash].blockNumber;
        }
        else {
            blockNumber = revisionBlockNumbers[hash][revisionId - 1];
        }
    }

    function() {
        throw;      // Do not maintain an ether balance.
    }

}


Do not maintain an ether balance.

Do not maintain an ether balance.

/**
 * @title BlobStore
 * @author Jonathan Brown <jbrown@bluedroplet.com>
 */
contract BlobStore {

    event logBlob(bytes32 indexed hash, bytes blob) anonymous;

    /**
     * @dev Stores a blob in the transaction log.
     * @param blob Blob that should be stored.
     * @return hash Hash of blob.
     */
    function storeBlob(bytes blob) external returns (bytes32 hash) {
        // Calculate the hash.
        hash = sha3(blob);
        // Store the blob in a log in the current block.
        logBlob(hash, blob);
    }

    function() {
        throw;      // Do not maintain an ether balance.
    }

}

/**
 * @title BlobStore
 * @author Jonathan Brown <jbrown@bluedroplet.com>
 */
contract BlobStore {

    event logBlob(bytes32 indexed hash, bytes blob) anonymous;

    /**
     * @dev Stores a blob in the transaction log.
     * @param blob Blob that should be stored.
     * @return hash Hash of the blob.
     */
    function storeBlob(bytes blob) external returns (bytes32 hash) {
        // Calculate the hash.
        hash = sha3(blob);
        // Store the blob in a log in the current block.
        logBlob(hash, blob);
    }

}


removed .call()

removed .call()

import "UnanimousConsent.sol";

/**
* This contract will consent to some hashes on behalf of a specified
* address if and only if the specified address has signed off on it
**/

contract ECDSASignatureProxy {
    address signer;
    UnanimousConsent unanimousConsent;

    function ECDSASignatureProxy(address _signer, UnanimousConsent _unanimousConsent) {
        signer = _signer;
        unanimousConsent = _unanimousConsent;
    }

    // Checks if all of the hashes have been signed off on
    function forward(bytes32[] hashes, uint8[] v, bytes32[] r, bytes32[] s) returns(bool) {
        uint length = hashes.length;
        for (uint i = length - 1; i <= 0; --i) {
            if (ecrecover(hashes[i], v[i], r[i], s[i]) != signer) {
                return false;
            }
        }
        unanimousConsent.consent(hashes);
        return true;
    }
}

import "UnanimousConsent.sol";

/**
* This contract will consent to some hashes on behalf of a specified
* address if and only if the specified address has signed off on it
**/

contract ECDSASignatureProxy {
    address signer;
    UnanimousConsent unanimousConsent;

    function ECDSASignatureProxy(address _signer, UnanimousConsent _unanimousConsent) {
        signer = _signer;
        unanimousConsent = _unanimousConsent;
    }

    // Checks if all of the hashes have been signed off on
    function forward(bytes32[] hashes, uint8[] v, bytes32[] r, bytes32[] s) returns(bool) {
        uint length = hashes.length;
        for (uint i = length - 1; i <= 0; --i) {
            if (ecrecover(hashes[i], v[i], r[i], s[i]) != signer) {
                return false;
            }
        }
        return unanimousConsent.call(bytes4(sha3("consent(bytes32)")), hashes);
    }
}


add storage keyword to silence compiler warn

/*
    Copyright 2017-2018 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.24;

import "./libraries/MathLib.sol";
import "./tokens/MarketToken.sol";
import "./Linkable.sol";
import "./MarketContract.sol";

import "openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";

/// @title MarketCollateralPool is a contract controlled by a specific Market Contract.  It holds collateral balances
/// as well as user balances and open positions.  It should be instantiated and then linked by a MarketContract.
/// @author Phil Elsasser <phil@marketprotocol.io>
contract MarketCollateralPool is Linkable {
    using MathLib for uint;
    using MathLib for int;
    using SafeERC20 for ERC20;

    struct UserNetPosition {
        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;
    }

    uint public collateralPoolBalance;                                 // current balance of all collateral committed
    mapping(address => UserNetPosition) addressToUserPosition;
    mapping(address => uint) public userAddressToAccountBalance;       // stores account balances allowed to be allocated to orders
    address public MKT_TOKEN_ADDRESS;
    MarketContract MKT_CONTRACT;

    event UpdatedUserBalance(address indexed user, uint balance);
    event UpdatedPoolBalance(uint balance);

    /// @dev instantiates a collateral pool that is unique to the supplied address of a MarketContract. This pairing
    /// is 1:1
    /// @param marketContractAddress deployed address of a MarketContract
    constructor(address marketContractAddress) Linkable(marketContractAddress) public {
        MKT_CONTRACT = MarketContract(marketContractAddress);
        MKT_TOKEN_ADDRESS = MKT_CONTRACT.MKT_TOKEN_ADDRESS();
    }

    /// @notice get the net position for a give user address
    /// @param userAddress address to return position for
    /// @return the users current open position.
    function getUserNetPosition(address userAddress) external view returns (int) {
        return addressToUserPosition[userAddress].netPosition;
    }

    /// @notice gets the number of positions currently held by this address. Useful for iterating
    /// over the positions array in order to retrieve all users data.
    /// @param userAddress address of user
    /// @return number of open unique positions in the array.
    function getUserPositionCount(address userAddress) external view returns (uint) {
        return addressToUserPosition[userAddress].positions.length;
    }

    /// @notice Allows for retrieval of user position struct (since solidity cannot return the struct) we return
    /// the data as a tuple of (uint, int) that represents (price, qty)
    /// @param userAddress address of user
    /// @param index 0 based index of position in array (older positions are lower indexes)
    /// @return (price, qty) tuple
    function getUserPosition(address userAddress, uint index) external view returns (uint, int) {
        Position storage pos = addressToUserPosition[userAddress].positions[index];
        return (pos.price, pos.qty);
    }

    /// @param userAddress address of user
    /// @return the users currently unallocated token balance
    function getUserUnallocatedBalance(address userAddress) external view returns (uint) {
        return userAddressToAccountBalance[userAddress];
    }

    /*
    // EXTERNAL METHODS
    */

    /// @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!
        require(MarketToken(MKT_TOKEN_ADDRESS).isUserEnabledForContract(MKT_CONTRACT, msg.sender));
        uint256 balanceAfterDeposit = userAddressToAccountBalance[msg.sender].add(depositAmount);
        ERC20(MKT_CONTRACT.COLLATERAL_TOKEN_ADDRESS()).safeTransferFrom(msg.sender, this, depositAmount);
        userAddressToAccountBalance[msg.sender] = balanceAfterDeposit;
        emit UpdatedUserBalance(msg.sender, balanceAfterDeposit);
    }

    // @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(MKT_CONTRACT.isSettled());
        require(MarketToken(MKT_TOKEN_ADDRESS).isUserEnabledForContract(MKT_CONTRACT, msg.sender));
        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(
                userNetPos,
                msg.sender,
                userNetPos.netPosition * - 1,
                MKT_CONTRACT.settlementPrice()
            );
        }
        // transfer all balances back to user.
        withdrawTokens(userAddressToAccountBalance[msg.sender]);
    }

    /// @dev called by our linked MarketContract when a trade occurs to update both maker and takers positions.
    /// @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
    ) external onlyLinked
    {
        updatePosition(
            maker,
            qty,
            price
        );
        // continue process for taker, but qty is opposite sign for taker
        updatePosition(
            taker,
            qty * -1,
            price
        );
    }

    /*
    // PUBLIC METHODS
    */

    /// @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);  subtract call below will enforce this
        uint256 balanceAfterWithdrawal = userAddressToAccountBalance[msg.sender].subtract(withdrawAmount);
        userAddressToAccountBalance[msg.sender] = balanceAfterWithdrawal;   // update balance before external call!
        ERC20(MKT_CONTRACT.COLLATERAL_TOKEN_ADDRESS()).safeTransfer(msg.sender, withdrawAmount);
        emit UpdatedUserBalance(msg.sender, balanceAfterWithdrawal);
    }

    /*
    // PRIVATE METHODS
    */

    /// @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(MKT_TOKEN.isUserEnabledForContract(MKT_CONTRACT, msg.sender)); already confirmed higher in call stack!
        //require(userAddressToAccountBalance[fromAddress] >= collateralAmount);   // ensure sufficient balance
        // subtract call will enforce sufficient balance.
        uint newBalance = userAddressToAccountBalance[fromAddress].subtract(collateralAmount);
        userAddressToAccountBalance[fromAddress] = newBalance;
        collateralPoolBalance = collateralPoolBalance.add(collateralAmount);
        emit UpdatedUserBalance(fromAddress, newBalance);
        emit 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(MKT_TOKEN.isUserEnabledForContract(MKT_CONTRACT, msg.sender)); already confirmed higher in call stack!
        // require(collateralPoolBalance >= collateralAmount); subtract call below will enforce this!
        uint newBalance = userAddressToAccountBalance[toAddress].add(collateralAmount);
        userAddressToAccountBalance[toAddress] = newBalance;
        collateralPoolBalance = collateralPoolBalance.subtract(collateralAmount);
        emit UpdatedUserBalance(toAddress, newBalance);
        emit UpdatedPoolBalance(collateralPoolBalance);
    }

    /// @dev handles all needed internal accounting when a user enters into a new trade
    /// @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 or flattened
                reduceUserNetPosition(
                    userNetPosition,
                    userAddress,
                    qty,
                    price
                );
            } else {    // pos is flipped, reduce and then create new open pos!

                reduceUserNetPosition(
                    userNetPosition,
                    userAddress,
                    userNetPosition.netPosition * -1,
                    price
                ); // flatten completely

                int newNetPos = userNetPosition.netPosition + qty;            // the portion remaining after flattening
                addUserNetPosition(
                    userNetPosition,
                    userAddress,
                    newNetPos,
                    price
                );
            }
        }
        userNetPosition.netPosition = 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(
            MKT_CONTRACT.PRICE_FLOOR(),
            MKT_CONTRACT.PRICE_CAP(),
            MKT_CONTRACT.QTY_MULTIPLIER(),
            qty,
            price
        );
        commitCollateralToPool(userAddress, neededCollateral);
        userNetPosition.positions.push(Position(price, qty));   // append array with new position
    }

    /// @dev reduces net position correctly allocating collateral back to user
    /// @param userNetPos storage struct for this users position
    /// @param userAddress address of user who is reducing their pos
    /// @param qty signed quantity of the qty to reduce this users position by
    /// @param price transacted price
    function reduceUserNetPosition(
        UserNetPosition storage userNetPos,
        address userAddress,
        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 = collateralToReturnToUserAccount.add(
                    MathLib.calculateNeededCollateral(
                        MKT_CONTRACT.PRICE_FLOOR(),
                        MKT_CONTRACT.PRICE_CAP(),
                        MKT_CONTRACT.QTY_MULTIPLIER(),
                        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 = collateralToReturnToUserAccount.add(
                    MathLib.calculateNeededCollateral(
                        MKT_CONTRACT.PRICE_FLOOR(),
                        MKT_CONTRACT.PRICE_CAP(),
                        MKT_CONTRACT.QTY_MULTIPLIER(),
                        qtyToReduce * -1,
                        price
                    )
                );
//                qtyToReduce = 0; // completely reduced now!
                break;
            }
        }

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

/*
    Copyright 2017-2018 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.24;

import "./libraries/MathLib.sol";
import "./tokens/MarketToken.sol";
import "./Linkable.sol";
import "./MarketContract.sol";

import "openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";

/// @title MarketCollateralPool is a contract controlled by a specific Market Contract.  It holds collateral balances
/// as well as user balances and open positions.  It should be instantiated and then linked by a MarketContract.
/// @author Phil Elsasser <phil@marketprotocol.io>
contract MarketCollateralPool is Linkable {
    using MathLib for uint;
    using MathLib for int;
    using SafeERC20 for ERC20;

    struct UserNetPosition {
        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;
    }

    uint public collateralPoolBalance;                                 // current balance of all collateral committed
    mapping(address => UserNetPosition) addressToUserPosition;
    mapping(address => uint) public userAddressToAccountBalance;       // stores account balances allowed to be allocated to orders
    address public MKT_TOKEN_ADDRESS;
    MarketContract MKT_CONTRACT;

    event UpdatedUserBalance(address indexed user, uint balance);
    event UpdatedPoolBalance(uint balance);

    /// @dev instantiates a collateral pool that is unique to the supplied address of a MarketContract. This pairing
    /// is 1:1
    /// @param marketContractAddress deployed address of a MarketContract
    constructor(address marketContractAddress) Linkable(marketContractAddress) public {
        MKT_CONTRACT = MarketContract(marketContractAddress);
        MKT_TOKEN_ADDRESS = MKT_CONTRACT.MKT_TOKEN_ADDRESS();
    }

    /// @notice get the net position for a give user address
    /// @param userAddress address to return position for
    /// @return the users current open position.
    function getUserNetPosition(address userAddress) external view returns (int) {
        return addressToUserPosition[userAddress].netPosition;
    }

    /// @notice gets the number of positions currently held by this address. Useful for iterating
    /// over the positions array in order to retrieve all users data.
    /// @param userAddress address of user
    /// @return number of open unique positions in the array.
    function getUserPositionCount(address userAddress) external view returns (uint) {
        return addressToUserPosition[userAddress].positions.length;
    }

    /// @notice Allows for retrieval of user position struct (since solidity cannot return the struct) we return
    /// the data as a tuple of (uint, int) that represents (price, qty)
    /// @param userAddress address of user
    /// @param index 0 based index of position in array (older positions are lower indexes)
    /// @return (price, qty) tuple
    function getUserPosition(address userAddress, uint index) external view returns (uint, int) {
        Position pos = addressToUserPosition[userAddress].positions[index];
        return (pos.price, pos.qty);
    }

    /// @param userAddress address of user
    /// @return the users currently unallocated token balance
    function getUserUnallocatedBalance(address userAddress) external view returns (uint) {
        return userAddressToAccountBalance[userAddress];
    }

    /*
    // EXTERNAL METHODS
    */

    /// @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!
        require(MarketToken(MKT_TOKEN_ADDRESS).isUserEnabledForContract(MKT_CONTRACT, msg.sender));
        uint256 balanceAfterDeposit = userAddressToAccountBalance[msg.sender].add(depositAmount);
        ERC20(MKT_CONTRACT.COLLATERAL_TOKEN_ADDRESS()).safeTransferFrom(msg.sender, this, depositAmount);
        userAddressToAccountBalance[msg.sender] = balanceAfterDeposit;
        emit UpdatedUserBalance(msg.sender, balanceAfterDeposit);
    }

    // @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(MKT_CONTRACT.isSettled());
        require(MarketToken(MKT_TOKEN_ADDRESS).isUserEnabledForContract(MKT_CONTRACT, msg.sender));
        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(
                userNetPos,
                msg.sender,
                userNetPos.netPosition * - 1,
                MKT_CONTRACT.settlementPrice()
            );
        }
        // transfer all balances back to user.
        withdrawTokens(userAddressToAccountBalance[msg.sender]);
    }

    /// @dev called by our linked MarketContract when a trade occurs to update both maker and takers positions.
    /// @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
    ) external onlyLinked
    {
        updatePosition(
            maker,
            qty,
            price
        );
        // continue process for taker, but qty is opposite sign for taker
        updatePosition(
            taker,
            qty * -1,
            price
        );
    }

    /*
    // PUBLIC METHODS
    */

    /// @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);  subtract call below will enforce this
        uint256 balanceAfterWithdrawal = userAddressToAccountBalance[msg.sender].subtract(withdrawAmount);
        userAddressToAccountBalance[msg.sender] = balanceAfterWithdrawal;   // update balance before external call!
        ERC20(MKT_CONTRACT.COLLATERAL_TOKEN_ADDRESS()).safeTransfer(msg.sender, withdrawAmount);
        emit UpdatedUserBalance(msg.sender, balanceAfterWithdrawal);
    }

    /*
    // PRIVATE METHODS
    */

    /// @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(MKT_TOKEN.isUserEnabledForContract(MKT_CONTRACT, msg.sender)); already confirmed higher in call stack!
        //require(userAddressToAccountBalance[fromAddress] >= collateralAmount);   // ensure sufficient balance
        // subtract call will enforce sufficient balance.
        uint newBalance = userAddressToAccountBalance[fromAddress].subtract(collateralAmount);
        userAddressToAccountBalance[fromAddress] = newBalance;
        collateralPoolBalance = collateralPoolBalance.add(collateralAmount);
        emit UpdatedUserBalance(fromAddress, newBalance);
        emit 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(MKT_TOKEN.isUserEnabledForContract(MKT_CONTRACT, msg.sender)); already confirmed higher in call stack!
        // require(collateralPoolBalance >= collateralAmount); subtract call below will enforce this!
        uint newBalance = userAddressToAccountBalance[toAddress].add(collateralAmount);
        userAddressToAccountBalance[toAddress] = newBalance;
        collateralPoolBalance = collateralPoolBalance.subtract(collateralAmount);
        emit UpdatedUserBalance(toAddress, newBalance);
        emit UpdatedPoolBalance(collateralPoolBalance);
    }

    /// @dev handles all needed internal accounting when a user enters into a new trade
    /// @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 or flattened
                reduceUserNetPosition(
                    userNetPosition,
                    userAddress,
                    qty,
                    price
                );
            } else {    // pos is flipped, reduce and then create new open pos!

                reduceUserNetPosition(
                    userNetPosition,
                    userAddress,
                    userNetPosition.netPosition * -1,
                    price
                ); // flatten completely

                int newNetPos = userNetPosition.netPosition + qty;            // the portion remaining after flattening
                addUserNetPosition(
                    userNetPosition,
                    userAddress,
                    newNetPos,
                    price
                );
            }
        }
        userNetPosition.netPosition = 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(
            MKT_CONTRACT.PRICE_FLOOR(),
            MKT_CONTRACT.PRICE_CAP(),
            MKT_CONTRACT.QTY_MULTIPLIER(),
            qty,
            price
        );
        commitCollateralToPool(userAddress, neededCollateral);
        userNetPosition.positions.push(Position(price, qty));   // append array with new position
    }

    /// @dev reduces net position correctly allocating collateral back to user
    /// @param userNetPos storage struct for this users position
    /// @param userAddress address of user who is reducing their pos
    /// @param qty signed quantity of the qty to reduce this users position by
    /// @param price transacted price
    function reduceUserNetPosition(
        UserNetPosition storage userNetPos,
        address userAddress,
        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 = collateralToReturnToUserAccount.add(
                    MathLib.calculateNeededCollateral(
                        MKT_CONTRACT.PRICE_FLOOR(),
                        MKT_CONTRACT.PRICE_CAP(),
                        MKT_CONTRACT.QTY_MULTIPLIER(),
                        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 = collateralToReturnToUserAccount.add(
                    MathLib.calculateNeededCollateral(
                        MKT_CONTRACT.PRICE_FLOOR(),
                        MKT_CONTRACT.PRICE_CAP(),
                        MKT_CONTRACT.QTY_MULTIPLIER(),
                        qtyToReduce * -1,
                        price
                    )
                );
//                qtyToReduce = 0; // completely reduced now!
                break;
            }
        }

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


6.1 fix stuck Ether in Crowdsale contract

pragma solidity ^0.4.8;

import "./StandardToken.sol";

/*
 * CrowdsaleToken
 *
 * Simple ERC20 Token example, with crowdsale token creation
 * IMPORTANT NOTE: do not use or deploy this contract as-is.
 * It needs some changes to be production ready.
 */
contract CrowdsaleToken is StandardToken {

  string public constant name = "CrowdsaleToken";
  string public constant symbol = "CRW";
  uint public constant decimals = 18;
  // replace with your fund collection multisig address
  address public constant multisig = 0x0;

  // 1 ether = 500 example tokens
  uint public constant PRICE = 500;

  function () payable {
    createTokens(msg.sender);
  }

  function createTokens(address recipient) payable {
    if (msg.value == 0) {
      throw;
    }

    uint tokens = safeMul(msg.value, getPrice());
    totalSupply = safeAdd(totalSupply, tokens);

    balances[recipient] = safeAdd(balances[recipient], tokens);

    if (!multisig.send(msg.value)) {
      throw;
    }
  }

  // replace this with any other price function
  function getPrice() constant returns (uint result) {
    return PRICE;
  }
}

pragma solidity ^0.4.8;

import "./StandardToken.sol";

/*
 * CrowdsaleToken
 *
 * Simple ERC20 Token example, with crowdsale token creation
 */
contract CrowdsaleToken is StandardToken {

  string public name = "CrowdsaleToken";
  string public symbol = "CRW";
  uint public decimals = 18;

  // 1 ether = 500 example tokens
  uint PRICE = 500;

  function () payable {
    createTokens(msg.sender);
  }

  function createTokens(address recipient) payable {
    if (msg.value == 0) {
      throw;
    }

    uint tokens = safeMul(msg.value, getPrice());

    totalSupply = safeAdd(totalSupply, tokens);
    balances[recipient] = safeAdd(balances[recipient], tokens);
  }

  // replace this with any other price function
  function getPrice() constant returns (uint result) {
    return PRICE;
  }
}


Add warning about trading tokens before refundable crowdsale goal is met (#1452)

This attack was reported in https://github.com/OpenZeppelin/openzeppelin-solidity/issues/877

pragma solidity ^0.4.24;

import "../../math/SafeMath.sol";
import "./FinalizableCrowdsale.sol";
import "../../payment/escrow/RefundEscrow.sol";

/**
 * @title RefundableCrowdsale
 * @dev Extension of Crowdsale contract that adds a funding goal, and
 * the possibility of users getting a refund if goal is not met.
 * WARNING: note that if you allow tokens to be traded before the goal
 * is met, then an attack is possible in which the attacker purchases
 * tokens from the crowdsale and when they sees that the goal is
 * unlikely to be met, they sell their tokens (possibly at a discount).
 * The attacker will be refunded when the crowdsale is finalized, and
 * the users that purchased from them will be left with worthless
 * tokens. There are many possible ways to avoid this, like making the
 * the crowdsale inherit from PostDeliveryCrowdsale, or imposing
 * restrictions on token trading until the crowdsale is finalized.
 * This is being discussed in
 * https://github.com/OpenZeppelin/openzeppelin-solidity/issues/877
 * This contract will be updated when we agree on a general solution
 * for this problem.
 */
contract RefundableCrowdsale is FinalizableCrowdsale {
  using SafeMath for uint256;

  // minimum amount of funds to be raised in weis
  uint256 private _goal;

  // refund escrow used to hold funds while crowdsale is running
  RefundEscrow private _escrow;

  /**
   * @dev Constructor, creates RefundEscrow.
   * @param goal Funding goal
   */
  constructor(uint256 goal) internal {
    require(goal > 0);
    _escrow = new RefundEscrow(wallet());
    _goal = goal;
  }

  /**
   * @return minimum amount of funds to be raised in wei.
   */
  function goal() public view returns(uint256) {
    return _goal;
  }

  /**
   * @dev Investors can claim refunds here if crowdsale is unsuccessful
   * @param beneficiary Whose refund will be claimed.
   */
  function claimRefund(address beneficiary) public {
    require(finalized());
    require(!goalReached());

    _escrow.withdraw(beneficiary);
  }

  /**
   * @dev Checks whether funding goal was reached.
   * @return Whether funding goal was reached
   */
  function goalReached() public view returns (bool) {
    return weiRaised() >= _goal;
  }

  /**
   * @dev escrow finalization task, called when finalize() is called
   */
  function _finalization() internal {
    if (goalReached()) {
      _escrow.close();
      _escrow.beneficiaryWithdraw();
    } else {
      _escrow.enableRefunds();
    }

    super._finalization();
  }

  /**
   * @dev Overrides Crowdsale fund forwarding, sending funds to escrow.
   */
  function _forwardFunds() internal {
    _escrow.deposit.value(msg.value)(msg.sender);
  }

}

pragma solidity ^0.4.24;

import "../../math/SafeMath.sol";
import "./FinalizableCrowdsale.sol";
import "../../payment/escrow/RefundEscrow.sol";

/**
 * @title RefundableCrowdsale
 * @dev Extension of Crowdsale contract that adds a funding goal, and
 * the possibility of users getting a refund if goal is not met.
 */
contract RefundableCrowdsale is FinalizableCrowdsale {
  using SafeMath for uint256;

  // minimum amount of funds to be raised in weis
  uint256 private _goal;

  // refund escrow used to hold funds while crowdsale is running
  RefundEscrow private _escrow;

  /**
   * @dev Constructor, creates RefundEscrow.
   * @param goal Funding goal
   */
  constructor(uint256 goal) internal {
    require(goal > 0);
    _escrow = new RefundEscrow(wallet());
    _goal = goal;
  }

  /**
   * @return minimum amount of funds to be raised in wei.
   */
  function goal() public view returns(uint256) {
    return _goal;
  }

  /**
   * @dev Investors can claim refunds here if crowdsale is unsuccessful
   * @param beneficiary Whose refund will be claimed.
   */
  function claimRefund(address beneficiary) public {
    require(finalized());
    require(!goalReached());

    _escrow.withdraw(beneficiary);
  }

  /**
   * @dev Checks whether funding goal was reached.
   * @return Whether funding goal was reached
   */
  function goalReached() public view returns (bool) {
    return weiRaised() >= _goal;
  }

  /**
   * @dev escrow finalization task, called when finalize() is called
   */
  function _finalization() internal {
    if (goalReached()) {
      _escrow.close();
      _escrow.beneficiaryWithdraw();
    } else {
      _escrow.enableRefunds();
    }

    super._finalization();
  }

  /**
   * @dev Overrides Crowdsale fund forwarding, sending funds to escrow.
   */
  function _forwardFunds() internal {
    _escrow.deposit.value(msg.value)(msg.sender);
  }

}


Update Arrays.sol to require solc 0.4.24. (#1553)

pragma solidity ^0.4.24;

import "../math/Math.sol";

/**
 * @title Arrays
 * @dev Utility library of inline array functions
 */
library Arrays {
    /**
     * @dev Upper bound search function which is kind of binary search algoritm. It searches sorted
     * array to find index of the element value. If element is found then returns it's index otherwise
     * it returns index of first element which is grater than searched value. If searched element is
     * bigger than any array element function then returns first index after last element (i.e. all
     * values inside the array are smaller than the target). Complexity O(log n).
     * @param array The array sorted in ascending order.
     * @param element The element's value to be find.
     * @return The calculated index value. Returns 0 for empty array.
     */
    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
        if (array.length == 0) {
            return 0;
        }

        uint256 low = 0;
        uint256 high = array.length;

        while (low < high) {
            uint256 mid = Math.average(low, high);

            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
            // because Math.average rounds down (it does integer division with truncation).
            if (array[mid] > element) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
        if (low > 0 && array[low - 1] == element) {
            return low - 1;
        } else {
            return low;
        }
    }
}

pragma solidity ^0.4.23;

import "../math/Math.sol";

/**
 * @title Arrays
 * @dev Utility library of inline array functions
 */
library Arrays {
    /**
     * @dev Upper bound search function which is kind of binary search algoritm. It searches sorted
     * array to find index of the element value. If element is found then returns it's index otherwise
     * it returns index of first element which is grater than searched value. If searched element is
     * bigger than any array element function then returns first index after last element (i.e. all
     * values inside the array are smaller than the target). Complexity O(log n).
     * @param array The array sorted in ascending order.
     * @param element The element's value to be find.
     * @return The calculated index value. Returns 0 for empty array.
     */
    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
        if (array.length == 0) {
            return 0;
        }

        uint256 low = 0;
        uint256 high = array.length;

        while (low < high) {
            uint256 mid = Math.average(low, high);

            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)
            // because Math.average rounds down (it does integer division with truncation).
            if (array[mid] > element) {
                high = mid;
            } else {
                low = mid + 1;
            }
        }

        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
        if (low > 0 && array[low - 1] == element) {
            return low - 1;
        } else {
            return low;
        }
    }
}


MintableToken contract was updated

MintableToken contract was updated

pragma solidity ^0.4.11;

import 'zeppelin-solidity/contracts/token/StandardToken.sol';
import 'zeppelin-solidity/contracts/ownership/Ownable.sol';

contract MintableToken is StandardToken, Ownable {

    uint256 public hardCap;

    event Mint(address indexed to, uint256 amount);

    modifier canMint() {
        require(totalSupply == 0);
        _;
    }

    /**
     * @dev Function to mint tokens
     * @param _to The address that will receive the minted tokens.
     * @param _amount The amount of tokens to mint.
     * @return A boolean that indicates if the operation was successful.
     */
    function mint(address _to, uint256 _amount) onlyOwner canMint public returns (bool) {
        require(_amount < hardCap);
        totalSupply = totalSupply.add(_amount);
        balances[_to] = balances[_to].add(_amount);
        Mint(_to, _amount);
        Transfer(0x0, _to, _amount);
        return true;
    }

    /**
     * @dev Function to stop minting new tokens.
     * @return True if the operation was successful.
     */
}
contract DMToken is MintableToken {

    string public name = "DMarket Token";
    string public symbol = "DMT";
    uint256 public decimals = 8;

    function DMToken() {

        /**
        *  1-Phase: 36037245 * 10^8 tokens
        *  2-Phase: 100000000 * 10^8 tokens
        *    36037245 + 100000000) % 15 =  20405587 * 10^8 tokens
        *  HardCap will be equal: 36037245 + 100000000 + 20405587 = 156442831 * 10^8 tokens
        */
        hardCap = 15644283100000000;
    }
}

pragma solidity ^0.4.11;

import 'zeppelin-solidity/contracts/token/MintableToken.sol';

contract DMToken is MintableToken {

    string public name = "DMarket Token";
    string public symbol = "DMT";
    uint256 public decimals = 8;

}


revert marble identification to uid

revert marble identification to uid

contract FamilyResourceControl{

    uint public contractStart = 1462744800; // represents 05/09/2016 00:00:00, use e.g. http://www.timestampconvert.com/ to get your start timestamp
    uint public renewalPeriod = 7; // in days
    uint public requiredMarbles = 2; // of each type, every period
    uint public requiredExtraMarbles = 10; // number of extra marbles required for redeeming
    uint[] allowedDays = [1, 4]; // array of days on which the ressource may be used in the following period. If the Contract starts on Monday 00:00, day 0 is monday, day 6 is sunday.

    struct Child {
        uint indianredMarbles; // vocabulary
        uint skyblueMarbles; // instrument
        uint neonMarbles; // represent extra credit
    }

    struct Parent {
        bool canAward;
    }

    address responsibleParent; // this is the owner of the contract

    mapping(address => Child) children;
    mapping(address => Parent) parents;

    // modifiers
    modifier onlyOwner {
        if (msg.sender != responsibleParent)
            throw;
        _
    }

    modifier onlyParent {
        if (!parents[msg.sender].canAward)
            throw;
        _
    }

    // constructor
    function FamilyResourceControl(){
        responsibleParent = msg.sender; // this is the creator of the contract and the one authorized to add other parents
        parents[responsibleParent].canAward = true;
    }

    // cumulative required marbles
    function cumReqMarbles() returns(uint) {
        return ((now - contractStart)/(renewalPeriod * 1 days))*requiredMarbles;
    }

    // calculate current day of week (first day => day 0)
    function currentDay() returns(uint){
        return ((now - contractStart)/ 1 days) % (renewalPeriod);
    }

    // award a marble
    function awardMarble(uint whatMarble, address goodChild) onlyParent {
        if (whatMarble == 0) {
            if (children[goodChild].indianredMarbles >= cumReqMarbles()+2){
                children[goodChild].neonMarbles++;
            } else {
                children[goodChild].indianredMarbles++;
            }
        } else if (whatMarble == 1){
            if (children[goodChild].skyblueMarbles >= cumReqMarbles()+2){
                children[goodChild].neonMarbles++;
            } else {
                children[goodChild].skyblueMarbles++;
            }
        }
    }

    // function to be called by the resource controler
    function canUseResource(address goodChild) returns (bool) {
        for (uint i = 0; i < allowedDays.length; i++) {
            if (
                allowedDays[i] == currentDay()
                && children[goodChild].indianredMarbles >= cumReqMarbles()
                && children[goodChild].skyblueMarbles >= cumReqMarbles()
                ){
                return true;
            }
        }
        return false;
    }

    // redeem neon marbles
    function useNeonMarbles(address goodChild) onlyParent returns(bool){
        if (children[goodChild].neonMarbles >= requiredExtraMarbles) {
            children[goodChild].neonMarbles -=  requiredExtraMarbles;
            return true;
        } else {
            return false;
        }
    }

    function addParent(address furtherParent) onlyOwner {
            parents[furtherParent].canAward = true;
    }

    function removeParent(address realParent) onlyOwner{
        if (msg.sender == responsibleParent){
            parents[realParent].canAward = false;
        } else {
            throw;
        }
    }

    function marbleBalance(address goodChild) returns(uint indianredMarbles, uint skyblueMarbles, uint neonMarbles){
        return(
            children[goodChild].indianredMarbles,
            children[goodChild].skyblueMarbles,
            children[goodChild].neonMarbles);
    }

    function remove() onlyOwner{
        selfdestruct(responsibleParent);
    }
}

contract FamilyResourceControl{

    uint public contractStart = 1462744800; // represents 05/09/2016 00:00:00, use e.g. http://www.timestampconvert.com/ to get your start timestamp
    uint public renewalPeriod = 7; // in days
    uint public requiredMarbles = 2; // of each type, every period
    uint public requiredExtraMarbles = 10; // number of extra marbles required for redeeming
    uint[] allowedDays = [1, 4]; // array of days on which the ressource may be used in the following period. If the Contract starts on Monday 00:00, day 0 is monday, day 6 is sunday.

    struct Child {
        uint indianredMarbles; // vocabulary
        uint skyblueMarbles; // instrument
        uint neonMarbles; // represent extra credit
    }

    struct Parent {
        bool canAward;
    }

    address responsibleParent; // this is the owner of the contract

    mapping(address => Child) children;
    mapping(address => Parent) parents;

    // modifiers
    modifier onlyOwner {
        if (msg.sender != responsibleParent)
            throw;
        _
    }

    modifier onlyParent {
        if (!parents[msg.sender].canAward)
            throw;
        _
    }

    // constructor
    function FamilyResourceControl(){
        responsibleParent = msg.sender; // this is the creator of the contract and the one authorized to add other parents
        parents[responsibleParent].canAward = true;
    }

    // cumulative required marbles
    function cumReqMarbles() returns(uint) {
        return ((now - contractStart)/(renewalPeriod * 1 days))*requiredMarbles;
    }

    // calculate current day of week (first day => day 0)
    function currentDay() returns(uint){
        return ((now - contractStart)/ 1 days) % (renewalPeriod);
    }

    // award a marble
    function awardMarble(bytes32 whatMarble, address goodChild) onlyParent {
        if (whatMarble == "indianredMarble") {
            if (children[goodChild].indianredMarbles >= cumReqMarbles()+2){
                children[goodChild].neonMarbles++;
            } else {
                children[goodChild].indianredMarbles++;
            }
        } else if (whatMarble == "skyblueMarble"){
            if (children[goodChild].skyblueMarbles >= cumReqMarbles()+2){
                children[goodChild].neonMarbles++;
            } else {
                children[goodChild].skyblueMarbles++;
            }
        }
    }

    // function to be called by the resource controler
    function canUseResource(address goodChild) returns (bool) {
        for (uint i = 0; i < allowedDays.length; i++) {
            if (
                allowedDays[i] == currentDay()
                && children[goodChild].indianredMarbles >= cumReqMarbles()
                && children[goodChild].skyblueMarbles >= cumReqMarbles()
                ){
                return true;
            }
        }
        return false;
    }

    // redeem neon marbles
    function useNeonMarbles(address goodChild) onlyParent returns(bool){
        if (children[goodChild].neonMarbles >= requiredExtraMarbles) {
            children[goodChild].neonMarbles -=  requiredExtraMarbles;
            return true;
        } else {
            return false;
        }
    }

    function addParent(address furtherParent) onlyOwner {
            parents[furtherParent].canAward = true;
    }

    function removeParent(address realParent) onlyOwner{
        if (msg.sender == responsibleParent){
            parents[realParent].canAward = false;
        } else {
            throw;
        }
    }

    function marbleBalance(address goodChild) returns(uint indianredMarbles, uint skyblueMarbles, uint neonMarbles){
        return(
            children[goodChild].indianredMarbles,
            children[goodChild].skyblueMarbles,
            children[goodChild].neonMarbles);
    }

    function remove() onlyOwner{
        selfdestruct(responsibleParent);
    }
}