{
    "schemaVersion": "2.0.0",
    "contractName": "IExchange",
    "compilerOutput": {
        "abi": [
            {
                "anonymous": false,
                "inputs": [
                    {
                        "indexed": false,
                        "internalType": "bytes4",
                        "name": "id",
                        "type": "bytes4"
                    },
                    {
                        "indexed": false,
                        "internalType": "address",
                        "name": "assetProxy",
                        "type": "address"
                    }
                ],
                "name": "AssetProxyRegistered",
                "type": "event"
            },
            {
                "anonymous": false,
                "inputs": [
                    {
                        "indexed": true,
                        "internalType": "address",
                        "name": "makerAddress",
                        "type": "address"
                    },
                    {
                        "indexed": true,
                        "internalType": "address",
                        "name": "feeRecipientAddress",
                        "type": "address"
                    },
                    {
                        "indexed": false,
                        "internalType": "bytes",
                        "name": "makerAssetData",
                        "type": "bytes"
                    },
                    {
                        "indexed": false,
                        "internalType": "bytes",
                        "name": "takerAssetData",
                        "type": "bytes"
                    },
                    {
                        "indexed": false,
                        "internalType": "address",
                        "name": "senderAddress",
                        "type": "address"
                    },
                    {
                        "indexed": true,
                        "internalType": "bytes32",
                        "name": "orderHash",
                        "type": "bytes32"
                    }
                ],
                "name": "Cancel",
                "type": "event"
            },
            {
                "anonymous": false,
                "inputs": [
                    {
                        "indexed": true,
                        "internalType": "address",
                        "name": "makerAddress",
                        "type": "address"
                    },
                    {
                        "indexed": true,
                        "internalType": "address",
                        "name": "orderSenderAddress",
                        "type": "address"
                    },
                    {
                        "indexed": false,
                        "internalType": "uint256",
                        "name": "orderEpoch",
                        "type": "uint256"
                    }
                ],
                "name": "CancelUpTo",
                "type": "event"
            },
            {
                "anonymous": false,
                "inputs": [
                    {
                        "indexed": true,
                        "internalType": "address",
                        "name": "makerAddress",
                        "type": "address"
                    },
                    {
                        "indexed": true,
                        "internalType": "address",
                        "name": "feeRecipientAddress",
                        "type": "address"
                    },
                    {
                        "indexed": false,
                        "internalType": "bytes",
                        "name": "makerAssetData",
                        "type": "bytes"
                    },
                    {
                        "indexed": false,
                        "internalType": "bytes",
                        "name": "takerAssetData",
                        "type": "bytes"
                    },
                    {
                        "indexed": false,
                        "internalType": "bytes",
                        "name": "makerFeeAssetData",
                        "type": "bytes"
                    },
                    {
                        "indexed": false,
                        "internalType": "bytes",
                        "name": "takerFeeAssetData",
                        "type": "bytes"
                    },
                    {
                        "indexed": true,
                        "internalType": "bytes32",
                        "name": "orderHash",
                        "type": "bytes32"
                    },
                    {
                        "indexed": false,
                        "internalType": "address",
                        "name": "takerAddress",
                        "type": "address"
                    },
                    {
                        "indexed": false,
                        "internalType": "address",
                        "name": "senderAddress",
                        "type": "address"
                    },
                    {
                        "indexed": false,
                        "internalType": "uint256",
                        "name": "makerAssetFilledAmount",
                        "type": "uint256"
                    },
                    {
                        "indexed": false,
                        "internalType": "uint256",
                        "name": "takerAssetFilledAmount",
                        "type": "uint256"
                    },
                    {
                        "indexed": false,
                        "internalType": "uint256",
                        "name": "makerFeePaid",
                        "type": "uint256"
                    },
                    {
                        "indexed": false,
                        "internalType": "uint256",
                        "name": "takerFeePaid",
                        "type": "uint256"
                    },
                    {
                        "indexed": false,
                        "internalType": "uint256",
                        "name": "protocolFeePaid",
                        "type": "uint256"
                    }
                ],
                "name": "Fill",
                "type": "event"
            },
            {
                "anonymous": false,
                "inputs": [
                    {
                        "indexed": false,
                        "internalType": "address",
                        "name": "oldProtocolFeeCollector",
                        "type": "address"
                    },
                    {
                        "indexed": false,
                        "internalType": "address",
                        "name": "updatedProtocolFeeCollector",
                        "type": "address"
                    }
                ],
                "name": "ProtocolFeeCollectorAddress",
                "type": "event"
            },
            {
                "anonymous": false,
                "inputs": [
                    {
                        "indexed": false,
                        "internalType": "uint256",
                        "name": "oldProtocolFeeMultiplier",
                        "type": "uint256"
                    },
                    {
                        "indexed": false,
                        "internalType": "uint256",
                        "name": "updatedProtocolFeeMultiplier",
                        "type": "uint256"
                    }
                ],
                "name": "ProtocolFeeMultiplier",
                "type": "event"
            },
            {
                "anonymous": false,
                "inputs": [
                    {
                        "indexed": true,
                        "internalType": "address",
                        "name": "signerAddress",
                        "type": "address"
                    },
                    {
                        "indexed": true,
                        "internalType": "address",
                        "name": "validatorAddress",
                        "type": "address"
                    },
                    {
                        "indexed": false,
                        "internalType": "bool",
                        "name": "isApproved",
                        "type": "bool"
                    }
                ],
                "name": "SignatureValidatorApproval",
                "type": "event"
            },
            {
                "anonymous": false,
                "inputs": [
                    {
                        "indexed": true,
                        "internalType": "bytes32",
                        "name": "transactionHash",
                        "type": "bytes32"
                    }
                ],
                "name": "TransactionExecution",
                "type": "event"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order[]",
                        "name": "orders",
                        "type": "tuple[]"
                    }
                ],
                "name": "batchCancelOrders",
                "outputs": [],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "gasPrice",
                                "type": "uint256"
                            },
                            {
                                "internalType": "address",
                                "name": "signerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "bytes",
                                "name": "data",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibZeroExTransaction.ZeroExTransaction[]",
                        "name": "transactions",
                        "type": "tuple[]"
                    },
                    {
                        "internalType": "bytes[]",
                        "name": "signatures",
                        "type": "bytes[]"
                    }
                ],
                "name": "batchExecuteTransactions",
                "outputs": [
                    {
                        "internalType": "bytes[]",
                        "name": "",
                        "type": "bytes[]"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order[]",
                        "name": "orders",
                        "type": "tuple[]"
                    },
                    {
                        "internalType": "uint256[]",
                        "name": "takerAssetFillAmounts",
                        "type": "uint256[]"
                    },
                    {
                        "internalType": "bytes[]",
                        "name": "signatures",
                        "type": "bytes[]"
                    }
                ],
                "name": "batchFillOrKillOrders",
                "outputs": [
                    {
                        "components": [
                            {
                                "internalType": "uint256",
                                "name": "makerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "protocolFeePaid",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.FillResults[]",
                        "name": "fillResults",
                        "type": "tuple[]"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order[]",
                        "name": "orders",
                        "type": "tuple[]"
                    },
                    {
                        "internalType": "uint256[]",
                        "name": "takerAssetFillAmounts",
                        "type": "uint256[]"
                    },
                    {
                        "internalType": "bytes[]",
                        "name": "signatures",
                        "type": "bytes[]"
                    }
                ],
                "name": "batchFillOrders",
                "outputs": [
                    {
                        "components": [
                            {
                                "internalType": "uint256",
                                "name": "makerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "protocolFeePaid",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.FillResults[]",
                        "name": "fillResults",
                        "type": "tuple[]"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order[]",
                        "name": "orders",
                        "type": "tuple[]"
                    },
                    {
                        "internalType": "uint256[]",
                        "name": "takerAssetFillAmounts",
                        "type": "uint256[]"
                    },
                    {
                        "internalType": "bytes[]",
                        "name": "signatures",
                        "type": "bytes[]"
                    }
                ],
                "name": "batchFillOrdersNoThrow",
                "outputs": [
                    {
                        "components": [
                            {
                                "internalType": "uint256",
                                "name": "makerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "protocolFeePaid",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.FillResults[]",
                        "name": "fillResults",
                        "type": "tuple[]"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order[]",
                        "name": "leftOrders",
                        "type": "tuple[]"
                    },
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order[]",
                        "name": "rightOrders",
                        "type": "tuple[]"
                    },
                    {
                        "internalType": "bytes[]",
                        "name": "leftSignatures",
                        "type": "bytes[]"
                    },
                    {
                        "internalType": "bytes[]",
                        "name": "rightSignatures",
                        "type": "bytes[]"
                    }
                ],
                "name": "batchMatchOrders",
                "outputs": [
                    {
                        "components": [
                            {
                                "components": [
                                    {
                                        "internalType": "uint256",
                                        "name": "makerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "makerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "protocolFeePaid",
                                        "type": "uint256"
                                    }
                                ],
                                "internalType": "struct LibFillResults.FillResults[]",
                                "name": "left",
                                "type": "tuple[]"
                            },
                            {
                                "components": [
                                    {
                                        "internalType": "uint256",
                                        "name": "makerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "makerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "protocolFeePaid",
                                        "type": "uint256"
                                    }
                                ],
                                "internalType": "struct LibFillResults.FillResults[]",
                                "name": "right",
                                "type": "tuple[]"
                            },
                            {
                                "internalType": "uint256",
                                "name": "profitInLeftMakerAsset",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "profitInRightMakerAsset",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.BatchMatchedFillResults",
                        "name": "batchMatchedFillResults",
                        "type": "tuple"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order[]",
                        "name": "leftOrders",
                        "type": "tuple[]"
                    },
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order[]",
                        "name": "rightOrders",
                        "type": "tuple[]"
                    },
                    {
                        "internalType": "bytes[]",
                        "name": "leftSignatures",
                        "type": "bytes[]"
                    },
                    {
                        "internalType": "bytes[]",
                        "name": "rightSignatures",
                        "type": "bytes[]"
                    }
                ],
                "name": "batchMatchOrdersWithMaximalFill",
                "outputs": [
                    {
                        "components": [
                            {
                                "components": [
                                    {
                                        "internalType": "uint256",
                                        "name": "makerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "makerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "protocolFeePaid",
                                        "type": "uint256"
                                    }
                                ],
                                "internalType": "struct LibFillResults.FillResults[]",
                                "name": "left",
                                "type": "tuple[]"
                            },
                            {
                                "components": [
                                    {
                                        "internalType": "uint256",
                                        "name": "makerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "makerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "protocolFeePaid",
                                        "type": "uint256"
                                    }
                                ],
                                "internalType": "struct LibFillResults.FillResults[]",
                                "name": "right",
                                "type": "tuple[]"
                            },
                            {
                                "internalType": "uint256",
                                "name": "profitInLeftMakerAsset",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "profitInRightMakerAsset",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.BatchMatchedFillResults",
                        "name": "batchMatchedFillResults",
                        "type": "tuple"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order",
                        "name": "order",
                        "type": "tuple"
                    }
                ],
                "name": "cancelOrder",
                "outputs": [],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "internalType": "uint256",
                        "name": "targetOrderEpoch",
                        "type": "uint256"
                    }
                ],
                "name": "cancelOrdersUpTo",
                "outputs": [],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "gasPrice",
                                "type": "uint256"
                            },
                            {
                                "internalType": "address",
                                "name": "signerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "bytes",
                                "name": "data",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibZeroExTransaction.ZeroExTransaction",
                        "name": "transaction",
                        "type": "tuple"
                    },
                    {
                        "internalType": "bytes",
                        "name": "signature",
                        "type": "bytes"
                    }
                ],
                "name": "executeTransaction",
                "outputs": [
                    {
                        "internalType": "bytes",
                        "name": "",
                        "type": "bytes"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order",
                        "name": "order",
                        "type": "tuple"
                    },
                    {
                        "internalType": "uint256",
                        "name": "takerAssetFillAmount",
                        "type": "uint256"
                    },
                    {
                        "internalType": "bytes",
                        "name": "signature",
                        "type": "bytes"
                    }
                ],
                "name": "fillOrKillOrder",
                "outputs": [
                    {
                        "components": [
                            {
                                "internalType": "uint256",
                                "name": "makerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "protocolFeePaid",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.FillResults",
                        "name": "fillResults",
                        "type": "tuple"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order",
                        "name": "order",
                        "type": "tuple"
                    },
                    {
                        "internalType": "uint256",
                        "name": "takerAssetFillAmount",
                        "type": "uint256"
                    },
                    {
                        "internalType": "bytes",
                        "name": "signature",
                        "type": "bytes"
                    }
                ],
                "name": "fillOrder",
                "outputs": [
                    {
                        "components": [
                            {
                                "internalType": "uint256",
                                "name": "makerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "protocolFeePaid",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.FillResults",
                        "name": "fillResults",
                        "type": "tuple"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": true,
                "inputs": [
                    {
                        "internalType": "bytes4",
                        "name": "assetProxyId",
                        "type": "bytes4"
                    }
                ],
                "name": "getAssetProxy",
                "outputs": [
                    {
                        "internalType": "address",
                        "name": "",
                        "type": "address"
                    }
                ],
                "payable": false,
                "stateMutability": "view",
                "type": "function"
            },
            {
                "constant": true,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order",
                        "name": "order",
                        "type": "tuple"
                    }
                ],
                "name": "getOrderInfo",
                "outputs": [
                    {
                        "components": [
                            {
                                "internalType": "enum LibOrder.OrderStatus",
                                "name": "orderStatus",
                                "type": "uint8"
                            },
                            {
                                "internalType": "bytes32",
                                "name": "orderHash",
                                "type": "bytes32"
                            },
                            {
                                "internalType": "uint256",
                                "name": "orderTakerAssetFilledAmount",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibOrder.OrderInfo",
                        "name": "orderInfo",
                        "type": "tuple"
                    }
                ],
                "payable": false,
                "stateMutability": "view",
                "type": "function"
            },
            {
                "constant": true,
                "inputs": [
                    {
                        "internalType": "bytes32",
                        "name": "hash",
                        "type": "bytes32"
                    },
                    {
                        "internalType": "address",
                        "name": "signerAddress",
                        "type": "address"
                    },
                    {
                        "internalType": "bytes",
                        "name": "signature",
                        "type": "bytes"
                    }
                ],
                "name": "isValidHashSignature",
                "outputs": [
                    {
                        "internalType": "bool",
                        "name": "isValid",
                        "type": "bool"
                    }
                ],
                "payable": false,
                "stateMutability": "view",
                "type": "function"
            },
            {
                "constant": true,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order",
                        "name": "order",
                        "type": "tuple"
                    },
                    {
                        "internalType": "bytes",
                        "name": "signature",
                        "type": "bytes"
                    }
                ],
                "name": "isValidOrderSignature",
                "outputs": [
                    {
                        "internalType": "bool",
                        "name": "isValid",
                        "type": "bool"
                    }
                ],
                "payable": false,
                "stateMutability": "view",
                "type": "function"
            },
            {
                "constant": true,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "gasPrice",
                                "type": "uint256"
                            },
                            {
                                "internalType": "address",
                                "name": "signerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "bytes",
                                "name": "data",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibZeroExTransaction.ZeroExTransaction",
                        "name": "transaction",
                        "type": "tuple"
                    },
                    {
                        "internalType": "bytes",
                        "name": "signature",
                        "type": "bytes"
                    }
                ],
                "name": "isValidTransactionSignature",
                "outputs": [
                    {
                        "internalType": "bool",
                        "name": "isValid",
                        "type": "bool"
                    }
                ],
                "payable": false,
                "stateMutability": "view",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order[]",
                        "name": "orders",
                        "type": "tuple[]"
                    },
                    {
                        "internalType": "uint256",
                        "name": "makerAssetFillAmount",
                        "type": "uint256"
                    },
                    {
                        "internalType": "bytes[]",
                        "name": "signatures",
                        "type": "bytes[]"
                    }
                ],
                "name": "marketBuyOrdersFillOrKill",
                "outputs": [
                    {
                        "components": [
                            {
                                "internalType": "uint256",
                                "name": "makerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "protocolFeePaid",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.FillResults",
                        "name": "fillResults",
                        "type": "tuple"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order[]",
                        "name": "orders",
                        "type": "tuple[]"
                    },
                    {
                        "internalType": "uint256",
                        "name": "makerAssetFillAmount",
                        "type": "uint256"
                    },
                    {
                        "internalType": "bytes[]",
                        "name": "signatures",
                        "type": "bytes[]"
                    }
                ],
                "name": "marketBuyOrdersNoThrow",
                "outputs": [
                    {
                        "components": [
                            {
                                "internalType": "uint256",
                                "name": "makerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "protocolFeePaid",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.FillResults",
                        "name": "fillResults",
                        "type": "tuple"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order[]",
                        "name": "orders",
                        "type": "tuple[]"
                    },
                    {
                        "internalType": "uint256",
                        "name": "takerAssetFillAmount",
                        "type": "uint256"
                    },
                    {
                        "internalType": "bytes[]",
                        "name": "signatures",
                        "type": "bytes[]"
                    }
                ],
                "name": "marketSellOrdersFillOrKill",
                "outputs": [
                    {
                        "components": [
                            {
                                "internalType": "uint256",
                                "name": "makerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "protocolFeePaid",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.FillResults",
                        "name": "fillResults",
                        "type": "tuple"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order[]",
                        "name": "orders",
                        "type": "tuple[]"
                    },
                    {
                        "internalType": "uint256",
                        "name": "takerAssetFillAmount",
                        "type": "uint256"
                    },
                    {
                        "internalType": "bytes[]",
                        "name": "signatures",
                        "type": "bytes[]"
                    }
                ],
                "name": "marketSellOrdersNoThrow",
                "outputs": [
                    {
                        "components": [
                            {
                                "internalType": "uint256",
                                "name": "makerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetFilledAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFeePaid",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "protocolFeePaid",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.FillResults",
                        "name": "fillResults",
                        "type": "tuple"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order",
                        "name": "leftOrder",
                        "type": "tuple"
                    },
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order",
                        "name": "rightOrder",
                        "type": "tuple"
                    },
                    {
                        "internalType": "bytes",
                        "name": "leftSignature",
                        "type": "bytes"
                    },
                    {
                        "internalType": "bytes",
                        "name": "rightSignature",
                        "type": "bytes"
                    }
                ],
                "name": "matchOrders",
                "outputs": [
                    {
                        "components": [
                            {
                                "components": [
                                    {
                                        "internalType": "uint256",
                                        "name": "makerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "makerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "protocolFeePaid",
                                        "type": "uint256"
                                    }
                                ],
                                "internalType": "struct LibFillResults.FillResults",
                                "name": "left",
                                "type": "tuple"
                            },
                            {
                                "components": [
                                    {
                                        "internalType": "uint256",
                                        "name": "makerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "makerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "protocolFeePaid",
                                        "type": "uint256"
                                    }
                                ],
                                "internalType": "struct LibFillResults.FillResults",
                                "name": "right",
                                "type": "tuple"
                            },
                            {
                                "internalType": "uint256",
                                "name": "profitInLeftMakerAsset",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "profitInRightMakerAsset",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.MatchedFillResults",
                        "name": "matchedFillResults",
                        "type": "tuple"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order",
                        "name": "leftOrder",
                        "type": "tuple"
                    },
                    {
                        "components": [
                            {
                                "internalType": "address",
                                "name": "makerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "takerAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "feeRecipientAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "address",
                                "name": "senderAddress",
                                "type": "address"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerAssetAmount",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "makerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "takerFee",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "expirationTimeSeconds",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "salt",
                                "type": "uint256"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "makerFeeAssetData",
                                "type": "bytes"
                            },
                            {
                                "internalType": "bytes",
                                "name": "takerFeeAssetData",
                                "type": "bytes"
                            }
                        ],
                        "internalType": "struct LibOrder.Order",
                        "name": "rightOrder",
                        "type": "tuple"
                    },
                    {
                        "internalType": "bytes",
                        "name": "leftSignature",
                        "type": "bytes"
                    },
                    {
                        "internalType": "bytes",
                        "name": "rightSignature",
                        "type": "bytes"
                    }
                ],
                "name": "matchOrdersWithMaximalFill",
                "outputs": [
                    {
                        "components": [
                            {
                                "components": [
                                    {
                                        "internalType": "uint256",
                                        "name": "makerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "makerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "protocolFeePaid",
                                        "type": "uint256"
                                    }
                                ],
                                "internalType": "struct LibFillResults.FillResults",
                                "name": "left",
                                "type": "tuple"
                            },
                            {
                                "components": [
                                    {
                                        "internalType": "uint256",
                                        "name": "makerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerAssetFilledAmount",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "makerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "takerFeePaid",
                                        "type": "uint256"
                                    },
                                    {
                                        "internalType": "uint256",
                                        "name": "protocolFeePaid",
                                        "type": "uint256"
                                    }
                                ],
                                "internalType": "struct LibFillResults.FillResults",
                                "name": "right",
                                "type": "tuple"
                            },
                            {
                                "internalType": "uint256",
                                "name": "profitInLeftMakerAsset",
                                "type": "uint256"
                            },
                            {
                                "internalType": "uint256",
                                "name": "profitInRightMakerAsset",
                                "type": "uint256"
                            }
                        ],
                        "internalType": "struct LibFillResults.MatchedFillResults",
                        "name": "matchedFillResults",
                        "type": "tuple"
                    }
                ],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "internalType": "bytes32",
                        "name": "hash",
                        "type": "bytes32"
                    }
                ],
                "name": "preSign",
                "outputs": [],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": true,
                "inputs": [],
                "name": "protocolFeeCollector",
                "outputs": [
                    {
                        "internalType": "address",
                        "name": "",
                        "type": "address"
                    }
                ],
                "payable": false,
                "stateMutability": "view",
                "type": "function"
            },
            {
                "constant": true,
                "inputs": [],
                "name": "protocolFeeMultiplier",
                "outputs": [
                    {
                        "internalType": "uint256",
                        "name": "",
                        "type": "uint256"
                    }
                ],
                "payable": false,
                "stateMutability": "view",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "internalType": "address",
                        "name": "assetProxy",
                        "type": "address"
                    }
                ],
                "name": "registerAssetProxy",
                "outputs": [],
                "payable": false,
                "stateMutability": "nonpayable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "internalType": "address",
                        "name": "updatedProtocolFeeCollector",
                        "type": "address"
                    }
                ],
                "name": "setProtocolFeeCollectorAddress",
                "outputs": [],
                "payable": false,
                "stateMutability": "nonpayable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "internalType": "uint256",
                        "name": "updatedProtocolFeeMultiplier",
                        "type": "uint256"
                    }
                ],
                "name": "setProtocolFeeMultiplier",
                "outputs": [],
                "payable": false,
                "stateMutability": "nonpayable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "internalType": "address",
                        "name": "validatorAddress",
                        "type": "address"
                    },
                    {
                        "internalType": "bool",
                        "name": "approval",
                        "type": "bool"
                    }
                ],
                "name": "setSignatureValidatorApproval",
                "outputs": [],
                "payable": true,
                "stateMutability": "payable",
                "type": "function"
            },
            {
                "constant": false,
                "inputs": [
                    {
                        "internalType": "bytes[]",
                        "name": "assetData",
                        "type": "bytes[]"
                    },
                    {
                        "internalType": "address[]",
                        "name": "fromAddresses",
                        "type": "address[]"
                    },
                    {
                        "internalType": "address[]",
                        "name": "toAddresses",
                        "type": "address[]"
                    },
                    {
                        "internalType": "uint256[]",
                        "name": "amounts",
                        "type": "uint256[]"
                    }
                ],
                "name": "simulateDispatchTransferFromCalls",
                "outputs": [],
                "payable": false,
                "stateMutability": "nonpayable",
                "type": "function"
            }
        ],
        "devdoc": {
            "methods": {
                "batchCancelOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[])": {
                    "details": "Executes multiple calls of cancelOrder.",
                    "params": {
                        "orders": "Array of order specifications."
                    }
                },
                "batchExecuteTransactions((uint256,uint256,uint256,address,bytes)[],bytes[])": {
                    "details": "Executes a batch of Exchange method calls in the context of signer(s).",
                    "params": {
                        "signatures": "Array of proofs that transactions have been signed by signer(s).",
                        "transactions": "Array of 0x transactions containing salt, signerAddress, and data."
                    },
                    "return": "Array containing ABI encoded return data for each of the underlying Exchange function calls."
                },
                "batchFillOrKillOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256[],bytes[])": {
                    "details": "Executes multiple calls of fillOrKillOrder.",
                    "params": {
                        "orders": "Array of order specifications.",
                        "signatures": "Proofs that orders have been created by makers.",
                        "takerAssetFillAmounts": "Array of desired amounts of takerAsset to sell in orders."
                    },
                    "return": "Array of amounts filled and fees paid by makers and taker."
                },
                "batchFillOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256[],bytes[])": {
                    "details": "Executes multiple calls of fillOrder.",
                    "params": {
                        "orders": "Array of order specifications.",
                        "signatures": "Proofs that orders have been created by makers.",
                        "takerAssetFillAmounts": "Array of desired amounts of takerAsset to sell in orders."
                    },
                    "return": "Array of amounts filled and fees paid by makers and taker."
                },
                "batchFillOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256[],bytes[])": {
                    "details": "Executes multiple calls of fillOrder. If any fill reverts, the error is caught and ignored.",
                    "params": {
                        "orders": "Array of order specifications.",
                        "signatures": "Proofs that orders have been created by makers.",
                        "takerAssetFillAmounts": "Array of desired amounts of takerAsset to sell in orders."
                    },
                    "return": "Array of amounts filled and fees paid by makers and taker."
                },
                "batchMatchOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],bytes[],bytes[])": {
                    "details": "Match complementary orders that have a profitable spread.      Each order is filled at their respective price point, and      the matcher receives a profit denominated in the left maker asset.",
                    "params": {
                        "leftOrders": "Set of orders with the same maker / taker asset.",
                        "leftSignatures": "Proof that left orders were created by the left makers.",
                        "rightOrders": "Set of orders to match against `leftOrders`",
                        "rightSignatures": "Proof that right orders were created by the right makers."
                    },
                    "return": "batchMatchedFillResults Amounts filled and profit generated."
                },
                "batchMatchOrdersWithMaximalFill((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],bytes[],bytes[])": {
                    "details": "Match complementary orders that have a profitable spread.      Each order is maximally filled at their respective price point, and      the matcher receives a profit denominated in either the left maker asset,      right maker asset, or a combination of both.",
                    "params": {
                        "leftOrders": "Set of orders with the same maker / taker asset.",
                        "leftSignatures": "Proof that left orders were created by the left makers.",
                        "rightOrders": "Set of orders to match against `leftOrders`",
                        "rightSignatures": "Proof that right orders were created by the right makers."
                    },
                    "return": "batchMatchedFillResults Amounts filled and profit generated."
                },
                "cancelOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes))": {
                    "details": "After calling, the order can not be filled anymore.",
                    "params": {
                        "order": "Order struct containing order specifications."
                    }
                },
                "cancelOrdersUpTo(uint256)": {
                    "details": "Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch      and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress).",
                    "params": {
                        "targetOrderEpoch": "Orders created with a salt less or equal to this value will be cancelled."
                    }
                },
                "executeTransaction((uint256,uint256,uint256,address,bytes),bytes)": {
                    "details": "Executes an Exchange method call in the context of signer.",
                    "params": {
                        "signature": "Proof that transaction has been signed by signer.",
                        "transaction": "0x transaction containing salt, signerAddress, and data."
                    },
                    "return": "ABI encoded return data of the underlying Exchange function call."
                },
                "fillOrKillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),uint256,bytes)": {
                    "details": "Fills the input order. Reverts if exact takerAssetFillAmount not filled.",
                    "params": {
                        "order": "Order struct containing order specifications.",
                        "signature": "Proof that order has been created by maker.",
                        "takerAssetFillAmount": "Desired amount of takerAsset to sell."
                    }
                },
                "fillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),uint256,bytes)": {
                    "details": "Fills the input order.",
                    "params": {
                        "order": "Order struct containing order specifications.",
                        "signature": "Proof that order has been created by maker.",
                        "takerAssetFillAmount": "Desired amount of takerAsset to sell."
                    },
                    "return": "Amounts filled and fees paid by maker and taker."
                },
                "getAssetProxy(bytes4)": {
                    "details": "Gets an asset proxy.",
                    "params": {
                        "assetProxyId": "Id of the asset proxy."
                    },
                    "return": "The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered."
                },
                "getOrderInfo((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes))": {
                    "details": "Gets information about an order: status, hash, and amount filled.",
                    "params": {
                        "order": "Order to gather information on."
                    },
                    "return": "OrderInfo Information about the order and its state.                   See LibOrder.OrderInfo for a complete description."
                },
                "isValidHashSignature(bytes32,address,bytes)": {
                    "details": "Verifies that a hash has been signed by the given signer.",
                    "params": {
                        "hash": "Any 32-byte hash.",
                        "signature": "Proof that the hash has been signed by signer."
                    },
                    "return": "isValid `true` if the signature is valid for the given hash and signer."
                },
                "isValidOrderSignature((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),bytes)": {
                    "details": "Verifies that a signature for an order is valid.",
                    "params": {
                        "order": "The order.",
                        "signature": "Proof that the order has been signed by signer."
                    },
                    "return": "isValid true if the signature is valid for the given order and signer."
                },
                "isValidTransactionSignature((uint256,uint256,uint256,address,bytes),bytes)": {
                    "details": "Verifies that a signature for a transaction is valid.",
                    "params": {
                        "signature": "Proof that the order has been signed by signer.",
                        "transaction": "The transaction."
                    },
                    "return": "isValid true if the signature is valid for the given transaction and signer."
                },
                "marketBuyOrdersFillOrKill((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256,bytes[])": {
                    "details": "Calls marketBuyOrdersNoThrow then reverts if < makerAssetFillAmount has been bought.      NOTE: This function does not enforce that the makerAsset is the same for each order.",
                    "params": {
                        "makerAssetFillAmount": "Minimum amount of makerAsset to buy.",
                        "orders": "Array of order specifications.",
                        "signatures": "Proofs that orders have been signed by makers."
                    },
                    "return": "Amounts filled and fees paid by makers and taker."
                },
                "marketBuyOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256,bytes[])": {
                    "details": "Executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.      If any fill reverts, the error is caught and ignored.      NOTE: This function does not enforce that the makerAsset is the same for each order.",
                    "params": {
                        "makerAssetFillAmount": "Desired amount of makerAsset to buy.",
                        "orders": "Array of order specifications.",
                        "signatures": "Proofs that orders have been signed by makers."
                    },
                    "return": "Amounts filled and fees paid by makers and taker."
                },
                "marketSellOrdersFillOrKill((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256,bytes[])": {
                    "details": "Calls marketSellOrdersNoThrow then reverts if < takerAssetFillAmount has been sold.      NOTE: This function does not enforce that the takerAsset is the same for each order.",
                    "params": {
                        "orders": "Array of order specifications.",
                        "signatures": "Proofs that orders have been signed by makers.",
                        "takerAssetFillAmount": "Minimum amount of takerAsset to sell."
                    },
                    "return": "Amounts filled and fees paid by makers and taker."
                },
                "marketSellOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256,bytes[])": {
                    "details": "Executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.      If any fill reverts, the error is caught and ignored.      NOTE: This function does not enforce that the takerAsset is the same for each order.",
                    "params": {
                        "orders": "Array of order specifications.",
                        "signatures": "Proofs that orders have been signed by makers.",
                        "takerAssetFillAmount": "Desired amount of takerAsset to sell."
                    },
                    "return": "Amounts filled and fees paid by makers and taker."
                },
                "matchOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),bytes,bytes)": {
                    "details": "Match two complementary orders that have a profitable spread.      Each order is filled at their respective price point. However, the calculations are      carried out as though the orders are both being filled at the right order's price point.      The profit made by the left order goes to the taker (who matched the two orders).",
                    "params": {
                        "leftOrder": "First order to match.",
                        "leftSignature": "Proof that order was created by the left maker.",
                        "rightOrder": "Second order to match.",
                        "rightSignature": "Proof that order was created by the right maker."
                    },
                    "return": "matchedFillResults Amounts filled and fees paid by maker and taker of matched orders."
                },
                "matchOrdersWithMaximalFill((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),bytes,bytes)": {
                    "details": "Match two complementary orders that have a profitable spread.      Each order is maximally filled at their respective price point, and      the matcher receives a profit denominated in either the left maker asset,      right maker asset, or a combination of both.",
                    "params": {
                        "leftOrder": "First order to match.",
                        "leftSignature": "Proof that order was created by the left maker.",
                        "rightOrder": "Second order to match.",
                        "rightSignature": "Proof that order was created by the right maker."
                    },
                    "return": "matchedFillResults Amounts filled by maker and taker of matched orders."
                },
                "preSign(bytes32)": {
                    "details": "Approves a hash on-chain.      After presigning a hash, the preSign signature type will become valid for that hash and signer.",
                    "params": {
                        "hash": "Any 32-byte hash."
                    }
                },
                "protocolFeeCollector()": {
                    "details": "Returns the protocolFeeCollector address"
                },
                "protocolFeeMultiplier()": {
                    "details": "Returns the protocolFeeMultiplier"
                },
                "registerAssetProxy(address)": {
                    "details": "Registers an asset proxy to its asset proxy id.      Once an asset proxy is registered, it cannot be unregistered.",
                    "params": {
                        "assetProxy": "Address of new asset proxy to register."
                    }
                },
                "setProtocolFeeCollectorAddress(address)": {
                    "details": "Allows the owner to update the protocolFeeCollector address.",
                    "params": {
                        "updatedProtocolFeeCollector": "The updated protocolFeeCollector contract address."
                    }
                },
                "setProtocolFeeMultiplier(uint256)": {
                    "details": "Allows the owner to update the protocol fee multiplier.",
                    "params": {
                        "updatedProtocolFeeMultiplier": "The updated protocol fee multiplier."
                    }
                },
                "setSignatureValidatorApproval(address,bool)": {
                    "details": "Approves/unnapproves a Validator contract to verify signatures on signer's behalf.",
                    "params": {
                        "approval": "Approval or disapproval of  Validator contract.",
                        "validatorAddress": "Address of Validator contract."
                    }
                },
                "simulateDispatchTransferFromCalls(bytes[],address[],address[],uint256[])": {
                    "details": "This function may be used to simulate any amount of transfers As they would occur through the Exchange contract. Note that this function will always revert, even if all transfers are successful. However, it may be used with eth_call or with a try/catch pattern in order to simulate the results of the transfers.",
                    "params": {
                        "amounts": "Array containing the amounts that correspond to each transfer.",
                        "assetData": "Array of asset details, each encoded per the AssetProxy contract specification.",
                        "fromAddresses": "Array containing the `from` addresses that correspond with each transfer.",
                        "toAddresses": "Array containing the `to` addresses that correspond with each transfer."
                    },
                    "return": "This function does not return a value. However, it will always revert with `Error(\"TRANSFERS_SUCCESSFUL\")` if all of the transfers were successful."
                }
            }
        },
        "evm": {
            "bytecode": {
                "linkReferences": {},
                "object": "0x",
                "opcodes": "",
                "sourceMap": ""
            },
            "deployedBytecode": {
                "linkReferences": {},
                "object": "0x",
                "opcodes": "",
                "sourceMap": ""
            }
        }
    },
    "sourceTreeHashHex": "0xe1120735f8b95d9bd5721dca890b1165024bc87f1ae33076432f30f32eb76f0a",
    "sources": {
        "./IExchange.sol": {
            "id": 13,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"./IExchangeCore.sol\";\nimport \"./IProtocolFees.sol\";\nimport \"./IMatchOrders.sol\";\nimport \"./ISignatureValidator.sol\";\nimport \"./ITransactions.sol\";\nimport \"./IAssetProxyDispatcher.sol\";\nimport \"./IWrapperFunctions.sol\";\nimport \"./ITransferSimulator.sol\";\n\n\n// solhint-disable no-empty-blocks\ncontract IExchange is\n    IProtocolFees,\n    IExchangeCore,\n    IMatchOrders,\n    ISignatureValidator,\n    ITransactions,\n    IAssetProxyDispatcher,\n    ITransferSimulator,\n    IWrapperFunctions\n{}\n"
        },
        "./IExchangeCore.sol": {
            "id": 14,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-exchange-libs/contracts/src/LibOrder.sol\";\nimport \"@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol\";\n\n\ncontract IExchangeCore {\n\n    // Fill event is emitted whenever an order is filled.\n    event Fill(\n        address indexed makerAddress,         // Address that created the order.\n        address indexed feeRecipientAddress,  // Address that received fees.\n        bytes makerAssetData,                 // Encoded data specific to makerAsset.\n        bytes takerAssetData,                 // Encoded data specific to takerAsset.\n        bytes makerFeeAssetData,              // Encoded data specific to makerFeeAsset.\n        bytes takerFeeAssetData,              // Encoded data specific to takerFeeAsset.\n        bytes32 indexed orderHash,            // EIP712 hash of order (see LibOrder.getTypedDataHash).\n        address takerAddress,                 // Address that filled the order.\n        address senderAddress,                // Address that called the Exchange contract (msg.sender).\n        uint256 makerAssetFilledAmount,       // Amount of makerAsset sold by maker and bought by taker.\n        uint256 takerAssetFilledAmount,       // Amount of takerAsset sold by taker and bought by maker.\n        uint256 makerFeePaid,                 // Amount of makerFeeAssetData paid to feeRecipient by maker.\n        uint256 takerFeePaid,                 // Amount of takerFeeAssetData paid to feeRecipient by taker.\n        uint256 protocolFeePaid               // Amount of eth or weth paid to the staking contract.\n    );\n\n    // Cancel event is emitted whenever an individual order is cancelled.\n    event Cancel(\n        address indexed makerAddress,         // Address that created the order.\n        address indexed feeRecipientAddress,  // Address that would have recieved fees if order was filled.\n        bytes makerAssetData,                 // Encoded data specific to makerAsset.\n        bytes takerAssetData,                 // Encoded data specific to takerAsset.\n        address senderAddress,                // Address that called the Exchange contract (msg.sender).\n        bytes32 indexed orderHash             // EIP712 hash of order (see LibOrder.getTypedDataHash).\n    );\n\n    // CancelUpTo event is emitted whenever `cancelOrdersUpTo` is executed succesfully.\n    event CancelUpTo(\n        address indexed makerAddress,         // Orders cancelled must have been created by this address.\n        address indexed orderSenderAddress,   // Orders cancelled must have a `senderAddress` equal to this address.\n        uint256 orderEpoch                    // Orders with specified makerAddress and senderAddress with a salt less than this value are considered cancelled.\n    );\n\n    /// @dev Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch\n    ///      and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress).\n    /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled.\n    function cancelOrdersUpTo(uint256 targetOrderEpoch)\n        external\n        payable;\n\n    /// @dev Fills the input order.\n    /// @param order Order struct containing order specifications.\n    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n    /// @param signature Proof that order has been created by maker.\n    /// @return Amounts filled and fees paid by maker and taker.\n    function fillOrder(\n        LibOrder.Order memory order,\n        uint256 takerAssetFillAmount,\n        bytes memory signature\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults memory fillResults);\n\n    /// @dev After calling, the order can not be filled anymore.\n    /// @param order Order struct containing order specifications.\n    function cancelOrder(LibOrder.Order memory order)\n        public\n        payable;\n\n    /// @dev Gets information about an order: status, hash, and amount filled.\n    /// @param order Order to gather information on.\n    /// @return OrderInfo Information about the order and its state.\n    ///                   See LibOrder.OrderInfo for a complete description.\n    function getOrderInfo(LibOrder.Order memory order)\n        public\n        view\n        returns (LibOrder.OrderInfo memory orderInfo);\n}\n"
        },
        "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol": {
            "id": 42,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\nimport \"@0x/contracts-utils/contracts/src/LibEIP712.sol\";\n\n\nlibrary LibOrder {\n\n    using LibOrder for Order;\n\n    // Hash for the EIP712 Order Schema:\n    // keccak256(abi.encodePacked(\n    //     \"Order(\",\n    //     \"address makerAddress,\",\n    //     \"address takerAddress,\",\n    //     \"address feeRecipientAddress,\",\n    //     \"address senderAddress,\",\n    //     \"uint256 makerAssetAmount,\",\n    //     \"uint256 takerAssetAmount,\",\n    //     \"uint256 makerFee,\",\n    //     \"uint256 takerFee,\",\n    //     \"uint256 expirationTimeSeconds,\",\n    //     \"uint256 salt,\",\n    //     \"bytes makerAssetData,\",\n    //     \"bytes takerAssetData,\",\n    //     \"bytes makerFeeAssetData,\",\n    //     \"bytes takerFeeAssetData\",\n    //     \")\"\n    // ))\n    bytes32 constant internal _EIP712_ORDER_SCHEMA_HASH =\n        0xf80322eb8376aafb64eadf8f0d7623f22130fd9491a221e902b713cb984a7534;\n\n    // A valid order remains fillable until it is expired, fully filled, or cancelled.\n    // An order's status is unaffected by external factors, like account balances.\n    enum OrderStatus {\n        INVALID,                     // Default value\n        INVALID_MAKER_ASSET_AMOUNT,  // Order does not have a valid maker asset amount\n        INVALID_TAKER_ASSET_AMOUNT,  // Order does not have a valid taker asset amount\n        FILLABLE,                    // Order is fillable\n        EXPIRED,                     // Order has already expired\n        FULLY_FILLED,                // Order is fully filled\n        CANCELLED                    // Order has been cancelled\n    }\n\n    // solhint-disable max-line-length\n    /// @dev Canonical order structure.\n    struct Order {\n        address makerAddress;           // Address that created the order.\n        address takerAddress;           // Address that is allowed to fill the order. If set to 0, any address is allowed to fill the order.\n        address feeRecipientAddress;    // Address that will recieve fees when order is filled.\n        address senderAddress;          // Address that is allowed to call Exchange contract methods that affect this order. If set to 0, any address is allowed to call these methods.\n        uint256 makerAssetAmount;       // Amount of makerAsset being offered by maker. Must be greater than 0.\n        uint256 takerAssetAmount;       // Amount of takerAsset being bid on by maker. Must be greater than 0.\n        uint256 makerFee;               // Fee paid to feeRecipient by maker when order is filled.\n        uint256 takerFee;               // Fee paid to feeRecipient by taker when order is filled.\n        uint256 expirationTimeSeconds;  // Timestamp in seconds at which order expires.\n        uint256 salt;                   // Arbitrary number to facilitate uniqueness of the order's hash.\n        bytes makerAssetData;           // Encoded data that can be decoded by a specified proxy contract when transferring makerAsset. The leading bytes4 references the id of the asset proxy.\n        bytes takerAssetData;           // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The leading bytes4 references the id of the asset proxy.\n        bytes makerFeeAssetData;        // Encoded data that can be decoded by a specified proxy contract when transferring makerFeeAsset. The leading bytes4 references the id of the asset proxy.\n        bytes takerFeeAssetData;        // Encoded data that can be decoded by a specified proxy contract when transferring takerFeeAsset. The leading bytes4 references the id of the asset proxy.\n    }\n    // solhint-enable max-line-length\n\n    /// @dev Order information returned by `getOrderInfo()`.\n    struct OrderInfo {\n        OrderStatus orderStatus;                    // Status that describes order's validity and fillability.\n        bytes32 orderHash;                    // EIP712 typed data hash of the order (see LibOrder.getTypedDataHash).\n        uint256 orderTakerAssetFilledAmount;  // Amount of order that has already been filled.\n    }\n\n    /// @dev Calculates the EIP712 typed data hash of an order with a given domain separator.\n    /// @param order The order structure.\n    /// @return EIP712 typed data hash of the order.\n    function getTypedDataHash(Order memory order, bytes32 eip712ExchangeDomainHash)\n        internal\n        pure\n        returns (bytes32 orderHash)\n    {\n        orderHash = LibEIP712.hashEIP712Message(\n            eip712ExchangeDomainHash,\n            order.getStructHash()\n        );\n        return orderHash;\n    }\n\n    /// @dev Calculates EIP712 hash of the order struct.\n    /// @param order The order structure.\n    /// @return EIP712 hash of the order struct.\n    function getStructHash(Order memory order)\n        internal\n        pure\n        returns (bytes32 result)\n    {\n        bytes32 schemaHash = _EIP712_ORDER_SCHEMA_HASH;\n        bytes memory makerAssetData = order.makerAssetData;\n        bytes memory takerAssetData = order.takerAssetData;\n        bytes memory makerFeeAssetData = order.makerFeeAssetData;\n        bytes memory takerFeeAssetData = order.takerFeeAssetData;\n\n        // Assembly for more efficiently computing:\n        // keccak256(abi.encodePacked(\n        //     EIP712_ORDER_SCHEMA_HASH,\n        //     uint256(order.makerAddress),\n        //     uint256(order.takerAddress),\n        //     uint256(order.feeRecipientAddress),\n        //     uint256(order.senderAddress),\n        //     order.makerAssetAmount,\n        //     order.takerAssetAmount,\n        //     order.makerFee,\n        //     order.takerFee,\n        //     order.expirationTimeSeconds,\n        //     order.salt,\n        //     keccak256(order.makerAssetData),\n        //     keccak256(order.takerAssetData),\n        //     keccak256(order.makerFeeAssetData),\n        //     keccak256(order.takerFeeAssetData)\n        // ));\n\n        assembly {\n            // Assert order offset (this is an internal error that should never be triggered)\n            if lt(order, 32) {\n                invalid()\n            }\n\n            // Calculate memory addresses that will be swapped out before hashing\n            let pos1 := sub(order, 32)\n            let pos2 := add(order, 320)\n            let pos3 := add(order, 352)\n            let pos4 := add(order, 384)\n            let pos5 := add(order, 416)\n\n            // Backup\n            let temp1 := mload(pos1)\n            let temp2 := mload(pos2)\n            let temp3 := mload(pos3)\n            let temp4 := mload(pos4)\n            let temp5 := mload(pos5)\n\n            // Hash in place\n            mstore(pos1, schemaHash)\n            mstore(pos2, keccak256(add(makerAssetData, 32), mload(makerAssetData)))        // store hash of makerAssetData\n            mstore(pos3, keccak256(add(takerAssetData, 32), mload(takerAssetData)))        // store hash of takerAssetData\n            mstore(pos4, keccak256(add(makerFeeAssetData, 32), mload(makerFeeAssetData)))  // store hash of makerFeeAssetData\n            mstore(pos5, keccak256(add(takerFeeAssetData, 32), mload(takerFeeAssetData)))  // store hash of takerFeeAssetData\n            result := keccak256(pos1, 480)\n\n            // Restore\n            mstore(pos1, temp1)\n            mstore(pos2, temp2)\n            mstore(pos3, temp3)\n            mstore(pos4, temp4)\n            mstore(pos5, temp5)\n        }\n        return result;\n    }\n}\n"
        },
        "@0x/contracts-utils/contracts/src/LibEIP712.sol": {
            "id": 50,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\n\nlibrary LibEIP712 {\n\n    // Hash of the EIP712 Domain Separator Schema\n    // keccak256(abi.encodePacked(\n    //     \"EIP712Domain(\",\n    //     \"string name,\",\n    //     \"string version,\",\n    //     \"uint256 chainId,\",\n    //     \"address verifyingContract\",\n    //     \")\"\n    // ))\n    bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n    /// @dev Calculates a EIP712 domain separator.\n    /// @param name The EIP712 domain name.\n    /// @param version The EIP712 domain version.\n    /// @param verifyingContract The EIP712 verifying contract.\n    /// @return EIP712 domain separator.\n    function hashEIP712Domain(\n        string memory name,\n        string memory version,\n        uint256 chainId,\n        address verifyingContract\n    )\n        internal\n        pure\n        returns (bytes32 result)\n    {\n        bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n        // Assembly for more efficient computing:\n        // keccak256(abi.encodePacked(\n        //     _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n        //     keccak256(bytes(name)),\n        //     keccak256(bytes(version)),\n        //     chainId,\n        //     uint256(verifyingContract)\n        // ))\n\n        assembly {\n            // Calculate hashes of dynamic data\n            let nameHash := keccak256(add(name, 32), mload(name))\n            let versionHash := keccak256(add(version, 32), mload(version))\n\n            // Load free memory pointer\n            let memPtr := mload(64)\n\n            // Store params in memory\n            mstore(memPtr, schemaHash)\n            mstore(add(memPtr, 32), nameHash)\n            mstore(add(memPtr, 64), versionHash)\n            mstore(add(memPtr, 96), chainId)\n            mstore(add(memPtr, 128), verifyingContract)\n\n            // Compute hash\n            result := keccak256(memPtr, 160)\n        }\n        return result;\n    }\n\n    /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n    /// @param eip712DomainHash Hash of the domain domain separator data, computed\n    ///                         with getDomainHash().\n    /// @param hashStruct The EIP712 hash struct.\n    /// @return EIP712 hash applied to the given EIP712 Domain.\n    function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n        internal\n        pure\n        returns (bytes32 result)\n    {\n        // Assembly for more efficient computing:\n        // keccak256(abi.encodePacked(\n        //     EIP191_HEADER,\n        //     EIP712_DOMAIN_HASH,\n        //     hashStruct\n        // ));\n\n        assembly {\n            // Load free memory pointer\n            let memPtr := mload(64)\n\n            mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000)  // EIP191 header\n            mstore(add(memPtr, 2), eip712DomainHash)                                            // EIP712 domain hash\n            mstore(add(memPtr, 34), hashStruct)                                                 // Hash of struct\n\n            // Compute hash\n            result := keccak256(memPtr, 66)\n        }\n        return result;\n    }\n}\n"
        },
        "@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol": {
            "id": 39,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\nimport \"@0x/contracts-utils/contracts/src/LibSafeMath.sol\";\nimport \"./LibMath.sol\";\nimport \"./LibOrder.sol\";\n\n\nlibrary LibFillResults {\n\n    using LibSafeMath for uint256;\n\n    struct BatchMatchedFillResults {\n        FillResults[] left;              // Fill results for left orders\n        FillResults[] right;             // Fill results for right orders\n        uint256 profitInLeftMakerAsset;  // Profit taken from left makers\n        uint256 profitInRightMakerAsset; // Profit taken from right makers\n    }\n\n    struct FillResults {\n        uint256 makerAssetFilledAmount;  // Total amount of makerAsset(s) filled.\n        uint256 takerAssetFilledAmount;  // Total amount of takerAsset(s) filled.\n        uint256 makerFeePaid;            // Total amount of fees paid by maker(s) to feeRecipient(s).\n        uint256 takerFeePaid;            // Total amount of fees paid by taker to feeRecipients(s).\n        uint256 protocolFeePaid;         // Total amount of fees paid by taker to the staking contract.\n    }\n\n    struct MatchedFillResults {\n        FillResults left;                // Amounts filled and fees paid of left order.\n        FillResults right;               // Amounts filled and fees paid of right order.\n        uint256 profitInLeftMakerAsset;  // Profit taken from the left maker\n        uint256 profitInRightMakerAsset; // Profit taken from the right maker\n    }\n\n    /// @dev Calculates amounts filled and fees paid by maker and taker.\n    /// @param order to be filled.\n    /// @param takerAssetFilledAmount Amount of takerAsset that will be filled.\n    /// @param protocolFeeMultiplier The current protocol fee of the exchange contract.\n    /// @param gasPrice The gasprice of the transaction. This is provided so that the function call can continue\n    ///        to be pure rather than view.\n    /// @return fillResults Amounts filled and fees paid by maker and taker.\n    function calculateFillResults(\n        LibOrder.Order memory order,\n        uint256 takerAssetFilledAmount,\n        uint256 protocolFeeMultiplier,\n        uint256 gasPrice\n    )\n        internal\n        pure\n        returns (FillResults memory fillResults)\n    {\n        // Compute proportional transfer amounts\n        fillResults.takerAssetFilledAmount = takerAssetFilledAmount;\n        fillResults.makerAssetFilledAmount = LibMath.safeGetPartialAmountFloor(\n            takerAssetFilledAmount,\n            order.takerAssetAmount,\n            order.makerAssetAmount\n        );\n        fillResults.makerFeePaid = LibMath.safeGetPartialAmountFloor(\n            takerAssetFilledAmount,\n            order.takerAssetAmount,\n            order.makerFee\n        );\n        fillResults.takerFeePaid = LibMath.safeGetPartialAmountFloor(\n            takerAssetFilledAmount,\n            order.takerAssetAmount,\n            order.takerFee\n        );\n\n        // Compute the protocol fee that should be paid for a single fill.\n        fillResults.protocolFeePaid = gasPrice.safeMul(protocolFeeMultiplier);\n\n        return fillResults;\n    }\n\n    /// @dev Calculates fill amounts for the matched orders.\n    ///      Each order is filled at their respective price point. However, the calculations are\n    ///      carried out as though the orders are both being filled at the right order's price point.\n    ///      The profit made by the leftOrder order goes to the taker (who matched the two orders).\n    /// @param leftOrder First order to match.\n    /// @param rightOrder Second order to match.\n    /// @param leftOrderTakerAssetFilledAmount Amount of left order already filled.\n    /// @param rightOrderTakerAssetFilledAmount Amount of right order already filled.\n    /// @param protocolFeeMultiplier The current protocol fee of the exchange contract.\n    /// @param gasPrice The gasprice of the transaction. This is provided so that the function call can continue\n    ///        to be pure rather than view.\n    /// @param shouldMaximallyFillOrders A value that indicates whether or not this calculation should use\n    ///                                  the maximal fill order matching strategy.\n    /// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders.\n    function calculateMatchedFillResults(\n        LibOrder.Order memory leftOrder,\n        LibOrder.Order memory rightOrder,\n        uint256 leftOrderTakerAssetFilledAmount,\n        uint256 rightOrderTakerAssetFilledAmount,\n        uint256 protocolFeeMultiplier,\n        uint256 gasPrice,\n        bool shouldMaximallyFillOrders\n    )\n        internal\n        pure\n        returns (MatchedFillResults memory matchedFillResults)\n    {\n        // Derive maker asset amounts for left & right orders, given store taker assert amounts\n        uint256 leftTakerAssetAmountRemaining = leftOrder.takerAssetAmount.safeSub(leftOrderTakerAssetFilledAmount);\n        uint256 leftMakerAssetAmountRemaining = LibMath.safeGetPartialAmountFloor(\n            leftOrder.makerAssetAmount,\n            leftOrder.takerAssetAmount,\n            leftTakerAssetAmountRemaining\n        );\n        uint256 rightTakerAssetAmountRemaining = rightOrder.takerAssetAmount.safeSub(rightOrderTakerAssetFilledAmount);\n        uint256 rightMakerAssetAmountRemaining = LibMath.safeGetPartialAmountFloor(\n            rightOrder.makerAssetAmount,\n            rightOrder.takerAssetAmount,\n            rightTakerAssetAmountRemaining\n        );\n\n        // Maximally fill the orders and pay out profits to the matcher in one or both of the maker assets.\n        if (shouldMaximallyFillOrders) {\n            matchedFillResults = _calculateMatchedFillResultsWithMaximalFill(\n                leftOrder,\n                rightOrder,\n                leftMakerAssetAmountRemaining,\n                leftTakerAssetAmountRemaining,\n                rightMakerAssetAmountRemaining,\n                rightTakerAssetAmountRemaining\n            );\n        } else {\n            matchedFillResults = _calculateMatchedFillResults(\n                leftOrder,\n                rightOrder,\n                leftMakerAssetAmountRemaining,\n                leftTakerAssetAmountRemaining,\n                rightMakerAssetAmountRemaining,\n                rightTakerAssetAmountRemaining\n            );\n        }\n\n        // Compute fees for left order\n        matchedFillResults.left.makerFeePaid = LibMath.safeGetPartialAmountFloor(\n            matchedFillResults.left.makerAssetFilledAmount,\n            leftOrder.makerAssetAmount,\n            leftOrder.makerFee\n        );\n        matchedFillResults.left.takerFeePaid = LibMath.safeGetPartialAmountFloor(\n            matchedFillResults.left.takerAssetFilledAmount,\n            leftOrder.takerAssetAmount,\n            leftOrder.takerFee\n        );\n\n        // Compute fees for right order\n        matchedFillResults.right.makerFeePaid = LibMath.safeGetPartialAmountFloor(\n            matchedFillResults.right.makerAssetFilledAmount,\n            rightOrder.makerAssetAmount,\n            rightOrder.makerFee\n        );\n        matchedFillResults.right.takerFeePaid = LibMath.safeGetPartialAmountFloor(\n            matchedFillResults.right.takerAssetFilledAmount,\n            rightOrder.takerAssetAmount,\n            rightOrder.takerFee\n        );\n\n        // Compute the protocol fee that should be paid for a single fill. In this\n        // case this should be made the protocol fee for both the left and right orders.\n        uint256 protocolFee = gasPrice.safeMul(protocolFeeMultiplier);\n        matchedFillResults.left.protocolFeePaid = protocolFee;\n        matchedFillResults.right.protocolFeePaid = protocolFee;\n\n        // Return fill results\n        return matchedFillResults;\n    }\n\n    /// @dev Adds properties of both FillResults instances.\n    /// @param fillResults1 The first FillResults.\n    /// @param fillResults2 The second FillResults.\n    /// @return The sum of both fill results.\n    function addFillResults(\n        FillResults memory fillResults1,\n        FillResults memory fillResults2\n    )\n        internal\n        pure\n        returns (FillResults memory totalFillResults)\n    {\n        totalFillResults.makerAssetFilledAmount = fillResults1.makerAssetFilledAmount.safeAdd(fillResults2.makerAssetFilledAmount);\n        totalFillResults.takerAssetFilledAmount = fillResults1.takerAssetFilledAmount.safeAdd(fillResults2.takerAssetFilledAmount);\n        totalFillResults.makerFeePaid = fillResults1.makerFeePaid.safeAdd(fillResults2.makerFeePaid);\n        totalFillResults.takerFeePaid = fillResults1.takerFeePaid.safeAdd(fillResults2.takerFeePaid);\n        totalFillResults.protocolFeePaid = fillResults1.protocolFeePaid.safeAdd(fillResults2.protocolFeePaid);\n\n        return totalFillResults;\n    }\n\n    /// @dev Calculates part of the matched fill results for a given situation using the fill strategy that only\n    ///      awards profit denominated in the left maker asset.\n    /// @param leftOrder The left order in the order matching situation.\n    /// @param rightOrder The right order in the order matching situation.\n    /// @param leftMakerAssetAmountRemaining The amount of the left order maker asset that can still be filled.\n    /// @param leftTakerAssetAmountRemaining The amount of the left order taker asset that can still be filled.\n    /// @param rightMakerAssetAmountRemaining The amount of the right order maker asset that can still be filled.\n    /// @param rightTakerAssetAmountRemaining The amount of the right order taker asset that can still be filled.\n    /// @return MatchFillResults struct that does not include fees paid.\n    function _calculateMatchedFillResults(\n        LibOrder.Order memory leftOrder,\n        LibOrder.Order memory rightOrder,\n        uint256 leftMakerAssetAmountRemaining,\n        uint256 leftTakerAssetAmountRemaining,\n        uint256 rightMakerAssetAmountRemaining,\n        uint256 rightTakerAssetAmountRemaining\n    )\n        private\n        pure\n        returns (MatchedFillResults memory matchedFillResults)\n    {\n        // Calculate fill results for maker and taker assets: at least one order will be fully filled.\n        // The maximum amount the left maker can buy is `leftTakerAssetAmountRemaining`\n        // The maximum amount the right maker can sell is `rightMakerAssetAmountRemaining`\n        // We have two distinct cases for calculating the fill results:\n        // Case 1.\n        //   If the left maker can buy more than the right maker can sell, then only the right order is fully filled.\n        //   If the left maker can buy exactly what the right maker can sell, then both orders are fully filled.\n        // Case 2.\n        //   If the left maker cannot buy more than the right maker can sell, then only the left order is fully filled.\n        // Case 3.\n        //   If the left maker can buy exactly as much as the right maker can sell, then both orders are fully filled.\n        if (leftTakerAssetAmountRemaining > rightMakerAssetAmountRemaining) {\n            // Case 1: Right order is fully filled\n            matchedFillResults = _calculateCompleteRightFill(\n                leftOrder,\n                rightMakerAssetAmountRemaining,\n                rightTakerAssetAmountRemaining\n            );\n        } else if (leftTakerAssetAmountRemaining < rightMakerAssetAmountRemaining) {\n            // Case 2: Left order is fully filled\n            matchedFillResults.left.makerAssetFilledAmount = leftMakerAssetAmountRemaining;\n            matchedFillResults.left.takerAssetFilledAmount = leftTakerAssetAmountRemaining;\n            matchedFillResults.right.makerAssetFilledAmount = leftTakerAssetAmountRemaining;\n            // Round up to ensure the maker's exchange rate does not exceed the price specified by the order.\n            // We favor the maker when the exchange rate must be rounded.\n            matchedFillResults.right.takerAssetFilledAmount = LibMath.safeGetPartialAmountCeil(\n                rightOrder.takerAssetAmount,\n                rightOrder.makerAssetAmount,\n                leftTakerAssetAmountRemaining // matchedFillResults.right.makerAssetFilledAmount\n            );\n        } else {\n            // leftTakerAssetAmountRemaining == rightMakerAssetAmountRemaining\n            // Case 3: Both orders are fully filled. Technically, this could be captured by the above cases, but\n            //         this calculation will be more precise since it does not include rounding.\n            matchedFillResults = _calculateCompleteFillBoth(\n                leftMakerAssetAmountRemaining,\n                leftTakerAssetAmountRemaining,\n                rightMakerAssetAmountRemaining,\n                rightTakerAssetAmountRemaining\n            );\n        }\n\n        // Calculate amount given to taker\n        matchedFillResults.profitInLeftMakerAsset = matchedFillResults.left.makerAssetFilledAmount.safeSub(\n            matchedFillResults.right.takerAssetFilledAmount\n        );\n\n        return matchedFillResults;\n    }\n\n    /// @dev Calculates part of the matched fill results for a given situation using the maximal fill order matching\n    ///      strategy.\n    /// @param leftOrder The left order in the order matching situation.\n    /// @param rightOrder The right order in the order matching situation.\n    /// @param leftMakerAssetAmountRemaining The amount of the left order maker asset that can still be filled.\n    /// @param leftTakerAssetAmountRemaining The amount of the left order taker asset that can still be filled.\n    /// @param rightMakerAssetAmountRemaining The amount of the right order maker asset that can still be filled.\n    /// @param rightTakerAssetAmountRemaining The amount of the right order taker asset that can still be filled.\n    /// @return MatchFillResults struct that does not include fees paid.\n    function _calculateMatchedFillResultsWithMaximalFill(\n        LibOrder.Order memory leftOrder,\n        LibOrder.Order memory rightOrder,\n        uint256 leftMakerAssetAmountRemaining,\n        uint256 leftTakerAssetAmountRemaining,\n        uint256 rightMakerAssetAmountRemaining,\n        uint256 rightTakerAssetAmountRemaining\n    )\n        private\n        pure\n        returns (MatchedFillResults memory matchedFillResults)\n    {\n        // If a maker asset is greater than the opposite taker asset, than there will be a spread denominated in that maker asset.\n        bool doesLeftMakerAssetProfitExist = leftMakerAssetAmountRemaining > rightTakerAssetAmountRemaining;\n        bool doesRightMakerAssetProfitExist = rightMakerAssetAmountRemaining > leftTakerAssetAmountRemaining;\n\n        // Calculate the maximum fill results for the maker and taker assets. At least one of the orders will be fully filled.\n        //\n        // The maximum that the left maker can possibly buy is the amount that the right order can sell.\n        // The maximum that the right maker can possibly buy is the amount that the left order can sell.\n        //\n        // If the left order is fully filled, profit will be paid out in the left maker asset. If the right order is fully filled,\n        // the profit will be out in the right maker asset.\n        //\n        // There are three cases to consider:\n        // Case 1.\n        //   If the left maker can buy more than the right maker can sell, then only the right order is fully filled.\n        // Case 2.\n        //   If the right maker can buy more than the left maker can sell, then only the right order is fully filled.\n        // Case 3.\n        //   If the right maker can sell the max of what the left maker can buy and the left maker can sell the max of\n        //   what the right maker can buy, then both orders are fully filled.\n        if (leftTakerAssetAmountRemaining > rightMakerAssetAmountRemaining) {\n            // Case 1: Right order is fully filled with the profit paid in the left makerAsset\n            matchedFillResults = _calculateCompleteRightFill(\n                leftOrder,\n                rightMakerAssetAmountRemaining,\n                rightTakerAssetAmountRemaining\n            );\n        } else if (rightTakerAssetAmountRemaining > leftMakerAssetAmountRemaining) {\n            // Case 2: Left order is fully filled with the profit paid in the right makerAsset.\n            matchedFillResults.left.makerAssetFilledAmount = leftMakerAssetAmountRemaining;\n            matchedFillResults.left.takerAssetFilledAmount = leftTakerAssetAmountRemaining;\n            // Round down to ensure the right maker's exchange rate does not exceed the price specified by the order.\n            // We favor the right maker when the exchange rate must be rounded and the profit is being paid in the\n            // right maker asset.\n            matchedFillResults.right.makerAssetFilledAmount = LibMath.safeGetPartialAmountFloor(\n                rightOrder.makerAssetAmount,\n                rightOrder.takerAssetAmount,\n                leftMakerAssetAmountRemaining\n            );\n            matchedFillResults.right.takerAssetFilledAmount = leftMakerAssetAmountRemaining;\n        } else {\n            // Case 3: The right and left orders are fully filled\n            matchedFillResults = _calculateCompleteFillBoth(\n                leftMakerAssetAmountRemaining,\n                leftTakerAssetAmountRemaining,\n                rightMakerAssetAmountRemaining,\n                rightTakerAssetAmountRemaining\n            );\n        }\n\n        // Calculate amount given to taker in the left order's maker asset if the left spread will be part of the profit.\n        if (doesLeftMakerAssetProfitExist) {\n            matchedFillResults.profitInLeftMakerAsset = matchedFillResults.left.makerAssetFilledAmount.safeSub(\n                matchedFillResults.right.takerAssetFilledAmount\n            );\n        }\n\n        // Calculate amount given to taker in the right order's maker asset if the right spread will be part of the profit.\n        if (doesRightMakerAssetProfitExist) {\n            matchedFillResults.profitInRightMakerAsset = matchedFillResults.right.makerAssetFilledAmount.safeSub(\n                matchedFillResults.left.takerAssetFilledAmount\n            );\n        }\n\n        return matchedFillResults;\n    }\n\n    /// @dev Calculates the fill results for the maker and taker in the order matching and writes the results\n    ///      to the fillResults that are being collected on the order. Both orders will be fully filled in this\n    ///      case.\n    /// @param leftMakerAssetAmountRemaining The amount of the left maker asset that is remaining to be filled.\n    /// @param leftTakerAssetAmountRemaining The amount of the left taker asset that is remaining to be filled.\n    /// @param rightMakerAssetAmountRemaining The amount of the right maker asset that is remaining to be filled.\n    /// @param rightTakerAssetAmountRemaining The amount of the right taker asset that is remaining to be filled.\n    /// @return MatchFillResults struct that does not include fees paid or spreads taken.\n    function _calculateCompleteFillBoth(\n        uint256 leftMakerAssetAmountRemaining,\n        uint256 leftTakerAssetAmountRemaining,\n        uint256 rightMakerAssetAmountRemaining,\n        uint256 rightTakerAssetAmountRemaining\n    )\n        private\n        pure\n        returns (MatchedFillResults memory matchedFillResults)\n    {\n        // Calculate the fully filled results for both orders.\n        matchedFillResults.left.makerAssetFilledAmount = leftMakerAssetAmountRemaining;\n        matchedFillResults.left.takerAssetFilledAmount = leftTakerAssetAmountRemaining;\n        matchedFillResults.right.makerAssetFilledAmount = rightMakerAssetAmountRemaining;\n        matchedFillResults.right.takerAssetFilledAmount = rightTakerAssetAmountRemaining;\n\n        return matchedFillResults;\n    }\n\n    /// @dev Calculates the fill results for the maker and taker in the order matching and writes the results\n    ///      to the fillResults that are being collected on the order.\n    /// @param leftOrder The left order that is being maximally filled. All of the information about fill amounts\n    ///                  can be derived from this order and the right asset remaining fields.\n    /// @param rightMakerAssetAmountRemaining The amount of the right maker asset that is remaining to be filled.\n    /// @param rightTakerAssetAmountRemaining The amount of the right taker asset that is remaining to be filled.\n    /// @return MatchFillResults struct that does not include fees paid or spreads taken.\n    function _calculateCompleteRightFill(\n        LibOrder.Order memory leftOrder,\n        uint256 rightMakerAssetAmountRemaining,\n        uint256 rightTakerAssetAmountRemaining\n    )\n        private\n        pure\n        returns (MatchedFillResults memory matchedFillResults)\n    {\n        matchedFillResults.right.makerAssetFilledAmount = rightMakerAssetAmountRemaining;\n        matchedFillResults.right.takerAssetFilledAmount = rightTakerAssetAmountRemaining;\n        matchedFillResults.left.takerAssetFilledAmount = rightMakerAssetAmountRemaining;\n        // Round down to ensure the left maker's exchange rate does not exceed the price specified by the order.\n        // We favor the left maker when the exchange rate must be rounded and the profit is being paid in the\n        // left maker asset.\n        matchedFillResults.left.makerAssetFilledAmount = LibMath.safeGetPartialAmountFloor(\n            leftOrder.makerAssetAmount,\n            leftOrder.takerAssetAmount,\n            rightMakerAssetAmountRemaining\n        );\n\n        return matchedFillResults;\n    }\n}\n"
        },
        "@0x/contracts-utils/contracts/src/LibSafeMath.sol": {
            "id": 54,
            "content": "pragma solidity ^0.5.9;\n\nimport \"./LibRichErrors.sol\";\nimport \"./LibSafeMathRichErrors.sol\";\n\n\nlibrary LibSafeMath {\n\n    function safeMul(uint256 a, uint256 b)\n        internal\n        pure\n        returns (uint256)\n    {\n        if (a == 0) {\n            return 0;\n        }\n        uint256 c = a * b;\n        if (c / a != b) {\n            LibRichErrors.rrevert(LibSafeMathRichErrors.Uint256BinOpError(\n                LibSafeMathRichErrors.BinOpErrorCodes.MULTIPLICATION_OVERFLOW,\n                a,\n                b\n            ));\n        }\n        return c;\n    }\n\n    function safeDiv(uint256 a, uint256 b)\n        internal\n        pure\n        returns (uint256)\n    {\n        if (b == 0) {\n            LibRichErrors.rrevert(LibSafeMathRichErrors.Uint256BinOpError(\n                LibSafeMathRichErrors.BinOpErrorCodes.DIVISION_BY_ZERO,\n                a,\n                b\n            ));\n        }\n        uint256 c = a / b;\n        return c;\n    }\n\n    function safeSub(uint256 a, uint256 b)\n        internal\n        pure\n        returns (uint256)\n    {\n        if (b > a) {\n            LibRichErrors.rrevert(LibSafeMathRichErrors.Uint256BinOpError(\n                LibSafeMathRichErrors.BinOpErrorCodes.SUBTRACTION_UNDERFLOW,\n                a,\n                b\n            ));\n        }\n        return a - b;\n    }\n\n    function safeAdd(uint256 a, uint256 b)\n        internal\n        pure\n        returns (uint256)\n    {\n        uint256 c = a + b;\n        if (c < a) {\n            LibRichErrors.rrevert(LibSafeMathRichErrors.Uint256BinOpError(\n                LibSafeMathRichErrors.BinOpErrorCodes.ADDITION_OVERFLOW,\n                a,\n                b\n            ));\n        }\n        return c;\n    }\n\n    function max256(uint256 a, uint256 b)\n        internal\n        pure\n        returns (uint256)\n    {\n        return a >= b ? a : b;\n    }\n\n    function min256(uint256 a, uint256 b)\n        internal\n        pure\n        returns (uint256)\n    {\n        return a < b ? a : b;\n    }\n}\n"
        },
        "@0x/contracts-utils/contracts/src/LibRichErrors.sol": {
            "id": 53,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\n\nlibrary LibRichErrors {\n\n    // bytes4(keccak256(\"Error(string)\"))\n    bytes4 internal constant STANDARD_ERROR_SELECTOR =\n        0x08c379a0;\n\n    // solhint-disable func-name-mixedcase\n    /// @dev ABI encode a standard, string revert error payload.\n    ///      This is the same payload that would be included by a `revert(string)`\n    ///      solidity statement. It has the function signature `Error(string)`.\n    /// @param message The error string.\n    /// @return The ABI encoded error.\n    function StandardError(\n        string memory message\n    )\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return abi.encodeWithSelector(\n            STANDARD_ERROR_SELECTOR,\n            bytes(message)\n        );\n    }\n    // solhint-enable func-name-mixedcase\n\n    /// @dev Reverts an encoded rich revert reason `errorData`.\n    /// @param errorData ABI encoded error data.\n    function rrevert(bytes memory errorData)\n        internal\n        pure\n    {\n        assembly {\n            revert(add(errorData, 0x20), mload(errorData))\n        }\n    }\n}\n"
        },
        "@0x/contracts-utils/contracts/src/LibSafeMathRichErrors.sol": {
            "id": 55,
            "content": "pragma solidity ^0.5.9;\n\n\nlibrary LibSafeMathRichErrors {\n\n    // bytes4(keccak256(\"Uint256BinOpError(uint8,uint256,uint256)\"))\n    bytes4 internal constant UINT256_BINOP_ERROR_SELECTOR =\n        0xe946c1bb;\n\n    // bytes4(keccak256(\"Uint256DowncastError(uint8,uint256)\"))\n    bytes4 internal constant UINT256_DOWNCAST_ERROR_SELECTOR =\n        0xc996af7b;\n\n    enum BinOpErrorCodes {\n        ADDITION_OVERFLOW,\n        MULTIPLICATION_OVERFLOW,\n        SUBTRACTION_UNDERFLOW,\n        DIVISION_BY_ZERO\n    }\n\n    enum DowncastErrorCodes {\n        VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT32,\n        VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT64,\n        VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT96\n    }\n\n    // solhint-disable func-name-mixedcase\n    function Uint256BinOpError(\n        BinOpErrorCodes errorCode,\n        uint256 a,\n        uint256 b\n    )\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return abi.encodeWithSelector(\n            UINT256_BINOP_ERROR_SELECTOR,\n            errorCode,\n            a,\n            b\n        );\n    }\n\n    function Uint256DowncastError(\n        DowncastErrorCodes errorCode,\n        uint256 a\n    )\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return abi.encodeWithSelector(\n            UINT256_DOWNCAST_ERROR_SELECTOR,\n            errorCode,\n            a\n        );\n    }\n}\n"
        },
        "@0x/contracts-exchange-libs/contracts/src/LibMath.sol": {
            "id": 40,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\nimport \"@0x/contracts-utils/contracts/src/LibSafeMath.sol\";\nimport \"@0x/contracts-utils/contracts/src/LibRichErrors.sol\";\nimport \"./LibMathRichErrors.sol\";\n\n\nlibrary LibMath {\n\n    using LibSafeMath for uint256;\n\n    /// @dev Calculates partial value given a numerator and denominator rounded down.\n    ///      Reverts if rounding error is >= 0.1%\n    /// @param numerator Numerator.\n    /// @param denominator Denominator.\n    /// @param target Value to calculate partial of.\n    /// @return Partial value of target rounded down.\n    function safeGetPartialAmountFloor(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (uint256 partialAmount)\n    {\n        if (isRoundingErrorFloor(\n                numerator,\n                denominator,\n                target\n        )) {\n            LibRichErrors.rrevert(LibMathRichErrors.RoundingError(\n                numerator,\n                denominator,\n                target\n            ));\n        }\n\n        partialAmount = numerator.safeMul(target).safeDiv(denominator);\n        return partialAmount;\n    }\n\n    /// @dev Calculates partial value given a numerator and denominator rounded down.\n    ///      Reverts if rounding error is >= 0.1%\n    /// @param numerator Numerator.\n    /// @param denominator Denominator.\n    /// @param target Value to calculate partial of.\n    /// @return Partial value of target rounded up.\n    function safeGetPartialAmountCeil(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (uint256 partialAmount)\n    {\n        if (isRoundingErrorCeil(\n                numerator,\n                denominator,\n                target\n        )) {\n            LibRichErrors.rrevert(LibMathRichErrors.RoundingError(\n                numerator,\n                denominator,\n                target\n            ));\n        }\n\n        // safeDiv computes `floor(a / b)`. We use the identity (a, b integer):\n        //       ceil(a / b) = floor((a + b - 1) / b)\n        // To implement `ceil(a / b)` using safeDiv.\n        partialAmount = numerator.safeMul(target)\n            .safeAdd(denominator.safeSub(1))\n            .safeDiv(denominator);\n\n        return partialAmount;\n    }\n\n    /// @dev Calculates partial value given a numerator and denominator rounded down.\n    /// @param numerator Numerator.\n    /// @param denominator Denominator.\n    /// @param target Value to calculate partial of.\n    /// @return Partial value of target rounded down.\n    function getPartialAmountFloor(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (uint256 partialAmount)\n    {\n        partialAmount = numerator.safeMul(target).safeDiv(denominator);\n        return partialAmount;\n    }\n\n    /// @dev Calculates partial value given a numerator and denominator rounded down.\n    /// @param numerator Numerator.\n    /// @param denominator Denominator.\n    /// @param target Value to calculate partial of.\n    /// @return Partial value of target rounded up.\n    function getPartialAmountCeil(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (uint256 partialAmount)\n    {\n        // safeDiv computes `floor(a / b)`. We use the identity (a, b integer):\n        //       ceil(a / b) = floor((a + b - 1) / b)\n        // To implement `ceil(a / b)` using safeDiv.\n        partialAmount = numerator.safeMul(target)\n            .safeAdd(denominator.safeSub(1))\n            .safeDiv(denominator);\n\n        return partialAmount;\n    }\n\n    /// @dev Checks if rounding error >= 0.1% when rounding down.\n    /// @param numerator Numerator.\n    /// @param denominator Denominator.\n    /// @param target Value to multiply with numerator/denominator.\n    /// @return Rounding error is present.\n    function isRoundingErrorFloor(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (bool isError)\n    {\n        if (denominator == 0) {\n            LibRichErrors.rrevert(LibMathRichErrors.DivisionByZeroError());\n        }\n\n        // The absolute rounding error is the difference between the rounded\n        // value and the ideal value. The relative rounding error is the\n        // absolute rounding error divided by the absolute value of the\n        // ideal value. This is undefined when the ideal value is zero.\n        //\n        // The ideal value is `numerator * target / denominator`.\n        // Let's call `numerator * target % denominator` the remainder.\n        // The absolute error is `remainder / denominator`.\n        //\n        // When the ideal value is zero, we require the absolute error to\n        // be zero. Fortunately, this is always the case. The ideal value is\n        // zero iff `numerator == 0` and/or `target == 0`. In this case the\n        // remainder and absolute error are also zero.\n        if (target == 0 || numerator == 0) {\n            return false;\n        }\n\n        // Otherwise, we want the relative rounding error to be strictly\n        // less than 0.1%.\n        // The relative error is `remainder / (numerator * target)`.\n        // We want the relative error less than 1 / 1000:\n        //        remainder / (numerator * denominator)  <  1 / 1000\n        // or equivalently:\n        //        1000 * remainder  <  numerator * target\n        // so we have a rounding error iff:\n        //        1000 * remainder  >=  numerator * target\n        uint256 remainder = mulmod(\n            target,\n            numerator,\n            denominator\n        );\n        isError = remainder.safeMul(1000) >= numerator.safeMul(target);\n        return isError;\n    }\n\n    /// @dev Checks if rounding error >= 0.1% when rounding up.\n    /// @param numerator Numerator.\n    /// @param denominator Denominator.\n    /// @param target Value to multiply with numerator/denominator.\n    /// @return Rounding error is present.\n    function isRoundingErrorCeil(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (bool isError)\n    {\n        if (denominator == 0) {\n            LibRichErrors.rrevert(LibMathRichErrors.DivisionByZeroError());\n        }\n\n        // See the comments in `isRoundingError`.\n        if (target == 0 || numerator == 0) {\n            // When either is zero, the ideal value and rounded value are zero\n            // and there is no rounding error. (Although the relative error\n            // is undefined.)\n            return false;\n        }\n        // Compute remainder as before\n        uint256 remainder = mulmod(\n            target,\n            numerator,\n            denominator\n        );\n        remainder = denominator.safeSub(remainder) % denominator;\n        isError = remainder.safeMul(1000) >= numerator.safeMul(target);\n        return isError;\n    }\n}\n"
        },
        "@0x/contracts-exchange-libs/contracts/src/LibMathRichErrors.sol": {
            "id": 41,
            "content": "pragma solidity ^0.5.9;\n\n\nlibrary LibMathRichErrors {\n\n    // bytes4(keccak256(\"DivisionByZeroError()\"))\n    bytes internal constant DIVISION_BY_ZERO_ERROR =\n        hex\"a791837c\";\n\n    // bytes4(keccak256(\"RoundingError(uint256,uint256,uint256)\"))\n    bytes4 internal constant ROUNDING_ERROR_SELECTOR =\n        0x339f3de2;\n\n    // solhint-disable func-name-mixedcase\n    function DivisionByZeroError()\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return DIVISION_BY_ZERO_ERROR;\n    }\n\n    function RoundingError(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return abi.encodeWithSelector(\n            ROUNDING_ERROR_SELECTOR,\n            numerator,\n            denominator,\n            target\n        );\n    }\n}\n"
        },
        "./IProtocolFees.sol": {
            "id": 16,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\n\ncontract IProtocolFees {\n\n    // Logs updates to the protocol fee multiplier.\n    event ProtocolFeeMultiplier(uint256 oldProtocolFeeMultiplier, uint256 updatedProtocolFeeMultiplier);\n\n    // Logs updates to the protocolFeeCollector address.\n    event ProtocolFeeCollectorAddress(address oldProtocolFeeCollector, address updatedProtocolFeeCollector);\n\n    /// @dev Allows the owner to update the protocol fee multiplier.\n    /// @param updatedProtocolFeeMultiplier The updated protocol fee multiplier.\n    function setProtocolFeeMultiplier(uint256 updatedProtocolFeeMultiplier)\n        external;\n\n    /// @dev Allows the owner to update the protocolFeeCollector address.\n    /// @param updatedProtocolFeeCollector The updated protocolFeeCollector contract address.\n    function setProtocolFeeCollectorAddress(address updatedProtocolFeeCollector)\n        external;\n\n    /// @dev Returns the protocolFeeMultiplier\n    function protocolFeeMultiplier()\n        external\n        view\n        returns (uint256);\n\n    /// @dev Returns the protocolFeeCollector address\n    function protocolFeeCollector()\n        external\n        view\n        returns (address);\n}\n"
        },
        "./IMatchOrders.sol": {
            "id": 15,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-exchange-libs/contracts/src/LibOrder.sol\";\nimport \"@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol\";\n\n\ncontract IMatchOrders {\n\n    /// @dev Match complementary orders that have a profitable spread.\n    ///      Each order is filled at their respective price point, and\n    ///      the matcher receives a profit denominated in the left maker asset.\n    /// @param leftOrders Set of orders with the same maker / taker asset.\n    /// @param rightOrders Set of orders to match against `leftOrders`\n    /// @param leftSignatures Proof that left orders were created by the left makers.\n    /// @param rightSignatures Proof that right orders were created by the right makers.\n    /// @return batchMatchedFillResults Amounts filled and profit generated.\n    function batchMatchOrders(\n        LibOrder.Order[] memory leftOrders,\n        LibOrder.Order[] memory rightOrders,\n        bytes[] memory leftSignatures,\n        bytes[] memory rightSignatures\n    )\n        public\n        payable\n        returns (LibFillResults.BatchMatchedFillResults memory batchMatchedFillResults);\n\n    /// @dev Match complementary orders that have a profitable spread.\n    ///      Each order is maximally filled at their respective price point, and\n    ///      the matcher receives a profit denominated in either the left maker asset,\n    ///      right maker asset, or a combination of both.\n    /// @param leftOrders Set of orders with the same maker / taker asset.\n    /// @param rightOrders Set of orders to match against `leftOrders`\n    /// @param leftSignatures Proof that left orders were created by the left makers.\n    /// @param rightSignatures Proof that right orders were created by the right makers.\n    /// @return batchMatchedFillResults Amounts filled and profit generated.\n    function batchMatchOrdersWithMaximalFill(\n        LibOrder.Order[] memory leftOrders,\n        LibOrder.Order[] memory rightOrders,\n        bytes[] memory leftSignatures,\n        bytes[] memory rightSignatures\n    )\n        public\n        payable\n        returns (LibFillResults.BatchMatchedFillResults memory batchMatchedFillResults);\n\n    /// @dev Match two complementary orders that have a profitable spread.\n    ///      Each order is filled at their respective price point. However, the calculations are\n    ///      carried out as though the orders are both being filled at the right order's price point.\n    ///      The profit made by the left order goes to the taker (who matched the two orders).\n    /// @param leftOrder First order to match.\n    /// @param rightOrder Second order to match.\n    /// @param leftSignature Proof that order was created by the left maker.\n    /// @param rightSignature Proof that order was created by the right maker.\n    /// @return matchedFillResults Amounts filled and fees paid by maker and taker of matched orders.\n    function matchOrders(\n        LibOrder.Order memory leftOrder,\n        LibOrder.Order memory rightOrder,\n        bytes memory leftSignature,\n        bytes memory rightSignature\n    )\n        public\n        payable\n        returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n\n    /// @dev Match two complementary orders that have a profitable spread.\n    ///      Each order is maximally filled at their respective price point, and\n    ///      the matcher receives a profit denominated in either the left maker asset,\n    ///      right maker asset, or a combination of both.\n    /// @param leftOrder First order to match.\n    /// @param rightOrder Second order to match.\n    /// @param leftSignature Proof that order was created by the left maker.\n    /// @param rightSignature Proof that order was created by the right maker.\n    /// @return matchedFillResults Amounts filled by maker and taker of matched orders.\n    function matchOrdersWithMaximalFill(\n        LibOrder.Order memory leftOrder,\n        LibOrder.Order memory rightOrder,\n        bytes memory leftSignature,\n        bytes memory rightSignature\n    )\n        public\n        payable\n        returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n}\n"
        },
        "./ISignatureValidator.sol": {
            "id": 17,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-exchange-libs/contracts/src/LibOrder.sol\";\nimport \"@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol\";\n\n\ncontract ISignatureValidator {\n\n   // Allowed signature types.\n    enum SignatureType {\n        Illegal,                     // 0x00, default value\n        Invalid,                     // 0x01\n        EIP712,                      // 0x02\n        EthSign,                     // 0x03\n        Wallet,                      // 0x04\n        Validator,                   // 0x05\n        PreSigned,                   // 0x06\n        EIP1271Wallet,               // 0x07\n        NSignatureTypes              // 0x08, number of signature types. Always leave at end.\n    }\n\n    event SignatureValidatorApproval(\n        address indexed signerAddress,     // Address that approves or disapproves a contract to verify signatures.\n        address indexed validatorAddress,  // Address of signature validator contract.\n        bool isApproved                    // Approval or disapproval of validator contract.\n    );\n\n    /// @dev Approves a hash on-chain.\n    ///      After presigning a hash, the preSign signature type will become valid for that hash and signer.\n    /// @param hash Any 32-byte hash.\n    function preSign(bytes32 hash)\n        external\n        payable;\n\n    /// @dev Approves/unnapproves a Validator contract to verify signatures on signer's behalf.\n    /// @param validatorAddress Address of Validator contract.\n    /// @param approval Approval or disapproval of  Validator contract.\n    function setSignatureValidatorApproval(\n        address validatorAddress,\n        bool approval\n    )\n        external\n        payable;\n\n    /// @dev Verifies that a hash has been signed by the given signer.\n    /// @param hash Any 32-byte hash.\n    /// @param signature Proof that the hash has been signed by signer.\n    /// @return isValid `true` if the signature is valid for the given hash and signer.\n    function isValidHashSignature(\n        bytes32 hash,\n        address signerAddress,\n        bytes memory signature\n    )\n        public\n        view\n        returns (bool isValid);\n\n    /// @dev Verifies that a signature for an order is valid.\n    /// @param order The order.\n    /// @param signature Proof that the order has been signed by signer.\n    /// @return isValid true if the signature is valid for the given order and signer.\n    function isValidOrderSignature(\n        LibOrder.Order memory order,\n        bytes memory signature\n    )\n        public\n        view\n        returns (bool isValid);\n\n    /// @dev Verifies that a signature for a transaction is valid.\n    /// @param transaction The transaction.\n    /// @param signature Proof that the order has been signed by signer.\n    /// @return isValid true if the signature is valid for the given transaction and signer.\n    function isValidTransactionSignature(\n        LibZeroExTransaction.ZeroExTransaction memory transaction,\n        bytes memory signature\n    )\n        public\n        view\n        returns (bool isValid);\n\n    /// @dev Verifies that an order, with provided order hash, has been signed\n    ///      by the given signer.\n    /// @param order The order.\n    /// @param orderHash The hash of the order.\n    /// @param signature Proof that the hash has been signed by signer.\n    /// @return isValid True if the signature is valid for the given order and signer.\n    function _isValidOrderWithHashSignature(\n        LibOrder.Order memory order,\n        bytes32 orderHash,\n        bytes memory signature\n    )\n        internal\n        view\n        returns (bool isValid);\n\n    /// @dev Verifies that a transaction, with provided order hash, has been signed\n    ///      by the given signer.\n    /// @param transaction The transaction.\n    /// @param transactionHash The hash of the transaction.\n    /// @param signature Proof that the hash has been signed by signer.\n    /// @return isValid True if the signature is valid for the given transaction and signer.\n    function _isValidTransactionWithHashSignature(\n        LibZeroExTransaction.ZeroExTransaction memory transaction,\n        bytes32 transactionHash,\n        bytes memory signature\n    )\n        internal\n        view\n        returns (bool isValid);\n}\n"
        },
        "@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol": {
            "id": 43,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-utils/contracts/src/LibEIP712.sol\";\n\n\nlibrary LibZeroExTransaction {\n\n    using LibZeroExTransaction for ZeroExTransaction;\n\n    // Hash for the EIP712 0x transaction schema\n    // keccak256(abi.encodePacked(\n    //    \"ZeroExTransaction(\",\n    //    \"uint256 salt,\",\n    //    \"uint256 expirationTimeSeconds,\",\n    //    \"uint256 gasPrice,\",\n    //    \"address signerAddress,\",\n    //    \"bytes data\",\n    //    \")\"\n    // ));\n    bytes32 constant internal _EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = 0xec69816980a3a3ca4554410e60253953e9ff375ba4536a98adfa15cc71541508;\n\n    struct ZeroExTransaction {\n        uint256 salt;                   // Arbitrary number to ensure uniqueness of transaction hash.\n        uint256 expirationTimeSeconds;  // Timestamp in seconds at which transaction expires.\n        uint256 gasPrice;               // gasPrice that transaction is required to be executed with.\n        address signerAddress;          // Address of transaction signer.\n        bytes data;                     // AbiV2 encoded calldata.\n    }\n\n    /// @dev Calculates the EIP712 typed data hash of a transaction with a given domain separator.\n    /// @param transaction 0x transaction structure.\n    /// @return EIP712 typed data hash of the transaction.\n    function getTypedDataHash(ZeroExTransaction memory transaction, bytes32 eip712ExchangeDomainHash)\n        internal\n        pure\n        returns (bytes32 transactionHash)\n    {\n        // Hash the transaction with the domain separator of the Exchange contract.\n        transactionHash = LibEIP712.hashEIP712Message(\n            eip712ExchangeDomainHash,\n            transaction.getStructHash()\n        );\n        return transactionHash;\n    }\n\n    /// @dev Calculates EIP712 hash of the 0x transaction struct.\n    /// @param transaction 0x transaction structure.\n    /// @return EIP712 hash of the transaction struct.\n    function getStructHash(ZeroExTransaction memory transaction)\n        internal\n        pure\n        returns (bytes32 result)\n    {\n        bytes32 schemaHash = _EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH;\n        bytes memory data = transaction.data;\n        uint256 salt = transaction.salt;\n        uint256 expirationTimeSeconds = transaction.expirationTimeSeconds;\n        uint256 gasPrice = transaction.gasPrice;\n        address signerAddress = transaction.signerAddress;\n\n        // Assembly for more efficiently computing:\n        // result = keccak256(abi.encodePacked(\n        //     schemaHash,\n        //     salt,\n        //     expirationTimeSeconds,\n        //     gasPrice,\n        //     uint256(signerAddress),\n        //     keccak256(data)\n        // ));\n\n        assembly {\n            // Compute hash of data\n            let dataHash := keccak256(add(data, 32), mload(data))\n\n            // Load free memory pointer\n            let memPtr := mload(64)\n\n            mstore(memPtr, schemaHash)                                                                // hash of schema\n            mstore(add(memPtr, 32), salt)                                                             // salt\n            mstore(add(memPtr, 64), expirationTimeSeconds)                                            // expirationTimeSeconds\n            mstore(add(memPtr, 96), gasPrice)                                                         // gasPrice\n            mstore(add(memPtr, 128), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff))  // signerAddress\n            mstore(add(memPtr, 160), dataHash)                                                        // hash of data\n\n            // Compute hash\n            result := keccak256(memPtr, 192)\n        }\n        return result;\n    }\n}\n"
        },
        "./ITransactions.sol": {
            "id": 18,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol\";\n\n\ncontract ITransactions {\n\n    // TransactionExecution event is emitted when a ZeroExTransaction is executed.\n    event TransactionExecution(bytes32 indexed transactionHash);\n\n    /// @dev Executes an Exchange method call in the context of signer.\n    /// @param transaction 0x transaction containing salt, signerAddress, and data.\n    /// @param signature Proof that transaction has been signed by signer.\n    /// @return ABI encoded return data of the underlying Exchange function call.\n    function executeTransaction(\n        LibZeroExTransaction.ZeroExTransaction memory transaction,\n        bytes memory signature\n    )\n        public\n        payable\n        returns (bytes memory);\n\n    /// @dev Executes a batch of Exchange method calls in the context of signer(s).\n    /// @param transactions Array of 0x transactions containing salt, signerAddress, and data.\n    /// @param signatures Array of proofs that transactions have been signed by signer(s).\n    /// @return Array containing ABI encoded return data for each of the underlying Exchange function calls.\n    function batchExecuteTransactions(\n        LibZeroExTransaction.ZeroExTransaction[] memory transactions,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (bytes[] memory);\n\n    /// @dev The current function will be called in the context of this address (either 0x transaction signer or `msg.sender`).\n    ///      If calling a fill function, this address will represent the taker.\n    ///      If calling a cancel function, this address will represent the maker.\n    /// @return Signer of 0x transaction if entry point is `executeTransaction`.\n    ///         `msg.sender` if entry point is any other function.\n    function _getCurrentContextAddress()\n        internal\n        view\n        returns (address);\n}\n"
        },
        "./IAssetProxyDispatcher.sol": {
            "id": 10,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\n\ncontract IAssetProxyDispatcher {\n\n    // Logs registration of new asset proxy\n    event AssetProxyRegistered(\n        bytes4 id,              // Id of new registered AssetProxy.\n        address assetProxy      // Address of new registered AssetProxy.\n    );\n\n    /// @dev Registers an asset proxy to its asset proxy id.\n    ///      Once an asset proxy is registered, it cannot be unregistered.\n    /// @param assetProxy Address of new asset proxy to register.\n    function registerAssetProxy(address assetProxy)\n        external;\n\n    /// @dev Gets an asset proxy.\n    /// @param assetProxyId Id of the asset proxy.\n    /// @return The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered.\n    function getAssetProxy(bytes4 assetProxyId)\n        external\n        view\n        returns (address);\n}\n"
        },
        "./IWrapperFunctions.sol": {
            "id": 21,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-exchange-libs/contracts/src/LibOrder.sol\";\nimport \"@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol\";\n\n\ncontract IWrapperFunctions {\n\n    /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.\n    /// @param order Order struct containing order specifications.\n    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n    /// @param signature Proof that order has been created by maker.\n    function fillOrKillOrder(\n        LibOrder.Order memory order,\n        uint256 takerAssetFillAmount,\n        bytes memory signature\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults memory fillResults);\n\n    /// @dev Executes multiple calls of fillOrder.\n    /// @param orders Array of order specifications.\n    /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.\n    /// @param signatures Proofs that orders have been created by makers.\n    /// @return Array of amounts filled and fees paid by makers and taker.\n    function batchFillOrders(\n        LibOrder.Order[] memory orders,\n        uint256[] memory takerAssetFillAmounts,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults[] memory fillResults);\n\n    /// @dev Executes multiple calls of fillOrKillOrder.\n    /// @param orders Array of order specifications.\n    /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.\n    /// @param signatures Proofs that orders have been created by makers.\n    /// @return Array of amounts filled and fees paid by makers and taker.\n    function batchFillOrKillOrders(\n        LibOrder.Order[] memory orders,\n        uint256[] memory takerAssetFillAmounts,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults[] memory fillResults);\n\n    /// @dev Executes multiple calls of fillOrder. If any fill reverts, the error is caught and ignored.\n    /// @param orders Array of order specifications.\n    /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.\n    /// @param signatures Proofs that orders have been created by makers.\n    /// @return Array of amounts filled and fees paid by makers and taker.\n    function batchFillOrdersNoThrow(\n        LibOrder.Order[] memory orders,\n        uint256[] memory takerAssetFillAmounts,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults[] memory fillResults);\n\n    /// @dev Executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n    ///      If any fill reverts, the error is caught and ignored.\n    ///      NOTE: This function does not enforce that the takerAsset is the same for each order.\n    /// @param orders Array of order specifications.\n    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n    /// @param signatures Proofs that orders have been signed by makers.\n    /// @return Amounts filled and fees paid by makers and taker.\n    function marketSellOrdersNoThrow(\n        LibOrder.Order[] memory orders,\n        uint256 takerAssetFillAmount,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults memory fillResults);\n\n    /// @dev Executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.\n    ///      If any fill reverts, the error is caught and ignored.\n    ///      NOTE: This function does not enforce that the makerAsset is the same for each order.\n    /// @param orders Array of order specifications.\n    /// @param makerAssetFillAmount Desired amount of makerAsset to buy.\n    /// @param signatures Proofs that orders have been signed by makers.\n    /// @return Amounts filled and fees paid by makers and taker.\n    function marketBuyOrdersNoThrow(\n        LibOrder.Order[] memory orders,\n        uint256 makerAssetFillAmount,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults memory fillResults);\n\n    /// @dev Calls marketSellOrdersNoThrow then reverts if < takerAssetFillAmount has been sold.\n    ///      NOTE: This function does not enforce that the takerAsset is the same for each order.\n    /// @param orders Array of order specifications.\n    /// @param takerAssetFillAmount Minimum amount of takerAsset to sell.\n    /// @param signatures Proofs that orders have been signed by makers.\n    /// @return Amounts filled and fees paid by makers and taker.\n    function marketSellOrdersFillOrKill(\n        LibOrder.Order[] memory orders,\n        uint256 takerAssetFillAmount,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults memory fillResults);\n\n    /// @dev Calls marketBuyOrdersNoThrow then reverts if < makerAssetFillAmount has been bought.\n    ///      NOTE: This function does not enforce that the makerAsset is the same for each order.\n    /// @param orders Array of order specifications.\n    /// @param makerAssetFillAmount Minimum amount of makerAsset to buy.\n    /// @param signatures Proofs that orders have been signed by makers.\n    /// @return Amounts filled and fees paid by makers and taker.\n    function marketBuyOrdersFillOrKill(\n        LibOrder.Order[] memory orders,\n        uint256 makerAssetFillAmount,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults memory fillResults);\n\n    /// @dev Executes multiple calls of cancelOrder.\n    /// @param orders Array of order specifications.\n    function batchCancelOrders(LibOrder.Order[] memory orders)\n        public\n        payable;\n}\n"
        },
        "./ITransferSimulator.sol": {
            "id": 19,
            "content": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\n\ncontract ITransferSimulator {\n\n    /// @dev This function may be used to simulate any amount of transfers\n    /// As they would occur through the Exchange contract. Note that this function\n    /// will always revert, even if all transfers are successful. However, it may\n    /// be used with eth_call or with a try/catch pattern in order to simulate\n    /// the results of the transfers.\n    /// @param assetData Array of asset details, each encoded per the AssetProxy contract specification.\n    /// @param fromAddresses Array containing the `from` addresses that correspond with each transfer.\n    /// @param toAddresses Array containing the `to` addresses that correspond with each transfer.\n    /// @param amounts Array containing the amounts that correspond to each transfer.\n    /// @return This function does not return a value. However, it will always revert with\n    /// `Error(\"TRANSFERS_SUCCESSFUL\")` if all of the transfers were successful.\n    function simulateDispatchTransferFromCalls(\n        bytes[] memory assetData,\n        address[] memory fromAddresses,\n        address[] memory toAddresses,\n        uint256[] memory amounts\n    )\n        public;\n}\n"
        }
    },
    "sourceCodes": {
        "./IExchange.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"./IExchangeCore.sol\";\nimport \"./IProtocolFees.sol\";\nimport \"./IMatchOrders.sol\";\nimport \"./ISignatureValidator.sol\";\nimport \"./ITransactions.sol\";\nimport \"./IAssetProxyDispatcher.sol\";\nimport \"./IWrapperFunctions.sol\";\nimport \"./ITransferSimulator.sol\";\n\n\n// solhint-disable no-empty-blocks\ncontract IExchange is\n    IProtocolFees,\n    IExchangeCore,\n    IMatchOrders,\n    ISignatureValidator,\n    ITransactions,\n    IAssetProxyDispatcher,\n    ITransferSimulator,\n    IWrapperFunctions\n{}\n",
        "./IExchangeCore.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-exchange-libs/contracts/src/LibOrder.sol\";\nimport \"@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol\";\n\n\ncontract IExchangeCore {\n\n    // Fill event is emitted whenever an order is filled.\n    event Fill(\n        address indexed makerAddress,         // Address that created the order.\n        address indexed feeRecipientAddress,  // Address that received fees.\n        bytes makerAssetData,                 // Encoded data specific to makerAsset.\n        bytes takerAssetData,                 // Encoded data specific to takerAsset.\n        bytes makerFeeAssetData,              // Encoded data specific to makerFeeAsset.\n        bytes takerFeeAssetData,              // Encoded data specific to takerFeeAsset.\n        bytes32 indexed orderHash,            // EIP712 hash of order (see LibOrder.getTypedDataHash).\n        address takerAddress,                 // Address that filled the order.\n        address senderAddress,                // Address that called the Exchange contract (msg.sender).\n        uint256 makerAssetFilledAmount,       // Amount of makerAsset sold by maker and bought by taker.\n        uint256 takerAssetFilledAmount,       // Amount of takerAsset sold by taker and bought by maker.\n        uint256 makerFeePaid,                 // Amount of makerFeeAssetData paid to feeRecipient by maker.\n        uint256 takerFeePaid,                 // Amount of takerFeeAssetData paid to feeRecipient by taker.\n        uint256 protocolFeePaid               // Amount of eth or weth paid to the staking contract.\n    );\n\n    // Cancel event is emitted whenever an individual order is cancelled.\n    event Cancel(\n        address indexed makerAddress,         // Address that created the order.\n        address indexed feeRecipientAddress,  // Address that would have recieved fees if order was filled.\n        bytes makerAssetData,                 // Encoded data specific to makerAsset.\n        bytes takerAssetData,                 // Encoded data specific to takerAsset.\n        address senderAddress,                // Address that called the Exchange contract (msg.sender).\n        bytes32 indexed orderHash             // EIP712 hash of order (see LibOrder.getTypedDataHash).\n    );\n\n    // CancelUpTo event is emitted whenever `cancelOrdersUpTo` is executed succesfully.\n    event CancelUpTo(\n        address indexed makerAddress,         // Orders cancelled must have been created by this address.\n        address indexed orderSenderAddress,   // Orders cancelled must have a `senderAddress` equal to this address.\n        uint256 orderEpoch                    // Orders with specified makerAddress and senderAddress with a salt less than this value are considered cancelled.\n    );\n\n    /// @dev Cancels all orders created by makerAddress with a salt less than or equal to the targetOrderEpoch\n    ///      and senderAddress equal to msg.sender (or null address if msg.sender == makerAddress).\n    /// @param targetOrderEpoch Orders created with a salt less or equal to this value will be cancelled.\n    function cancelOrdersUpTo(uint256 targetOrderEpoch)\n        external\n        payable;\n\n    /// @dev Fills the input order.\n    /// @param order Order struct containing order specifications.\n    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n    /// @param signature Proof that order has been created by maker.\n    /// @return Amounts filled and fees paid by maker and taker.\n    function fillOrder(\n        LibOrder.Order memory order,\n        uint256 takerAssetFillAmount,\n        bytes memory signature\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults memory fillResults);\n\n    /// @dev After calling, the order can not be filled anymore.\n    /// @param order Order struct containing order specifications.\n    function cancelOrder(LibOrder.Order memory order)\n        public\n        payable;\n\n    /// @dev Gets information about an order: status, hash, and amount filled.\n    /// @param order Order to gather information on.\n    /// @return OrderInfo Information about the order and its state.\n    ///                   See LibOrder.OrderInfo for a complete description.\n    function getOrderInfo(LibOrder.Order memory order)\n        public\n        view\n        returns (LibOrder.OrderInfo memory orderInfo);\n}\n",
        "@0x/contracts-exchange-libs/contracts/src/LibOrder.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\nimport \"@0x/contracts-utils/contracts/src/LibEIP712.sol\";\n\n\nlibrary LibOrder {\n\n    using LibOrder for Order;\n\n    // Hash for the EIP712 Order Schema:\n    // keccak256(abi.encodePacked(\n    //     \"Order(\",\n    //     \"address makerAddress,\",\n    //     \"address takerAddress,\",\n    //     \"address feeRecipientAddress,\",\n    //     \"address senderAddress,\",\n    //     \"uint256 makerAssetAmount,\",\n    //     \"uint256 takerAssetAmount,\",\n    //     \"uint256 makerFee,\",\n    //     \"uint256 takerFee,\",\n    //     \"uint256 expirationTimeSeconds,\",\n    //     \"uint256 salt,\",\n    //     \"bytes makerAssetData,\",\n    //     \"bytes takerAssetData,\",\n    //     \"bytes makerFeeAssetData,\",\n    //     \"bytes takerFeeAssetData\",\n    //     \")\"\n    // ))\n    bytes32 constant internal _EIP712_ORDER_SCHEMA_HASH =\n        0xf80322eb8376aafb64eadf8f0d7623f22130fd9491a221e902b713cb984a7534;\n\n    // A valid order remains fillable until it is expired, fully filled, or cancelled.\n    // An order's status is unaffected by external factors, like account balances.\n    enum OrderStatus {\n        INVALID,                     // Default value\n        INVALID_MAKER_ASSET_AMOUNT,  // Order does not have a valid maker asset amount\n        INVALID_TAKER_ASSET_AMOUNT,  // Order does not have a valid taker asset amount\n        FILLABLE,                    // Order is fillable\n        EXPIRED,                     // Order has already expired\n        FULLY_FILLED,                // Order is fully filled\n        CANCELLED                    // Order has been cancelled\n    }\n\n    // solhint-disable max-line-length\n    /// @dev Canonical order structure.\n    struct Order {\n        address makerAddress;           // Address that created the order.\n        address takerAddress;           // Address that is allowed to fill the order. If set to 0, any address is allowed to fill the order.\n        address feeRecipientAddress;    // Address that will recieve fees when order is filled.\n        address senderAddress;          // Address that is allowed to call Exchange contract methods that affect this order. If set to 0, any address is allowed to call these methods.\n        uint256 makerAssetAmount;       // Amount of makerAsset being offered by maker. Must be greater than 0.\n        uint256 takerAssetAmount;       // Amount of takerAsset being bid on by maker. Must be greater than 0.\n        uint256 makerFee;               // Fee paid to feeRecipient by maker when order is filled.\n        uint256 takerFee;               // Fee paid to feeRecipient by taker when order is filled.\n        uint256 expirationTimeSeconds;  // Timestamp in seconds at which order expires.\n        uint256 salt;                   // Arbitrary number to facilitate uniqueness of the order's hash.\n        bytes makerAssetData;           // Encoded data that can be decoded by a specified proxy contract when transferring makerAsset. The leading bytes4 references the id of the asset proxy.\n        bytes takerAssetData;           // Encoded data that can be decoded by a specified proxy contract when transferring takerAsset. The leading bytes4 references the id of the asset proxy.\n        bytes makerFeeAssetData;        // Encoded data that can be decoded by a specified proxy contract when transferring makerFeeAsset. The leading bytes4 references the id of the asset proxy.\n        bytes takerFeeAssetData;        // Encoded data that can be decoded by a specified proxy contract when transferring takerFeeAsset. The leading bytes4 references the id of the asset proxy.\n    }\n    // solhint-enable max-line-length\n\n    /// @dev Order information returned by `getOrderInfo()`.\n    struct OrderInfo {\n        OrderStatus orderStatus;                    // Status that describes order's validity and fillability.\n        bytes32 orderHash;                    // EIP712 typed data hash of the order (see LibOrder.getTypedDataHash).\n        uint256 orderTakerAssetFilledAmount;  // Amount of order that has already been filled.\n    }\n\n    /// @dev Calculates the EIP712 typed data hash of an order with a given domain separator.\n    /// @param order The order structure.\n    /// @return EIP712 typed data hash of the order.\n    function getTypedDataHash(Order memory order, bytes32 eip712ExchangeDomainHash)\n        internal\n        pure\n        returns (bytes32 orderHash)\n    {\n        orderHash = LibEIP712.hashEIP712Message(\n            eip712ExchangeDomainHash,\n            order.getStructHash()\n        );\n        return orderHash;\n    }\n\n    /// @dev Calculates EIP712 hash of the order struct.\n    /// @param order The order structure.\n    /// @return EIP712 hash of the order struct.\n    function getStructHash(Order memory order)\n        internal\n        pure\n        returns (bytes32 result)\n    {\n        bytes32 schemaHash = _EIP712_ORDER_SCHEMA_HASH;\n        bytes memory makerAssetData = order.makerAssetData;\n        bytes memory takerAssetData = order.takerAssetData;\n        bytes memory makerFeeAssetData = order.makerFeeAssetData;\n        bytes memory takerFeeAssetData = order.takerFeeAssetData;\n\n        // Assembly for more efficiently computing:\n        // keccak256(abi.encodePacked(\n        //     EIP712_ORDER_SCHEMA_HASH,\n        //     uint256(order.makerAddress),\n        //     uint256(order.takerAddress),\n        //     uint256(order.feeRecipientAddress),\n        //     uint256(order.senderAddress),\n        //     order.makerAssetAmount,\n        //     order.takerAssetAmount,\n        //     order.makerFee,\n        //     order.takerFee,\n        //     order.expirationTimeSeconds,\n        //     order.salt,\n        //     keccak256(order.makerAssetData),\n        //     keccak256(order.takerAssetData),\n        //     keccak256(order.makerFeeAssetData),\n        //     keccak256(order.takerFeeAssetData)\n        // ));\n\n        assembly {\n            // Assert order offset (this is an internal error that should never be triggered)\n            if lt(order, 32) {\n                invalid()\n            }\n\n            // Calculate memory addresses that will be swapped out before hashing\n            let pos1 := sub(order, 32)\n            let pos2 := add(order, 320)\n            let pos3 := add(order, 352)\n            let pos4 := add(order, 384)\n            let pos5 := add(order, 416)\n\n            // Backup\n            let temp1 := mload(pos1)\n            let temp2 := mload(pos2)\n            let temp3 := mload(pos3)\n            let temp4 := mload(pos4)\n            let temp5 := mload(pos5)\n\n            // Hash in place\n            mstore(pos1, schemaHash)\n            mstore(pos2, keccak256(add(makerAssetData, 32), mload(makerAssetData)))        // store hash of makerAssetData\n            mstore(pos3, keccak256(add(takerAssetData, 32), mload(takerAssetData)))        // store hash of takerAssetData\n            mstore(pos4, keccak256(add(makerFeeAssetData, 32), mload(makerFeeAssetData)))  // store hash of makerFeeAssetData\n            mstore(pos5, keccak256(add(takerFeeAssetData, 32), mload(takerFeeAssetData)))  // store hash of takerFeeAssetData\n            result := keccak256(pos1, 480)\n\n            // Restore\n            mstore(pos1, temp1)\n            mstore(pos2, temp2)\n            mstore(pos3, temp3)\n            mstore(pos4, temp4)\n            mstore(pos5, temp5)\n        }\n        return result;\n    }\n}\n",
        "@0x/contracts-utils/contracts/src/LibEIP712.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\n\nlibrary LibEIP712 {\n\n    // Hash of the EIP712 Domain Separator Schema\n    // keccak256(abi.encodePacked(\n    //     \"EIP712Domain(\",\n    //     \"string name,\",\n    //     \"string version,\",\n    //     \"uint256 chainId,\",\n    //     \"address verifyingContract\",\n    //     \")\"\n    // ))\n    bytes32 constant internal _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;\n\n    /// @dev Calculates a EIP712 domain separator.\n    /// @param name The EIP712 domain name.\n    /// @param version The EIP712 domain version.\n    /// @param verifyingContract The EIP712 verifying contract.\n    /// @return EIP712 domain separator.\n    function hashEIP712Domain(\n        string memory name,\n        string memory version,\n        uint256 chainId,\n        address verifyingContract\n    )\n        internal\n        pure\n        returns (bytes32 result)\n    {\n        bytes32 schemaHash = _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH;\n\n        // Assembly for more efficient computing:\n        // keccak256(abi.encodePacked(\n        //     _EIP712_DOMAIN_SEPARATOR_SCHEMA_HASH,\n        //     keccak256(bytes(name)),\n        //     keccak256(bytes(version)),\n        //     chainId,\n        //     uint256(verifyingContract)\n        // ))\n\n        assembly {\n            // Calculate hashes of dynamic data\n            let nameHash := keccak256(add(name, 32), mload(name))\n            let versionHash := keccak256(add(version, 32), mload(version))\n\n            // Load free memory pointer\n            let memPtr := mload(64)\n\n            // Store params in memory\n            mstore(memPtr, schemaHash)\n            mstore(add(memPtr, 32), nameHash)\n            mstore(add(memPtr, 64), versionHash)\n            mstore(add(memPtr, 96), chainId)\n            mstore(add(memPtr, 128), verifyingContract)\n\n            // Compute hash\n            result := keccak256(memPtr, 160)\n        }\n        return result;\n    }\n\n    /// @dev Calculates EIP712 encoding for a hash struct with a given domain hash.\n    /// @param eip712DomainHash Hash of the domain domain separator data, computed\n    ///                         with getDomainHash().\n    /// @param hashStruct The EIP712 hash struct.\n    /// @return EIP712 hash applied to the given EIP712 Domain.\n    function hashEIP712Message(bytes32 eip712DomainHash, bytes32 hashStruct)\n        internal\n        pure\n        returns (bytes32 result)\n    {\n        // Assembly for more efficient computing:\n        // keccak256(abi.encodePacked(\n        //     EIP191_HEADER,\n        //     EIP712_DOMAIN_HASH,\n        //     hashStruct\n        // ));\n\n        assembly {\n            // Load free memory pointer\n            let memPtr := mload(64)\n\n            mstore(memPtr, 0x1901000000000000000000000000000000000000000000000000000000000000)  // EIP191 header\n            mstore(add(memPtr, 2), eip712DomainHash)                                            // EIP712 domain hash\n            mstore(add(memPtr, 34), hashStruct)                                                 // Hash of struct\n\n            // Compute hash\n            result := keccak256(memPtr, 66)\n        }\n        return result;\n    }\n}\n",
        "@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\nimport \"@0x/contracts-utils/contracts/src/LibSafeMath.sol\";\nimport \"./LibMath.sol\";\nimport \"./LibOrder.sol\";\n\n\nlibrary LibFillResults {\n\n    using LibSafeMath for uint256;\n\n    struct BatchMatchedFillResults {\n        FillResults[] left;              // Fill results for left orders\n        FillResults[] right;             // Fill results for right orders\n        uint256 profitInLeftMakerAsset;  // Profit taken from left makers\n        uint256 profitInRightMakerAsset; // Profit taken from right makers\n    }\n\n    struct FillResults {\n        uint256 makerAssetFilledAmount;  // Total amount of makerAsset(s) filled.\n        uint256 takerAssetFilledAmount;  // Total amount of takerAsset(s) filled.\n        uint256 makerFeePaid;            // Total amount of fees paid by maker(s) to feeRecipient(s).\n        uint256 takerFeePaid;            // Total amount of fees paid by taker to feeRecipients(s).\n        uint256 protocolFeePaid;         // Total amount of fees paid by taker to the staking contract.\n    }\n\n    struct MatchedFillResults {\n        FillResults left;                // Amounts filled and fees paid of left order.\n        FillResults right;               // Amounts filled and fees paid of right order.\n        uint256 profitInLeftMakerAsset;  // Profit taken from the left maker\n        uint256 profitInRightMakerAsset; // Profit taken from the right maker\n    }\n\n    /// @dev Calculates amounts filled and fees paid by maker and taker.\n    /// @param order to be filled.\n    /// @param takerAssetFilledAmount Amount of takerAsset that will be filled.\n    /// @param protocolFeeMultiplier The current protocol fee of the exchange contract.\n    /// @param gasPrice The gasprice of the transaction. This is provided so that the function call can continue\n    ///        to be pure rather than view.\n    /// @return fillResults Amounts filled and fees paid by maker and taker.\n    function calculateFillResults(\n        LibOrder.Order memory order,\n        uint256 takerAssetFilledAmount,\n        uint256 protocolFeeMultiplier,\n        uint256 gasPrice\n    )\n        internal\n        pure\n        returns (FillResults memory fillResults)\n    {\n        // Compute proportional transfer amounts\n        fillResults.takerAssetFilledAmount = takerAssetFilledAmount;\n        fillResults.makerAssetFilledAmount = LibMath.safeGetPartialAmountFloor(\n            takerAssetFilledAmount,\n            order.takerAssetAmount,\n            order.makerAssetAmount\n        );\n        fillResults.makerFeePaid = LibMath.safeGetPartialAmountFloor(\n            takerAssetFilledAmount,\n            order.takerAssetAmount,\n            order.makerFee\n        );\n        fillResults.takerFeePaid = LibMath.safeGetPartialAmountFloor(\n            takerAssetFilledAmount,\n            order.takerAssetAmount,\n            order.takerFee\n        );\n\n        // Compute the protocol fee that should be paid for a single fill.\n        fillResults.protocolFeePaid = gasPrice.safeMul(protocolFeeMultiplier);\n\n        return fillResults;\n    }\n\n    /// @dev Calculates fill amounts for the matched orders.\n    ///      Each order is filled at their respective price point. However, the calculations are\n    ///      carried out as though the orders are both being filled at the right order's price point.\n    ///      The profit made by the leftOrder order goes to the taker (who matched the two orders).\n    /// @param leftOrder First order to match.\n    /// @param rightOrder Second order to match.\n    /// @param leftOrderTakerAssetFilledAmount Amount of left order already filled.\n    /// @param rightOrderTakerAssetFilledAmount Amount of right order already filled.\n    /// @param protocolFeeMultiplier The current protocol fee of the exchange contract.\n    /// @param gasPrice The gasprice of the transaction. This is provided so that the function call can continue\n    ///        to be pure rather than view.\n    /// @param shouldMaximallyFillOrders A value that indicates whether or not this calculation should use\n    ///                                  the maximal fill order matching strategy.\n    /// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders.\n    function calculateMatchedFillResults(\n        LibOrder.Order memory leftOrder,\n        LibOrder.Order memory rightOrder,\n        uint256 leftOrderTakerAssetFilledAmount,\n        uint256 rightOrderTakerAssetFilledAmount,\n        uint256 protocolFeeMultiplier,\n        uint256 gasPrice,\n        bool shouldMaximallyFillOrders\n    )\n        internal\n        pure\n        returns (MatchedFillResults memory matchedFillResults)\n    {\n        // Derive maker asset amounts for left & right orders, given store taker assert amounts\n        uint256 leftTakerAssetAmountRemaining = leftOrder.takerAssetAmount.safeSub(leftOrderTakerAssetFilledAmount);\n        uint256 leftMakerAssetAmountRemaining = LibMath.safeGetPartialAmountFloor(\n            leftOrder.makerAssetAmount,\n            leftOrder.takerAssetAmount,\n            leftTakerAssetAmountRemaining\n        );\n        uint256 rightTakerAssetAmountRemaining = rightOrder.takerAssetAmount.safeSub(rightOrderTakerAssetFilledAmount);\n        uint256 rightMakerAssetAmountRemaining = LibMath.safeGetPartialAmountFloor(\n            rightOrder.makerAssetAmount,\n            rightOrder.takerAssetAmount,\n            rightTakerAssetAmountRemaining\n        );\n\n        // Maximally fill the orders and pay out profits to the matcher in one or both of the maker assets.\n        if (shouldMaximallyFillOrders) {\n            matchedFillResults = _calculateMatchedFillResultsWithMaximalFill(\n                leftOrder,\n                rightOrder,\n                leftMakerAssetAmountRemaining,\n                leftTakerAssetAmountRemaining,\n                rightMakerAssetAmountRemaining,\n                rightTakerAssetAmountRemaining\n            );\n        } else {\n            matchedFillResults = _calculateMatchedFillResults(\n                leftOrder,\n                rightOrder,\n                leftMakerAssetAmountRemaining,\n                leftTakerAssetAmountRemaining,\n                rightMakerAssetAmountRemaining,\n                rightTakerAssetAmountRemaining\n            );\n        }\n\n        // Compute fees for left order\n        matchedFillResults.left.makerFeePaid = LibMath.safeGetPartialAmountFloor(\n            matchedFillResults.left.makerAssetFilledAmount,\n            leftOrder.makerAssetAmount,\n            leftOrder.makerFee\n        );\n        matchedFillResults.left.takerFeePaid = LibMath.safeGetPartialAmountFloor(\n            matchedFillResults.left.takerAssetFilledAmount,\n            leftOrder.takerAssetAmount,\n            leftOrder.takerFee\n        );\n\n        // Compute fees for right order\n        matchedFillResults.right.makerFeePaid = LibMath.safeGetPartialAmountFloor(\n            matchedFillResults.right.makerAssetFilledAmount,\n            rightOrder.makerAssetAmount,\n            rightOrder.makerFee\n        );\n        matchedFillResults.right.takerFeePaid = LibMath.safeGetPartialAmountFloor(\n            matchedFillResults.right.takerAssetFilledAmount,\n            rightOrder.takerAssetAmount,\n            rightOrder.takerFee\n        );\n\n        // Compute the protocol fee that should be paid for a single fill. In this\n        // case this should be made the protocol fee for both the left and right orders.\n        uint256 protocolFee = gasPrice.safeMul(protocolFeeMultiplier);\n        matchedFillResults.left.protocolFeePaid = protocolFee;\n        matchedFillResults.right.protocolFeePaid = protocolFee;\n\n        // Return fill results\n        return matchedFillResults;\n    }\n\n    /// @dev Adds properties of both FillResults instances.\n    /// @param fillResults1 The first FillResults.\n    /// @param fillResults2 The second FillResults.\n    /// @return The sum of both fill results.\n    function addFillResults(\n        FillResults memory fillResults1,\n        FillResults memory fillResults2\n    )\n        internal\n        pure\n        returns (FillResults memory totalFillResults)\n    {\n        totalFillResults.makerAssetFilledAmount = fillResults1.makerAssetFilledAmount.safeAdd(fillResults2.makerAssetFilledAmount);\n        totalFillResults.takerAssetFilledAmount = fillResults1.takerAssetFilledAmount.safeAdd(fillResults2.takerAssetFilledAmount);\n        totalFillResults.makerFeePaid = fillResults1.makerFeePaid.safeAdd(fillResults2.makerFeePaid);\n        totalFillResults.takerFeePaid = fillResults1.takerFeePaid.safeAdd(fillResults2.takerFeePaid);\n        totalFillResults.protocolFeePaid = fillResults1.protocolFeePaid.safeAdd(fillResults2.protocolFeePaid);\n\n        return totalFillResults;\n    }\n\n    /// @dev Calculates part of the matched fill results for a given situation using the fill strategy that only\n    ///      awards profit denominated in the left maker asset.\n    /// @param leftOrder The left order in the order matching situation.\n    /// @param rightOrder The right order in the order matching situation.\n    /// @param leftMakerAssetAmountRemaining The amount of the left order maker asset that can still be filled.\n    /// @param leftTakerAssetAmountRemaining The amount of the left order taker asset that can still be filled.\n    /// @param rightMakerAssetAmountRemaining The amount of the right order maker asset that can still be filled.\n    /// @param rightTakerAssetAmountRemaining The amount of the right order taker asset that can still be filled.\n    /// @return MatchFillResults struct that does not include fees paid.\n    function _calculateMatchedFillResults(\n        LibOrder.Order memory leftOrder,\n        LibOrder.Order memory rightOrder,\n        uint256 leftMakerAssetAmountRemaining,\n        uint256 leftTakerAssetAmountRemaining,\n        uint256 rightMakerAssetAmountRemaining,\n        uint256 rightTakerAssetAmountRemaining\n    )\n        private\n        pure\n        returns (MatchedFillResults memory matchedFillResults)\n    {\n        // Calculate fill results for maker and taker assets: at least one order will be fully filled.\n        // The maximum amount the left maker can buy is `leftTakerAssetAmountRemaining`\n        // The maximum amount the right maker can sell is `rightMakerAssetAmountRemaining`\n        // We have two distinct cases for calculating the fill results:\n        // Case 1.\n        //   If the left maker can buy more than the right maker can sell, then only the right order is fully filled.\n        //   If the left maker can buy exactly what the right maker can sell, then both orders are fully filled.\n        // Case 2.\n        //   If the left maker cannot buy more than the right maker can sell, then only the left order is fully filled.\n        // Case 3.\n        //   If the left maker can buy exactly as much as the right maker can sell, then both orders are fully filled.\n        if (leftTakerAssetAmountRemaining > rightMakerAssetAmountRemaining) {\n            // Case 1: Right order is fully filled\n            matchedFillResults = _calculateCompleteRightFill(\n                leftOrder,\n                rightMakerAssetAmountRemaining,\n                rightTakerAssetAmountRemaining\n            );\n        } else if (leftTakerAssetAmountRemaining < rightMakerAssetAmountRemaining) {\n            // Case 2: Left order is fully filled\n            matchedFillResults.left.makerAssetFilledAmount = leftMakerAssetAmountRemaining;\n            matchedFillResults.left.takerAssetFilledAmount = leftTakerAssetAmountRemaining;\n            matchedFillResults.right.makerAssetFilledAmount = leftTakerAssetAmountRemaining;\n            // Round up to ensure the maker's exchange rate does not exceed the price specified by the order.\n            // We favor the maker when the exchange rate must be rounded.\n            matchedFillResults.right.takerAssetFilledAmount = LibMath.safeGetPartialAmountCeil(\n                rightOrder.takerAssetAmount,\n                rightOrder.makerAssetAmount,\n                leftTakerAssetAmountRemaining // matchedFillResults.right.makerAssetFilledAmount\n            );\n        } else {\n            // leftTakerAssetAmountRemaining == rightMakerAssetAmountRemaining\n            // Case 3: Both orders are fully filled. Technically, this could be captured by the above cases, but\n            //         this calculation will be more precise since it does not include rounding.\n            matchedFillResults = _calculateCompleteFillBoth(\n                leftMakerAssetAmountRemaining,\n                leftTakerAssetAmountRemaining,\n                rightMakerAssetAmountRemaining,\n                rightTakerAssetAmountRemaining\n            );\n        }\n\n        // Calculate amount given to taker\n        matchedFillResults.profitInLeftMakerAsset = matchedFillResults.left.makerAssetFilledAmount.safeSub(\n            matchedFillResults.right.takerAssetFilledAmount\n        );\n\n        return matchedFillResults;\n    }\n\n    /// @dev Calculates part of the matched fill results for a given situation using the maximal fill order matching\n    ///      strategy.\n    /// @param leftOrder The left order in the order matching situation.\n    /// @param rightOrder The right order in the order matching situation.\n    /// @param leftMakerAssetAmountRemaining The amount of the left order maker asset that can still be filled.\n    /// @param leftTakerAssetAmountRemaining The amount of the left order taker asset that can still be filled.\n    /// @param rightMakerAssetAmountRemaining The amount of the right order maker asset that can still be filled.\n    /// @param rightTakerAssetAmountRemaining The amount of the right order taker asset that can still be filled.\n    /// @return MatchFillResults struct that does not include fees paid.\n    function _calculateMatchedFillResultsWithMaximalFill(\n        LibOrder.Order memory leftOrder,\n        LibOrder.Order memory rightOrder,\n        uint256 leftMakerAssetAmountRemaining,\n        uint256 leftTakerAssetAmountRemaining,\n        uint256 rightMakerAssetAmountRemaining,\n        uint256 rightTakerAssetAmountRemaining\n    )\n        private\n        pure\n        returns (MatchedFillResults memory matchedFillResults)\n    {\n        // If a maker asset is greater than the opposite taker asset, than there will be a spread denominated in that maker asset.\n        bool doesLeftMakerAssetProfitExist = leftMakerAssetAmountRemaining > rightTakerAssetAmountRemaining;\n        bool doesRightMakerAssetProfitExist = rightMakerAssetAmountRemaining > leftTakerAssetAmountRemaining;\n\n        // Calculate the maximum fill results for the maker and taker assets. At least one of the orders will be fully filled.\n        //\n        // The maximum that the left maker can possibly buy is the amount that the right order can sell.\n        // The maximum that the right maker can possibly buy is the amount that the left order can sell.\n        //\n        // If the left order is fully filled, profit will be paid out in the left maker asset. If the right order is fully filled,\n        // the profit will be out in the right maker asset.\n        //\n        // There are three cases to consider:\n        // Case 1.\n        //   If the left maker can buy more than the right maker can sell, then only the right order is fully filled.\n        // Case 2.\n        //   If the right maker can buy more than the left maker can sell, then only the right order is fully filled.\n        // Case 3.\n        //   If the right maker can sell the max of what the left maker can buy and the left maker can sell the max of\n        //   what the right maker can buy, then both orders are fully filled.\n        if (leftTakerAssetAmountRemaining > rightMakerAssetAmountRemaining) {\n            // Case 1: Right order is fully filled with the profit paid in the left makerAsset\n            matchedFillResults = _calculateCompleteRightFill(\n                leftOrder,\n                rightMakerAssetAmountRemaining,\n                rightTakerAssetAmountRemaining\n            );\n        } else if (rightTakerAssetAmountRemaining > leftMakerAssetAmountRemaining) {\n            // Case 2: Left order is fully filled with the profit paid in the right makerAsset.\n            matchedFillResults.left.makerAssetFilledAmount = leftMakerAssetAmountRemaining;\n            matchedFillResults.left.takerAssetFilledAmount = leftTakerAssetAmountRemaining;\n            // Round down to ensure the right maker's exchange rate does not exceed the price specified by the order.\n            // We favor the right maker when the exchange rate must be rounded and the profit is being paid in the\n            // right maker asset.\n            matchedFillResults.right.makerAssetFilledAmount = LibMath.safeGetPartialAmountFloor(\n                rightOrder.makerAssetAmount,\n                rightOrder.takerAssetAmount,\n                leftMakerAssetAmountRemaining\n            );\n            matchedFillResults.right.takerAssetFilledAmount = leftMakerAssetAmountRemaining;\n        } else {\n            // Case 3: The right and left orders are fully filled\n            matchedFillResults = _calculateCompleteFillBoth(\n                leftMakerAssetAmountRemaining,\n                leftTakerAssetAmountRemaining,\n                rightMakerAssetAmountRemaining,\n                rightTakerAssetAmountRemaining\n            );\n        }\n\n        // Calculate amount given to taker in the left order's maker asset if the left spread will be part of the profit.\n        if (doesLeftMakerAssetProfitExist) {\n            matchedFillResults.profitInLeftMakerAsset = matchedFillResults.left.makerAssetFilledAmount.safeSub(\n                matchedFillResults.right.takerAssetFilledAmount\n            );\n        }\n\n        // Calculate amount given to taker in the right order's maker asset if the right spread will be part of the profit.\n        if (doesRightMakerAssetProfitExist) {\n            matchedFillResults.profitInRightMakerAsset = matchedFillResults.right.makerAssetFilledAmount.safeSub(\n                matchedFillResults.left.takerAssetFilledAmount\n            );\n        }\n\n        return matchedFillResults;\n    }\n\n    /// @dev Calculates the fill results for the maker and taker in the order matching and writes the results\n    ///      to the fillResults that are being collected on the order. Both orders will be fully filled in this\n    ///      case.\n    /// @param leftMakerAssetAmountRemaining The amount of the left maker asset that is remaining to be filled.\n    /// @param leftTakerAssetAmountRemaining The amount of the left taker asset that is remaining to be filled.\n    /// @param rightMakerAssetAmountRemaining The amount of the right maker asset that is remaining to be filled.\n    /// @param rightTakerAssetAmountRemaining The amount of the right taker asset that is remaining to be filled.\n    /// @return MatchFillResults struct that does not include fees paid or spreads taken.\n    function _calculateCompleteFillBoth(\n        uint256 leftMakerAssetAmountRemaining,\n        uint256 leftTakerAssetAmountRemaining,\n        uint256 rightMakerAssetAmountRemaining,\n        uint256 rightTakerAssetAmountRemaining\n    )\n        private\n        pure\n        returns (MatchedFillResults memory matchedFillResults)\n    {\n        // Calculate the fully filled results for both orders.\n        matchedFillResults.left.makerAssetFilledAmount = leftMakerAssetAmountRemaining;\n        matchedFillResults.left.takerAssetFilledAmount = leftTakerAssetAmountRemaining;\n        matchedFillResults.right.makerAssetFilledAmount = rightMakerAssetAmountRemaining;\n        matchedFillResults.right.takerAssetFilledAmount = rightTakerAssetAmountRemaining;\n\n        return matchedFillResults;\n    }\n\n    /// @dev Calculates the fill results for the maker and taker in the order matching and writes the results\n    ///      to the fillResults that are being collected on the order.\n    /// @param leftOrder The left order that is being maximally filled. All of the information about fill amounts\n    ///                  can be derived from this order and the right asset remaining fields.\n    /// @param rightMakerAssetAmountRemaining The amount of the right maker asset that is remaining to be filled.\n    /// @param rightTakerAssetAmountRemaining The amount of the right taker asset that is remaining to be filled.\n    /// @return MatchFillResults struct that does not include fees paid or spreads taken.\n    function _calculateCompleteRightFill(\n        LibOrder.Order memory leftOrder,\n        uint256 rightMakerAssetAmountRemaining,\n        uint256 rightTakerAssetAmountRemaining\n    )\n        private\n        pure\n        returns (MatchedFillResults memory matchedFillResults)\n    {\n        matchedFillResults.right.makerAssetFilledAmount = rightMakerAssetAmountRemaining;\n        matchedFillResults.right.takerAssetFilledAmount = rightTakerAssetAmountRemaining;\n        matchedFillResults.left.takerAssetFilledAmount = rightMakerAssetAmountRemaining;\n        // Round down to ensure the left maker's exchange rate does not exceed the price specified by the order.\n        // We favor the left maker when the exchange rate must be rounded and the profit is being paid in the\n        // left maker asset.\n        matchedFillResults.left.makerAssetFilledAmount = LibMath.safeGetPartialAmountFloor(\n            leftOrder.makerAssetAmount,\n            leftOrder.takerAssetAmount,\n            rightMakerAssetAmountRemaining\n        );\n\n        return matchedFillResults;\n    }\n}\n",
        "@0x/contracts-utils/contracts/src/LibSafeMath.sol": "pragma solidity ^0.5.9;\n\nimport \"./LibRichErrors.sol\";\nimport \"./LibSafeMathRichErrors.sol\";\n\n\nlibrary LibSafeMath {\n\n    function safeMul(uint256 a, uint256 b)\n        internal\n        pure\n        returns (uint256)\n    {\n        if (a == 0) {\n            return 0;\n        }\n        uint256 c = a * b;\n        if (c / a != b) {\n            LibRichErrors.rrevert(LibSafeMathRichErrors.Uint256BinOpError(\n                LibSafeMathRichErrors.BinOpErrorCodes.MULTIPLICATION_OVERFLOW,\n                a,\n                b\n            ));\n        }\n        return c;\n    }\n\n    function safeDiv(uint256 a, uint256 b)\n        internal\n        pure\n        returns (uint256)\n    {\n        if (b == 0) {\n            LibRichErrors.rrevert(LibSafeMathRichErrors.Uint256BinOpError(\n                LibSafeMathRichErrors.BinOpErrorCodes.DIVISION_BY_ZERO,\n                a,\n                b\n            ));\n        }\n        uint256 c = a / b;\n        return c;\n    }\n\n    function safeSub(uint256 a, uint256 b)\n        internal\n        pure\n        returns (uint256)\n    {\n        if (b > a) {\n            LibRichErrors.rrevert(LibSafeMathRichErrors.Uint256BinOpError(\n                LibSafeMathRichErrors.BinOpErrorCodes.SUBTRACTION_UNDERFLOW,\n                a,\n                b\n            ));\n        }\n        return a - b;\n    }\n\n    function safeAdd(uint256 a, uint256 b)\n        internal\n        pure\n        returns (uint256)\n    {\n        uint256 c = a + b;\n        if (c < a) {\n            LibRichErrors.rrevert(LibSafeMathRichErrors.Uint256BinOpError(\n                LibSafeMathRichErrors.BinOpErrorCodes.ADDITION_OVERFLOW,\n                a,\n                b\n            ));\n        }\n        return c;\n    }\n\n    function max256(uint256 a, uint256 b)\n        internal\n        pure\n        returns (uint256)\n    {\n        return a >= b ? a : b;\n    }\n\n    function min256(uint256 a, uint256 b)\n        internal\n        pure\n        returns (uint256)\n    {\n        return a < b ? a : b;\n    }\n}\n",
        "@0x/contracts-utils/contracts/src/LibRichErrors.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\n\nlibrary LibRichErrors {\n\n    // bytes4(keccak256(\"Error(string)\"))\n    bytes4 internal constant STANDARD_ERROR_SELECTOR =\n        0x08c379a0;\n\n    // solhint-disable func-name-mixedcase\n    /// @dev ABI encode a standard, string revert error payload.\n    ///      This is the same payload that would be included by a `revert(string)`\n    ///      solidity statement. It has the function signature `Error(string)`.\n    /// @param message The error string.\n    /// @return The ABI encoded error.\n    function StandardError(\n        string memory message\n    )\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return abi.encodeWithSelector(\n            STANDARD_ERROR_SELECTOR,\n            bytes(message)\n        );\n    }\n    // solhint-enable func-name-mixedcase\n\n    /// @dev Reverts an encoded rich revert reason `errorData`.\n    /// @param errorData ABI encoded error data.\n    function rrevert(bytes memory errorData)\n        internal\n        pure\n    {\n        assembly {\n            revert(add(errorData, 0x20), mload(errorData))\n        }\n    }\n}\n",
        "@0x/contracts-utils/contracts/src/LibSafeMathRichErrors.sol": "pragma solidity ^0.5.9;\n\n\nlibrary LibSafeMathRichErrors {\n\n    // bytes4(keccak256(\"Uint256BinOpError(uint8,uint256,uint256)\"))\n    bytes4 internal constant UINT256_BINOP_ERROR_SELECTOR =\n        0xe946c1bb;\n\n    // bytes4(keccak256(\"Uint256DowncastError(uint8,uint256)\"))\n    bytes4 internal constant UINT256_DOWNCAST_ERROR_SELECTOR =\n        0xc996af7b;\n\n    enum BinOpErrorCodes {\n        ADDITION_OVERFLOW,\n        MULTIPLICATION_OVERFLOW,\n        SUBTRACTION_UNDERFLOW,\n        DIVISION_BY_ZERO\n    }\n\n    enum DowncastErrorCodes {\n        VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT32,\n        VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT64,\n        VALUE_TOO_LARGE_TO_DOWNCAST_TO_UINT96\n    }\n\n    // solhint-disable func-name-mixedcase\n    function Uint256BinOpError(\n        BinOpErrorCodes errorCode,\n        uint256 a,\n        uint256 b\n    )\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return abi.encodeWithSelector(\n            UINT256_BINOP_ERROR_SELECTOR,\n            errorCode,\n            a,\n            b\n        );\n    }\n\n    function Uint256DowncastError(\n        DowncastErrorCodes errorCode,\n        uint256 a\n    )\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return abi.encodeWithSelector(\n            UINT256_DOWNCAST_ERROR_SELECTOR,\n            errorCode,\n            a\n        );\n    }\n}\n",
        "@0x/contracts-exchange-libs/contracts/src/LibMath.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\nimport \"@0x/contracts-utils/contracts/src/LibSafeMath.sol\";\nimport \"@0x/contracts-utils/contracts/src/LibRichErrors.sol\";\nimport \"./LibMathRichErrors.sol\";\n\n\nlibrary LibMath {\n\n    using LibSafeMath for uint256;\n\n    /// @dev Calculates partial value given a numerator and denominator rounded down.\n    ///      Reverts if rounding error is >= 0.1%\n    /// @param numerator Numerator.\n    /// @param denominator Denominator.\n    /// @param target Value to calculate partial of.\n    /// @return Partial value of target rounded down.\n    function safeGetPartialAmountFloor(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (uint256 partialAmount)\n    {\n        if (isRoundingErrorFloor(\n                numerator,\n                denominator,\n                target\n        )) {\n            LibRichErrors.rrevert(LibMathRichErrors.RoundingError(\n                numerator,\n                denominator,\n                target\n            ));\n        }\n\n        partialAmount = numerator.safeMul(target).safeDiv(denominator);\n        return partialAmount;\n    }\n\n    /// @dev Calculates partial value given a numerator and denominator rounded down.\n    ///      Reverts if rounding error is >= 0.1%\n    /// @param numerator Numerator.\n    /// @param denominator Denominator.\n    /// @param target Value to calculate partial of.\n    /// @return Partial value of target rounded up.\n    function safeGetPartialAmountCeil(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (uint256 partialAmount)\n    {\n        if (isRoundingErrorCeil(\n                numerator,\n                denominator,\n                target\n        )) {\n            LibRichErrors.rrevert(LibMathRichErrors.RoundingError(\n                numerator,\n                denominator,\n                target\n            ));\n        }\n\n        // safeDiv computes `floor(a / b)`. We use the identity (a, b integer):\n        //       ceil(a / b) = floor((a + b - 1) / b)\n        // To implement `ceil(a / b)` using safeDiv.\n        partialAmount = numerator.safeMul(target)\n            .safeAdd(denominator.safeSub(1))\n            .safeDiv(denominator);\n\n        return partialAmount;\n    }\n\n    /// @dev Calculates partial value given a numerator and denominator rounded down.\n    /// @param numerator Numerator.\n    /// @param denominator Denominator.\n    /// @param target Value to calculate partial of.\n    /// @return Partial value of target rounded down.\n    function getPartialAmountFloor(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (uint256 partialAmount)\n    {\n        partialAmount = numerator.safeMul(target).safeDiv(denominator);\n        return partialAmount;\n    }\n\n    /// @dev Calculates partial value given a numerator and denominator rounded down.\n    /// @param numerator Numerator.\n    /// @param denominator Denominator.\n    /// @param target Value to calculate partial of.\n    /// @return Partial value of target rounded up.\n    function getPartialAmountCeil(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (uint256 partialAmount)\n    {\n        // safeDiv computes `floor(a / b)`. We use the identity (a, b integer):\n        //       ceil(a / b) = floor((a + b - 1) / b)\n        // To implement `ceil(a / b)` using safeDiv.\n        partialAmount = numerator.safeMul(target)\n            .safeAdd(denominator.safeSub(1))\n            .safeDiv(denominator);\n\n        return partialAmount;\n    }\n\n    /// @dev Checks if rounding error >= 0.1% when rounding down.\n    /// @param numerator Numerator.\n    /// @param denominator Denominator.\n    /// @param target Value to multiply with numerator/denominator.\n    /// @return Rounding error is present.\n    function isRoundingErrorFloor(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (bool isError)\n    {\n        if (denominator == 0) {\n            LibRichErrors.rrevert(LibMathRichErrors.DivisionByZeroError());\n        }\n\n        // The absolute rounding error is the difference between the rounded\n        // value and the ideal value. The relative rounding error is the\n        // absolute rounding error divided by the absolute value of the\n        // ideal value. This is undefined when the ideal value is zero.\n        //\n        // The ideal value is `numerator * target / denominator`.\n        // Let's call `numerator * target % denominator` the remainder.\n        // The absolute error is `remainder / denominator`.\n        //\n        // When the ideal value is zero, we require the absolute error to\n        // be zero. Fortunately, this is always the case. The ideal value is\n        // zero iff `numerator == 0` and/or `target == 0`. In this case the\n        // remainder and absolute error are also zero.\n        if (target == 0 || numerator == 0) {\n            return false;\n        }\n\n        // Otherwise, we want the relative rounding error to be strictly\n        // less than 0.1%.\n        // The relative error is `remainder / (numerator * target)`.\n        // We want the relative error less than 1 / 1000:\n        //        remainder / (numerator * denominator)  <  1 / 1000\n        // or equivalently:\n        //        1000 * remainder  <  numerator * target\n        // so we have a rounding error iff:\n        //        1000 * remainder  >=  numerator * target\n        uint256 remainder = mulmod(\n            target,\n            numerator,\n            denominator\n        );\n        isError = remainder.safeMul(1000) >= numerator.safeMul(target);\n        return isError;\n    }\n\n    /// @dev Checks if rounding error >= 0.1% when rounding up.\n    /// @param numerator Numerator.\n    /// @param denominator Denominator.\n    /// @param target Value to multiply with numerator/denominator.\n    /// @return Rounding error is present.\n    function isRoundingErrorCeil(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (bool isError)\n    {\n        if (denominator == 0) {\n            LibRichErrors.rrevert(LibMathRichErrors.DivisionByZeroError());\n        }\n\n        // See the comments in `isRoundingError`.\n        if (target == 0 || numerator == 0) {\n            // When either is zero, the ideal value and rounded value are zero\n            // and there is no rounding error. (Although the relative error\n            // is undefined.)\n            return false;\n        }\n        // Compute remainder as before\n        uint256 remainder = mulmod(\n            target,\n            numerator,\n            denominator\n        );\n        remainder = denominator.safeSub(remainder) % denominator;\n        isError = remainder.safeMul(1000) >= numerator.safeMul(target);\n        return isError;\n    }\n}\n",
        "@0x/contracts-exchange-libs/contracts/src/LibMathRichErrors.sol": "pragma solidity ^0.5.9;\n\n\nlibrary LibMathRichErrors {\n\n    // bytes4(keccak256(\"DivisionByZeroError()\"))\n    bytes internal constant DIVISION_BY_ZERO_ERROR =\n        hex\"a791837c\";\n\n    // bytes4(keccak256(\"RoundingError(uint256,uint256,uint256)\"))\n    bytes4 internal constant ROUNDING_ERROR_SELECTOR =\n        0x339f3de2;\n\n    // solhint-disable func-name-mixedcase\n    function DivisionByZeroError()\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return DIVISION_BY_ZERO_ERROR;\n    }\n\n    function RoundingError(\n        uint256 numerator,\n        uint256 denominator,\n        uint256 target\n    )\n        internal\n        pure\n        returns (bytes memory)\n    {\n        return abi.encodeWithSelector(\n            ROUNDING_ERROR_SELECTOR,\n            numerator,\n            denominator,\n            target\n        );\n    }\n}\n",
        "./IProtocolFees.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\n\ncontract IProtocolFees {\n\n    // Logs updates to the protocol fee multiplier.\n    event ProtocolFeeMultiplier(uint256 oldProtocolFeeMultiplier, uint256 updatedProtocolFeeMultiplier);\n\n    // Logs updates to the protocolFeeCollector address.\n    event ProtocolFeeCollectorAddress(address oldProtocolFeeCollector, address updatedProtocolFeeCollector);\n\n    /// @dev Allows the owner to update the protocol fee multiplier.\n    /// @param updatedProtocolFeeMultiplier The updated protocol fee multiplier.\n    function setProtocolFeeMultiplier(uint256 updatedProtocolFeeMultiplier)\n        external;\n\n    /// @dev Allows the owner to update the protocolFeeCollector address.\n    /// @param updatedProtocolFeeCollector The updated protocolFeeCollector contract address.\n    function setProtocolFeeCollectorAddress(address updatedProtocolFeeCollector)\n        external;\n\n    /// @dev Returns the protocolFeeMultiplier\n    function protocolFeeMultiplier()\n        external\n        view\n        returns (uint256);\n\n    /// @dev Returns the protocolFeeCollector address\n    function protocolFeeCollector()\n        external\n        view\n        returns (address);\n}\n",
        "./IMatchOrders.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-exchange-libs/contracts/src/LibOrder.sol\";\nimport \"@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol\";\n\n\ncontract IMatchOrders {\n\n    /// @dev Match complementary orders that have a profitable spread.\n    ///      Each order is filled at their respective price point, and\n    ///      the matcher receives a profit denominated in the left maker asset.\n    /// @param leftOrders Set of orders with the same maker / taker asset.\n    /// @param rightOrders Set of orders to match against `leftOrders`\n    /// @param leftSignatures Proof that left orders were created by the left makers.\n    /// @param rightSignatures Proof that right orders were created by the right makers.\n    /// @return batchMatchedFillResults Amounts filled and profit generated.\n    function batchMatchOrders(\n        LibOrder.Order[] memory leftOrders,\n        LibOrder.Order[] memory rightOrders,\n        bytes[] memory leftSignatures,\n        bytes[] memory rightSignatures\n    )\n        public\n        payable\n        returns (LibFillResults.BatchMatchedFillResults memory batchMatchedFillResults);\n\n    /// @dev Match complementary orders that have a profitable spread.\n    ///      Each order is maximally filled at their respective price point, and\n    ///      the matcher receives a profit denominated in either the left maker asset,\n    ///      right maker asset, or a combination of both.\n    /// @param leftOrders Set of orders with the same maker / taker asset.\n    /// @param rightOrders Set of orders to match against `leftOrders`\n    /// @param leftSignatures Proof that left orders were created by the left makers.\n    /// @param rightSignatures Proof that right orders were created by the right makers.\n    /// @return batchMatchedFillResults Amounts filled and profit generated.\n    function batchMatchOrdersWithMaximalFill(\n        LibOrder.Order[] memory leftOrders,\n        LibOrder.Order[] memory rightOrders,\n        bytes[] memory leftSignatures,\n        bytes[] memory rightSignatures\n    )\n        public\n        payable\n        returns (LibFillResults.BatchMatchedFillResults memory batchMatchedFillResults);\n\n    /// @dev Match two complementary orders that have a profitable spread.\n    ///      Each order is filled at their respective price point. However, the calculations are\n    ///      carried out as though the orders are both being filled at the right order's price point.\n    ///      The profit made by the left order goes to the taker (who matched the two orders).\n    /// @param leftOrder First order to match.\n    /// @param rightOrder Second order to match.\n    /// @param leftSignature Proof that order was created by the left maker.\n    /// @param rightSignature Proof that order was created by the right maker.\n    /// @return matchedFillResults Amounts filled and fees paid by maker and taker of matched orders.\n    function matchOrders(\n        LibOrder.Order memory leftOrder,\n        LibOrder.Order memory rightOrder,\n        bytes memory leftSignature,\n        bytes memory rightSignature\n    )\n        public\n        payable\n        returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n\n    /// @dev Match two complementary orders that have a profitable spread.\n    ///      Each order is maximally filled at their respective price point, and\n    ///      the matcher receives a profit denominated in either the left maker asset,\n    ///      right maker asset, or a combination of both.\n    /// @param leftOrder First order to match.\n    /// @param rightOrder Second order to match.\n    /// @param leftSignature Proof that order was created by the left maker.\n    /// @param rightSignature Proof that order was created by the right maker.\n    /// @return matchedFillResults Amounts filled by maker and taker of matched orders.\n    function matchOrdersWithMaximalFill(\n        LibOrder.Order memory leftOrder,\n        LibOrder.Order memory rightOrder,\n        bytes memory leftSignature,\n        bytes memory rightSignature\n    )\n        public\n        payable\n        returns (LibFillResults.MatchedFillResults memory matchedFillResults);\n}\n",
        "./ISignatureValidator.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-exchange-libs/contracts/src/LibOrder.sol\";\nimport \"@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol\";\n\n\ncontract ISignatureValidator {\n\n   // Allowed signature types.\n    enum SignatureType {\n        Illegal,                     // 0x00, default value\n        Invalid,                     // 0x01\n        EIP712,                      // 0x02\n        EthSign,                     // 0x03\n        Wallet,                      // 0x04\n        Validator,                   // 0x05\n        PreSigned,                   // 0x06\n        EIP1271Wallet,               // 0x07\n        NSignatureTypes              // 0x08, number of signature types. Always leave at end.\n    }\n\n    event SignatureValidatorApproval(\n        address indexed signerAddress,     // Address that approves or disapproves a contract to verify signatures.\n        address indexed validatorAddress,  // Address of signature validator contract.\n        bool isApproved                    // Approval or disapproval of validator contract.\n    );\n\n    /// @dev Approves a hash on-chain.\n    ///      After presigning a hash, the preSign signature type will become valid for that hash and signer.\n    /// @param hash Any 32-byte hash.\n    function preSign(bytes32 hash)\n        external\n        payable;\n\n    /// @dev Approves/unnapproves a Validator contract to verify signatures on signer's behalf.\n    /// @param validatorAddress Address of Validator contract.\n    /// @param approval Approval or disapproval of  Validator contract.\n    function setSignatureValidatorApproval(\n        address validatorAddress,\n        bool approval\n    )\n        external\n        payable;\n\n    /// @dev Verifies that a hash has been signed by the given signer.\n    /// @param hash Any 32-byte hash.\n    /// @param signature Proof that the hash has been signed by signer.\n    /// @return isValid `true` if the signature is valid for the given hash and signer.\n    function isValidHashSignature(\n        bytes32 hash,\n        address signerAddress,\n        bytes memory signature\n    )\n        public\n        view\n        returns (bool isValid);\n\n    /// @dev Verifies that a signature for an order is valid.\n    /// @param order The order.\n    /// @param signature Proof that the order has been signed by signer.\n    /// @return isValid true if the signature is valid for the given order and signer.\n    function isValidOrderSignature(\n        LibOrder.Order memory order,\n        bytes memory signature\n    )\n        public\n        view\n        returns (bool isValid);\n\n    /// @dev Verifies that a signature for a transaction is valid.\n    /// @param transaction The transaction.\n    /// @param signature Proof that the order has been signed by signer.\n    /// @return isValid true if the signature is valid for the given transaction and signer.\n    function isValidTransactionSignature(\n        LibZeroExTransaction.ZeroExTransaction memory transaction,\n        bytes memory signature\n    )\n        public\n        view\n        returns (bool isValid);\n\n    /// @dev Verifies that an order, with provided order hash, has been signed\n    ///      by the given signer.\n    /// @param order The order.\n    /// @param orderHash The hash of the order.\n    /// @param signature Proof that the hash has been signed by signer.\n    /// @return isValid True if the signature is valid for the given order and signer.\n    function _isValidOrderWithHashSignature(\n        LibOrder.Order memory order,\n        bytes32 orderHash,\n        bytes memory signature\n    )\n        internal\n        view\n        returns (bool isValid);\n\n    /// @dev Verifies that a transaction, with provided order hash, has been signed\n    ///      by the given signer.\n    /// @param transaction The transaction.\n    /// @param transactionHash The hash of the transaction.\n    /// @param signature Proof that the hash has been signed by signer.\n    /// @return isValid True if the signature is valid for the given transaction and signer.\n    function _isValidTransactionWithHashSignature(\n        LibZeroExTransaction.ZeroExTransaction memory transaction,\n        bytes32 transactionHash,\n        bytes memory signature\n    )\n        internal\n        view\n        returns (bool isValid);\n}\n",
        "@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-utils/contracts/src/LibEIP712.sol\";\n\n\nlibrary LibZeroExTransaction {\n\n    using LibZeroExTransaction for ZeroExTransaction;\n\n    // Hash for the EIP712 0x transaction schema\n    // keccak256(abi.encodePacked(\n    //    \"ZeroExTransaction(\",\n    //    \"uint256 salt,\",\n    //    \"uint256 expirationTimeSeconds,\",\n    //    \"uint256 gasPrice,\",\n    //    \"address signerAddress,\",\n    //    \"bytes data\",\n    //    \")\"\n    // ));\n    bytes32 constant internal _EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH = 0xec69816980a3a3ca4554410e60253953e9ff375ba4536a98adfa15cc71541508;\n\n    struct ZeroExTransaction {\n        uint256 salt;                   // Arbitrary number to ensure uniqueness of transaction hash.\n        uint256 expirationTimeSeconds;  // Timestamp in seconds at which transaction expires.\n        uint256 gasPrice;               // gasPrice that transaction is required to be executed with.\n        address signerAddress;          // Address of transaction signer.\n        bytes data;                     // AbiV2 encoded calldata.\n    }\n\n    /// @dev Calculates the EIP712 typed data hash of a transaction with a given domain separator.\n    /// @param transaction 0x transaction structure.\n    /// @return EIP712 typed data hash of the transaction.\n    function getTypedDataHash(ZeroExTransaction memory transaction, bytes32 eip712ExchangeDomainHash)\n        internal\n        pure\n        returns (bytes32 transactionHash)\n    {\n        // Hash the transaction with the domain separator of the Exchange contract.\n        transactionHash = LibEIP712.hashEIP712Message(\n            eip712ExchangeDomainHash,\n            transaction.getStructHash()\n        );\n        return transactionHash;\n    }\n\n    /// @dev Calculates EIP712 hash of the 0x transaction struct.\n    /// @param transaction 0x transaction structure.\n    /// @return EIP712 hash of the transaction struct.\n    function getStructHash(ZeroExTransaction memory transaction)\n        internal\n        pure\n        returns (bytes32 result)\n    {\n        bytes32 schemaHash = _EIP712_ZEROEX_TRANSACTION_SCHEMA_HASH;\n        bytes memory data = transaction.data;\n        uint256 salt = transaction.salt;\n        uint256 expirationTimeSeconds = transaction.expirationTimeSeconds;\n        uint256 gasPrice = transaction.gasPrice;\n        address signerAddress = transaction.signerAddress;\n\n        // Assembly for more efficiently computing:\n        // result = keccak256(abi.encodePacked(\n        //     schemaHash,\n        //     salt,\n        //     expirationTimeSeconds,\n        //     gasPrice,\n        //     uint256(signerAddress),\n        //     keccak256(data)\n        // ));\n\n        assembly {\n            // Compute hash of data\n            let dataHash := keccak256(add(data, 32), mload(data))\n\n            // Load free memory pointer\n            let memPtr := mload(64)\n\n            mstore(memPtr, schemaHash)                                                                // hash of schema\n            mstore(add(memPtr, 32), salt)                                                             // salt\n            mstore(add(memPtr, 64), expirationTimeSeconds)                                            // expirationTimeSeconds\n            mstore(add(memPtr, 96), gasPrice)                                                         // gasPrice\n            mstore(add(memPtr, 128), and(signerAddress, 0xffffffffffffffffffffffffffffffffffffffff))  // signerAddress\n            mstore(add(memPtr, 160), dataHash)                                                        // hash of data\n\n            // Compute hash\n            result := keccak256(memPtr, 192)\n        }\n        return result;\n    }\n}\n",
        "./ITransactions.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-exchange-libs/contracts/src/LibZeroExTransaction.sol\";\n\n\ncontract ITransactions {\n\n    // TransactionExecution event is emitted when a ZeroExTransaction is executed.\n    event TransactionExecution(bytes32 indexed transactionHash);\n\n    /// @dev Executes an Exchange method call in the context of signer.\n    /// @param transaction 0x transaction containing salt, signerAddress, and data.\n    /// @param signature Proof that transaction has been signed by signer.\n    /// @return ABI encoded return data of the underlying Exchange function call.\n    function executeTransaction(\n        LibZeroExTransaction.ZeroExTransaction memory transaction,\n        bytes memory signature\n    )\n        public\n        payable\n        returns (bytes memory);\n\n    /// @dev Executes a batch of Exchange method calls in the context of signer(s).\n    /// @param transactions Array of 0x transactions containing salt, signerAddress, and data.\n    /// @param signatures Array of proofs that transactions have been signed by signer(s).\n    /// @return Array containing ABI encoded return data for each of the underlying Exchange function calls.\n    function batchExecuteTransactions(\n        LibZeroExTransaction.ZeroExTransaction[] memory transactions,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (bytes[] memory);\n\n    /// @dev The current function will be called in the context of this address (either 0x transaction signer or `msg.sender`).\n    ///      If calling a fill function, this address will represent the taker.\n    ///      If calling a cancel function, this address will represent the maker.\n    /// @return Signer of 0x transaction if entry point is `executeTransaction`.\n    ///         `msg.sender` if entry point is any other function.\n    function _getCurrentContextAddress()\n        internal\n        view\n        returns (address);\n}\n",
        "./IAssetProxyDispatcher.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\n\n\ncontract IAssetProxyDispatcher {\n\n    // Logs registration of new asset proxy\n    event AssetProxyRegistered(\n        bytes4 id,              // Id of new registered AssetProxy.\n        address assetProxy      // Address of new registered AssetProxy.\n    );\n\n    /// @dev Registers an asset proxy to its asset proxy id.\n    ///      Once an asset proxy is registered, it cannot be unregistered.\n    /// @param assetProxy Address of new asset proxy to register.\n    function registerAssetProxy(address assetProxy)\n        external;\n\n    /// @dev Gets an asset proxy.\n    /// @param assetProxyId Id of the asset proxy.\n    /// @return The asset proxy registered to assetProxyId. Returns 0x0 if no proxy is registered.\n    function getAssetProxy(bytes4 assetProxyId)\n        external\n        view\n        returns (address);\n}\n",
        "./IWrapperFunctions.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\nimport \"@0x/contracts-exchange-libs/contracts/src/LibOrder.sol\";\nimport \"@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol\";\n\n\ncontract IWrapperFunctions {\n\n    /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.\n    /// @param order Order struct containing order specifications.\n    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n    /// @param signature Proof that order has been created by maker.\n    function fillOrKillOrder(\n        LibOrder.Order memory order,\n        uint256 takerAssetFillAmount,\n        bytes memory signature\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults memory fillResults);\n\n    /// @dev Executes multiple calls of fillOrder.\n    /// @param orders Array of order specifications.\n    /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.\n    /// @param signatures Proofs that orders have been created by makers.\n    /// @return Array of amounts filled and fees paid by makers and taker.\n    function batchFillOrders(\n        LibOrder.Order[] memory orders,\n        uint256[] memory takerAssetFillAmounts,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults[] memory fillResults);\n\n    /// @dev Executes multiple calls of fillOrKillOrder.\n    /// @param orders Array of order specifications.\n    /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.\n    /// @param signatures Proofs that orders have been created by makers.\n    /// @return Array of amounts filled and fees paid by makers and taker.\n    function batchFillOrKillOrders(\n        LibOrder.Order[] memory orders,\n        uint256[] memory takerAssetFillAmounts,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults[] memory fillResults);\n\n    /// @dev Executes multiple calls of fillOrder. If any fill reverts, the error is caught and ignored.\n    /// @param orders Array of order specifications.\n    /// @param takerAssetFillAmounts Array of desired amounts of takerAsset to sell in orders.\n    /// @param signatures Proofs that orders have been created by makers.\n    /// @return Array of amounts filled and fees paid by makers and taker.\n    function batchFillOrdersNoThrow(\n        LibOrder.Order[] memory orders,\n        uint256[] memory takerAssetFillAmounts,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults[] memory fillResults);\n\n    /// @dev Executes multiple calls of fillOrder until total amount of takerAsset is sold by taker.\n    ///      If any fill reverts, the error is caught and ignored.\n    ///      NOTE: This function does not enforce that the takerAsset is the same for each order.\n    /// @param orders Array of order specifications.\n    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.\n    /// @param signatures Proofs that orders have been signed by makers.\n    /// @return Amounts filled and fees paid by makers and taker.\n    function marketSellOrdersNoThrow(\n        LibOrder.Order[] memory orders,\n        uint256 takerAssetFillAmount,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults memory fillResults);\n\n    /// @dev Executes multiple calls of fillOrder until total amount of makerAsset is bought by taker.\n    ///      If any fill reverts, the error is caught and ignored.\n    ///      NOTE: This function does not enforce that the makerAsset is the same for each order.\n    /// @param orders Array of order specifications.\n    /// @param makerAssetFillAmount Desired amount of makerAsset to buy.\n    /// @param signatures Proofs that orders have been signed by makers.\n    /// @return Amounts filled and fees paid by makers and taker.\n    function marketBuyOrdersNoThrow(\n        LibOrder.Order[] memory orders,\n        uint256 makerAssetFillAmount,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults memory fillResults);\n\n    /// @dev Calls marketSellOrdersNoThrow then reverts if < takerAssetFillAmount has been sold.\n    ///      NOTE: This function does not enforce that the takerAsset is the same for each order.\n    /// @param orders Array of order specifications.\n    /// @param takerAssetFillAmount Minimum amount of takerAsset to sell.\n    /// @param signatures Proofs that orders have been signed by makers.\n    /// @return Amounts filled and fees paid by makers and taker.\n    function marketSellOrdersFillOrKill(\n        LibOrder.Order[] memory orders,\n        uint256 takerAssetFillAmount,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults memory fillResults);\n\n    /// @dev Calls marketBuyOrdersNoThrow then reverts if < makerAssetFillAmount has been bought.\n    ///      NOTE: This function does not enforce that the makerAsset is the same for each order.\n    /// @param orders Array of order specifications.\n    /// @param makerAssetFillAmount Minimum amount of makerAsset to buy.\n    /// @param signatures Proofs that orders have been signed by makers.\n    /// @return Amounts filled and fees paid by makers and taker.\n    function marketBuyOrdersFillOrKill(\n        LibOrder.Order[] memory orders,\n        uint256 makerAssetFillAmount,\n        bytes[] memory signatures\n    )\n        public\n        payable\n        returns (LibFillResults.FillResults memory fillResults);\n\n    /// @dev Executes multiple calls of cancelOrder.\n    /// @param orders Array of order specifications.\n    function batchCancelOrders(LibOrder.Order[] memory orders)\n        public\n        payable;\n}\n",
        "./ITransferSimulator.sol": "/*\n\n  Copyright 2019 ZeroEx Intl.\n\n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\n  Unless required by applicable law or agreed to in writing, software\n  distributed under the License is distributed on an \"AS IS\" BASIS,\n  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n  See the License for the specific language governing permissions and\n  limitations under the License.\n\n*/\n\npragma solidity ^0.5.9;\npragma experimental ABIEncoderV2;\n\n\ncontract ITransferSimulator {\n\n    /// @dev This function may be used to simulate any amount of transfers\n    /// As they would occur through the Exchange contract. Note that this function\n    /// will always revert, even if all transfers are successful. However, it may\n    /// be used with eth_call or with a try/catch pattern in order to simulate\n    /// the results of the transfers.\n    /// @param assetData Array of asset details, each encoded per the AssetProxy contract specification.\n    /// @param fromAddresses Array containing the `from` addresses that correspond with each transfer.\n    /// @param toAddresses Array containing the `to` addresses that correspond with each transfer.\n    /// @param amounts Array containing the amounts that correspond to each transfer.\n    /// @return This function does not return a value. However, it will always revert with\n    /// `Error(\"TRANSFERS_SUCCESSFUL\")` if all of the transfers were successful.\n    function simulateDispatchTransferFromCalls(\n        bytes[] memory assetData,\n        address[] memory fromAddresses,\n        address[] memory toAddresses,\n        uint256[] memory amounts\n    )\n        public;\n}\n"
    },
    "compiler": {
        "name": "solc",
        "version": "0.5.17+commit.d19bba13",
        "settings": {
            "remappings": [
                "@0x/contracts-exchange-libs=/home/runner/work/protocol/protocol/contracts/exchange/node_modules/@0x/contracts-exchange-libs",
                "@0x/contracts-utils=/home/runner/work/protocol/protocol/contracts/exchange/node_modules/@0x/contracts-utils",
                "@0x/contracts-staking=/home/runner/work/protocol/protocol/contracts/exchange/node_modules/@0x/contracts-staking",
                "@0x/contracts-erc20=/home/runner/work/protocol/protocol/contracts/exchange/node_modules/@0x/contracts-erc20"
            ],
            "optimizer": {
                "enabled": true,
                "runs": 1000000,
                "details": {
                    "yul": true,
                    "deduplicate": true,
                    "cse": true,
                    "constantOptimizer": true
                }
            },
            "outputSelection": {
                "*": {
                    "*": [
                        "abi",
                        "devdoc",
                        "evm.bytecode.object",
                        "evm.bytecode.sourceMap",
                        "evm.deployedBytecode.object",
                        "evm.deployedBytecode.sourceMap"
                    ]
                }
            },
            "evmVersion": "istanbul"
        }
    },
    "chains": {}
}
