ETH Price: $1,870.25 (-0.91%)

Transaction Decoder

Block:
9987611 at May-02-2020 03:38:34 PM +UTC
Transaction Fee:
0.000371454 ETH $0.69
Gas Used:
61,909 Gas / 6 Gwei

Emitted Events:

45 Delegator.0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5( 0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5, 0x00000000000000000000000007efa0f70b14c621e482d038df57a1a98cab8952, 0000000000000000000000000000000000000000000000000035d599cc7b9c1e )

Account State Difference:

  Address   Before After State Difference Code
0x88A62883...ecE7C799f
(Fake_Phishing313358)
31.078290853149165922 Eth
Nonce: 206
31.093072429452196224 Eth
Nonce: 207
0.014781576303030302
0xd5524179...baa76B96b 1,616.274233846648713379 Eth1,616.259080816345683077 Eth0.015153030303030302
(Ethermine)
800.877423302264465902 Eth800.877794756264465902 Eth0.000371454

Execution Trace

0x07efa0f70b14c621e482d038df57a1a98cab8952.CALL( )
  • Controller.lookup( _key=4D61696C626F7800000000000000000000000000000000000000000000000000 ) => ( 0x4DCB585B8C8c52C2D25D5a7c2672646BC24b3B66 )
  • Mailbox.DELEGATECALL( )
    • Controller.lookup( _key=4361736800000000000000000000000000000000000000000000000000000000 ) => ( 0xd5524179cB7AE012f5B642C1D6D700Bbaa76B96b )
    • Delegator.70a08231( )
      • Controller.lookup( _key=4361736854617267657400000000000000000000000000000000000000000000 ) => ( 0x9B4Af4a3295cF476a2b00736f7332f35BbEE960E )
      • Cash.balanceOf( _owner=0x07Efa0F70B14c621e482d038dF57a1A98CAB8952 ) => ( 15153030303030302 )
      • Delegator.1baffe38( )
        • Controller.lookup( _key=4361736854617267657400000000000000000000000000000000000000000000 ) => ( 0x9B4Af4a3295cF476a2b00736f7332f35BbEE960E )
        • Cash.withdrawEtherTo( _to=0x88A6288370255dbF40Af80da260Ac95ecE7C799f, _amount=15153030303030302 ) => ( True )
          • ETH 0.015153030303030302 Fake_Phishing313358.CALL( )
            File 1 of 4: Delegator
            pragma solidity 0.4.20;
            
            contract IAugur {
                function createChildUniverse(bytes32 _parentPayoutDistributionHash, uint256[] _parentPayoutNumerators, bool _parentInvalid) public returns (IUniverse);
                function isKnownUniverse(IUniverse _universe) public view returns (bool);
                function trustedTransfer(ERC20 _token, address _from, address _to, uint256 _amount) public returns (bool);
                function logMarketCreated(bytes32 _topic, string _description, string _extraInfo, IUniverse _universe, address _market, address _marketCreator, bytes32[] _outcomes, int256 _minPrice, int256 _maxPrice, IMarket.MarketType _marketType) public returns (bool);
                function logMarketCreated(bytes32 _topic, string _description, string _extraInfo, IUniverse _universe, address _market, address _marketCreator, int256 _minPrice, int256 _maxPrice, IMarket.MarketType _marketType) public returns (bool);
                function logInitialReportSubmitted(IUniverse _universe, address _reporter, address _market, uint256 _amountStaked, bool _isDesignatedReporter, uint256[] _payoutNumerators, bool _invalid) public returns (bool);
                function disputeCrowdsourcerCreated(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] _payoutNumerators, uint256 _size, bool _invalid) public returns (bool);
                function logDisputeCrowdsourcerContribution(IUniverse _universe, address _reporter, address _market, address _disputeCrowdsourcer, uint256 _amountStaked) public returns (bool);
                function logDisputeCrowdsourcerCompleted(IUniverse _universe, address _market, address _disputeCrowdsourcer) public returns (bool);
                function logInitialReporterRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256 _reportingFeesReceived, uint256[] _payoutNumerators) public returns (bool);
                function logDisputeCrowdsourcerRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256 _reportingFeesReceived, uint256[] _payoutNumerators) public returns (bool);
                function logFeeWindowRedeemed(IUniverse _universe, address _reporter, uint256 _amountRedeemed, uint256 _reportingFeesReceived) public returns (bool);
                function logMarketFinalized(IUniverse _universe) public returns (bool);
                function logMarketMigrated(IMarket _market, IUniverse _originalUniverse) public returns (bool);
                function logReportingParticipantDisavowed(IUniverse _universe, IMarket _market) public returns (bool);
                function logMarketParticipantsDisavowed(IUniverse _universe) public returns (bool);
                function logOrderCanceled(IUniverse _universe, address _shareToken, address _sender, bytes32 _orderId, Order.Types _orderType, uint256 _tokenRefund, uint256 _sharesRefund) public returns (bool);
                function logOrderCreated(Order.Types _orderType, uint256 _amount, uint256 _price, address _creator, uint256 _moneyEscrowed, uint256 _sharesEscrowed, bytes32 _tradeGroupId, bytes32 _orderId, IUniverse _universe, address _shareToken) public returns (bool);
                function logOrderFilled(IUniverse _universe, address _shareToken, address _filler, bytes32 _orderId, uint256 _numCreatorShares, uint256 _numCreatorTokens, uint256 _numFillerShares, uint256 _numFillerTokens, uint256 _marketCreatorFees, uint256 _reporterFees, uint256 _amountFilled, bytes32 _tradeGroupId) public returns (bool);
                function logCompleteSetsPurchased(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
                function logCompleteSetsSold(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
                function logTradingProceedsClaimed(IUniverse _universe, address _shareToken, address _sender, address _market, uint256 _numShares, uint256 _numPayoutTokens, uint256 _finalTokenBalance) public returns (bool);
                function logUniverseForked() public returns (bool);
                function logFeeWindowTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logReputationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logDisputeCrowdsourcerTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logShareTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logReputationTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logReputationTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logShareTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logShareTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeWindowBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeWindowMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logDisputeCrowdsourcerTokensBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logDisputeCrowdsourcerTokensMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeWindowCreated(IFeeWindow _feeWindow, uint256 _id) public returns (bool);
                function logFeeTokenTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logFeeTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logTimestampSet(uint256 _newTimestamp) public returns (bool);
                function logInitialReporterTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
                function logMarketTransferred(IUniverse _universe, address _from, address _to) public returns (bool);
                function logMarketMailboxTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
                function logEscapeHatchChanged(bool _isOn) public returns (bool);
            }
            
            contract IControlled {
                function getController() public view returns (IController);
                function setController(IController _controller) public returns(bool);
            }
            
            contract Controlled is IControlled {
                IController internal controller;
            
                modifier onlyWhitelistedCallers {
                    require(controller.assertIsWhitelisted(msg.sender));
                    _;
                }
            
                modifier onlyCaller(bytes32 _key) {
                    require(msg.sender == controller.lookup(_key));
                    _;
                }
            
                modifier onlyControllerCaller {
                    require(IController(msg.sender) == controller);
                    _;
                }
            
                modifier onlyInGoodTimes {
                    require(controller.stopInEmergency());
                    _;
                }
            
                modifier onlyInBadTimes {
                    require(controller.onlyInEmergency());
                    _;
                }
            
                function Controlled() public {
                    controller = IController(msg.sender);
                }
            
                function getController() public view returns(IController) {
                    return controller;
                }
            
                function setController(IController _controller) public onlyControllerCaller returns(bool) {
                    controller = _controller;
                    return true;
                }
            }
            
            contract IController {
                function assertIsWhitelisted(address _target) public view returns(bool);
                function lookup(bytes32 _key) public view returns(address);
                function stopInEmergency() public view returns(bool);
                function onlyInEmergency() public view returns(bool);
                function getAugur() public view returns (IAugur);
                function getTimestamp() public view returns (uint256);
            }
            
            contract DelegationTarget is Controlled {
                bytes32 public controllerLookupName;
            }
            
            contract Delegator is DelegationTarget {
                function Delegator(IController _controller, bytes32 _controllerLookupName) public {
                    controller = _controller;
                    controllerLookupName = _controllerLookupName;
                }
            
                function() external payable {
                    // Do nothing if we haven't properly set up the delegator to delegate calls
                    if (controllerLookupName == 0) {
                        return;
                    }
            
                    // Get the delegation target contract
                    address _target = controller.lookup(controllerLookupName);
            
                    assembly {
                        //0x40 is the address where the next free memory slot is stored in Solidity
                        let _calldataMemoryOffset := mload(0x40)
                        // new "memory end" including padding. The bitwise operations here ensure we get rounded up to the nearest 32 byte boundary
                        let _size := and(add(calldatasize, 0x1f), not(0x1f))
                        // Update the pointer at 0x40 to point at new free memory location so any theoretical allocation doesn't stomp our memory in this call
                        mstore(0x40, add(_calldataMemoryOffset, _size))
                        // Copy method signature and parameters of this call into memory
                        calldatacopy(_calldataMemoryOffset, 0x0, calldatasize)
                        // Call the actual method via delegation
                        let _retval := delegatecall(gas, _target, _calldataMemoryOffset, calldatasize, 0, 0)
                        switch _retval
                        case 0 {
                            // 0 == it threw, so we revert
                            revert(0,0)
                        } default {
                            // If the call succeeded return the return data from the delegate call
                            let _returndataMemoryOffset := mload(0x40)
                            // Update the pointer at 0x40 again to point at new free memory location so any theoretical allocation doesn't stomp our memory in this call
                            mstore(0x40, add(_returndataMemoryOffset, returndatasize))
                            returndatacopy(_returndataMemoryOffset, 0x0, returndatasize)
                            return(_returndataMemoryOffset, returndatasize)
                        }
                    }
                }
            }
            
            contract IOwnable {
                function getOwner() public view returns (address);
                function transferOwnership(address newOwner) public returns (bool);
            }
            
            contract ITyped {
                function getTypeName() public view returns (bytes32);
            }
            
            contract Initializable {
                bool private initialized = false;
            
                modifier afterInitialized {
                    require(initialized);
                    _;
                }
            
                modifier beforeInitialized {
                    require(!initialized);
                    _;
                }
            
                function endInitialization() internal beforeInitialized returns (bool) {
                    initialized = true;
                    return true;
                }
            
                function getInitialized() public view returns (bool) {
                    return initialized;
                }
            }
            
            library SafeMathUint256 {
                function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                    uint256 c = a * b;
                    require(a == 0 || c / a == b);
                    return c;
                }
            
                function div(uint256 a, uint256 b) internal pure returns (uint256) {
                    // assert(b > 0); // Solidity automatically throws when dividing by 0
                    uint256 c = a / b;
                    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
                    return c;
                }
            
                function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                    require(b <= a);
                    return a - b;
                }
            
                function add(uint256 a, uint256 b) internal pure returns (uint256) {
                    uint256 c = a + b;
                    require(c >= a);
                    return c;
                }
            
                function min(uint256 a, uint256 b) internal pure returns (uint256) {
                    if (a <= b) {
                        return a;
                    } else {
                        return b;
                    }
                }
            
                function max(uint256 a, uint256 b) internal pure returns (uint256) {
                    if (a >= b) {
                        return a;
                    } else {
                        return b;
                    }
                }
            
                function getUint256Min() internal pure returns (uint256) {
                    return 0;
                }
            
                function getUint256Max() internal pure returns (uint256) {
                    return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
                }
            
                function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {
                    return a % b == 0;
                }
            
                // Float [fixed point] Operations
                function fxpMul(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
                    return div(mul(a, b), base);
                }
            
                function fxpDiv(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
                    return div(mul(a, base), b);
                }
            }
            
            contract ERC20Basic {
                event Transfer(address indexed from, address indexed to, uint256 value);
            
                function balanceOf(address _who) public view returns (uint256);
                function transfer(address _to, uint256 _value) public returns (bool);
                function totalSupply() public view returns (uint256);
            }
            
            contract ERC20 is ERC20Basic {
                event Approval(address indexed owner, address indexed spender, uint256 value);
            
                function allowance(address _owner, address _spender) public view returns (uint256);
                function transferFrom(address _from, address _to, uint256 _value) public returns (bool);
                function approve(address _spender, uint256 _value) public returns (bool);
            }
            
            contract IFeeToken is ERC20, Initializable {
                function initialize(IFeeWindow _feeWindow) public returns (bool);
                function getFeeWindow() public view returns (IFeeWindow);
                function feeWindowBurn(address _target, uint256 _amount) public returns (bool);
                function mintForReportingParticipant(address _target, uint256 _amount) public returns (bool);
            }
            
            contract IFeeWindow is ITyped, ERC20 {
                function initialize(IUniverse _universe, uint256 _feeWindowId) public returns (bool);
                function getUniverse() public view returns (IUniverse);
                function getReputationToken() public view returns (IReputationToken);
                function getStartTime() public view returns (uint256);
                function getEndTime() public view returns (uint256);
                function getNumMarkets() public view returns (uint256);
                function getNumInvalidMarkets() public view returns (uint256);
                function getNumIncorrectDesignatedReportMarkets() public view returns (uint256);
                function getNumDesignatedReportNoShows() public view returns (uint256);
                function getFeeToken() public view returns (IFeeToken);
                function isActive() public view returns (bool);
                function isOver() public view returns (bool);
                function onMarketFinalized() public returns (bool);
                function buy(uint256 _attotokens) public returns (bool);
                function redeem(address _sender) public returns (bool);
                function redeemForReportingParticipant() public returns (bool);
                function mintFeeTokens(uint256 _amount) public returns (bool);
                function trustedUniverseBuy(address _buyer, uint256 _attotokens) public returns (bool);
            }
            
            contract IMailbox {
                function initialize(address _owner, IMarket _market) public returns (bool);
                function depositEther() public payable returns (bool);
            }
            
            contract IMarket is ITyped, IOwnable {
                enum MarketType {
                    YES_NO,
                    CATEGORICAL,
                    SCALAR
                }
            
                function initialize(IUniverse _universe, uint256 _endTime, uint256 _feePerEthInAttoeth, ICash _cash, address _designatedReporterAddress, address _creator, uint256 _numOutcomes, uint256 _numTicks) public payable returns (bool _success);
                function derivePayoutDistributionHash(uint256[] _payoutNumerators, bool _invalid) public view returns (bytes32);
                function getUniverse() public view returns (IUniverse);
                function getFeeWindow() public view returns (IFeeWindow);
                function getNumberOfOutcomes() public view returns (uint256);
                function getNumTicks() public view returns (uint256);
                function getDenominationToken() public view returns (ICash);
                function getShareToken(uint256 _outcome)  public view returns (IShareToken);
                function getMarketCreatorSettlementFeeDivisor() public view returns (uint256);
                function getForkingMarket() public view returns (IMarket _market);
                function getEndTime() public view returns (uint256);
                function getMarketCreatorMailbox() public view returns (IMailbox);
                function getWinningPayoutDistributionHash() public view returns (bytes32);
                function getWinningPayoutNumerator(uint256 _outcome) public view returns (uint256);
                function getReputationToken() public view returns (IReputationToken);
                function getFinalizationTime() public view returns (uint256);
                function getInitialReporterAddress() public view returns (address);
                function deriveMarketCreatorFeeAmount(uint256 _amount) public view returns (uint256);
                function isContainerForShareToken(IShareToken _shadyTarget) public view returns (bool);
                function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
                function isInvalid() public view returns (bool);
                function finalize() public returns (bool);
                function designatedReporterWasCorrect() public view returns (bool);
                function designatedReporterShowed() public view returns (bool);
                function isFinalized() public view returns (bool);
                function finalizeFork() public returns (bool);
                function assertBalances() public view returns (bool);
            }
            
            contract IReportingParticipant {
                function getStake() public view returns (uint256);
                function getPayoutDistributionHash() public view returns (bytes32);
                function liquidateLosing() public returns (bool);
                function redeem(address _redeemer) public returns (bool);
                function isInvalid() public view returns (bool);
                function isDisavowed() public view returns (bool);
                function migrate() public returns (bool);
                function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
                function getMarket() public view returns (IMarket);
                function getSize() public view returns (uint256);
            }
            
            contract IDisputeCrowdsourcer is IReportingParticipant, ERC20 {
                function initialize(IMarket market, uint256 _size, bytes32 _payoutDistributionHash, uint256[] _payoutNumerators, bool _invalid) public returns (bool);
                function contribute(address _participant, uint256 _amount) public returns (uint256);
            }
            
            contract IReputationToken is ITyped, ERC20 {
                function initialize(IUniverse _universe) public returns (bool);
                function migrateOut(IReputationToken _destination, uint256 _attotokens) public returns (bool);
                function migrateIn(address _reporter, uint256 _attotokens) public returns (bool);
                function trustedReportingParticipantTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedMarketTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedFeeWindowTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedUniverseTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function getUniverse() public view returns (IUniverse);
                function getTotalMigrated() public view returns (uint256);
                function getTotalTheoreticalSupply() public view returns (uint256);
                function mintForReportingParticipant(uint256 _amountMigrated) public returns (bool);
            }
            
            contract IUniverse is ITyped {
                function initialize(IUniverse _parentUniverse, bytes32 _parentPayoutDistributionHash) external returns (bool);
                function fork() public returns (bool);
                function getParentUniverse() public view returns (IUniverse);
                function createChildUniverse(uint256[] _parentPayoutNumerators, bool _invalid) public returns (IUniverse);
                function getChildUniverse(bytes32 _parentPayoutDistributionHash) public view returns (IUniverse);
                function getReputationToken() public view returns (IReputationToken);
                function getForkingMarket() public view returns (IMarket);
                function getForkEndTime() public view returns (uint256);
                function getForkReputationGoal() public view returns (uint256);
                function getParentPayoutDistributionHash() public view returns (bytes32);
                function getDisputeRoundDurationInSeconds() public view returns (uint256);
                function getOrCreateFeeWindowByTimestamp(uint256 _timestamp) public returns (IFeeWindow);
                function getOrCreateCurrentFeeWindow() public returns (IFeeWindow);
                function getOrCreateNextFeeWindow() public returns (IFeeWindow);
                function getOpenInterestInAttoEth() public view returns (uint256);
                function getRepMarketCapInAttoeth() public view returns (uint256);
                function getTargetRepMarketCapInAttoeth() public view returns (uint256);
                function getOrCacheValidityBond() public returns (uint256);
                function getOrCacheDesignatedReportStake() public returns (uint256);
                function getOrCacheDesignatedReportNoShowBond() public returns (uint256);
                function getOrCacheReportingFeeDivisor() public returns (uint256);
                function getDisputeThresholdForFork() public view returns (uint256);
                function getInitialReportMinValue() public view returns (uint256);
                function calculateFloatingValue(uint256 _badMarkets, uint256 _totalMarkets, uint256 _targetDivisor, uint256 _previousValue, uint256 _defaultValue, uint256 _floor) public pure returns (uint256 _newValue);
                function getOrCacheMarketCreationCost() public returns (uint256);
                function getCurrentFeeWindow() public view returns (IFeeWindow);
                function getOrCreateFeeWindowBefore(IFeeWindow _feeWindow) public returns (IFeeWindow);
                function isParentOf(IUniverse _shadyChild) public view returns (bool);
                function updateTentativeWinningChildUniverse(bytes32 _parentPayoutDistributionHash) public returns (bool);
                function isContainerForFeeWindow(IFeeWindow _shadyTarget) public view returns (bool);
                function isContainerForMarket(IMarket _shadyTarget) public view returns (bool);
                function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
                function isContainerForShareToken(IShareToken _shadyTarget) public view returns (bool);
                function isContainerForFeeToken(IFeeToken _shadyTarget) public view returns (bool);
                function addMarketTo() public returns (bool);
                function removeMarketFrom() public returns (bool);
                function decrementOpenInterest(uint256 _amount) public returns (bool);
                function decrementOpenInterestFromMarket(uint256 _amount) public returns (bool);
                function incrementOpenInterest(uint256 _amount) public returns (bool);
                function incrementOpenInterestFromMarket(uint256 _amount) public returns (bool);
                function getWinningChildUniverse() public view returns (IUniverse);
                function isForking() public view returns (bool);
            }
            
            contract ICash is ERC20 {
                function depositEther() external payable returns(bool);
                function depositEtherFor(address _to) external payable returns(bool);
                function withdrawEther(uint256 _amount) external returns(bool);
                function withdrawEtherTo(address _to, uint256 _amount) external returns(bool);
                function withdrawEtherToIfPossible(address _to, uint256 _amount) external returns (bool);
            }
            
            contract IOrders {
                function saveOrder(Order.Types _type, IMarket _market, uint256 _fxpAmount, uint256 _price, address _sender, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed, bytes32 _betterOrderId, bytes32 _worseOrderId, bytes32 _tradeGroupId) public returns (bytes32 _orderId);
                function removeOrder(bytes32 _orderId) public returns (bool);
                function getMarket(bytes32 _orderId) public view returns (IMarket);
                function getOrderType(bytes32 _orderId) public view returns (Order.Types);
                function getOutcome(bytes32 _orderId) public view returns (uint256);
                function getAmount(bytes32 _orderId) public view returns (uint256);
                function getPrice(bytes32 _orderId) public view returns (uint256);
                function getOrderCreator(bytes32 _orderId) public view returns (address);
                function getOrderSharesEscrowed(bytes32 _orderId) public view returns (uint256);
                function getOrderMoneyEscrowed(bytes32 _orderId) public view returns (uint256);
                function getBetterOrderId(bytes32 _orderId) public view returns (bytes32);
                function getWorseOrderId(bytes32 _orderId) public view returns (bytes32);
                function getBestOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
                function getWorstOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
                function getLastOutcomePrice(IMarket _market, uint256 _outcome) public view returns (uint256);
                function getOrderId(Order.Types _type, IMarket _market, uint256 _fxpAmount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) public pure returns (bytes32);
                function getTotalEscrowed(IMarket _market) public view returns (uint256);
                function isBetterPrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
                function isWorsePrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
                function assertIsNotBetterPrice(Order.Types _type, uint256 _price, bytes32 _betterOrderId) public view returns (bool);
                function assertIsNotWorsePrice(Order.Types _type, uint256 _price, bytes32 _worseOrderId) public returns (bool);
                function recordFillOrder(bytes32 _orderId, uint256 _sharesFilled, uint256 _tokensFilled) public returns (bool);
                function setPrice(IMarket _market, uint256 _outcome, uint256 _price) external returns (bool);
                function incrementTotalEscrowed(IMarket _market, uint256 _amount) external returns (bool);
                function decrementTotalEscrowed(IMarket _market, uint256 _amount) external returns (bool);
            }
            
            contract IShareToken is ITyped, ERC20 {
                function initialize(IMarket _market, uint256 _outcome) external returns (bool);
                function createShares(address _owner, uint256 _amount) external returns (bool);
                function destroyShares(address, uint256 balance) external returns (bool);
                function getMarket() external view returns (IMarket);
                function getOutcome() external view returns (uint256);
                function trustedOrderTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedFillOrderTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedCancelOrderTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
            }
            
            library Order {
                using SafeMathUint256 for uint256;
            
                enum Types {
                    Bid, Ask
                }
            
                enum TradeDirections {
                    Long, Short
                }
            
                struct Data {
                    // Contracts
                    IOrders orders;
                    IMarket market;
                    IAugur augur;
            
                    // Order
                    bytes32 id;
                    address creator;
                    uint256 outcome;
                    Order.Types orderType;
                    uint256 amount;
                    uint256 price;
                    uint256 sharesEscrowed;
                    uint256 moneyEscrowed;
                    bytes32 betterOrderId;
                    bytes32 worseOrderId;
                }
            
                //
                // Constructor
                //
            
                // No validation is needed here as it is simply a librarty function for organizing data
                function create(IController _controller, address _creator, uint256 _outcome, Order.Types _type, uint256 _attoshares, uint256 _price, IMarket _market, bytes32 _betterOrderId, bytes32 _worseOrderId) internal view returns (Data) {
                    require(_outcome < _market.getNumberOfOutcomes());
                    require(_price < _market.getNumTicks());
            
                    IOrders _orders = IOrders(_controller.lookup("Orders"));
                    IAugur _augur = _controller.getAugur();
            
                    return Data({
                        orders: _orders,
                        market: _market,
                        augur: _augur,
                        id: 0,
                        creator: _creator,
                        outcome: _outcome,
                        orderType: _type,
                        amount: _attoshares,
                        price: _price,
                        sharesEscrowed: 0,
                        moneyEscrowed: 0,
                        betterOrderId: _betterOrderId,
                        worseOrderId: _worseOrderId
                    });
                }
            
                //
                // "public" functions
                //
            
                function getOrderId(Order.Data _orderData) internal view returns (bytes32) {
                    if (_orderData.id == bytes32(0)) {
                        bytes32 _orderId = _orderData.orders.getOrderId(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, block.number, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed);
                        require(_orderData.orders.getAmount(_orderId) == 0);
                        _orderData.id = _orderId;
                    }
                    return _orderData.id;
                }
            
                function getOrderTradingTypeFromMakerDirection(Order.TradeDirections _creatorDirection) internal pure returns (Order.Types) {
                    return (_creatorDirection == Order.TradeDirections.Long) ? Order.Types.Bid : Order.Types.Ask;
                }
            
                function getOrderTradingTypeFromFillerDirection(Order.TradeDirections _fillerDirection) internal pure returns (Order.Types) {
                    return (_fillerDirection == Order.TradeDirections.Long) ? Order.Types.Ask : Order.Types.Bid;
                }
            
                function escrowFunds(Order.Data _orderData) internal returns (bool) {
                    if (_orderData.orderType == Order.Types.Ask) {
                        return escrowFundsForAsk(_orderData);
                    } else if (_orderData.orderType == Order.Types.Bid) {
                        return escrowFundsForBid(_orderData);
                    }
                }
            
                function saveOrder(Order.Data _orderData, bytes32 _tradeGroupId) internal returns (bytes32) {
                    return _orderData.orders.saveOrder(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed, _orderData.betterOrderId, _orderData.worseOrderId, _tradeGroupId);
                }
            
                //
                // Private functions
                //
            
                function escrowFundsForBid(Order.Data _orderData) private returns (bool) {
                    require(_orderData.moneyEscrowed == 0);
                    require(_orderData.sharesEscrowed == 0);
                    uint256 _attosharesToCover = _orderData.amount;
                    uint256 _numberOfOutcomes = _orderData.market.getNumberOfOutcomes();
            
                    // Figure out how many almost-complete-sets (just missing `outcome` share) the creator has
                    uint256 _attosharesHeld = 2**254;
                    for (uint256 _i = 0; _i < _numberOfOutcomes; _i++) {
                        if (_i != _orderData.outcome) {
                            uint256 _creatorShareTokenBalance = _orderData.market.getShareToken(_i).balanceOf(_orderData.creator);
                            _attosharesHeld = SafeMathUint256.min(_creatorShareTokenBalance, _attosharesHeld);
                        }
                    }
            
                    // Take shares into escrow if they have any almost-complete-sets
                    if (_attosharesHeld > 0) {
                        _orderData.sharesEscrowed = SafeMathUint256.min(_attosharesHeld, _attosharesToCover);
                        _attosharesToCover -= _orderData.sharesEscrowed;
                        for (_i = 0; _i < _numberOfOutcomes; _i++) {
                            if (_i != _orderData.outcome) {
                                _orderData.market.getShareToken(_i).trustedOrderTransfer(_orderData.creator, _orderData.market, _orderData.sharesEscrowed);
                            }
                        }
                    }
                    // If not able to cover entire order with shares alone, then cover remaining with tokens
                    if (_attosharesToCover > 0) {
                        _orderData.moneyEscrowed = _attosharesToCover.mul(_orderData.price);
                        require(_orderData.augur.trustedTransfer(_orderData.market.getDenominationToken(), _orderData.creator, _orderData.market, _orderData.moneyEscrowed));
                    }
            
                    return true;
                }
            
                function escrowFundsForAsk(Order.Data _orderData) private returns (bool) {
                    require(_orderData.moneyEscrowed == 0);
                    require(_orderData.sharesEscrowed == 0);
                    IShareToken _shareToken = _orderData.market.getShareToken(_orderData.outcome);
                    uint256 _attosharesToCover = _orderData.amount;
            
                    // Figure out how many shares of the outcome the creator has
                    uint256 _attosharesHeld = _shareToken.balanceOf(_orderData.creator);
            
                    // Take shares in escrow if user has shares
                    if (_attosharesHeld > 0) {
                        _orderData.sharesEscrowed = SafeMathUint256.min(_attosharesHeld, _attosharesToCover);
                        _attosharesToCover -= _orderData.sharesEscrowed;
                        _shareToken.trustedOrderTransfer(_orderData.creator, _orderData.market, _orderData.sharesEscrowed);
                    }
            
                    // If not able to cover entire order with shares alone, then cover remaining with tokens
                    if (_attosharesToCover > 0) {
                        _orderData.moneyEscrowed = _orderData.market.getNumTicks().sub(_orderData.price).mul(_attosharesToCover);
                        require(_orderData.augur.trustedTransfer(_orderData.market.getDenominationToken(), _orderData.creator, _orderData.market, _orderData.moneyEscrowed));
                    }
            
                    return true;
                }
            }

            File 2 of 4: Controller
            pragma solidity 0.4.20;
            
            contract IAugur {
                function createChildUniverse(bytes32 _parentPayoutDistributionHash, uint256[] _parentPayoutNumerators, bool _parentInvalid) public returns (IUniverse);
                function isKnownUniverse(IUniverse _universe) public view returns (bool);
                function trustedTransfer(ERC20 _token, address _from, address _to, uint256 _amount) public returns (bool);
                function logMarketCreated(bytes32 _topic, string _description, string _extraInfo, IUniverse _universe, address _market, address _marketCreator, bytes32[] _outcomes, int256 _minPrice, int256 _maxPrice, IMarket.MarketType _marketType) public returns (bool);
                function logMarketCreated(bytes32 _topic, string _description, string _extraInfo, IUniverse _universe, address _market, address _marketCreator, int256 _minPrice, int256 _maxPrice, IMarket.MarketType _marketType) public returns (bool);
                function logInitialReportSubmitted(IUniverse _universe, address _reporter, address _market, uint256 _amountStaked, bool _isDesignatedReporter, uint256[] _payoutNumerators, bool _invalid) public returns (bool);
                function disputeCrowdsourcerCreated(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] _payoutNumerators, uint256 _size, bool _invalid) public returns (bool);
                function logDisputeCrowdsourcerContribution(IUniverse _universe, address _reporter, address _market, address _disputeCrowdsourcer, uint256 _amountStaked) public returns (bool);
                function logDisputeCrowdsourcerCompleted(IUniverse _universe, address _market, address _disputeCrowdsourcer) public returns (bool);
                function logInitialReporterRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256 _reportingFeesReceived, uint256[] _payoutNumerators) public returns (bool);
                function logDisputeCrowdsourcerRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256 _reportingFeesReceived, uint256[] _payoutNumerators) public returns (bool);
                function logFeeWindowRedeemed(IUniverse _universe, address _reporter, uint256 _amountRedeemed, uint256 _reportingFeesReceived) public returns (bool);
                function logMarketFinalized(IUniverse _universe) public returns (bool);
                function logMarketMigrated(IMarket _market, IUniverse _originalUniverse) public returns (bool);
                function logReportingParticipantDisavowed(IUniverse _universe, IMarket _market) public returns (bool);
                function logMarketParticipantsDisavowed(IUniverse _universe) public returns (bool);
                function logOrderCanceled(IUniverse _universe, address _shareToken, address _sender, bytes32 _orderId, Order.Types _orderType, uint256 _tokenRefund, uint256 _sharesRefund) public returns (bool);
                function logOrderCreated(Order.Types _orderType, uint256 _amount, uint256 _price, address _creator, uint256 _moneyEscrowed, uint256 _sharesEscrowed, bytes32 _tradeGroupId, bytes32 _orderId, IUniverse _universe, address _shareToken) public returns (bool);
                function logOrderFilled(IUniverse _universe, address _shareToken, address _filler, bytes32 _orderId, uint256 _numCreatorShares, uint256 _numCreatorTokens, uint256 _numFillerShares, uint256 _numFillerTokens, uint256 _marketCreatorFees, uint256 _reporterFees, uint256 _amountFilled, bytes32 _tradeGroupId) public returns (bool);
                function logCompleteSetsPurchased(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
                function logCompleteSetsSold(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
                function logTradingProceedsClaimed(IUniverse _universe, address _shareToken, address _sender, address _market, uint256 _numShares, uint256 _numPayoutTokens, uint256 _finalTokenBalance) public returns (bool);
                function logUniverseForked() public returns (bool);
                function logFeeWindowTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logReputationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logDisputeCrowdsourcerTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logShareTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logReputationTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logReputationTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logShareTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logShareTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeWindowBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeWindowMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logDisputeCrowdsourcerTokensBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logDisputeCrowdsourcerTokensMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeWindowCreated(IFeeWindow _feeWindow, uint256 _id) public returns (bool);
                function logFeeTokenTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logFeeTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logTimestampSet(uint256 _newTimestamp) public returns (bool);
                function logInitialReporterTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
                function logMarketTransferred(IUniverse _universe, address _from, address _to) public returns (bool);
                function logMarketMailboxTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
                function logEscapeHatchChanged(bool _isOn) public returns (bool);
            }
            
            contract IControlled {
                function getController() public view returns (IController);
                function setController(IController _controller) public returns(bool);
            }
            
            contract Controlled is IControlled {
                IController internal controller;
            
                modifier onlyWhitelistedCallers {
                    require(controller.assertIsWhitelisted(msg.sender));
                    _;
                }
            
                modifier onlyCaller(bytes32 _key) {
                    require(msg.sender == controller.lookup(_key));
                    _;
                }
            
                modifier onlyControllerCaller {
                    require(IController(msg.sender) == controller);
                    _;
                }
            
                modifier onlyInGoodTimes {
                    require(controller.stopInEmergency());
                    _;
                }
            
                modifier onlyInBadTimes {
                    require(controller.onlyInEmergency());
                    _;
                }
            
                function Controlled() public {
                    controller = IController(msg.sender);
                }
            
                function getController() public view returns(IController) {
                    return controller;
                }
            
                function setController(IController _controller) public onlyControllerCaller returns(bool) {
                    controller = _controller;
                    return true;
                }
            }
            
            contract IController {
                function assertIsWhitelisted(address _target) public view returns(bool);
                function lookup(bytes32 _key) public view returns(address);
                function stopInEmergency() public view returns(bool);
                function onlyInEmergency() public view returns(bool);
                function getAugur() public view returns (IAugur);
                function getTimestamp() public view returns (uint256);
            }
            
            contract Controller is IController {
                struct ContractDetails {
                    bytes32 name;
                    address contractAddress;
                    bytes20 commitHash;
                    bytes32 bytecodeHash;
                }
            
                address public owner;
                mapping(address => bool) public whitelist;
                mapping(bytes32 => ContractDetails) public registry;
                bool public stopped = false;
            
                modifier onlyOwnerCaller {
                    require(msg.sender == owner);
                    _;
                }
            
                modifier onlyInBadTimes {
                    require(stopped);
                    _;
                }
            
                modifier onlyInGoodTimes {
                    require(!stopped);
                    _;
                }
            
                function Controller() public {
                    owner = msg.sender;
                    whitelist[msg.sender] = true;
                }
            
                /*
                 * Contract Administration
                 */
            
                function addToWhitelist(address _target) public onlyOwnerCaller returns (bool) {
                    whitelist[_target] = true;
                    return true;
                }
            
                function removeFromWhitelist(address _target) public onlyOwnerCaller returns (bool) {
                    whitelist[_target] = false;
                    return true;
                }
            
                function assertIsWhitelisted(address _target) public view returns (bool) {
                    require(whitelist[_target]);
                    return true;
                }
            
                function registerContract(bytes32 _key, address _address, bytes20 _commitHash, bytes32 _bytecodeHash) public onlyOwnerCaller returns (bool) {
                    require(registry[_key].contractAddress == address(0));
                    registry[_key] = ContractDetails(_key, _address, _commitHash, _bytecodeHash);
                    return true;
                }
            
                function getContractDetails(bytes32 _key) public view returns (address, bytes20, bytes32) {
                    ContractDetails storage _details = registry[_key];
                    return (_details.contractAddress, _details.commitHash, _details.bytecodeHash);
                }
            
                function lookup(bytes32 _key) public view returns (address) {
                    return registry[_key].contractAddress;
                }
            
                function transferOwnership(address _newOwner) public onlyOwnerCaller returns (bool) {
                    owner = _newOwner;
                    return true;
                }
            
                function emergencyStop() public onlyOwnerCaller onlyInGoodTimes returns (bool) {
                    getAugur().logEscapeHatchChanged(true);
                    stopped = true;
                    return true;
                }
            
                function stopInEmergency() public view onlyInGoodTimes returns (bool) {
                    return true;
                }
            
                function onlyInEmergency() public view onlyInBadTimes returns (bool) {
                    return true;
                }
            
                /*
                 * Helper functions
                 */
            
                function getAugur() public view returns (IAugur) {
                    return IAugur(lookup("Augur"));
                }
            
                function getTimestamp() public view returns (uint256) {
                    return ITime(lookup("Time")).getTimestamp();
                }
            }
            
            contract IOwnable {
                function getOwner() public view returns (address);
                function transferOwnership(address newOwner) public returns (bool);
            }
            
            contract ITyped {
                function getTypeName() public view returns (bytes32);
            }
            
            contract ITime is Controlled, ITyped {
                function getTimestamp() external view returns (uint256);
            }
            
            contract Initializable {
                bool private initialized = false;
            
                modifier afterInitialized {
                    require(initialized);
                    _;
                }
            
                modifier beforeInitialized {
                    require(!initialized);
                    _;
                }
            
                function endInitialization() internal beforeInitialized returns (bool) {
                    initialized = true;
                    return true;
                }
            
                function getInitialized() public view returns (bool) {
                    return initialized;
                }
            }
            
            library SafeMathUint256 {
                function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                    uint256 c = a * b;
                    require(a == 0 || c / a == b);
                    return c;
                }
            
                function div(uint256 a, uint256 b) internal pure returns (uint256) {
                    // assert(b > 0); // Solidity automatically throws when dividing by 0
                    uint256 c = a / b;
                    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
                    return c;
                }
            
                function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                    require(b <= a);
                    return a - b;
                }
            
                function add(uint256 a, uint256 b) internal pure returns (uint256) {
                    uint256 c = a + b;
                    require(c >= a);
                    return c;
                }
            
                function min(uint256 a, uint256 b) internal pure returns (uint256) {
                    if (a <= b) {
                        return a;
                    } else {
                        return b;
                    }
                }
            
                function max(uint256 a, uint256 b) internal pure returns (uint256) {
                    if (a >= b) {
                        return a;
                    } else {
                        return b;
                    }
                }
            
                function getUint256Min() internal pure returns (uint256) {
                    return 0;
                }
            
                function getUint256Max() internal pure returns (uint256) {
                    return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
                }
            
                function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {
                    return a % b == 0;
                }
            
                // Float [fixed point] Operations
                function fxpMul(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
                    return div(mul(a, b), base);
                }
            
                function fxpDiv(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
                    return div(mul(a, base), b);
                }
            }
            
            contract ERC20Basic {
                event Transfer(address indexed from, address indexed to, uint256 value);
            
                function balanceOf(address _who) public view returns (uint256);
                function transfer(address _to, uint256 _value) public returns (bool);
                function totalSupply() public view returns (uint256);
            }
            
            contract ERC20 is ERC20Basic {
                event Approval(address indexed owner, address indexed spender, uint256 value);
            
                function allowance(address _owner, address _spender) public view returns (uint256);
                function transferFrom(address _from, address _to, uint256 _value) public returns (bool);
                function approve(address _spender, uint256 _value) public returns (bool);
            }
            
            contract IFeeToken is ERC20, Initializable {
                function initialize(IFeeWindow _feeWindow) public returns (bool);
                function getFeeWindow() public view returns (IFeeWindow);
                function feeWindowBurn(address _target, uint256 _amount) public returns (bool);
                function mintForReportingParticipant(address _target, uint256 _amount) public returns (bool);
            }
            
            contract IFeeWindow is ITyped, ERC20 {
                function initialize(IUniverse _universe, uint256 _feeWindowId) public returns (bool);
                function getUniverse() public view returns (IUniverse);
                function getReputationToken() public view returns (IReputationToken);
                function getStartTime() public view returns (uint256);
                function getEndTime() public view returns (uint256);
                function getNumMarkets() public view returns (uint256);
                function getNumInvalidMarkets() public view returns (uint256);
                function getNumIncorrectDesignatedReportMarkets() public view returns (uint256);
                function getNumDesignatedReportNoShows() public view returns (uint256);
                function getFeeToken() public view returns (IFeeToken);
                function isActive() public view returns (bool);
                function isOver() public view returns (bool);
                function onMarketFinalized() public returns (bool);
                function buy(uint256 _attotokens) public returns (bool);
                function redeem(address _sender) public returns (bool);
                function redeemForReportingParticipant() public returns (bool);
                function mintFeeTokens(uint256 _amount) public returns (bool);
                function trustedUniverseBuy(address _buyer, uint256 _attotokens) public returns (bool);
            }
            
            contract IMailbox {
                function initialize(address _owner, IMarket _market) public returns (bool);
                function depositEther() public payable returns (bool);
            }
            
            contract IMarket is ITyped, IOwnable {
                enum MarketType {
                    YES_NO,
                    CATEGORICAL,
                    SCALAR
                }
            
                function initialize(IUniverse _universe, uint256 _endTime, uint256 _feePerEthInAttoeth, ICash _cash, address _designatedReporterAddress, address _creator, uint256 _numOutcomes, uint256 _numTicks) public payable returns (bool _success);
                function derivePayoutDistributionHash(uint256[] _payoutNumerators, bool _invalid) public view returns (bytes32);
                function getUniverse() public view returns (IUniverse);
                function getFeeWindow() public view returns (IFeeWindow);
                function getNumberOfOutcomes() public view returns (uint256);
                function getNumTicks() public view returns (uint256);
                function getDenominationToken() public view returns (ICash);
                function getShareToken(uint256 _outcome)  public view returns (IShareToken);
                function getMarketCreatorSettlementFeeDivisor() public view returns (uint256);
                function getForkingMarket() public view returns (IMarket _market);
                function getEndTime() public view returns (uint256);
                function getMarketCreatorMailbox() public view returns (IMailbox);
                function getWinningPayoutDistributionHash() public view returns (bytes32);
                function getWinningPayoutNumerator(uint256 _outcome) public view returns (uint256);
                function getReputationToken() public view returns (IReputationToken);
                function getFinalizationTime() public view returns (uint256);
                function getInitialReporterAddress() public view returns (address);
                function deriveMarketCreatorFeeAmount(uint256 _amount) public view returns (uint256);
                function isContainerForShareToken(IShareToken _shadyTarget) public view returns (bool);
                function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
                function isInvalid() public view returns (bool);
                function finalize() public returns (bool);
                function designatedReporterWasCorrect() public view returns (bool);
                function designatedReporterShowed() public view returns (bool);
                function isFinalized() public view returns (bool);
                function finalizeFork() public returns (bool);
                function assertBalances() public view returns (bool);
            }
            
            contract IReportingParticipant {
                function getStake() public view returns (uint256);
                function getPayoutDistributionHash() public view returns (bytes32);
                function liquidateLosing() public returns (bool);
                function redeem(address _redeemer) public returns (bool);
                function isInvalid() public view returns (bool);
                function isDisavowed() public view returns (bool);
                function migrate() public returns (bool);
                function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
                function getMarket() public view returns (IMarket);
                function getSize() public view returns (uint256);
            }
            
            contract IDisputeCrowdsourcer is IReportingParticipant, ERC20 {
                function initialize(IMarket market, uint256 _size, bytes32 _payoutDistributionHash, uint256[] _payoutNumerators, bool _invalid) public returns (bool);
                function contribute(address _participant, uint256 _amount) public returns (uint256);
            }
            
            contract IReputationToken is ITyped, ERC20 {
                function initialize(IUniverse _universe) public returns (bool);
                function migrateOut(IReputationToken _destination, uint256 _attotokens) public returns (bool);
                function migrateIn(address _reporter, uint256 _attotokens) public returns (bool);
                function trustedReportingParticipantTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedMarketTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedFeeWindowTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedUniverseTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function getUniverse() public view returns (IUniverse);
                function getTotalMigrated() public view returns (uint256);
                function getTotalTheoreticalSupply() public view returns (uint256);
                function mintForReportingParticipant(uint256 _amountMigrated) public returns (bool);
            }
            
            contract IUniverse is ITyped {
                function initialize(IUniverse _parentUniverse, bytes32 _parentPayoutDistributionHash) external returns (bool);
                function fork() public returns (bool);
                function getParentUniverse() public view returns (IUniverse);
                function createChildUniverse(uint256[] _parentPayoutNumerators, bool _invalid) public returns (IUniverse);
                function getChildUniverse(bytes32 _parentPayoutDistributionHash) public view returns (IUniverse);
                function getReputationToken() public view returns (IReputationToken);
                function getForkingMarket() public view returns (IMarket);
                function getForkEndTime() public view returns (uint256);
                function getForkReputationGoal() public view returns (uint256);
                function getParentPayoutDistributionHash() public view returns (bytes32);
                function getDisputeRoundDurationInSeconds() public view returns (uint256);
                function getOrCreateFeeWindowByTimestamp(uint256 _timestamp) public returns (IFeeWindow);
                function getOrCreateCurrentFeeWindow() public returns (IFeeWindow);
                function getOrCreateNextFeeWindow() public returns (IFeeWindow);
                function getOpenInterestInAttoEth() public view returns (uint256);
                function getRepMarketCapInAttoeth() public view returns (uint256);
                function getTargetRepMarketCapInAttoeth() public view returns (uint256);
                function getOrCacheValidityBond() public returns (uint256);
                function getOrCacheDesignatedReportStake() public returns (uint256);
                function getOrCacheDesignatedReportNoShowBond() public returns (uint256);
                function getOrCacheReportingFeeDivisor() public returns (uint256);
                function getDisputeThresholdForFork() public view returns (uint256);
                function getInitialReportMinValue() public view returns (uint256);
                function calculateFloatingValue(uint256 _badMarkets, uint256 _totalMarkets, uint256 _targetDivisor, uint256 _previousValue, uint256 _defaultValue, uint256 _floor) public pure returns (uint256 _newValue);
                function getOrCacheMarketCreationCost() public returns (uint256);
                function getCurrentFeeWindow() public view returns (IFeeWindow);
                function getOrCreateFeeWindowBefore(IFeeWindow _feeWindow) public returns (IFeeWindow);
                function isParentOf(IUniverse _shadyChild) public view returns (bool);
                function updateTentativeWinningChildUniverse(bytes32 _parentPayoutDistributionHash) public returns (bool);
                function isContainerForFeeWindow(IFeeWindow _shadyTarget) public view returns (bool);
                function isContainerForMarket(IMarket _shadyTarget) public view returns (bool);
                function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
                function isContainerForShareToken(IShareToken _shadyTarget) public view returns (bool);
                function isContainerForFeeToken(IFeeToken _shadyTarget) public view returns (bool);
                function addMarketTo() public returns (bool);
                function removeMarketFrom() public returns (bool);
                function decrementOpenInterest(uint256 _amount) public returns (bool);
                function decrementOpenInterestFromMarket(uint256 _amount) public returns (bool);
                function incrementOpenInterest(uint256 _amount) public returns (bool);
                function incrementOpenInterestFromMarket(uint256 _amount) public returns (bool);
                function getWinningChildUniverse() public view returns (IUniverse);
                function isForking() public view returns (bool);
            }
            
            contract ICash is ERC20 {
                function depositEther() external payable returns(bool);
                function depositEtherFor(address _to) external payable returns(bool);
                function withdrawEther(uint256 _amount) external returns(bool);
                function withdrawEtherTo(address _to, uint256 _amount) external returns(bool);
                function withdrawEtherToIfPossible(address _to, uint256 _amount) external returns (bool);
            }
            
            contract IOrders {
                function saveOrder(Order.Types _type, IMarket _market, uint256 _fxpAmount, uint256 _price, address _sender, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed, bytes32 _betterOrderId, bytes32 _worseOrderId, bytes32 _tradeGroupId) public returns (bytes32 _orderId);
                function removeOrder(bytes32 _orderId) public returns (bool);
                function getMarket(bytes32 _orderId) public view returns (IMarket);
                function getOrderType(bytes32 _orderId) public view returns (Order.Types);
                function getOutcome(bytes32 _orderId) public view returns (uint256);
                function getAmount(bytes32 _orderId) public view returns (uint256);
                function getPrice(bytes32 _orderId) public view returns (uint256);
                function getOrderCreator(bytes32 _orderId) public view returns (address);
                function getOrderSharesEscrowed(bytes32 _orderId) public view returns (uint256);
                function getOrderMoneyEscrowed(bytes32 _orderId) public view returns (uint256);
                function getBetterOrderId(bytes32 _orderId) public view returns (bytes32);
                function getWorseOrderId(bytes32 _orderId) public view returns (bytes32);
                function getBestOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
                function getWorstOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
                function getLastOutcomePrice(IMarket _market, uint256 _outcome) public view returns (uint256);
                function getOrderId(Order.Types _type, IMarket _market, uint256 _fxpAmount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) public pure returns (bytes32);
                function getTotalEscrowed(IMarket _market) public view returns (uint256);
                function isBetterPrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
                function isWorsePrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
                function assertIsNotBetterPrice(Order.Types _type, uint256 _price, bytes32 _betterOrderId) public view returns (bool);
                function assertIsNotWorsePrice(Order.Types _type, uint256 _price, bytes32 _worseOrderId) public returns (bool);
                function recordFillOrder(bytes32 _orderId, uint256 _sharesFilled, uint256 _tokensFilled) public returns (bool);
                function setPrice(IMarket _market, uint256 _outcome, uint256 _price) external returns (bool);
                function incrementTotalEscrowed(IMarket _market, uint256 _amount) external returns (bool);
                function decrementTotalEscrowed(IMarket _market, uint256 _amount) external returns (bool);
            }
            
            contract IShareToken is ITyped, ERC20 {
                function initialize(IMarket _market, uint256 _outcome) external returns (bool);
                function createShares(address _owner, uint256 _amount) external returns (bool);
                function destroyShares(address, uint256 balance) external returns (bool);
                function getMarket() external view returns (IMarket);
                function getOutcome() external view returns (uint256);
                function trustedOrderTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedFillOrderTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedCancelOrderTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
            }
            
            library Order {
                using SafeMathUint256 for uint256;
            
                enum Types {
                    Bid, Ask
                }
            
                enum TradeDirections {
                    Long, Short
                }
            
                struct Data {
                    // Contracts
                    IOrders orders;
                    IMarket market;
                    IAugur augur;
            
                    // Order
                    bytes32 id;
                    address creator;
                    uint256 outcome;
                    Order.Types orderType;
                    uint256 amount;
                    uint256 price;
                    uint256 sharesEscrowed;
                    uint256 moneyEscrowed;
                    bytes32 betterOrderId;
                    bytes32 worseOrderId;
                }
            
                //
                // Constructor
                //
            
                // No validation is needed here as it is simply a librarty function for organizing data
                function create(IController _controller, address _creator, uint256 _outcome, Order.Types _type, uint256 _attoshares, uint256 _price, IMarket _market, bytes32 _betterOrderId, bytes32 _worseOrderId) internal view returns (Data) {
                    require(_outcome < _market.getNumberOfOutcomes());
                    require(_price < _market.getNumTicks());
            
                    IOrders _orders = IOrders(_controller.lookup("Orders"));
                    IAugur _augur = _controller.getAugur();
            
                    return Data({
                        orders: _orders,
                        market: _market,
                        augur: _augur,
                        id: 0,
                        creator: _creator,
                        outcome: _outcome,
                        orderType: _type,
                        amount: _attoshares,
                        price: _price,
                        sharesEscrowed: 0,
                        moneyEscrowed: 0,
                        betterOrderId: _betterOrderId,
                        worseOrderId: _worseOrderId
                    });
                }
            
                //
                // "public" functions
                //
            
                function getOrderId(Order.Data _orderData) internal view returns (bytes32) {
                    if (_orderData.id == bytes32(0)) {
                        bytes32 _orderId = _orderData.orders.getOrderId(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, block.number, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed);
                        require(_orderData.orders.getAmount(_orderId) == 0);
                        _orderData.id = _orderId;
                    }
                    return _orderData.id;
                }
            
                function getOrderTradingTypeFromMakerDirection(Order.TradeDirections _creatorDirection) internal pure returns (Order.Types) {
                    return (_creatorDirection == Order.TradeDirections.Long) ? Order.Types.Bid : Order.Types.Ask;
                }
            
                function getOrderTradingTypeFromFillerDirection(Order.TradeDirections _fillerDirection) internal pure returns (Order.Types) {
                    return (_fillerDirection == Order.TradeDirections.Long) ? Order.Types.Ask : Order.Types.Bid;
                }
            
                function escrowFunds(Order.Data _orderData) internal returns (bool) {
                    if (_orderData.orderType == Order.Types.Ask) {
                        return escrowFundsForAsk(_orderData);
                    } else if (_orderData.orderType == Order.Types.Bid) {
                        return escrowFundsForBid(_orderData);
                    }
                }
            
                function saveOrder(Order.Data _orderData, bytes32 _tradeGroupId) internal returns (bytes32) {
                    return _orderData.orders.saveOrder(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed, _orderData.betterOrderId, _orderData.worseOrderId, _tradeGroupId);
                }
            
                //
                // Private functions
                //
            
                function escrowFundsForBid(Order.Data _orderData) private returns (bool) {
                    require(_orderData.moneyEscrowed == 0);
                    require(_orderData.sharesEscrowed == 0);
                    uint256 _attosharesToCover = _orderData.amount;
                    uint256 _numberOfOutcomes = _orderData.market.getNumberOfOutcomes();
            
                    // Figure out how many almost-complete-sets (just missing `outcome` share) the creator has
                    uint256 _attosharesHeld = 2**254;
                    for (uint256 _i = 0; _i < _numberOfOutcomes; _i++) {
                        if (_i != _orderData.outcome) {
                            uint256 _creatorShareTokenBalance = _orderData.market.getShareToken(_i).balanceOf(_orderData.creator);
                            _attosharesHeld = SafeMathUint256.min(_creatorShareTokenBalance, _attosharesHeld);
                        }
                    }
            
                    // Take shares into escrow if they have any almost-complete-sets
                    if (_attosharesHeld > 0) {
                        _orderData.sharesEscrowed = SafeMathUint256.min(_attosharesHeld, _attosharesToCover);
                        _attosharesToCover -= _orderData.sharesEscrowed;
                        for (_i = 0; _i < _numberOfOutcomes; _i++) {
                            if (_i != _orderData.outcome) {
                                _orderData.market.getShareToken(_i).trustedOrderTransfer(_orderData.creator, _orderData.market, _orderData.sharesEscrowed);
                            }
                        }
                    }
                    // If not able to cover entire order with shares alone, then cover remaining with tokens
                    if (_attosharesToCover > 0) {
                        _orderData.moneyEscrowed = _attosharesToCover.mul(_orderData.price);
                        require(_orderData.augur.trustedTransfer(_orderData.market.getDenominationToken(), _orderData.creator, _orderData.market, _orderData.moneyEscrowed));
                    }
            
                    return true;
                }
            
                function escrowFundsForAsk(Order.Data _orderData) private returns (bool) {
                    require(_orderData.moneyEscrowed == 0);
                    require(_orderData.sharesEscrowed == 0);
                    IShareToken _shareToken = _orderData.market.getShareToken(_orderData.outcome);
                    uint256 _attosharesToCover = _orderData.amount;
            
                    // Figure out how many shares of the outcome the creator has
                    uint256 _attosharesHeld = _shareToken.balanceOf(_orderData.creator);
            
                    // Take shares in escrow if user has shares
                    if (_attosharesHeld > 0) {
                        _orderData.sharesEscrowed = SafeMathUint256.min(_attosharesHeld, _attosharesToCover);
                        _attosharesToCover -= _orderData.sharesEscrowed;
                        _shareToken.trustedOrderTransfer(_orderData.creator, _orderData.market, _orderData.sharesEscrowed);
                    }
            
                    // If not able to cover entire order with shares alone, then cover remaining with tokens
                    if (_attosharesToCover > 0) {
                        _orderData.moneyEscrowed = _orderData.market.getNumTicks().sub(_orderData.price).mul(_attosharesToCover);
                        require(_orderData.augur.trustedTransfer(_orderData.market.getDenominationToken(), _orderData.creator, _orderData.market, _orderData.moneyEscrowed));
                    }
            
                    return true;
                }
            }

            File 3 of 4: Mailbox
            pragma solidity 0.4.20;
            
            contract IAugur {
                function createChildUniverse(bytes32 _parentPayoutDistributionHash, uint256[] _parentPayoutNumerators, bool _parentInvalid) public returns (IUniverse);
                function isKnownUniverse(IUniverse _universe) public view returns (bool);
                function trustedTransfer(ERC20 _token, address _from, address _to, uint256 _amount) public returns (bool);
                function logMarketCreated(bytes32 _topic, string _description, string _extraInfo, IUniverse _universe, address _market, address _marketCreator, bytes32[] _outcomes, int256 _minPrice, int256 _maxPrice, IMarket.MarketType _marketType) public returns (bool);
                function logMarketCreated(bytes32 _topic, string _description, string _extraInfo, IUniverse _universe, address _market, address _marketCreator, int256 _minPrice, int256 _maxPrice, IMarket.MarketType _marketType) public returns (bool);
                function logInitialReportSubmitted(IUniverse _universe, address _reporter, address _market, uint256 _amountStaked, bool _isDesignatedReporter, uint256[] _payoutNumerators, bool _invalid) public returns (bool);
                function disputeCrowdsourcerCreated(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] _payoutNumerators, uint256 _size, bool _invalid) public returns (bool);
                function logDisputeCrowdsourcerContribution(IUniverse _universe, address _reporter, address _market, address _disputeCrowdsourcer, uint256 _amountStaked) public returns (bool);
                function logDisputeCrowdsourcerCompleted(IUniverse _universe, address _market, address _disputeCrowdsourcer) public returns (bool);
                function logInitialReporterRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256 _reportingFeesReceived, uint256[] _payoutNumerators) public returns (bool);
                function logDisputeCrowdsourcerRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256 _reportingFeesReceived, uint256[] _payoutNumerators) public returns (bool);
                function logFeeWindowRedeemed(IUniverse _universe, address _reporter, uint256 _amountRedeemed, uint256 _reportingFeesReceived) public returns (bool);
                function logMarketFinalized(IUniverse _universe) public returns (bool);
                function logMarketMigrated(IMarket _market, IUniverse _originalUniverse) public returns (bool);
                function logReportingParticipantDisavowed(IUniverse _universe, IMarket _market) public returns (bool);
                function logMarketParticipantsDisavowed(IUniverse _universe) public returns (bool);
                function logOrderCanceled(IUniverse _universe, address _shareToken, address _sender, bytes32 _orderId, Order.Types _orderType, uint256 _tokenRefund, uint256 _sharesRefund) public returns (bool);
                function logOrderCreated(Order.Types _orderType, uint256 _amount, uint256 _price, address _creator, uint256 _moneyEscrowed, uint256 _sharesEscrowed, bytes32 _tradeGroupId, bytes32 _orderId, IUniverse _universe, address _shareToken) public returns (bool);
                function logOrderFilled(IUniverse _universe, address _shareToken, address _filler, bytes32 _orderId, uint256 _numCreatorShares, uint256 _numCreatorTokens, uint256 _numFillerShares, uint256 _numFillerTokens, uint256 _marketCreatorFees, uint256 _reporterFees, uint256 _amountFilled, bytes32 _tradeGroupId) public returns (bool);
                function logCompleteSetsPurchased(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
                function logCompleteSetsSold(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
                function logTradingProceedsClaimed(IUniverse _universe, address _shareToken, address _sender, address _market, uint256 _numShares, uint256 _numPayoutTokens, uint256 _finalTokenBalance) public returns (bool);
                function logUniverseForked() public returns (bool);
                function logFeeWindowTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logReputationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logDisputeCrowdsourcerTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logShareTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logReputationTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logReputationTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logShareTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logShareTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeWindowBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeWindowMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logDisputeCrowdsourcerTokensBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logDisputeCrowdsourcerTokensMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeWindowCreated(IFeeWindow _feeWindow, uint256 _id) public returns (bool);
                function logFeeTokenTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logFeeTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logTimestampSet(uint256 _newTimestamp) public returns (bool);
                function logInitialReporterTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
                function logMarketTransferred(IUniverse _universe, address _from, address _to) public returns (bool);
                function logMarketMailboxTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
                function logEscapeHatchChanged(bool _isOn) public returns (bool);
            }
            
            contract IControlled {
                function getController() public view returns (IController);
                function setController(IController _controller) public returns(bool);
            }
            
            contract Controlled is IControlled {
                IController internal controller;
            
                modifier onlyWhitelistedCallers {
                    require(controller.assertIsWhitelisted(msg.sender));
                    _;
                }
            
                modifier onlyCaller(bytes32 _key) {
                    require(msg.sender == controller.lookup(_key));
                    _;
                }
            
                modifier onlyControllerCaller {
                    require(IController(msg.sender) == controller);
                    _;
                }
            
                modifier onlyInGoodTimes {
                    require(controller.stopInEmergency());
                    _;
                }
            
                modifier onlyInBadTimes {
                    require(controller.onlyInEmergency());
                    _;
                }
            
                function Controlled() public {
                    controller = IController(msg.sender);
                }
            
                function getController() public view returns(IController) {
                    return controller;
                }
            
                function setController(IController _controller) public onlyControllerCaller returns(bool) {
                    controller = _controller;
                    return true;
                }
            }
            
            contract IController {
                function assertIsWhitelisted(address _target) public view returns(bool);
                function lookup(bytes32 _key) public view returns(address);
                function stopInEmergency() public view returns(bool);
                function onlyInEmergency() public view returns(bool);
                function getAugur() public view returns (IAugur);
                function getTimestamp() public view returns (uint256);
            }
            
            contract DelegationTarget is Controlled {
                bytes32 public controllerLookupName;
            }
            
            contract IOwnable {
                function getOwner() public view returns (address);
                function transferOwnership(address newOwner) public returns (bool);
            }
            
            contract ITyped {
                function getTypeName() public view returns (bytes32);
            }
            
            contract Initializable {
                bool private initialized = false;
            
                modifier afterInitialized {
                    require(initialized);
                    _;
                }
            
                modifier beforeInitialized {
                    require(!initialized);
                    _;
                }
            
                function endInitialization() internal beforeInitialized returns (bool) {
                    initialized = true;
                    return true;
                }
            
                function getInitialized() public view returns (bool) {
                    return initialized;
                }
            }
            
            contract Ownable is IOwnable {
                address internal owner;
            
                /**
                 * @dev The Ownable constructor sets the original `owner` of the contract to the sender
                 * account.
                 */
                function Ownable() public {
                    owner = msg.sender;
                }
            
                /**
                 * @dev Throws if called by any account other than the owner.
                 */
                modifier onlyOwner() {
                    require(msg.sender == owner);
                    _;
                }
            
                function getOwner() public view returns (address) {
                    return owner;
                }
            
                /**
                 * @dev Allows the current owner to transfer control of the contract to a newOwner.
                 * @param _newOwner The address to transfer ownership to.
                 */
                function transferOwnership(address _newOwner) public onlyOwner returns (bool) {
                    if (_newOwner != address(0)) {
                        onTransferOwnership(owner, _newOwner);
                        owner = _newOwner;
                    }
                    return true;
                }
            
                // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract
                function onTransferOwnership(address, address) internal returns (bool);
            }
            
            library SafeMathUint256 {
                function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                    uint256 c = a * b;
                    require(a == 0 || c / a == b);
                    return c;
                }
            
                function div(uint256 a, uint256 b) internal pure returns (uint256) {
                    // assert(b > 0); // Solidity automatically throws when dividing by 0
                    uint256 c = a / b;
                    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
                    return c;
                }
            
                function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                    require(b <= a);
                    return a - b;
                }
            
                function add(uint256 a, uint256 b) internal pure returns (uint256) {
                    uint256 c = a + b;
                    require(c >= a);
                    return c;
                }
            
                function min(uint256 a, uint256 b) internal pure returns (uint256) {
                    if (a <= b) {
                        return a;
                    } else {
                        return b;
                    }
                }
            
                function max(uint256 a, uint256 b) internal pure returns (uint256) {
                    if (a >= b) {
                        return a;
                    } else {
                        return b;
                    }
                }
            
                function getUint256Min() internal pure returns (uint256) {
                    return 0;
                }
            
                function getUint256Max() internal pure returns (uint256) {
                    return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
                }
            
                function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {
                    return a % b == 0;
                }
            
                // Float [fixed point] Operations
                function fxpMul(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
                    return div(mul(a, b), base);
                }
            
                function fxpDiv(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
                    return div(mul(a, base), b);
                }
            }
            
            contract ERC20Basic {
                event Transfer(address indexed from, address indexed to, uint256 value);
            
                function balanceOf(address _who) public view returns (uint256);
                function transfer(address _to, uint256 _value) public returns (bool);
                function totalSupply() public view returns (uint256);
            }
            
            contract ERC20 is ERC20Basic {
                event Approval(address indexed owner, address indexed spender, uint256 value);
            
                function allowance(address _owner, address _spender) public view returns (uint256);
                function transferFrom(address _from, address _to, uint256 _value) public returns (bool);
                function approve(address _spender, uint256 _value) public returns (bool);
            }
            
            contract IFeeToken is ERC20, Initializable {
                function initialize(IFeeWindow _feeWindow) public returns (bool);
                function getFeeWindow() public view returns (IFeeWindow);
                function feeWindowBurn(address _target, uint256 _amount) public returns (bool);
                function mintForReportingParticipant(address _target, uint256 _amount) public returns (bool);
            }
            
            contract IFeeWindow is ITyped, ERC20 {
                function initialize(IUniverse _universe, uint256 _feeWindowId) public returns (bool);
                function getUniverse() public view returns (IUniverse);
                function getReputationToken() public view returns (IReputationToken);
                function getStartTime() public view returns (uint256);
                function getEndTime() public view returns (uint256);
                function getNumMarkets() public view returns (uint256);
                function getNumInvalidMarkets() public view returns (uint256);
                function getNumIncorrectDesignatedReportMarkets() public view returns (uint256);
                function getNumDesignatedReportNoShows() public view returns (uint256);
                function getFeeToken() public view returns (IFeeToken);
                function isActive() public view returns (bool);
                function isOver() public view returns (bool);
                function onMarketFinalized() public returns (bool);
                function buy(uint256 _attotokens) public returns (bool);
                function redeem(address _sender) public returns (bool);
                function redeemForReportingParticipant() public returns (bool);
                function mintFeeTokens(uint256 _amount) public returns (bool);
                function trustedUniverseBuy(address _buyer, uint256 _attotokens) public returns (bool);
            }
            
            contract IMailbox {
                function initialize(address _owner, IMarket _market) public returns (bool);
                function depositEther() public payable returns (bool);
            }
            
            contract IMarket is ITyped, IOwnable {
                enum MarketType {
                    YES_NO,
                    CATEGORICAL,
                    SCALAR
                }
            
                function initialize(IUniverse _universe, uint256 _endTime, uint256 _feePerEthInAttoeth, ICash _cash, address _designatedReporterAddress, address _creator, uint256 _numOutcomes, uint256 _numTicks) public payable returns (bool _success);
                function derivePayoutDistributionHash(uint256[] _payoutNumerators, bool _invalid) public view returns (bytes32);
                function getUniverse() public view returns (IUniverse);
                function getFeeWindow() public view returns (IFeeWindow);
                function getNumberOfOutcomes() public view returns (uint256);
                function getNumTicks() public view returns (uint256);
                function getDenominationToken() public view returns (ICash);
                function getShareToken(uint256 _outcome)  public view returns (IShareToken);
                function getMarketCreatorSettlementFeeDivisor() public view returns (uint256);
                function getForkingMarket() public view returns (IMarket _market);
                function getEndTime() public view returns (uint256);
                function getMarketCreatorMailbox() public view returns (IMailbox);
                function getWinningPayoutDistributionHash() public view returns (bytes32);
                function getWinningPayoutNumerator(uint256 _outcome) public view returns (uint256);
                function getReputationToken() public view returns (IReputationToken);
                function getFinalizationTime() public view returns (uint256);
                function getInitialReporterAddress() public view returns (address);
                function deriveMarketCreatorFeeAmount(uint256 _amount) public view returns (uint256);
                function isContainerForShareToken(IShareToken _shadyTarget) public view returns (bool);
                function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
                function isInvalid() public view returns (bool);
                function finalize() public returns (bool);
                function designatedReporterWasCorrect() public view returns (bool);
                function designatedReporterShowed() public view returns (bool);
                function isFinalized() public view returns (bool);
                function finalizeFork() public returns (bool);
                function assertBalances() public view returns (bool);
            }
            
            contract IReportingParticipant {
                function getStake() public view returns (uint256);
                function getPayoutDistributionHash() public view returns (bytes32);
                function liquidateLosing() public returns (bool);
                function redeem(address _redeemer) public returns (bool);
                function isInvalid() public view returns (bool);
                function isDisavowed() public view returns (bool);
                function migrate() public returns (bool);
                function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
                function getMarket() public view returns (IMarket);
                function getSize() public view returns (uint256);
            }
            
            contract IDisputeCrowdsourcer is IReportingParticipant, ERC20 {
                function initialize(IMarket market, uint256 _size, bytes32 _payoutDistributionHash, uint256[] _payoutNumerators, bool _invalid) public returns (bool);
                function contribute(address _participant, uint256 _amount) public returns (uint256);
            }
            
            contract IReputationToken is ITyped, ERC20 {
                function initialize(IUniverse _universe) public returns (bool);
                function migrateOut(IReputationToken _destination, uint256 _attotokens) public returns (bool);
                function migrateIn(address _reporter, uint256 _attotokens) public returns (bool);
                function trustedReportingParticipantTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedMarketTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedFeeWindowTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedUniverseTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function getUniverse() public view returns (IUniverse);
                function getTotalMigrated() public view returns (uint256);
                function getTotalTheoreticalSupply() public view returns (uint256);
                function mintForReportingParticipant(uint256 _amountMigrated) public returns (bool);
            }
            
            contract IUniverse is ITyped {
                function initialize(IUniverse _parentUniverse, bytes32 _parentPayoutDistributionHash) external returns (bool);
                function fork() public returns (bool);
                function getParentUniverse() public view returns (IUniverse);
                function createChildUniverse(uint256[] _parentPayoutNumerators, bool _invalid) public returns (IUniverse);
                function getChildUniverse(bytes32 _parentPayoutDistributionHash) public view returns (IUniverse);
                function getReputationToken() public view returns (IReputationToken);
                function getForkingMarket() public view returns (IMarket);
                function getForkEndTime() public view returns (uint256);
                function getForkReputationGoal() public view returns (uint256);
                function getParentPayoutDistributionHash() public view returns (bytes32);
                function getDisputeRoundDurationInSeconds() public view returns (uint256);
                function getOrCreateFeeWindowByTimestamp(uint256 _timestamp) public returns (IFeeWindow);
                function getOrCreateCurrentFeeWindow() public returns (IFeeWindow);
                function getOrCreateNextFeeWindow() public returns (IFeeWindow);
                function getOpenInterestInAttoEth() public view returns (uint256);
                function getRepMarketCapInAttoeth() public view returns (uint256);
                function getTargetRepMarketCapInAttoeth() public view returns (uint256);
                function getOrCacheValidityBond() public returns (uint256);
                function getOrCacheDesignatedReportStake() public returns (uint256);
                function getOrCacheDesignatedReportNoShowBond() public returns (uint256);
                function getOrCacheReportingFeeDivisor() public returns (uint256);
                function getDisputeThresholdForFork() public view returns (uint256);
                function getInitialReportMinValue() public view returns (uint256);
                function calculateFloatingValue(uint256 _badMarkets, uint256 _totalMarkets, uint256 _targetDivisor, uint256 _previousValue, uint256 _defaultValue, uint256 _floor) public pure returns (uint256 _newValue);
                function getOrCacheMarketCreationCost() public returns (uint256);
                function getCurrentFeeWindow() public view returns (IFeeWindow);
                function getOrCreateFeeWindowBefore(IFeeWindow _feeWindow) public returns (IFeeWindow);
                function isParentOf(IUniverse _shadyChild) public view returns (bool);
                function updateTentativeWinningChildUniverse(bytes32 _parentPayoutDistributionHash) public returns (bool);
                function isContainerForFeeWindow(IFeeWindow _shadyTarget) public view returns (bool);
                function isContainerForMarket(IMarket _shadyTarget) public view returns (bool);
                function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
                function isContainerForShareToken(IShareToken _shadyTarget) public view returns (bool);
                function isContainerForFeeToken(IFeeToken _shadyTarget) public view returns (bool);
                function addMarketTo() public returns (bool);
                function removeMarketFrom() public returns (bool);
                function decrementOpenInterest(uint256 _amount) public returns (bool);
                function decrementOpenInterestFromMarket(uint256 _amount) public returns (bool);
                function incrementOpenInterest(uint256 _amount) public returns (bool);
                function incrementOpenInterestFromMarket(uint256 _amount) public returns (bool);
                function getWinningChildUniverse() public view returns (IUniverse);
                function isForking() public view returns (bool);
            }
            
            contract Mailbox is DelegationTarget, Ownable, Initializable, IMailbox {
                IMarket private market;
            
                function initialize(address _owner, IMarket _market) public onlyInGoodTimes beforeInitialized returns (bool) {
                    endInitialization();
                    owner = _owner;
                    market = _market;
                    return true;
                }
            
                //As a delegation target we cannot override the fallback, so we provide a specific method to deposit ETH
                function depositEther() public payable onlyInGoodTimes returns (bool) {
                    return true;
                }
            
                function withdrawEther() public onlyOwner returns (bool) {
                    // Withdraw any Cash balance
                    ICash _cash = ICash(controller.lookup("Cash"));
                    uint256 _tokenBalance = _cash.balanceOf(this);
                    if (_tokenBalance > 0) {
                        _cash.withdrawEtherTo(owner, _tokenBalance);
                    }
                    // Withdraw any ETH balance
                    if (this.balance > 0) {
                        owner.transfer(this.balance);
                    }
                    return true;
                }
            
                function withdrawTokens(ERC20Basic _token) public onlyOwner returns (bool) {
                    uint256 _balance = _token.balanceOf(this);
                    require(_token.transfer(owner, _balance));
                    return true;
                }
            
                function onTransferOwnership(address _owner, address _newOwner) internal returns (bool) {
                    controller.getAugur().logMarketMailboxTransferred(market.getUniverse(), market, _owner, _newOwner);
                    return true;
                }
            }
            
            contract ICash is ERC20 {
                function depositEther() external payable returns(bool);
                function depositEtherFor(address _to) external payable returns(bool);
                function withdrawEther(uint256 _amount) external returns(bool);
                function withdrawEtherTo(address _to, uint256 _amount) external returns(bool);
                function withdrawEtherToIfPossible(address _to, uint256 _amount) external returns (bool);
            }
            
            contract IOrders {
                function saveOrder(Order.Types _type, IMarket _market, uint256 _fxpAmount, uint256 _price, address _sender, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed, bytes32 _betterOrderId, bytes32 _worseOrderId, bytes32 _tradeGroupId) public returns (bytes32 _orderId);
                function removeOrder(bytes32 _orderId) public returns (bool);
                function getMarket(bytes32 _orderId) public view returns (IMarket);
                function getOrderType(bytes32 _orderId) public view returns (Order.Types);
                function getOutcome(bytes32 _orderId) public view returns (uint256);
                function getAmount(bytes32 _orderId) public view returns (uint256);
                function getPrice(bytes32 _orderId) public view returns (uint256);
                function getOrderCreator(bytes32 _orderId) public view returns (address);
                function getOrderSharesEscrowed(bytes32 _orderId) public view returns (uint256);
                function getOrderMoneyEscrowed(bytes32 _orderId) public view returns (uint256);
                function getBetterOrderId(bytes32 _orderId) public view returns (bytes32);
                function getWorseOrderId(bytes32 _orderId) public view returns (bytes32);
                function getBestOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
                function getWorstOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
                function getLastOutcomePrice(IMarket _market, uint256 _outcome) public view returns (uint256);
                function getOrderId(Order.Types _type, IMarket _market, uint256 _fxpAmount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) public pure returns (bytes32);
                function getTotalEscrowed(IMarket _market) public view returns (uint256);
                function isBetterPrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
                function isWorsePrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
                function assertIsNotBetterPrice(Order.Types _type, uint256 _price, bytes32 _betterOrderId) public view returns (bool);
                function assertIsNotWorsePrice(Order.Types _type, uint256 _price, bytes32 _worseOrderId) public returns (bool);
                function recordFillOrder(bytes32 _orderId, uint256 _sharesFilled, uint256 _tokensFilled) public returns (bool);
                function setPrice(IMarket _market, uint256 _outcome, uint256 _price) external returns (bool);
                function incrementTotalEscrowed(IMarket _market, uint256 _amount) external returns (bool);
                function decrementTotalEscrowed(IMarket _market, uint256 _amount) external returns (bool);
            }
            
            contract IShareToken is ITyped, ERC20 {
                function initialize(IMarket _market, uint256 _outcome) external returns (bool);
                function createShares(address _owner, uint256 _amount) external returns (bool);
                function destroyShares(address, uint256 balance) external returns (bool);
                function getMarket() external view returns (IMarket);
                function getOutcome() external view returns (uint256);
                function trustedOrderTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedFillOrderTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedCancelOrderTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
            }
            
            library Order {
                using SafeMathUint256 for uint256;
            
                enum Types {
                    Bid, Ask
                }
            
                enum TradeDirections {
                    Long, Short
                }
            
                struct Data {
                    // Contracts
                    IOrders orders;
                    IMarket market;
                    IAugur augur;
            
                    // Order
                    bytes32 id;
                    address creator;
                    uint256 outcome;
                    Order.Types orderType;
                    uint256 amount;
                    uint256 price;
                    uint256 sharesEscrowed;
                    uint256 moneyEscrowed;
                    bytes32 betterOrderId;
                    bytes32 worseOrderId;
                }
            
                //
                // Constructor
                //
            
                // No validation is needed here as it is simply a librarty function for organizing data
                function create(IController _controller, address _creator, uint256 _outcome, Order.Types _type, uint256 _attoshares, uint256 _price, IMarket _market, bytes32 _betterOrderId, bytes32 _worseOrderId) internal view returns (Data) {
                    require(_outcome < _market.getNumberOfOutcomes());
                    require(_price < _market.getNumTicks());
            
                    IOrders _orders = IOrders(_controller.lookup("Orders"));
                    IAugur _augur = _controller.getAugur();
            
                    return Data({
                        orders: _orders,
                        market: _market,
                        augur: _augur,
                        id: 0,
                        creator: _creator,
                        outcome: _outcome,
                        orderType: _type,
                        amount: _attoshares,
                        price: _price,
                        sharesEscrowed: 0,
                        moneyEscrowed: 0,
                        betterOrderId: _betterOrderId,
                        worseOrderId: _worseOrderId
                    });
                }
            
                //
                // "public" functions
                //
            
                function getOrderId(Order.Data _orderData) internal view returns (bytes32) {
                    if (_orderData.id == bytes32(0)) {
                        bytes32 _orderId = _orderData.orders.getOrderId(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, block.number, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed);
                        require(_orderData.orders.getAmount(_orderId) == 0);
                        _orderData.id = _orderId;
                    }
                    return _orderData.id;
                }
            
                function getOrderTradingTypeFromMakerDirection(Order.TradeDirections _creatorDirection) internal pure returns (Order.Types) {
                    return (_creatorDirection == Order.TradeDirections.Long) ? Order.Types.Bid : Order.Types.Ask;
                }
            
                function getOrderTradingTypeFromFillerDirection(Order.TradeDirections _fillerDirection) internal pure returns (Order.Types) {
                    return (_fillerDirection == Order.TradeDirections.Long) ? Order.Types.Ask : Order.Types.Bid;
                }
            
                function escrowFunds(Order.Data _orderData) internal returns (bool) {
                    if (_orderData.orderType == Order.Types.Ask) {
                        return escrowFundsForAsk(_orderData);
                    } else if (_orderData.orderType == Order.Types.Bid) {
                        return escrowFundsForBid(_orderData);
                    }
                }
            
                function saveOrder(Order.Data _orderData, bytes32 _tradeGroupId) internal returns (bytes32) {
                    return _orderData.orders.saveOrder(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed, _orderData.betterOrderId, _orderData.worseOrderId, _tradeGroupId);
                }
            
                //
                // Private functions
                //
            
                function escrowFundsForBid(Order.Data _orderData) private returns (bool) {
                    require(_orderData.moneyEscrowed == 0);
                    require(_orderData.sharesEscrowed == 0);
                    uint256 _attosharesToCover = _orderData.amount;
                    uint256 _numberOfOutcomes = _orderData.market.getNumberOfOutcomes();
            
                    // Figure out how many almost-complete-sets (just missing `outcome` share) the creator has
                    uint256 _attosharesHeld = 2**254;
                    for (uint256 _i = 0; _i < _numberOfOutcomes; _i++) {
                        if (_i != _orderData.outcome) {
                            uint256 _creatorShareTokenBalance = _orderData.market.getShareToken(_i).balanceOf(_orderData.creator);
                            _attosharesHeld = SafeMathUint256.min(_creatorShareTokenBalance, _attosharesHeld);
                        }
                    }
            
                    // Take shares into escrow if they have any almost-complete-sets
                    if (_attosharesHeld > 0) {
                        _orderData.sharesEscrowed = SafeMathUint256.min(_attosharesHeld, _attosharesToCover);
                        _attosharesToCover -= _orderData.sharesEscrowed;
                        for (_i = 0; _i < _numberOfOutcomes; _i++) {
                            if (_i != _orderData.outcome) {
                                _orderData.market.getShareToken(_i).trustedOrderTransfer(_orderData.creator, _orderData.market, _orderData.sharesEscrowed);
                            }
                        }
                    }
                    // If not able to cover entire order with shares alone, then cover remaining with tokens
                    if (_attosharesToCover > 0) {
                        _orderData.moneyEscrowed = _attosharesToCover.mul(_orderData.price);
                        require(_orderData.augur.trustedTransfer(_orderData.market.getDenominationToken(), _orderData.creator, _orderData.market, _orderData.moneyEscrowed));
                    }
            
                    return true;
                }
            
                function escrowFundsForAsk(Order.Data _orderData) private returns (bool) {
                    require(_orderData.moneyEscrowed == 0);
                    require(_orderData.sharesEscrowed == 0);
                    IShareToken _shareToken = _orderData.market.getShareToken(_orderData.outcome);
                    uint256 _attosharesToCover = _orderData.amount;
            
                    // Figure out how many shares of the outcome the creator has
                    uint256 _attosharesHeld = _shareToken.balanceOf(_orderData.creator);
            
                    // Take shares in escrow if user has shares
                    if (_attosharesHeld > 0) {
                        _orderData.sharesEscrowed = SafeMathUint256.min(_attosharesHeld, _attosharesToCover);
                        _attosharesToCover -= _orderData.sharesEscrowed;
                        _shareToken.trustedOrderTransfer(_orderData.creator, _orderData.market, _orderData.sharesEscrowed);
                    }
            
                    // If not able to cover entire order with shares alone, then cover remaining with tokens
                    if (_attosharesToCover > 0) {
                        _orderData.moneyEscrowed = _orderData.market.getNumTicks().sub(_orderData.price).mul(_attosharesToCover);
                        require(_orderData.augur.trustedTransfer(_orderData.market.getDenominationToken(), _orderData.creator, _orderData.market, _orderData.moneyEscrowed));
                    }
            
                    return true;
                }
            }

            File 4 of 4: Cash
            pragma solidity 0.4.20;
            
            contract IAugur {
                function createChildUniverse(bytes32 _parentPayoutDistributionHash, uint256[] _parentPayoutNumerators, bool _parentInvalid) public returns (IUniverse);
                function isKnownUniverse(IUniverse _universe) public view returns (bool);
                function trustedTransfer(ERC20 _token, address _from, address _to, uint256 _amount) public returns (bool);
                function logMarketCreated(bytes32 _topic, string _description, string _extraInfo, IUniverse _universe, address _market, address _marketCreator, bytes32[] _outcomes, int256 _minPrice, int256 _maxPrice, IMarket.MarketType _marketType) public returns (bool);
                function logMarketCreated(bytes32 _topic, string _description, string _extraInfo, IUniverse _universe, address _market, address _marketCreator, int256 _minPrice, int256 _maxPrice, IMarket.MarketType _marketType) public returns (bool);
                function logInitialReportSubmitted(IUniverse _universe, address _reporter, address _market, uint256 _amountStaked, bool _isDesignatedReporter, uint256[] _payoutNumerators, bool _invalid) public returns (bool);
                function disputeCrowdsourcerCreated(IUniverse _universe, address _market, address _disputeCrowdsourcer, uint256[] _payoutNumerators, uint256 _size, bool _invalid) public returns (bool);
                function logDisputeCrowdsourcerContribution(IUniverse _universe, address _reporter, address _market, address _disputeCrowdsourcer, uint256 _amountStaked) public returns (bool);
                function logDisputeCrowdsourcerCompleted(IUniverse _universe, address _market, address _disputeCrowdsourcer) public returns (bool);
                function logInitialReporterRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256 _reportingFeesReceived, uint256[] _payoutNumerators) public returns (bool);
                function logDisputeCrowdsourcerRedeemed(IUniverse _universe, address _reporter, address _market, uint256 _amountRedeemed, uint256 _repReceived, uint256 _reportingFeesReceived, uint256[] _payoutNumerators) public returns (bool);
                function logFeeWindowRedeemed(IUniverse _universe, address _reporter, uint256 _amountRedeemed, uint256 _reportingFeesReceived) public returns (bool);
                function logMarketFinalized(IUniverse _universe) public returns (bool);
                function logMarketMigrated(IMarket _market, IUniverse _originalUniverse) public returns (bool);
                function logReportingParticipantDisavowed(IUniverse _universe, IMarket _market) public returns (bool);
                function logMarketParticipantsDisavowed(IUniverse _universe) public returns (bool);
                function logOrderCanceled(IUniverse _universe, address _shareToken, address _sender, bytes32 _orderId, Order.Types _orderType, uint256 _tokenRefund, uint256 _sharesRefund) public returns (bool);
                function logOrderCreated(Order.Types _orderType, uint256 _amount, uint256 _price, address _creator, uint256 _moneyEscrowed, uint256 _sharesEscrowed, bytes32 _tradeGroupId, bytes32 _orderId, IUniverse _universe, address _shareToken) public returns (bool);
                function logOrderFilled(IUniverse _universe, address _shareToken, address _filler, bytes32 _orderId, uint256 _numCreatorShares, uint256 _numCreatorTokens, uint256 _numFillerShares, uint256 _numFillerTokens, uint256 _marketCreatorFees, uint256 _reporterFees, uint256 _amountFilled, bytes32 _tradeGroupId) public returns (bool);
                function logCompleteSetsPurchased(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
                function logCompleteSetsSold(IUniverse _universe, IMarket _market, address _account, uint256 _numCompleteSets) public returns (bool);
                function logTradingProceedsClaimed(IUniverse _universe, address _shareToken, address _sender, address _market, uint256 _numShares, uint256 _numPayoutTokens, uint256 _finalTokenBalance) public returns (bool);
                function logUniverseForked() public returns (bool);
                function logFeeWindowTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logReputationTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logDisputeCrowdsourcerTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logShareTokensTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logReputationTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logReputationTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logShareTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logShareTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeWindowBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeWindowMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logDisputeCrowdsourcerTokensBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logDisputeCrowdsourcerTokensMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeWindowCreated(IFeeWindow _feeWindow, uint256 _id) public returns (bool);
                function logFeeTokenTransferred(IUniverse _universe, address _from, address _to, uint256 _value) public returns (bool);
                function logFeeTokenBurned(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logFeeTokenMinted(IUniverse _universe, address _target, uint256 _amount) public returns (bool);
                function logTimestampSet(uint256 _newTimestamp) public returns (bool);
                function logInitialReporterTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
                function logMarketTransferred(IUniverse _universe, address _from, address _to) public returns (bool);
                function logMarketMailboxTransferred(IUniverse _universe, IMarket _market, address _from, address _to) public returns (bool);
                function logEscapeHatchChanged(bool _isOn) public returns (bool);
            }
            
            contract IControlled {
                function getController() public view returns (IController);
                function setController(IController _controller) public returns(bool);
            }
            
            contract Controlled is IControlled {
                IController internal controller;
            
                modifier onlyWhitelistedCallers {
                    require(controller.assertIsWhitelisted(msg.sender));
                    _;
                }
            
                modifier onlyCaller(bytes32 _key) {
                    require(msg.sender == controller.lookup(_key));
                    _;
                }
            
                modifier onlyControllerCaller {
                    require(IController(msg.sender) == controller);
                    _;
                }
            
                modifier onlyInGoodTimes {
                    require(controller.stopInEmergency());
                    _;
                }
            
                modifier onlyInBadTimes {
                    require(controller.onlyInEmergency());
                    _;
                }
            
                function Controlled() public {
                    controller = IController(msg.sender);
                }
            
                function getController() public view returns(IController) {
                    return controller;
                }
            
                function setController(IController _controller) public onlyControllerCaller returns(bool) {
                    controller = _controller;
                    return true;
                }
            }
            
            contract IController {
                function assertIsWhitelisted(address _target) public view returns(bool);
                function lookup(bytes32 _key) public view returns(address);
                function stopInEmergency() public view returns(bool);
                function onlyInEmergency() public view returns(bool);
                function getAugur() public view returns (IAugur);
                function getTimestamp() public view returns (uint256);
            }
            
            contract DelegationTarget is Controlled {
                bytes32 public controllerLookupName;
            }
            
            contract IOwnable {
                function getOwner() public view returns (address);
                function transferOwnership(address newOwner) public returns (bool);
            }
            
            contract ITyped {
                function getTypeName() public view returns (bytes32);
            }
            
            contract Initializable {
                bool private initialized = false;
            
                modifier afterInitialized {
                    require(initialized);
                    _;
                }
            
                modifier beforeInitialized {
                    require(!initialized);
                    _;
                }
            
                function endInitialization() internal beforeInitialized returns (bool) {
                    initialized = true;
                    return true;
                }
            
                function getInitialized() public view returns (bool) {
                    return initialized;
                }
            }
            
            library SafeMathUint256 {
                function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                    uint256 c = a * b;
                    require(a == 0 || c / a == b);
                    return c;
                }
            
                function div(uint256 a, uint256 b) internal pure returns (uint256) {
                    // assert(b > 0); // Solidity automatically throws when dividing by 0
                    uint256 c = a / b;
                    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
                    return c;
                }
            
                function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                    require(b <= a);
                    return a - b;
                }
            
                function add(uint256 a, uint256 b) internal pure returns (uint256) {
                    uint256 c = a + b;
                    require(c >= a);
                    return c;
                }
            
                function min(uint256 a, uint256 b) internal pure returns (uint256) {
                    if (a <= b) {
                        return a;
                    } else {
                        return b;
                    }
                }
            
                function max(uint256 a, uint256 b) internal pure returns (uint256) {
                    if (a >= b) {
                        return a;
                    } else {
                        return b;
                    }
                }
            
                function getUint256Min() internal pure returns (uint256) {
                    return 0;
                }
            
                function getUint256Max() internal pure returns (uint256) {
                    return 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
                }
            
                function isMultipleOf(uint256 a, uint256 b) internal pure returns (bool) {
                    return a % b == 0;
                }
            
                // Float [fixed point] Operations
                function fxpMul(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
                    return div(mul(a, b), base);
                }
            
                function fxpDiv(uint256 a, uint256 b, uint256 base) internal pure returns (uint256) {
                    return div(mul(a, base), b);
                }
            }
            
            contract ERC20Basic {
                event Transfer(address indexed from, address indexed to, uint256 value);
            
                function balanceOf(address _who) public view returns (uint256);
                function transfer(address _to, uint256 _value) public returns (bool);
                function totalSupply() public view returns (uint256);
            }
            
            contract BasicToken is ERC20Basic {
                using SafeMathUint256 for uint256;
            
                uint256 internal supply;
                mapping(address => uint256) internal balances;
            
                /**
                * @dev transfer token for a specified address
                * @param _to The address to transfer to.
                * @param _value The amount to be transferred.
                */
                function transfer(address _to, uint256 _value) public returns(bool) {
                    return internalTransfer(msg.sender, _to, _value);
                }
            
                /**
                * @dev allows internal token transfers
                * @param _from The source address
                * @param _to The destination address
                */
                function internalTransfer(address _from, address _to, uint256 _value) internal returns (bool) {
                    balances[_from] = balances[_from].sub(_value);
                    balances[_to] = balances[_to].add(_value);
                    Transfer(_from, _to, _value);
                    onTokenTransfer(_from, _to, _value);
                    return true;
                }
            
                /**
                * @dev Gets the balance of the specified address.
                * @param _owner The address to query the the balance of.
                * @return An uint256 representing the amount owned by the passed address.
                */
                function balanceOf(address _owner) public view returns (uint256) {
                    return balances[_owner];
                }
            
                function totalSupply() public view returns (uint256) {
                    return supply;
                }
            
                // Subclasses of this token generally want to send additional logs through the centralized Augur log emitter contract
                function onTokenTransfer(address _from, address _to, uint256 _value) internal returns (bool);
            }
            
            contract ERC20 is ERC20Basic {
                event Approval(address indexed owner, address indexed spender, uint256 value);
            
                function allowance(address _owner, address _spender) public view returns (uint256);
                function transferFrom(address _from, address _to, uint256 _value) public returns (bool);
                function approve(address _spender, uint256 _value) public returns (bool);
            }
            
            contract StandardToken is ERC20, BasicToken {
                using SafeMathUint256 for uint256;
            
                // Approvals of this amount are simply considered an everlasting approval which is not decremented when transfers occur
                uint256 public constant ETERNAL_APPROVAL_VALUE = 2 ** 256 - 1;
            
                mapping (address => mapping (address => uint256)) internal allowed;
            
                /**
                * @dev Transfer tokens from one address to another
                * @param _from address The address which you want to send tokens from
                * @param _to address The address which you want to transfer to
                * @param _value uint256 the amout of tokens to be transfered
                */
                function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
                    uint256 _allowance = allowed[_from][msg.sender];
            
                    if (_allowance != ETERNAL_APPROVAL_VALUE) {
                        allowed[_from][msg.sender] = _allowance.sub(_value);
                    }
                    internalTransfer(_from, _to, _value);
                    return true;
                }
            
                /**
                * @dev Aprove the passed address to spend the specified amount of tokens on behalf of msg.sender.
                * @param _spender The address which will spend the funds.
                * @param _value The amount of tokens to be spent.
                */
                function approve(address _spender, uint256 _value) public returns (bool) {
                    approveInternal(msg.sender, _spender, _value);
                    return true;
                }
            
                /**
                * @dev Function to check the amount of tokens that an owner allowed to a spender.
                * @param _owner address The address which owns the funds.
                * @param _spender address The address which will spend the funds.
                * @return A uint256 specifing the amount of tokens still avaible for the spender.
                */
                function allowance(address _owner, address _spender) public view returns (uint256 remaining) {
                    return allowed[_owner][_spender];
                }
            
               /**
               * @dev Increase the amount of tokens that an owner allowed to a spender.
               *
               * Approve should be called when allowed[_spender] == 0. To increment allowed value is better to use this function to avoid 2 calls (and wait until the first transaction is mined)
               * @param _spender The address which will spend the funds.
               * @param _addedValue The amount of tokens to increase the allowance by.
               */
                function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
                    approveInternal(msg.sender, _spender, allowed[msg.sender][_spender].add(_addedValue));
                    return true;
                }
            
              /**
               * @dev Decrease the amount of tokens that an owner allowed to a spender.
               *
               * approve should be called when allowed[_spender] == 0. To decrement allowed value is better to use this function to avoid 2 calls (and wait until the first transaction is mined)
               * @param _spender The address which will spend the funds.
               * @param _subtractedValue The amount of tokens to decrease the allowance by.
               */
                function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
                    uint oldValue = allowed[msg.sender][_spender];
                    if (_subtractedValue > oldValue) {
                        approveInternal(msg.sender, _spender, 0);
                    } else {
                        approveInternal(msg.sender, _spender, oldValue.sub(_subtractedValue));
                    }
                    return true;
                }
            
                function approveInternal(address _owner, address _spender, uint256 _value) internal returns (bool) {
                    allowed[_owner][_spender] = _value;
                    Approval(_owner, _spender, _value);
                    return true;
                }
            }
            
            contract VariableSupplyToken is StandardToken {
                using SafeMathUint256 for uint256;
            
                event Mint(address indexed target, uint256 value);
                event Burn(address indexed target, uint256 value);
            
                /**
                * @dev mint tokens for a specified address
                * @param _target The address to mint tokens for.
                * @param _amount The amount to be minted.
                */
                function mint(address _target, uint256 _amount) internal returns (bool) {
                    balances[_target] = balances[_target].add(_amount);
                    supply = supply.add(_amount);
                    Mint(_target, _amount);
                    onMint(_target, _amount);
                    return true;
                }
            
                /**
                * @dev burn tokens belonging to a specified address
                * @param _target The address to burn tokens for.
                * @param _amount The amount to be burned.
                */
                function burn(address _target, uint256 _amount) internal returns (bool) {
                    balances[_target] = balances[_target].sub(_amount);
                    supply = supply.sub(_amount);
                    Burn(_target, _amount);
                    onBurn(_target, _amount);
                    return true;
                }
            
                // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract
                function onMint(address, uint256) internal returns (bool);
            
                // Subclasses of this token may want to send additional logs through the centralized Augur log emitter contract
                function onBurn(address, uint256) internal returns (bool);
            }
            
            contract IFeeToken is ERC20, Initializable {
                function initialize(IFeeWindow _feeWindow) public returns (bool);
                function getFeeWindow() public view returns (IFeeWindow);
                function feeWindowBurn(address _target, uint256 _amount) public returns (bool);
                function mintForReportingParticipant(address _target, uint256 _amount) public returns (bool);
            }
            
            contract IFeeWindow is ITyped, ERC20 {
                function initialize(IUniverse _universe, uint256 _feeWindowId) public returns (bool);
                function getUniverse() public view returns (IUniverse);
                function getReputationToken() public view returns (IReputationToken);
                function getStartTime() public view returns (uint256);
                function getEndTime() public view returns (uint256);
                function getNumMarkets() public view returns (uint256);
                function getNumInvalidMarkets() public view returns (uint256);
                function getNumIncorrectDesignatedReportMarkets() public view returns (uint256);
                function getNumDesignatedReportNoShows() public view returns (uint256);
                function getFeeToken() public view returns (IFeeToken);
                function isActive() public view returns (bool);
                function isOver() public view returns (bool);
                function onMarketFinalized() public returns (bool);
                function buy(uint256 _attotokens) public returns (bool);
                function redeem(address _sender) public returns (bool);
                function redeemForReportingParticipant() public returns (bool);
                function mintFeeTokens(uint256 _amount) public returns (bool);
                function trustedUniverseBuy(address _buyer, uint256 _attotokens) public returns (bool);
            }
            
            contract IMailbox {
                function initialize(address _owner, IMarket _market) public returns (bool);
                function depositEther() public payable returns (bool);
            }
            
            contract IMarket is ITyped, IOwnable {
                enum MarketType {
                    YES_NO,
                    CATEGORICAL,
                    SCALAR
                }
            
                function initialize(IUniverse _universe, uint256 _endTime, uint256 _feePerEthInAttoeth, ICash _cash, address _designatedReporterAddress, address _creator, uint256 _numOutcomes, uint256 _numTicks) public payable returns (bool _success);
                function derivePayoutDistributionHash(uint256[] _payoutNumerators, bool _invalid) public view returns (bytes32);
                function getUniverse() public view returns (IUniverse);
                function getFeeWindow() public view returns (IFeeWindow);
                function getNumberOfOutcomes() public view returns (uint256);
                function getNumTicks() public view returns (uint256);
                function getDenominationToken() public view returns (ICash);
                function getShareToken(uint256 _outcome)  public view returns (IShareToken);
                function getMarketCreatorSettlementFeeDivisor() public view returns (uint256);
                function getForkingMarket() public view returns (IMarket _market);
                function getEndTime() public view returns (uint256);
                function getMarketCreatorMailbox() public view returns (IMailbox);
                function getWinningPayoutDistributionHash() public view returns (bytes32);
                function getWinningPayoutNumerator(uint256 _outcome) public view returns (uint256);
                function getReputationToken() public view returns (IReputationToken);
                function getFinalizationTime() public view returns (uint256);
                function getInitialReporterAddress() public view returns (address);
                function deriveMarketCreatorFeeAmount(uint256 _amount) public view returns (uint256);
                function isContainerForShareToken(IShareToken _shadyTarget) public view returns (bool);
                function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
                function isInvalid() public view returns (bool);
                function finalize() public returns (bool);
                function designatedReporterWasCorrect() public view returns (bool);
                function designatedReporterShowed() public view returns (bool);
                function isFinalized() public view returns (bool);
                function finalizeFork() public returns (bool);
                function assertBalances() public view returns (bool);
            }
            
            contract IReportingParticipant {
                function getStake() public view returns (uint256);
                function getPayoutDistributionHash() public view returns (bytes32);
                function liquidateLosing() public returns (bool);
                function redeem(address _redeemer) public returns (bool);
                function isInvalid() public view returns (bool);
                function isDisavowed() public view returns (bool);
                function migrate() public returns (bool);
                function getPayoutNumerator(uint256 _outcome) public view returns (uint256);
                function getMarket() public view returns (IMarket);
                function getSize() public view returns (uint256);
            }
            
            contract IDisputeCrowdsourcer is IReportingParticipant, ERC20 {
                function initialize(IMarket market, uint256 _size, bytes32 _payoutDistributionHash, uint256[] _payoutNumerators, bool _invalid) public returns (bool);
                function contribute(address _participant, uint256 _amount) public returns (uint256);
            }
            
            contract IReputationToken is ITyped, ERC20 {
                function initialize(IUniverse _universe) public returns (bool);
                function migrateOut(IReputationToken _destination, uint256 _attotokens) public returns (bool);
                function migrateIn(address _reporter, uint256 _attotokens) public returns (bool);
                function trustedReportingParticipantTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedMarketTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedFeeWindowTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedUniverseTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function getUniverse() public view returns (IUniverse);
                function getTotalMigrated() public view returns (uint256);
                function getTotalTheoreticalSupply() public view returns (uint256);
                function mintForReportingParticipant(uint256 _amountMigrated) public returns (bool);
            }
            
            contract IUniverse is ITyped {
                function initialize(IUniverse _parentUniverse, bytes32 _parentPayoutDistributionHash) external returns (bool);
                function fork() public returns (bool);
                function getParentUniverse() public view returns (IUniverse);
                function createChildUniverse(uint256[] _parentPayoutNumerators, bool _invalid) public returns (IUniverse);
                function getChildUniverse(bytes32 _parentPayoutDistributionHash) public view returns (IUniverse);
                function getReputationToken() public view returns (IReputationToken);
                function getForkingMarket() public view returns (IMarket);
                function getForkEndTime() public view returns (uint256);
                function getForkReputationGoal() public view returns (uint256);
                function getParentPayoutDistributionHash() public view returns (bytes32);
                function getDisputeRoundDurationInSeconds() public view returns (uint256);
                function getOrCreateFeeWindowByTimestamp(uint256 _timestamp) public returns (IFeeWindow);
                function getOrCreateCurrentFeeWindow() public returns (IFeeWindow);
                function getOrCreateNextFeeWindow() public returns (IFeeWindow);
                function getOpenInterestInAttoEth() public view returns (uint256);
                function getRepMarketCapInAttoeth() public view returns (uint256);
                function getTargetRepMarketCapInAttoeth() public view returns (uint256);
                function getOrCacheValidityBond() public returns (uint256);
                function getOrCacheDesignatedReportStake() public returns (uint256);
                function getOrCacheDesignatedReportNoShowBond() public returns (uint256);
                function getOrCacheReportingFeeDivisor() public returns (uint256);
                function getDisputeThresholdForFork() public view returns (uint256);
                function getInitialReportMinValue() public view returns (uint256);
                function calculateFloatingValue(uint256 _badMarkets, uint256 _totalMarkets, uint256 _targetDivisor, uint256 _previousValue, uint256 _defaultValue, uint256 _floor) public pure returns (uint256 _newValue);
                function getOrCacheMarketCreationCost() public returns (uint256);
                function getCurrentFeeWindow() public view returns (IFeeWindow);
                function getOrCreateFeeWindowBefore(IFeeWindow _feeWindow) public returns (IFeeWindow);
                function isParentOf(IUniverse _shadyChild) public view returns (bool);
                function updateTentativeWinningChildUniverse(bytes32 _parentPayoutDistributionHash) public returns (bool);
                function isContainerForFeeWindow(IFeeWindow _shadyTarget) public view returns (bool);
                function isContainerForMarket(IMarket _shadyTarget) public view returns (bool);
                function isContainerForReportingParticipant(IReportingParticipant _reportingParticipant) public view returns (bool);
                function isContainerForShareToken(IShareToken _shadyTarget) public view returns (bool);
                function isContainerForFeeToken(IFeeToken _shadyTarget) public view returns (bool);
                function addMarketTo() public returns (bool);
                function removeMarketFrom() public returns (bool);
                function decrementOpenInterest(uint256 _amount) public returns (bool);
                function decrementOpenInterestFromMarket(uint256 _amount) public returns (bool);
                function incrementOpenInterest(uint256 _amount) public returns (bool);
                function incrementOpenInterestFromMarket(uint256 _amount) public returns (bool);
                function getWinningChildUniverse() public view returns (IUniverse);
                function isForking() public view returns (bool);
            }
            
            contract ICash is ERC20 {
                function depositEther() external payable returns(bool);
                function depositEtherFor(address _to) external payable returns(bool);
                function withdrawEther(uint256 _amount) external returns(bool);
                function withdrawEtherTo(address _to, uint256 _amount) external returns(bool);
                function withdrawEtherToIfPossible(address _to, uint256 _amount) external returns (bool);
            }
            
            contract Cash is DelegationTarget, ITyped, VariableSupplyToken, ICash {
            
                string constant public name = "Cash";
                string constant public symbol = "CASH";
                uint8 constant public decimals = 18;
            
                function depositEther() external payable onlyInGoodTimes returns(bool) {
                    mint(msg.sender, msg.value);
                    assert(this.balance >= totalSupply());
                    return true;
                }
            
                function depositEtherFor(address _to) external payable onlyInGoodTimes returns(bool) {
                    mint(_to, msg.value);
                    assert(this.balance >= totalSupply());
                    return true;
                }
            
                function withdrawEther(uint256 _amount) external returns(bool) {
                    withdrawEtherInternal(msg.sender, msg.sender, _amount);
                    return true;
                }
            
                function withdrawEtherTo(address _to, uint256 _amount) external returns(bool) {
                    withdrawEtherInternal(msg.sender, _to, _amount);
                    return true;
                }
            
                function withdrawEtherInternal(address _from, address _to, uint256 _amount) private returns(bool) {
                    require(_amount > 0 && _amount <= balances[_from]);
                    burn(_from, _amount);
                    _to.transfer(_amount);
                    assert(this.balance >= totalSupply());
                    return true;
                }
            
                function withdrawEtherToIfPossible(address _to, uint256 _amount) external returns (bool) {
                    require(_amount > 0 && _amount <= balances[msg.sender]);
                    if (_to.send(_amount)) {
                        burn(msg.sender, _amount);
                    } else {
                        internalTransfer(msg.sender, _to, _amount);
                    }
                    assert(this.balance >= totalSupply());
                    return true;
                }
            
                function getTypeName() public view returns (bytes32) {
                    return "Cash";
                }
            
                function onMint(address, uint256) internal returns (bool) {
                    return true;
                }
            
                function onBurn(address, uint256) internal returns (bool) {
                    return true;
                }
            
                function onTokenTransfer(address, address, uint256) internal returns (bool) {
                    return true;
                }
            }
            
            contract IOrders {
                function saveOrder(Order.Types _type, IMarket _market, uint256 _fxpAmount, uint256 _price, address _sender, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed, bytes32 _betterOrderId, bytes32 _worseOrderId, bytes32 _tradeGroupId) public returns (bytes32 _orderId);
                function removeOrder(bytes32 _orderId) public returns (bool);
                function getMarket(bytes32 _orderId) public view returns (IMarket);
                function getOrderType(bytes32 _orderId) public view returns (Order.Types);
                function getOutcome(bytes32 _orderId) public view returns (uint256);
                function getAmount(bytes32 _orderId) public view returns (uint256);
                function getPrice(bytes32 _orderId) public view returns (uint256);
                function getOrderCreator(bytes32 _orderId) public view returns (address);
                function getOrderSharesEscrowed(bytes32 _orderId) public view returns (uint256);
                function getOrderMoneyEscrowed(bytes32 _orderId) public view returns (uint256);
                function getBetterOrderId(bytes32 _orderId) public view returns (bytes32);
                function getWorseOrderId(bytes32 _orderId) public view returns (bytes32);
                function getBestOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
                function getWorstOrderId(Order.Types _type, IMarket _market, uint256 _outcome) public view returns (bytes32);
                function getLastOutcomePrice(IMarket _market, uint256 _outcome) public view returns (uint256);
                function getOrderId(Order.Types _type, IMarket _market, uint256 _fxpAmount, uint256 _price, address _sender, uint256 _blockNumber, uint256 _outcome, uint256 _moneyEscrowed, uint256 _sharesEscrowed) public pure returns (bytes32);
                function getTotalEscrowed(IMarket _market) public view returns (uint256);
                function isBetterPrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
                function isWorsePrice(Order.Types _type, uint256 _price, bytes32 _orderId) public view returns (bool);
                function assertIsNotBetterPrice(Order.Types _type, uint256 _price, bytes32 _betterOrderId) public view returns (bool);
                function assertIsNotWorsePrice(Order.Types _type, uint256 _price, bytes32 _worseOrderId) public returns (bool);
                function recordFillOrder(bytes32 _orderId, uint256 _sharesFilled, uint256 _tokensFilled) public returns (bool);
                function setPrice(IMarket _market, uint256 _outcome, uint256 _price) external returns (bool);
                function incrementTotalEscrowed(IMarket _market, uint256 _amount) external returns (bool);
                function decrementTotalEscrowed(IMarket _market, uint256 _amount) external returns (bool);
            }
            
            contract IShareToken is ITyped, ERC20 {
                function initialize(IMarket _market, uint256 _outcome) external returns (bool);
                function createShares(address _owner, uint256 _amount) external returns (bool);
                function destroyShares(address, uint256 balance) external returns (bool);
                function getMarket() external view returns (IMarket);
                function getOutcome() external view returns (uint256);
                function trustedOrderTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedFillOrderTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
                function trustedCancelOrderTransfer(address _source, address _destination, uint256 _attotokens) public returns (bool);
            }
            
            library Order {
                using SafeMathUint256 for uint256;
            
                enum Types {
                    Bid, Ask
                }
            
                enum TradeDirections {
                    Long, Short
                }
            
                struct Data {
                    // Contracts
                    IOrders orders;
                    IMarket market;
                    IAugur augur;
            
                    // Order
                    bytes32 id;
                    address creator;
                    uint256 outcome;
                    Order.Types orderType;
                    uint256 amount;
                    uint256 price;
                    uint256 sharesEscrowed;
                    uint256 moneyEscrowed;
                    bytes32 betterOrderId;
                    bytes32 worseOrderId;
                }
            
                //
                // Constructor
                //
            
                // No validation is needed here as it is simply a librarty function for organizing data
                function create(IController _controller, address _creator, uint256 _outcome, Order.Types _type, uint256 _attoshares, uint256 _price, IMarket _market, bytes32 _betterOrderId, bytes32 _worseOrderId) internal view returns (Data) {
                    require(_outcome < _market.getNumberOfOutcomes());
                    require(_price < _market.getNumTicks());
            
                    IOrders _orders = IOrders(_controller.lookup("Orders"));
                    IAugur _augur = _controller.getAugur();
            
                    return Data({
                        orders: _orders,
                        market: _market,
                        augur: _augur,
                        id: 0,
                        creator: _creator,
                        outcome: _outcome,
                        orderType: _type,
                        amount: _attoshares,
                        price: _price,
                        sharesEscrowed: 0,
                        moneyEscrowed: 0,
                        betterOrderId: _betterOrderId,
                        worseOrderId: _worseOrderId
                    });
                }
            
                //
                // "public" functions
                //
            
                function getOrderId(Order.Data _orderData) internal view returns (bytes32) {
                    if (_orderData.id == bytes32(0)) {
                        bytes32 _orderId = _orderData.orders.getOrderId(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, block.number, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed);
                        require(_orderData.orders.getAmount(_orderId) == 0);
                        _orderData.id = _orderId;
                    }
                    return _orderData.id;
                }
            
                function getOrderTradingTypeFromMakerDirection(Order.TradeDirections _creatorDirection) internal pure returns (Order.Types) {
                    return (_creatorDirection == Order.TradeDirections.Long) ? Order.Types.Bid : Order.Types.Ask;
                }
            
                function getOrderTradingTypeFromFillerDirection(Order.TradeDirections _fillerDirection) internal pure returns (Order.Types) {
                    return (_fillerDirection == Order.TradeDirections.Long) ? Order.Types.Ask : Order.Types.Bid;
                }
            
                function escrowFunds(Order.Data _orderData) internal returns (bool) {
                    if (_orderData.orderType == Order.Types.Ask) {
                        return escrowFundsForAsk(_orderData);
                    } else if (_orderData.orderType == Order.Types.Bid) {
                        return escrowFundsForBid(_orderData);
                    }
                }
            
                function saveOrder(Order.Data _orderData, bytes32 _tradeGroupId) internal returns (bytes32) {
                    return _orderData.orders.saveOrder(_orderData.orderType, _orderData.market, _orderData.amount, _orderData.price, _orderData.creator, _orderData.outcome, _orderData.moneyEscrowed, _orderData.sharesEscrowed, _orderData.betterOrderId, _orderData.worseOrderId, _tradeGroupId);
                }
            
                //
                // Private functions
                //
            
                function escrowFundsForBid(Order.Data _orderData) private returns (bool) {
                    require(_orderData.moneyEscrowed == 0);
                    require(_orderData.sharesEscrowed == 0);
                    uint256 _attosharesToCover = _orderData.amount;
                    uint256 _numberOfOutcomes = _orderData.market.getNumberOfOutcomes();
            
                    // Figure out how many almost-complete-sets (just missing `outcome` share) the creator has
                    uint256 _attosharesHeld = 2**254;
                    for (uint256 _i = 0; _i < _numberOfOutcomes; _i++) {
                        if (_i != _orderData.outcome) {
                            uint256 _creatorShareTokenBalance = _orderData.market.getShareToken(_i).balanceOf(_orderData.creator);
                            _attosharesHeld = SafeMathUint256.min(_creatorShareTokenBalance, _attosharesHeld);
                        }
                    }
            
                    // Take shares into escrow if they have any almost-complete-sets
                    if (_attosharesHeld > 0) {
                        _orderData.sharesEscrowed = SafeMathUint256.min(_attosharesHeld, _attosharesToCover);
                        _attosharesToCover -= _orderData.sharesEscrowed;
                        for (_i = 0; _i < _numberOfOutcomes; _i++) {
                            if (_i != _orderData.outcome) {
                                _orderData.market.getShareToken(_i).trustedOrderTransfer(_orderData.creator, _orderData.market, _orderData.sharesEscrowed);
                            }
                        }
                    }
                    // If not able to cover entire order with shares alone, then cover remaining with tokens
                    if (_attosharesToCover > 0) {
                        _orderData.moneyEscrowed = _attosharesToCover.mul(_orderData.price);
                        require(_orderData.augur.trustedTransfer(_orderData.market.getDenominationToken(), _orderData.creator, _orderData.market, _orderData.moneyEscrowed));
                    }
            
                    return true;
                }
            
                function escrowFundsForAsk(Order.Data _orderData) private returns (bool) {
                    require(_orderData.moneyEscrowed == 0);
                    require(_orderData.sharesEscrowed == 0);
                    IShareToken _shareToken = _orderData.market.getShareToken(_orderData.outcome);
                    uint256 _attosharesToCover = _orderData.amount;
            
                    // Figure out how many shares of the outcome the creator has
                    uint256 _attosharesHeld = _shareToken.balanceOf(_orderData.creator);
            
                    // Take shares in escrow if user has shares
                    if (_attosharesHeld > 0) {
                        _orderData.sharesEscrowed = SafeMathUint256.min(_attosharesHeld, _attosharesToCover);
                        _attosharesToCover -= _orderData.sharesEscrowed;
                        _shareToken.trustedOrderTransfer(_orderData.creator, _orderData.market, _orderData.sharesEscrowed);
                    }
            
                    // If not able to cover entire order with shares alone, then cover remaining with tokens
                    if (_attosharesToCover > 0) {
                        _orderData.moneyEscrowed = _orderData.market.getNumTicks().sub(_orderData.price).mul(_attosharesToCover);
                        require(_orderData.augur.trustedTransfer(_orderData.market.getDenominationToken(), _orderData.creator, _orderData.market, _orderData.moneyEscrowed));
                    }
            
                    return true;
                }
            }